summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Noonan <steven@uplinklabs.net>2009-10-14 01:05:00 -0700
committerSteven Noonan <steven@uplinklabs.net>2009-10-14 21:33:59 -0700
commit9d51433ef6329e65938c5655586ea915493ba8ac (patch)
treea904d02f87629deaddb5cca83ff205eb836e53ba
parent59134ed3b2808e4e48ecc64ed8579b84431af057 (diff)
downloadcrawl-ref-9d51433ef6329e65938c5655586ea915493ba8ac.tar.gz
crawl-ref-9d51433ef6329e65938c5655586ea915493ba8ac.zip
contribs: moved to contribs dir, added as submodules
Signed-off-by: Steven Noonan <steven@uplinklabs.net>
-rw-r--r--.gitmodules9
-rw-r--r--crawl-ref/.gitignore3
-rw-r--r--crawl-ref/source/Crawl.xcodeproj/project.pbxproj6
-rw-r--r--crawl-ref/source/MSVC/crawl.vcproj8
-rw-r--r--crawl-ref/source/MSVC/lua.vcproj106
-rw-r--r--crawl-ref/source/MSVC/pcre.vcproj46
-rw-r--r--crawl-ref/source/MSVC/sqlite.vcproj4
m---------crawl-ref/source/contrib/lua0
m---------crawl-ref/source/contrib/pcre0
m---------crawl-ref/source/contrib/sqlite0
-rw-r--r--crawl-ref/source/makefile33
-rw-r--r--crawl-ref/source/makefile.dos6
-rwxr-xr-xcrawl-ref/source/misc/build_dcss_release.rb6
-rw-r--r--crawl-ref/source/util/lua/COPYRIGHT34
-rw-r--r--crawl-ref/source/util/lua/HISTORY183
-rw-r--r--crawl-ref/source/util/lua/INSTALL99
-rw-r--r--crawl-ref/source/util/lua/Makefile128
-rw-r--r--crawl-ref/source/util/lua/README37
-rw-r--r--crawl-ref/source/util/lua/doc/amazon.gifbin797 -> 0 bytes
-rw-r--r--crawl-ref/source/util/lua/doc/contents.html499
-rw-r--r--crawl-ref/source/util/lua/doc/cover.pngbin3305 -> 0 bytes
-rw-r--r--crawl-ref/source/util/lua/doc/logo.gifbin4232 -> 0 bytes
-rw-r--r--crawl-ref/source/util/lua/doc/lua.1163
-rw-r--r--crawl-ref/source/util/lua/doc/lua.css41
-rw-r--r--crawl-ref/source/util/lua/doc/lua.html172
-rw-r--r--crawl-ref/source/util/lua/doc/luac.1136
-rw-r--r--crawl-ref/source/util/lua/doc/luac.html145
-rw-r--r--crawl-ref/source/util/lua/doc/manual.css13
-rw-r--r--crawl-ref/source/util/lua/doc/manual.html8801
-rw-r--r--crawl-ref/source/util/lua/doc/readme.html40
-rw-r--r--crawl-ref/source/util/lua/etc/Makefile44
-rw-r--r--crawl-ref/source/util/lua/etc/README37
-rw-r--r--crawl-ref/source/util/lua/etc/all.c38
-rw-r--r--crawl-ref/source/util/lua/etc/lua.hpp9
-rw-r--r--crawl-ref/source/util/lua/etc/lua.icobin1078 -> 0 bytes
-rw-r--r--crawl-ref/source/util/lua/etc/lua.pc31
-rw-r--r--crawl-ref/source/util/lua/etc/luavs.bat28
-rw-r--r--crawl-ref/source/util/lua/etc/min.c39
-rw-r--r--crawl-ref/source/util/lua/etc/noparser.c50
-rw-r--r--crawl-ref/source/util/lua/etc/strict.lua41
-rw-r--r--crawl-ref/source/util/lua/src/Makefile208
-rw-r--r--crawl-ref/source/util/lua/src/lapi.c1087
-rw-r--r--crawl-ref/source/util/lua/src/lapi.h16
-rw-r--r--crawl-ref/source/util/lua/src/lauxlib.c652
-rw-r--r--crawl-ref/source/util/lua/src/lauxlib.h174
-rw-r--r--crawl-ref/source/util/lua/src/lbaselib.c653
-rw-r--r--crawl-ref/source/util/lua/src/lcode.c839
-rw-r--r--crawl-ref/source/util/lua/src/lcode.h76
-rw-r--r--crawl-ref/source/util/lua/src/ldblib.c397
-rw-r--r--crawl-ref/source/util/lua/src/ldebug.c638
-rw-r--r--crawl-ref/source/util/lua/src/ldebug.h33
-rw-r--r--crawl-ref/source/util/lua/src/ldo.c518
-rw-r--r--crawl-ref/source/util/lua/src/ldo.h57
-rw-r--r--crawl-ref/source/util/lua/src/ldump.c164
-rw-r--r--crawl-ref/source/util/lua/src/lfunc.c174
-rw-r--r--crawl-ref/source/util/lua/src/lfunc.h34
-rw-r--r--crawl-ref/source/util/lua/src/lgc.c711
-rw-r--r--crawl-ref/source/util/lua/src/lgc.h110
-rw-r--r--crawl-ref/source/util/lua/src/linit.c38
-rw-r--r--crawl-ref/source/util/lua/src/liolib.c553
-rw-r--r--crawl-ref/source/util/lua/src/llex.c461
-rw-r--r--crawl-ref/source/util/lua/src/llex.h81
-rw-r--r--crawl-ref/source/util/lua/src/llimits.h128
-rw-r--r--crawl-ref/source/util/lua/src/lmathlib.c263
-rw-r--r--crawl-ref/source/util/lua/src/lmem.c86
-rw-r--r--crawl-ref/source/util/lua/src/lmem.h49
-rw-r--r--crawl-ref/source/util/lua/src/loadlib.c666
-rw-r--r--crawl-ref/source/util/lua/src/lobject.c214
-rw-r--r--crawl-ref/source/util/lua/src/lobject.h381
-rw-r--r--crawl-ref/source/util/lua/src/lopcodes.c102
-rw-r--r--crawl-ref/source/util/lua/src/lopcodes.h268
-rw-r--r--crawl-ref/source/util/lua/src/loslib.c243
-rw-r--r--crawl-ref/source/util/lua/src/lparser.c1339
-rw-r--r--crawl-ref/source/util/lua/src/lparser.h82
-rw-r--r--crawl-ref/source/util/lua/src/lstate.c214
-rw-r--r--crawl-ref/source/util/lua/src/lstate.h169
-rw-r--r--crawl-ref/source/util/lua/src/lstring.c111
-rw-r--r--crawl-ref/source/util/lua/src/lstring.h31
-rw-r--r--crawl-ref/source/util/lua/src/lstrlib.c869
-rw-r--r--crawl-ref/source/util/lua/src/ltable.c588
-rw-r--r--crawl-ref/source/util/lua/src/ltable.h40
-rw-r--r--crawl-ref/source/util/lua/src/ltablib.c287
-rw-r--r--crawl-ref/source/util/lua/src/ltm.c75
-rw-r--r--crawl-ref/source/util/lua/src/ltm.h54
-rw-r--r--crawl-ref/source/util/lua/src/lua.c392
-rw-r--r--crawl-ref/source/util/lua/src/lua.h388
-rw-r--r--crawl-ref/source/util/lua/src/luac.c200
-rw-r--r--crawl-ref/source/util/lua/src/luaconf.h763
-rw-r--r--crawl-ref/source/util/lua/src/lualib.h53
-rw-r--r--crawl-ref/source/util/lua/src/lundump.c271
-rw-r--r--crawl-ref/source/util/lua/src/lundump.h36
-rw-r--r--crawl-ref/source/util/lua/src/lvm.c763
-rw-r--r--crawl-ref/source/util/lua/src/lvm.h36
-rw-r--r--crawl-ref/source/util/lua/src/lzio.c82
-rw-r--r--crawl-ref/source/util/lua/src/lzio.h67
-rw-r--r--crawl-ref/source/util/lua/src/print.c227
-rw-r--r--crawl-ref/source/util/lua/test/README26
-rw-r--r--crawl-ref/source/util/lua/test/bisect.lua27
-rw-r--r--crawl-ref/source/util/lua/test/cf.lua16
-rw-r--r--crawl-ref/source/util/lua/test/echo.lua5
-rw-r--r--crawl-ref/source/util/lua/test/env.lua7
-rw-r--r--crawl-ref/source/util/lua/test/factorial.lua32
-rw-r--r--crawl-ref/source/util/lua/test/fib.lua40
-rw-r--r--crawl-ref/source/util/lua/test/fibfor.lua13
-rw-r--r--crawl-ref/source/util/lua/test/globals.lua13
-rw-r--r--crawl-ref/source/util/lua/test/hello.lua3
-rw-r--r--crawl-ref/source/util/lua/test/life.lua111
-rw-r--r--crawl-ref/source/util/lua/test/luac.lua7
-rw-r--r--crawl-ref/source/util/lua/test/printf.lua7
-rw-r--r--crawl-ref/source/util/lua/test/readonly.lua12
-rw-r--r--crawl-ref/source/util/lua/test/sieve.lua29
-rw-r--r--crawl-ref/source/util/lua/test/sort.lua66
-rw-r--r--crawl-ref/source/util/lua/test/table.lua12
-rw-r--r--crawl-ref/source/util/lua/test/trace-calls.lua32
-rw-r--r--crawl-ref/source/util/lua/test/trace-globals.lua38
-rw-r--r--crawl-ref/source/util/lua/test/xd.lua14
-rw-r--r--crawl-ref/source/util/pcre/132html296
-rw-r--r--crawl-ref/source/util/pcre/AUTHORS23
-rw-r--r--crawl-ref/source/util/pcre/CMakeLists.txt540
-rw-r--r--crawl-ref/source/util/pcre/COPYING5
-rw-r--r--crawl-ref/source/util/pcre/ChangeLog3308
-rw-r--r--crawl-ref/source/util/pcre/CleanTxt113
-rw-r--r--crawl-ref/source/util/pcre/Detrail35
-rw-r--r--crawl-ref/source/util/pcre/HACKING418
-rw-r--r--crawl-ref/source/util/pcre/INSTALL237
-rw-r--r--crawl-ref/source/util/pcre/LICENCE68
-rw-r--r--crawl-ref/source/util/pcre/Makefile55
-rw-r--r--crawl-ref/source/util/pcre/Makefile.am392
-rw-r--r--crawl-ref/source/util/pcre/Makefile.in1436
-rw-r--r--crawl-ref/source/util/pcre/NEWS416
-rw-r--r--crawl-ref/source/util/pcre/NON-UNIX-USE432
-rw-r--r--crawl-ref/source/util/pcre/PrepareRelease214
-rw-r--r--crawl-ref/source/util/pcre/README752
-rw-r--r--crawl-ref/source/util/pcre/RunGrepTest277
-rw-r--r--crawl-ref/source/util/pcre/RunTest285
-rw-r--r--crawl-ref/source/util/pcre/RunTest.bat39
-rw-r--r--crawl-ref/source/util/pcre/aclocal.m47560
-rw-r--r--crawl-ref/source/util/pcre/config-cmake.h.in44
-rw-r--r--crawl-ref/source/util/pcre/config.guess1535
-rw-r--r--crawl-ref/source/util/pcre/config.h307
-rw-r--r--crawl-ref/source/util/pcre/config.h.in242
-rw-r--r--crawl-ref/source/util/pcre/config.sub1644
-rw-r--r--crawl-ref/source/util/pcre/configure24388
-rw-r--r--crawl-ref/source/util/pcre/configure.ac641
-rw-r--r--crawl-ref/source/util/pcre/depcomp589
-rw-r--r--crawl-ref/source/util/pcre/dftables.c199
-rw-r--r--crawl-ref/source/util/pcre/install-sh519
-rw-r--r--crawl-ref/source/util/pcre/libpcre.pc.in12
-rw-r--r--crawl-ref/source/util/pcre/libpcrecpp.pc.in12
-rw-r--r--crawl-ref/source/util/pcre/ltmain.sh6975
-rw-r--r--crawl-ref/source/util/pcre/makevp.bat44
-rw-r--r--crawl-ref/source/util/pcre/makevp_c.txt20
-rw-r--r--crawl-ref/source/util/pcre/makevp_l.txt20
-rw-r--r--crawl-ref/source/util/pcre/missing367
-rw-r--r--crawl-ref/source/util/pcre/pcre-config.in69
-rw-r--r--crawl-ref/source/util/pcre/pcre.h304
-rw-r--r--crawl-ref/source/util/pcre/pcre.h.in304
-rw-r--r--crawl-ref/source/util/pcre/pcre_chartables.c198
-rw-r--r--crawl-ref/source/util/pcre/pcre_compile.c6379
-rw-r--r--crawl-ref/source/util/pcre/pcre_config.c128
-rw-r--r--crawl-ref/source/util/pcre/pcre_dfa_exec.c2899
-rw-r--r--crawl-ref/source/util/pcre/pcre_exec.c4953
-rw-r--r--crawl-ref/source/util/pcre/pcre_fullinfo.c165
-rw-r--r--crawl-ref/source/util/pcre/pcre_get.c465
-rw-r--r--crawl-ref/source/util/pcre/pcre_globals.c63
-rw-r--r--crawl-ref/source/util/pcre/pcre_info.c93
-rw-r--r--crawl-ref/source/util/pcre/pcre_internal.h1138
-rw-r--r--crawl-ref/source/util/pcre/pcre_maketables.c143
-rw-r--r--crawl-ref/source/util/pcre/pcre_newline.c164
-rw-r--r--crawl-ref/source/util/pcre/pcre_ord2utf8.c85
-rw-r--r--crawl-ref/source/util/pcre/pcre_printint.src512
-rw-r--r--crawl-ref/source/util/pcre/pcre_refcount.c82
-rw-r--r--crawl-ref/source/util/pcre/pcre_scanner.cc199
-rw-r--r--crawl-ref/source/util/pcre/pcre_scanner.h172
-rw-r--r--crawl-ref/source/util/pcre/pcre_scanner_unittest.cc158
-rw-r--r--crawl-ref/source/util/pcre/pcre_stringpiece.cc43
-rw-r--r--crawl-ref/source/util/pcre/pcre_stringpiece.h.in177
-rw-r--r--crawl-ref/source/util/pcre/pcre_stringpiece_unittest.cc151
-rw-r--r--crawl-ref/source/util/pcre/pcre_study.c587
-rw-r--r--crawl-ref/source/util/pcre/pcre_tables.c318
-rw-r--r--crawl-ref/source/util/pcre/pcre_try_flipped.c137
-rw-r--r--crawl-ref/source/util/pcre/pcre_ucp_searchfuncs.c179
-rw-r--r--crawl-ref/source/util/pcre/pcre_valid_utf8.c162
-rw-r--r--crawl-ref/source/util/pcre/pcre_version.c90
-rw-r--r--crawl-ref/source/util/pcre/pcre_xclass.c148
-rw-r--r--crawl-ref/source/util/pcre/pcrecpp.cc893
-rw-r--r--crawl-ref/source/util/pcre/pcrecpp.h703
-rw-r--r--crawl-ref/source/util/pcre/pcrecpp_internal.h68
-rw-r--r--crawl-ref/source/util/pcre/pcrecpp_unittest.cc1276
-rw-r--r--crawl-ref/source/util/pcre/pcrecpparg.h.in174
-rw-r--r--crawl-ref/source/util/pcre/pcredemo.c334
-rw-r--r--crawl-ref/source/util/pcre/pcregexp.pas783
-rw-r--r--crawl-ref/source/util/pcre/pcregrep.c2379
-rw-r--r--crawl-ref/source/util/pcre/pcreposix.c356
-rw-r--r--crawl-ref/source/util/pcre/pcreposix.h143
-rw-r--r--crawl-ref/source/util/pcre/pcretest.c2448
-rw-r--r--crawl-ref/source/util/pcre/perltest.pl191
-rw-r--r--crawl-ref/source/util/pcre/ucp.h133
-rw-r--r--crawl-ref/source/util/pcre/ucpinternal.h92
-rw-r--r--crawl-ref/source/util/pcre/ucptable.h3088
-rw-r--r--crawl-ref/source/util/sqlite/Makefile48
-rw-r--r--crawl-ref/source/util/sqlite/sqlite3.c108806
-rw-r--r--crawl-ref/source/util/sqlite/sqlite3.h5759
203 files changed, 127 insertions, 231427 deletions
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000000..42d67fdc22
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,9 @@
+[submodule "crawl-ref/source/contrib/sqlite"]
+ path = crawl-ref/source/contrib/sqlite
+ url = git://crawl-ref.git.sourceforge.net/gitroot/crawl-ref/sqlite
+[submodule "crawl-ref/source/contrib/lua"]
+ path = crawl-ref/source/contrib/lua
+ url = git://crawl-ref.git.sourceforge.net/gitroot/crawl-ref/lua
+[submodule "crawl-ref/source/contrib/pcre"]
+ path = crawl-ref/source/contrib/pcre
+ url = git://crawl-ref.git.sourceforge.net/gitroot/crawl-ref/pcre
diff --git a/crawl-ref/.gitignore b/crawl-ref/.gitignore
index a4a2366785..bb47af26ed 100644
--- a/crawl-ref/.gitignore
+++ b/crawl-ref/.gitignore
@@ -28,6 +28,9 @@ source/dat/tiles/main.png
source/dat/tiles/player.png
source/dat/tiles/gui.png
+# Makefile-generated junk
+source/.contrib-ok
+
# The Crawl executable.
source/crawl
source/crawl.exe
diff --git a/crawl-ref/source/Crawl.xcodeproj/project.pbxproj b/crawl-ref/source/Crawl.xcodeproj/project.pbxproj
index 76c482425c..2a3ce98eb8 100644
--- a/crawl-ref/source/Crawl.xcodeproj/project.pbxproj
+++ b/crawl-ref/source/Crawl.xcodeproj/project.pbxproj
@@ -869,8 +869,8 @@
B07818DC1075D979008C3B64 /* sqldbm.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sqldbm.cc; sourceTree = "<group>"; };
B07818DD1075D979008C3B64 /* sqldbm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sqldbm.h; sourceTree = "<group>"; };
B082656F10731A95006EEC5A /* libSQLite.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libSQLite.a; sourceTree = BUILT_PRODUCTS_DIR; };
- B082657610731AB5006EEC5A /* sqlite3.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = sqlite3.c; path = util/sqlite/sqlite3.c; sourceTree = "<group>"; };
- B082657710731AB5006EEC5A /* sqlite3.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = sqlite3.h; path = util/sqlite/sqlite3.h; sourceTree = "<group>"; };
+ B082657610731AB5006EEC5A /* sqlite3.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = sqlite3.c; path = contrib/sqlite/sqlite3.c; sourceTree = "<group>"; };
+ B082657710731AB5006EEC5A /* sqlite3.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = sqlite3.h; path = contrib/sqlite/sqlite3.h; sourceTree = "<group>"; };
B0826648107333BB006EEC5A /* AppHdr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppHdr.h; sourceTree = "<group>"; };
B090C2EE10671F8900AE855D /* dngn.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = dngn.png; path = rltiles/dngn.png; sourceTree = "<group>"; };
B090C2EF10671F8900AE855D /* gui.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = gui.png; path = rltiles/gui.png; sourceTree = "<group>"; };
@@ -1086,7 +1086,7 @@
7B0EFD830BD12EEB00002671 /* print.c */,
);
name = Lua;
- path = util/lua/src;
+ path = contrib/lua/src;
sourceTree = "<group>";
};
7B352E950B0017CF00CABB32 /* Levcomp */ = {
diff --git a/crawl-ref/source/MSVC/crawl.vcproj b/crawl-ref/source/MSVC/crawl.vcproj
index b93b357894..fd2a1327e7 100644
--- a/crawl-ref/source/MSVC/crawl.vcproj
+++ b/crawl-ref/source/MSVC/crawl.vcproj
@@ -41,7 +41,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
- AdditionalIncludeDirectories=".;..;../util/lua/src;../util/sqlite;../util/pcre;../rltiles"
+ AdditionalIncludeDirectories=".;..;../contrib/lua/src;../contrib/sqlite;../contrib/pcre;../rltiles"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;YY_NO_UNISTD_H;_USE_MATH_DEFINES"
MinimalRebuild="true"
BasicRuntimeChecks="3"
@@ -118,7 +118,7 @@
/>
<Tool
Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=".;..;../util/lua/src;../util/sqlite;../util/pcre;../rltiles"
+ AdditionalIncludeDirectories=".;..;../contrib/lua/src;../contrib/sqlite;../contrib/pcre;../rltiles"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;YY_NO_UNISTD_H;_USE_MATH_DEFINES"
UsePrecompiledHeader="2"
PrecompiledHeaderThrough="AppHdr.h"
@@ -196,7 +196,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
- AdditionalIncludeDirectories=".;..;../util/lua/src;../util/sqlite;../util/pcre;../rltiles"
+ AdditionalIncludeDirectories=".;..;../contrib/lua/src;../contrib/sqlite;../contrib/pcre;../rltiles"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;YY_NO_UNISTD_H;_USE_MATH_DEFINES"
MinimalRebuild="true"
BasicRuntimeChecks="3"
@@ -273,7 +273,7 @@
/>
<Tool
Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=".;..;../util/lua/src;../util/sqlite;../util/pcre;../rltiles"
+ AdditionalIncludeDirectories=".;..;../contrib/lua/src;../contrib/sqlite;../contrib/pcre;../rltiles"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;YY_NO_UNISTD_H;_USE_MATH_DEFINES"
UsePrecompiledHeader="2"
PrecompiledHeaderThrough="AppHdr.h"
diff --git a/crawl-ref/source/MSVC/lua.vcproj b/crawl-ref/source/MSVC/lua.vcproj
index 0f9e53a8c3..973087193f 100644
--- a/crawl-ref/source/MSVC/lua.vcproj
+++ b/crawl-ref/source/MSVC/lua.vcproj
@@ -138,215 +138,215 @@
</References>
<Files>
<File
- RelativePath="..\util\lua\src\lapi.c"
+ RelativePath="..\contrib\lua\src\lapi.c"
>
</File>
<File
- RelativePath="..\util\lua\src\lapi.h"
+ RelativePath="..\contrib\lua\src\lapi.h"
>
</File>
<File
- RelativePath="..\util\lua\src\lauxlib.c"
+ RelativePath="..\contrib\lua\src\lauxlib.c"
>
</File>
<File
- RelativePath="..\util\lua\src\lauxlib.h"
+ RelativePath="..\contrib\lua\src\lauxlib.h"
>
</File>
<File
- RelativePath="..\util\lua\src\lbaselib.c"
+ RelativePath="..\contrib\lua\src\lbaselib.c"
>
</File>
<File
- RelativePath="..\util\lua\src\lcode.c"
+ RelativePath="..\contrib\lua\src\lcode.c"
>
</File>
<File
- RelativePath="..\util\lua\src\lcode.h"
+ RelativePath="..\contrib\lua\src\lcode.h"
>
</File>
<File
- RelativePath="..\util\lua\src\ldblib.c"
+ RelativePath="..\contrib\lua\src\ldblib.c"
>
</File>
<File
- RelativePath="..\util\lua\src\ldebug.c"
+ RelativePath="..\contrib\lua\src\ldebug.c"
>
</File>
<File
- RelativePath="..\util\lua\src\ldebug.h"
+ RelativePath="..\contrib\lua\src\ldebug.h"
>
</File>
<File
- RelativePath="..\util\lua\src\ldo.c"
+ RelativePath="..\contrib\lua\src\ldo.c"
>
</File>
<File
- RelativePath="..\util\lua\src\ldo.h"
+ RelativePath="..\contrib\lua\src\ldo.h"
>
</File>
<File
- RelativePath="..\util\lua\src\ldump.c"
+ RelativePath="..\contrib\lua\src\ldump.c"
>
</File>
<File
- RelativePath="..\util\lua\src\lfunc.c"
+ RelativePath="..\contrib\lua\src\lfunc.c"
>
</File>
<File
- RelativePath="..\util\lua\src\lfunc.h"
+ RelativePath="..\contrib\lua\src\lfunc.h"
>
</File>
<File
- RelativePath="..\util\lua\src\lgc.c"
+ RelativePath="..\contrib\lua\src\lgc.c"
>
</File>
<File
- RelativePath="..\util\lua\src\lgc.h"
+ RelativePath="..\contrib\lua\src\lgc.h"
>
</File>
<File
- RelativePath="..\util\lua\src\linit.c"
+ RelativePath="..\contrib\lua\src\linit.c"
>
</File>
<File
- RelativePath="..\util\lua\src\liolib.c"
+ RelativePath="..\contrib\lua\src\liolib.c"
>
</File>
<File
- RelativePath="..\util\lua\src\llex.c"
+ RelativePath="..\contrib\lua\src\llex.c"
>
</File>
<File
- RelativePath="..\util\lua\src\llex.h"
+ RelativePath="..\contrib\lua\src\llex.h"
>
</File>
<File
- RelativePath="..\util\lua\src\llimits.h"
+ RelativePath="..\contrib\lua\src\llimits.h"
>
</File>
<File
- RelativePath="..\util\lua\src\lmathlib.c"
+ RelativePath="..\contrib\lua\src\lmathlib.c"
>
</File>
<File
- RelativePath="..\util\lua\src\lmem.c"
+ RelativePath="..\contrib\lua\src\lmem.c"
>
</File>
<File
- RelativePath="..\util\lua\src\lmem.h"
+ RelativePath="..\contrib\lua\src\lmem.h"
>
</File>
<File
- RelativePath="..\util\lua\src\loadlib.c"
+ RelativePath="..\contrib\lua\src\loadlib.c"
>
</File>
<File
- RelativePath="..\util\lua\src\lobject.c"
+ RelativePath="..\contrib\lua\src\lobject.c"
>
</File>
<File
- RelativePath="..\util\lua\src\lobject.h"
+ RelativePath="..\contrib\lua\src\lobject.h"
>
</File>
<File
- RelativePath="..\util\lua\src\lopcodes.c"
+ RelativePath="..\contrib\lua\src\lopcodes.c"
>
</File>
<File
- RelativePath="..\util\lua\src\lopcodes.h"
+ RelativePath="..\contrib\lua\src\lopcodes.h"
>
</File>
<File
- RelativePath="..\util\lua\src\loslib.c"
+ RelativePath="..\contrib\lua\src\loslib.c"
>
</File>
<File
- RelativePath="..\util\lua\src\lparser.c"
+ RelativePath="..\contrib\lua\src\lparser.c"
>
</File>
<File
- RelativePath="..\util\lua\src\lparser.h"
+ RelativePath="..\contrib\lua\src\lparser.h"
>
</File>
<File
- RelativePath="..\util\lua\src\lstate.c"
+ RelativePath="..\contrib\lua\src\lstate.c"
>
</File>
<File
- RelativePath="..\util\lua\src\lstate.h"
+ RelativePath="..\contrib\lua\src\lstate.h"
>
</File>
<File
- RelativePath="..\util\lua\src\lstring.c"
+ RelativePath="..\contrib\lua\src\lstring.c"
>
</File>
<File
- RelativePath="..\util\lua\src\lstring.h"
+ RelativePath="..\contrib\lua\src\lstring.h"
>
</File>
<File
- RelativePath="..\util\lua\src\lstrlib.c"
+ RelativePath="..\contrib\lua\src\lstrlib.c"
>
</File>
<File
- RelativePath="..\util\lua\src\ltable.c"
+ RelativePath="..\contrib\lua\src\ltable.c"
>
</File>
<File
- RelativePath="..\util\lua\src\ltable.h"
+ RelativePath="..\contrib\lua\src\ltable.h"
>
</File>
<File
- RelativePath="..\util\lua\src\ltablib.c"
+ RelativePath="..\contrib\lua\src\ltablib.c"
>
</File>
<File
- RelativePath="..\util\lua\src\ltm.c"
+ RelativePath="..\contrib\lua\src\ltm.c"
>
</File>
<File
- RelativePath="..\util\lua\src\ltm.h"
+ RelativePath="..\contrib\lua\src\ltm.h"
>
</File>
<File
- RelativePath="..\util\lua\src\lua.h"
+ RelativePath="..\contrib\lua\src\lua.h"
>
</File>
<File
- RelativePath="..\util\lua\src\luaconf.h"
+ RelativePath="..\contrib\lua\src\luaconf.h"
>
</File>
<File
- RelativePath="..\util\lua\src\lualib.h"
+ RelativePath="..\contrib\lua\src\lualib.h"
>
</File>
<File
- RelativePath="..\util\lua\src\lundump.c"
+ RelativePath="..\contrib\lua\src\lundump.c"
>
</File>
<File
- RelativePath="..\util\lua\src\lundump.h"
+ RelativePath="..\contrib\lua\src\lundump.h"
>
</File>
<File
- RelativePath="..\util\lua\src\lvm.c"
+ RelativePath="..\contrib\lua\src\lvm.c"
>
</File>
<File
- RelativePath="..\util\lua\src\lvm.h"
+ RelativePath="..\contrib\lua\src\lvm.h"
>
</File>
<File
- RelativePath="..\util\lua\src\lzio.c"
+ RelativePath="..\contrib\lua\src\lzio.c"
>
</File>
<File
- RelativePath="..\util\lua\src\lzio.h"
+ RelativePath="..\contrib\lua\src\lzio.h"
>
</File>
<File
- RelativePath="..\util\lua\src\print.c"
+ RelativePath="..\contrib\lua\src\print.c"
>
</File>
</Files>
diff --git a/crawl-ref/source/MSVC/pcre.vcproj b/crawl-ref/source/MSVC/pcre.vcproj
index 2bca04c5d8..1f4aa13aaa 100644
--- a/crawl-ref/source/MSVC/pcre.vcproj
+++ b/crawl-ref/source/MSVC/pcre.vcproj
@@ -138,95 +138,95 @@
</References>
<Files>
<File
- RelativePath="..\util\pcre\pcre.h"
+ RelativePath="..\contrib\pcre\pcre.h"
>
</File>
<File
- RelativePath="..\util\pcre\pcre_chartables.c"
+ RelativePath="..\contrib\pcre\pcre_chartables.c"
>
</File>
<File
- RelativePath="..\util\pcre\pcre_compile.c"
+ RelativePath="..\contrib\pcre\pcre_compile.c"
>
</File>
<File
- RelativePath="..\util\pcre\pcre_config.c"
+ RelativePath="..\contrib\pcre\pcre_config.c"
>
</File>
<File
- RelativePath="..\util\pcre\pcre_dfa_exec.c"
+ RelativePath="..\contrib\pcre\pcre_dfa_exec.c"
>
</File>
<File
- RelativePath="..\util\pcre\pcre_exec.c"
+ RelativePath="..\contrib\pcre\pcre_exec.c"
>
</File>
<File
- RelativePath="..\util\pcre\pcre_fullinfo.c"
+ RelativePath="..\contrib\pcre\pcre_fullinfo.c"
>
</File>
<File
- RelativePath="..\util\pcre\pcre_get.c"
+ RelativePath="..\contrib\pcre\pcre_get.c"
>
</File>
<File
- RelativePath="..\util\pcre\pcre_globals.c"
+ RelativePath="..\contrib\pcre\pcre_globals.c"
>
</File>
<File
- RelativePath="..\util\pcre\pcre_info.c"
+ RelativePath="..\contrib\pcre\pcre_info.c"
>
</File>
<File
- RelativePath="..\util\pcre\pcre_internal.h"
+ RelativePath="..\contrib\pcre\pcre_internal.h"
>
</File>
<File
- RelativePath="..\util\pcre\pcre_maketables.c"
+ RelativePath="..\contrib\pcre\pcre_maketables.c"
>
</File>
<File
- RelativePath="..\util\pcre\pcre_newline.c"
+ RelativePath="..\contrib\pcre\pcre_newline.c"
>
</File>
<File
- RelativePath="..\util\pcre\pcre_ord2utf8.c"
+ RelativePath="..\contrib\pcre\pcre_ord2utf8.c"
>
</File>
<File
- RelativePath="..\util\pcre\pcre_refcount.c"
+ RelativePath="..\contrib\pcre\pcre_refcount.c"
>
</File>
<File
- RelativePath="..\util\pcre\pcre_scanner.h"
+ RelativePath="..\contrib\pcre\pcre_scanner.h"
>
</File>
<File
- RelativePath="..\util\pcre\pcre_study.c"
+ RelativePath="..\contrib\pcre\pcre_study.c"
>
</File>
<File
- RelativePath="..\util\pcre\pcre_tables.c"
+ RelativePath="..\contrib\pcre\pcre_tables.c"
>
</File>
<File
- RelativePath="..\util\pcre\pcre_try_flipped.c"
+ RelativePath="..\contrib\pcre\pcre_try_flipped.c"
>
</File>
<File
- RelativePath="..\util\pcre\pcre_ucp_searchfuncs.c"
+ RelativePath="..\contrib\pcre\pcre_ucp_searchfuncs.c"
>
</File>
<File
- RelativePath="..\util\pcre\pcre_valid_utf8.c"
+ RelativePath="..\contrib\pcre\pcre_valid_utf8.c"
>
</File>
<File
- RelativePath="..\util\pcre\pcre_version.c"
+ RelativePath="..\contrib\pcre\pcre_version.c"
>
</File>
<File
- RelativePath="..\util\pcre\pcre_xclass.c"
+ RelativePath="..\contrib\pcre\pcre_xclass.c"
>
</File>
</Files>
diff --git a/crawl-ref/source/MSVC/sqlite.vcproj b/crawl-ref/source/MSVC/sqlite.vcproj
index 72f023ad76..0d3c3a4410 100644
--- a/crawl-ref/source/MSVC/sqlite.vcproj
+++ b/crawl-ref/source/MSVC/sqlite.vcproj
@@ -138,11 +138,11 @@
</References>
<Files>
<File
- RelativePath="..\util\sqlite\sqlite3.c"
+ RelativePath="..\contrib\sqlite\sqlite3.c"
>
</File>
<File
- RelativePath="..\util\sqlite\sqlite3.h"
+ RelativePath="..\contrib\sqlite\sqlite3.h"
>
</File>
</Files>
diff --git a/crawl-ref/source/contrib/lua b/crawl-ref/source/contrib/lua
new file mode 160000
+Subproject 9ca5e4ce20daff5a11d19132ada7936d3390680
diff --git a/crawl-ref/source/contrib/pcre b/crawl-ref/source/contrib/pcre
new file mode 160000
+Subproject 27d0ec7ed9034beb3d2d7f0addd8812a8a1ba05
diff --git a/crawl-ref/source/contrib/sqlite b/crawl-ref/source/contrib/sqlite
new file mode 160000
+Subproject 44ae8d12a69ffa25c67568ca152379dd364afb2
diff --git a/crawl-ref/source/makefile b/crawl-ref/source/makefile
index 24d5337c30..a6ad9608d0 100644
--- a/crawl-ref/source/makefile
+++ b/crawl-ref/source/makefile
@@ -32,6 +32,7 @@ CFOPTIMIZE := -O2
CFOTHERS := -fno-strict-aliasing -pipe
CFOTHERS_L := -fsigned-char
CFWARN := -Wall
+MAKEFLAGS := --no-print-directory
#
# The GCC and GXX variables are set later.
@@ -47,6 +48,7 @@ export RM
export CC
export CXX
export CFLAGS
+export MAKEFLAGS
#
# Platform Detection
@@ -146,19 +148,19 @@ INSTALLDIR := /usr/games/crawl
PCH := n
# libpcre
-PCRESRC := util/pcre/
+PCRESRC := contrib/pcre/
PCRELIB := pcre
PCRELIBA := lib$(PCRELIB).a
FPCRELIBA := $(PCRESRC)$(PCRELIBA)
# LUA
-LUASRC := util/lua/src/
+LUASRC := contrib/lua/src/
LUALIB := lua
LUALIBA := lib$(LUALIB).a
FLUALIBA := $(LUASRC)$(LUALIBA)
# SQLite
-SQLSRC := util/sqlite/
+SQLSRC := contrib/sqlite/
SQLLIB := sqlite3
SQLLIBA := lib$(SQLLIB).a
FSQLLIBA := $(SQLSRC)$(SQLLIBA)
@@ -553,6 +555,8 @@ PKG_TIDY_LIST := $(UTIL)*.o $(LEVCOMP) *.o \
$(UTIL)*.tab.cc $(UTIL)*.tab.h $(UTIL)*.lex.cc *.ixx
PKG_EXCLUDES := $(PWD)/misc/src-pkg-excludes.lst
+.PHONY: install clean clean-lua clean-sql distclean debug profile wizard
+
##########################################################################
all: $(GAME)
@@ -576,6 +580,8 @@ depend: $(OBJECTS:.o=.cc)
else
depend: $(DEPENDENCY_MKF)
+makefile.dep: .contrib-ok
+
%.dep: $(OBJECTS:.o=.cc)
$(QUIET_DEPEND)fastdep $(DEFINES) $(INCLUDES) *.h $(OBJECTS:.o=.cc) > $@
endif
@@ -595,6 +601,9 @@ ifeq ($(strip $(DOYACC)),y)
prebuildyacc: $(UTIL)levcomp.tab.cc $(UTIL)levcomp.tab.h $(UTIL)levcomp.lex.cc
$(QUIET_COPY)$(COPY) $^ prebuilt/
+$(UTIL)levcomp.tab.cc: .contrib-ok
+$(UTIL)levcomp.lex.cc: .contrib-ok
+
$(UTIL)levcomp.tab.cc: $(UTIL)levcomp.ypp
+@$(MAKE) -C $(UTIL) levcomp.tab.cc
@@ -620,7 +629,6 @@ endif
##########################################################################
# The actual build targets
#
-
install: $(GAME)
ifeq ($(DATADIR),)
$(error DATADIR not set! Set DATADIR and run make clean install again)
@@ -663,11 +671,18 @@ clean-sql:
distclean: clean clean-lua clean-sql clean-rltiles
$(RM) bones.* morgue.txt scores $(GAME) *.sav core *.0* *.lab $(DEPENDENCY_MKF)
+.contrib-ok:
+ @for a in $(LUASRC)Makefile $(SQLSRC)Makefile $(PCRESRC)Makefile; do \
+ if [ ! -f $$a ]; then \
+ echo "The '$$a' file is missing. Have you run 'git submodule update --init'?"; \
+ exit 1; \
+ fi \
+ done
+ @touch .contrib-ok
+
$(GAME): $(GAME_DEPENDS)
$(QUIET_LINK)$(CXX) $(LDFLAGS) $(EXTRA_OBJECTS) $(OBJECTS) -o $(GAME) $(LIB)
-.PHONY : debug profile wizard
-
debug: $(GAME)
profile: $(GAME)
wizard: $(GAME)
@@ -697,19 +712,19 @@ $(OBJECTS:%.o=%.cc): $(CC_DEP) $(TILEDEFHDRS)
#############################################################################
# Build PCRE
-$(FPCRELIBA):
+$(FPCRELIBA): .contrib-ok
+@$(MAKE) -C $(PCRESRC)
#############################################################################
# Build Lua
-$(FLUALIBA):
+$(FLUALIBA): .contrib-ok
+@$(MAKE) -C $(LUASRC) crawl_unix
#############################################################################
# Build SQLite
-$(FSQLLIBA):
+$(FSQLLIBA): .contrib-ok
+@$(MAKE) -C $(SQLSRC)
#############################################################################
diff --git a/crawl-ref/source/makefile.dos b/crawl-ref/source/makefile.dos
index d144708306..127bc384ff 100644
--- a/crawl-ref/source/makefile.dos
+++ b/crawl-ref/source/makefile.dos
@@ -19,18 +19,18 @@ YACC := bison -y
INSTALLDIR ?= package
ifeq ($(LUASRC),)
-LUASRC := util\lua\src
+LUASRC := contrib\lua\src
endif
LUALIB = lua
LUALIBA = lib$(LUALIB).a
-SQLSRC := util\sqlite
+SQLSRC := contrib\sqlite
SQLLIB := sql3
SQLLIBA := lib$(SQLLIB).a
FSQLLIBA := $(SQLSRC)\$(SQLLIBA)
-PCRESRC := util\pcre
+PCRESRC := contrib\pcre
PCRELIB := pcre
PCRELIBA := lib$(PCRELIB).a
diff --git a/crawl-ref/source/misc/build_dcss_release.rb b/crawl-ref/source/misc/build_dcss_release.rb
index 5f620fb209..92e8750d21 100755
--- a/crawl-ref/source/misc/build_dcss_release.rb
+++ b/crawl-ref/source/misc/build_dcss_release.rb
@@ -96,7 +96,7 @@ def path_prefix(prefix)
end
def clean_objects
- [ '.', 'rel', 'dbg', 'util', 'util/lua/src', 'util/sqlite' ].each do |dir|
+ [ '.', 'rel', 'dbg', 'util', 'contrib/lua/src', 'contrib/sqlite' ].each do |dir|
if File.directory? dir
FileUtils.rm( Dir[dir + '/*.o'], :force => true )
FileUtils.rm( Dir[dir + '/*.a'], :force => true )
@@ -155,7 +155,7 @@ def build_dos
setup_dosmake_env
puts "\nBuilding stone_soup (ndebug) for #{release_version} DOS"
- ENV['LIB'] = "-static -Lutil\\lua\\src -llua -lpcre -Lutil\\sqlite -lsql3"
+ ENV['LIB'] = "-static -Lcontrib\\lua\\src -llua -lpcre -Lcontrib\\sqlite -lsql3"
ENV['EXTRA_FLAGS'] = "-O2 -DCLUA_BINDINGS -DREGEX_PCRE -DDEBUG -DWIZARD"
puts %{ #{DOSMAKE} -e -f makefile.dos DOYACC=y }
@@ -171,7 +171,7 @@ def build_win32
puts "\nBuilding stone_soup (non-debug) for #{release_version} release!"
system( %{#{W32MAKE} -f makefile.mgw DOYACC=y "EXTRA_FLAGS=-O2 } +
%{-DCLUA_BINDINGS -DREGEX_PCRE -DDEBUG -DWIZARD" } +
- %{"LIB=-lwinmm -static -Lutil/lua/src -llua -lpcre -Lutil/sqlite -lsqlite3"} ) or
+ %{"LIB=-lwinmm -static -Lcontrib/lua/src -llua -lpcre -Lcontrib/sqlite -lsqlite3"} ) or
raise "#{W32MAKE} failed: #$?"
clean_w32build_area
diff --git a/crawl-ref/source/util/lua/COPYRIGHT b/crawl-ref/source/util/lua/COPYRIGHT
deleted file mode 100644
index 3a53e741e0..0000000000
--- a/crawl-ref/source/util/lua/COPYRIGHT
+++ /dev/null
@@ -1,34 +0,0 @@
-Lua License
------------
-
-Lua is licensed under the terms of the MIT license reproduced below.
-This means that Lua is free software and can be used for both academic
-and commercial purposes at absolutely no cost.
-
-For details and rationale, see http://www.lua.org/license.html .
-
-===============================================================================
-
-Copyright (C) 1994-2008 Lua.org, PUC-Rio.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-
-===============================================================================
-
-(end of COPYRIGHT)
diff --git a/crawl-ref/source/util/lua/HISTORY b/crawl-ref/source/util/lua/HISTORY
deleted file mode 100644
index ce0c95bc69..0000000000
--- a/crawl-ref/source/util/lua/HISTORY
+++ /dev/null
@@ -1,183 +0,0 @@
-HISTORY for Lua 5.1
-
-* Changes from version 5.0 to 5.1
- -------------------------------
- Language:
- + new module system.
- + new semantics for control variables of fors.
- + new semantics for setn/getn.
- + new syntax/semantics for varargs.
- + new long strings and comments.
- + new `mod' operator (`%')
- + new length operator #t
- + metatables for all types
- API:
- + new functions: lua_createtable, lua_get(set)field, lua_push(to)integer.
- + user supplies memory allocator (lua_open becomes lua_newstate).
- + luaopen_* functions must be called through Lua.
- Implementation:
- + new configuration scheme via luaconf.h.
- + incremental garbage collection.
- + better handling of end-of-line in the lexer.
- + fully reentrant parser (new Lua function `load')
- + better support for 64-bit machines.
- + native loadlib support for Mac OS X.
- + standard distribution in only one library (lualib.a merged into lua.a)
-
-* Changes from version 4.0 to 5.0
- -------------------------------
- Language:
- + lexical scoping.
- + Lua coroutines.
- + standard libraries now packaged in tables.
- + tags replaced by metatables and tag methods replaced by metamethods,
- stored in metatables.
- + proper tail calls.
- + each function can have its own global table, which can be shared.
- + new __newindex metamethod, called when we insert a new key into a table.
- + new block comments: --[[ ... ]].
- + new generic for.
- + new weak tables.
- + new boolean type.
- + new syntax "local function".
- + (f()) returns the first value returned by f.
- + {f()} fills a table with all values returned by f.
- + \n ignored in [[\n .
- + fixed and-or priorities.
- + more general syntax for function definition (e.g. function a.x.y:f()...end).
- + more general syntax for function calls (e.g. (print or write)(9)).
- + new functions (time/date, tmpfile, unpack, require, load*, etc.).
- API:
- + chunks are loaded by using lua_load; new luaL_loadfile and luaL_loadbuffer.
- + introduced lightweight userdata, a simple "void*" without a metatable.
- + new error handling protocol: the core no longer prints error messages;
- all errors are reported to the caller on the stack.
- + new lua_atpanic for host cleanup.
- + new, signal-safe, hook scheme.
- Implementation:
- + new license: MIT.
- + new, faster, register-based virtual machine.
- + support for external multithreading and coroutines.
- + new and consistent error message format.
- + the core no longer needs "stdio.h" for anything (except for a single
- use of sprintf to convert numbers to strings).
- + lua.c now runs the environment variable LUA_INIT, if present. It can
- be "@filename", to run a file, or the chunk itself.
- + support for user extensions in lua.c.
- sample implementation given for command line editing.
- + new dynamic loading library, active by default on several platforms.
- + safe garbage-collector metamethods.
- + precompiled bytecodes checked for integrity (secure binary dostring).
- + strings are fully aligned.
- + position capture in string.find.
- + read('*l') can read lines with embedded zeros.
-
-* Changes from version 3.2 to 4.0
- -------------------------------
- Language:
- + new "break" and "for" statements (both numerical and for tables).
- + uniform treatment of globals: globals are now stored in a Lua table.
- + improved error messages.
- + no more '$debug': full speed *and* full debug information.
- + new read form: read(N) for next N bytes.
- + general read patterns now deprecated.
- (still available with -DCOMPAT_READPATTERNS.)
- + all return values are passed as arguments for the last function
- (old semantics still available with -DLUA_COMPAT_ARGRET)
- + garbage collection tag methods for tables now deprecated.
- + there is now only one tag method for order.
- API:
- + New API: fully re-entrant, simpler, and more efficient.
- + New debug API.
- Implementation:
- + faster than ever: cleaner virtual machine and new hashing algorithm.
- + non-recursive garbage-collector algorithm.
- + reduced memory usage for programs with many strings.
- + improved treatment for memory allocation errors.
- + improved support for 16-bit machines (we hope).
- + code now compiles unmodified as both ANSI C and C++.
- + numbers in bases other than 10 are converted using strtoul.
- + new -f option in Lua to support #! scripts.
- + luac can now combine text and binaries.
-
-* Changes from version 3.1 to 3.2
- -------------------------------
- + redirected all output in Lua's core to _ERRORMESSAGE and _ALERT.
- + increased limit on the number of constants and globals per function
- (from 2^16 to 2^24).
- + debugging info (lua_debug and hooks) moved into lua_state and new API
- functions provided to get and set this info.
- + new debug lib gives full debugging access within Lua.
- + new table functions "foreachi", "sort", "tinsert", "tremove", "getn".
- + new io functions "flush", "seek".
-
-* Changes from version 3.0 to 3.1
- -------------------------------
- + NEW FEATURE: anonymous functions with closures (via "upvalues").
- + new syntax:
- - local variables in chunks.
- - better scope control with DO block END.
- - constructors can now be also written: { record-part; list-part }.
- - more general syntax for function calls and lvalues, e.g.:
- f(x).y=1
- o:f(x,y):g(z)
- f"string" is sugar for f("string")
- + strings may now contain arbitrary binary data (e.g., embedded zeros).
- + major code re-organization and clean-up; reduced module interdependecies.
- + no arbitrary limits on the total number of constants and globals.
- + support for multiple global contexts.
- + better syntax error messages.
- + new traversal functions "foreach" and "foreachvar".
- + the default for numbers is now double.
- changing it to use floats or longs is easy.
- + complete debug information stored in pre-compiled chunks.
- + sample interpreter now prompts user when run interactively, and also
- handles control-C interruptions gracefully.
-
-* Changes from version 2.5 to 3.0
- -------------------------------
- + NEW CONCEPT: "tag methods".
- Tag methods replace fallbacks as the meta-mechanism for extending the
- semantics of Lua. Whereas fallbacks had a global nature, tag methods
- work on objects having the same tag (e.g., groups of tables).
- Existing code that uses fallbacks should work without change.
- + new, general syntax for constructors {[exp] = exp, ... }.
- + support for handling variable number of arguments in functions (varargs).
- + support for conditional compilation ($if ... $else ... $end).
- + cleaner semantics in API simplifies host code.
- + better support for writing libraries (auxlib.h).
- + better type checking and error messages in the standard library.
- + luac can now also undump.
-
-* Changes from version 2.4 to 2.5
- -------------------------------
- + io and string libraries are now based on pattern matching;
- the old libraries are still available for compatibility
- + dofile and dostring can now return values (via return statement)
- + better support for 16- and 64-bit machines
- + expanded documentation, with more examples
-
-* Changes from version 2.2 to 2.4
- -------------------------------
- + external compiler creates portable binary files that can be loaded faster
- + interface for debugging and profiling
- + new "getglobal" fallback
- + new functions for handling references to Lua objects
- + new functions in standard lib
- + only one copy of each string is stored
- + expanded documentation, with more examples
-
-* Changes from version 2.1 to 2.2
- -------------------------------
- + functions now may be declared with any "lvalue" as a name
- + garbage collection of functions
- + support for pipes
-
-* Changes from version 1.1 to 2.1
- -------------------------------
- + object-oriented support
- + fallbacks
- + simplified syntax for tables
- + many internal improvements
-
-(end of HISTORY)
diff --git a/crawl-ref/source/util/lua/INSTALL b/crawl-ref/source/util/lua/INSTALL
deleted file mode 100644
index 17eb8aee8c..0000000000
--- a/crawl-ref/source/util/lua/INSTALL
+++ /dev/null
@@ -1,99 +0,0 @@
-INSTALL for Lua 5.1
-
-* Building Lua
- ------------
- Lua is built in the src directory, but the build process can be
- controlled from the top-level Makefile.
-
- Building Lua on Unix systems should be very easy. First do "make" and
- see if your platform is listed. If so, just do "make xxx", where xxx
- is your platform name. The platforms currently supported are:
- aix ansi bsd freebsd generic linux macosx mingw posix solaris
-
- If your platform is not listed, try the closest one or posix, generic,
- ansi, in this order.
-
- See below for customization instructions and for instructions on how
- to build with other Windows compilers.
-
- If you want to check that Lua has been built correctly, do "make test"
- after building Lua. Also, have a look at the example programs in test.
-
-* Installing Lua
- --------------
- Once you have built Lua, you may want to install it in an official
- place in your system. In this case, do "make install". The official
- place and the way to install files are defined in Makefile. You must
- have the right permissions to install files.
-
- If you want to build and install Lua in one step, do "make xxx install",
- where xxx is your platform name.
-
- If you want to install Lua locally, then do "make local". This will
- create directories bin, include, lib, man, and install Lua there as
- follows:
-
- bin: lua luac
- include: lua.h luaconf.h lualib.h lauxlib.h lua.hpp
- lib: liblua.a
- man/man1: lua.1 luac.1
-
- These are the only directories you need for development.
-
- There are man pages for lua and luac, in both nroff and html, and a
- reference manual in html in doc, some sample code in test, and some
- useful stuff in etc. You don't need these directories for development.
-
- If you want to install Lua locally, but in some other directory, do
- "make install INSTALL_TOP=xxx", where xxx is your chosen directory.
-
- See below for instructions for Windows and other systems.
-
-* Customization
- -------------
- Three things can be customized by editing a file:
- - Where and how to install Lua -- edit Makefile.
- - How to build Lua -- edit src/Makefile.
- - Lua features -- edit src/luaconf.h.
-
- You don't actually need to edit the Makefiles because you may set the
- relevant variables when invoking make.
-
- On the other hand, if you need to select some Lua features, you'll need
- to edit src/luaconf.h. The edited file will be the one installed, and
- it will be used by any Lua clients that you build, to ensure consistency.
-
- We strongly recommend that you enable dynamic loading. This is done
- automatically for all platforms listed above that have this feature
- (and also Windows). See src/luaconf.h and also src/Makefile.
-
-* Building Lua on Windows and other systems
- -----------------------------------------
- If you're not using the usual Unix tools, then the instructions for
- building Lua depend on the compiler you use. You'll need to create
- projects (or whatever your compiler uses) for building the library,
- the interpreter, and the compiler, as follows:
-
- library: lapi.c lcode.c ldebug.c ldo.c ldump.c lfunc.c lgc.c llex.c
- lmem.c lobject.c lopcodes.c lparser.c lstate.c lstring.c
- ltable.c ltm.c lundump.c lvm.c lzio.c
- lauxlib.c lbaselib.c ldblib.c liolib.c lmathlib.c loslib.c
- ltablib.c lstrlib.c loadlib.c linit.c
-
- interpreter: library, lua.c
-
- compiler: library, luac.c print.c
-
- If you use Visual Studio .NET, you can use etc/luavs.bat in its
- "Command Prompt".
-
- If all you want is to build the Lua interpreter, you may put all .c files
- in a single project, except for luac.c and print.c. Or just use etc/all.c.
-
- To use Lua as a library in your own programs, you'll need to know how to
- create and use libraries with your compiler.
-
- As mentioned above, you may edit luaconf.h to select some features before
- building Lua.
-
-(end of INSTALL)
diff --git a/crawl-ref/source/util/lua/Makefile b/crawl-ref/source/util/lua/Makefile
deleted file mode 100644
index 6e78f66fa5..0000000000
--- a/crawl-ref/source/util/lua/Makefile
+++ /dev/null
@@ -1,128 +0,0 @@
-# makefile for installing Lua
-# see INSTALL for installation instructions
-# see src/Makefile and src/luaconf.h for further customization
-
-# == CHANGE THE SETTINGS BELOW TO SUIT YOUR ENVIRONMENT =======================
-
-# Your platform. See PLATS for possible values.
-PLAT= none
-
-# Where to install. The installation starts in the src and doc directories,
-# so take care if INSTALL_TOP is not an absolute path.
-INSTALL_TOP= /usr/local
-INSTALL_BIN= $(INSTALL_TOP)/bin
-INSTALL_INC= $(INSTALL_TOP)/include
-INSTALL_LIB= $(INSTALL_TOP)/lib
-INSTALL_MAN= $(INSTALL_TOP)/man/man1
-#
-# You probably want to make INSTALL_LMOD and INSTALL_CMOD consistent with
-# LUA_ROOT, LUA_LDIR, and LUA_CDIR in luaconf.h (and also with etc/lua.pc).
-INSTALL_LMOD= $(INSTALL_TOP)/share/lua/$V
-INSTALL_CMOD= $(INSTALL_TOP)/lib/lua/$V
-
-# How to install. If your install program does not support "-p", then you
-# may have to run ranlib on the installed liblua.a (do "make ranlib").
-INSTALL= install -p
-INSTALL_EXEC= $(INSTALL) -m 0755
-INSTALL_DATA= $(INSTALL) -m 0644
-#
-# If you don't have install you can use cp instead.
-# INSTALL= cp -p
-# INSTALL_EXEC= $(INSTALL)
-# INSTALL_DATA= $(INSTALL)
-
-# Utilities.
-MKDIR= mkdir -p
-RANLIB= ranlib
-
-# == END OF USER SETTINGS. NO NEED TO CHANGE ANYTHING BELOW THIS LINE =========
-
-# Convenience platforms targets.
-PLATS= aix ansi bsd freebsd generic linux macosx mingw posix solaris
-
-# What to install.
-TO_BIN= lua luac
-TO_INC= lua.h luaconf.h lualib.h lauxlib.h ../etc/lua.hpp
-TO_LIB= liblua.a
-TO_MAN= lua.1 luac.1
-
-# Lua version and release.
-V= 5.1
-R= 5.1.4
-
-all: $(PLAT)
-
-$(PLATS) clean:
- cd src && $(MAKE) $@
-
-test: dummy
- src/lua test/hello.lua
-
-install: dummy
- cd src && $(MKDIR) $(INSTALL_BIN) $(INSTALL_INC) $(INSTALL_LIB) $(INSTALL_MAN) $(INSTALL_LMOD) $(INSTALL_CMOD)
- cd src && $(INSTALL_EXEC) $(TO_BIN) $(INSTALL_BIN)
- cd src && $(INSTALL_DATA) $(TO_INC) $(INSTALL_INC)
- cd src && $(INSTALL_DATA) $(TO_LIB) $(INSTALL_LIB)
- cd doc && $(INSTALL_DATA) $(TO_MAN) $(INSTALL_MAN)
-
-ranlib:
- cd src && cd $(INSTALL_LIB) && $(RANLIB) $(TO_LIB)
-
-local:
- $(MAKE) install INSTALL_TOP=..
-
-none:
- @echo "Please do"
- @echo " make PLATFORM"
- @echo "where PLATFORM is one of these:"
- @echo " $(PLATS)"
- @echo "See INSTALL for complete instructions."
-
-# make may get confused with test/ and INSTALL in a case-insensitive OS
-dummy:
-
-# echo config parameters
-echo:
- @echo ""
- @echo "These are the parameters currently set in src/Makefile to build Lua $R:"
- @echo ""
- @cd src && $(MAKE) -s echo
- @echo ""
- @echo "These are the parameters currently set in Makefile to install Lua $R:"
- @echo ""
- @echo "PLAT = $(PLAT)"
- @echo "INSTALL_TOP = $(INSTALL_TOP)"
- @echo "INSTALL_BIN = $(INSTALL_BIN)"
- @echo "INSTALL_INC = $(INSTALL_INC)"
- @echo "INSTALL_LIB = $(INSTALL_LIB)"
- @echo "INSTALL_MAN = $(INSTALL_MAN)"
- @echo "INSTALL_LMOD = $(INSTALL_LMOD)"
- @echo "INSTALL_CMOD = $(INSTALL_CMOD)"
- @echo "INSTALL_EXEC = $(INSTALL_EXEC)"
- @echo "INSTALL_DATA = $(INSTALL_DATA)"
- @echo ""
- @echo "See also src/luaconf.h ."
- @echo ""
-
-# echo private config parameters
-pecho:
- @echo "V = $(V)"
- @echo "R = $(R)"
- @echo "TO_BIN = $(TO_BIN)"
- @echo "TO_INC = $(TO_INC)"
- @echo "TO_LIB = $(TO_LIB)"
- @echo "TO_MAN = $(TO_MAN)"
-
-# echo config parameters as Lua code
-# uncomment the last sed expression if you want nil instead of empty strings
-lecho:
- @echo "-- installation parameters for Lua $R"
- @echo "VERSION = '$V'"
- @echo "RELEASE = '$R'"
- @$(MAKE) echo | grep = | sed -e 's/= /= "/' -e 's/$$/"/' #-e 's/""/nil/'
- @echo "-- EOF"
-
-# list targets that do not create files (but not all makes understand .PHONY)
-.PHONY: all $(PLATS) clean test install local none dummy echo pecho lecho
-
-# (end of Makefile)
diff --git a/crawl-ref/source/util/lua/README b/crawl-ref/source/util/lua/README
deleted file mode 100644
index 11b4dff70e..0000000000
--- a/crawl-ref/source/util/lua/README
+++ /dev/null
@@ -1,37 +0,0 @@
-README for Lua 5.1
-
-See INSTALL for installation instructions.
-See HISTORY for a summary of changes since the last released version.
-
-* What is Lua?
- ------------
- Lua is a powerful, light-weight programming language designed for extending
- applications. Lua is also frequently used as a general-purpose, stand-alone
- language. Lua is free software.
-
- For complete information, visit Lua's web site at http://www.lua.org/ .
- For an executive summary, see http://www.lua.org/about.html .
-
- Lua has been used in many different projects around the world.
- For a short list, see http://www.lua.org/uses.html .
-
-* Availability
- ------------
- Lua is freely available for both academic and commercial purposes.
- See COPYRIGHT and http://www.lua.org/license.html for details.
- Lua can be downloaded at http://www.lua.org/download.html .
-
-* Installation
- ------------
- Lua is implemented in pure ANSI C, and compiles unmodified in all known
- platforms that have an ANSI C compiler. In most Unix-like platforms, simply
- do "make" with a suitable target. See INSTALL for detailed instructions.
-
-* Origin
- ------
- Lua is developed at Lua.org, a laboratory of the Department of Computer
- Science of PUC-Rio (the Pontifical Catholic University of Rio de Janeiro
- in Brazil).
- For more information about the authors, see http://www.lua.org/authors.html .
-
-(end of README)
diff --git a/crawl-ref/source/util/lua/doc/amazon.gif b/crawl-ref/source/util/lua/doc/amazon.gif
deleted file mode 100644
index f2586d5765..0000000000
--- a/crawl-ref/source/util/lua/doc/amazon.gif
+++ /dev/null
Binary files differ
diff --git a/crawl-ref/source/util/lua/doc/contents.html b/crawl-ref/source/util/lua/doc/contents.html
deleted file mode 100644
index 8e58e18ca9..0000000000
--- a/crawl-ref/source/util/lua/doc/contents.html
+++ /dev/null
@@ -1,499 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
-<HTML>
-<HEAD>
-<TITLE>Lua 5.1 Reference Manual - contents</TITLE>
-<LINK REL="stylesheet" TYPE="text/css" HREF="lua.css">
-<META HTTP-EQUIV="content-type" CONTENT="text/html; charset=iso-8859-1">
-<STYLE TYPE="text/css">
-ul {
- list-style-type: none ;
- list-style-position: outside ;
-}
-</STYLE>
-</HEAD>
-
-<BODY>
-
-<HR>
-<H1>
-<A HREF="http://www.lua.org/"><IMG SRC="logo.gif" ALT="" BORDER=0></A>
-Lua 5.1 Reference Manual
-</H1>
-
-This is an online version of
-<BLOCKQUOTE>
-<A HREF="http://www.amazon.com/exec/obidos/ASIN/8590379833/lua-indexmanual-20">
-<IMG SRC="cover.png" ALT="" TITLE="buy from Amazon" BORDER=1 ALIGN="left" HSPACE=12>
-</A>
-<B>Lua 5.1 Reference Manual</B>
-<BR>by R. Ierusalimschy, L. H. de Figueiredo, W. Celes
-<BR>Lua.org, August 2006
-<BR>ISBN 85-903798-3-3
-<BR><A HREF="http://www.amazon.com/exec/obidos/ASIN/8590379833/lua-indexmanual-20">
-<IMG SRC="amazon.gif" ALT="[Buy from Amazon]" BORDER=0></A>
-<BR CLEAR="all">
-</BLOCKQUOTE>
-<P>
-
-Buy a copy of this book and
-<A HREF="http://www.lua.org/donations.html">help to support</A>
-the Lua project.
-<P>
-
-The reference manual is the official definition of the Lua language.
-For a complete introduction to Lua programming, see the book
-<A HREF="http://www.lua.org/docs.html#books">Programming in Lua</A>.
-<P>
-
-<A HREF="manual.html">start</A>
-&middot;
-<A HREF="#contents">contents</A>
-&middot;
-<A HREF="#index">index</A>
-&middot;
-<A HREF="http://www.lua.org/manual/5.1/pt/">português</A>
-&middot;
-<A HREF="http://www.lua.org/manual/5.1/es/">español</A>
-<HR>
-<SMALL>
-Copyright &copy; 2006-2008 Lua.org, PUC-Rio.
-Freely available under the terms of the
-<a href="http://www.lua.org/license.html#5">Lua license</a>.
-</SMALL>
-<P>
-
-<H2><A NAME="contents">Contents</A></H2>
-<UL style="padding: 0">
-<LI><A HREF="manual.html">1 - Introduction</A>
-<P>
-<LI><A HREF="manual.html#2">2 - The Language</A>
-<UL>
-<LI><A HREF="manual.html#2.1">2.1 - Lexical Conventions</A>
-<LI><A HREF="manual.html#2.2">2.2 - Values and Types</A>
-<UL>
-<LI><A HREF="manual.html#2.2.1">2.2.1 - Coercion</A>
-</UL>
-<LI><A HREF="manual.html#2.3">2.3 - Variables</A>
-<LI><A HREF="manual.html#2.4">2.4 - Statements</A>
-<UL>
-<LI><A HREF="manual.html#2.4.1">2.4.1 - Chunks</A>
-<LI><A HREF="manual.html#2.4.2">2.4.2 - Blocks</A>
-<LI><A HREF="manual.html#2.4.3">2.4.3 - Assignment</A>
-<LI><A HREF="manual.html#2.4.4">2.4.4 - Control Structures</A>
-<LI><A HREF="manual.html#2.4.5">2.4.5 - For Statement</A>
-<LI><A HREF="manual.html#2.4.6">2.4.6 - Function Calls as Statements</A>
-<LI><A HREF="manual.html#2.4.7">2.4.7 - Local Declarations</A>
-</UL>
-<LI><A HREF="manual.html#2.5">2.5 - Expressions</A>
-<UL>
-<LI><A HREF="manual.html#2.5.1">2.5.1 - Arithmetic Operators</A>
-<LI><A HREF="manual.html#2.5.2">2.5.2 - Relational Operators</A>
-<LI><A HREF="manual.html#2.5.3">2.5.3 - Logical Operators</A>
-<LI><A HREF="manual.html#2.5.4">2.5.4 - Concatenation</A>
-<LI><A HREF="manual.html#2.5.5">2.5.5 - The Length Operator</A>
-<LI><A HREF="manual.html#2.5.6">2.5.6 - Precedence</A>
-<LI><A HREF="manual.html#2.5.7">2.5.7 - Table Constructors</A>
-<LI><A HREF="manual.html#2.5.8">2.5.8 - Function Calls</A>
-<LI><A HREF="manual.html#2.5.9">2.5.9 - Function Definitions</A>
-</UL>
-<LI><A HREF="manual.html#2.6">2.6 - Visibility Rules</A>
-<LI><A HREF="manual.html#2.7">2.7 - Error Handling</A>
-<LI><A HREF="manual.html#2.8">2.8 - Metatables</A>
-<LI><A HREF="manual.html#2.9">2.9 - Environments</A>
-<LI><A HREF="manual.html#2.10">2.10 - Garbage Collection</A>
-<UL>
-<LI><A HREF="manual.html#2.10.1">2.10.1 - Garbage-Collection Metamethods</A>
-<LI><A HREF="manual.html#2.10.2">2.10.2 - Weak Tables</A>
-</UL>
-<LI><A HREF="manual.html#2.11">2.11 - Coroutines</A>
-</UL>
-<P>
-<LI><A HREF="manual.html#3">3 - The Application Program Interface</A>
-<UL>
-<LI><A HREF="manual.html#3.1">3.1 - The Stack</A>
-<LI><A HREF="manual.html#3.2">3.2 - Stack Size</A>
-<LI><A HREF="manual.html#3.3">3.3 - Pseudo-Indices</A>
-<LI><A HREF="manual.html#3.4">3.4 - C Closures</A>
-<LI><A HREF="manual.html#3.5">3.5 - Registry</A>
-<LI><A HREF="manual.html#3.6">3.6 - Error Handling in C</A>
-<LI><A HREF="manual.html#3.7">3.7 - Functions and Types</A>
-<LI><A HREF="manual.html#3.8">3.8 - The Debug Interface</A>
-</UL>
-<P>
-<LI><A HREF="manual.html#4">4 - The Auxiliary Library</A>
-<UL>
-<LI><A HREF="manual.html#4.1">4.1 - Functions and Types</A>
-</UL>
-<P>
-<LI><A HREF="manual.html#5">5 - Standard Libraries</A>
-<UL>
-<LI><A HREF="manual.html#5.1">5.1 - Basic Functions</A>
-<LI><A HREF="manual.html#5.2">5.2 - Coroutine Manipulation</A>
-<LI><A HREF="manual.html#5.3">5.3 - Modules</A>
-<LI><A HREF="manual.html#5.4">5.4 - String Manipulation</A>
-<UL>
-<LI><A HREF="manual.html#5.4.1">5.4.1 - Patterns</A>
-</UL>
-<LI><A HREF="manual.html#5.5">5.5 - Table Manipulation</A>
-<LI><A HREF="manual.html#5.6">5.6 - Mathematical Functions</A>
-<LI><A HREF="manual.html#5.7">5.7 - Input and Output Facilities</A>
-<LI><A HREF="manual.html#5.8">5.8 - Operating System Facilities</A>
-<LI><A HREF="manual.html#5.9">5.9 - The Debug Library</A>
-</UL>
-<P>
-<LI><A HREF="manual.html#6">6 - Lua Stand-alone</A>
-<P>
-<LI><A HREF="manual.html#7">7 - Incompatibilities with the Previous Version</A>
-<UL>
-<LI><A HREF="manual.html#7.1">7.1 - Changes in the Language</A>
-<LI><A HREF="manual.html#7.2">7.2 - Changes in the Libraries</A>
-<LI><A HREF="manual.html#7.3">7.3 - Changes in the API</A>
-</UL>
-<P>
-<LI><A HREF="manual.html#8">8 - The Complete Syntax of Lua</A>
-</UL>
-
-<H2><A NAME="index">Index</A></H2>
-<TABLE WIDTH="100%">
-<TR VALIGN="top">
-<TD>
-<H3><A NAME="functions">Lua functions</A></H3>
-<A HREF="manual.html#pdf-_G">_G</A><BR>
-<A HREF="manual.html#pdf-_VERSION">_VERSION</A><BR>
-<A HREF="manual.html#pdf-assert">assert</A><BR>
-<A HREF="manual.html#pdf-collectgarbage">collectgarbage</A><BR>
-<A HREF="manual.html#pdf-dofile">dofile</A><BR>
-<A HREF="manual.html#pdf-error">error</A><BR>
-<A HREF="manual.html#pdf-getfenv">getfenv</A><BR>
-<A HREF="manual.html#pdf-getmetatable">getmetatable</A><BR>
-<A HREF="manual.html#pdf-ipairs">ipairs</A><BR>
-<A HREF="manual.html#pdf-load">load</A><BR>
-<A HREF="manual.html#pdf-loadfile">loadfile</A><BR>
-<A HREF="manual.html#pdf-loadstring">loadstring</A><BR>
-<A HREF="manual.html#pdf-module">module</A><BR>
-<A HREF="manual.html#pdf-next">next</A><BR>
-<A HREF="manual.html#pdf-pairs">pairs</A><BR>
-<A HREF="manual.html#pdf-pcall">pcall</A><BR>
-<A HREF="manual.html#pdf-print">print</A><BR>
-<A HREF="manual.html#pdf-rawequal">rawequal</A><BR>
-<A HREF="manual.html#pdf-rawget">rawget</A><BR>
-<A HREF="manual.html#pdf-rawset">rawset</A><BR>
-<A HREF="manual.html#pdf-require">require</A><BR>
-<A HREF="manual.html#pdf-select">select</A><BR>
-<A HREF="manual.html#pdf-setfenv">setfenv</A><BR>
-<A HREF="manual.html#pdf-setmetatable">setmetatable</A><BR>
-<A HREF="manual.html#pdf-tonumber">tonumber</A><BR>
-<A HREF="manual.html#pdf-tostring">tostring</A><BR>
-<A HREF="manual.html#pdf-type">type</A><BR>
-<A HREF="manual.html#pdf-unpack">unpack</A><BR>
-<A HREF="manual.html#pdf-xpcall">xpcall</A><BR>
-<P>
-
-<A HREF="manual.html#pdf-coroutine.create">coroutine.create</A><BR>
-<A HREF="manual.html#pdf-coroutine.resume">coroutine.resume</A><BR>
-<A HREF="manual.html#pdf-coroutine.running">coroutine.running</A><BR>
-<A HREF="manual.html#pdf-coroutine.status">coroutine.status</A><BR>
-<A HREF="manual.html#pdf-coroutine.wrap">coroutine.wrap</A><BR>
-<A HREF="manual.html#pdf-coroutine.yield">coroutine.yield</A><BR>
-<P>
-
-<A HREF="manual.html#pdf-debug.debug">debug.debug</A><BR>
-<A HREF="manual.html#pdf-debug.getfenv">debug.getfenv</A><BR>
-<A HREF="manual.html#pdf-debug.gethook">debug.gethook</A><BR>
-<A HREF="manual.html#pdf-debug.getinfo">debug.getinfo</A><BR>
-<A HREF="manual.html#pdf-debug.getlocal">debug.getlocal</A><BR>
-<A HREF="manual.html#pdf-debug.getmetatable">debug.getmetatable</A><BR>
-<A HREF="manual.html#pdf-debug.getregistry">debug.getregistry</A><BR>
-<A HREF="manual.html#pdf-debug.getupvalue">debug.getupvalue</A><BR>
-<A HREF="manual.html#pdf-debug.setfenv">debug.setfenv</A><BR>
-<A HREF="manual.html#pdf-debug.sethook">debug.sethook</A><BR>
-<A HREF="manual.html#pdf-debug.setlocal">debug.setlocal</A><BR>
-<A HREF="manual.html#pdf-debug.setmetatable">debug.setmetatable</A><BR>
-<A HREF="manual.html#pdf-debug.setupvalue">debug.setupvalue</A><BR>
-<A HREF="manual.html#pdf-debug.traceback">debug.traceback</A><BR>
-
-</TD>
-<TD>
-<H3>&nbsp;</H3>
-<A HREF="manual.html#pdf-file:close">file:close</A><BR>
-<A HREF="manual.html#pdf-file:flush">file:flush</A><BR>
-<A HREF="manual.html#pdf-file:lines">file:lines</A><BR>
-<A HREF="manual.html#pdf-file:read">file:read</A><BR>
-<A HREF="manual.html#pdf-file:seek">file:seek</A><BR>
-<A HREF="manual.html#pdf-file:setvbuf">file:setvbuf</A><BR>
-<A HREF="manual.html#pdf-file:write">file:write</A><BR>
-<P>
-
-<A HREF="manual.html#pdf-io.close">io.close</A><BR>
-<A HREF="manual.html#pdf-io.flush">io.flush</A><BR>
-<A HREF="manual.html#pdf-io.input">io.input</A><BR>
-<A HREF="manual.html#pdf-io.lines">io.lines</A><BR>
-<A HREF="manual.html#pdf-io.open">io.open</A><BR>
-<A HREF="manual.html#pdf-io.output">io.output</A><BR>
-<A HREF="manual.html#pdf-io.popen">io.popen</A><BR>
-<A HREF="manual.html#pdf-io.read">io.read</A><BR>
-<A HREF="manual.html#pdf-io.stderr">io.stderr</A><BR>
-<A HREF="manual.html#pdf-io.stdin">io.stdin</A><BR>
-<A HREF="manual.html#pdf-io.stdout">io.stdout</A><BR>
-<A HREF="manual.html#pdf-io.tmpfile">io.tmpfile</A><BR>
-<A HREF="manual.html#pdf-io.type">io.type</A><BR>
-<A HREF="manual.html#pdf-io.write">io.write</A><BR>
-<P>
-
-<A HREF="manual.html#pdf-math.abs">math.abs</A><BR>
-<A HREF="manual.html#pdf-math.acos">math.acos</A><BR>
-<A HREF="manual.html#pdf-math.asin">math.asin</A><BR>
-<A HREF="manual.html#pdf-math.atan">math.atan</A><BR>
-<A HREF="manual.html#pdf-math.atan2">math.atan2</A><BR>
-<A HREF="manual.html#pdf-math.ceil">math.ceil</A><BR>
-<A HREF="manual.html#pdf-math.cos">math.cos</A><BR>
-<A HREF="manual.html#pdf-math.cosh">math.cosh</A><BR>
-<A HREF="manual.html#pdf-math.deg">math.deg</A><BR>
-<A HREF="manual.html#pdf-math.exp">math.exp</A><BR>
-<A HREF="manual.html#pdf-math.floor">math.floor</A><BR>
-<A HREF="manual.html#pdf-math.fmod">math.fmod</A><BR>
-<A HREF="manual.html#pdf-math.frexp">math.frexp</A><BR>
-<A HREF="manual.html#pdf-math.huge">math.huge</A><BR>
-<A HREF="manual.html#pdf-math.ldexp">math.ldexp</A><BR>
-<A HREF="manual.html#pdf-math.log">math.log</A><BR>
-<A HREF="manual.html#pdf-math.log10">math.log10</A><BR>
-<A HREF="manual.html#pdf-math.max">math.max</A><BR>
-<A HREF="manual.html#pdf-math.min">math.min</A><BR>
-<A HREF="manual.html#pdf-math.modf">math.modf</A><BR>
-<A HREF="manual.html#pdf-math.pi">math.pi</A><BR>
-<A HREF="manual.html#pdf-math.pow">math.pow</A><BR>
-<A HREF="manual.html#pdf-math.rad">math.rad</A><BR>
-<A HREF="manual.html#pdf-math.random">math.random</A><BR>
-<A HREF="manual.html#pdf-math.randomseed">math.randomseed</A><BR>
-<A HREF="manual.html#pdf-math.sin">math.sin</A><BR>
-<A HREF="manual.html#pdf-math.sinh">math.sinh</A><BR>
-<A HREF="manual.html#pdf-math.sqrt">math.sqrt</A><BR>
-<A HREF="manual.html#pdf-math.tan">math.tan</A><BR>
-<A HREF="manual.html#pdf-math.tanh">math.tanh</A><BR>
-<P>
-
-<A HREF="manual.html#pdf-os.clock">os.clock</A><BR>
-<A HREF="manual.html#pdf-os.date">os.date</A><BR>
-<A HREF="manual.html#pdf-os.difftime">os.difftime</A><BR>
-<A HREF="manual.html#pdf-os.execute">os.execute</A><BR>
-<A HREF="manual.html#pdf-os.exit">os.exit</A><BR>
-<A HREF="manual.html#pdf-os.getenv">os.getenv</A><BR>
-<A HREF="manual.html#pdf-os.remove">os.remove</A><BR>
-<A HREF="manual.html#pdf-os.rename">os.rename</A><BR>
-<A HREF="manual.html#pdf-os.setlocale">os.setlocale</A><BR>
-<A HREF="manual.html#pdf-os.time">os.time</A><BR>
-<A HREF="manual.html#pdf-os.tmpname">os.tmpname</A><BR>
-<P>
-
-<A HREF="manual.html#pdf-package.cpath">package.cpath</A><BR>
-<A HREF="manual.html#pdf-package.loaded">package.loaded</A><BR>
-<A HREF="manual.html#pdf-package.loaders">package.loaders</A><BR>
-<A HREF="manual.html#pdf-package.loadlib">package.loadlib</A><BR>
-<A HREF="manual.html#pdf-package.path">package.path</A><BR>
-<A HREF="manual.html#pdf-package.preload">package.preload</A><BR>
-<A HREF="manual.html#pdf-package.seeall">package.seeall</A><BR>
-<P>
-
-<A HREF="manual.html#pdf-string.byte">string.byte</A><BR>
-<A HREF="manual.html#pdf-string.char">string.char</A><BR>
-<A HREF="manual.html#pdf-string.dump">string.dump</A><BR>
-<A HREF="manual.html#pdf-string.find">string.find</A><BR>
-<A HREF="manual.html#pdf-string.format">string.format</A><BR>
-<A HREF="manual.html#pdf-string.gmatch">string.gmatch</A><BR>
-<A HREF="manual.html#pdf-string.gsub">string.gsub</A><BR>
-<A HREF="manual.html#pdf-string.len">string.len</A><BR>
-<A HREF="manual.html#pdf-string.lower">string.lower</A><BR>
-<A HREF="manual.html#pdf-string.match">string.match</A><BR>
-<A HREF="manual.html#pdf-string.rep">string.rep</A><BR>
-<A HREF="manual.html#pdf-string.reverse">string.reverse</A><BR>
-<A HREF="manual.html#pdf-string.sub">string.sub</A><BR>
-<A HREF="manual.html#pdf-string.upper">string.upper</A><BR>
-<P>
-
-<A HREF="manual.html#pdf-table.concat">table.concat</A><BR>
-<A HREF="manual.html#pdf-table.insert">table.insert</A><BR>
-<A HREF="manual.html#pdf-table.maxn">table.maxn</A><BR>
-<A HREF="manual.html#pdf-table.remove">table.remove</A><BR>
-<A HREF="manual.html#pdf-table.sort">table.sort</A><BR>
-
-</TD>
-<TD>
-<H3>C API</H3>
-<A HREF="manual.html#lua_Alloc">lua_Alloc</A><BR>
-<A HREF="manual.html#lua_CFunction">lua_CFunction</A><BR>
-<A HREF="manual.html#lua_Debug">lua_Debug</A><BR>
-<A HREF="manual.html#lua_Hook">lua_Hook</A><BR>
-<A HREF="manual.html#lua_Integer">lua_Integer</A><BR>
-<A HREF="manual.html#lua_Number">lua_Number</A><BR>
-<A HREF="manual.html#lua_Reader">lua_Reader</A><BR>
-<A HREF="manual.html#lua_State">lua_State</A><BR>
-<A HREF="manual.html#lua_Writer">lua_Writer</A><BR>
-<P>
-
-<A HREF="manual.html#lua_atpanic">lua_atpanic</A><BR>
-<A HREF="manual.html#lua_call">lua_call</A><BR>
-<A HREF="manual.html#lua_checkstack">lua_checkstack</A><BR>
-<A HREF="manual.html#lua_close">lua_close</A><BR>
-<A HREF="manual.html#lua_concat">lua_concat</A><BR>
-<A HREF="manual.html#lua_cpcall">lua_cpcall</A><BR>
-<A HREF="manual.html#lua_createtable">lua_createtable</A><BR>
-<A HREF="manual.html#lua_dump">lua_dump</A><BR>
-<A HREF="manual.html#lua_equal">lua_equal</A><BR>
-<A HREF="manual.html#lua_error">lua_error</A><BR>
-<A HREF="manual.html#lua_gc">lua_gc</A><BR>
-<A HREF="manual.html#lua_getallocf">lua_getallocf</A><BR>
-<A HREF="manual.html#lua_getfenv">lua_getfenv</A><BR>
-<A HREF="manual.html#lua_getfield">lua_getfield</A><BR>
-<A HREF="manual.html#lua_getglobal">lua_getglobal</A><BR>
-<A HREF="manual.html#lua_gethook">lua_gethook</A><BR>
-<A HREF="manual.html#lua_gethookcount">lua_gethookcount</A><BR>
-<A HREF="manual.html#lua_gethookmask">lua_gethookmask</A><BR>
-<A HREF="manual.html#lua_getinfo">lua_getinfo</A><BR>
-<A HREF="manual.html#lua_getlocal">lua_getlocal</A><BR>
-<A HREF="manual.html#lua_getmetatable">lua_getmetatable</A><BR>
-<A HREF="manual.html#lua_getstack">lua_getstack</A><BR>
-<A HREF="manual.html#lua_gettable">lua_gettable</A><BR>
-<A HREF="manual.html#lua_gettop">lua_gettop</A><BR>
-<A HREF="manual.html#lua_getupvalue">lua_getupvalue</A><BR>
-<A HREF="manual.html#lua_insert">lua_insert</A><BR>
-<A HREF="manual.html#lua_isboolean">lua_isboolean</A><BR>
-<A HREF="manual.html#lua_iscfunction">lua_iscfunction</A><BR>
-<A HREF="manual.html#lua_isfunction">lua_isfunction</A><BR>
-<A HREF="manual.html#lua_islightuserdata">lua_islightuserdata</A><BR>
-<A HREF="manual.html#lua_isnil">lua_isnil</A><BR>
-<A HREF="manual.html#lua_isnone">lua_isnone</A><BR>
-<A HREF="manual.html#lua_isnoneornil">lua_isnoneornil</A><BR>
-<A HREF="manual.html#lua_isnumber">lua_isnumber</A><BR>
-<A HREF="manual.html#lua_isstring">lua_isstring</A><BR>
-<A HREF="manual.html#lua_istable">lua_istable</A><BR>
-<A HREF="manual.html#lua_isthread">lua_isthread</A><BR>
-<A HREF="manual.html#lua_isuserdata">lua_isuserdata</A><BR>
-<A HREF="manual.html#lua_lessthan">lua_lessthan</A><BR>
-<A HREF="manual.html#lua_load">lua_load</A><BR>
-<A HREF="manual.html#lua_newstate">lua_newstate</A><BR>
-<A HREF="manual.html#lua_newtable">lua_newtable</A><BR>
-<A HREF="manual.html#lua_newthread">lua_newthread</A><BR>
-<A HREF="manual.html#lua_newuserdata">lua_newuserdata</A><BR>
-<A HREF="manual.html#lua_next">lua_next</A><BR>
-<A HREF="manual.html#lua_objlen">lua_objlen</A><BR>
-<A HREF="manual.html#lua_pcall">lua_pcall</A><BR>
-<A HREF="manual.html#lua_pop">lua_pop</A><BR>
-<A HREF="manual.html#lua_pushboolean">lua_pushboolean</A><BR>
-<A HREF="manual.html#lua_pushcclosure">lua_pushcclosure</A><BR>
-<A HREF="manual.html#lua_pushcfunction">lua_pushcfunction</A><BR>
-<A HREF="manual.html#lua_pushfstring">lua_pushfstring</A><BR>
-<A HREF="manual.html#lua_pushinteger">lua_pushinteger</A><BR>
-<A HREF="manual.html#lua_pushlightuserdata">lua_pushlightuserdata</A><BR>
-<A HREF="manual.html#lua_pushliteral">lua_pushliteral</A><BR>
-<A HREF="manual.html#lua_pushlstring">lua_pushlstring</A><BR>
-<A HREF="manual.html#lua_pushnil">lua_pushnil</A><BR>
-<A HREF="manual.html#lua_pushnumber">lua_pushnumber</A><BR>
-<A HREF="manual.html#lua_pushstring">lua_pushstring</A><BR>
-<A HREF="manual.html#lua_pushthread">lua_pushthread</A><BR>
-<A HREF="manual.html#lua_pushvalue">lua_pushvalue</A><BR>
-<A HREF="manual.html#lua_pushvfstring">lua_pushvfstring</A><BR>
-<A HREF="manual.html#lua_rawequal">lua_rawequal</A><BR>
-<A HREF="manual.html#lua_rawget">lua_rawget</A><BR>
-<A HREF="manual.html#lua_rawgeti">lua_rawgeti</A><BR>
-<A HREF="manual.html#lua_rawset">lua_rawset</A><BR>
-<A HREF="manual.html#lua_rawseti">lua_rawseti</A><BR>
-<A HREF="manual.html#lua_register">lua_register</A><BR>
-<A HREF="manual.html#lua_remove">lua_remove</A><BR>
-<A HREF="manual.html#lua_replace">lua_replace</A><BR>
-<A HREF="manual.html#lua_resume">lua_resume</A><BR>
-<A HREF="manual.html#lua_setallocf">lua_setallocf</A><BR>
-<A HREF="manual.html#lua_setfenv">lua_setfenv</A><BR>
-<A HREF="manual.html#lua_setfield">lua_setfield</A><BR>
-<A HREF="manual.html#lua_setglobal">lua_setglobal</A><BR>
-<A HREF="manual.html#lua_sethook">lua_sethook</A><BR>
-<A HREF="manual.html#lua_setlocal">lua_setlocal</A><BR>
-<A HREF="manual.html#lua_setmetatable">lua_setmetatable</A><BR>
-<A HREF="manual.html#lua_settable">lua_settable</A><BR>
-<A HREF="manual.html#lua_settop">lua_settop</A><BR>
-<A HREF="manual.html#lua_setupvalue">lua_setupvalue</A><BR>
-<A HREF="manual.html#lua_status">lua_status</A><BR>
-<A HREF="manual.html#lua_toboolean">lua_toboolean</A><BR>
-<A HREF="manual.html#lua_tocfunction">lua_tocfunction</A><BR>
-<A HREF="manual.html#lua_tointeger">lua_tointeger</A><BR>
-<A HREF="manual.html#lua_tolstring">lua_tolstring</A><BR>
-<A HREF="manual.html#lua_tonumber">lua_tonumber</A><BR>
-<A HREF="manual.html#lua_topointer">lua_topointer</A><BR>
-<A HREF="manual.html#lua_tostring">lua_tostring</A><BR>
-<A HREF="manual.html#lua_tothread">lua_tothread</A><BR>
-<A HREF="manual.html#lua_touserdata">lua_touserdata</A><BR>
-<A HREF="manual.html#lua_type">lua_type</A><BR>
-<A HREF="manual.html#lua_typename">lua_typename</A><BR>
-<A HREF="manual.html#lua_upvalueindex">lua_upvalueindex</A><BR>
-<A HREF="manual.html#lua_xmove">lua_xmove</A><BR>
-<A HREF="manual.html#lua_yield">lua_yield</A><BR>
-
-</TD>
-<TD>
-<H3>auxiliary library</H3>
-<A HREF="manual.html#luaL_Buffer">luaL_Buffer</A><BR>
-<A HREF="manual.html#luaL_Reg">luaL_Reg</A><BR>
-<P>
-
-<A HREF="manual.html#luaL_addchar">luaL_addchar</A><BR>
-<A HREF="manual.html#luaL_addlstring">luaL_addlstring</A><BR>
-<A HREF="manual.html#luaL_addsize">luaL_addsize</A><BR>
-<A HREF="manual.html#luaL_addstring">luaL_addstring</A><BR>
-<A HREF="manual.html#luaL_addvalue">luaL_addvalue</A><BR>
-<A HREF="manual.html#luaL_argcheck">luaL_argcheck</A><BR>
-<A HREF="manual.html#luaL_argerror">luaL_argerror</A><BR>
-<A HREF="manual.html#luaL_buffinit">luaL_buffinit</A><BR>
-<A HREF="manual.html#luaL_callmeta">luaL_callmeta</A><BR>
-<A HREF="manual.html#luaL_checkany">luaL_checkany</A><BR>
-<A HREF="manual.html#luaL_checkint">luaL_checkint</A><BR>
-<A HREF="manual.html#luaL_checkinteger">luaL_checkinteger</A><BR>
-<A HREF="manual.html#luaL_checklong">luaL_checklong</A><BR>
-<A HREF="manual.html#luaL_checklstring">luaL_checklstring</A><BR>
-<A HREF="manual.html#luaL_checknumber">luaL_checknumber</A><BR>
-<A HREF="manual.html#luaL_checkoption">luaL_checkoption</A><BR>
-<A HREF="manual.html#luaL_checkstack">luaL_checkstack</A><BR>
-<A HREF="manual.html#luaL_checkstring">luaL_checkstring</A><BR>
-<A HREF="manual.html#luaL_checktype">luaL_checktype</A><BR>
-<A HREF="manual.html#luaL_checkudata">luaL_checkudata</A><BR>
-<A HREF="manual.html#luaL_dofile">luaL_dofile</A><BR>
-<A HREF="manual.html#luaL_dostring">luaL_dostring</A><BR>
-<A HREF="manual.html#luaL_error">luaL_error</A><BR>
-<A HREF="manual.html#luaL_getmetafield">luaL_getmetafield</A><BR>
-<A HREF="manual.html#luaL_getmetatable">luaL_getmetatable</A><BR>
-<A HREF="manual.html#luaL_gsub">luaL_gsub</A><BR>
-<A HREF="manual.html#luaL_loadbuffer">luaL_loadbuffer</A><BR>
-<A HREF="manual.html#luaL_loadfile">luaL_loadfile</A><BR>
-<A HREF="manual.html#luaL_loadstring">luaL_loadstring</A><BR>
-<A HREF="manual.html#luaL_newmetatable">luaL_newmetatable</A><BR>
-<A HREF="manual.html#luaL_newstate">luaL_newstate</A><BR>
-<A HREF="manual.html#luaL_openlibs">luaL_openlibs</A><BR>
-<A HREF="manual.html#luaL_optint">luaL_optint</A><BR>
-<A HREF="manual.html#luaL_optinteger">luaL_optinteger</A><BR>
-<A HREF="manual.html#luaL_optlong">luaL_optlong</A><BR>
-<A HREF="manual.html#luaL_optlstring">luaL_optlstring</A><BR>
-<A HREF="manual.html#luaL_optnumber">luaL_optnumber</A><BR>
-<A HREF="manual.html#luaL_optstring">luaL_optstring</A><BR>
-<A HREF="manual.html#luaL_prepbuffer">luaL_prepbuffer</A><BR>
-<A HREF="manual.html#luaL_pushresult">luaL_pushresult</A><BR>
-<A HREF="manual.html#luaL_ref">luaL_ref</A><BR>
-<A HREF="manual.html#luaL_register">luaL_register</A><BR>
-<A HREF="manual.html#luaL_typename">luaL_typename</A><BR>
-<A HREF="manual.html#luaL_typerror">luaL_typerror</A><BR>
-<A HREF="manual.html#luaL_unref">luaL_unref</A><BR>
-<A HREF="manual.html#luaL_where">luaL_where</A><BR>
-
-</TD>
-</TR>
-</TABLE>
-<P>
-
-<HR>
-<SMALL>
-Last update:
-Sat Jan 19 13:24:29 BRST 2008
-</SMALL>
-<!--
-Last change: revised for Lua 5.1.3
--->
-
-</BODY>
-</HTML>
diff --git a/crawl-ref/source/util/lua/doc/cover.png b/crawl-ref/source/util/lua/doc/cover.png
deleted file mode 100644
index 2dbb198123..0000000000
--- a/crawl-ref/source/util/lua/doc/cover.png
+++ /dev/null
Binary files differ
diff --git a/crawl-ref/source/util/lua/doc/logo.gif b/crawl-ref/source/util/lua/doc/logo.gif
deleted file mode 100644
index 2f5e4ac2e7..0000000000
--- a/crawl-ref/source/util/lua/doc/logo.gif
+++ /dev/null
Binary files differ
diff --git a/crawl-ref/source/util/lua/doc/lua.1 b/crawl-ref/source/util/lua/doc/lua.1
deleted file mode 100644
index 24809cc6c1..0000000000
--- a/crawl-ref/source/util/lua/doc/lua.1
+++ /dev/null
@@ -1,163 +0,0 @@
-.\" $Id: lua.man,v 1.11 2006/01/06 16:03:34 lhf Exp $
-.TH LUA 1 "$Date: 2006/01/06 16:03:34 $"
-.SH NAME
-lua \- Lua interpreter
-.SH SYNOPSIS
-.B lua
-[
-.I options
-]
-[
-.I script
-[
-.I args
-]
-]
-.SH DESCRIPTION
-.B lua
-is the stand-alone Lua interpreter.
-It loads and executes Lua programs,
-either in textual source form or
-in precompiled binary form.
-(Precompiled binaries are output by
-.BR luac ,
-the Lua compiler.)
-.B lua
-can be used as a batch interpreter and also interactively.
-.LP
-The given
-.I options
-(see below)
-are executed and then
-the Lua program in file
-.I script
-is loaded and executed.
-The given
-.I args
-are available to
-.I script
-as strings in a global table named
-.BR arg .
-If these arguments contain spaces or other characters special to the shell,
-then they should be quoted
-(but note that the quotes will be removed by the shell).
-The arguments in
-.B arg
-start at 0,
-which contains the string
-.RI ' script '.
-The index of the last argument is stored in
-.BR arg.n .
-The arguments given in the command line before
-.IR script ,
-including the name of the interpreter,
-are available in negative indices in
-.BR arg .
-.LP
-At the very start,
-before even handling the command line,
-.B lua
-executes the contents of the environment variable
-.BR LUA_INIT ,
-if it is defined.
-If the value of
-.B LUA_INIT
-is of the form
-.RI '@ filename ',
-then
-.I filename
-is executed.
-Otherwise, the string is assumed to be a Lua statement and is executed.
-.LP
-Options start with
-.B '\-'
-and are described below.
-You can use
-.B "'\--'"
-to signal the end of options.
-.LP
-If no arguments are given,
-then
-.B "\-v \-i"
-is assumed when the standard input is a terminal;
-otherwise,
-.B "\-"
-is assumed.
-.LP
-In interactive mode,
-.B lua
-prompts the user,
-reads lines from the standard input,
-and executes them as they are read.
-If a line does not contain a complete statement,
-then a secondary prompt is displayed and
-lines are read until a complete statement is formed or
-a syntax error is found.
-So, one way to interrupt the reading of an incomplete statement is
-to force a syntax error:
-adding a
-.B ';'
-in the middle of a statement is a sure way of forcing a syntax error
-(except inside multiline strings and comments; these must be closed explicitly).
-If a line starts with
-.BR '=' ,
-then
-.B lua
-displays the values of all the expressions in the remainder of the
-line. The expressions must be separated by commas.
-The primary prompt is the value of the global variable
-.BR _PROMPT ,
-if this value is a string;
-otherwise, the default prompt is used.
-Similarly, the secondary prompt is the value of the global variable
-.BR _PROMPT2 .
-So,
-to change the prompts,
-set the corresponding variable to a string of your choice.
-You can do that after calling the interpreter
-or on the command line
-(but in this case you have to be careful with quotes
-if the prompt string contains a space; otherwise you may confuse the shell.)
-The default prompts are "> " and ">> ".
-.SH OPTIONS
-.TP
-.B \-
-load and execute the standard input as a file,
-that is,
-not interactively,
-even when the standard input is a terminal.
-.TP
-.BI \-e " stat"
-execute statement
-.IR stat .
-You need to quote
-.I stat
-if it contains spaces, quotes,
-or other characters special to the shell.
-.TP
-.B \-i
-enter interactive mode after
-.I script
-is executed.
-.TP
-.BI \-l " name"
-call
-.BI require(' name ')
-before executing
-.IR script .
-Typically used to load libraries.
-.TP
-.B \-v
-show version information.
-.SH "SEE ALSO"
-.BR luac (1)
-.br
-http://www.lua.org/
-.SH DIAGNOSTICS
-Error messages should be self explanatory.
-.SH AUTHORS
-R. Ierusalimschy,
-L. H. de Figueiredo,
-and
-W. Celes
-.\" EOF
diff --git a/crawl-ref/source/util/lua/doc/lua.css b/crawl-ref/source/util/lua/doc/lua.css
deleted file mode 100644
index 039cf11698..0000000000
--- a/crawl-ref/source/util/lua/doc/lua.css
+++ /dev/null
@@ -1,41 +0,0 @@
-body {
- color: #000000 ;
- background-color: #FFFFFF ;
- font-family: sans-serif ;
- text-align: justify ;
- margin-right: 20px ;
- margin-left: 20px ;
-}
-
-h1, h2, h3, h4 {
- font-weight: normal ;
- font-style: italic ;
-}
-
-a:link {
- color: #000080 ;
- background-color: inherit ;
- text-decoration: none ;
-}
-
-a:visited {
- background-color: inherit ;
- text-decoration: none ;
-}
-
-a:link:hover, a:visited:hover {
- color: #000080 ;
- background-color: #E0E0FF ;
-}
-
-a:link:active, a:visited:active {
- color: #FF0000 ;
-}
-
-hr {
- border: 0 ;
- height: 1px ;
- color: #a0a0a0 ;
- background-color: #a0a0a0 ;
-}
-
diff --git a/crawl-ref/source/util/lua/doc/lua.html b/crawl-ref/source/util/lua/doc/lua.html
deleted file mode 100644
index 1d435ab029..0000000000
--- a/crawl-ref/source/util/lua/doc/lua.html
+++ /dev/null
@@ -1,172 +0,0 @@
-<!-- $Id: lua.man,v 1.11 2006/01/06 16:03:34 lhf Exp $ -->
-<HTML>
-<HEAD>
-<TITLE>LUA man page</TITLE>
-<LINK REL="stylesheet" TYPE="text/css" HREF="lua.css">
-</HEAD>
-
-<BODY BGCOLOR="#FFFFFF">
-
-<H2>NAME</H2>
-lua - Lua interpreter
-<H2>SYNOPSIS</H2>
-<B>lua</B>
-[
-<I>options</I>
-]
-[
-<I>script</I>
-[
-<I>args</I>
-]
-]
-<H2>DESCRIPTION</H2>
-<B>lua</B>
-is the stand-alone Lua interpreter.
-It loads and executes Lua programs,
-either in textual source form or
-in precompiled binary form.
-(Precompiled binaries are output by
-<B>luac</B>,
-the Lua compiler.)
-<B>lua</B>
-can be used as a batch interpreter and also interactively.
-<P>
-The given
-<I>options</I>
-(see below)
-are executed and then
-the Lua program in file
-<I>script</I>
-is loaded and executed.
-The given
-<I>args</I>
-are available to
-<I>script</I>
-as strings in a global table named
-<B>arg</B>.
-If these arguments contain spaces or other characters special to the shell,
-then they should be quoted
-(but note that the quotes will be removed by the shell).
-The arguments in
-<B>arg</B>
-start at 0,
-which contains the string
-'<I>script</I>'.
-The index of the last argument is stored in
-<B>arg.n</B>.
-The arguments given in the command line before
-<I>script</I>,
-including the name of the interpreter,
-are available in negative indices in
-<B>arg</B>.
-<P>
-At the very start,
-before even handling the command line,
-<B>lua</B>
-executes the contents of the environment variable
-<B>LUA_INIT</B>,
-if it is defined.
-If the value of
-<B>LUA_INIT</B>
-is of the form
-'@<I>filename</I>',
-then
-<I>filename</I>
-is executed.
-Otherwise, the string is assumed to be a Lua statement and is executed.
-<P>
-Options start with
-<B>'-'</B>
-and are described below.
-You can use
-<B>'--'</B>
-to signal the end of options.
-<P>
-If no arguments are given,
-then
-<B>"-v -i"</B>
-is assumed when the standard input is a terminal;
-otherwise,
-<B>"-"</B>
-is assumed.
-<P>
-In interactive mode,
-<B>lua</B>
-prompts the user,
-reads lines from the standard input,
-and executes them as they are read.
-If a line does not contain a complete statement,
-then a secondary prompt is displayed and
-lines are read until a complete statement is formed or
-a syntax error is found.
-So, one way to interrupt the reading of an incomplete statement is
-to force a syntax error:
-adding a
-<B>';'</B>
-in the middle of a statement is a sure way of forcing a syntax error
-(except inside multiline strings and comments; these must be closed explicitly).
-If a line starts with
-<B>'='</B>,
-then
-<B>lua</B>
-displays the values of all the expressions in the remainder of the
-line. The expressions must be separated by commas.
-The primary prompt is the value of the global variable
-<B>_PROMPT</B>,
-if this value is a string;
-otherwise, the default prompt is used.
-Similarly, the secondary prompt is the value of the global variable
-<B>_PROMPT2</B>.
-So,
-to change the prompts,
-set the corresponding variable to a string of your choice.
-You can do that after calling the interpreter
-or on the command line
-(but in this case you have to be careful with quotes
-if the prompt string contains a space; otherwise you may confuse the shell.)
-The default prompts are "&gt; " and "&gt;&gt; ".
-<H2>OPTIONS</H2>
-<P>
-<B>-</B>
-load and execute the standard input as a file,
-that is,
-not interactively,
-even when the standard input is a terminal.
-<P>
-<B>-e </B><I>stat</I>
-execute statement
-<I>stat</I>.
-You need to quote
-<I>stat </I>
-if it contains spaces, quotes,
-or other characters special to the shell.
-<P>
-<B>-i</B>
-enter interactive mode after
-<I>script</I>
-is executed.
-<P>
-<B>-l </B><I>name</I>
-call
-<B>require</B>('<I>name</I>')
-before executing
-<I>script</I>.
-Typically used to load libraries.
-<P>
-<B>-v</B>
-show version information.
-<H2>SEE ALSO</H2>
-<B>luac</B>(1)
-<BR>
-<A HREF="http://www.lua.org/">http://www.lua.org/</A>
-<H2>DIAGNOSTICS</H2>
-Error messages should be self explanatory.
-<H2>AUTHORS</H2>
-R. Ierusalimschy,
-L. H. de Figueiredo,
-and
-W. Celes
-<!-- EOF -->
-</BODY>
-</HTML>
diff --git a/crawl-ref/source/util/lua/doc/luac.1 b/crawl-ref/source/util/lua/doc/luac.1
deleted file mode 100644
index d8146782df..0000000000
--- a/crawl-ref/source/util/lua/doc/luac.1
+++ /dev/null
@@ -1,136 +0,0 @@
-.\" $Id: luac.man,v 1.28 2006/01/06 16:03:34 lhf Exp $
-.TH LUAC 1 "$Date: 2006/01/06 16:03:34 $"
-.SH NAME
-luac \- Lua compiler
-.SH SYNOPSIS
-.B luac
-[
-.I options
-] [
-.I filenames
-]
-.SH DESCRIPTION
-.B luac
-is the Lua compiler.
-It translates programs written in the Lua programming language
-into binary files that can be later loaded and executed.
-.LP
-The main advantages of precompiling chunks are:
-faster loading,
-protecting source code from accidental user changes,
-and
-off-line syntax checking.
-.LP
-Pre-compiling does not imply faster execution
-because in Lua chunks are always compiled into bytecodes before being executed.
-.B luac
-simply allows those bytecodes to be saved in a file for later execution.
-.LP
-Pre-compiled chunks are not necessarily smaller than the corresponding source.
-The main goal in pre-compiling is faster loading.
-.LP
-The binary files created by
-.B luac
-are portable only among architectures with the same word size and byte order.
-.LP
-.B luac
-produces a single output file containing the bytecodes
-for all source files given.
-By default,
-the output file is named
-.BR luac.out ,
-but you can change this with the
-.B \-o
-option.
-.LP
-In the command line,
-you can mix
-text files containing Lua source and
-binary files containing precompiled chunks.
-This is useful to combine several precompiled chunks,
-even from different (but compatible) platforms,
-into a single precompiled chunk.
-.LP
-You can use
-.B "'\-'"
-to indicate the standard input as a source file
-and
-.B "'\--'"
-to signal the end of options
-(that is,
-all remaining arguments will be treated as files even if they start with
-.BR "'\-'" ).
-.LP
-The internal format of the binary files produced by
-.B luac
-is likely to change when a new version of Lua is released.
-So,
-save the source files of all Lua programs that you precompile.
-.LP
-.SH OPTIONS
-Options must be separate.
-.TP
-.B \-l
-produce a listing of the compiled bytecode for Lua's virtual machine.
-Listing bytecodes is useful to learn about Lua's virtual machine.
-If no files are given, then
-.B luac
-loads
-.B luac.out
-and lists its contents.
-.TP
-.BI \-o " file"
-output to
-.IR file ,
-instead of the default
-.BR luac.out .
-(You can use
-.B "'\-'"
-for standard output,
-but not on platforms that open standard output in text mode.)
-The output file may be a source file because
-all files are loaded before the output file is written.
-Be careful not to overwrite precious files.
-.TP
-.B \-p
-load files but do not generate any output file.
-Used mainly for syntax checking and for testing precompiled chunks:
-corrupted files will probably generate errors when loaded.
-Lua always performs a thorough integrity test on precompiled chunks.
-Bytecode that passes this test is completely safe,
-in the sense that it will not break the interpreter.
-However,
-there is no guarantee that such code does anything sensible.
-(None can be given, because the halting problem is unsolvable.)
-If no files are given, then
-.B luac
-loads
-.B luac.out
-and tests its contents.
-No messages are displayed if the file passes the integrity test.
-.TP
-.B \-s
-strip debug information before writing the output file.
-This saves some space in very large chunks,
-but if errors occur when running a stripped chunk,
-then the error messages may not contain the full information they usually do.
-For instance,
-line numbers and names of local variables are lost.
-.TP
-.B \-v
-show version information.
-.SH FILES
-.TP 15
-.B luac.out
-default output file
-.SH "SEE ALSO"
-.BR lua (1)
-.br
-http://www.lua.org/
-.SH DIAGNOSTICS
-Error messages should be self explanatory.
-.SH AUTHORS
-L. H. de Figueiredo,
-R. Ierusalimschy and
-W. Celes
-.\" EOF
diff --git a/crawl-ref/source/util/lua/doc/luac.html b/crawl-ref/source/util/lua/doc/luac.html
deleted file mode 100644
index 179ffe8288..0000000000
--- a/crawl-ref/source/util/lua/doc/luac.html
+++ /dev/null
@@ -1,145 +0,0 @@
-<!-- $Id: luac.man,v 1.28 2006/01/06 16:03:34 lhf Exp $ -->
-<HTML>
-<HEAD>
-<TITLE>LUAC man page</TITLE>
-<LINK REL="stylesheet" TYPE="text/css" HREF="lua.css">
-</HEAD>
-
-<BODY BGCOLOR="#FFFFFF">
-
-<H2>NAME</H2>
-luac - Lua compiler
-<H2>SYNOPSIS</H2>
-<B>luac</B>
-[
-<I>options</I>
-] [
-<I>filenames</I>
-]
-<H2>DESCRIPTION</H2>
-<B>luac</B>
-is the Lua compiler.
-It translates programs written in the Lua programming language
-into binary files that can be later loaded and executed.
-<P>
-The main advantages of precompiling chunks are:
-faster loading,
-protecting source code from accidental user changes,
-and
-off-line syntax checking.
-<P>
-Precompiling does not imply faster execution
-because in Lua chunks are always compiled into bytecodes before being executed.
-<B>luac</B>
-simply allows those bytecodes to be saved in a file for later execution.
-<P>
-Precompiled chunks are not necessarily smaller than the corresponding source.
-The main goal in precompiling is faster loading.
-<P>
-The binary files created by
-<B>luac</B>
-are portable only among architectures with the same word size and byte order.
-<P>
-<B>luac</B>
-produces a single output file containing the bytecodes
-for all source files given.
-By default,
-the output file is named
-<B>luac.out</B>,
-but you can change this with the
-<B>-o</B>
-option.
-<P>
-In the command line,
-you can mix
-text files containing Lua source and
-binary files containing precompiled chunks.
-This is useful because several precompiled chunks,
-even from different (but compatible) platforms,
-can be combined into a single precompiled chunk.
-<P>
-You can use
-<B>'-'</B>
-to indicate the standard input as a source file
-and
-<B>'--'</B>
-to signal the end of options
-(that is,
-all remaining arguments will be treated as files even if they start with
-<B>'-'</B>).
-<P>
-The internal format of the binary files produced by
-<B>luac</B>
-is likely to change when a new version of Lua is released.
-So,
-save the source files of all Lua programs that you precompile.
-<P>
-<H2>OPTIONS</H2>
-Options must be separate.
-<P>
-<B>-l</B>
-produce a listing of the compiled bytecode for Lua's virtual machine.
-Listing bytecodes is useful to learn about Lua's virtual machine.
-If no files are given, then
-<B>luac</B>
-loads
-<B>luac.out</B>
-and lists its contents.
-<P>
-<B>-o </B><I>file</I>
-output to
-<I>file</I>,
-instead of the default
-<B>luac.out</B>.
-(You can use
-<B>'-'</B>
-for standard output,
-but not on platforms that open standard output in text mode.)
-The output file may be a source file because
-all files are loaded before the output file is written.
-Be careful not to overwrite precious files.
-<P>
-<B>-p</B>
-load files but do not generate any output file.
-Used mainly for syntax checking and for testing precompiled chunks:
-corrupted files will probably generate errors when loaded.
-Lua always performs a thorough integrity test on precompiled chunks.
-Bytecode that passes this test is completely safe,
-in the sense that it will not break the interpreter.
-However,
-there is no guarantee that such code does anything sensible.
-(None can be given, because the halting problem is unsolvable.)
-If no files are given, then
-<B>luac</B>
-loads
-<B>luac.out</B>
-and tests its contents.
-No messages are displayed if the file passes the integrity test.
-<P>
-<B>-s</B>
-strip debug information before writing the output file.
-This saves some space in very large chunks,
-but if errors occur when running a stripped chunk,
-then the error messages may not contain the full information they usually do.
-For instance,
-line numbers and names of local variables are lost.
-<P>
-<B>-v</B>
-show version information.
-<H2>FILES</H2>
-<P>
-<B>luac.out</B>
-default output file
-<H2>SEE ALSO</H2>
-<B>lua</B>(1)
-<BR>
-<A HREF="http://www.lua.org/">http://www.lua.org/</A>
-<H2>DIAGNOSTICS</H2>
-Error messages should be self explanatory.
-<H2>AUTHORS</H2>
-L. H. de Figueiredo,
-R. Ierusalimschy and
-W. Celes
-<!-- EOF -->
-</BODY>
-</HTML>
diff --git a/crawl-ref/source/util/lua/doc/manual.css b/crawl-ref/source/util/lua/doc/manual.css
deleted file mode 100644
index eed5afd9ee..0000000000
--- a/crawl-ref/source/util/lua/doc/manual.css
+++ /dev/null
@@ -1,13 +0,0 @@
-h3 code {
- font-family: inherit ;
-}
-
-pre {
- font-size: 105% ;
-}
-
-span.apii {
- float: right ;
- font-family: inherit ;
-}
-
diff --git a/crawl-ref/source/util/lua/doc/manual.html b/crawl-ref/source/util/lua/doc/manual.html
deleted file mode 100644
index f46f17c8ec..0000000000
--- a/crawl-ref/source/util/lua/doc/manual.html
+++ /dev/null
@@ -1,8801 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
-<html>
-
-<head>
-<title>Lua 5.1 Reference Manual</title>
-<link rel="stylesheet" type="text/css" href="lua.css">
-<link rel="stylesheet" type="text/css" href="manual.css">
-<META HTTP-EQUIV="content-type" CONTENT="text/html; charset=iso-8859-1">
-</head>
-
-<body>
-
-<hr>
-<h1>
-<a href="http://www.lua.org/"><img src="logo.gif" alt="" border="0"></a>
-Lua 5.1 Reference Manual
-</h1>
-
-by Roberto Ierusalimschy, Luiz Henrique de Figueiredo, Waldemar Celes
-<p>
-<small>
-Copyright &copy; 2006-2008 Lua.org, PUC-Rio.
-Freely available under the terms of the
-<a href="http://www.lua.org/license.html#5">Lua license</a>.
-</small>
-<hr>
-<p>
-
-<a href="contents.html#contents">contents</A>
-&middot;
-<a href="contents.html#index">index</A>
-
-<!-- ====================================================================== -->
-<p>
-
-<!-- $Id: manual.of,v 1.48 2008/08/18 15:24:20 roberto Exp $ -->
-
-
-
-
-<h1>1 - <a name="1">Introduction</a></h1>
-
-<p>
-Lua is an extension programming language designed to support
-general procedural programming with data description
-facilities.
-It also offers good support for object-oriented programming,
-functional programming, and data-driven programming.
-Lua is intended to be used as a powerful, light-weight
-scripting language for any program that needs one.
-Lua is implemented as a library, written in <em>clean</em> C
-(that is, in the common subset of ANSI&nbsp;C and C++).
-
-
-<p>
-Being an extension language, Lua has no notion of a "main" program:
-it only works <em>embedded</em> in a host client,
-called the <em>embedding program</em> or simply the <em>host</em>.
-This host program can invoke functions to execute a piece of Lua code,
-can write and read Lua variables,
-and can register C&nbsp;functions to be called by Lua code.
-Through the use of C&nbsp;functions, Lua can be augmented to cope with
-a wide range of different domains,
-thus creating customized programming languages sharing a syntactical framework.
-The Lua distribution includes a sample host program called <code>lua</code>,
-which uses the Lua library to offer a complete, stand-alone Lua interpreter.
-
-
-<p>
-Lua is free software,
-and is provided as usual with no guarantees,
-as stated in its license.
-The implementation described in this manual is available
-at Lua's official web site, <code>www.lua.org</code>.
-
-
-<p>
-Like any other reference manual,
-this document is dry in places.
-For a discussion of the decisions behind the design of Lua,
-see the technical papers available at Lua's web site.
-For a detailed introduction to programming in Lua,
-see Roberto's book, <em>Programming in Lua (Second Edition)</em>.
-
-
-
-<h1>2 - <a name="2">The Language</a></h1>
-
-<p>
-This section describes the lexis, the syntax, and the semantics of Lua.
-In other words,
-this section describes
-which tokens are valid,
-how they can be combined,
-and what their combinations mean.
-
-
-<p>
-The language constructs will be explained using the usual extended BNF notation,
-in which
-{<em>a</em>}&nbsp;means&nbsp;0 or more <em>a</em>'s, and
-[<em>a</em>]&nbsp;means an optional <em>a</em>.
-Non-terminals are shown like non-terminal,
-keywords are shown like <b>kword</b>,
-and other terminal symbols are shown like `<b>=</b>&acute;.
-The complete syntax of Lua can be found in <a href="#8">&sect;8</a>
-at the end of this manual.
-
-
-
-<h2>2.1 - <a name="2.1">Lexical Conventions</a></h2>
-
-<p>
-<em>Names</em>
-(also called <em>identifiers</em>)
-in Lua can be any string of letters,
-digits, and underscores,
-not beginning with a digit.
-This coincides with the definition of names in most languages.
-(The definition of letter depends on the current locale:
-any character considered alphabetic by the current locale
-can be used in an identifier.)
-Identifiers are used to name variables and table fields.
-
-
-<p>
-The following <em>keywords</em> are reserved
-and cannot be used as names:
-
-
-<pre>
- and break do else elseif
- end false for function if
- in local nil not or
- repeat return then true until while
-</pre>
-
-<p>
-Lua is a case-sensitive language:
-<code>and</code> is a reserved word, but <code>And</code> and <code>AND</code>
-are two different, valid names.
-As a convention, names starting with an underscore followed by
-uppercase letters (such as <a href="#pdf-_VERSION"><code>_VERSION</code></a>)
-are reserved for internal global variables used by Lua.
-
-
-<p>
-The following strings denote other tokens:
-
-<pre>
- + - * / % ^ #
- == ~= &lt;= &gt;= &lt; &gt; =
- ( ) { } [ ]
- ; : , . .. ...
-</pre>
-
-<p>
-<em>Literal strings</em>
-can be delimited by matching single or double quotes,
-and can contain the following C-like escape sequences:
-'<code>\a</code>' (bell),
-'<code>\b</code>' (backspace),
-'<code>\f</code>' (form feed),
-'<code>\n</code>' (newline),
-'<code>\r</code>' (carriage return),
-'<code>\t</code>' (horizontal tab),
-'<code>\v</code>' (vertical tab),
-'<code>\\</code>' (backslash),
-'<code>\"</code>' (quotation mark [double quote]),
-and '<code>\'</code>' (apostrophe [single quote]).
-Moreover, a backslash followed by a real newline
-results in a newline in the string.
-A character in a string can also be specified by its numerical value
-using the escape sequence <code>\<em>ddd</em></code>,
-where <em>ddd</em> is a sequence of up to three decimal digits.
-(Note that if a numerical escape is to be followed by a digit,
-it must be expressed using exactly three digits.)
-Strings in Lua can contain any 8-bit value, including embedded zeros,
-which can be specified as '<code>\0</code>'.
-
-
-<p>
-Literal strings can also be defined using a long format
-enclosed by <em>long brackets</em>.
-We define an <em>opening long bracket of level <em>n</em></em> as an opening
-square bracket followed by <em>n</em> equal signs followed by another
-opening square bracket.
-So, an opening long bracket of level&nbsp;0 is written as <code>[[</code>,
-an opening long bracket of level&nbsp;1 is written as <code>[=[</code>,
-and so on.
-A <em>closing long bracket</em> is defined similarly;
-for instance, a closing long bracket of level&nbsp;4 is written as <code>]====]</code>.
-A long string starts with an opening long bracket of any level and
-ends at the first closing long bracket of the same level.
-Literals in this bracketed form can run for several lines,
-do not interpret any escape sequences,
-and ignore long brackets of any other level.
-They can contain anything except a closing bracket of the proper level.
-
-
-<p>
-For convenience,
-when the opening long bracket is immediately followed by a newline,
-the newline is not included in the string.
-As an example, in a system using ASCII
-(in which '<code>a</code>' is coded as&nbsp;97,
-newline is coded as&nbsp;10, and '<code>1</code>' is coded as&nbsp;49),
-the five literal strings below denote the same string:
-
-<pre>
- a = 'alo\n123"'
- a = "alo\n123\""
- a = '\97lo\10\04923"'
- a = [[alo
- 123"]]
- a = [==[
- alo
- 123"]==]
-</pre>
-
-<p>
-A <em>numerical constant</em> can be written with an optional decimal part
-and an optional decimal exponent.
-Lua also accepts integer hexadecimal constants,
-by prefixing them with <code>0x</code>.
-Examples of valid numerical constants are
-
-<pre>
- 3 3.0 3.1416 314.16e-2 0.31416E1 0xff 0x56
-</pre>
-
-<p>
-A <em>comment</em> starts with a double hyphen (<code>--</code>)
-anywhere outside a string.
-If the text immediately after <code>--</code> is not an opening long bracket,
-the comment is a <em>short comment</em>,
-which runs until the end of the line.
-Otherwise, it is a <em>long comment</em>,
-which runs until the corresponding closing long bracket.
-Long comments are frequently used to disable code temporarily.
-
-
-
-
-
-<h2>2.2 - <a name="2.2">Values and Types</a></h2>
-
-<p>
-Lua is a <em>dynamically typed language</em>.
-This means that
-variables do not have types; only values do.
-There are no type definitions in the language.
-All values carry their own type.
-
-
-<p>
-All values in Lua are <em>first-class values</em>.
-This means that all values can be stored in variables,
-passed as arguments to other functions, and returned as results.
-
-
-<p>
-There are eight basic types in Lua:
-<em>nil</em>, <em>boolean</em>, <em>number</em>,
-<em>string</em>, <em>function</em>, <em>userdata</em>,
-<em>thread</em>, and <em>table</em>.
-<em>Nil</em> is the type of the value <b>nil</b>,
-whose main property is to be different from any other value;
-it usually represents the absence of a useful value.
-<em>Boolean</em> is the type of the values <b>false</b> and <b>true</b>.
-Both <b>nil</b> and <b>false</b> make a condition false;
-any other value makes it true.
-<em>Number</em> represents real (double-precision floating-point) numbers.
-(It is easy to build Lua interpreters that use other
-internal representations for numbers,
-such as single-precision float or long integers;
-see file <code>luaconf.h</code>.)
-<em>String</em> represents arrays of characters.
-
-Lua is 8-bit clean:
-strings can contain any 8-bit character,
-including embedded zeros ('<code>\0</code>') (see <a href="#2.1">&sect;2.1</a>).
-
-
-<p>
-Lua can call (and manipulate) functions written in Lua and
-functions written in C
-(see <a href="#2.5.8">&sect;2.5.8</a>).
-
-
-<p>
-The type <em>userdata</em> is provided to allow arbitrary C&nbsp;data to
-be stored in Lua variables.
-This type corresponds to a block of raw memory
-and has no pre-defined operations in Lua,
-except assignment and identity test.
-However, by using <em>metatables</em>,
-the programmer can define operations for userdata values
-(see <a href="#2.8">&sect;2.8</a>).
-Userdata values cannot be created or modified in Lua,
-only through the C&nbsp;API.
-This guarantees the integrity of data owned by the host program.
-
-
-<p>
-The type <em>thread</em> represents independent threads of execution
-and it is used to implement coroutines (see <a href="#2.11">&sect;2.11</a>).
-Do not confuse Lua threads with operating-system threads.
-Lua supports coroutines on all systems,
-even those that do not support threads.
-
-
-<p>
-The type <em>table</em> implements associative arrays,
-that is, arrays that can be indexed not only with numbers,
-but with any value (except <b>nil</b>).
-Tables can be <em>heterogeneous</em>;
-that is, they can contain values of all types (except <b>nil</b>).
-Tables are the sole data structuring mechanism in Lua;
-they can be used to represent ordinary arrays,
-symbol tables, sets, records, graphs, trees, etc.
-To represent records, Lua uses the field name as an index.
-The language supports this representation by
-providing <code>a.name</code> as syntactic sugar for <code>a["name"]</code>.
-There are several convenient ways to create tables in Lua
-(see <a href="#2.5.7">&sect;2.5.7</a>).
-
-
-<p>
-Like indices,
-the value of a table field can be of any type (except <b>nil</b>).
-In particular,
-because functions are first-class values,
-table fields can contain functions.
-Thus tables can also carry <em>methods</em> (see <a href="#2.5.9">&sect;2.5.9</a>).
-
-
-<p>
-Tables, functions, threads, and (full) userdata values are <em>objects</em>:
-variables do not actually <em>contain</em> these values,
-only <em>references</em> to them.
-Assignment, parameter passing, and function returns
-always manipulate references to such values;
-these operations do not imply any kind of copy.
-
-
-<p>
-The library function <a href="#pdf-type"><code>type</code></a> returns a string describing the type
-of a given value.
-
-
-
-<h3>2.2.1 - <a name="2.2.1">Coercion</a></h3>
-
-<p>
-Lua provides automatic conversion between
-string and number values at run time.
-Any arithmetic operation applied to a string tries to convert
-this string to a number, following the usual conversion rules.
-Conversely, whenever a number is used where a string is expected,
-the number is converted to a string, in a reasonable format.
-For complete control over how numbers are converted to strings,
-use the <code>format</code> function from the string library
-(see <a href="#pdf-string.format"><code>string.format</code></a>).
-
-
-
-
-
-
-
-<h2>2.3 - <a name="2.3">Variables</a></h2>
-
-<p>
-Variables are places that store values.
-
-There are three kinds of variables in Lua:
-global variables, local variables, and table fields.
-
-
-<p>
-A single name can denote a global variable or a local variable
-(or a function's formal parameter,
-which is a particular kind of local variable):
-
-<pre>
- var ::= Name
-</pre><p>
-Name denotes identifiers, as defined in <a href="#2.1">&sect;2.1</a>.
-
-
-<p>
-Any variable is assumed to be global unless explicitly declared
-as a local (see <a href="#2.4.7">&sect;2.4.7</a>).
-Local variables are <em>lexically scoped</em>:
-local variables can be freely accessed by functions
-defined inside their scope (see <a href="#2.6">&sect;2.6</a>).
-
-
-<p>
-Before the first assignment to a variable, its value is <b>nil</b>.
-
-
-<p>
-Square brackets are used to index a table:
-
-<pre>
- var ::= prefixexp `<b>[</b>&acute; exp `<b>]</b>&acute;
-</pre><p>
-The meaning of accesses to global variables
-and table fields can be changed via metatables.
-An access to an indexed variable <code>t[i]</code> is equivalent to
-a call <code>gettable_event(t,i)</code>.
-(See <a href="#2.8">&sect;2.8</a> for a complete description of the
-<code>gettable_event</code> function.
-This function is not defined or callable in Lua.
-We use it here only for explanatory purposes.)
-
-
-<p>
-The syntax <code>var.Name</code> is just syntactic sugar for
-<code>var["Name"]</code>:
-
-<pre>
- var ::= prefixexp `<b>.</b>&acute; Name
-</pre>
-
-<p>
-All global variables live as fields in ordinary Lua tables,
-called <em>environment tables</em> or simply
-<em>environments</em> (see <a href="#2.9">&sect;2.9</a>).
-Each function has its own reference to an environment,
-so that all global variables in this function
-will refer to this environment table.
-When a function is created,
-it inherits the environment from the function that created it.
-To get the environment table of a Lua function,
-you call <a href="#pdf-getfenv"><code>getfenv</code></a>.
-To replace it,
-you call <a href="#pdf-setfenv"><code>setfenv</code></a>.
-(You can only manipulate the environment of C&nbsp;functions
-through the debug library; (see <a href="#5.9">&sect;5.9</a>).)
-
-
-<p>
-An access to a global variable <code>x</code>
-is equivalent to <code>_env.x</code>,
-which in turn is equivalent to
-
-<pre>
- gettable_event(_env, "x")
-</pre><p>
-where <code>_env</code> is the environment of the running function.
-(See <a href="#2.8">&sect;2.8</a> for a complete description of the
-<code>gettable_event</code> function.
-This function is not defined or callable in Lua.
-Similarly, the <code>_env</code> variable is not defined in Lua.
-We use them here only for explanatory purposes.)
-
-
-
-
-
-<h2>2.4 - <a name="2.4">Statements</a></h2>
-
-<p>
-Lua supports an almost conventional set of statements,
-similar to those in Pascal or C.
-This set includes
-assignments, control structures, function calls,
-and variable declarations.
-
-
-
-<h3>2.4.1 - <a name="2.4.1">Chunks</a></h3>
-
-<p>
-The unit of execution of Lua is called a <em>chunk</em>.
-A chunk is simply a sequence of statements,
-which are executed sequentially.
-Each statement can be optionally followed by a semicolon:
-
-<pre>
- chunk ::= {stat [`<b>;</b>&acute;]}
-</pre><p>
-There are no empty statements and thus '<code>;;</code>' is not legal.
-
-
-<p>
-Lua handles a chunk as the body of an anonymous function
-with a variable number of arguments
-(see <a href="#2.5.9">&sect;2.5.9</a>).
-As such, chunks can define local variables,
-receive arguments, and return values.
-
-
-<p>
-A chunk can be stored in a file or in a string inside the host program.
-To execute a chunk,
-Lua first pre-compiles the chunk into instructions for a virtual machine,
-and then it executes the compiled code
-with an interpreter for the virtual machine.
-
-
-<p>
-Chunks can also be pre-compiled into binary form;
-see program <code>luac</code> for details.
-Programs in source and compiled forms are interchangeable;
-Lua automatically detects the file type and acts accordingly.
-
-
-
-
-
-
-<h3>2.4.2 - <a name="2.4.2">Blocks</a></h3><p>
-A block is a list of statements;
-syntactically, a block is the same as a chunk:
-
-<pre>
- block ::= chunk
-</pre>
-
-<p>
-A block can be explicitly delimited to produce a single statement:
-
-<pre>
- stat ::= <b>do</b> block <b>end</b>
-</pre><p>
-Explicit blocks are useful
-to control the scope of variable declarations.
-Explicit blocks are also sometimes used to
-add a <b>return</b> or <b>break</b> statement in the middle
-of another block (see <a href="#2.4.4">&sect;2.4.4</a>).
-
-
-
-
-
-<h3>2.4.3 - <a name="2.4.3">Assignment</a></h3>
-
-<p>
-Lua allows multiple assignments.
-Therefore, the syntax for assignment
-defines a list of variables on the left side
-and a list of expressions on the right side.
-The elements in both lists are separated by commas:
-
-<pre>
- stat ::= varlist `<b>=</b>&acute; explist
- varlist ::= var {`<b>,</b>&acute; var}
- explist ::= exp {`<b>,</b>&acute; exp}
-</pre><p>
-Expressions are discussed in <a href="#2.5">&sect;2.5</a>.
-
-
-<p>
-Before the assignment,
-the list of values is <em>adjusted</em> to the length of
-the list of variables.
-If there are more values than needed,
-the excess values are thrown away.
-If there are fewer values than needed,
-the list is extended with as many <b>nil</b>'s as needed.
-If the list of expressions ends with a function call,
-then all values returned by that call enter the list of values,
-before the adjustment
-(except when the call is enclosed in parentheses; see <a href="#2.5">&sect;2.5</a>).
-
-
-<p>
-The assignment statement first evaluates all its expressions
-and only then are the assignments performed.
-Thus the code
-
-<pre>
- i = 3
- i, a[i] = i+1, 20
-</pre><p>
-sets <code>a[3]</code> to 20, without affecting <code>a[4]</code>
-because the <code>i</code> in <code>a[i]</code> is evaluated (to 3)
-before it is assigned&nbsp;4.
-Similarly, the line
-
-<pre>
- x, y = y, x
-</pre><p>
-exchanges the values of <code>x</code> and <code>y</code>,
-and
-
-<pre>
- x, y, z = y, z, x
-</pre><p>
-cyclically permutes the values of <code>x</code>, <code>y</code>, and <code>z</code>.
-
-
-<p>
-The meaning of assignments to global variables
-and table fields can be changed via metatables.
-An assignment to an indexed variable <code>t[i] = val</code> is equivalent to
-<code>settable_event(t,i,val)</code>.
-(See <a href="#2.8">&sect;2.8</a> for a complete description of the
-<code>settable_event</code> function.
-This function is not defined or callable in Lua.
-We use it here only for explanatory purposes.)
-
-
-<p>
-An assignment to a global variable <code>x = val</code>
-is equivalent to the assignment
-<code>_env.x = val</code>,
-which in turn is equivalent to
-
-<pre>
- settable_event(_env, "x", val)
-</pre><p>
-where <code>_env</code> is the environment of the running function.
-(The <code>_env</code> variable is not defined in Lua.
-We use it here only for explanatory purposes.)
-
-
-
-
-
-<h3>2.4.4 - <a name="2.4.4">Control Structures</a></h3><p>
-The control structures
-<b>if</b>, <b>while</b>, and <b>repeat</b> have the usual meaning and
-familiar syntax:
-
-
-
-
-<pre>
- stat ::= <b>while</b> exp <b>do</b> block <b>end</b>
- stat ::= <b>repeat</b> block <b>until</b> exp
- stat ::= <b>if</b> exp <b>then</b> block {<b>elseif</b> exp <b>then</b> block} [<b>else</b> block] <b>end</b>
-</pre><p>
-Lua also has a <b>for</b> statement, in two flavors (see <a href="#2.4.5">&sect;2.4.5</a>).
-
-
-<p>
-The condition expression of a
-control structure can return any value.
-Both <b>false</b> and <b>nil</b> are considered false.
-All values different from <b>nil</b> and <b>false</b> are considered true
-(in particular, the number 0 and the empty string are also true).
-
-
-<p>
-In the <b>repeat</b>&ndash;<b>until</b> loop,
-the inner block does not end at the <b>until</b> keyword,
-but only after the condition.
-So, the condition can refer to local variables
-declared inside the loop block.
-
-
-<p>
-The <b>return</b> statement is used to return values
-from a function or a chunk (which is just a function).
-
-Functions and chunks can return more than one value,
-and so the syntax for the <b>return</b> statement is
-
-<pre>
- stat ::= <b>return</b> [explist]
-</pre>
-
-<p>
-The <b>break</b> statement is used to terminate the execution of a
-<b>while</b>, <b>repeat</b>, or <b>for</b> loop,
-skipping to the next statement after the loop:
-
-
-<pre>
- stat ::= <b>break</b>
-</pre><p>
-A <b>break</b> ends the innermost enclosing loop.
-
-
-<p>
-The <b>return</b> and <b>break</b>
-statements can only be written as the <em>last</em> statement of a block.
-If it is really necessary to <b>return</b> or <b>break</b> in the
-middle of a block,
-then an explicit inner block can be used,
-as in the idioms
-<code>do return end</code> and <code>do break end</code>,
-because now <b>return</b> and <b>break</b> are the last statements in
-their (inner) blocks.
-
-
-
-
-
-<h3>2.4.5 - <a name="2.4.5">For Statement</a></h3>
-
-<p>
-
-The <b>for</b> statement has two forms:
-one numeric and one generic.
-
-
-<p>
-The numeric <b>for</b> loop repeats a block of code while a
-control variable runs through an arithmetic progression.
-It has the following syntax:
-
-<pre>
- stat ::= <b>for</b> Name `<b>=</b>&acute; exp `<b>,</b>&acute; exp [`<b>,</b>&acute; exp] <b>do</b> block <b>end</b>
-</pre><p>
-The <em>block</em> is repeated for <em>name</em> starting at the value of
-the first <em>exp</em>, until it passes the second <em>exp</em> by steps of the
-third <em>exp</em>.
-More precisely, a <b>for</b> statement like
-
-<pre>
- for v = <em>e1</em>, <em>e2</em>, <em>e3</em> do <em>block</em> end
-</pre><p>
-is equivalent to the code:
-
-<pre>
- do
- local <em>var</em>, <em>limit</em>, <em>step</em> = tonumber(<em>e1</em>), tonumber(<em>e2</em>), tonumber(<em>e3</em>)
- if not (<em>var</em> and <em>limit</em> and <em>step</em>) then error() end
- while (<em>step</em> &gt; 0 and <em>var</em> &lt;= <em>limit</em>) or (<em>step</em> &lt;= 0 and <em>var</em> &gt;= <em>limit</em>) do
- local v = <em>var</em>
- <em>block</em>
- <em>var</em> = <em>var</em> + <em>step</em>
- end
- end
-</pre><p>
-Note the following:
-
-<ul>
-
-<li>
-All three control expressions are evaluated only once,
-before the loop starts.
-They must all result in numbers.
-</li>
-
-<li>
-<code><em>var</em></code>, <code><em>limit</em></code>, and <code><em>step</em></code> are invisible variables.
-The names shown here are for explanatory purposes only.
-</li>
-
-<li>
-If the third expression (the step) is absent,
-then a step of&nbsp;1 is used.
-</li>
-
-<li>
-You can use <b>break</b> to exit a <b>for</b> loop.
-</li>
-
-<li>
-The loop variable <code>v</code> is local to the loop;
-you cannot use its value after the <b>for</b> ends or is broken.
-If you need this value,
-assign it to another variable before breaking or exiting the loop.
-</li>
-
-</ul>
-
-<p>
-The generic <b>for</b> statement works over functions,
-called <em>iterators</em>.
-On each iteration, the iterator function is called to produce a new value,
-stopping when this new value is <b>nil</b>.
-The generic <b>for</b> loop has the following syntax:
-
-<pre>
- stat ::= <b>for</b> namelist <b>in</b> explist <b>do</b> block <b>end</b>
- namelist ::= Name {`<b>,</b>&acute; Name}
-</pre><p>
-A <b>for</b> statement like
-
-<pre>
- for <em>var_1</em>, &middot;&middot;&middot;, <em>var_n</em> in <em>explist</em> do <em>block</em> end
-</pre><p>
-is equivalent to the code:
-
-<pre>
- do
- local <em>f</em>, <em>s</em>, <em>var</em> = <em>explist</em>
- while true do
- local <em>var_1</em>, &middot;&middot;&middot;, <em>var_n</em> = <em>f</em>(<em>s</em>, <em>var</em>)
- <em>var</em> = <em>var_1</em>
- if <em>var</em> == nil then break end
- <em>block</em>
- end
- end
-</pre><p>
-Note the following:
-
-<ul>
-
-<li>
-<code><em>explist</em></code> is evaluated only once.
-Its results are an <em>iterator</em> function,
-a <em>state</em>,
-and an initial value for the first <em>iterator variable</em>.
-</li>
-
-<li>
-<code><em>f</em></code>, <code><em>s</em></code>, and <code><em>var</em></code> are invisible variables.
-The names are here for explanatory purposes only.
-</li>
-
-<li>
-You can use <b>break</b> to exit a <b>for</b> loop.
-</li>
-
-<li>
-The loop variables <code><em>var_i</em></code> are local to the loop;
-you cannot use their values after the <b>for</b> ends.
-If you need these values,
-then assign them to other variables before breaking or exiting the loop.
-</li>
-
-</ul>
-
-
-
-
-<h3>2.4.6 - <a name="2.4.6">Function Calls as Statements</a></h3><p>
-To allow possible side-effects,
-function calls can be executed as statements:
-
-<pre>
- stat ::= functioncall
-</pre><p>
-In this case, all returned values are thrown away.
-Function calls are explained in <a href="#2.5.8">&sect;2.5.8</a>.
-
-
-
-
-
-<h3>2.4.7 - <a name="2.4.7">Local Declarations</a></h3><p>
-Local variables can be declared anywhere inside a block.
-The declaration can include an initial assignment:
-
-<pre>
- stat ::= <b>local</b> namelist [`<b>=</b>&acute; explist]
-</pre><p>
-If present, an initial assignment has the same semantics
-of a multiple assignment (see <a href="#2.4.3">&sect;2.4.3</a>).
-Otherwise, all variables are initialized with <b>nil</b>.
-
-
-<p>
-A chunk is also a block (see <a href="#2.4.1">&sect;2.4.1</a>),
-and so local variables can be declared in a chunk outside any explicit block.
-The scope of such local variables extends until the end of the chunk.
-
-
-<p>
-The visibility rules for local variables are explained in <a href="#2.6">&sect;2.6</a>.
-
-
-
-
-
-
-
-<h2>2.5 - <a name="2.5">Expressions</a></h2>
-
-<p>
-The basic expressions in Lua are the following:
-
-<pre>
- exp ::= prefixexp
- exp ::= <b>nil</b> | <b>false</b> | <b>true</b>
- exp ::= Number
- exp ::= String
- exp ::= function
- exp ::= tableconstructor
- exp ::= `<b>...</b>&acute;
- exp ::= exp binop exp
- exp ::= unop exp
- prefixexp ::= var | functioncall | `<b>(</b>&acute; exp `<b>)</b>&acute;
-</pre>
-
-<p>
-Numbers and literal strings are explained in <a href="#2.1">&sect;2.1</a>;
-variables are explained in <a href="#2.3">&sect;2.3</a>;
-function definitions are explained in <a href="#2.5.9">&sect;2.5.9</a>;
-function calls are explained in <a href="#2.5.8">&sect;2.5.8</a>;
-table constructors are explained in <a href="#2.5.7">&sect;2.5.7</a>.
-Vararg expressions,
-denoted by three dots ('<code>...</code>'), can only be used when
-directly inside a vararg function;
-they are explained in <a href="#2.5.9">&sect;2.5.9</a>.
-
-
-<p>
-Binary operators comprise arithmetic operators (see <a href="#2.5.1">&sect;2.5.1</a>),
-relational operators (see <a href="#2.5.2">&sect;2.5.2</a>), logical operators (see <a href="#2.5.3">&sect;2.5.3</a>),
-and the concatenation operator (see <a href="#2.5.4">&sect;2.5.4</a>).
-Unary operators comprise the unary minus (see <a href="#2.5.1">&sect;2.5.1</a>),
-the unary <b>not</b> (see <a href="#2.5.3">&sect;2.5.3</a>),
-and the unary <em>length operator</em> (see <a href="#2.5.5">&sect;2.5.5</a>).
-
-
-<p>
-Both function calls and vararg expressions can result in multiple values.
-If an expression is used as a statement
-(only possible for function calls (see <a href="#2.4.6">&sect;2.4.6</a>)),
-then its return list is adjusted to zero elements,
-thus discarding all returned values.
-If an expression is used as the last (or the only) element
-of a list of expressions,
-then no adjustment is made
-(unless the call is enclosed in parentheses).
-In all other contexts,
-Lua adjusts the result list to one element,
-discarding all values except the first one.
-
-
-<p>
-Here are some examples:
-
-<pre>
- f() -- adjusted to 0 results
- g(f(), x) -- f() is adjusted to 1 result
- g(x, f()) -- g gets x plus all results from f()
- a,b,c = f(), x -- f() is adjusted to 1 result (c gets nil)
- a,b = ... -- a gets the first vararg parameter, b gets
- -- the second (both a and b can get nil if there
- -- is no corresponding vararg parameter)
-
- a,b,c = x, f() -- f() is adjusted to 2 results
- a,b,c = f() -- f() is adjusted to 3 results
- return f() -- returns all results from f()
- return ... -- returns all received vararg parameters
- return x,y,f() -- returns x, y, and all results from f()
- {f()} -- creates a list with all results from f()
- {...} -- creates a list with all vararg parameters
- {f(), nil} -- f() is adjusted to 1 result
-</pre>
-
-<p>
-Any expression enclosed in parentheses always results in only one value.
-Thus,
-<code>(f(x,y,z))</code> is always a single value,
-even if <code>f</code> returns several values.
-(The value of <code>(f(x,y,z))</code> is the first value returned by <code>f</code>
-or <b>nil</b> if <code>f</code> does not return any values.)
-
-
-
-<h3>2.5.1 - <a name="2.5.1">Arithmetic Operators</a></h3><p>
-Lua supports the usual arithmetic operators:
-the binary <code>+</code> (addition),
-<code>-</code> (subtraction), <code>*</code> (multiplication),
-<code>/</code> (division), <code>%</code> (modulo), and <code>^</code> (exponentiation);
-and unary <code>-</code> (negation).
-If the operands are numbers, or strings that can be converted to
-numbers (see <a href="#2.2.1">&sect;2.2.1</a>),
-then all operations have the usual meaning.
-Exponentiation works for any exponent.
-For instance, <code>x^(-0.5)</code> computes the inverse of the square root of <code>x</code>.
-Modulo is defined as
-
-<pre>
- a % b == a - math.floor(a/b)*b
-</pre><p>
-That is, it is the remainder of a division that rounds
-the quotient towards minus infinity.
-
-
-
-
-
-<h3>2.5.2 - <a name="2.5.2">Relational Operators</a></h3><p>
-The relational operators in Lua are
-
-<pre>
- == ~= &lt; &gt; &lt;= &gt;=
-</pre><p>
-These operators always result in <b>false</b> or <b>true</b>.
-
-
-<p>
-Equality (<code>==</code>) first compares the type of its operands.
-If the types are different, then the result is <b>false</b>.
-Otherwise, the values of the operands are compared.
-Numbers and strings are compared in the usual way.
-Objects (tables, userdata, threads, and functions)
-are compared by <em>reference</em>:
-two objects are considered equal only if they are the <em>same</em> object.
-Every time you create a new object
-(a table, userdata, thread, or function),
-this new object is different from any previously existing object.
-
-
-<p>
-You can change the way that Lua compares tables and userdata
-by using the "eq" metamethod (see <a href="#2.8">&sect;2.8</a>).
-
-
-<p>
-The conversion rules of <a href="#2.2.1">&sect;2.2.1</a>
-<em>do not</em> apply to equality comparisons.
-Thus, <code>"0"==0</code> evaluates to <b>false</b>,
-and <code>t[0]</code> and <code>t["0"]</code> denote different
-entries in a table.
-
-
-<p>
-The operator <code>~=</code> is exactly the negation of equality (<code>==</code>).
-
-
-<p>
-The order operators work as follows.
-If both arguments are numbers, then they are compared as such.
-Otherwise, if both arguments are strings,
-then their values are compared according to the current locale.
-Otherwise, Lua tries to call the "lt" or the "le"
-metamethod (see <a href="#2.8">&sect;2.8</a>).
-A comparison <code>a &gt; b</code> is translated to <code>b &lt; a</code>
-and <code>a &gt;= b</code> is translated to <code>b &lt;= a</code>.
-
-
-
-
-
-<h3>2.5.3 - <a name="2.5.3">Logical Operators</a></h3><p>
-The logical operators in Lua are
-<b>and</b>, <b>or</b>, and <b>not</b>.
-Like the control structures (see <a href="#2.4.4">&sect;2.4.4</a>),
-all logical operators consider both <b>false</b> and <b>nil</b> as false
-and anything else as true.
-
-
-<p>
-The negation operator <b>not</b> always returns <b>false</b> or <b>true</b>.
-The conjunction operator <b>and</b> returns its first argument
-if this value is <b>false</b> or <b>nil</b>;
-otherwise, <b>and</b> returns its second argument.
-The disjunction operator <b>or</b> returns its first argument
-if this value is different from <b>nil</b> and <b>false</b>;
-otherwise, <b>or</b> returns its second argument.
-Both <b>and</b> and <b>or</b> use short-cut evaluation;
-that is,
-the second operand is evaluated only if necessary.
-Here are some examples:
-
-<pre>
- 10 or 20 --&gt; 10
- 10 or error() --&gt; 10
- nil or "a" --&gt; "a"
- nil and 10 --&gt; nil
- false and error() --&gt; false
- false and nil --&gt; false
- false or nil --&gt; nil
- 10 and 20 --&gt; 20
-</pre><p>
-(In this manual,
-<code>--&gt;</code> indicates the result of the preceding expression.)
-
-
-
-
-
-<h3>2.5.4 - <a name="2.5.4">Concatenation</a></h3><p>
-The string concatenation operator in Lua is
-denoted by two dots ('<code>..</code>').
-If both operands are strings or numbers, then they are converted to
-strings according to the rules mentioned in <a href="#2.2.1">&sect;2.2.1</a>.
-Otherwise, the "concat" metamethod is called (see <a href="#2.8">&sect;2.8</a>).
-
-
-
-
-
-<h3>2.5.5 - <a name="2.5.5">The Length Operator</a></h3>
-
-<p>
-The length operator is denoted by the unary operator <code>#</code>.
-The length of a string is its number of bytes
-(that is, the usual meaning of string length when each
-character is one byte).
-
-
-<p>
-The length of a table <code>t</code> is defined to be any
-integer index <code>n</code>
-such that <code>t[n]</code> is not <b>nil</b> and <code>t[n+1]</code> is <b>nil</b>;
-moreover, if <code>t[1]</code> is <b>nil</b>, <code>n</code> can be zero.
-For a regular array, with non-nil values from 1 to a given <code>n</code>,
-its length is exactly that <code>n</code>,
-the index of its last value.
-If the array has "holes"
-(that is, <b>nil</b> values between other non-nil values),
-then <code>#t</code> can be any of the indices that
-directly precedes a <b>nil</b> value
-(that is, it may consider any such <b>nil</b> value as the end of
-the array).
-
-
-
-
-
-<h3>2.5.6 - <a name="2.5.6">Precedence</a></h3><p>
-Operator precedence in Lua follows the table below,
-from lower to higher priority:
-
-<pre>
- or
- and
- &lt; &gt; &lt;= &gt;= ~= ==
- ..
- + -
- * / %
- not # - (unary)
- ^
-</pre><p>
-As usual,
-you can use parentheses to change the precedences of an expression.
-The concatenation ('<code>..</code>') and exponentiation ('<code>^</code>')
-operators are right associative.
-All other binary operators are left associative.
-
-
-
-
-
-<h3>2.5.7 - <a name="2.5.7">Table Constructors</a></h3><p>
-Table constructors are expressions that create tables.
-Every time a constructor is evaluated, a new table is created.
-A constructor can be used to create an empty table
-or to create a table and initialize some of its fields.
-The general syntax for constructors is
-
-<pre>
- tableconstructor ::= `<b>{</b>&acute; [fieldlist] `<b>}</b>&acute;
- fieldlist ::= field {fieldsep field} [fieldsep]
- field ::= `<b>[</b>&acute; exp `<b>]</b>&acute; `<b>=</b>&acute; exp | Name `<b>=</b>&acute; exp | exp
- fieldsep ::= `<b>,</b>&acute; | `<b>;</b>&acute;
-</pre>
-
-<p>
-Each field of the form <code>[exp1] = exp2</code> adds to the new table an entry
-with key <code>exp1</code> and value <code>exp2</code>.
-A field of the form <code>name = exp</code> is equivalent to
-<code>["name"] = exp</code>.
-Finally, fields of the form <code>exp</code> are equivalent to
-<code>[i] = exp</code>, where <code>i</code> are consecutive numerical integers,
-starting with 1.
-Fields in the other formats do not affect this counting.
-For example,
-
-<pre>
- a = { [f(1)] = g; "x", "y"; x = 1, f(x), [30] = 23; 45 }
-</pre><p>
-is equivalent to
-
-<pre>
- do
- local t = {}
- t[f(1)] = g
- t[1] = "x" -- 1st exp
- t[2] = "y" -- 2nd exp
- t.x = 1 -- t["x"] = 1
- t[3] = f(x) -- 3rd exp
- t[30] = 23
- t[4] = 45 -- 4th exp
- a = t
- end
-</pre>
-
-<p>
-If the last field in the list has the form <code>exp</code>
-and the expression is a function call or a vararg expression,
-then all values returned by this expression enter the list consecutively
-(see <a href="#2.5.8">&sect;2.5.8</a>).
-To avoid this,
-enclose the function call or the vararg expression
-in parentheses (see <a href="#2.5">&sect;2.5</a>).
-
-
-<p>
-The field list can have an optional trailing separator,
-as a convenience for machine-generated code.
-
-
-
-
-
-<h3>2.5.8 - <a name="2.5.8">Function Calls</a></h3><p>
-A function call in Lua has the following syntax:
-
-<pre>
- functioncall ::= prefixexp args
-</pre><p>
-In a function call,
-first prefixexp and args are evaluated.
-If the value of prefixexp has type <em>function</em>,
-then this function is called
-with the given arguments.
-Otherwise, the prefixexp "call" metamethod is called,
-having as first parameter the value of prefixexp,
-followed by the original call arguments
-(see <a href="#2.8">&sect;2.8</a>).
-
-
-<p>
-The form
-
-<pre>
- functioncall ::= prefixexp `<b>:</b>&acute; Name args
-</pre><p>
-can be used to call "methods".
-A call <code>v:name(<em>args</em>)</code>
-is syntactic sugar for <code>v.name(v,<em>args</em>)</code>,
-except that <code>v</code> is evaluated only once.
-
-
-<p>
-Arguments have the following syntax:
-
-<pre>
- args ::= `<b>(</b>&acute; [explist] `<b>)</b>&acute;
- args ::= tableconstructor
- args ::= String
-</pre><p>
-All argument expressions are evaluated before the call.
-A call of the form <code>f{<em>fields</em>}</code> is
-syntactic sugar for <code>f({<em>fields</em>})</code>;
-that is, the argument list is a single new table.
-A call of the form <code>f'<em>string</em>'</code>
-(or <code>f"<em>string</em>"</code> or <code>f[[<em>string</em>]]</code>)
-is syntactic sugar for <code>f('<em>string</em>')</code>;
-that is, the argument list is a single literal string.
-
-
-<p>
-As an exception to the free-format syntax of Lua,
-you cannot put a line break before the '<code>(</code>' in a function call.
-This restriction avoids some ambiguities in the language.
-If you write
-
-<pre>
- a = f
- (g).x(a)
-</pre><p>
-Lua would see that as a single statement, <code>a = f(g).x(a)</code>.
-So, if you want two statements, you must add a semi-colon between them.
-If you actually want to call <code>f</code>,
-you must remove the line break before <code>(g)</code>.
-
-
-<p>
-A call of the form <code>return</code> <em>functioncall</em> is called
-a <em>tail call</em>.
-Lua implements <em>proper tail calls</em>
-(or <em>proper tail recursion</em>):
-in a tail call,
-the called function reuses the stack entry of the calling function.
-Therefore, there is no limit on the number of nested tail calls that
-a program can execute.
-However, a tail call erases any debug information about the
-calling function.
-Note that a tail call only happens with a particular syntax,
-where the <b>return</b> has one single function call as argument;
-this syntax makes the calling function return exactly
-the returns of the called function.
-So, none of the following examples are tail calls:
-
-<pre>
- return (f(x)) -- results adjusted to 1
- return 2 * f(x)
- return x, f(x) -- additional results
- f(x); return -- results discarded
- return x or f(x) -- results adjusted to 1
-</pre>
-
-
-
-
-<h3>2.5.9 - <a name="2.5.9">Function Definitions</a></h3>
-
-<p>
-The syntax for function definition is
-
-<pre>
- function ::= <b>function</b> funcbody
- funcbody ::= `<b>(</b>&acute; [parlist] `<b>)</b>&acute; block <b>end</b>
-</pre>
-
-<p>
-The following syntactic sugar simplifies function definitions:
-
-<pre>
- stat ::= <b>function</b> funcname funcbody
- stat ::= <b>local</b> <b>function</b> Name funcbody
- funcname ::= Name {`<b>.</b>&acute; Name} [`<b>:</b>&acute; Name]
-</pre><p>
-The statement
-
-<pre>
- function f () <em>body</em> end
-</pre><p>
-translates to
-
-<pre>
- f = function () <em>body</em> end
-</pre><p>
-The statement
-
-<pre>
- function t.a.b.c.f () <em>body</em> end
-</pre><p>
-translates to
-
-<pre>
- t.a.b.c.f = function () <em>body</em> end
-</pre><p>
-The statement
-
-<pre>
- local function f () <em>body</em> end
-</pre><p>
-translates to
-
-<pre>
- local f; f = function () <em>body</em> end
-</pre><p>
-<em>not</em> to
-
-<pre>
- local f = function () <em>body</em> end
-</pre><p>
-(This only makes a difference when the body of the function
-contains references to <code>f</code>.)
-
-
-<p>
-A function definition is an executable expression,
-whose value has type <em>function</em>.
-When Lua pre-compiles a chunk,
-all its function bodies are pre-compiled too.
-Then, whenever Lua executes the function definition,
-the function is <em>instantiated</em> (or <em>closed</em>).
-This function instance (or <em>closure</em>)
-is the final value of the expression.
-Different instances of the same function
-can refer to different external local variables
-and can have different environment tables.
-
-
-<p>
-Parameters act as local variables that are
-initialized with the argument values:
-
-<pre>
- parlist ::= namelist [`<b>,</b>&acute; `<b>...</b>&acute;] | `<b>...</b>&acute;
-</pre><p>
-When a function is called,
-the list of arguments is adjusted to
-the length of the list of parameters,
-unless the function is a variadic or <em>vararg function</em>,
-which is
-indicated by three dots ('<code>...</code>') at the end of its parameter list.
-A vararg function does not adjust its argument list;
-instead, it collects all extra arguments and supplies them
-to the function through a <em>vararg expression</em>,
-which is also written as three dots.
-The value of this expression is a list of all actual extra arguments,
-similar to a function with multiple results.
-If a vararg expression is used inside another expression
-or in the middle of a list of expressions,
-then its return list is adjusted to one element.
-If the expression is used as the last element of a list of expressions,
-then no adjustment is made
-(unless that last expression is enclosed in parentheses).
-
-
-<p>
-As an example, consider the following definitions:
-
-<pre>
- function f(a, b) end
- function g(a, b, ...) end
- function r() return 1,2,3 end
-</pre><p>
-Then, we have the following mapping from arguments to parameters and
-to the vararg expression:
-
-<pre>
- CALL PARAMETERS
-
- f(3) a=3, b=nil
- f(3, 4) a=3, b=4
- f(3, 4, 5) a=3, b=4
- f(r(), 10) a=1, b=10
- f(r()) a=1, b=2
-
- g(3) a=3, b=nil, ... --&gt; (nothing)
- g(3, 4) a=3, b=4, ... --&gt; (nothing)
- g(3, 4, 5, 8) a=3, b=4, ... --&gt; 5 8
- g(5, r()) a=5, b=1, ... --&gt; 2 3
-</pre>
-
-<p>
-Results are returned using the <b>return</b> statement (see <a href="#2.4.4">&sect;2.4.4</a>).
-If control reaches the end of a function
-without encountering a <b>return</b> statement,
-then the function returns with no results.
-
-
-<p>
-The <em>colon</em> syntax
-is used for defining <em>methods</em>,
-that is, functions that have an implicit extra parameter <code>self</code>.
-Thus, the statement
-
-<pre>
- function t.a.b.c:f (<em>params</em>) <em>body</em> end
-</pre><p>
-is syntactic sugar for
-
-<pre>
- t.a.b.c.f = function (self, <em>params</em>) <em>body</em> end
-</pre>
-
-
-
-
-
-
-<h2>2.6 - <a name="2.6">Visibility Rules</a></h2>
-
-<p>
-
-Lua is a lexically scoped language.
-The scope of variables begins at the first statement <em>after</em>
-their declaration and lasts until the end of the innermost block that
-includes the declaration.
-Consider the following example:
-
-<pre>
- x = 10 -- global variable
- do -- new block
- local x = x -- new 'x', with value 10
- print(x) --&gt; 10
- x = x+1
- do -- another block
- local x = x+1 -- another 'x'
- print(x) --&gt; 12
- end
- print(x) --&gt; 11
- end
- print(x) --&gt; 10 (the global one)
-</pre>
-
-<p>
-Notice that, in a declaration like <code>local x = x</code>,
-the new <code>x</code> being declared is not in scope yet,
-and so the second <code>x</code> refers to the outside variable.
-
-
-<p>
-Because of the lexical scoping rules,
-local variables can be freely accessed by functions
-defined inside their scope.
-A local variable used by an inner function is called
-an <em>upvalue</em>, or <em>external local variable</em>,
-inside the inner function.
-
-
-<p>
-Notice that each execution of a <b>local</b> statement
-defines new local variables.
-Consider the following example:
-
-<pre>
- a = {}
- local x = 20
- for i=1,10 do
- local y = 0
- a[i] = function () y=y+1; return x+y end
- end
-</pre><p>
-The loop creates ten closures
-(that is, ten instances of the anonymous function).
-Each of these closures uses a different <code>y</code> variable,
-while all of them share the same <code>x</code>.
-
-
-
-
-
-<h2>2.7 - <a name="2.7">Error Handling</a></h2>
-
-<p>
-Because Lua is an embedded extension language,
-all Lua actions start from C&nbsp;code in the host program
-calling a function from the Lua library (see <a href="#lua_pcall"><code>lua_pcall</code></a>).
-Whenever an error occurs during Lua compilation or execution,
-control returns to C,
-which can take appropriate measures
-(such as printing an error message).
-
-
-<p>
-Lua code can explicitly generate an error by calling the
-<a href="#pdf-error"><code>error</code></a> function.
-If you need to catch errors in Lua,
-you can use the <a href="#pdf-pcall"><code>pcall</code></a> function.
-
-
-
-
-
-<h2>2.8 - <a name="2.8">Metatables</a></h2>
-
-<p>
-Every value in Lua can have a <em>metatable</em>.
-This <em>metatable</em> is an ordinary Lua table
-that defines the behavior of the original value
-under certain special operations.
-You can change several aspects of the behavior
-of operations over a value by setting specific fields in its metatable.
-For instance, when a non-numeric value is the operand of an addition,
-Lua checks for a function in the field <code>"__add"</code> in its metatable.
-If it finds one,
-Lua calls this function to perform the addition.
-
-
-<p>
-We call the keys in a metatable <em>events</em>
-and the values <em>metamethods</em>.
-In the previous example, the event is <code>"add"</code>
-and the metamethod is the function that performs the addition.
-
-
-<p>
-You can query the metatable of any value
-through the <a href="#pdf-getmetatable"><code>getmetatable</code></a> function.
-
-
-<p>
-You can replace the metatable of tables
-through the <a href="#pdf-setmetatable"><code>setmetatable</code></a>
-function.
-You cannot change the metatable of other types from Lua
-(except by using the debug library);
-you must use the C&nbsp;API for that.
-
-
-<p>
-Tables and full userdata have individual metatables
-(although multiple tables and userdata can share their metatables).
-Values of all other types share one single metatable per type;
-that is, there is one single metatable for all numbers,
-one for all strings, etc.
-
-
-<p>
-A metatable controls how an object behaves in arithmetic operations,
-order comparisons, concatenation, length operation, and indexing.
-A metatable also can define a function to be called when a userdata
-is garbage collected.
-For each of these operations Lua associates a specific key
-called an <em>event</em>.
-When Lua performs one of these operations over a value,
-it checks whether this value has a metatable with the corresponding event.
-If so, the value associated with that key (the metamethod)
-controls how Lua will perform the operation.
-
-
-<p>
-Metatables control the operations listed next.
-Each operation is identified by its corresponding name.
-The key for each operation is a string with its name prefixed by
-two underscores, '<code>__</code>';
-for instance, the key for operation "add" is the
-string <code>"__add"</code>.
-The semantics of these operations is better explained by a Lua function
-describing how the interpreter executes the operation.
-
-
-<p>
-The code shown here in Lua is only illustrative;
-the real behavior is hard coded in the interpreter
-and it is much more efficient than this simulation.
-All functions used in these descriptions
-(<a href="#pdf-rawget"><code>rawget</code></a>, <a href="#pdf-tonumber"><code>tonumber</code></a>, etc.)
-are described in <a href="#5.1">&sect;5.1</a>.
-In particular, to retrieve the metamethod of a given object,
-we use the expression
-
-<pre>
- metatable(obj)[event]
-</pre><p>
-This should be read as
-
-<pre>
- rawget(getmetatable(obj) or {}, event)
-</pre><p>
-
-That is, the access to a metamethod does not invoke other metamethods,
-and the access to objects with no metatables does not fail
-(it simply results in <b>nil</b>).
-
-
-
-<ul>
-
-<li><b>"add":</b>
-the <code>+</code> operation.
-
-
-
-<p>
-The function <code>getbinhandler</code> below defines how Lua chooses a handler
-for a binary operation.
-First, Lua tries the first operand.
-If its type does not define a handler for the operation,
-then Lua tries the second operand.
-
-<pre>
- function getbinhandler (op1, op2, event)
- return metatable(op1)[event] or metatable(op2)[event]
- end
-</pre><p>
-By using this function,
-the behavior of the <code>op1 + op2</code> is
-
-<pre>
- function add_event (op1, op2)
- local o1, o2 = tonumber(op1), tonumber(op2)
- if o1 and o2 then -- both operands are numeric?
- return o1 + o2 -- '+' here is the primitive 'add'
- else -- at least one of the operands is not numeric
- local h = getbinhandler(op1, op2, "__add")
- if h then
- -- call the handler with both operands
- return (h(op1, op2))
- else -- no handler available: default behavior
- error(&middot;&middot;&middot;)
- end
- end
- end
-</pre><p>
-</li>
-
-<li><b>"sub":</b>
-the <code>-</code> operation.
-
-Behavior similar to the "add" operation.
-</li>
-
-<li><b>"mul":</b>
-the <code>*</code> operation.
-
-Behavior similar to the "add" operation.
-</li>
-
-<li><b>"div":</b>
-the <code>/</code> operation.
-
-Behavior similar to the "add" operation.
-</li>
-
-<li><b>"mod":</b>
-the <code>%</code> operation.
-
-Behavior similar to the "add" operation,
-with the operation
-<code>o1 - floor(o1/o2)*o2</code> as the primitive operation.
-</li>
-
-<li><b>"pow":</b>
-the <code>^</code> (exponentiation) operation.
-
-Behavior similar to the "add" operation,
-with the function <code>pow</code> (from the C&nbsp;math library)
-as the primitive operation.
-</li>
-
-<li><b>"unm":</b>
-the unary <code>-</code> operation.
-
-
-<pre>
- function unm_event (op)
- local o = tonumber(op)
- if o then -- operand is numeric?
- return -o -- '-' here is the primitive 'unm'
- else -- the operand is not numeric.
- -- Try to get a handler from the operand
- local h = metatable(op).__unm
- if h then
- -- call the handler with the operand
- return (h(op))
- else -- no handler available: default behavior
- error(&middot;&middot;&middot;)
- end
- end
- end
-</pre><p>
-</li>
-
-<li><b>"concat":</b>
-the <code>..</code> (concatenation) operation.
-
-
-<pre>
- function concat_event (op1, op2)
- if (type(op1) == "string" or type(op1) == "number") and
- (type(op2) == "string" or type(op2) == "number") then
- return op1 .. op2 -- primitive string concatenation
- else
- local h = getbinhandler(op1, op2, "__concat")
- if h then
- return (h(op1, op2))
- else
- error(&middot;&middot;&middot;)
- end
- end
- end
-</pre><p>
-</li>
-
-<li><b>"len":</b>
-the <code>#</code> operation.
-
-
-<pre>
- function len_event (op)
- if type(op) == "string" then
- return strlen(op) -- primitive string length
- elseif type(op) == "table" then
- return #op -- primitive table length
- else
- local h = metatable(op).__len
- if h then
- -- call the handler with the operand
- return (h(op))
- else -- no handler available: default behavior
- error(&middot;&middot;&middot;)
- end
- end
- end
-</pre><p>
-See <a href="#2.5.5">&sect;2.5.5</a> for a description of the length of a table.
-</li>
-
-<li><b>"eq":</b>
-the <code>==</code> operation.
-
-The function <code>getcomphandler</code> defines how Lua chooses a metamethod
-for comparison operators.
-A metamethod only is selected when both objects
-being compared have the same type
-and the same metamethod for the selected operation.
-
-<pre>
- function getcomphandler (op1, op2, event)
- if type(op1) ~= type(op2) then return nil end
- local mm1 = metatable(op1)[event]
- local mm2 = metatable(op2)[event]
- if mm1 == mm2 then return mm1 else return nil end
- end
-</pre><p>
-The "eq" event is defined as follows:
-
-<pre>
- function eq_event (op1, op2)
- if type(op1) ~= type(op2) then -- different types?
- return false -- different objects
- end
- if op1 == op2 then -- primitive equal?
- return true -- objects are equal
- end
- -- try metamethod
- local h = getcomphandler(op1, op2, "__eq")
- if h then
- return (h(op1, op2))
- else
- return false
- end
- end
-</pre><p>
-<code>a ~= b</code> is equivalent to <code>not (a == b)</code>.
-</li>
-
-<li><b>"lt":</b>
-the <code>&lt;</code> operation.
-
-
-<pre>
- function lt_event (op1, op2)
- if type(op1) == "number" and type(op2) == "number" then
- return op1 &lt; op2 -- numeric comparison
- elseif type(op1) == "string" and type(op2) == "string" then
- return op1 &lt; op2 -- lexicographic comparison
- else
- local h = getcomphandler(op1, op2, "__lt")
- if h then
- return (h(op1, op2))
- else
- error(&middot;&middot;&middot;)
- end
- end
- end
-</pre><p>
-<code>a &gt; b</code> is equivalent to <code>b &lt; a</code>.
-</li>
-
-<li><b>"le":</b>
-the <code>&lt;=</code> operation.
-
-
-<pre>
- function le_event (op1, op2)
- if type(op1) == "number" and type(op2) == "number" then
- return op1 &lt;= op2 -- numeric comparison
- elseif type(op1) == "string" and type(op2) == "string" then
- return op1 &lt;= op2 -- lexicographic comparison
- else
- local h = getcomphandler(op1, op2, "__le")
- if h then
- return (h(op1, op2))
- else
- h = getcomphandler(op1, op2, "__lt")
- if h then
- return not h(op2, op1)
- else
- error(&middot;&middot;&middot;)
- end
- end
- end
- end
-</pre><p>
-<code>a &gt;= b</code> is equivalent to <code>b &lt;= a</code>.
-Note that, in the absence of a "le" metamethod,
-Lua tries the "lt", assuming that <code>a &lt;= b</code> is
-equivalent to <code>not (b &lt; a)</code>.
-</li>
-
-<li><b>"index":</b>
-The indexing access <code>table[key]</code>.
-
-
-<pre>
- function gettable_event (table, key)
- local h
- if type(table) == "table" then
- local v = rawget(table, key)
- if v ~= nil then return v end
- h = metatable(table).__index
- if h == nil then return nil end
- else
- h = metatable(table).__index
- if h == nil then
- error(&middot;&middot;&middot;)
- end
- end
- if type(h) == "function" then
- return (h(table, key)) -- call the handler
- else return h[key] -- or repeat operation on it
- end
- end
-</pre><p>
-</li>
-
-<li><b>"newindex":</b>
-The indexing assignment <code>table[key] = value</code>.
-
-
-<pre>
- function settable_event (table, key, value)
- local h
- if type(table) == "table" then
- local v = rawget(table, key)
- if v ~= nil then rawset(table, key, value); return end
- h = metatable(table).__newindex
- if h == nil then rawset(table, key, value); return end
- else
- h = metatable(table).__newindex
- if h == nil then
- error(&middot;&middot;&middot;)
- end
- end
- if type(h) == "function" then
- h(table, key,value) -- call the handler
- else h[key] = value -- or repeat operation on it
- end
- end
-</pre><p>
-</li>
-
-<li><b>"call":</b>
-called when Lua calls a value.
-
-
-<pre>
- function function_event (func, ...)
- if type(func) == "function" then
- return func(...) -- primitive call
- else
- local h = metatable(func).__call
- if h then
- return h(func, ...)
- else
- error(&middot;&middot;&middot;)
- end
- end
- end
-</pre><p>
-</li>
-
-</ul>
-
-
-
-
-<h2>2.9 - <a name="2.9">Environments</a></h2>
-
-<p>
-Besides metatables,
-objects of types thread, function, and userdata
-have another table associated with them,
-called their <em>environment</em>.
-Like metatables, environments are regular tables and
-multiple objects can share the same environment.
-
-
-<p>
-Threads are created sharing the environment of the creating thread.
-Userdata and C&nbsp;functions are created sharing the environment
-of the creating C&nbsp;function.
-Non-nested Lua functions
-(created by <a href="#pdf-loadfile"><code>loadfile</code></a>, <a href="#pdf-loadstring"><code>loadstring</code></a> or <a href="#pdf-load"><code>load</code></a>)
-are created sharing the environment of the creating thread.
-Nested Lua functions are created sharing the environment of
-the creating Lua function.
-
-
-<p>
-Environments associated with userdata have no meaning for Lua.
-It is only a convenience feature for programmers to associate a table to
-a userdata.
-
-
-<p>
-Environments associated with threads are called
-<em>global environments</em>.
-They are used as the default environment for threads and
-non-nested Lua functions created by the thread
-and can be directly accessed by C&nbsp;code (see <a href="#3.3">&sect;3.3</a>).
-
-
-<p>
-The environment associated with a C&nbsp;function can be directly
-accessed by C&nbsp;code (see <a href="#3.3">&sect;3.3</a>).
-It is used as the default environment for other C&nbsp;functions
-and userdata created by the function.
-
-
-<p>
-Environments associated with Lua functions are used to resolve
-all accesses to global variables within the function (see <a href="#2.3">&sect;2.3</a>).
-They are used as the default environment for nested Lua functions
-created by the function.
-
-
-<p>
-You can change the environment of a Lua function or the
-running thread by calling <a href="#pdf-setfenv"><code>setfenv</code></a>.
-You can get the environment of a Lua function or the running thread
-by calling <a href="#pdf-getfenv"><code>getfenv</code></a>.
-To manipulate the environment of other objects
-(userdata, C&nbsp;functions, other threads) you must
-use the C&nbsp;API.
-
-
-
-
-
-<h2>2.10 - <a name="2.10">Garbage Collection</a></h2>
-
-<p>
-Lua performs automatic memory management.
-This means that
-you have to worry neither about allocating memory for new objects
-nor about freeing it when the objects are no longer needed.
-Lua manages memory automatically by running
-a <em>garbage collector</em> from time to time
-to collect all <em>dead objects</em>
-(that is, objects that are no longer accessible from Lua).
-All memory used by Lua is subject to automatic management:
-tables, userdata, functions, threads, strings, etc.
-
-
-<p>
-Lua implements an incremental mark-and-sweep collector.
-It uses two numbers to control its garbage-collection cycles:
-the <em>garbage-collector pause</em> and
-the <em>garbage-collector step multiplier</em>.
-Both use percentage points as units
-(so that a value of 100 means an internal value of 1).
-
-
-<p>
-The garbage-collector pause
-controls how long the collector waits before starting a new cycle.
-Larger values make the collector less aggressive.
-Values smaller than 100 mean the collector will not wait to
-start a new cycle.
-A value of 200 means that the collector waits for the total memory in use
-to double before starting a new cycle.
-
-
-<p>
-The step multiplier
-controls the relative speed of the collector relative to
-memory allocation.
-Larger values make the collector more aggressive but also increase
-the size of each incremental step.
-Values smaller than 100 make the collector too slow and
-can result in the collector never finishing a cycle.
-The default, 200, means that the collector runs at "twice"
-the speed of memory allocation.
-
-
-<p>
-You can change these numbers by calling <a href="#lua_gc"><code>lua_gc</code></a> in C
-or <a href="#pdf-collectgarbage"><code>collectgarbage</code></a> in Lua.
-With these functions you can also control
-the collector directly (e.g., stop and restart it).
-
-
-
-<h3>2.10.1 - <a name="2.10.1">Garbage-Collection Metamethods</a></h3>
-
-<p>
-Using the C&nbsp;API,
-you can set garbage-collector metamethods for userdata (see <a href="#2.8">&sect;2.8</a>).
-These metamethods are also called <em>finalizers</em>.
-Finalizers allow you to coordinate Lua's garbage collection
-with external resource management
-(such as closing files, network or database connections,
-or freeing your own memory).
-
-
-<p>
-Garbage userdata with a field <code>__gc</code> in their metatables are not
-collected immediately by the garbage collector.
-Instead, Lua puts them in a list.
-After the collection,
-Lua does the equivalent of the following function
-for each userdata in that list:
-
-<pre>
- function gc_event (udata)
- local h = metatable(udata).__gc
- if h then
- h(udata)
- end
- end
-</pre>
-
-<p>
-At the end of each garbage-collection cycle,
-the finalizers for userdata are called in <em>reverse</em>
-order of their creation,
-among those collected in that cycle.
-That is, the first finalizer to be called is the one associated
-with the userdata created last in the program.
-The userdata itself is freed only in the next garbage-collection cycle.
-
-
-
-
-
-<h3>2.10.2 - <a name="2.10.2">Weak Tables</a></h3>
-
-<p>
-A <em>weak table</em> is a table whose elements are
-<em>weak references</em>.
-A weak reference is ignored by the garbage collector.
-In other words,
-if the only references to an object are weak references,
-then the garbage collector will collect this object.
-
-
-<p>
-A weak table can have weak keys, weak values, or both.
-A table with weak keys allows the collection of its keys,
-but prevents the collection of its values.
-A table with both weak keys and weak values allows the collection of
-both keys and values.
-In any case, if either the key or the value is collected,
-the whole pair is removed from the table.
-The weakness of a table is controlled by the
-<code>__mode</code> field of its metatable.
-If the <code>__mode</code> field is a string containing the character&nbsp;'<code>k</code>',
-the keys in the table are weak.
-If <code>__mode</code> contains '<code>v</code>',
-the values in the table are weak.
-
-
-<p>
-After you use a table as a metatable,
-you should not change the value of its <code>__mode</code> field.
-Otherwise, the weak behavior of the tables controlled by this
-metatable is undefined.
-
-
-
-
-
-
-
-<h2>2.11 - <a name="2.11">Coroutines</a></h2>
-
-<p>
-Lua supports coroutines,
-also called <em>collaborative multithreading</em>.
-A coroutine in Lua represents an independent thread of execution.
-Unlike threads in multithread systems, however,
-a coroutine only suspends its execution by explicitly calling
-a yield function.
-
-
-<p>
-You create a coroutine with a call to <a href="#pdf-coroutine.create"><code>coroutine.create</code></a>.
-Its sole argument is a function
-that is the main function of the coroutine.
-The <code>create</code> function only creates a new coroutine and
-returns a handle to it (an object of type <em>thread</em>);
-it does not start the coroutine execution.
-
-
-<p>
-When you first call <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a>,
-passing as its first argument
-a thread returned by <a href="#pdf-coroutine.create"><code>coroutine.create</code></a>,
-the coroutine starts its execution,
-at the first line of its main function.
-Extra arguments passed to <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a> are passed on
-to the coroutine main function.
-After the coroutine starts running,
-it runs until it terminates or <em>yields</em>.
-
-
-<p>
-A coroutine can terminate its execution in two ways:
-normally, when its main function returns
-(explicitly or implicitly, after the last instruction);
-and abnormally, if there is an unprotected error.
-In the first case, <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a> returns <b>true</b>,
-plus any values returned by the coroutine main function.
-In case of errors, <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a> returns <b>false</b>
-plus an error message.
-
-
-<p>
-A coroutine yields by calling <a href="#pdf-coroutine.yield"><code>coroutine.yield</code></a>.
-When a coroutine yields,
-the corresponding <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a> returns immediately,
-even if the yield happens inside nested function calls
-(that is, not in the main function,
-but in a function directly or indirectly called by the main function).
-In the case of a yield, <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a> also returns <b>true</b>,
-plus any values passed to <a href="#pdf-coroutine.yield"><code>coroutine.yield</code></a>.
-The next time you resume the same coroutine,
-it continues its execution from the point where it yielded,
-with the call to <a href="#pdf-coroutine.yield"><code>coroutine.yield</code></a> returning any extra
-arguments passed to <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a>.
-
-
-<p>
-Like <a href="#pdf-coroutine.create"><code>coroutine.create</code></a>,
-the <a href="#pdf-coroutine.wrap"><code>coroutine.wrap</code></a> function also creates a coroutine,
-but instead of returning the coroutine itself,
-it returns a function that, when called, resumes the coroutine.
-Any arguments passed to this function
-go as extra arguments to <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a>.
-<a href="#pdf-coroutine.wrap"><code>coroutine.wrap</code></a> returns all the values returned by <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a>,
-except the first one (the boolean error code).
-Unlike <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a>,
-<a href="#pdf-coroutine.wrap"><code>coroutine.wrap</code></a> does not catch errors;
-any error is propagated to the caller.
-
-
-<p>
-As an example,
-consider the following code:
-
-<pre>
- function foo (a)
- print("foo", a)
- return coroutine.yield(2*a)
- end
-
- co = coroutine.create(function (a,b)
- print("co-body", a, b)
- local r = foo(a+1)
- print("co-body", r)
- local r, s = coroutine.yield(a+b, a-b)
- print("co-body", r, s)
- return b, "end"
- end)
-
- print("main", coroutine.resume(co, 1, 10))
- print("main", coroutine.resume(co, "r"))
- print("main", coroutine.resume(co, "x", "y"))
- print("main", coroutine.resume(co, "x", "y"))
-</pre><p>
-When you run it, it produces the following output:
-
-<pre>
- co-body 1 10
- foo 2
-
- main true 4
- co-body r
- main true 11 -9
- co-body x y
- main true 10 end
- main false cannot resume dead coroutine
-</pre>
-
-
-
-
-<h1>3 - <a name="3">The Application Program Interface</a></h1>
-
-<p>
-
-This section describes the C&nbsp;API for Lua, that is,
-the set of C&nbsp;functions available to the host program to communicate
-with Lua.
-All API functions and related types and constants
-are declared in the header file <a name="pdf-lua.h"><code>lua.h</code></a>.
-
-
-<p>
-Even when we use the term "function",
-any facility in the API may be provided as a macro instead.
-All such macros use each of their arguments exactly once
-(except for the first argument, which is always a Lua state),
-and so do not generate any hidden side-effects.
-
-
-<p>
-As in most C&nbsp;libraries,
-the Lua API functions do not check their arguments for validity or consistency.
-However, you can change this behavior by compiling Lua
-with a proper definition for the macro <a name="pdf-luai_apicheck"><code>luai_apicheck</code></a>,
-in file <code>luaconf.h</code>.
-
-
-
-<h2>3.1 - <a name="3.1">The Stack</a></h2>
-
-<p>
-Lua uses a <em>virtual stack</em> to pass values to and from C.
-Each element in this stack represents a Lua value
-(<b>nil</b>, number, string, etc.).
-
-
-<p>
-Whenever Lua calls C, the called function gets a new stack,
-which is independent of previous stacks and of stacks of
-C&nbsp;functions that are still active.
-This stack initially contains any arguments to the C&nbsp;function
-and it is where the C&nbsp;function pushes its results
-to be returned to the caller (see <a href="#lua_CFunction"><code>lua_CFunction</code></a>).
-
-
-<p>
-For convenience,
-most query operations in the API do not follow a strict stack discipline.
-Instead, they can refer to any element in the stack
-by using an <em>index</em>:
-A positive index represents an <em>absolute</em> stack position
-(starting at&nbsp;1);
-a negative index represents an <em>offset</em> relative to the top of the stack.
-More specifically, if the stack has <em>n</em> elements,
-then index&nbsp;1 represents the first element
-(that is, the element that was pushed onto the stack first)
-and
-index&nbsp;<em>n</em> represents the last element;
-index&nbsp;-1 also represents the last element
-(that is, the element at the&nbsp;top)
-and index <em>-n</em> represents the first element.
-We say that an index is <em>valid</em>
-if it lies between&nbsp;1 and the stack top
-(that is, if <code>1 &le; abs(index) &le; top</code>).
-
-
-
-
-
-
-<h2>3.2 - <a name="3.2">Stack Size</a></h2>
-
-<p>
-When you interact with Lua API,
-you are responsible for ensuring consistency.
-In particular,
-<em>you are responsible for controlling stack overflow</em>.
-You can use the function <a href="#lua_checkstack"><code>lua_checkstack</code></a>
-to grow the stack size.
-
-
-<p>
-Whenever Lua calls C,
-it ensures that at least <a name="pdf-LUA_MINSTACK"><code>LUA_MINSTACK</code></a> stack positions are available.
-<code>LUA_MINSTACK</code> is defined as 20,
-so that usually you do not have to worry about stack space
-unless your code has loops pushing elements onto the stack.
-
-
-<p>
-Most query functions accept as indices any value inside the
-available stack space, that is, indices up to the maximum stack size
-you have set through <a href="#lua_checkstack"><code>lua_checkstack</code></a>.
-Such indices are called <em>acceptable indices</em>.
-More formally, we define an <em>acceptable index</em>
-as follows:
-
-<pre>
- (index &lt; 0 &amp;&amp; abs(index) &lt;= top) ||
- (index &gt; 0 &amp;&amp; index &lt;= stackspace)
-</pre><p>
-Note that 0 is never an acceptable index.
-
-
-
-
-
-<h2>3.3 - <a name="3.3">Pseudo-Indices</a></h2>
-
-<p>
-Unless otherwise noted,
-any function that accepts valid indices can also be called with
-<em>pseudo-indices</em>,
-which represent some Lua values that are accessible to C&nbsp;code
-but which are not in the stack.
-Pseudo-indices are used to access the thread environment,
-the function environment,
-the registry,
-and the upvalues of a C&nbsp;function (see <a href="#3.4">&sect;3.4</a>).
-
-
-<p>
-The thread environment (where global variables live) is
-always at pseudo-index <a name="pdf-LUA_GLOBALSINDEX"><code>LUA_GLOBALSINDEX</code></a>.
-The environment of the running C&nbsp;function is always
-at pseudo-index <a name="pdf-LUA_ENVIRONINDEX"><code>LUA_ENVIRONINDEX</code></a>.
-
-
-<p>
-To access and change the value of global variables,
-you can use regular table operations over an environment table.
-For instance, to access the value of a global variable, do
-
-<pre>
- lua_getfield(L, LUA_GLOBALSINDEX, varname);
-</pre>
-
-
-
-
-<h2>3.4 - <a name="3.4">C Closures</a></h2>
-
-<p>
-When a C&nbsp;function is created,
-it is possible to associate some values with it,
-thus creating a <em>C&nbsp;closure</em>;
-these values are called <em>upvalues</em> and are
-accessible to the function whenever it is called
-(see <a href="#lua_pushcclosure"><code>lua_pushcclosure</code></a>).
-
-
-<p>
-Whenever a C&nbsp;function is called,
-its upvalues are located at specific pseudo-indices.
-These pseudo-indices are produced by the macro
-<a name="lua_upvalueindex"><code>lua_upvalueindex</code></a>.
-The first value associated with a function is at position
-<code>lua_upvalueindex(1)</code>, and so on.
-Any access to <code>lua_upvalueindex(<em>n</em>)</code>,
-where <em>n</em> is greater than the number of upvalues of the
-current function (but not greater than 256),
-produces an acceptable (but invalid) index.
-
-
-
-
-
-<h2>3.5 - <a name="3.5">Registry</a></h2>
-
-<p>
-Lua provides a <em>registry</em>,
-a pre-defined table that can be used by any C&nbsp;code to
-store whatever Lua value it needs to store.
-This table is always located at pseudo-index
-<a name="pdf-LUA_REGISTRYINDEX"><code>LUA_REGISTRYINDEX</code></a>.
-Any C&nbsp;library can store data into this table,
-but it should take care to choose keys different from those used
-by other libraries, to avoid collisions.
-Typically, you should use as key a string containing your library name
-or a light userdata with the address of a C&nbsp;object in your code.
-
-
-<p>
-The integer keys in the registry are used by the reference mechanism,
-implemented by the auxiliary library,
-and therefore should not be used for other purposes.
-
-
-
-
-
-<h2>3.6 - <a name="3.6">Error Handling in C</a></h2>
-
-<p>
-Internally, Lua uses the C <code>longjmp</code> facility to handle errors.
-(You can also choose to use exceptions if you use C++;
-see file <code>luaconf.h</code>.)
-When Lua faces any error
-(such as memory allocation errors, type errors, syntax errors,
-and runtime errors)
-it <em>raises</em> an error;
-that is, it does a long jump.
-A <em>protected environment</em> uses <code>setjmp</code>
-to set a recover point;
-any error jumps to the most recent active recover point.
-
-
-<p>
-Most functions in the API can throw an error,
-for instance due to a memory allocation error.
-The documentation for each function indicates whether
-it can throw errors.
-
-
-<p>
-Inside a C&nbsp;function you can throw an error by calling <a href="#lua_error"><code>lua_error</code></a>.
-
-
-
-
-
-<h2>3.7 - <a name="3.7">Functions and Types</a></h2>
-
-<p>
-Here we list all functions and types from the C&nbsp;API in
-alphabetical order.
-Each function has an indicator like this:
-<span class="apii">[-o, +p, <em>x</em>]</span>
-
-
-<p>
-The first field, <code>o</code>,
-is how many elements the function pops from the stack.
-The second field, <code>p</code>,
-is how many elements the function pushes onto the stack.
-(Any function always pushes its results after popping its arguments.)
-A field in the form <code>x|y</code> means the function can push (or pop)
-<code>x</code> or <code>y</code> elements,
-depending on the situation;
-an interrogation mark '<code>?</code>' means that
-we cannot know how many elements the function pops/pushes
-by looking only at its arguments
-(e.g., they may depend on what is on the stack).
-The third field, <code>x</code>,
-tells whether the function may throw errors:
-'<code>-</code>' means the function never throws any error;
-'<code>m</code>' means the function may throw an error
-only due to not enough memory;
-'<code>e</code>' means the function may throw other kinds of errors;
-'<code>v</code>' means the function may throw an error on purpose.
-
-
-
-<hr><h3><a name="lua_Alloc"><code>lua_Alloc</code></a></h3>
-<pre>typedef void * (*lua_Alloc) (void *ud,
- void *ptr,
- size_t osize,
- size_t nsize);</pre>
-
-<p>
-The type of the memory-allocation function used by Lua states.
-The allocator function must provide a
-functionality similar to <code>realloc</code>,
-but not exactly the same.
-Its arguments are
-<code>ud</code>, an opaque pointer passed to <a href="#lua_newstate"><code>lua_newstate</code></a>;
-<code>ptr</code>, a pointer to the block being allocated/reallocated/freed;
-<code>osize</code>, the original size of the block;
-<code>nsize</code>, the new size of the block.
-<code>ptr</code> is <code>NULL</code> if and only if <code>osize</code> is zero.
-When <code>nsize</code> is zero, the allocator must return <code>NULL</code>;
-if <code>osize</code> is not zero,
-it should free the block pointed to by <code>ptr</code>.
-When <code>nsize</code> is not zero, the allocator returns <code>NULL</code>
-if and only if it cannot fill the request.
-When <code>nsize</code> is not zero and <code>osize</code> is zero,
-the allocator should behave like <code>malloc</code>.
-When <code>nsize</code> and <code>osize</code> are not zero,
-the allocator behaves like <code>realloc</code>.
-Lua assumes that the allocator never fails when
-<code>osize &gt;= nsize</code>.
-
-
-<p>
-Here is a simple implementation for the allocator function.
-It is used in the auxiliary library by <a href="#luaL_newstate"><code>luaL_newstate</code></a>.
-
-<pre>
- static void *l_alloc (void *ud, void *ptr, size_t osize,
- size_t nsize) {
- (void)ud; (void)osize; /* not used */
- if (nsize == 0) {
- free(ptr);
- return NULL;
- }
- else
- return realloc(ptr, nsize);
- }
-</pre><p>
-This code assumes
-that <code>free(NULL)</code> has no effect and that
-<code>realloc(NULL, size)</code> is equivalent to <code>malloc(size)</code>.
-ANSI&nbsp;C ensures both behaviors.
-
-
-
-
-
-<hr><h3><a name="lua_atpanic"><code>lua_atpanic</code></a></h3><p>
-<span class="apii">[-0, +0, <em>-</em>]</span>
-<pre>lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf);</pre>
-
-<p>
-Sets a new panic function and returns the old one.
-
-
-<p>
-If an error happens outside any protected environment,
-Lua calls a <em>panic function</em>
-and then calls <code>exit(EXIT_FAILURE)</code>,
-thus exiting the host application.
-Your panic function can avoid this exit by
-never returning (e.g., doing a long jump).
-
-
-<p>
-The panic function can access the error message at the top of the stack.
-
-
-
-
-
-<hr><h3><a name="lua_call"><code>lua_call</code></a></h3><p>
-<span class="apii">[-(nargs + 1), +nresults, <em>e</em>]</span>
-<pre>void lua_call (lua_State *L, int nargs, int nresults);</pre>
-
-<p>
-Calls a function.
-
-
-<p>
-To call a function you must use the following protocol:
-first, the function to be called is pushed onto the stack;
-then, the arguments to the function are pushed
-in direct order;
-that is, the first argument is pushed first.
-Finally you call <a href="#lua_call"><code>lua_call</code></a>;
-<code>nargs</code> is the number of arguments that you pushed onto the stack.
-All arguments and the function value are popped from the stack
-when the function is called.
-The function results are pushed onto the stack when the function returns.
-The number of results is adjusted to <code>nresults</code>,
-unless <code>nresults</code> is <a name="pdf-LUA_MULTRET"><code>LUA_MULTRET</code></a>.
-In this case, <em>all</em> results from the function are pushed.
-Lua takes care that the returned values fit into the stack space.
-The function results are pushed onto the stack in direct order
-(the first result is pushed first),
-so that after the call the last result is on the top of the stack.
-
-
-<p>
-Any error inside the called function is propagated upwards
-(with a <code>longjmp</code>).
-
-
-<p>
-The following example shows how the host program can do the
-equivalent to this Lua code:
-
-<pre>
- a = f("how", t.x, 14)
-</pre><p>
-Here it is in&nbsp;C:
-
-<pre>
- lua_getfield(L, LUA_GLOBALSINDEX, "f"); /* function to be called */
- lua_pushstring(L, "how"); /* 1st argument */
- lua_getfield(L, LUA_GLOBALSINDEX, "t"); /* table to be indexed */
- lua_getfield(L, -1, "x"); /* push result of t.x (2nd arg) */
- lua_remove(L, -2); /* remove 't' from the stack */
- lua_pushinteger(L, 14); /* 3rd argument */
- lua_call(L, 3, 1); /* call 'f' with 3 arguments and 1 result */
- lua_setfield(L, LUA_GLOBALSINDEX, "a"); /* set global 'a' */
-</pre><p>
-Note that the code above is "balanced":
-at its end, the stack is back to its original configuration.
-This is considered good programming practice.
-
-
-
-
-
-<hr><h3><a name="lua_CFunction"><code>lua_CFunction</code></a></h3>
-<pre>typedef int (*lua_CFunction) (lua_State *L);</pre>
-
-<p>
-Type for C&nbsp;functions.
-
-
-<p>
-In order to communicate properly with Lua,
-a C&nbsp;function must use the following protocol,
-which defines the way parameters and results are passed:
-a C&nbsp;function receives its arguments from Lua in its stack
-in direct order (the first argument is pushed first).
-So, when the function starts,
-<code>lua_gettop(L)</code> returns the number of arguments received by the function.
-The first argument (if any) is at index 1
-and its last argument is at index <code>lua_gettop(L)</code>.
-To return values to Lua, a C&nbsp;function just pushes them onto the stack,
-in direct order (the first result is pushed first),
-and returns the number of results.
-Any other value in the stack below the results will be properly
-discarded by Lua.
-Like a Lua function, a C&nbsp;function called by Lua can also return
-many results.
-
-
-<p>
-As an example, the following function receives a variable number
-of numerical arguments and returns their average and sum:
-
-<pre>
- static int foo (lua_State *L) {
- int n = lua_gettop(L); /* number of arguments */
- lua_Number sum = 0;
- int i;
- for (i = 1; i &lt;= n; i++) {
- if (!lua_isnumber(L, i)) {
- lua_pushstring(L, "incorrect argument");
- lua_error(L);
- }
- sum += lua_tonumber(L, i);
- }
- lua_pushnumber(L, sum/n); /* first result */
- lua_pushnumber(L, sum); /* second result */
- return 2; /* number of results */
- }
-</pre>
-
-
-
-
-<hr><h3><a name="lua_checkstack"><code>lua_checkstack</code></a></h3><p>
-<span class="apii">[-0, +0, <em>m</em>]</span>
-<pre>int lua_checkstack (lua_State *L, int extra);</pre>
-
-<p>
-Ensures that there are at least <code>extra</code> free stack slots in the stack.
-It returns false if it cannot grow the stack to that size.
-This function never shrinks the stack;
-if the stack is already larger than the new size,
-it is left unchanged.
-
-
-
-
-
-<hr><h3><a name="lua_close"><code>lua_close</code></a></h3><p>
-<span class="apii">[-0, +0, <em>-</em>]</span>
-<pre>void lua_close (lua_State *L);</pre>
-
-<p>
-Destroys all objects in the given Lua state
-(calling the corresponding garbage-collection metamethods, if any)
-and frees all dynamic memory used by this state.
-On several platforms, you may not need to call this function,
-because all resources are naturally released when the host program ends.
-On the other hand, long-running programs,
-such as a daemon or a web server,
-might need to release states as soon as they are not needed,
-to avoid growing too large.
-
-
-
-
-
-<hr><h3><a name="lua_concat"><code>lua_concat</code></a></h3><p>
-<span class="apii">[-n, +1, <em>e</em>]</span>
-<pre>void lua_concat (lua_State *L, int n);</pre>
-
-<p>
-Concatenates the <code>n</code> values at the top of the stack,
-pops them, and leaves the result at the top.
-If <code>n</code>&nbsp;is&nbsp;1, the result is the single value on the stack
-(that is, the function does nothing);
-if <code>n</code> is 0, the result is the empty string.
-Concatenation is performed following the usual semantics of Lua
-(see <a href="#2.5.4">&sect;2.5.4</a>).
-
-
-
-
-
-<hr><h3><a name="lua_cpcall"><code>lua_cpcall</code></a></h3><p>
-<span class="apii">[-0, +(0|1), <em>-</em>]</span>
-<pre>int lua_cpcall (lua_State *L, lua_CFunction func, void *ud);</pre>
-
-<p>
-Calls the C&nbsp;function <code>func</code> in protected mode.
-<code>func</code> starts with only one element in its stack,
-a light userdata containing <code>ud</code>.
-In case of errors,
-<a href="#lua_cpcall"><code>lua_cpcall</code></a> returns the same error codes as <a href="#lua_pcall"><code>lua_pcall</code></a>,
-plus the error object on the top of the stack;
-otherwise, it returns zero, and does not change the stack.
-All values returned by <code>func</code> are discarded.
-
-
-
-
-
-<hr><h3><a name="lua_createtable"><code>lua_createtable</code></a></h3><p>
-<span class="apii">[-0, +1, <em>m</em>]</span>
-<pre>void lua_createtable (lua_State *L, int narr, int nrec);</pre>
-
-<p>
-Creates a new empty table and pushes it onto the stack.
-The new table has space pre-allocated
-for <code>narr</code> array elements and <code>nrec</code> non-array elements.
-This pre-allocation is useful when you know exactly how many elements
-the table will have.
-Otherwise you can use the function <a href="#lua_newtable"><code>lua_newtable</code></a>.
-
-
-
-
-
-<hr><h3><a name="lua_dump"><code>lua_dump</code></a></h3><p>
-<span class="apii">[-0, +0, <em>m</em>]</span>
-<pre>int lua_dump (lua_State *L, lua_Writer writer, void *data);</pre>
-
-<p>
-Dumps a function as a binary chunk.
-Receives a Lua function on the top of the stack
-and produces a binary chunk that,
-if loaded again,
-results in a function equivalent to the one dumped.
-As it produces parts of the chunk,
-<a href="#lua_dump"><code>lua_dump</code></a> calls function <code>writer</code> (see <a href="#lua_Writer"><code>lua_Writer</code></a>)
-with the given <code>data</code>
-to write them.
-
-
-<p>
-The value returned is the error code returned by the last
-call to the writer;
-0&nbsp;means no errors.
-
-
-<p>
-This function does not pop the Lua function from the stack.
-
-
-
-
-
-<hr><h3><a name="lua_equal"><code>lua_equal</code></a></h3><p>
-<span class="apii">[-0, +0, <em>e</em>]</span>
-<pre>int lua_equal (lua_State *L, int index1, int index2);</pre>
-
-<p>
-Returns 1 if the two values in acceptable indices <code>index1</code> and
-<code>index2</code> are equal,
-following the semantics of the Lua <code>==</code> operator
-(that is, may call metamethods).
-Otherwise returns&nbsp;0.
-Also returns&nbsp;0 if any of the indices is non valid.
-
-
-
-
-
-<hr><h3><a name="lua_error"><code>lua_error</code></a></h3><p>
-<span class="apii">[-1, +0, <em>v</em>]</span>
-<pre>int lua_error (lua_State *L);</pre>
-
-<p>
-Generates a Lua error.
-The error message (which can actually be a Lua value of any type)
-must be on the stack top.
-This function does a long jump,
-and therefore never returns.
-(see <a href="#luaL_error"><code>luaL_error</code></a>).
-
-
-
-
-
-<hr><h3><a name="lua_gc"><code>lua_gc</code></a></h3><p>
-<span class="apii">[-0, +0, <em>e</em>]</span>
-<pre>int lua_gc (lua_State *L, int what, int data);</pre>
-
-<p>
-Controls the garbage collector.
-
-
-<p>
-This function performs several tasks,
-according to the value of the parameter <code>what</code>:
-
-<ul>
-
-<li><b><code>LUA_GCSTOP</code>:</b>
-stops the garbage collector.
-</li>
-
-<li><b><code>LUA_GCRESTART</code>:</b>
-restarts the garbage collector.
-</li>
-
-<li><b><code>LUA_GCCOLLECT</code>:</b>
-performs a full garbage-collection cycle.
-</li>
-
-<li><b><code>LUA_GCCOUNT</code>:</b>
-returns the current amount of memory (in Kbytes) in use by Lua.
-</li>
-
-<li><b><code>LUA_GCCOUNTB</code>:</b>
-returns the remainder of dividing the current amount of bytes of
-memory in use by Lua by 1024.
-</li>
-
-<li><b><code>LUA_GCSTEP</code>:</b>
-performs an incremental step of garbage collection.
-The step "size" is controlled by <code>data</code>
-(larger values mean more steps) in a non-specified way.
-If you want to control the step size
-you must experimentally tune the value of <code>data</code>.
-The function returns 1 if the step finished a
-garbage-collection cycle.
-</li>
-
-<li><b><code>LUA_GCSETPAUSE</code>:</b>
-sets <code>data</code> as the new value
-for the <em>pause</em> of the collector (see <a href="#2.10">&sect;2.10</a>).
-The function returns the previous value of the pause.
-</li>
-
-<li><b><code>LUA_GCSETSTEPMUL</code>:</b>
-sets <code>data</code> as the new value for the <em>step multiplier</em> of
-the collector (see <a href="#2.10">&sect;2.10</a>).
-The function returns the previous value of the step multiplier.
-</li>
-
-</ul>
-
-
-
-
-<hr><h3><a name="lua_getallocf"><code>lua_getallocf</code></a></h3><p>
-<span class="apii">[-0, +0, <em>-</em>]</span>
-<pre>lua_Alloc lua_getallocf (lua_State *L, void **ud);</pre>
-
-<p>
-Returns the memory-allocation function of a given state.
-If <code>ud</code> is not <code>NULL</code>, Lua stores in <code>*ud</code> the
-opaque pointer passed to <a href="#lua_newstate"><code>lua_newstate</code></a>.
-
-
-
-
-
-<hr><h3><a name="lua_getfenv"><code>lua_getfenv</code></a></h3><p>
-<span class="apii">[-0, +1, <em>-</em>]</span>
-<pre>void lua_getfenv (lua_State *L, int index);</pre>
-
-<p>
-Pushes onto the stack the environment table of
-the value at the given index.
-
-
-
-
-
-<hr><h3><a name="lua_getfield"><code>lua_getfield</code></a></h3><p>
-<span class="apii">[-0, +1, <em>e</em>]</span>
-<pre>void lua_getfield (lua_State *L, int index, const char *k);</pre>
-
-<p>
-Pushes onto the stack the value <code>t[k]</code>,
-where <code>t</code> is the value at the given valid index.
-As in Lua, this function may trigger a metamethod
-for the "index" event (see <a href="#2.8">&sect;2.8</a>).
-
-
-
-
-
-<hr><h3><a name="lua_getglobal"><code>lua_getglobal</code></a></h3><p>
-<span class="apii">[-0, +1, <em>e</em>]</span>
-<pre>void lua_getglobal (lua_State *L, const char *name);</pre>
-
-<p>
-Pushes onto the stack the value of the global <code>name</code>.
-It is defined as a macro:
-
-<pre>
- #define lua_getglobal(L,s) lua_getfield(L, LUA_GLOBALSINDEX, s)
-</pre>
-
-
-
-
-<hr><h3><a name="lua_getmetatable"><code>lua_getmetatable</code></a></h3><p>
-<span class="apii">[-0, +(0|1), <em>-</em>]</span>
-<pre>int lua_getmetatable (lua_State *L, int index);</pre>
-
-<p>
-Pushes onto the stack the metatable of the value at the given
-acceptable index.
-If the index is not valid,
-or if the value does not have a metatable,
-the function returns&nbsp;0 and pushes nothing on the stack.
-
-
-
-
-
-<hr><h3><a name="lua_gettable"><code>lua_gettable</code></a></h3><p>
-<span class="apii">[-1, +1, <em>e</em>]</span>
-<pre>void lua_gettable (lua_State *L, int index);</pre>
-
-<p>
-Pushes onto the stack the value <code>t[k]</code>,
-where <code>t</code> is the value at the given valid index
-and <code>k</code> is the value at the top of the stack.
-
-
-<p>
-This function pops the key from the stack
-(putting the resulting value in its place).
-As in Lua, this function may trigger a metamethod
-for the "index" event (see <a href="#2.8">&sect;2.8</a>).
-
-
-
-
-
-<hr><h3><a name="lua_gettop"><code>lua_gettop</code></a></h3><p>
-<span class="apii">[-0, +0, <em>-</em>]</span>
-<pre>int lua_gettop (lua_State *L);</pre>
-
-<p>
-Returns the index of the top element in the stack.
-Because indices start at&nbsp;1,
-this result is equal to the number of elements in the stack
-(and so 0&nbsp;means an empty stack).
-
-
-
-
-
-<hr><h3><a name="lua_insert"><code>lua_insert</code></a></h3><p>
-<span class="apii">[-1, +1, <em>-</em>]</span>
-<pre>void lua_insert (lua_State *L, int index);</pre>
-
-<p>
-Moves the top element into the given valid index,
-shifting up the elements above this index to open space.
-Cannot be called with a pseudo-index,
-because a pseudo-index is not an actual stack position.
-
-
-
-
-
-<hr><h3><a name="lua_Integer"><code>lua_Integer</code></a></h3>
-<pre>typedef ptrdiff_t lua_Integer;</pre>
-
-<p>
-The type used by the Lua API to represent integral values.
-
-
-<p>
-By default it is a <code>ptrdiff_t</code>,
-which is usually the largest signed integral type the machine handles
-"comfortably".
-
-
-
-
-
-<hr><h3><a name="lua_isboolean"><code>lua_isboolean</code></a></h3><p>
-<span class="apii">[-0, +0, <em>-</em>]</span>
-<pre>int lua_isboolean (lua_State *L, int index);</pre>
-
-<p>
-Returns 1 if the value at the given acceptable index has type boolean,
-and 0&nbsp;otherwise.
-
-
-
-
-
-<hr><h3><a name="lua_iscfunction"><code>lua_iscfunction</code></a></h3><p>
-<span class="apii">[-0, +0, <em>-</em>]</span>
-<pre>int lua_iscfunction (lua_State *L, int index);</pre>
-
-<p>
-Returns 1 if the value at the given acceptable index is a C&nbsp;function,
-and 0&nbsp;otherwise.
-
-
-
-
-
-<hr><h3><a name="lua_isfunction"><code>lua_isfunction</code></a></h3><p>
-<span class="apii">[-0, +0, <em>-</em>]</span>
-<pre>int lua_isfunction (lua_State *L, int index);</pre>
-
-<p>
-Returns 1 if the value at the given acceptable index is a function
-(either C or Lua), and 0&nbsp;otherwise.
-
-
-
-
-
-<hr><h3><a name="lua_islightuserdata"><code>lua_islightuserdata</code></a></h3><p>
-<span class="apii">[-0, +0, <em>-</em>]</span>
-<pre>int lua_islightuserdata (lua_State *L, int index);</pre>
-
-<p>
-Returns 1 if the value at the given acceptable index is a light userdata,
-and 0&nbsp;otherwise.
-
-
-
-
-
-<hr><h3><a name="lua_isnil"><code>lua_isnil</code></a></h3><p>
-<span class="apii">[-0, +0, <em>-</em>]</span>
-<pre>int lua_isnil (lua_State *L, int index);</pre>
-
-<p>
-Returns 1 if the value at the given acceptable index is <b>nil</b>,
-and 0&nbsp;otherwise.
-
-
-
-
-
-<hr><h3><a name="lua_isnone"><code>lua_isnone</code></a></h3><p>
-<span class="apii">[-0, +0, <em>-</em>]</span>
-<pre>int lua_isnone (lua_State *L, int index);</pre>
-
-<p>
-Returns 1 if the given acceptable index is not valid
-(that is, it refers to an element outside the current stack),
-and 0&nbsp;otherwise.
-
-
-
-
-
-<hr><h3><a name="lua_isnoneornil"><code>lua_isnoneornil</code></a></h3><p>
-<span class="apii">[-0, +0, <em>-</em>]</span>
-<pre>int lua_isnoneornil (lua_State *L, int index);</pre>
-
-<p>
-Returns 1 if the given acceptable index is not valid
-(that is, it refers to an element outside the current stack)
-or if the value at this index is <b>nil</b>,
-and 0&nbsp;otherwise.
-
-
-
-
-
-<hr><h3><a name="lua_isnumber"><code>lua_isnumber</code></a></h3><p>
-<span class="apii">[-0, +0, <em>-</em>]</span>
-<pre>int lua_isnumber (lua_State *L, int index);</pre>
-
-<p>
-Returns 1 if the value at the given acceptable index is a number
-or a string convertible to a number,
-and 0&nbsp;otherwise.
-
-
-
-
-
-<hr><h3><a name="lua_isstring"><code>lua_isstring</code></a></h3><p>
-<span class="apii">[-0, +0, <em>-</em>]</span>
-<pre>int lua_isstring (lua_State *L, int index);</pre>
-
-<p>
-Returns 1 if the value at the given acceptable index is a string
-or a number (which is always convertible to a string),
-and 0&nbsp;otherwise.
-
-
-
-
-
-<hr><h3><a name="lua_istable"><code>lua_istable</code></a></h3><p>
-<span class="apii">[-0, +0, <em>-</em>]</span>
-<pre>int lua_istable (lua_State *L, int index);</pre>
-
-<p>
-Returns 1 if the value at the given acceptable index is a table,
-and 0&nbsp;otherwise.
-
-
-
-
-
-<hr><h3><a name="lua_isthread"><code>lua_isthread</code></a></h3><p>
-<span class="apii">[-0, +0, <em>-</em>]</span>
-<pre>int lua_isthread (lua_State *L, int index);</pre>
-
-<p>
-Returns 1 if the value at the given acceptable index is a thread,
-and 0&nbsp;otherwise.
-
-
-
-
-
-<hr><h3><a name="lua_isuserdata"><code>lua_isuserdata</code></a></h3><p>
-<span class="apii">[-0, +0, <em>-</em>]</span>
-<pre>int lua_isuserdata (lua_State *L, int index);</pre>
-
-<p>
-Returns 1 if the value at the given acceptable index is a userdata
-(either full or light), and 0&nbsp;otherwise.
-
-
-
-
-
-<hr><h3><a name="lua_lessthan"><code>lua_lessthan</code></a></h3><p>
-<span class="apii">[-0, +0, <em>e</em>]</span>
-<pre>int lua_lessthan (lua_State *L, int index1, int index2);</pre>
-
-<p>
-Returns 1 if the value at acceptable index <code>index1</code> is smaller
-than the value at acceptable index <code>index2</code>,
-following the semantics of the Lua <code>&lt;</code> operator
-(that is, may call metamethods).
-Otherwise returns&nbsp;0.
-Also returns&nbsp;0 if any of the indices is non valid.
-
-
-
-
-
-<hr><h3><a name="lua_load"><code>lua_load</code></a></h3><p>
-<span class="apii">[-0, +1, <em>-</em>]</span>
-<pre>int lua_load (lua_State *L,
- lua_Reader reader,
- void *data,
- const char *chunkname);</pre>
-
-<p>
-Loads a Lua chunk.
-If there are no errors,
-<a href="#lua_load"><code>lua_load</code></a> pushes the compiled chunk as a Lua
-function on top of the stack.
-Otherwise, it pushes an error message.
-The return values of <a href="#lua_load"><code>lua_load</code></a> are:
-
-<ul>
-
-<li><b>0:</b> no errors;</li>
-
-<li><b><a name="pdf-LUA_ERRSYNTAX"><code>LUA_ERRSYNTAX</code></a>:</b>
-syntax error during pre-compilation;</li>
-
-<li><b><a href="#pdf-LUA_ERRMEM"><code>LUA_ERRMEM</code></a>:</b>
-memory allocation error.</li>
-
-</ul>
-
-<p>
-This function only loads a chunk;
-it does not run it.
-
-
-<p>
-<a href="#lua_load"><code>lua_load</code></a> automatically detects whether the chunk is text or binary,
-and loads it accordingly (see program <code>luac</code>).
-
-
-<p>
-The <a href="#lua_load"><code>lua_load</code></a> function uses a user-supplied <code>reader</code> function
-to read the chunk (see <a href="#lua_Reader"><code>lua_Reader</code></a>).
-The <code>data</code> argument is an opaque value passed to the reader function.
-
-
-<p>
-The <code>chunkname</code> argument gives a name to the chunk,
-which is used for error messages and in debug information (see <a href="#3.8">&sect;3.8</a>).
-
-
-
-
-
-<hr><h3><a name="lua_newstate"><code>lua_newstate</code></a></h3><p>
-<span class="apii">[-0, +0, <em>-</em>]</span>
-<pre>lua_State *lua_newstate (lua_Alloc f, void *ud);</pre>
-
-<p>
-Creates a new, independent state.
-Returns <code>NULL</code> if cannot create the state
-(due to lack of memory).
-The argument <code>f</code> is the allocator function;
-Lua does all memory allocation for this state through this function.
-The second argument, <code>ud</code>, is an opaque pointer that Lua
-simply passes to the allocator in every call.
-
-
-
-
-
-<hr><h3><a name="lua_newtable"><code>lua_newtable</code></a></h3><p>
-<span class="apii">[-0, +1, <em>m</em>]</span>
-<pre>void lua_newtable (lua_State *L);</pre>
-
-<p>
-Creates a new empty table and pushes it onto the stack.
-It is equivalent to <code>lua_createtable(L, 0, 0)</code>.
-
-
-
-
-
-<hr><h3><a name="lua_newthread"><code>lua_newthread</code></a></h3><p>
-<span class="apii">[-0, +1, <em>m</em>]</span>
-<pre>lua_State *lua_newthread (lua_State *L);</pre>
-
-<p>
-Creates a new thread, pushes it on the stack,
-and returns a pointer to a <a href="#lua_State"><code>lua_State</code></a> that represents this new thread.
-The new state returned by this function shares with the original state
-all global objects (such as tables),
-but has an independent execution stack.
-
-
-<p>
-There is no explicit function to close or to destroy a thread.
-Threads are subject to garbage collection,
-like any Lua object.
-
-
-
-
-
-<hr><h3><a name="lua_newuserdata"><code>lua_newuserdata</code></a></h3><p>
-<span class="apii">[-0, +1, <em>m</em>]</span>
-<pre>void *lua_newuserdata (lua_State *L, size_t size);</pre>
-
-<p>
-This function allocates a new block of memory with the given size,
-pushes onto the stack a new full userdata with the block address,
-and returns this address.
-
-
-<p>
-Userdata represent C&nbsp;values in Lua.
-A <em>full userdata</em> represents a block of memory.
-It is an object (like a table):
-you must create it, it can have its own metatable,
-and you can detect when it is being collected.
-A full userdata is only equal to itself (under raw equality).
-
-
-<p>
-When Lua collects a full userdata with a <code>gc</code> metamethod,
-Lua calls the metamethod and marks the userdata as finalized.
-When this userdata is collected again then
-Lua frees its corresponding memory.
-
-
-
-
-
-<hr><h3><a name="lua_next"><code>lua_next</code></a></h3><p>
-<span class="apii">[-1, +(2|0), <em>e</em>]</span>
-<pre>int lua_next (lua_State *L, int index);</pre>
-
-<p>
-Pops a key from the stack,
-and pushes a key-value pair from the table at the given index
-(the "next" pair after the given key).
-If there are no more elements in the table,
-then <a href="#lua_next"><code>lua_next</code></a> returns 0 (and pushes nothing).
-
-
-<p>
-A typical traversal looks like this:
-
-<pre>
- /* table is in the stack at index 't' */
- lua_pushnil(L); /* first key */
- while (lua_next(L, t) != 0) {
- /* uses 'key' (at index -2) and 'value' (at index -1) */
- printf("%s - %s\n",
- lua_typename(L, lua_type(L, -2)),
- lua_typename(L, lua_type(L, -1)));
- /* removes 'value'; keeps 'key' for next iteration */
- lua_pop(L, 1);
- }
-</pre>
-
-<p>
-While traversing a table,
-do not call <a href="#lua_tolstring"><code>lua_tolstring</code></a> directly on a key,
-unless you know that the key is actually a string.
-Recall that <a href="#lua_tolstring"><code>lua_tolstring</code></a> <em>changes</em>
-the value at the given index;
-this confuses the next call to <a href="#lua_next"><code>lua_next</code></a>.
-
-
-
-
-
-<hr><h3><a name="lua_Number"><code>lua_Number</code></a></h3>
-<pre>typedef double lua_Number;</pre>
-
-<p>
-The type of numbers in Lua.
-By default, it is double, but that can be changed in <code>luaconf.h</code>.
-
-
-<p>
-Through the configuration file you can change
-Lua to operate with another type for numbers (e.g., float or long).
-
-
-
-
-
-<hr><h3><a name="lua_objlen"><code>lua_objlen</code></a></h3><p>
-<span class="apii">[-0, +0, <em>-</em>]</span>
-<pre>size_t lua_objlen (lua_State *L, int index);</pre>
-
-<p>
-Returns the "length" of the value at the given acceptable index:
-for strings, this is the string length;
-for tables, this is the result of the length operator ('<code>#</code>');
-for userdata, this is the size of the block of memory allocated
-for the userdata;
-for other values, it is&nbsp;0.
-
-
-
-
-
-<hr><h3><a name="lua_pcall"><code>lua_pcall</code></a></h3><p>
-<span class="apii">[-(nargs + 1), +(nresults|1), <em>-</em>]</span>
-<pre>int lua_pcall (lua_State *L, int nargs, int nresults, int errfunc);</pre>
-
-<p>
-Calls a function in protected mode.
-
-
-<p>
-Both <code>nargs</code> and <code>nresults</code> have the same meaning as
-in <a href="#lua_call"><code>lua_call</code></a>.
-If there are no errors during the call,
-<a href="#lua_pcall"><code>lua_pcall</code></a> behaves exactly like <a href="#lua_call"><code>lua_call</code></a>.
-However, if there is any error,
-<a href="#lua_pcall"><code>lua_pcall</code></a> catches it,
-pushes a single value on the stack (the error message),
-and returns an error code.
-Like <a href="#lua_call"><code>lua_call</code></a>,
-<a href="#lua_pcall"><code>lua_pcall</code></a> always removes the function
-and its arguments from the stack.
-
-
-<p>
-If <code>errfunc</code> is 0,
-then the error message returned on the stack
-is exactly the original error message.
-Otherwise, <code>errfunc</code> is the stack index of an
-<em>error handler function</em>.
-(In the current implementation, this index cannot be a pseudo-index.)
-In case of runtime errors,
-this function will be called with the error message
-and its return value will be the message returned on the stack by <a href="#lua_pcall"><code>lua_pcall</code></a>.
-
-
-<p>
-Typically, the error handler function is used to add more debug
-information to the error message, such as a stack traceback.
-Such information cannot be gathered after the return of <a href="#lua_pcall"><code>lua_pcall</code></a>,
-since by then the stack has unwound.
-
-
-<p>
-The <a href="#lua_pcall"><code>lua_pcall</code></a> function returns 0 in case of success
-or one of the following error codes
-(defined in <code>lua.h</code>):
-
-<ul>
-
-<li><b><a name="pdf-LUA_ERRRUN"><code>LUA_ERRRUN</code></a>:</b>
-a runtime error.
-</li>
-
-<li><b><a name="pdf-LUA_ERRMEM"><code>LUA_ERRMEM</code></a>:</b>
-memory allocation error.
-For such errors, Lua does not call the error handler function.
-</li>
-
-<li><b><a name="pdf-LUA_ERRERR"><code>LUA_ERRERR</code></a>:</b>
-error while running the error handler function.
-</li>
-
-</ul>
-
-
-
-
-<hr><h3><a name="lua_pop"><code>lua_pop</code></a></h3><p>
-<span class="apii">[-n, +0, <em>-</em>]</span>
-<pre>void lua_pop (lua_State *L, int n);</pre>
-
-<p>
-Pops <code>n</code> elements from the stack.
-
-
-
-
-
-<hr><h3><a name="lua_pushboolean"><code>lua_pushboolean</code></a></h3><p>
-<span class="apii">[-0, +1, <em>-</em>]</span>
-<pre>void lua_pushboolean (lua_State *L, int b);</pre>
-
-<p>
-Pushes a boolean value with value <code>b</code> onto the stack.
-
-
-
-
-
-<hr><h3><a name="lua_pushcclosure"><code>lua_pushcclosure</code></a></h3><p>
-<span class="apii">[-n, +1, <em>m</em>]</span>
-<pre>void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n);</pre>
-
-<p>
-Pushes a new C&nbsp;closure onto the stack.
-
-
-<p>
-When a C&nbsp;function is created,
-it is possible to associate some values with it,
-thus creating a C&nbsp;closure (see <a href="#3.4">&sect;3.4</a>);
-these values are then accessible to the function whenever it is called.
-To associate values with a C&nbsp;function,
-first these values should be pushed onto the stack
-(when there are multiple values, the first value is pushed first).
-Then <a href="#lua_pushcclosure"><code>lua_pushcclosure</code></a>
-is called to create and push the C&nbsp;function onto the stack,
-with the argument <code>n</code> telling how many values should be
-associated with the function.
-<a href="#lua_pushcclosure"><code>lua_pushcclosure</code></a> also pops these values from the stack.
-
-
-<p>
-The maximum value for <code>n</code> is 255.
-
-
-
-
-
-<hr><h3><a name="lua_pushcfunction"><code>lua_pushcfunction</code></a></h3><p>
-<span class="apii">[-0, +1, <em>m</em>]</span>
-<pre>void lua_pushcfunction (lua_State *L, lua_CFunction f);</pre>
-
-<p>
-Pushes a C&nbsp;function onto the stack.
-This function receives a pointer to a C function
-and pushes onto the stack a Lua value of type <code>function</code> that,
-when called, invokes the corresponding C&nbsp;function.
-
-
-<p>
-Any function to be registered in Lua must
-follow the correct protocol to receive its parameters
-and return its results (see <a href="#lua_CFunction"><code>lua_CFunction</code></a>).
-
-
-<p>
-<code>lua_pushcfunction</code> is defined as a macro:
-
-<pre>
- #define lua_pushcfunction(L,f) lua_pushcclosure(L,f,0)
-</pre>
-
-
-
-
-<hr><h3><a name="lua_pushfstring"><code>lua_pushfstring</code></a></h3><p>
-<span class="apii">[-0, +1, <em>m</em>]</span>
-<pre>const char *lua_pushfstring (lua_State *L, const char *fmt, ...);</pre>
-
-<p>
-Pushes onto the stack a formatted string
-and returns a pointer to this string.
-It is similar to the C&nbsp;function <code>sprintf</code>,
-but has some important differences:
-
-<ul>
-
-<li>
-You do not have to allocate space for the result:
-the result is a Lua string and Lua takes care of memory allocation
-(and deallocation, through garbage collection).
-</li>
-
-<li>
-The conversion specifiers are quite restricted.
-There are no flags, widths, or precisions.
-The conversion specifiers can only be
-'<code>%%</code>' (inserts a '<code>%</code>' in the string),
-'<code>%s</code>' (inserts a zero-terminated string, with no size restrictions),
-'<code>%f</code>' (inserts a <a href="#lua_Number"><code>lua_Number</code></a>),
-'<code>%p</code>' (inserts a pointer as a hexadecimal numeral),
-'<code>%d</code>' (inserts an <code>int</code>), and
-'<code>%c</code>' (inserts an <code>int</code> as a character).
-</li>
-
-</ul>
-
-
-
-
-<hr><h3><a name="lua_pushinteger"><code>lua_pushinteger</code></a></h3><p>
-<span class="apii">[-0, +1, <em>-</em>]</span>
-<pre>void lua_pushinteger (lua_State *L, lua_Integer n);</pre>
-
-<p>
-Pushes a number with value <code>n</code> onto the stack.
-
-
-
-
-
-<hr><h3><a name="lua_pushlightuserdata"><code>lua_pushlightuserdata</code></a></h3><p>
-<span class="apii">[-0, +1, <em>-</em>]</span>
-<pre>void lua_pushlightuserdata (lua_State *L, void *p);</pre>
-
-<p>
-Pushes a light userdata onto the stack.
-
-
-<p>
-Userdata represent C&nbsp;values in Lua.
-A <em>light userdata</em> represents a pointer.
-It is a value (like a number):
-you do not create it, it has no individual metatable,
-and it is not collected (as it was never created).
-A light userdata is equal to "any"
-light userdata with the same C&nbsp;address.
-
-
-
-
-
-<hr><h3><a name="lua_pushliteral"><code>lua_pushliteral</code></a></h3><p>
-<span class="apii">[-0, +1, <em>m</em>]</span>
-<pre>void lua_pushliteral (lua_State *L, const char *s);</pre>
-
-<p>
-This macro is equivalent to <a href="#lua_pushlstring"><code>lua_pushlstring</code></a>,
-but can be used only when <code>s</code> is a literal string.
-In these cases, it automatically provides the string length.
-
-
-
-
-
-<hr><h3><a name="lua_pushlstring"><code>lua_pushlstring</code></a></h3><p>
-<span class="apii">[-0, +1, <em>m</em>]</span>
-<pre>void lua_pushlstring (lua_State *L, const char *s, size_t len);</pre>
-
-<p>
-Pushes the string pointed to by <code>s</code> with size <code>len</code>
-onto the stack.
-Lua makes (or reuses) an internal copy of the given string,
-so the memory at <code>s</code> can be freed or reused immediately after
-the function returns.
-The string can contain embedded zeros.
-
-
-
-
-
-<hr><h3><a name="lua_pushnil"><code>lua_pushnil</code></a></h3><p>
-<span class="apii">[-0, +1, <em>-</em>]</span>
-<pre>void lua_pushnil (lua_State *L);</pre>
-
-<p>
-Pushes a nil value onto the stack.
-
-
-
-
-
-<hr><h3><a name="lua_pushnumber"><code>lua_pushnumber</code></a></h3><p>
-<span class="apii">[-0, +1, <em>-</em>]</span>
-<pre>void lua_pushnumber (lua_State *L, lua_Number n);</pre>
-
-<p>
-Pushes a number with value <code>n</code> onto the stack.
-
-
-
-
-
-<hr><h3><a name="lua_pushstring"><code>lua_pushstring</code></a></h3><p>
-<span class="apii">[-0, +1, <em>m</em>]</span>
-<pre>void lua_pushstring (lua_State *L, const char *s);</pre>
-
-<p>
-Pushes the zero-terminated string pointed to by <code>s</code>
-onto the stack.
-Lua makes (or reuses) an internal copy of the given string,
-so the memory at <code>s</code> can be freed or reused immediately after
-the function returns.
-The string cannot contain embedded zeros;
-it is assumed to end at the first zero.
-
-
-
-
-
-<hr><h3><a name="lua_pushthread"><code>lua_pushthread</code></a></h3><p>
-<span class="apii">[-0, +1, <em>-</em>]</span>
-<pre>int lua_pushthread (lua_State *L);</pre>
-
-<p>
-Pushes the thread represented by <code>L</code> onto the stack.
-Returns 1 if this thread is the main thread of its state.
-
-
-
-
-
-<hr><h3><a name="lua_pushvalue"><code>lua_pushvalue</code></a></h3><p>
-<span class="apii">[-0, +1, <em>-</em>]</span>
-<pre>void lua_pushvalue (lua_State *L, int index);</pre>
-
-<p>
-Pushes a copy of the element at the given valid index
-onto the stack.
-
-
-
-
-
-<hr><h3><a name="lua_pushvfstring"><code>lua_pushvfstring</code></a></h3><p>
-<span class="apii">[-0, +1, <em>m</em>]</span>
-<pre>const char *lua_pushvfstring (lua_State *L,
- const char *fmt,
- va_list argp);</pre>
-
-<p>
-Equivalent to <a href="#lua_pushfstring"><code>lua_pushfstring</code></a>, except that it receives a <code>va_list</code>
-instead of a variable number of arguments.
-
-
-
-
-
-<hr><h3><a name="lua_rawequal"><code>lua_rawequal</code></a></h3><p>
-<span class="apii">[-0, +0, <em>-</em>]</span>
-<pre>int lua_rawequal (lua_State *L, int index1, int index2);</pre>
-
-<p>
-Returns 1 if the two values in acceptable indices <code>index1</code> and
-<code>index2</code> are primitively equal
-(that is, without calling metamethods).
-Otherwise returns&nbsp;0.
-Also returns&nbsp;0 if any of the indices are non valid.
-
-
-
-
-
-<hr><h3><a name="lua_rawget"><code>lua_rawget</code></a></h3><p>
-<span class="apii">[-1, +1, <em>-</em>]</span>
-<pre>void lua_rawget (lua_State *L, int index);</pre>
-
-<p>
-Similar to <a href="#lua_gettable"><code>lua_gettable</code></a>, but does a raw access
-(i.e., without metamethods).
-
-
-
-
-
-<hr><h3><a name="lua_rawgeti"><code>lua_rawgeti</code></a></h3><p>
-<span class="apii">[-0, +1, <em>-</em>]</span>
-<pre>void lua_rawgeti (lua_State *L, int index, int n);</pre>
-
-<p>
-Pushes onto the stack the value <code>t[n]</code>,
-where <code>t</code> is the value at the given valid index.
-The access is raw;
-that is, it does not invoke metamethods.
-
-
-
-
-
-<hr><h3><a name="lua_rawset"><code>lua_rawset</code></a></h3><p>
-<span class="apii">[-2, +0, <em>m</em>]</span>
-<pre>void lua_rawset (lua_State *L, int index);</pre>
-
-<p>
-Similar to <a href="#lua_settable"><code>lua_settable</code></a>, but does a raw assignment
-(i.e., without metamethods).
-
-
-
-
-
-<hr><h3><a name="lua_rawseti"><code>lua_rawseti</code></a></h3><p>
-<span class="apii">[-1, +0, <em>m</em>]</span>
-<pre>void lua_rawseti (lua_State *L, int index, int n);</pre>
-
-<p>
-Does the equivalent of <code>t[n] = v</code>,
-where <code>t</code> is the value at the given valid index
-and <code>v</code> is the value at the top of the stack.
-
-
-<p>
-This function pops the value from the stack.
-The assignment is raw;
-that is, it does not invoke metamethods.
-
-
-
-
-
-<hr><h3><a name="lua_Reader"><code>lua_Reader</code></a></h3>
-<pre>typedef const char * (*lua_Reader) (lua_State *L,
- void *data,
- size_t *size);</pre>
-
-<p>
-The reader function used by <a href="#lua_load"><code>lua_load</code></a>.
-Every time it needs another piece of the chunk,
-<a href="#lua_load"><code>lua_load</code></a> calls the reader,
-passing along its <code>data</code> parameter.
-The reader must return a pointer to a block of memory
-with a new piece of the chunk
-and set <code>size</code> to the block size.
-The block must exist until the reader function is called again.
-To signal the end of the chunk,
-the reader must return <code>NULL</code> or set <code>size</code> to zero.
-The reader function may return pieces of any size greater than zero.
-
-
-
-
-
-<hr><h3><a name="lua_register"><code>lua_register</code></a></h3><p>
-<span class="apii">[-0, +0, <em>e</em>]</span>
-<pre>void lua_register (lua_State *L,
- const char *name,
- lua_CFunction f);</pre>
-
-<p>
-Sets the C function <code>f</code> as the new value of global <code>name</code>.
-It is defined as a macro:
-
-<pre>
- #define lua_register(L,n,f) \
- (lua_pushcfunction(L, f), lua_setglobal(L, n))
-</pre>
-
-
-
-
-<hr><h3><a name="lua_remove"><code>lua_remove</code></a></h3><p>
-<span class="apii">[-1, +0, <em>-</em>]</span>
-<pre>void lua_remove (lua_State *L, int index);</pre>
-
-<p>
-Removes the element at the given valid index,
-shifting down the elements above this index to fill the gap.
-Cannot be called with a pseudo-index,
-because a pseudo-index is not an actual stack position.
-
-
-
-
-
-<hr><h3><a name="lua_replace"><code>lua_replace</code></a></h3><p>
-<span class="apii">[-1, +0, <em>-</em>]</span>
-<pre>void lua_replace (lua_State *L, int index);</pre>
-
-<p>
-Moves the top element into the given position (and pops it),
-without shifting any element
-(therefore replacing the value at the given position).
-
-
-
-
-
-<hr><h3><a name="lua_resume"><code>lua_resume</code></a></h3><p>
-<span class="apii">[-?, +?, <em>-</em>]</span>
-<pre>int lua_resume (lua_State *L, int narg);</pre>
-
-<p>
-Starts and resumes a coroutine in a given thread.
-
-
-<p>
-To start a coroutine, you first create a new thread
-(see <a href="#lua_newthread"><code>lua_newthread</code></a>);
-then you push onto its stack the main function plus any arguments;
-then you call <a href="#lua_resume"><code>lua_resume</code></a>,
-with <code>narg</code> being the number of arguments.
-This call returns when the coroutine suspends or finishes its execution.
-When it returns, the stack contains all values passed to <a href="#lua_yield"><code>lua_yield</code></a>,
-or all values returned by the body function.
-<a href="#lua_resume"><code>lua_resume</code></a> returns
-<a href="#pdf-LUA_YIELD"><code>LUA_YIELD</code></a> if the coroutine yields,
-0 if the coroutine finishes its execution
-without errors,
-or an error code in case of errors (see <a href="#lua_pcall"><code>lua_pcall</code></a>).
-In case of errors,
-the stack is not unwound,
-so you can use the debug API over it.
-The error message is on the top of the stack.
-To restart a coroutine, you put on its stack only the values to
-be passed as results from <code>yield</code>,
-and then call <a href="#lua_resume"><code>lua_resume</code></a>.
-
-
-
-
-
-<hr><h3><a name="lua_setallocf"><code>lua_setallocf</code></a></h3><p>
-<span class="apii">[-0, +0, <em>-</em>]</span>
-<pre>void lua_setallocf (lua_State *L, lua_Alloc f, void *ud);</pre>
-
-<p>
-Changes the allocator function of a given state to <code>f</code>
-with user data <code>ud</code>.
-
-
-
-
-
-<hr><h3><a name="lua_setfenv"><code>lua_setfenv</code></a></h3><p>
-<span class="apii">[-1, +0, <em>-</em>]</span>
-<pre>int lua_setfenv (lua_State *L, int index);</pre>
-
-<p>
-Pops a table from the stack and sets it as
-the new environment for the value at the given index.
-If the value at the given index is
-neither a function nor a thread nor a userdata,
-<a href="#lua_setfenv"><code>lua_setfenv</code></a> returns 0.
-Otherwise it returns 1.
-
-
-
-
-
-<hr><h3><a name="lua_setfield"><code>lua_setfield</code></a></h3><p>
-<span class="apii">[-1, +0, <em>e</em>]</span>
-<pre>void lua_setfield (lua_State *L, int index, const char *k);</pre>
-
-<p>
-Does the equivalent to <code>t[k] = v</code>,
-where <code>t</code> is the value at the given valid index
-and <code>v</code> is the value at the top of the stack.
-
-
-<p>
-This function pops the value from the stack.
-As in Lua, this function may trigger a metamethod
-for the "newindex" event (see <a href="#2.8">&sect;2.8</a>).
-
-
-
-
-
-<hr><h3><a name="lua_setglobal"><code>lua_setglobal</code></a></h3><p>
-<span class="apii">[-1, +0, <em>e</em>]</span>
-<pre>void lua_setglobal (lua_State *L, const char *name);</pre>
-
-<p>
-Pops a value from the stack and
-sets it as the new value of global <code>name</code>.
-It is defined as a macro:
-
-<pre>
- #define lua_setglobal(L,s) lua_setfield(L, LUA_GLOBALSINDEX, s)
-</pre>
-
-
-
-
-<hr><h3><a name="lua_setmetatable"><code>lua_setmetatable</code></a></h3><p>
-<span class="apii">[-1, +0, <em>-</em>]</span>
-<pre>int lua_setmetatable (lua_State *L, int index);</pre>
-
-<p>
-Pops a table from the stack and
-sets it as the new metatable for the value at the given
-acceptable index.
-
-
-
-
-
-<hr><h3><a name="lua_settable"><code>lua_settable</code></a></h3><p>
-<span class="apii">[-2, +0, <em>e</em>]</span>
-<pre>void lua_settable (lua_State *L, int index);</pre>
-
-<p>
-Does the equivalent to <code>t[k] = v</code>,
-where <code>t</code> is the value at the given valid index,
-<code>v</code> is the value at the top of the stack,
-and <code>k</code> is the value just below the top.
-
-
-<p>
-This function pops both the key and the value from the stack.
-As in Lua, this function may trigger a metamethod
-for the "newindex" event (see <a href="#2.8">&sect;2.8</a>).
-
-
-
-
-
-<hr><h3><a name="lua_settop"><code>lua_settop</code></a></h3><p>
-<span class="apii">[-?, +?, <em>-</em>]</span>
-<pre>void lua_settop (lua_State *L, int index);</pre>
-
-<p>
-Accepts any acceptable index, or&nbsp;0,
-and sets the stack top to this index.
-If the new top is larger than the old one,
-then the new elements are filled with <b>nil</b>.
-If <code>index</code> is&nbsp;0, then all stack elements are removed.
-
-
-
-
-
-<hr><h3><a name="lua_State"><code>lua_State</code></a></h3>
-<pre>typedef struct lua_State lua_State;</pre>
-
-<p>
-Opaque structure that keeps the whole state of a Lua interpreter.
-The Lua library is fully reentrant:
-it has no global variables.
-All information about a state is kept in this structure.
-
-
-<p>
-A pointer to this state must be passed as the first argument to
-every function in the library, except to <a href="#lua_newstate"><code>lua_newstate</code></a>,
-which creates a Lua state from scratch.
-
-
-
-
-
-<hr><h3><a name="lua_status"><code>lua_status</code></a></h3><p>
-<span class="apii">[-0, +0, <em>-</em>]</span>
-<pre>int lua_status (lua_State *L);</pre>
-
-<p>
-Returns the status of the thread <code>L</code>.
-
-
-<p>
-The status can be 0 for a normal thread,
-an error code if the thread finished its execution with an error,
-or <a name="pdf-LUA_YIELD"><code>LUA_YIELD</code></a> if the thread is suspended.
-
-
-
-
-
-<hr><h3><a name="lua_toboolean"><code>lua_toboolean</code></a></h3><p>
-<span class="apii">[-0, +0, <em>-</em>]</span>
-<pre>int lua_toboolean (lua_State *L, int index);</pre>
-
-<p>
-Converts the Lua value at the given acceptable index to a C&nbsp;boolean
-value (0&nbsp;or&nbsp;1).
-Like all tests in Lua,
-<a href="#lua_toboolean"><code>lua_toboolean</code></a> returns 1 for any Lua value
-different from <b>false</b> and <b>nil</b>;
-otherwise it returns 0.
-It also returns 0 when called with a non-valid index.
-(If you want to accept only actual boolean values,
-use <a href="#lua_isboolean"><code>lua_isboolean</code></a> to test the value's type.)
-
-
-
-
-
-<hr><h3><a name="lua_tocfunction"><code>lua_tocfunction</code></a></h3><p>
-<span class="apii">[-0, +0, <em>-</em>]</span>
-<pre>lua_CFunction lua_tocfunction (lua_State *L, int index);</pre>
-
-<p>
-Converts a value at the given acceptable index to a C&nbsp;function.
-That value must be a C&nbsp;function;
-otherwise, returns <code>NULL</code>.
-
-
-
-
-
-<hr><h3><a name="lua_tointeger"><code>lua_tointeger</code></a></h3><p>
-<span class="apii">[-0, +0, <em>-</em>]</span>
-<pre>lua_Integer lua_tointeger (lua_State *L, int index);</pre>
-
-<p>
-Converts the Lua value at the given acceptable index
-to the signed integral type <a href="#lua_Integer"><code>lua_Integer</code></a>.
-The Lua value must be a number or a string convertible to a number
-(see <a href="#2.2.1">&sect;2.2.1</a>);
-otherwise, <a href="#lua_tointeger"><code>lua_tointeger</code></a> returns&nbsp;0.
-
-
-<p>
-If the number is not an integer,
-it is truncated in some non-specified way.
-
-
-
-
-
-<hr><h3><a name="lua_tolstring"><code>lua_tolstring</code></a></h3><p>
-<span class="apii">[-0, +0, <em>m</em>]</span>
-<pre>const char *lua_tolstring (lua_State *L, int index, size_t *len);</pre>
-
-<p>
-Converts the Lua value at the given acceptable index to a C&nbsp;string.
-If <code>len</code> is not <code>NULL</code>,
-it also sets <code>*len</code> with the string length.
-The Lua value must be a string or a number;
-otherwise, the function returns <code>NULL</code>.
-If the value is a number,
-then <a href="#lua_tolstring"><code>lua_tolstring</code></a> also
-<em>changes the actual value in the stack to a string</em>.
-(This change confuses <a href="#lua_next"><code>lua_next</code></a>
-when <a href="#lua_tolstring"><code>lua_tolstring</code></a> is applied to keys during a table traversal.)
-
-
-<p>
-<a href="#lua_tolstring"><code>lua_tolstring</code></a> returns a fully aligned pointer
-to a string inside the Lua state.
-This string always has a zero ('<code>\0</code>')
-after its last character (as in&nbsp;C),
-but can contain other zeros in its body.
-Because Lua has garbage collection,
-there is no guarantee that the pointer returned by <a href="#lua_tolstring"><code>lua_tolstring</code></a>
-will be valid after the corresponding value is removed from the stack.
-
-
-
-
-
-<hr><h3><a name="lua_tonumber"><code>lua_tonumber</code></a></h3><p>
-<span class="apii">[-0, +0, <em>-</em>]</span>
-<pre>lua_Number lua_tonumber (lua_State *L, int index);</pre>
-
-<p>
-Converts the Lua value at the given acceptable index
-to the C&nbsp;type <a href="#lua_Number"><code>lua_Number</code></a> (see <a href="#lua_Number"><code>lua_Number</code></a>).
-The Lua value must be a number or a string convertible to a number
-(see <a href="#2.2.1">&sect;2.2.1</a>);
-otherwise, <a href="#lua_tonumber"><code>lua_tonumber</code></a> returns&nbsp;0.
-
-
-
-
-
-<hr><h3><a name="lua_topointer"><code>lua_topointer</code></a></h3><p>
-<span class="apii">[-0, +0, <em>-</em>]</span>
-<pre>const void *lua_topointer (lua_State *L, int index);</pre>
-
-<p>
-Converts the value at the given acceptable index to a generic
-C&nbsp;pointer (<code>void*</code>).
-The value can be a userdata, a table, a thread, or a function;
-otherwise, <a href="#lua_topointer"><code>lua_topointer</code></a> returns <code>NULL</code>.
-Different objects will give different pointers.
-There is no way to convert the pointer back to its original value.
-
-
-<p>
-Typically this function is used only for debug information.
-
-
-
-
-
-<hr><h3><a name="lua_tostring"><code>lua_tostring</code></a></h3><p>
-<span class="apii">[-0, +0, <em>m</em>]</span>
-<pre>const char *lua_tostring (lua_State *L, int index);</pre>
-
-<p>
-Equivalent to <a href="#lua_tolstring"><code>lua_tolstring</code></a> with <code>len</code> equal to <code>NULL</code>.
-
-
-
-
-
-<hr><h3><a name="lua_tothread"><code>lua_tothread</code></a></h3><p>
-<span class="apii">[-0, +0, <em>-</em>]</span>
-<pre>lua_State *lua_tothread (lua_State *L, int index);</pre>
-
-<p>
-Converts the value at the given acceptable index to a Lua thread
-(represented as <code>lua_State*</code>).
-This value must be a thread;
-otherwise, the function returns <code>NULL</code>.
-
-
-
-
-
-<hr><h3><a name="lua_touserdata"><code>lua_touserdata</code></a></h3><p>
-<span class="apii">[-0, +0, <em>-</em>]</span>
-<pre>void *lua_touserdata (lua_State *L, int index);</pre>
-
-<p>
-If the value at the given acceptable index is a full userdata,
-returns its block address.
-If the value is a light userdata,
-returns its pointer.
-Otherwise, returns <code>NULL</code>.
-
-
-
-
-
-<hr><h3><a name="lua_type"><code>lua_type</code></a></h3><p>
-<span class="apii">[-0, +0, <em>-</em>]</span>
-<pre>int lua_type (lua_State *L, int index);</pre>
-
-<p>
-Returns the type of the value in the given acceptable index,
-or <code>LUA_TNONE</code> for a non-valid index
-(that is, an index to an "empty" stack position).
-The types returned by <a href="#lua_type"><code>lua_type</code></a> are coded by the following constants
-defined in <code>lua.h</code>:
-<code>LUA_TNIL</code>,
-<code>LUA_TNUMBER</code>,
-<code>LUA_TBOOLEAN</code>,
-<code>LUA_TSTRING</code>,
-<code>LUA_TTABLE</code>,
-<code>LUA_TFUNCTION</code>,
-<code>LUA_TUSERDATA</code>,
-<code>LUA_TTHREAD</code>,
-and
-<code>LUA_TLIGHTUSERDATA</code>.
-
-
-
-
-
-<hr><h3><a name="lua_typename"><code>lua_typename</code></a></h3><p>
-<span class="apii">[-0, +0, <em>-</em>]</span>
-<pre>const char *lua_typename (lua_State *L, int tp);</pre>
-
-<p>
-Returns the name of the type encoded by the value <code>tp</code>,
-which must be one the values returned by <a href="#lua_type"><code>lua_type</code></a>.
-
-
-
-
-
-<hr><h3><a name="lua_Writer"><code>lua_Writer</code></a></h3>
-<pre>typedef int (*lua_Writer) (lua_State *L,
- const void* p,
- size_t sz,
- void* ud);</pre>
-
-<p>
-The type of the writer function used by <a href="#lua_dump"><code>lua_dump</code></a>.
-Every time it produces another piece of chunk,
-<a href="#lua_dump"><code>lua_dump</code></a> calls the writer,
-passing along the buffer to be written (<code>p</code>),
-its size (<code>sz</code>),
-and the <code>data</code> parameter supplied to <a href="#lua_dump"><code>lua_dump</code></a>.
-
-
-<p>
-The writer returns an error code:
-0&nbsp;means no errors;
-any other value means an error and stops <a href="#lua_dump"><code>lua_dump</code></a> from
-calling the writer again.
-
-
-
-
-
-<hr><h3><a name="lua_xmove"><code>lua_xmove</code></a></h3><p>
-<span class="apii">[-?, +?, <em>-</em>]</span>
-<pre>void lua_xmove (lua_State *from, lua_State *to, int n);</pre>
-
-<p>
-Exchange values between different threads of the <em>same</em> global state.
-
-
-<p>
-This function pops <code>n</code> values from the stack <code>from</code>,
-and pushes them onto the stack <code>to</code>.
-
-
-
-
-
-<hr><h3><a name="lua_yield"><code>lua_yield</code></a></h3><p>
-<span class="apii">[-?, +?, <em>-</em>]</span>
-<pre>int lua_yield (lua_State *L, int nresults);</pre>
-
-<p>
-Yields a coroutine.
-
-
-<p>
-This function should only be called as the
-return expression of a C&nbsp;function, as follows:
-
-<pre>
- return lua_yield (L, nresults);
-</pre><p>
-When a C&nbsp;function calls <a href="#lua_yield"><code>lua_yield</code></a> in that way,
-the running coroutine suspends its execution,
-and the call to <a href="#lua_resume"><code>lua_resume</code></a> that started this coroutine returns.
-The parameter <code>nresults</code> is the number of values from the stack
-that are passed as results to <a href="#lua_resume"><code>lua_resume</code></a>.
-
-
-
-
-
-
-
-<h2>3.8 - <a name="3.8">The Debug Interface</a></h2>
-
-<p>
-Lua has no built-in debugging facilities.
-Instead, it offers a special interface
-by means of functions and <em>hooks</em>.
-This interface allows the construction of different
-kinds of debuggers, profilers, and other tools
-that need "inside information" from the interpreter.
-
-
-
-<hr><h3><a name="lua_Debug"><code>lua_Debug</code></a></h3>
-<pre>typedef struct lua_Debug {
- int event;
- const char *name; /* (n) */
- const char *namewhat; /* (n) */
- const char *what; /* (S) */
- const char *source; /* (S) */
- int currentline; /* (l) */
- int nups; /* (u) number of upvalues */
- int linedefined; /* (S) */
- int lastlinedefined; /* (S) */
- char short_src[LUA_IDSIZE]; /* (S) */
- /* private part */
- <em>other fields</em>
-} lua_Debug;</pre>
-
-<p>
-A structure used to carry different pieces of
-information about an active function.
-<a href="#lua_getstack"><code>lua_getstack</code></a> fills only the private part
-of this structure, for later use.
-To fill the other fields of <a href="#lua_Debug"><code>lua_Debug</code></a> with useful information,
-call <a href="#lua_getinfo"><code>lua_getinfo</code></a>.
-
-
-<p>
-The fields of <a href="#lua_Debug"><code>lua_Debug</code></a> have the following meaning:
-
-<ul>
-
-<li><b><code>source</code>:</b>
-If the function was defined in a string,
-then <code>source</code> is that string.
-If the function was defined in a file,
-then <code>source</code> starts with a '<code>@</code>' followed by the file name.
-</li>
-
-<li><b><code>short_src</code>:</b>
-a "printable" version of <code>source</code>, to be used in error messages.
-</li>
-
-<li><b><code>linedefined</code>:</b>
-the line number where the definition of the function starts.
-</li>
-
-<li><b><code>lastlinedefined</code>:</b>
-the line number where the definition of the function ends.
-</li>
-
-<li><b><code>what</code>:</b>
-the string <code>"Lua"</code> if the function is a Lua function,
-<code>"C"</code> if it is a C&nbsp;function,
-<code>"main"</code> if it is the main part of a chunk,
-and <code>"tail"</code> if it was a function that did a tail call.
-In the latter case,
-Lua has no other information about the function.
-</li>
-
-<li><b><code>currentline</code>:</b>
-the current line where the given function is executing.
-When no line information is available,
-<code>currentline</code> is set to -1.
-</li>
-
-<li><b><code>name</code>:</b>
-a reasonable name for the given function.
-Because functions in Lua are first-class values,
-they do not have a fixed name:
-some functions can be the value of multiple global variables,
-while others can be stored only in a table field.
-The <code>lua_getinfo</code> function checks how the function was
-called to find a suitable name.
-If it cannot find a name,
-then <code>name</code> is set to <code>NULL</code>.
-</li>
-
-<li><b><code>namewhat</code>:</b>
-explains the <code>name</code> field.
-The value of <code>namewhat</code> can be
-<code>"global"</code>, <code>"local"</code>, <code>"method"</code>,
-<code>"field"</code>, <code>"upvalue"</code>, or <code>""</code> (the empty string),
-according to how the function was called.
-(Lua uses the empty string when no other option seems to apply.)
-</li>
-
-<li><b><code>nups</code>:</b>
-the number of upvalues of the function.
-</li>
-
-</ul>
-
-
-
-
-<hr><h3><a name="lua_gethook"><code>lua_gethook</code></a></h3><p>
-<span class="apii">[-0, +0, <em>-</em>]</span>
-<pre>lua_Hook lua_gethook (lua_State *L);</pre>
-
-<p>
-Returns the current hook function.
-
-
-
-
-
-<hr><h3><a name="lua_gethookcount"><code>lua_gethookcount</code></a></h3><p>
-<span class="apii">[-0, +0, <em>-</em>]</span>
-<pre>int lua_gethookcount (lua_State *L);</pre>
-
-<p>
-Returns the current hook count.
-
-
-
-
-
-<hr><h3><a name="lua_gethookmask"><code>lua_gethookmask</code></a></h3><p>
-<span class="apii">[-0, +0, <em>-</em>]</span>
-<pre>int lua_gethookmask (lua_State *L);</pre>
-
-<p>
-Returns the current hook mask.
-
-
-
-
-
-<hr><h3><a name="lua_getinfo"><code>lua_getinfo</code></a></h3><p>
-<span class="apii">[-(0|1), +(0|1|2), <em>m</em>]</span>
-<pre>int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar);</pre>
-
-<p>
-Returns information about a specific function or function invocation.
-
-
-<p>
-To get information about a function invocation,
-the parameter <code>ar</code> must be a valid activation record that was
-filled by a previous call to <a href="#lua_getstack"><code>lua_getstack</code></a> or
-given as argument to a hook (see <a href="#lua_Hook"><code>lua_Hook</code></a>).
-
-
-<p>
-To get information about a function you push it onto the stack
-and start the <code>what</code> string with the character '<code>&gt;</code>'.
-(In that case,
-<code>lua_getinfo</code> pops the function in the top of the stack.)
-For instance, to know in which line a function <code>f</code> was defined,
-you can write the following code:
-
-<pre>
- lua_Debug ar;
- lua_getfield(L, LUA_GLOBALSINDEX, "f"); /* get global 'f' */
- lua_getinfo(L, "&gt;S", &amp;ar);
- printf("%d\n", ar.linedefined);
-</pre>
-
-<p>
-Each character in the string <code>what</code>
-selects some fields of the structure <code>ar</code> to be filled or
-a value to be pushed on the stack:
-
-<ul>
-
-<li><b>'<code>n</code>':</b> fills in the field <code>name</code> and <code>namewhat</code>;
-</li>
-
-<li><b>'<code>S</code>':</b>
-fills in the fields <code>source</code>, <code>short_src</code>,
-<code>linedefined</code>, <code>lastlinedefined</code>, and <code>what</code>;
-</li>
-
-<li><b>'<code>l</code>':</b> fills in the field <code>currentline</code>;
-</li>
-
-<li><b>'<code>u</code>':</b> fills in the field <code>nups</code>;
-</li>
-
-<li><b>'<code>f</code>':</b>
-pushes onto the stack the function that is
-running at the given level;
-</li>
-
-<li><b>'<code>L</code>':</b>
-pushes onto the stack a table whose indices are the
-numbers of the lines that are valid on the function.
-(A <em>valid line</em> is a line with some associated code,
-that is, a line where you can put a break point.
-Non-valid lines include empty lines and comments.)
-</li>
-
-</ul>
-
-<p>
-This function returns 0 on error
-(for instance, an invalid option in <code>what</code>).
-
-
-
-
-
-<hr><h3><a name="lua_getlocal"><code>lua_getlocal</code></a></h3><p>
-<span class="apii">[-0, +(0|1), <em>-</em>]</span>
-<pre>const char *lua_getlocal (lua_State *L, lua_Debug *ar, int n);</pre>
-
-<p>
-Gets information about a local variable of a given activation record.
-The parameter <code>ar</code> must be a valid activation record that was
-filled by a previous call to <a href="#lua_getstack"><code>lua_getstack</code></a> or
-given as argument to a hook (see <a href="#lua_Hook"><code>lua_Hook</code></a>).
-The index <code>n</code> selects which local variable to inspect
-(1 is the first parameter or active local variable, and so on,
-until the last active local variable).
-<a href="#lua_getlocal"><code>lua_getlocal</code></a> pushes the variable's value onto the stack
-and returns its name.
-
-
-<p>
-Variable names starting with '<code>(</code>' (open parentheses)
-represent internal variables
-(loop control variables, temporaries, and C&nbsp;function locals).
-
-
-<p>
-Returns <code>NULL</code> (and pushes nothing)
-when the index is greater than
-the number of active local variables.
-
-
-
-
-
-<hr><h3><a name="lua_getstack"><code>lua_getstack</code></a></h3><p>
-<span class="apii">[-0, +0, <em>-</em>]</span>
-<pre>int lua_getstack (lua_State *L, int level, lua_Debug *ar);</pre>
-
-<p>
-Get information about the interpreter runtime stack.
-
-
-<p>
-This function fills parts of a <a href="#lua_Debug"><code>lua_Debug</code></a> structure with
-an identification of the <em>activation record</em>
-of the function executing at a given level.
-Level&nbsp;0 is the current running function,
-whereas level <em>n+1</em> is the function that has called level <em>n</em>.
-When there are no errors, <a href="#lua_getstack"><code>lua_getstack</code></a> returns 1;
-when called with a level greater than the stack depth,
-it returns 0.
-
-
-
-
-
-<hr><h3><a name="lua_getupvalue"><code>lua_getupvalue</code></a></h3><p>
-<span class="apii">[-0, +(0|1), <em>-</em>]</span>
-<pre>const char *lua_getupvalue (lua_State *L, int funcindex, int n);</pre>
-
-<p>
-Gets information about a closure's upvalue.
-(For Lua functions,
-upvalues are the external local variables that the function uses,
-and that are consequently included in its closure.)
-<a href="#lua_getupvalue"><code>lua_getupvalue</code></a> gets the index <code>n</code> of an upvalue,
-pushes the upvalue's value onto the stack,
-and returns its name.
-<code>funcindex</code> points to the closure in the stack.
-(Upvalues have no particular order,
-as they are active through the whole function.
-So, they are numbered in an arbitrary order.)
-
-
-<p>
-Returns <code>NULL</code> (and pushes nothing)
-when the index is greater than the number of upvalues.
-For C&nbsp;functions, this function uses the empty string <code>""</code>
-as a name for all upvalues.
-
-
-
-
-
-<hr><h3><a name="lua_Hook"><code>lua_Hook</code></a></h3>
-<pre>typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar);</pre>
-
-<p>
-Type for debugging hook functions.
-
-
-<p>
-Whenever a hook is called, its <code>ar</code> argument has its field
-<code>event</code> set to the specific event that triggered the hook.
-Lua identifies these events with the following constants:
-<a name="pdf-LUA_HOOKCALL"><code>LUA_HOOKCALL</code></a>, <a name="pdf-LUA_HOOKRET"><code>LUA_HOOKRET</code></a>,
-<a name="pdf-LUA_HOOKTAILRET"><code>LUA_HOOKTAILRET</code></a>, <a name="pdf-LUA_HOOKLINE"><code>LUA_HOOKLINE</code></a>,
-and <a name="pdf-LUA_HOOKCOUNT"><code>LUA_HOOKCOUNT</code></a>.
-Moreover, for line events, the field <code>currentline</code> is also set.
-To get the value of any other field in <code>ar</code>,
-the hook must call <a href="#lua_getinfo"><code>lua_getinfo</code></a>.
-For return events, <code>event</code> can be <code>LUA_HOOKRET</code>,
-the normal value, or <code>LUA_HOOKTAILRET</code>.
-In the latter case, Lua is simulating a return from
-a function that did a tail call;
-in this case, it is useless to call <a href="#lua_getinfo"><code>lua_getinfo</code></a>.
-
-
-<p>
-While Lua is running a hook, it disables other calls to hooks.
-Therefore, if a hook calls back Lua to execute a function or a chunk,
-this execution occurs without any calls to hooks.
-
-
-
-
-
-<hr><h3><a name="lua_sethook"><code>lua_sethook</code></a></h3><p>
-<span class="apii">[-0, +0, <em>-</em>]</span>
-<pre>int lua_sethook (lua_State *L, lua_Hook f, int mask, int count);</pre>
-
-<p>
-Sets the debugging hook function.
-
-
-<p>
-Argument <code>f</code> is the hook function.
-<code>mask</code> specifies on which events the hook will be called:
-it is formed by a bitwise or of the constants
-<a name="pdf-LUA_MASKCALL"><code>LUA_MASKCALL</code></a>,
-<a name="pdf-LUA_MASKRET"><code>LUA_MASKRET</code></a>,
-<a name="pdf-LUA_MASKLINE"><code>LUA_MASKLINE</code></a>,
-and <a name="pdf-LUA_MASKCOUNT"><code>LUA_MASKCOUNT</code></a>.
-The <code>count</code> argument is only meaningful when the mask
-includes <code>LUA_MASKCOUNT</code>.
-For each event, the hook is called as explained below:
-
-<ul>
-
-<li><b>The call hook:</b> is called when the interpreter calls a function.
-The hook is called just after Lua enters the new function,
-before the function gets its arguments.
-</li>
-
-<li><b>The return hook:</b> is called when the interpreter returns from a function.
-The hook is called just before Lua leaves the function.
-You have no access to the values to be returned by the function.
-</li>
-
-<li><b>The line hook:</b> is called when the interpreter is about to
-start the execution of a new line of code,
-or when it jumps back in the code (even to the same line).
-(This event only happens while Lua is executing a Lua function.)
-</li>
-
-<li><b>The count hook:</b> is called after the interpreter executes every
-<code>count</code> instructions.
-(This event only happens while Lua is executing a Lua function.)
-</li>
-
-</ul>
-
-<p>
-A hook is disabled by setting <code>mask</code> to zero.
-
-
-
-
-
-<hr><h3><a name="lua_setlocal"><code>lua_setlocal</code></a></h3><p>
-<span class="apii">[-(0|1), +0, <em>-</em>]</span>
-<pre>const char *lua_setlocal (lua_State *L, lua_Debug *ar, int n);</pre>
-
-<p>
-Sets the value of a local variable of a given activation record.
-Parameters <code>ar</code> and <code>n</code> are as in <a href="#lua_getlocal"><code>lua_getlocal</code></a>
-(see <a href="#lua_getlocal"><code>lua_getlocal</code></a>).
-<a href="#lua_setlocal"><code>lua_setlocal</code></a> assigns the value at the top of the stack
-to the variable and returns its name.
-It also pops the value from the stack.
-
-
-<p>
-Returns <code>NULL</code> (and pops nothing)
-when the index is greater than
-the number of active local variables.
-
-
-
-
-
-<hr><h3><a name="lua_setupvalue"><code>lua_setupvalue</code></a></h3><p>
-<span class="apii">[-(0|1), +0, <em>-</em>]</span>
-<pre>const char *lua_setupvalue (lua_State *L, int funcindex, int n);</pre>
-
-<p>
-Sets the value of a closure's upvalue.
-It assigns the value at the top of the stack
-to the upvalue and returns its name.
-It also pops the value from the stack.
-Parameters <code>funcindex</code> and <code>n</code> are as in the <a href="#lua_getupvalue"><code>lua_getupvalue</code></a>
-(see <a href="#lua_getupvalue"><code>lua_getupvalue</code></a>).
-
-
-<p>
-Returns <code>NULL</code> (and pops nothing)
-when the index is greater than the number of upvalues.
-
-
-
-
-
-
-
-<h1>4 - <a name="4">The Auxiliary Library</a></h1>
-
-<p>
-
-The <em>auxiliary library</em> provides several convenient functions
-to interface C with Lua.
-While the basic API provides the primitive functions for all
-interactions between C and Lua,
-the auxiliary library provides higher-level functions for some
-common tasks.
-
-
-<p>
-All functions from the auxiliary library
-are defined in header file <code>lauxlib.h</code> and
-have a prefix <code>luaL_</code>.
-
-
-<p>
-All functions in the auxiliary library are built on
-top of the basic API,
-and so they provide nothing that cannot be done with this API.
-
-
-<p>
-Several functions in the auxiliary library are used to
-check C&nbsp;function arguments.
-Their names are always <code>luaL_check*</code> or <code>luaL_opt*</code>.
-All of these functions throw an error if the check is not satisfied.
-Because the error message is formatted for arguments
-(e.g., "<code>bad argument #1</code>"),
-you should not use these functions for other stack values.
-
-
-
-<h2>4.1 - <a name="4.1">Functions and Types</a></h2>
-
-<p>
-Here we list all functions and types from the auxiliary library
-in alphabetical order.
-
-
-
-<hr><h3><a name="luaL_addchar"><code>luaL_addchar</code></a></h3><p>
-<span class="apii">[-0, +0, <em>m</em>]</span>
-<pre>void luaL_addchar (luaL_Buffer *B, char c);</pre>
-
-<p>
-Adds the character <code>c</code> to the buffer <code>B</code>
-(see <a href="#luaL_Buffer"><code>luaL_Buffer</code></a>).
-
-
-
-
-
-<hr><h3><a name="luaL_addlstring"><code>luaL_addlstring</code></a></h3><p>
-<span class="apii">[-0, +0, <em>m</em>]</span>
-<pre>void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l);</pre>
-
-<p>
-Adds the string pointed to by <code>s</code> with length <code>l</code> to
-the buffer <code>B</code>
-(see <a href="#luaL_Buffer"><code>luaL_Buffer</code></a>).
-The string may contain embedded zeros.
-
-
-
-
-
-<hr><h3><a name="luaL_addsize"><code>luaL_addsize</code></a></h3><p>
-<span class="apii">[-0, +0, <em>m</em>]</span>
-<pre>void luaL_addsize (luaL_Buffer *B, size_t n);</pre>
-
-<p>
-Adds to the buffer <code>B</code> (see <a href="#luaL_Buffer"><code>luaL_Buffer</code></a>)
-a string of length <code>n</code> previously copied to the
-buffer area (see <a href="#luaL_prepbuffer"><code>luaL_prepbuffer</code></a>).
-
-
-
-
-
-<hr><h3><a name="luaL_addstring"><code>luaL_addstring</code></a></h3><p>
-<span class="apii">[-0, +0, <em>m</em>]</span>
-<pre>void luaL_addstring (luaL_Buffer *B, const char *s);</pre>
-
-<p>
-Adds the zero-terminated string pointed to by <code>s</code>
-to the buffer <code>B</code>
-(see <a href="#luaL_Buffer"><code>luaL_Buffer</code></a>).
-The string may not contain embedded zeros.
-
-
-
-
-
-<hr><h3><a name="luaL_addvalue"><code>luaL_addvalue</code></a></h3><p>
-<span class="apii">[-1, +0, <em>m</em>]</span>
-<pre>void luaL_addvalue (luaL_Buffer *B);</pre>
-
-<p>
-Adds the value at the top of the stack
-to the buffer <code>B</code>
-(see <a href="#luaL_Buffer"><code>luaL_Buffer</code></a>).
-Pops the value.
-
-
-<p>
-This is the only function on string buffers that can (and must)
-be called with an extra element on the stack,
-which is the value to be added to the buffer.
-
-
-
-
-
-<hr><h3><a name="luaL_argcheck"><code>luaL_argcheck</code></a></h3><p>
-<span class="apii">[-0, +0, <em>v</em>]</span>
-<pre>void luaL_argcheck (lua_State *L,
- int cond,
- int narg,
- const char *extramsg);</pre>
-
-<p>
-Checks whether <code>cond</code> is true.
-If not, raises an error with the following message,
-where <code>func</code> is retrieved from the call stack:
-
-<pre>
- bad argument #&lt;narg&gt; to &lt;func&gt; (&lt;extramsg&gt;)
-</pre>
-
-
-
-
-<hr><h3><a name="luaL_argerror"><code>luaL_argerror</code></a></h3><p>
-<span class="apii">[-0, +0, <em>v</em>]</span>
-<pre>int luaL_argerror (lua_State *L, int narg, const char *extramsg);</pre>
-
-<p>
-Raises an error with the following message,
-where <code>func</code> is retrieved from the call stack:
-
-<pre>
- bad argument #&lt;narg&gt; to &lt;func&gt; (&lt;extramsg&gt;)
-</pre>
-
-<p>
-This function never returns,
-but it is an idiom to use it in C&nbsp;functions
-as <code>return luaL_argerror(<em>args</em>)</code>.
-
-
-
-
-
-<hr><h3><a name="luaL_Buffer"><code>luaL_Buffer</code></a></h3>
-<pre>typedef struct luaL_Buffer luaL_Buffer;</pre>
-
-<p>
-Type for a <em>string buffer</em>.
-
-
-<p>
-A string buffer allows C&nbsp;code to build Lua strings piecemeal.
-Its pattern of use is as follows:
-
-<ul>
-
-<li>First you declare a variable <code>b</code> of type <a href="#luaL_Buffer"><code>luaL_Buffer</code></a>.</li>
-
-<li>Then you initialize it with a call <code>luaL_buffinit(L, &amp;b)</code>.</li>
-
-<li>
-Then you add string pieces to the buffer calling any of
-the <code>luaL_add*</code> functions.
-</li>
-
-<li>
-You finish by calling <code>luaL_pushresult(&amp;b)</code>.
-This call leaves the final string on the top of the stack.
-</li>
-
-</ul>
-
-<p>
-During its normal operation,
-a string buffer uses a variable number of stack slots.
-So, while using a buffer, you cannot assume that you know where
-the top of the stack is.
-You can use the stack between successive calls to buffer operations
-as long as that use is balanced;
-that is,
-when you call a buffer operation,
-the stack is at the same level
-it was immediately after the previous buffer operation.
-(The only exception to this rule is <a href="#luaL_addvalue"><code>luaL_addvalue</code></a>.)
-After calling <a href="#luaL_pushresult"><code>luaL_pushresult</code></a> the stack is back to its
-level when the buffer was initialized,
-plus the final string on its top.
-
-
-
-
-
-<hr><h3><a name="luaL_buffinit"><code>luaL_buffinit</code></a></h3><p>
-<span class="apii">[-0, +0, <em>-</em>]</span>
-<pre>void luaL_buffinit (lua_State *L, luaL_Buffer *B);</pre>
-
-<p>
-Initializes a buffer <code>B</code>.
-This function does not allocate any space;
-the buffer must be declared as a variable
-(see <a href="#luaL_Buffer"><code>luaL_Buffer</code></a>).
-
-
-
-
-
-<hr><h3><a name="luaL_callmeta"><code>luaL_callmeta</code></a></h3><p>
-<span class="apii">[-0, +(0|1), <em>e</em>]</span>
-<pre>int luaL_callmeta (lua_State *L, int obj, const char *e);</pre>
-
-<p>
-Calls a metamethod.
-
-
-<p>
-If the object at index <code>obj</code> has a metatable and this
-metatable has a field <code>e</code>,
-this function calls this field and passes the object as its only argument.
-In this case this function returns 1 and pushes onto the
-stack the value returned by the call.
-If there is no metatable or no metamethod,
-this function returns 0 (without pushing any value on the stack).
-
-
-
-
-
-<hr><h3><a name="luaL_checkany"><code>luaL_checkany</code></a></h3><p>
-<span class="apii">[-0, +0, <em>v</em>]</span>
-<pre>void luaL_checkany (lua_State *L, int narg);</pre>
-
-<p>
-Checks whether the function has an argument
-of any type (including <b>nil</b>) at position <code>narg</code>.
-
-
-
-
-
-<hr><h3><a name="luaL_checkint"><code>luaL_checkint</code></a></h3><p>
-<span class="apii">[-0, +0, <em>v</em>]</span>
-<pre>int luaL_checkint (lua_State *L, int narg);</pre>
-
-<p>
-Checks whether the function argument <code>narg</code> is a number
-and returns this number cast to an <code>int</code>.
-
-
-
-
-
-<hr><h3><a name="luaL_checkinteger"><code>luaL_checkinteger</code></a></h3><p>
-<span class="apii">[-0, +0, <em>v</em>]</span>
-<pre>lua_Integer luaL_checkinteger (lua_State *L, int narg);</pre>
-
-<p>
-Checks whether the function argument <code>narg</code> is a number
-and returns this number cast to a <a href="#lua_Integer"><code>lua_Integer</code></a>.
-
-
-
-
-
-<hr><h3><a name="luaL_checklong"><code>luaL_checklong</code></a></h3><p>
-<span class="apii">[-0, +0, <em>v</em>]</span>
-<pre>long luaL_checklong (lua_State *L, int narg);</pre>
-
-<p>
-Checks whether the function argument <code>narg</code> is a number
-and returns this number cast to a <code>long</code>.
-
-
-
-
-
-<hr><h3><a name="luaL_checklstring"><code>luaL_checklstring</code></a></h3><p>
-<span class="apii">[-0, +0, <em>v</em>]</span>
-<pre>const char *luaL_checklstring (lua_State *L, int narg, size_t *l);</pre>
-
-<p>
-Checks whether the function argument <code>narg</code> is a string
-and returns this string;
-if <code>l</code> is not <code>NULL</code> fills <code>*l</code>
-with the string's length.
-
-
-<p>
-This function uses <a href="#lua_tolstring"><code>lua_tolstring</code></a> to get its result,
-so all conversions and caveats of that function apply here.
-
-
-
-
-
-<hr><h3><a name="luaL_checknumber"><code>luaL_checknumber</code></a></h3><p>
-<span class="apii">[-0, +0, <em>v</em>]</span>
-<pre>lua_Number luaL_checknumber (lua_State *L, int narg);</pre>
-
-<p>
-Checks whether the function argument <code>narg</code> is a number
-and returns this number.
-
-
-
-
-
-<hr><h3><a name="luaL_checkoption"><code>luaL_checkoption</code></a></h3><p>
-<span class="apii">[-0, +0, <em>v</em>]</span>
-<pre>int luaL_checkoption (lua_State *L,
- int narg,
- const char *def,
- const char *const lst[]);</pre>
-
-<p>
-Checks whether the function argument <code>narg</code> is a string and
-searches for this string in the array <code>lst</code>
-(which must be NULL-terminated).
-Returns the index in the array where the string was found.
-Raises an error if the argument is not a string or
-if the string cannot be found.
-
-
-<p>
-If <code>def</code> is not <code>NULL</code>,
-the function uses <code>def</code> as a default value when
-there is no argument <code>narg</code> or if this argument is <b>nil</b>.
-
-
-<p>
-This is a useful function for mapping strings to C&nbsp;enums.
-(The usual convention in Lua libraries is
-to use strings instead of numbers to select options.)
-
-
-
-
-
-<hr><h3><a name="luaL_checkstack"><code>luaL_checkstack</code></a></h3><p>
-<span class="apii">[-0, +0, <em>v</em>]</span>
-<pre>void luaL_checkstack (lua_State *L, int sz, const char *msg);</pre>
-
-<p>
-Grows the stack size to <code>top + sz</code> elements,
-raising an error if the stack cannot grow to that size.
-<code>msg</code> is an additional text to go into the error message.
-
-
-
-
-
-<hr><h3><a name="luaL_checkstring"><code>luaL_checkstring</code></a></h3><p>
-<span class="apii">[-0, +0, <em>v</em>]</span>
-<pre>const char *luaL_checkstring (lua_State *L, int narg);</pre>
-
-<p>
-Checks whether the function argument <code>narg</code> is a string
-and returns this string.
-
-
-<p>
-This function uses <a href="#lua_tolstring"><code>lua_tolstring</code></a> to get its result,
-so all conversions and caveats of that function apply here.
-
-
-
-
-
-<hr><h3><a name="luaL_checktype"><code>luaL_checktype</code></a></h3><p>
-<span class="apii">[-0, +0, <em>v</em>]</span>
-<pre>void luaL_checktype (lua_State *L, int narg, int t);</pre>
-
-<p>
-Checks whether the function argument <code>narg</code> has type <code>t</code>.
-See <a href="#lua_type"><code>lua_type</code></a> for the encoding of types for <code>t</code>.
-
-
-
-
-
-<hr><h3><a name="luaL_checkudata"><code>luaL_checkudata</code></a></h3><p>
-<span class="apii">[-0, +0, <em>v</em>]</span>
-<pre>void *luaL_checkudata (lua_State *L, int narg, const char *tname);</pre>
-
-<p>
-Checks whether the function argument <code>narg</code> is a userdata
-of the type <code>tname</code> (see <a href="#luaL_newmetatable"><code>luaL_newmetatable</code></a>).
-
-
-
-
-
-<hr><h3><a name="luaL_dofile"><code>luaL_dofile</code></a></h3><p>
-<span class="apii">[-0, +?, <em>m</em>]</span>
-<pre>int luaL_dofile (lua_State *L, const char *filename);</pre>
-
-<p>
-Loads and runs the given file.
-It is defined as the following macro:
-
-<pre>
- (luaL_loadfile(L, filename) || lua_pcall(L, 0, LUA_MULTRET, 0))
-</pre><p>
-It returns 0 if there are no errors
-or 1 in case of errors.
-
-
-
-
-
-<hr><h3><a name="luaL_dostring"><code>luaL_dostring</code></a></h3><p>
-<span class="apii">[-0, +?, <em>m</em>]</span>
-<pre>int luaL_dostring (lua_State *L, const char *str);</pre>
-
-<p>
-Loads and runs the given string.
-It is defined as the following macro:
-
-<pre>
- (luaL_loadstring(L, str) || lua_pcall(L, 0, LUA_MULTRET, 0))
-</pre><p>
-It returns 0 if there are no errors
-or 1 in case of errors.
-
-
-
-
-
-<hr><h3><a name="luaL_error"><code>luaL_error</code></a></h3><p>
-<span class="apii">[-0, +0, <em>v</em>]</span>
-<pre>int luaL_error (lua_State *L, const char *fmt, ...);</pre>
-
-<p>
-Raises an error.
-The error message format is given by <code>fmt</code>
-plus any extra arguments,
-following the same rules of <a href="#lua_pushfstring"><code>lua_pushfstring</code></a>.
-It also adds at the beginning of the message the file name and
-the line number where the error occurred,
-if this information is available.
-
-
-<p>
-This function never returns,
-but it is an idiom to use it in C&nbsp;functions
-as <code>return luaL_error(<em>args</em>)</code>.
-
-
-
-
-
-<hr><h3><a name="luaL_getmetafield"><code>luaL_getmetafield</code></a></h3><p>
-<span class="apii">[-0, +(0|1), <em>m</em>]</span>
-<pre>int luaL_getmetafield (lua_State *L, int obj, const char *e);</pre>
-
-<p>
-Pushes onto the stack the field <code>e</code> from the metatable
-of the object at index <code>obj</code>.
-If the object does not have a metatable,
-or if the metatable does not have this field,
-returns 0 and pushes nothing.
-
-
-
-
-
-<hr><h3><a name="luaL_getmetatable"><code>luaL_getmetatable</code></a></h3><p>
-<span class="apii">[-0, +1, <em>-</em>]</span>
-<pre>void luaL_getmetatable (lua_State *L, const char *tname);</pre>
-
-<p>
-Pushes onto the stack the metatable associated with name <code>tname</code>
-in the registry (see <a href="#luaL_newmetatable"><code>luaL_newmetatable</code></a>).
-
-
-
-
-
-<hr><h3><a name="luaL_gsub"><code>luaL_gsub</code></a></h3><p>
-<span class="apii">[-0, +1, <em>m</em>]</span>
-<pre>const char *luaL_gsub (lua_State *L,
- const char *s,
- const char *p,
- const char *r);</pre>
-
-<p>
-Creates a copy of string <code>s</code> by replacing
-any occurrence of the string <code>p</code>
-with the string <code>r</code>.
-Pushes the resulting string on the stack and returns it.
-
-
-
-
-
-<hr><h3><a name="luaL_loadbuffer"><code>luaL_loadbuffer</code></a></h3><p>
-<span class="apii">[-0, +1, <em>m</em>]</span>
-<pre>int luaL_loadbuffer (lua_State *L,
- const char *buff,
- size_t sz,
- const char *name);</pre>
-
-<p>
-Loads a buffer as a Lua chunk.
-This function uses <a href="#lua_load"><code>lua_load</code></a> to load the chunk in the
-buffer pointed to by <code>buff</code> with size <code>sz</code>.
-
-
-<p>
-This function returns the same results as <a href="#lua_load"><code>lua_load</code></a>.
-<code>name</code> is the chunk name,
-used for debug information and error messages.
-
-
-
-
-
-<hr><h3><a name="luaL_loadfile"><code>luaL_loadfile</code></a></h3><p>
-<span class="apii">[-0, +1, <em>m</em>]</span>
-<pre>int luaL_loadfile (lua_State *L, const char *filename);</pre>
-
-<p>
-Loads a file as a Lua chunk.
-This function uses <a href="#lua_load"><code>lua_load</code></a> to load the chunk in the file
-named <code>filename</code>.
-If <code>filename</code> is <code>NULL</code>,
-then it loads from the standard input.
-The first line in the file is ignored if it starts with a <code>#</code>.
-
-
-<p>
-This function returns the same results as <a href="#lua_load"><code>lua_load</code></a>,
-but it has an extra error code <a name="pdf-LUA_ERRFILE"><code>LUA_ERRFILE</code></a>
-if it cannot open/read the file.
-
-
-<p>
-As <a href="#lua_load"><code>lua_load</code></a>, this function only loads the chunk;
-it does not run it.
-
-
-
-
-
-<hr><h3><a name="luaL_loadstring"><code>luaL_loadstring</code></a></h3><p>
-<span class="apii">[-0, +1, <em>m</em>]</span>
-<pre>int luaL_loadstring (lua_State *L, const char *s);</pre>
-
-<p>
-Loads a string as a Lua chunk.
-This function uses <a href="#lua_load"><code>lua_load</code></a> to load the chunk in
-the zero-terminated string <code>s</code>.
-
-
-<p>
-This function returns the same results as <a href="#lua_load"><code>lua_load</code></a>.
-
-
-<p>
-Also as <a href="#lua_load"><code>lua_load</code></a>, this function only loads the chunk;
-it does not run it.
-
-
-
-
-
-<hr><h3><a name="luaL_newmetatable"><code>luaL_newmetatable</code></a></h3><p>
-<span class="apii">[-0, +1, <em>m</em>]</span>
-<pre>int luaL_newmetatable (lua_State *L, const char *tname);</pre>
-
-<p>
-If the registry already has the key <code>tname</code>,
-returns 0.
-Otherwise,
-creates a new table to be used as a metatable for userdata,
-adds it to the registry with key <code>tname</code>,
-and returns 1.
-
-
-<p>
-In both cases pushes onto the stack the final value associated
-with <code>tname</code> in the registry.
-
-
-
-
-
-<hr><h3><a name="luaL_newstate"><code>luaL_newstate</code></a></h3><p>
-<span class="apii">[-0, +0, <em>-</em>]</span>
-<pre>lua_State *luaL_newstate (void);</pre>
-
-<p>
-Creates a new Lua state.
-It calls <a href="#lua_newstate"><code>lua_newstate</code></a> with an
-allocator based on the standard&nbsp;C <code>realloc</code> function
-and then sets a panic function (see <a href="#lua_atpanic"><code>lua_atpanic</code></a>) that prints
-an error message to the standard error output in case of fatal
-errors.
-
-
-<p>
-Returns the new state,
-or <code>NULL</code> if there is a memory allocation error.
-
-
-
-
-
-<hr><h3><a name="luaL_openlibs"><code>luaL_openlibs</code></a></h3><p>
-<span class="apii">[-0, +0, <em>m</em>]</span>
-<pre>void luaL_openlibs (lua_State *L);</pre>
-
-<p>
-Opens all standard Lua libraries into the given state.
-
-
-
-
-
-<hr><h3><a name="luaL_optint"><code>luaL_optint</code></a></h3><p>
-<span class="apii">[-0, +0, <em>v</em>]</span>
-<pre>int luaL_optint (lua_State *L, int narg, int d);</pre>
-
-<p>
-If the function argument <code>narg</code> is a number,
-returns this number cast to an <code>int</code>.
-If this argument is absent or is <b>nil</b>,
-returns <code>d</code>.
-Otherwise, raises an error.
-
-
-
-
-
-<hr><h3><a name="luaL_optinteger"><code>luaL_optinteger</code></a></h3><p>
-<span class="apii">[-0, +0, <em>v</em>]</span>
-<pre>lua_Integer luaL_optinteger (lua_State *L,
- int narg,
- lua_Integer d);</pre>
-
-<p>
-If the function argument <code>narg</code> is a number,
-returns this number cast to a <a href="#lua_Integer"><code>lua_Integer</code></a>.
-If this argument is absent or is <b>nil</b>,
-returns <code>d</code>.
-Otherwise, raises an error.
-
-
-
-
-
-<hr><h3><a name="luaL_optlong"><code>luaL_optlong</code></a></h3><p>
-<span class="apii">[-0, +0, <em>v</em>]</span>
-<pre>long luaL_optlong (lua_State *L, int narg, long d);</pre>
-
-<p>
-If the function argument <code>narg</code> is a number,
-returns this number cast to a <code>long</code>.
-If this argument is absent or is <b>nil</b>,
-returns <code>d</code>.
-Otherwise, raises an error.
-
-
-
-
-
-<hr><h3><a name="luaL_optlstring"><code>luaL_optlstring</code></a></h3><p>
-<span class="apii">[-0, +0, <em>v</em>]</span>
-<pre>const char *luaL_optlstring (lua_State *L,
- int narg,
- const char *d,
- size_t *l);</pre>
-
-<p>
-If the function argument <code>narg</code> is a string,
-returns this string.
-If this argument is absent or is <b>nil</b>,
-returns <code>d</code>.
-Otherwise, raises an error.
-
-
-<p>
-If <code>l</code> is not <code>NULL</code>,
-fills the position <code>*l</code> with the results's length.
-
-
-
-
-
-<hr><h3><a name="luaL_optnumber"><code>luaL_optnumber</code></a></h3><p>
-<span class="apii">[-0, +0, <em>v</em>]</span>
-<pre>lua_Number luaL_optnumber (lua_State *L, int narg, lua_Number d);</pre>
-
-<p>
-If the function argument <code>narg</code> is a number,
-returns this number.
-If this argument is absent or is <b>nil</b>,
-returns <code>d</code>.
-Otherwise, raises an error.
-
-
-
-
-
-<hr><h3><a name="luaL_optstring"><code>luaL_optstring</code></a></h3><p>
-<span class="apii">[-0, +0, <em>v</em>]</span>
-<pre>const char *luaL_optstring (lua_State *L,
- int narg,
- const char *d);</pre>
-
-<p>
-If the function argument <code>narg</code> is a string,
-returns this string.
-If this argument is absent or is <b>nil</b>,
-returns <code>d</code>.
-Otherwise, raises an error.
-
-
-
-
-
-<hr><h3><a name="luaL_prepbuffer"><code>luaL_prepbuffer</code></a></h3><p>
-<span class="apii">[-0, +0, <em>-</em>]</span>
-<pre>char *luaL_prepbuffer (luaL_Buffer *B);</pre>
-
-<p>
-Returns an address to a space of size <a name="pdf-LUAL_BUFFERSIZE"><code>LUAL_BUFFERSIZE</code></a>
-where you can copy a string to be added to buffer <code>B</code>
-(see <a href="#luaL_Buffer"><code>luaL_Buffer</code></a>).
-After copying the string into this space you must call
-<a href="#luaL_addsize"><code>luaL_addsize</code></a> with the size of the string to actually add
-it to the buffer.
-
-
-
-
-
-<hr><h3><a name="luaL_pushresult"><code>luaL_pushresult</code></a></h3><p>
-<span class="apii">[-?, +1, <em>m</em>]</span>
-<pre>void luaL_pushresult (luaL_Buffer *B);</pre>
-
-<p>
-Finishes the use of buffer <code>B</code> leaving the final string on
-the top of the stack.
-
-
-
-
-
-<hr><h3><a name="luaL_ref"><code>luaL_ref</code></a></h3><p>
-<span class="apii">[-1, +0, <em>m</em>]</span>
-<pre>int luaL_ref (lua_State *L, int t);</pre>
-
-<p>
-Creates and returns a <em>reference</em>,
-in the table at index <code>t</code>,
-for the object at the top of the stack (and pops the object).
-
-
-<p>
-A reference is a unique integer key.
-As long as you do not manually add integer keys into table <code>t</code>,
-<a href="#luaL_ref"><code>luaL_ref</code></a> ensures the uniqueness of the key it returns.
-You can retrieve an object referred by reference <code>r</code>
-by calling <code>lua_rawgeti(L, t, r)</code>.
-Function <a href="#luaL_unref"><code>luaL_unref</code></a> frees a reference and its associated object.
-
-
-<p>
-If the object at the top of the stack is <b>nil</b>,
-<a href="#luaL_ref"><code>luaL_ref</code></a> returns the constant <a name="pdf-LUA_REFNIL"><code>LUA_REFNIL</code></a>.
-The constant <a name="pdf-LUA_NOREF"><code>LUA_NOREF</code></a> is guaranteed to be different
-from any reference returned by <a href="#luaL_ref"><code>luaL_ref</code></a>.
-
-
-
-
-
-<hr><h3><a name="luaL_Reg"><code>luaL_Reg</code></a></h3>
-<pre>typedef struct luaL_Reg {
- const char *name;
- lua_CFunction func;
-} luaL_Reg;</pre>
-
-<p>
-Type for arrays of functions to be registered by
-<a href="#luaL_register"><code>luaL_register</code></a>.
-<code>name</code> is the function name and <code>func</code> is a pointer to
-the function.
-Any array of <a href="#luaL_Reg"><code>luaL_Reg</code></a> must end with an sentinel entry
-in which both <code>name</code> and <code>func</code> are <code>NULL</code>.
-
-
-
-
-
-<hr><h3><a name="luaL_register"><code>luaL_register</code></a></h3><p>
-<span class="apii">[-(0|1), +1, <em>m</em>]</span>
-<pre>void luaL_register (lua_State *L,
- const char *libname,
- const luaL_Reg *l);</pre>
-
-<p>
-Opens a library.
-
-
-<p>
-When called with <code>libname</code> equal to <code>NULL</code>,
-it simply registers all functions in the list <code>l</code>
-(see <a href="#luaL_Reg"><code>luaL_Reg</code></a>) into the table on the top of the stack.
-
-
-<p>
-When called with a non-null <code>libname</code>,
-<code>luaL_register</code> creates a new table <code>t</code>,
-sets it as the value of the global variable <code>libname</code>,
-sets it as the value of <code>package.loaded[libname]</code>,
-and registers on it all functions in the list <code>l</code>.
-If there is a table in <code>package.loaded[libname]</code> or in
-variable <code>libname</code>,
-reuses this table instead of creating a new one.
-
-
-<p>
-In any case the function leaves the table
-on the top of the stack.
-
-
-
-
-
-<hr><h3><a name="luaL_typename"><code>luaL_typename</code></a></h3><p>
-<span class="apii">[-0, +0, <em>-</em>]</span>
-<pre>const char *luaL_typename (lua_State *L, int index);</pre>
-
-<p>
-Returns the name of the type of the value at the given index.
-
-
-
-
-
-<hr><h3><a name="luaL_typerror"><code>luaL_typerror</code></a></h3><p>
-<span class="apii">[-0, +0, <em>v</em>]</span>
-<pre>int luaL_typerror (lua_State *L, int narg, const char *tname);</pre>
-
-<p>
-Generates an error with a message like the following:
-
-<pre>
- <em>location</em>: bad argument <em>narg</em> to '<em>func</em>' (<em>tname</em> expected, got <em>rt</em>)
-</pre><p>
-where <code><em>location</em></code> is produced by <a href="#luaL_where"><code>luaL_where</code></a>,
-<code><em>func</em></code> is the name of the current function,
-and <code><em>rt</em></code> is the type name of the actual argument.
-
-
-
-
-
-<hr><h3><a name="luaL_unref"><code>luaL_unref</code></a></h3><p>
-<span class="apii">[-0, +0, <em>-</em>]</span>
-<pre>void luaL_unref (lua_State *L, int t, int ref);</pre>
-
-<p>
-Releases reference <code>ref</code> from the table at index <code>t</code>
-(see <a href="#luaL_ref"><code>luaL_ref</code></a>).
-The entry is removed from the table,
-so that the referred object can be collected.
-The reference <code>ref</code> is also freed to be used again.
-
-
-<p>
-If <code>ref</code> is <a href="#pdf-LUA_NOREF"><code>LUA_NOREF</code></a> or <a href="#pdf-LUA_REFNIL"><code>LUA_REFNIL</code></a>,
-<a href="#luaL_unref"><code>luaL_unref</code></a> does nothing.
-
-
-
-
-
-<hr><h3><a name="luaL_where"><code>luaL_where</code></a></h3><p>
-<span class="apii">[-0, +1, <em>m</em>]</span>
-<pre>void luaL_where (lua_State *L, int lvl);</pre>
-
-<p>
-Pushes onto the stack a string identifying the current position
-of the control at level <code>lvl</code> in the call stack.
-Typically this string has the following format:
-
-<pre>
- <em>chunkname</em>:<em>currentline</em>:
-</pre><p>
-Level&nbsp;0 is the running function,
-level&nbsp;1 is the function that called the running function,
-etc.
-
-
-<p>
-This function is used to build a prefix for error messages.
-
-
-
-
-
-
-
-<h1>5 - <a name="5">Standard Libraries</a></h1>
-
-<p>
-The standard Lua libraries provide useful functions
-that are implemented directly through the C&nbsp;API.
-Some of these functions provide essential services to the language
-(e.g., <a href="#pdf-type"><code>type</code></a> and <a href="#pdf-getmetatable"><code>getmetatable</code></a>);
-others provide access to "outside" services (e.g., I/O);
-and others could be implemented in Lua itself,
-but are quite useful or have critical performance requirements that
-deserve an implementation in C (e.g., <a href="#pdf-table.sort"><code>table.sort</code></a>).
-
-
-<p>
-All libraries are implemented through the official C&nbsp;API
-and are provided as separate C&nbsp;modules.
-Currently, Lua has the following standard libraries:
-
-<ul>
-
-<li>basic library,</li> which includes the coroutine sub-library;
-
-<li>package library;</li>
-
-<li>string manipulation;</li>
-
-<li>table manipulation;</li>
-
-<li>mathematical functions (sin, log, etc.);</li>
-
-<li>input and output;</li>
-
-<li>operating system facilities;</li>
-
-<li>debug facilities.</li>
-
-</ul><p>
-Except for the basic and package libraries,
-each library provides all its functions as fields of a global table
-or as methods of its objects.
-
-
-<p>
-To have access to these libraries,
-the C&nbsp;host program should call the <a href="#luaL_openlibs"><code>luaL_openlibs</code></a> function,
-which opens all standard libraries.
-Alternatively,
-it can open them individually by calling
-<a name="pdf-luaopen_base"><code>luaopen_base</code></a> (for the basic library),
-<a name="pdf-luaopen_package"><code>luaopen_package</code></a> (for the package library),
-<a name="pdf-luaopen_string"><code>luaopen_string</code></a> (for the string library),
-<a name="pdf-luaopen_table"><code>luaopen_table</code></a> (for the table library),
-<a name="pdf-luaopen_math"><code>luaopen_math</code></a> (for the mathematical library),
-<a name="pdf-luaopen_io"><code>luaopen_io</code></a> (for the I/O library),
-<a name="pdf-luaopen_os"><code>luaopen_os</code></a> (for the Operating System library),
-and <a name="pdf-luaopen_debug"><code>luaopen_debug</code></a> (for the debug library).
-These functions are declared in <a name="pdf-lualib.h"><code>lualib.h</code></a>
-and should not be called directly:
-you must call them like any other Lua C&nbsp;function,
-e.g., by using <a href="#lua_call"><code>lua_call</code></a>.
-
-
-
-<h2>5.1 - <a name="5.1">Basic Functions</a></h2>
-
-<p>
-The basic library provides some core functions to Lua.
-If you do not include this library in your application,
-you should check carefully whether you need to provide
-implementations for some of its facilities.
-
-
-<p>
-<hr><h3><a name="pdf-assert"><code>assert (v [, message])</code></a></h3>
-Issues an error when
-the value of its argument <code>v</code> is false (i.e., <b>nil</b> or <b>false</b>);
-otherwise, returns all its arguments.
-<code>message</code> is an error message;
-when absent, it defaults to "assertion failed!"
-
-
-
-
-<p>
-<hr><h3><a name="pdf-collectgarbage"><code>collectgarbage (opt [, arg])</code></a></h3>
-
-
-<p>
-This function is a generic interface to the garbage collector.
-It performs different functions according to its first argument, <code>opt</code>:
-
-<ul>
-
-<li><b>"stop":</b>
-stops the garbage collector.
-</li>
-
-<li><b>"restart":</b>
-restarts the garbage collector.
-</li>
-
-<li><b>"collect":</b>
-performs a full garbage-collection cycle.
-</li>
-
-<li><b>"count":</b>
-returns the total memory in use by Lua (in Kbytes).
-</li>
-
-<li><b>"step":</b>
-performs a garbage-collection step.
-The step "size" is controlled by <code>arg</code>
-(larger values mean more steps) in a non-specified way.
-If you want to control the step size
-you must experimentally tune the value of <code>arg</code>.
-Returns <b>true</b> if the step finished a collection cycle.
-</li>
-
-<li><b>"setpause":</b>
-sets <code>arg</code> as the new value for the <em>pause</em> of
-the collector (see <a href="#2.10">&sect;2.10</a>).
-Returns the previous value for <em>pause</em>.
-</li>
-
-<li><b>"setstepmul":</b>
-sets <code>arg</code> as the new value for the <em>step multiplier</em> of
-the collector (see <a href="#2.10">&sect;2.10</a>).
-Returns the previous value for <em>step</em>.
-</li>
-
-</ul>
-
-
-
-<p>
-<hr><h3><a name="pdf-dofile"><code>dofile (filename)</code></a></h3>
-Opens the named file and executes its contents as a Lua chunk.
-When called without arguments,
-<code>dofile</code> executes the contents of the standard input (<code>stdin</code>).
-Returns all values returned by the chunk.
-In case of errors, <code>dofile</code> propagates the error
-to its caller (that is, <code>dofile</code> does not run in protected mode).
-
-
-
-
-<p>
-<hr><h3><a name="pdf-error"><code>error (message [, level])</code></a></h3>
-Terminates the last protected function called
-and returns <code>message</code> as the error message.
-Function <code>error</code> never returns.
-
-
-<p>
-Usually, <code>error</code> adds some information about the error position
-at the beginning of the message.
-The <code>level</code> argument specifies how to get the error position.
-With level&nbsp;1 (the default), the error position is where the
-<code>error</code> function was called.
-Level&nbsp;2 points the error to where the function
-that called <code>error</code> was called; and so on.
-Passing a level&nbsp;0 avoids the addition of error position information
-to the message.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-_G"><code>_G</code></a></h3>
-A global variable (not a function) that
-holds the global environment (that is, <code>_G._G = _G</code>).
-Lua itself does not use this variable;
-changing its value does not affect any environment,
-nor vice-versa.
-(Use <a href="#pdf-setfenv"><code>setfenv</code></a> to change environments.)
-
-
-
-
-<p>
-<hr><h3><a name="pdf-getfenv"><code>getfenv ([f])</code></a></h3>
-Returns the current environment in use by the function.
-<code>f</code> can be a Lua function or a number
-that specifies the function at that stack level:
-Level&nbsp;1 is the function calling <code>getfenv</code>.
-If the given function is not a Lua function,
-or if <code>f</code> is 0,
-<code>getfenv</code> returns the global environment.
-The default for <code>f</code> is 1.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-getmetatable"><code>getmetatable (object)</code></a></h3>
-
-
-<p>
-If <code>object</code> does not have a metatable, returns <b>nil</b>.
-Otherwise,
-if the object's metatable has a <code>"__metatable"</code> field,
-returns the associated value.
-Otherwise, returns the metatable of the given object.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-ipairs"><code>ipairs (t)</code></a></h3>
-
-
-<p>
-Returns three values: an iterator function, the table <code>t</code>, and 0,
-so that the construction
-
-<pre>
- for i,v in ipairs(t) do <em>body</em> end
-</pre><p>
-will iterate over the pairs (<code>1,t[1]</code>), (<code>2,t[2]</code>), &middot;&middot;&middot;,
-up to the first integer key absent from the table.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-load"><code>load (func [, chunkname])</code></a></h3>
-
-
-<p>
-Loads a chunk using function <code>func</code> to get its pieces.
-Each call to <code>func</code> must return a string that concatenates
-with previous results.
-A return of an empty string, <b>nil</b>, or no value signals the end of the chunk.
-
-
-<p>
-If there are no errors,
-returns the compiled chunk as a function;
-otherwise, returns <b>nil</b> plus the error message.
-The environment of the returned function is the global environment.
-
-
-<p>
-<code>chunkname</code> is used as the chunk name for error messages
-and debug information.
-When absent,
-it defaults to "<code>=(load)</code>".
-
-
-
-
-<p>
-<hr><h3><a name="pdf-loadfile"><code>loadfile ([filename])</code></a></h3>
-
-
-<p>
-Similar to <a href="#pdf-load"><code>load</code></a>,
-but gets the chunk from file <code>filename</code>
-or from the standard input,
-if no file name is given.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-loadstring"><code>loadstring (string [, chunkname])</code></a></h3>
-
-
-<p>
-Similar to <a href="#pdf-load"><code>load</code></a>,
-but gets the chunk from the given string.
-
-
-<p>
-To load and run a given string, use the idiom
-
-<pre>
- assert(loadstring(s))()
-</pre>
-
-<p>
-When absent,
-<code>chunkname</code> defaults to the given string.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-next"><code>next (table [, index])</code></a></h3>
-
-
-<p>
-Allows a program to traverse all fields of a table.
-Its first argument is a table and its second argument
-is an index in this table.
-<code>next</code> returns the next index of the table
-and its associated value.
-When called with <b>nil</b> as its second argument,
-<code>next</code> returns an initial index
-and its associated value.
-When called with the last index,
-or with <b>nil</b> in an empty table,
-<code>next</code> returns <b>nil</b>.
-If the second argument is absent, then it is interpreted as <b>nil</b>.
-In particular,
-you can use <code>next(t)</code> to check whether a table is empty.
-
-
-<p>
-The order in which the indices are enumerated is not specified,
-<em>even for numeric indices</em>.
-(To traverse a table in numeric order,
-use a numerical <b>for</b> or the <a href="#pdf-ipairs"><code>ipairs</code></a> function.)
-
-
-<p>
-The behavior of <code>next</code> is <em>undefined</em> if,
-during the traversal,
-you assign any value to a non-existent field in the table.
-You may however modify existing fields.
-In particular, you may clear existing fields.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-pairs"><code>pairs (t)</code></a></h3>
-
-
-<p>
-Returns three values: the <a href="#pdf-next"><code>next</code></a> function, the table <code>t</code>, and <b>nil</b>,
-so that the construction
-
-<pre>
- for k,v in pairs(t) do <em>body</em> end
-</pre><p>
-will iterate over all key&ndash;value pairs of table <code>t</code>.
-
-
-<p>
-See function <a href="#pdf-next"><code>next</code></a> for the caveats of modifying
-the table during its traversal.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-pcall"><code>pcall (f, arg1, &middot;&middot;&middot;)</code></a></h3>
-
-
-<p>
-Calls function <code>f</code> with
-the given arguments in <em>protected mode</em>.
-This means that any error inside&nbsp;<code>f</code> is not propagated;
-instead, <code>pcall</code> catches the error
-and returns a status code.
-Its first result is the status code (a boolean),
-which is true if the call succeeds without errors.
-In such case, <code>pcall</code> also returns all results from the call,
-after this first result.
-In case of any error, <code>pcall</code> returns <b>false</b> plus the error message.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-print"><code>print (&middot;&middot;&middot;)</code></a></h3>
-Receives any number of arguments,
-and prints their values to <code>stdout</code>,
-using the <a href="#pdf-tostring"><code>tostring</code></a> function to convert them to strings.
-<code>print</code> is not intended for formatted output,
-but only as a quick way to show a value,
-typically for debugging.
-For formatted output, use <a href="#pdf-string.format"><code>string.format</code></a>.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-rawequal"><code>rawequal (v1, v2)</code></a></h3>
-Checks whether <code>v1</code> is equal to <code>v2</code>,
-without invoking any metamethod.
-Returns a boolean.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-rawget"><code>rawget (table, index)</code></a></h3>
-Gets the real value of <code>table[index]</code>,
-without invoking any metamethod.
-<code>table</code> must be a table;
-<code>index</code> may be any value.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-rawset"><code>rawset (table, index, value)</code></a></h3>
-Sets the real value of <code>table[index]</code> to <code>value</code>,
-without invoking any metamethod.
-<code>table</code> must be a table,
-<code>index</code> any value different from <b>nil</b>,
-and <code>value</code> any Lua value.
-
-
-<p>
-This function returns <code>table</code>.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-select"><code>select (index, &middot;&middot;&middot;)</code></a></h3>
-
-
-<p>
-If <code>index</code> is a number,
-returns all arguments after argument number <code>index</code>.
-Otherwise, <code>index</code> must be the string <code>"#"</code>,
-and <code>select</code> returns the total number of extra arguments it received.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-setfenv"><code>setfenv (f, table)</code></a></h3>
-
-
-<p>
-Sets the environment to be used by the given function.
-<code>f</code> can be a Lua function or a number
-that specifies the function at that stack level:
-Level&nbsp;1 is the function calling <code>setfenv</code>.
-<code>setfenv</code> returns the given function.
-
-
-<p>
-As a special case, when <code>f</code> is 0 <code>setfenv</code> changes
-the environment of the running thread.
-In this case, <code>setfenv</code> returns no values.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-setmetatable"><code>setmetatable (table, metatable)</code></a></h3>
-
-
-<p>
-Sets the metatable for the given table.
-(You cannot change the metatable of other types from Lua, only from&nbsp;C.)
-If <code>metatable</code> is <b>nil</b>,
-removes the metatable of the given table.
-If the original metatable has a <code>"__metatable"</code> field,
-raises an error.
-
-
-<p>
-This function returns <code>table</code>.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-tonumber"><code>tonumber (e [, base])</code></a></h3>
-Tries to convert its argument to a number.
-If the argument is already a number or a string convertible
-to a number, then <code>tonumber</code> returns this number;
-otherwise, it returns <b>nil</b>.
-
-
-<p>
-An optional argument specifies the base to interpret the numeral.
-The base may be any integer between 2 and 36, inclusive.
-In bases above&nbsp;10, the letter '<code>A</code>' (in either upper or lower case)
-represents&nbsp;10, '<code>B</code>' represents&nbsp;11, and so forth,
-with '<code>Z</code>' representing 35.
-In base 10 (the default), the number can have a decimal part,
-as well as an optional exponent part (see <a href="#2.1">&sect;2.1</a>).
-In other bases, only unsigned integers are accepted.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-tostring"><code>tostring (e)</code></a></h3>
-Receives an argument of any type and
-converts it to a string in a reasonable format.
-For complete control of how numbers are converted,
-use <a href="#pdf-string.format"><code>string.format</code></a>.
-
-
-<p>
-If the metatable of <code>e</code> has a <code>"__tostring"</code> field,
-then <code>tostring</code> calls the corresponding value
-with <code>e</code> as argument,
-and uses the result of the call as its result.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-type"><code>type (v)</code></a></h3>
-Returns the type of its only argument, coded as a string.
-The possible results of this function are
-"<code>nil</code>" (a string, not the value <b>nil</b>),
-"<code>number</code>",
-"<code>string</code>",
-"<code>boolean</code>",
-"<code>table</code>",
-"<code>function</code>",
-"<code>thread</code>",
-and "<code>userdata</code>".
-
-
-
-
-<p>
-<hr><h3><a name="pdf-unpack"><code>unpack (list [, i [, j]])</code></a></h3>
-Returns the elements from the given table.
-This function is equivalent to
-
-<pre>
- return list[i], list[i+1], &middot;&middot;&middot;, list[j]
-</pre><p>
-except that the above code can be written only for a fixed number
-of elements.
-By default, <code>i</code> is&nbsp;1 and <code>j</code> is the length of the list,
-as defined by the length operator (see <a href="#2.5.5">&sect;2.5.5</a>).
-
-
-
-
-<p>
-<hr><h3><a name="pdf-_VERSION"><code>_VERSION</code></a></h3>
-A global variable (not a function) that
-holds a string containing the current interpreter version.
-The current contents of this variable is "<code>Lua 5.1</code>".
-
-
-
-
-<p>
-<hr><h3><a name="pdf-xpcall"><code>xpcall (f, err)</code></a></h3>
-
-
-<p>
-This function is similar to <a href="#pdf-pcall"><code>pcall</code></a>,
-except that you can set a new error handler.
-
-
-<p>
-<code>xpcall</code> calls function <code>f</code> in protected mode,
-using <code>err</code> as the error handler.
-Any error inside <code>f</code> is not propagated;
-instead, <code>xpcall</code> catches the error,
-calls the <code>err</code> function with the original error object,
-and returns a status code.
-Its first result is the status code (a boolean),
-which is true if the call succeeds without errors.
-In this case, <code>xpcall</code> also returns all results from the call,
-after this first result.
-In case of any error,
-<code>xpcall</code> returns <b>false</b> plus the result from <code>err</code>.
-
-
-
-
-
-
-
-<h2>5.2 - <a name="5.2">Coroutine Manipulation</a></h2>
-
-<p>
-The operations related to coroutines comprise a sub-library of
-the basic library and come inside the table <a name="pdf-coroutine"><code>coroutine</code></a>.
-See <a href="#2.11">&sect;2.11</a> for a general description of coroutines.
-
-
-<p>
-<hr><h3><a name="pdf-coroutine.create"><code>coroutine.create (f)</code></a></h3>
-
-
-<p>
-Creates a new coroutine, with body <code>f</code>.
-<code>f</code> must be a Lua function.
-Returns this new coroutine,
-an object with type <code>"thread"</code>.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-coroutine.resume"><code>coroutine.resume (co [, val1, &middot;&middot;&middot;])</code></a></h3>
-
-
-<p>
-Starts or continues the execution of coroutine <code>co</code>.
-The first time you resume a coroutine,
-it starts running its body.
-The values <code>val1</code>, &middot;&middot;&middot; are passed
-as the arguments to the body function.
-If the coroutine has yielded,
-<code>resume</code> restarts it;
-the values <code>val1</code>, &middot;&middot;&middot; are passed
-as the results from the yield.
-
-
-<p>
-If the coroutine runs without any errors,
-<code>resume</code> returns <b>true</b> plus any values passed to <code>yield</code>
-(if the coroutine yields) or any values returned by the body function
-(if the coroutine terminates).
-If there is any error,
-<code>resume</code> returns <b>false</b> plus the error message.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-coroutine.running"><code>coroutine.running ()</code></a></h3>
-
-
-<p>
-Returns the running coroutine,
-or <b>nil</b> when called by the main thread.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-coroutine.status"><code>coroutine.status (co)</code></a></h3>
-
-
-<p>
-Returns the status of coroutine <code>co</code>, as a string:
-<code>"running"</code>,
-if the coroutine is running (that is, it called <code>status</code>);
-<code>"suspended"</code>, if the coroutine is suspended in a call to <code>yield</code>,
-or if it has not started running yet;
-<code>"normal"</code> if the coroutine is active but not running
-(that is, it has resumed another coroutine);
-and <code>"dead"</code> if the coroutine has finished its body function,
-or if it has stopped with an error.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-coroutine.wrap"><code>coroutine.wrap (f)</code></a></h3>
-
-
-<p>
-Creates a new coroutine, with body <code>f</code>.
-<code>f</code> must be a Lua function.
-Returns a function that resumes the coroutine each time it is called.
-Any arguments passed to the function behave as the
-extra arguments to <code>resume</code>.
-Returns the same values returned by <code>resume</code>,
-except the first boolean.
-In case of error, propagates the error.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-coroutine.yield"><code>coroutine.yield (&middot;&middot;&middot;)</code></a></h3>
-
-
-<p>
-Suspends the execution of the calling coroutine.
-The coroutine cannot be running a C&nbsp;function,
-a metamethod, or an iterator.
-Any arguments to <code>yield</code> are passed as extra results to <code>resume</code>.
-
-
-
-
-
-
-
-<h2>5.3 - <a name="5.3">Modules</a></h2>
-
-<p>
-The package library provides basic
-facilities for loading and building modules in Lua.
-It exports two of its functions directly in the global environment:
-<a href="#pdf-require"><code>require</code></a> and <a href="#pdf-module"><code>module</code></a>.
-Everything else is exported in a table <a name="pdf-package"><code>package</code></a>.
-
-
-<p>
-<hr><h3><a name="pdf-module"><code>module (name [, &middot;&middot;&middot;])</code></a></h3>
-
-
-<p>
-Creates a module.
-If there is a table in <code>package.loaded[name]</code>,
-this table is the module.
-Otherwise, if there is a global table <code>t</code> with the given name,
-this table is the module.
-Otherwise creates a new table <code>t</code> and
-sets it as the value of the global <code>name</code> and
-the value of <code>package.loaded[name]</code>.
-This function also initializes <code>t._NAME</code> with the given name,
-<code>t._M</code> with the module (<code>t</code> itself),
-and <code>t._PACKAGE</code> with the package name
-(the full module name minus last component; see below).
-Finally, <code>module</code> sets <code>t</code> as the new environment
-of the current function and the new value of <code>package.loaded[name]</code>,
-so that <a href="#pdf-require"><code>require</code></a> returns <code>t</code>.
-
-
-<p>
-If <code>name</code> is a compound name
-(that is, one with components separated by dots),
-<code>module</code> creates (or reuses, if they already exist)
-tables for each component.
-For instance, if <code>name</code> is <code>a.b.c</code>,
-then <code>module</code> stores the module table in field <code>c</code> of
-field <code>b</code> of global <code>a</code>.
-
-
-<p>
-This function can receive optional <em>options</em> after
-the module name,
-where each option is a function to be applied over the module.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-require"><code>require (modname)</code></a></h3>
-
-
-<p>
-Loads the given module.
-The function starts by looking into the <a href="#pdf-package.loaded"><code>package.loaded</code></a> table
-to determine whether <code>modname</code> is already loaded.
-If it is, then <code>require</code> returns the value stored
-at <code>package.loaded[modname]</code>.
-Otherwise, it tries to find a <em>loader</em> for the module.
-
-
-<p>
-To find a loader,
-<code>require</code> is guided by the <a href="#pdf-package.loaders"><code>package.loaders</code></a> array.
-By changing this array,
-we can change how <code>require</code> looks for a module.
-The following explanation is based on the default configuration
-for <a href="#pdf-package.loaders"><code>package.loaders</code></a>.
-
-
-<p>
-First <code>require</code> queries <code>package.preload[modname]</code>.
-If it has a value,
-this value (which should be a function) is the loader.
-Otherwise <code>require</code> searches for a Lua loader using the
-path stored in <a href="#pdf-package.path"><code>package.path</code></a>.
-If that also fails, it searches for a C&nbsp;loader using the
-path stored in <a href="#pdf-package.cpath"><code>package.cpath</code></a>.
-If that also fails,
-it tries an <em>all-in-one</em> loader (see <a href="#pdf-package.loaders"><code>package.loaders</code></a>).
-
-
-<p>
-Once a loader is found,
-<code>require</code> calls the loader with a single argument, <code>modname</code>.
-If the loader returns any value,
-<code>require</code> assigns the returned value to <code>package.loaded[modname]</code>.
-If the loader returns no value and
-has not assigned any value to <code>package.loaded[modname]</code>,
-then <code>require</code> assigns <b>true</b> to this entry.
-In any case, <code>require</code> returns the
-final value of <code>package.loaded[modname]</code>.
-
-
-<p>
-If there is any error loading or running the module,
-or if it cannot find any loader for the module,
-then <code>require</code> signals an error.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-package.cpath"><code>package.cpath</code></a></h3>
-
-
-<p>
-The path used by <a href="#pdf-require"><code>require</code></a> to search for a C&nbsp;loader.
-
-
-<p>
-Lua initializes the C&nbsp;path <a href="#pdf-package.cpath"><code>package.cpath</code></a> in the same way
-it initializes the Lua path <a href="#pdf-package.path"><code>package.path</code></a>,
-using the environment variable <a name="pdf-LUA_CPATH"><code>LUA_CPATH</code></a>
-or a default path defined in <code>luaconf.h</code>.
-
-
-
-
-<p>
-
-<hr><h3><a name="pdf-package.loaded"><code>package.loaded</code></a></h3>
-
-
-<p>
-A table used by <a href="#pdf-require"><code>require</code></a> to control which
-modules are already loaded.
-When you require a module <code>modname</code> and
-<code>package.loaded[modname]</code> is not false,
-<a href="#pdf-require"><code>require</code></a> simply returns the value stored there.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-package.loaders"><code>package.loaders</code></a></h3>
-
-
-<p>
-A table used by <a href="#pdf-require"><code>require</code></a> to control how to load modules.
-
-
-<p>
-Each entry in this table is a <em>searcher function</em>.
-When looking for a module,
-<a href="#pdf-require"><code>require</code></a> calls each of these searchers in ascending order,
-with the module name (the argument given to <a href="#pdf-require"><code>require</code></a>) as its
-sole parameter.
-The function can return another function (the module <em>loader</em>)
-or a string explaining why it did not find that module
-(or <b>nil</b> if it has nothing to say).
-Lua initializes this table with four functions.
-
-
-<p>
-The first searcher simply looks for a loader in the
-<a href="#pdf-package.preload"><code>package.preload</code></a> table.
-
-
-<p>
-The second searcher looks for a loader as a Lua library,
-using the path stored at <a href="#pdf-package.path"><code>package.path</code></a>.
-A path is a sequence of <em>templates</em> separated by semicolons.
-For each template,
-the searcher will change each interrogation
-mark in the template by <code>filename</code>,
-which is the module name with each dot replaced by a
-"directory separator" (such as "<code>/</code>" in Unix);
-then it will try to open the resulting file name.
-So, for instance, if the Lua path is the string
-
-<pre>
- "./?.lua;./?.lc;/usr/local/?/init.lua"
-</pre><p>
-the search for a Lua file for module <code>foo</code>
-will try to open the files
-<code>./foo.lua</code>, <code>./foo.lc</code>, and
-<code>/usr/local/foo/init.lua</code>, in that order.
-
-
-<p>
-The third searcher looks for a loader as a C&nbsp;library,
-using the path given by the variable <a href="#pdf-package.cpath"><code>package.cpath</code></a>.
-For instance,
-if the C&nbsp;path is the string
-
-<pre>
- "./?.so;./?.dll;/usr/local/?/init.so"
-</pre><p>
-the searcher for module <code>foo</code>
-will try to open the files <code>./foo.so</code>, <code>./foo.dll</code>,
-and <code>/usr/local/foo/init.so</code>, in that order.
-Once it finds a C&nbsp;library,
-this searcher first uses a dynamic link facility to link the
-application with the library.
-Then it tries to find a C&nbsp;function inside the library to
-be used as the loader.
-The name of this C&nbsp;function is the string "<code>luaopen_</code>"
-concatenated with a copy of the module name where each dot
-is replaced by an underscore.
-Moreover, if the module name has a hyphen,
-its prefix up to (and including) the first hyphen is removed.
-For instance, if the module name is <code>a.v1-b.c</code>,
-the function name will be <code>luaopen_b_c</code>.
-
-
-<p>
-The fourth searcher tries an <em>all-in-one loader</em>.
-It searches the C&nbsp;path for a library for
-the root name of the given module.
-For instance, when requiring <code>a.b.c</code>,
-it will search for a C&nbsp;library for <code>a</code>.
-If found, it looks into it for an open function for
-the submodule;
-in our example, that would be <code>luaopen_a_b_c</code>.
-With this facility, a package can pack several C&nbsp;submodules
-into one single library,
-with each submodule keeping its original open function.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-package.loadlib"><code>package.loadlib (libname, funcname)</code></a></h3>
-
-
-<p>
-Dynamically links the host program with the C&nbsp;library <code>libname</code>.
-Inside this library, looks for a function <code>funcname</code>
-and returns this function as a C&nbsp;function.
-(So, <code>funcname</code> must follow the protocol (see <a href="#lua_CFunction"><code>lua_CFunction</code></a>)).
-
-
-<p>
-This is a low-level function.
-It completely bypasses the package and module system.
-Unlike <a href="#pdf-require"><code>require</code></a>,
-it does not perform any path searching and
-does not automatically adds extensions.
-<code>libname</code> must be the complete file name of the C&nbsp;library,
-including if necessary a path and extension.
-<code>funcname</code> must be the exact name exported by the C&nbsp;library
-(which may depend on the C&nbsp;compiler and linker used).
-
-
-<p>
-This function is not supported by ANSI C.
-As such, it is only available on some platforms
-(Windows, Linux, Mac OS X, Solaris, BSD,
-plus other Unix systems that support the <code>dlfcn</code> standard).
-
-
-
-
-<p>
-<hr><h3><a name="pdf-package.path"><code>package.path</code></a></h3>
-
-
-<p>
-The path used by <a href="#pdf-require"><code>require</code></a> to search for a Lua loader.
-
-
-<p>
-At start-up, Lua initializes this variable with
-the value of the environment variable <a name="pdf-LUA_PATH"><code>LUA_PATH</code></a> or
-with a default path defined in <code>luaconf.h</code>,
-if the environment variable is not defined.
-Any "<code>;;</code>" in the value of the environment variable
-is replaced by the default path.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-package.preload"><code>package.preload</code></a></h3>
-
-
-<p>
-A table to store loaders for specific modules
-(see <a href="#pdf-require"><code>require</code></a>).
-
-
-
-
-<p>
-<hr><h3><a name="pdf-package.seeall"><code>package.seeall (module)</code></a></h3>
-
-
-<p>
-Sets a metatable for <code>module</code> with
-its <code>__index</code> field referring to the global environment,
-so that this module inherits values
-from the global environment.
-To be used as an option to function <a href="#pdf-module"><code>module</code></a>.
-
-
-
-
-
-
-
-<h2>5.4 - <a name="5.4">String Manipulation</a></h2>
-
-<p>
-This library provides generic functions for string manipulation,
-such as finding and extracting substrings, and pattern matching.
-When indexing a string in Lua, the first character is at position&nbsp;1
-(not at&nbsp;0, as in C).
-Indices are allowed to be negative and are interpreted as indexing backwards,
-from the end of the string.
-Thus, the last character is at position -1, and so on.
-
-
-<p>
-The string library provides all its functions inside the table
-<a name="pdf-string"><code>string</code></a>.
-It also sets a metatable for strings
-where the <code>__index</code> field points to the <code>string</code> table.
-Therefore, you can use the string functions in object-oriented style.
-For instance, <code>string.byte(s, i)</code>
-can be written as <code>s:byte(i)</code>.
-
-
-<p>
-The string library assumes one-byte character encodings.
-
-
-<p>
-<hr><h3><a name="pdf-string.byte"><code>string.byte (s [, i [, j]])</code></a></h3>
-Returns the internal numerical codes of the characters <code>s[i]</code>,
-<code>s[i+1]</code>, &middot;&middot;&middot;, <code>s[j]</code>.
-The default value for <code>i</code> is&nbsp;1;
-the default value for <code>j</code> is&nbsp;<code>i</code>.
-
-
-<p>
-Note that numerical codes are not necessarily portable across platforms.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-string.char"><code>string.char (&middot;&middot;&middot;)</code></a></h3>
-Receives zero or more integers.
-Returns a string with length equal to the number of arguments,
-in which each character has the internal numerical code equal
-to its corresponding argument.
-
-
-<p>
-Note that numerical codes are not necessarily portable across platforms.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-string.dump"><code>string.dump (function)</code></a></h3>
-
-
-<p>
-Returns a string containing a binary representation of the given function,
-so that a later <a href="#pdf-loadstring"><code>loadstring</code></a> on this string returns
-a copy of the function.
-<code>function</code> must be a Lua function without upvalues.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-string.find"><code>string.find (s, pattern [, init [, plain]])</code></a></h3>
-Looks for the first match of
-<code>pattern</code> in the string <code>s</code>.
-If it finds a match, then <code>find</code> returns the indices of&nbsp;<code>s</code>
-where this occurrence starts and ends;
-otherwise, it returns <b>nil</b>.
-A third, optional numerical argument <code>init</code> specifies
-where to start the search;
-its default value is&nbsp;1 and can be negative.
-A value of <b>true</b> as a fourth, optional argument <code>plain</code>
-turns off the pattern matching facilities,
-so the function does a plain "find substring" operation,
-with no characters in <code>pattern</code> being considered "magic".
-Note that if <code>plain</code> is given, then <code>init</code> must be given as well.
-
-
-<p>
-If the pattern has captures,
-then in a successful match
-the captured values are also returned,
-after the two indices.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-string.format"><code>string.format (formatstring, &middot;&middot;&middot;)</code></a></h3>
-Returns a formatted version of its variable number of arguments
-following the description given in its first argument (which must be a string).
-The format string follows the same rules as the <code>printf</code> family of
-standard C&nbsp;functions.
-The only differences are that the options/modifiers
-<code>*</code>, <code>l</code>, <code>L</code>, <code>n</code>, <code>p</code>,
-and <code>h</code> are not supported
-and that there is an extra option, <code>q</code>.
-The <code>q</code> option formats a string in a form suitable to be safely read
-back by the Lua interpreter:
-the string is written between double quotes,
-and all double quotes, newlines, embedded zeros,
-and backslashes in the string
-are correctly escaped when written.
-For instance, the call
-
-<pre>
- string.format('%q', 'a string with "quotes" and \n new line')
-</pre><p>
-will produce the string:
-
-<pre>
- "a string with \"quotes\" and \
- new line"
-</pre>
-
-<p>
-The options <code>c</code>, <code>d</code>, <code>E</code>, <code>e</code>, <code>f</code>,
-<code>g</code>, <code>G</code>, <code>i</code>, <code>o</code>, <code>u</code>, <code>X</code>, and <code>x</code> all
-expect a number as argument,
-whereas <code>q</code> and <code>s</code> expect a string.
-
-
-<p>
-This function does not accept string values
-containing embedded zeros,
-except as arguments to the <code>q</code> option.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-string.gmatch"><code>string.gmatch (s, pattern)</code></a></h3>
-Returns an iterator function that,
-each time it is called,
-returns the next captures from <code>pattern</code> over string <code>s</code>.
-If <code>pattern</code> specifies no captures,
-then the whole match is produced in each call.
-
-
-<p>
-As an example, the following loop
-
-<pre>
- s = "hello world from Lua"
- for w in string.gmatch(s, "%a+") do
- print(w)
- end
-</pre><p>
-will iterate over all the words from string <code>s</code>,
-printing one per line.
-The next example collects all pairs <code>key=value</code> from the
-given string into a table:
-
-<pre>
- t = {}
- s = "from=world, to=Lua"
- for k, v in string.gmatch(s, "(%w+)=(%w+)") do
- t[k] = v
- end
-</pre>
-
-<p>
-For this function, a '<code>^</code>' at the start of a pattern does not
-work as an anchor, as this would prevent the iteration.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-string.gsub"><code>string.gsub (s, pattern, repl [, n])</code></a></h3>
-Returns a copy of <code>s</code>
-in which all (or the first <code>n</code>, if given)
-occurrences of the <code>pattern</code> have been
-replaced by a replacement string specified by <code>repl</code>,
-which can be a string, a table, or a function.
-<code>gsub</code> also returns, as its second value,
-the total number of matches that occurred.
-
-
-<p>
-If <code>repl</code> is a string, then its value is used for replacement.
-The character&nbsp;<code>%</code> works as an escape character:
-any sequence in <code>repl</code> of the form <code>%<em>n</em></code>,
-with <em>n</em> between 1 and 9,
-stands for the value of the <em>n</em>-th captured substring (see below).
-The sequence <code>%0</code> stands for the whole match.
-The sequence <code>%%</code> stands for a single&nbsp;<code>%</code>.
-
-
-<p>
-If <code>repl</code> is a table, then the table is queried for every match,
-using the first capture as the key;
-if the pattern specifies no captures,
-then the whole match is used as the key.
-
-
-<p>
-If <code>repl</code> is a function, then this function is called every time a
-match occurs, with all captured substrings passed as arguments,
-in order;
-if the pattern specifies no captures,
-then the whole match is passed as a sole argument.
-
-
-<p>
-If the value returned by the table query or by the function call
-is a string or a number,
-then it is used as the replacement string;
-otherwise, if it is <b>false</b> or <b>nil</b>,
-then there is no replacement
-(that is, the original match is kept in the string).
-
-
-<p>
-Here are some examples:
-
-<pre>
- x = string.gsub("hello world", "(%w+)", "%1 %1")
- --&gt; x="hello hello world world"
-
- x = string.gsub("hello world", "%w+", "%0 %0", 1)
- --&gt; x="hello hello world"
-
- x = string.gsub("hello world from Lua", "(%w+)%s*(%w+)", "%2 %1")
- --&gt; x="world hello Lua from"
-
- x = string.gsub("home = $HOME, user = $USER", "%$(%w+)", os.getenv)
- --&gt; x="home = /home/roberto, user = roberto"
-
- x = string.gsub("4+5 = $return 4+5$", "%$(.-)%$", function (s)
- return loadstring(s)()
- end)
- --&gt; x="4+5 = 9"
-
- local t = {name="lua", version="5.1"}
- x = string.gsub("$name-$version.tar.gz", "%$(%w+)", t)
- --&gt; x="lua-5.1.tar.gz"
-</pre>
-
-
-
-<p>
-<hr><h3><a name="pdf-string.len"><code>string.len (s)</code></a></h3>
-Receives a string and returns its length.
-The empty string <code>""</code> has length 0.
-Embedded zeros are counted,
-so <code>"a\000bc\000"</code> has length 5.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-string.lower"><code>string.lower (s)</code></a></h3>
-Receives a string and returns a copy of this string with all
-uppercase letters changed to lowercase.
-All other characters are left unchanged.
-The definition of what an uppercase letter is depends on the current locale.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-string.match"><code>string.match (s, pattern [, init])</code></a></h3>
-Looks for the first <em>match</em> of
-<code>pattern</code> in the string <code>s</code>.
-If it finds one, then <code>match</code> returns
-the captures from the pattern;
-otherwise it returns <b>nil</b>.
-If <code>pattern</code> specifies no captures,
-then the whole match is returned.
-A third, optional numerical argument <code>init</code> specifies
-where to start the search;
-its default value is&nbsp;1 and can be negative.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-string.rep"><code>string.rep (s, n)</code></a></h3>
-Returns a string that is the concatenation of <code>n</code> copies of
-the string <code>s</code>.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-string.reverse"><code>string.reverse (s)</code></a></h3>
-Returns a string that is the string <code>s</code> reversed.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-string.sub"><code>string.sub (s, i [, j])</code></a></h3>
-Returns the substring of <code>s</code> that
-starts at <code>i</code> and continues until <code>j</code>;
-<code>i</code> and <code>j</code> can be negative.
-If <code>j</code> is absent, then it is assumed to be equal to -1
-(which is the same as the string length).
-In particular,
-the call <code>string.sub(s,1,j)</code> returns a prefix of <code>s</code>
-with length <code>j</code>,
-and <code>string.sub(s, -i)</code> returns a suffix of <code>s</code>
-with length <code>i</code>.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-string.upper"><code>string.upper (s)</code></a></h3>
-Receives a string and returns a copy of this string with all
-lowercase letters changed to uppercase.
-All other characters are left unchanged.
-The definition of what a lowercase letter is depends on the current locale.
-
-
-
-<h3>5.4.1 - <a name="5.4.1">Patterns</a></h3>
-
-
-<h4>Character Class:</h4><p>
-A <em>character class</em> is used to represent a set of characters.
-The following combinations are allowed in describing a character class:
-
-<ul>
-
-<li><b><em>x</em>:</b>
-(where <em>x</em> is not one of the <em>magic characters</em>
-<code>^$()%.[]*+-?</code>)
-represents the character <em>x</em> itself.
-</li>
-
-<li><b><code>.</code>:</b> (a dot) represents all characters.</li>
-
-<li><b><code>%a</code>:</b> represents all letters.</li>
-
-<li><b><code>%c</code>:</b> represents all control characters.</li>
-
-<li><b><code>%d</code>:</b> represents all digits.</li>
-
-<li><b><code>%l</code>:</b> represents all lowercase letters.</li>
-
-<li><b><code>%p</code>:</b> represents all punctuation characters.</li>
-
-<li><b><code>%s</code>:</b> represents all space characters.</li>
-
-<li><b><code>%u</code>:</b> represents all uppercase letters.</li>
-
-<li><b><code>%w</code>:</b> represents all alphanumeric characters.</li>
-
-<li><b><code>%x</code>:</b> represents all hexadecimal digits.</li>
-
-<li><b><code>%z</code>:</b> represents the character with representation 0.</li>
-
-<li><b><code>%<em>x</em></code>:</b> (where <em>x</em> is any non-alphanumeric character)
-represents the character <em>x</em>.
-This is the standard way to escape the magic characters.
-Any punctuation character (even the non magic)
-can be preceded by a '<code>%</code>'
-when used to represent itself in a pattern.
-</li>
-
-<li><b><code>[<em>set</em>]</code>:</b>
-represents the class which is the union of all
-characters in <em>set</em>.
-A range of characters can be specified by
-separating the end characters of the range with a '<code>-</code>'.
-All classes <code>%</code><em>x</em> described above can also be used as
-components in <em>set</em>.
-All other characters in <em>set</em> represent themselves.
-For example, <code>[%w_]</code> (or <code>[_%w]</code>)
-represents all alphanumeric characters plus the underscore,
-<code>[0-7]</code> represents the octal digits,
-and <code>[0-7%l%-]</code> represents the octal digits plus
-the lowercase letters plus the '<code>-</code>' character.
-
-
-<p>
-The interaction between ranges and classes is not defined.
-Therefore, patterns like <code>[%a-z]</code> or <code>[a-%%]</code>
-have no meaning.
-</li>
-
-<li><b><code>[^<em>set</em>]</code>:</b>
-represents the complement of <em>set</em>,
-where <em>set</em> is interpreted as above.
-</li>
-
-</ul><p>
-For all classes represented by single letters (<code>%a</code>, <code>%c</code>, etc.),
-the corresponding uppercase letter represents the complement of the class.
-For instance, <code>%S</code> represents all non-space characters.
-
-
-<p>
-The definitions of letter, space, and other character groups
-depend on the current locale.
-In particular, the class <code>[a-z]</code> may not be equivalent to <code>%l</code>.
-
-
-
-
-
-<h4>Pattern Item:</h4><p>
-A <em>pattern item</em> can be
-
-<ul>
-
-<li>
-a single character class,
-which matches any single character in the class;
-</li>
-
-<li>
-a single character class followed by '<code>*</code>',
-which matches 0 or more repetitions of characters in the class.
-These repetition items will always match the longest possible sequence;
-</li>
-
-<li>
-a single character class followed by '<code>+</code>',
-which matches 1 or more repetitions of characters in the class.
-These repetition items will always match the longest possible sequence;
-</li>
-
-<li>
-a single character class followed by '<code>-</code>',
-which also matches 0 or more repetitions of characters in the class.
-Unlike '<code>*</code>',
-these repetition items will always match the <em>shortest</em> possible sequence;
-</li>
-
-<li>
-a single character class followed by '<code>?</code>',
-which matches 0 or 1 occurrence of a character in the class;
-</li>
-
-<li>
-<code>%<em>n</em></code>, for <em>n</em> between 1 and 9;
-such item matches a substring equal to the <em>n</em>-th captured string
-(see below);
-</li>
-
-<li>
-<code>%b<em>xy</em></code>, where <em>x</em> and <em>y</em> are two distinct characters;
-such item matches strings that start with&nbsp;<em>x</em>, end with&nbsp;<em>y</em>,
-and where the <em>x</em> and <em>y</em> are <em>balanced</em>.
-This means that, if one reads the string from left to right,
-counting <em>+1</em> for an <em>x</em> and <em>-1</em> for a <em>y</em>,
-the ending <em>y</em> is the first <em>y</em> where the count reaches 0.
-For instance, the item <code>%b()</code> matches expressions with
-balanced parentheses.
-</li>
-
-</ul>
-
-
-
-
-<h4>Pattern:</h4><p>
-A <em>pattern</em> is a sequence of pattern items.
-A '<code>^</code>' at the beginning of a pattern anchors the match at the
-beginning of the subject string.
-A '<code>$</code>' at the end of a pattern anchors the match at the
-end of the subject string.
-At other positions,
-'<code>^</code>' and '<code>$</code>' have no special meaning and represent themselves.
-
-
-
-
-
-<h4>Captures:</h4><p>
-A pattern can contain sub-patterns enclosed in parentheses;
-they describe <em>captures</em>.
-When a match succeeds, the substrings of the subject string
-that match captures are stored (<em>captured</em>) for future use.
-Captures are numbered according to their left parentheses.
-For instance, in the pattern <code>"(a*(.)%w(%s*))"</code>,
-the part of the string matching <code>"a*(.)%w(%s*)"</code> is
-stored as the first capture (and therefore has number&nbsp;1);
-the character matching "<code>.</code>" is captured with number&nbsp;2,
-and the part matching "<code>%s*</code>" has number&nbsp;3.
-
-
-<p>
-As a special case, the empty capture <code>()</code> captures
-the current string position (a number).
-For instance, if we apply the pattern <code>"()aa()"</code> on the
-string <code>"flaaap"</code>, there will be two captures: 3&nbsp;and&nbsp;5.
-
-
-<p>
-A pattern cannot contain embedded zeros. Use <code>%z</code> instead.
-
-
-
-
-
-
-
-
-
-
-
-<h2>5.5 - <a name="5.5">Table Manipulation</a></h2><p>
-This library provides generic functions for table manipulation.
-It provides all its functions inside the table <a name="pdf-table"><code>table</code></a>.
-
-
-<p>
-Most functions in the table library assume that the table
-represents an array or a list.
-For these functions, when we talk about the "length" of a table
-we mean the result of the length operator.
-
-
-<p>
-<hr><h3><a name="pdf-table.concat"><code>table.concat (table [, sep [, i [, j]]])</code></a></h3>
-Given an array where all elements are strings or numbers,
-returns <code>table[i]..sep..table[i+1] &middot;&middot;&middot; sep..table[j]</code>.
-The default value for <code>sep</code> is the empty string,
-the default for <code>i</code> is 1,
-and the default for <code>j</code> is the length of the table.
-If <code>i</code> is greater than <code>j</code>, returns the empty string.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-table.insert"><code>table.insert (table, [pos,] value)</code></a></h3>
-
-
-<p>
-Inserts element <code>value</code> at position <code>pos</code> in <code>table</code>,
-shifting up other elements to open space, if necessary.
-The default value for <code>pos</code> is <code>n+1</code>,
-where <code>n</code> is the length of the table (see <a href="#2.5.5">&sect;2.5.5</a>),
-so that a call <code>table.insert(t,x)</code> inserts <code>x</code> at the end
-of table <code>t</code>.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-table.maxn"><code>table.maxn (table)</code></a></h3>
-
-
-<p>
-Returns the largest positive numerical index of the given table,
-or zero if the table has no positive numerical indices.
-(To do its job this function does a linear traversal of
-the whole table.)
-
-
-
-
-<p>
-<hr><h3><a name="pdf-table.remove"><code>table.remove (table [, pos])</code></a></h3>
-
-
-<p>
-Removes from <code>table</code> the element at position <code>pos</code>,
-shifting down other elements to close the space, if necessary.
-Returns the value of the removed element.
-The default value for <code>pos</code> is <code>n</code>,
-where <code>n</code> is the length of the table,
-so that a call <code>table.remove(t)</code> removes the last element
-of table <code>t</code>.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-table.sort"><code>table.sort (table [, comp])</code></a></h3>
-Sorts table elements in a given order, <em>in-place</em>,
-from <code>table[1]</code> to <code>table[n]</code>,
-where <code>n</code> is the length of the table.
-If <code>comp</code> is given,
-then it must be a function that receives two table elements,
-and returns true
-when the first is less than the second
-(so that <code>not comp(a[i+1],a[i])</code> will be true after the sort).
-If <code>comp</code> is not given,
-then the standard Lua operator <code>&lt;</code> is used instead.
-
-
-<p>
-The sort algorithm is not stable;
-that is, elements considered equal by the given order
-may have their relative positions changed by the sort.
-
-
-
-
-
-
-
-<h2>5.6 - <a name="5.6">Mathematical Functions</a></h2>
-
-<p>
-This library is an interface to the standard C&nbsp;math library.
-It provides all its functions inside the table <a name="pdf-math"><code>math</code></a>.
-
-
-<p>
-<hr><h3><a name="pdf-math.abs"><code>math.abs (x)</code></a></h3>
-
-
-<p>
-Returns the absolute value of <code>x</code>.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-math.acos"><code>math.acos (x)</code></a></h3>
-
-
-<p>
-Returns the arc cosine of <code>x</code> (in radians).
-
-
-
-
-<p>
-<hr><h3><a name="pdf-math.asin"><code>math.asin (x)</code></a></h3>
-
-
-<p>
-Returns the arc sine of <code>x</code> (in radians).
-
-
-
-
-<p>
-<hr><h3><a name="pdf-math.atan"><code>math.atan (x)</code></a></h3>
-
-
-<p>
-Returns the arc tangent of <code>x</code> (in radians).
-
-
-
-
-<p>
-<hr><h3><a name="pdf-math.atan2"><code>math.atan2 (y, x)</code></a></h3>
-
-
-<p>
-Returns the arc tangent of <code>y/x</code> (in radians),
-but uses the signs of both parameters to find the
-quadrant of the result.
-(It also handles correctly the case of <code>x</code> being zero.)
-
-
-
-
-<p>
-<hr><h3><a name="pdf-math.ceil"><code>math.ceil (x)</code></a></h3>
-
-
-<p>
-Returns the smallest integer larger than or equal to <code>x</code>.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-math.cos"><code>math.cos (x)</code></a></h3>
-
-
-<p>
-Returns the cosine of <code>x</code> (assumed to be in radians).
-
-
-
-
-<p>
-<hr><h3><a name="pdf-math.cosh"><code>math.cosh (x)</code></a></h3>
-
-
-<p>
-Returns the hyperbolic cosine of <code>x</code>.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-math.deg"><code>math.deg (x)</code></a></h3>
-
-
-<p>
-Returns the angle <code>x</code> (given in radians) in degrees.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-math.exp"><code>math.exp (x)</code></a></h3>
-
-
-<p>
-Returns the value <em>e<sup>x</sup></em>.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-math.floor"><code>math.floor (x)</code></a></h3>
-
-
-<p>
-Returns the largest integer smaller than or equal to <code>x</code>.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-math.fmod"><code>math.fmod (x, y)</code></a></h3>
-
-
-<p>
-Returns the remainder of the division of <code>x</code> by <code>y</code>
-that rounds the quotient towards zero.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-math.frexp"><code>math.frexp (x)</code></a></h3>
-
-
-<p>
-Returns <code>m</code> and <code>e</code> such that <em>x = m2<sup>e</sup></em>,
-<code>e</code> is an integer and the absolute value of <code>m</code> is
-in the range <em>[0.5, 1)</em>
-(or zero when <code>x</code> is zero).
-
-
-
-
-<p>
-<hr><h3><a name="pdf-math.huge"><code>math.huge</code></a></h3>
-
-
-<p>
-The value <code>HUGE_VAL</code>,
-a value larger than or equal to any other numerical value.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-math.ldexp"><code>math.ldexp (m, e)</code></a></h3>
-
-
-<p>
-Returns <em>m2<sup>e</sup></em> (<code>e</code> should be an integer).
-
-
-
-
-<p>
-<hr><h3><a name="pdf-math.log"><code>math.log (x)</code></a></h3>
-
-
-<p>
-Returns the natural logarithm of <code>x</code>.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-math.log10"><code>math.log10 (x)</code></a></h3>
-
-
-<p>
-Returns the base-10 logarithm of <code>x</code>.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-math.max"><code>math.max (x, &middot;&middot;&middot;)</code></a></h3>
-
-
-<p>
-Returns the maximum value among its arguments.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-math.min"><code>math.min (x, &middot;&middot;&middot;)</code></a></h3>
-
-
-<p>
-Returns the minimum value among its arguments.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-math.modf"><code>math.modf (x)</code></a></h3>
-
-
-<p>
-Returns two numbers,
-the integral part of <code>x</code> and the fractional part of <code>x</code>.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-math.pi"><code>math.pi</code></a></h3>
-
-
-<p>
-The value of <em>pi</em>.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-math.pow"><code>math.pow (x, y)</code></a></h3>
-
-
-<p>
-Returns <em>x<sup>y</sup></em>.
-(You can also use the expression <code>x^y</code> to compute this value.)
-
-
-
-
-<p>
-<hr><h3><a name="pdf-math.rad"><code>math.rad (x)</code></a></h3>
-
-
-<p>
-Returns the angle <code>x</code> (given in degrees) in radians.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-math.random"><code>math.random ([m [, n]])</code></a></h3>
-
-
-<p>
-This function is an interface to the simple
-pseudo-random generator function <code>rand</code> provided by ANSI&nbsp;C.
-(No guarantees can be given for its statistical properties.)
-
-
-<p>
-When called without arguments,
-returns a uniform pseudo-random real number
-in the range <em>[0,1)</em>.
-When called with an integer number <code>m</code>,
-<code>math.random</code> returns
-a uniform pseudo-random integer in the range <em>[1, m]</em>.
-When called with two integer numbers <code>m</code> and <code>n</code>,
-<code>math.random</code> returns a uniform pseudo-random
-integer in the range <em>[m, n]</em>.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-math.randomseed"><code>math.randomseed (x)</code></a></h3>
-
-
-<p>
-Sets <code>x</code> as the "seed"
-for the pseudo-random generator:
-equal seeds produce equal sequences of numbers.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-math.sin"><code>math.sin (x)</code></a></h3>
-
-
-<p>
-Returns the sine of <code>x</code> (assumed to be in radians).
-
-
-
-
-<p>
-<hr><h3><a name="pdf-math.sinh"><code>math.sinh (x)</code></a></h3>
-
-
-<p>
-Returns the hyperbolic sine of <code>x</code>.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-math.sqrt"><code>math.sqrt (x)</code></a></h3>
-
-
-<p>
-Returns the square root of <code>x</code>.
-(You can also use the expression <code>x^0.5</code> to compute this value.)
-
-
-
-
-<p>
-<hr><h3><a name="pdf-math.tan"><code>math.tan (x)</code></a></h3>
-
-
-<p>
-Returns the tangent of <code>x</code> (assumed to be in radians).
-
-
-
-
-<p>
-<hr><h3><a name="pdf-math.tanh"><code>math.tanh (x)</code></a></h3>
-
-
-<p>
-Returns the hyperbolic tangent of <code>x</code>.
-
-
-
-
-
-
-
-<h2>5.7 - <a name="5.7">Input and Output Facilities</a></h2>
-
-<p>
-The I/O library provides two different styles for file manipulation.
-The first one uses implicit file descriptors;
-that is, there are operations to set a default input file and a
-default output file,
-and all input/output operations are over these default files.
-The second style uses explicit file descriptors.
-
-
-<p>
-When using implicit file descriptors,
-all operations are supplied by table <a name="pdf-io"><code>io</code></a>.
-When using explicit file descriptors,
-the operation <a href="#pdf-io.open"><code>io.open</code></a> returns a file descriptor
-and then all operations are supplied as methods of the file descriptor.
-
-
-<p>
-The table <code>io</code> also provides
-three predefined file descriptors with their usual meanings from C:
-<a name="pdf-io.stdin"><code>io.stdin</code></a>, <a name="pdf-io.stdout"><code>io.stdout</code></a>, and <a name="pdf-io.stderr"><code>io.stderr</code></a>.
-The I/O library never closes these files.
-
-
-<p>
-Unless otherwise stated,
-all I/O functions return <b>nil</b> on failure
-(plus an error message as a second result and
-a system-dependent error code as a third result)
-and some value different from <b>nil</b> on success.
-
-
-<p>
-<hr><h3><a name="pdf-io.close"><code>io.close ([file])</code></a></h3>
-
-
-<p>
-Equivalent to <code>file:close()</code>.
-Without a <code>file</code>, closes the default output file.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-io.flush"><code>io.flush ()</code></a></h3>
-
-
-<p>
-Equivalent to <code>file:flush</code> over the default output file.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-io.input"><code>io.input ([file])</code></a></h3>
-
-
-<p>
-When called with a file name, it opens the named file (in text mode),
-and sets its handle as the default input file.
-When called with a file handle,
-it simply sets this file handle as the default input file.
-When called without parameters,
-it returns the current default input file.
-
-
-<p>
-In case of errors this function raises the error,
-instead of returning an error code.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-io.lines"><code>io.lines ([filename])</code></a></h3>
-
-
-<p>
-Opens the given file name in read mode
-and returns an iterator function that,
-each time it is called,
-returns a new line from the file.
-Therefore, the construction
-
-<pre>
- for line in io.lines(filename) do <em>body</em> end
-</pre><p>
-will iterate over all lines of the file.
-When the iterator function detects the end of file,
-it returns <b>nil</b> (to finish the loop) and automatically closes the file.
-
-
-<p>
-The call <code>io.lines()</code> (with no file name) is equivalent
-to <code>io.input():lines()</code>;
-that is, it iterates over the lines of the default input file.
-In this case it does not close the file when the loop ends.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-io.open"><code>io.open (filename [, mode])</code></a></h3>
-
-
-<p>
-This function opens a file,
-in the mode specified in the string <code>mode</code>.
-It returns a new file handle,
-or, in case of errors, <b>nil</b> plus an error message.
-
-
-<p>
-The <code>mode</code> string can be any of the following:
-
-<ul>
-<li><b>"r":</b> read mode (the default);</li>
-<li><b>"w":</b> write mode;</li>
-<li><b>"a":</b> append mode;</li>
-<li><b>"r+":</b> update mode, all previous data is preserved;</li>
-<li><b>"w+":</b> update mode, all previous data is erased;</li>
-<li><b>"a+":</b> append update mode, previous data is preserved,
- writing is only allowed at the end of file.</li>
-</ul><p>
-The <code>mode</code> string can also have a '<code>b</code>' at the end,
-which is needed in some systems to open the file in binary mode.
-This string is exactly what is used in the
-standard&nbsp;C function <code>fopen</code>.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-io.output"><code>io.output ([file])</code></a></h3>
-
-
-<p>
-Similar to <a href="#pdf-io.input"><code>io.input</code></a>, but operates over the default output file.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-io.popen"><code>io.popen (prog [, mode])</code></a></h3>
-
-
-<p>
-Starts program <code>prog</code> in a separated process and returns
-a file handle that you can use to read data from this program
-(if <code>mode</code> is <code>"r"</code>, the default)
-or to write data to this program
-(if <code>mode</code> is <code>"w"</code>).
-
-
-<p>
-This function is system dependent and is not available
-on all platforms.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-io.read"><code>io.read (&middot;&middot;&middot;)</code></a></h3>
-
-
-<p>
-Equivalent to <code>io.input():read</code>.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-io.tmpfile"><code>io.tmpfile ()</code></a></h3>
-
-
-<p>
-Returns a handle for a temporary file.
-This file is opened in update mode
-and it is automatically removed when the program ends.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-io.type"><code>io.type (obj)</code></a></h3>
-
-
-<p>
-Checks whether <code>obj</code> is a valid file handle.
-Returns the string <code>"file"</code> if <code>obj</code> is an open file handle,
-<code>"closed file"</code> if <code>obj</code> is a closed file handle,
-or <b>nil</b> if <code>obj</code> is not a file handle.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-io.write"><code>io.write (&middot;&middot;&middot;)</code></a></h3>
-
-
-<p>
-Equivalent to <code>io.output():write</code>.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-file:close"><code>file:close ()</code></a></h3>
-
-
-<p>
-Closes <code>file</code>.
-Note that files are automatically closed when
-their handles are garbage collected,
-but that takes an unpredictable amount of time to happen.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-file:flush"><code>file:flush ()</code></a></h3>
-
-
-<p>
-Saves any written data to <code>file</code>.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-file:lines"><code>file:lines ()</code></a></h3>
-
-
-<p>
-Returns an iterator function that,
-each time it is called,
-returns a new line from the file.
-Therefore, the construction
-
-<pre>
- for line in file:lines() do <em>body</em> end
-</pre><p>
-will iterate over all lines of the file.
-(Unlike <a href="#pdf-io.lines"><code>io.lines</code></a>, this function does not close the file
-when the loop ends.)
-
-
-
-
-<p>
-<hr><h3><a name="pdf-file:read"><code>file:read (&middot;&middot;&middot;)</code></a></h3>
-
-
-<p>
-Reads the file <code>file</code>,
-according to the given formats, which specify what to read.
-For each format,
-the function returns a string (or a number) with the characters read,
-or <b>nil</b> if it cannot read data with the specified format.
-When called without formats,
-it uses a default format that reads the entire next line
-(see below).
-
-
-<p>
-The available formats are
-
-<ul>
-
-<li><b>"*n":</b>
-reads a number;
-this is the only format that returns a number instead of a string.
-</li>
-
-<li><b>"*a":</b>
-reads the whole file, starting at the current position.
-On end of file, it returns the empty string.
-</li>
-
-<li><b>"*l":</b>
-reads the next line (skipping the end of line),
-returning <b>nil</b> on end of file.
-This is the default format.
-</li>
-
-<li><b><em>number</em>:</b>
-reads a string with up to this number of characters,
-returning <b>nil</b> on end of file.
-If number is zero,
-it reads nothing and returns an empty string,
-or <b>nil</b> on end of file.
-</li>
-
-</ul>
-
-
-
-<p>
-<hr><h3><a name="pdf-file:seek"><code>file:seek ([whence] [, offset])</code></a></h3>
-
-
-<p>
-Sets and gets the file position,
-measured from the beginning of the file,
-to the position given by <code>offset</code> plus a base
-specified by the string <code>whence</code>, as follows:
-
-<ul>
-<li><b>"set":</b> base is position 0 (beginning of the file);</li>
-<li><b>"cur":</b> base is current position;</li>
-<li><b>"end":</b> base is end of file;</li>
-</ul><p>
-In case of success, function <code>seek</code> returns the final file position,
-measured in bytes from the beginning of the file.
-If this function fails, it returns <b>nil</b>,
-plus a string describing the error.
-
-
-<p>
-The default value for <code>whence</code> is <code>"cur"</code>,
-and for <code>offset</code> is 0.
-Therefore, the call <code>file:seek()</code> returns the current
-file position, without changing it;
-the call <code>file:seek("set")</code> sets the position to the
-beginning of the file (and returns 0);
-and the call <code>file:seek("end")</code> sets the position to the
-end of the file, and returns its size.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-file:setvbuf"><code>file:setvbuf (mode [, size])</code></a></h3>
-
-
-<p>
-Sets the buffering mode for an output file.
-There are three available modes:
-
-<ul>
-
-<li><b>"no":</b>
-no buffering; the result of any output operation appears immediately.
-</li>
-
-<li><b>"full":</b>
-full buffering; output operation is performed only
-when the buffer is full (or when you explicitly <code>flush</code> the file
-(see <a href="#pdf-io.flush"><code>io.flush</code></a>)).
-</li>
-
-<li><b>"line":</b>
-line buffering; output is buffered until a newline is output
-or there is any input from some special files
-(such as a terminal device).
-</li>
-
-</ul><p>
-For the last two cases, <code>size</code>
-specifies the size of the buffer, in bytes.
-The default is an appropriate size.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-file:write"><code>file:write (&middot;&middot;&middot;)</code></a></h3>
-
-
-<p>
-Writes the value of each of its arguments to
-the <code>file</code>.
-The arguments must be strings or numbers.
-To write other values,
-use <a href="#pdf-tostring"><code>tostring</code></a> or <a href="#pdf-string.format"><code>string.format</code></a> before <code>write</code>.
-
-
-
-
-
-
-
-<h2>5.8 - <a name="5.8">Operating System Facilities</a></h2>
-
-<p>
-This library is implemented through table <a name="pdf-os"><code>os</code></a>.
-
-
-<p>
-<hr><h3><a name="pdf-os.clock"><code>os.clock ()</code></a></h3>
-
-
-<p>
-Returns an approximation of the amount in seconds of CPU time
-used by the program.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-os.date"><code>os.date ([format [, time]])</code></a></h3>
-
-
-<p>
-Returns a string or a table containing date and time,
-formatted according to the given string <code>format</code>.
-
-
-<p>
-If the <code>time</code> argument is present,
-this is the time to be formatted
-(see the <a href="#pdf-os.time"><code>os.time</code></a> function for a description of this value).
-Otherwise, <code>date</code> formats the current time.
-
-
-<p>
-If <code>format</code> starts with '<code>!</code>',
-then the date is formatted in Coordinated Universal Time.
-After this optional character,
-if <code>format</code> is the string "<code>*t</code>",
-then <code>date</code> returns a table with the following fields:
-<code>year</code> (four digits), <code>month</code> (1--12), <code>day</code> (1--31),
-<code>hour</code> (0--23), <code>min</code> (0--59), <code>sec</code> (0--61),
-<code>wday</code> (weekday, Sunday is&nbsp;1),
-<code>yday</code> (day of the year),
-and <code>isdst</code> (daylight saving flag, a boolean).
-
-
-<p>
-If <code>format</code> is not "<code>*t</code>",
-then <code>date</code> returns the date as a string,
-formatted according to the same rules as the C&nbsp;function <code>strftime</code>.
-
-
-<p>
-When called without arguments,
-<code>date</code> returns a reasonable date and time representation that depends on
-the host system and on the current locale
-(that is, <code>os.date()</code> is equivalent to <code>os.date("%c")</code>).
-
-
-
-
-<p>
-<hr><h3><a name="pdf-os.difftime"><code>os.difftime (t2, t1)</code></a></h3>
-
-
-<p>
-Returns the number of seconds from time <code>t1</code> to time <code>t2</code>.
-In POSIX, Windows, and some other systems,
-this value is exactly <code>t2</code><em>-</em><code>t1</code>.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-os.execute"><code>os.execute ([command])</code></a></h3>
-
-
-<p>
-This function is equivalent to the C&nbsp;function <code>system</code>.
-It passes <code>command</code> to be executed by an operating system shell.
-It returns a status code, which is system-dependent.
-If <code>command</code> is absent, then it returns nonzero if a shell is available
-and zero otherwise.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-os.exit"><code>os.exit ([code])</code></a></h3>
-
-
-<p>
-Calls the C&nbsp;function <code>exit</code>,
-with an optional <code>code</code>,
-to terminate the host program.
-The default value for <code>code</code> is the success code.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-os.getenv"><code>os.getenv (varname)</code></a></h3>
-
-
-<p>
-Returns the value of the process environment variable <code>varname</code>,
-or <b>nil</b> if the variable is not defined.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-os.remove"><code>os.remove (filename)</code></a></h3>
-
-
-<p>
-Deletes the file or directory with the given name.
-Directories must be empty to be removed.
-If this function fails, it returns <b>nil</b>,
-plus a string describing the error.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-os.rename"><code>os.rename (oldname, newname)</code></a></h3>
-
-
-<p>
-Renames file or directory named <code>oldname</code> to <code>newname</code>.
-If this function fails, it returns <b>nil</b>,
-plus a string describing the error.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-os.setlocale"><code>os.setlocale (locale [, category])</code></a></h3>
-
-
-<p>
-Sets the current locale of the program.
-<code>locale</code> is a string specifying a locale;
-<code>category</code> is an optional string describing which category to change:
-<code>"all"</code>, <code>"collate"</code>, <code>"ctype"</code>,
-<code>"monetary"</code>, <code>"numeric"</code>, or <code>"time"</code>;
-the default category is <code>"all"</code>.
-The function returns the name of the new locale,
-or <b>nil</b> if the request cannot be honored.
-
-
-<p>
-If <code>locale</code> is the empty string,
-the current locale is set to an implementation-defined native locale.
-If <code>locale</code> is the string "<code>C</code>",
-the current locale is set to the standard C locale.
-
-
-<p>
-When called with <b>nil</b> as the first argument,
-this function only returns the name of the current locale
-for the given category.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-os.time"><code>os.time ([table])</code></a></h3>
-
-
-<p>
-Returns the current time when called without arguments,
-or a time representing the date and time specified by the given table.
-This table must have fields <code>year</code>, <code>month</code>, and <code>day</code>,
-and may have fields <code>hour</code>, <code>min</code>, <code>sec</code>, and <code>isdst</code>
-(for a description of these fields, see the <a href="#pdf-os.date"><code>os.date</code></a> function).
-
-
-<p>
-The returned value is a number, whose meaning depends on your system.
-In POSIX, Windows, and some other systems, this number counts the number
-of seconds since some given start time (the "epoch").
-In other systems, the meaning is not specified,
-and the number returned by <code>time</code> can be used only as an argument to
-<code>date</code> and <code>difftime</code>.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-os.tmpname"><code>os.tmpname ()</code></a></h3>
-
-
-<p>
-Returns a string with a file name that can
-be used for a temporary file.
-The file must be explicitly opened before its use
-and explicitly removed when no longer needed.
-
-
-<p>
-On some systems (POSIX),
-this function also creates a file with that name,
-to avoid security risks.
-(Someone else might create the file with wrong permissions
-in the time between getting the name and creating the file.)
-You still have to open the file to use it
-and to remove it (even if you do not use it).
-
-
-<p>
-When possible,
-you may prefer to use <a href="#pdf-io.tmpfile"><code>io.tmpfile</code></a>,
-which automatically removes the file when the program ends.
-
-
-
-
-
-
-
-<h2>5.9 - <a name="5.9">The Debug Library</a></h2>
-
-<p>
-This library provides
-the functionality of the debug interface to Lua programs.
-You should exert care when using this library.
-The functions provided here should be used exclusively for debugging
-and similar tasks, such as profiling.
-Please resist the temptation to use them as a
-usual programming tool:
-they can be very slow.
-Moreover, several of these functions
-violate some assumptions about Lua code
-(e.g., that variables local to a function
-cannot be accessed from outside or
-that userdata metatables cannot be changed by Lua code)
-and therefore can compromise otherwise secure code.
-
-
-<p>
-All functions in this library are provided
-inside the <a name="pdf-debug"><code>debug</code></a> table.
-All functions that operate over a thread
-have an optional first argument which is the
-thread to operate over.
-The default is always the current thread.
-
-
-<p>
-<hr><h3><a name="pdf-debug.debug"><code>debug.debug ()</code></a></h3>
-
-
-<p>
-Enters an interactive mode with the user,
-running each string that the user enters.
-Using simple commands and other debug facilities,
-the user can inspect global and local variables,
-change their values, evaluate expressions, and so on.
-A line containing only the word <code>cont</code> finishes this function,
-so that the caller continues its execution.
-
-
-<p>
-Note that commands for <code>debug.debug</code> are not lexically nested
-within any function, and so have no direct access to local variables.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-debug.getfenv"><code>debug.getfenv (o)</code></a></h3>
-Returns the environment of object <code>o</code>.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-debug.gethook"><code>debug.gethook ([thread])</code></a></h3>
-
-
-<p>
-Returns the current hook settings of the thread, as three values:
-the current hook function, the current hook mask,
-and the current hook count
-(as set by the <a href="#pdf-debug.sethook"><code>debug.sethook</code></a> function).
-
-
-
-
-<p>
-<hr><h3><a name="pdf-debug.getinfo"><code>debug.getinfo ([thread,] function [, what])</code></a></h3>
-
-
-<p>
-Returns a table with information about a function.
-You can give the function directly,
-or you can give a number as the value of <code>function</code>,
-which means the function running at level <code>function</code> of the call stack
-of the given thread:
-level&nbsp;0 is the current function (<code>getinfo</code> itself);
-level&nbsp;1 is the function that called <code>getinfo</code>;
-and so on.
-If <code>function</code> is a number larger than the number of active functions,
-then <code>getinfo</code> returns <b>nil</b>.
-
-
-<p>
-The returned table can contain all the fields returned by <a href="#lua_getinfo"><code>lua_getinfo</code></a>,
-with the string <code>what</code> describing which fields to fill in.
-The default for <code>what</code> is to get all information available,
-except the table of valid lines.
-If present,
-the option '<code>f</code>'
-adds a field named <code>func</code> with the function itself.
-If present,
-the option '<code>L</code>'
-adds a field named <code>activelines</code> with the table of
-valid lines.
-
-
-<p>
-For instance, the expression <code>debug.getinfo(1,"n").name</code> returns
-a table with a name for the current function,
-if a reasonable name can be found,
-and the expression <code>debug.getinfo(print)</code>
-returns a table with all available information
-about the <a href="#pdf-print"><code>print</code></a> function.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-debug.getlocal"><code>debug.getlocal ([thread,] level, local)</code></a></h3>
-
-
-<p>
-This function returns the name and the value of the local variable
-with index <code>local</code> of the function at level <code>level</code> of the stack.
-(The first parameter or local variable has index&nbsp;1, and so on,
-until the last active local variable.)
-The function returns <b>nil</b> if there is no local
-variable with the given index,
-and raises an error when called with a <code>level</code> out of range.
-(You can call <a href="#pdf-debug.getinfo"><code>debug.getinfo</code></a> to check whether the level is valid.)
-
-
-<p>
-Variable names starting with '<code>(</code>' (open parentheses)
-represent internal variables
-(loop control variables, temporaries, and C&nbsp;function locals).
-
-
-
-
-<p>
-<hr><h3><a name="pdf-debug.getmetatable"><code>debug.getmetatable (object)</code></a></h3>
-
-
-<p>
-Returns the metatable of the given <code>object</code>
-or <b>nil</b> if it does not have a metatable.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-debug.getregistry"><code>debug.getregistry ()</code></a></h3>
-
-
-<p>
-Returns the registry table (see <a href="#3.5">&sect;3.5</a>).
-
-
-
-
-<p>
-<hr><h3><a name="pdf-debug.getupvalue"><code>debug.getupvalue (func, up)</code></a></h3>
-
-
-<p>
-This function returns the name and the value of the upvalue
-with index <code>up</code> of the function <code>func</code>.
-The function returns <b>nil</b> if there is no upvalue with the given index.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-debug.setfenv"><code>debug.setfenv (object, table)</code></a></h3>
-
-
-<p>
-Sets the environment of the given <code>object</code> to the given <code>table</code>.
-Returns <code>object</code>.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-debug.sethook"><code>debug.sethook ([thread,] hook, mask [, count])</code></a></h3>
-
-
-<p>
-Sets the given function as a hook.
-The string <code>mask</code> and the number <code>count</code> describe
-when the hook will be called.
-The string mask may have the following characters,
-with the given meaning:
-
-<ul>
-<li><b><code>"c"</code>:</b> the hook is called every time Lua calls a function;</li>
-<li><b><code>"r"</code>:</b> the hook is called every time Lua returns from a function;</li>
-<li><b><code>"l"</code>:</b> the hook is called every time Lua enters a new line of code.</li>
-</ul><p>
-With a <code>count</code> different from zero,
-the hook is called after every <code>count</code> instructions.
-
-
-<p>
-When called without arguments,
-<a href="#pdf-debug.sethook"><code>debug.sethook</code></a> turns off the hook.
-
-
-<p>
-When the hook is called, its first parameter is a string
-describing the event that has triggered its call:
-<code>"call"</code>, <code>"return"</code> (or <code>"tail return"</code>,
-when simulating a return from a tail call),
-<code>"line"</code>, and <code>"count"</code>.
-For line events,
-the hook also gets the new line number as its second parameter.
-Inside a hook,
-you can call <code>getinfo</code> with level&nbsp;2 to get more information about
-the running function
-(level&nbsp;0 is the <code>getinfo</code> function,
-and level&nbsp;1 is the hook function),
-unless the event is <code>"tail return"</code>.
-In this case, Lua is only simulating the return,
-and a call to <code>getinfo</code> will return invalid data.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-debug.setlocal"><code>debug.setlocal ([thread,] level, local, value)</code></a></h3>
-
-
-<p>
-This function assigns the value <code>value</code> to the local variable
-with index <code>local</code> of the function at level <code>level</code> of the stack.
-The function returns <b>nil</b> if there is no local
-variable with the given index,
-and raises an error when called with a <code>level</code> out of range.
-(You can call <code>getinfo</code> to check whether the level is valid.)
-Otherwise, it returns the name of the local variable.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-debug.setmetatable"><code>debug.setmetatable (object, table)</code></a></h3>
-
-
-<p>
-Sets the metatable for the given <code>object</code> to the given <code>table</code>
-(which can be <b>nil</b>).
-
-
-
-
-<p>
-<hr><h3><a name="pdf-debug.setupvalue"><code>debug.setupvalue (func, up, value)</code></a></h3>
-
-
-<p>
-This function assigns the value <code>value</code> to the upvalue
-with index <code>up</code> of the function <code>func</code>.
-The function returns <b>nil</b> if there is no upvalue
-with the given index.
-Otherwise, it returns the name of the upvalue.
-
-
-
-
-<p>
-<hr><h3><a name="pdf-debug.traceback"><code>debug.traceback ([thread,] [message] [, level])</code></a></h3>
-
-
-<p>
-Returns a string with a traceback of the call stack.
-An optional <code>message</code> string is appended
-at the beginning of the traceback.
-An optional <code>level</code> number tells at which level
-to start the traceback
-(default is 1, the function calling <code>traceback</code>).
-
-
-
-
-
-
-
-<h1>6 - <a name="6">Lua Stand-alone</a></h1>
-
-<p>
-Although Lua has been designed as an extension language,
-to be embedded in a host C&nbsp;program,
-it is also frequently used as a stand-alone language.
-An interpreter for Lua as a stand-alone language,
-called simply <code>lua</code>,
-is provided with the standard distribution.
-The stand-alone interpreter includes
-all standard libraries, including the debug library.
-Its usage is:
-
-<pre>
- lua [options] [script [args]]
-</pre><p>
-The options are:
-
-<ul>
-<li><b><code>-e <em>stat</em></code>:</b> executes string <em>stat</em>;</li>
-<li><b><code>-l <em>mod</em></code>:</b> "requires" <em>mod</em>;</li>
-<li><b><code>-i</code>:</b> enters interactive mode after running <em>script</em>;</li>
-<li><b><code>-v</code>:</b> prints version information;</li>
-<li><b><code>--</code>:</b> stops handling options;</li>
-<li><b><code>-</code>:</b> executes <code>stdin</code> as a file and stops handling options.</li>
-</ul><p>
-After handling its options, <code>lua</code> runs the given <em>script</em>,
-passing to it the given <em>args</em> as string arguments.
-When called without arguments,
-<code>lua</code> behaves as <code>lua -v -i</code>
-when the standard input (<code>stdin</code>) is a terminal,
-and as <code>lua -</code> otherwise.
-
-
-<p>
-Before running any argument,
-the interpreter checks for an environment variable <a name="pdf-LUA_INIT"><code>LUA_INIT</code></a>.
-If its format is <code>@<em>filename</em></code>,
-then <code>lua</code> executes the file.
-Otherwise, <code>lua</code> executes the string itself.
-
-
-<p>
-All options are handled in order, except <code>-i</code>.
-For instance, an invocation like
-
-<pre>
- $ lua -e'a=1' -e 'print(a)' script.lua
-</pre><p>
-will first set <code>a</code> to 1, then print the value of <code>a</code> (which is '<code>1</code>'),
-and finally run the file <code>script.lua</code> with no arguments.
-(Here <code>$</code> is the shell prompt. Your prompt may be different.)
-
-
-<p>
-Before starting to run the script,
-<code>lua</code> collects all arguments in the command line
-in a global table called <code>arg</code>.
-The script name is stored at index 0,
-the first argument after the script name goes to index 1,
-and so on.
-Any arguments before the script name
-(that is, the interpreter name plus the options)
-go to negative indices.
-For instance, in the call
-
-<pre>
- $ lua -la b.lua t1 t2
-</pre><p>
-the interpreter first runs the file <code>a.lua</code>,
-then creates a table
-
-<pre>
- arg = { [-2] = "lua", [-1] = "-la",
- [0] = "b.lua",
- [1] = "t1", [2] = "t2" }
-</pre><p>
-and finally runs the file <code>b.lua</code>.
-The script is called with <code>arg[1]</code>, <code>arg[2]</code>, &middot;&middot;&middot;
-as arguments;
-it can also access these arguments with the vararg expression '<code>...</code>'.
-
-
-<p>
-In interactive mode,
-if you write an incomplete statement,
-the interpreter waits for its completion
-by issuing a different prompt.
-
-
-<p>
-If the global variable <a name="pdf-_PROMPT"><code>_PROMPT</code></a> contains a string,
-then its value is used as the prompt.
-Similarly, if the global variable <a name="pdf-_PROMPT2"><code>_PROMPT2</code></a> contains a string,
-its value is used as the secondary prompt
-(issued during incomplete statements).
-Therefore, both prompts can be changed directly on the command line
-or in any Lua programs by assigning to <code>_PROMPT</code>.
-See the next example:
-
-<pre>
- $ lua -e"_PROMPT='myprompt&gt; '" -i
-</pre><p>
-(The outer pair of quotes is for the shell,
-the inner pair is for Lua.)
-Note the use of <code>-i</code> to enter interactive mode;
-otherwise,
-the program would just end silently
-right after the assignment to <code>_PROMPT</code>.
-
-
-<p>
-To allow the use of Lua as a
-script interpreter in Unix systems,
-the stand-alone interpreter skips
-the first line of a chunk if it starts with <code>#</code>.
-Therefore, Lua scripts can be made into executable programs
-by using <code>chmod +x</code> and the&nbsp;<code>#!</code> form,
-as in
-
-<pre>
- #!/usr/local/bin/lua
-</pre><p>
-(Of course,
-the location of the Lua interpreter may be different in your machine.
-If <code>lua</code> is in your <code>PATH</code>,
-then
-
-<pre>
- #!/usr/bin/env lua
-</pre><p>
-is a more portable solution.)
-
-
-
-<h1>7 - <a name="7">Incompatibilities with the Previous Version</a></h1>
-
-<p>
-Here we list the incompatibilities that you may find when moving a program
-from Lua&nbsp;5.0 to Lua&nbsp;5.1.
-You can avoid most of the incompatibilities compiling Lua with
-appropriate options (see file <code>luaconf.h</code>).
-However,
-all these compatibility options will be removed in the next version of Lua.
-
-
-
-<h2>7.1 - <a name="7.1">Changes in the Language</a></h2>
-<ul>
-
-<li>
-The vararg system changed from the pseudo-argument <code>arg</code> with a
-table with the extra arguments to the vararg expression.
-(See compile-time option <code>LUA_COMPAT_VARARG</code> in <code>luaconf.h</code>.)
-</li>
-
-<li>
-There was a subtle change in the scope of the implicit
-variables of the <b>for</b> statement and for the <b>repeat</b> statement.
-</li>
-
-<li>
-The long string/long comment syntax (<code>[[<em>string</em>]]</code>)
-does not allow nesting.
-You can use the new syntax (<code>[=[<em>string</em>]=]</code>) in these cases.
-(See compile-time option <code>LUA_COMPAT_LSTR</code> in <code>luaconf.h</code>.)
-</li>
-
-</ul>
-
-
-
-
-<h2>7.2 - <a name="7.2">Changes in the Libraries</a></h2>
-<ul>
-
-<li>
-Function <code>string.gfind</code> was renamed <a href="#pdf-string.gmatch"><code>string.gmatch</code></a>.
-(See compile-time option <code>LUA_COMPAT_GFIND</code> in <code>luaconf.h</code>.)
-</li>
-
-<li>
-When <a href="#pdf-string.gsub"><code>string.gsub</code></a> is called with a function as its
-third argument,
-whenever this function returns <b>nil</b> or <b>false</b> the
-replacement string is the whole match,
-instead of the empty string.
-</li>
-
-<li>
-Function <code>table.setn</code> was deprecated.
-Function <code>table.getn</code> corresponds
-to the new length operator (<code>#</code>);
-use the operator instead of the function.
-(See compile-time option <code>LUA_COMPAT_GETN</code> in <code>luaconf.h</code>.)
-</li>
-
-<li>
-Function <code>loadlib</code> was renamed <a href="#pdf-package.loadlib"><code>package.loadlib</code></a>.
-(See compile-time option <code>LUA_COMPAT_LOADLIB</code> in <code>luaconf.h</code>.)
-</li>
-
-<li>
-Function <code>math.mod</code> was renamed <a href="#pdf-math.fmod"><code>math.fmod</code></a>.
-(See compile-time option <code>LUA_COMPAT_MOD</code> in <code>luaconf.h</code>.)
-</li>
-
-<li>
-Functions <code>table.foreach</code> and <code>table.foreachi</code> are deprecated.
-You can use a for loop with <code>pairs</code> or <code>ipairs</code> instead.
-</li>
-
-<li>
-There were substantial changes in function <a href="#pdf-require"><code>require</code></a> due to
-the new module system.
-However, the new behavior is mostly compatible with the old,
-but <code>require</code> gets the path from <a href="#pdf-package.path"><code>package.path</code></a> instead
-of from <code>LUA_PATH</code>.
-</li>
-
-<li>
-Function <a href="#pdf-collectgarbage"><code>collectgarbage</code></a> has different arguments.
-Function <code>gcinfo</code> is deprecated;
-use <code>collectgarbage("count")</code> instead.
-</li>
-
-</ul>
-
-
-
-
-<h2>7.3 - <a name="7.3">Changes in the API</a></h2>
-<ul>
-
-<li>
-The <code>luaopen_*</code> functions (to open libraries)
-cannot be called directly,
-like a regular C function.
-They must be called through Lua,
-like a Lua function.
-</li>
-
-<li>
-Function <code>lua_open</code> was replaced by <a href="#lua_newstate"><code>lua_newstate</code></a> to
-allow the user to set a memory-allocation function.
-You can use <a href="#luaL_newstate"><code>luaL_newstate</code></a> from the standard library to
-create a state with a standard allocation function
-(based on <code>realloc</code>).
-</li>
-
-<li>
-Functions <code>luaL_getn</code> and <code>luaL_setn</code>
-(from the auxiliary library) are deprecated.
-Use <a href="#lua_objlen"><code>lua_objlen</code></a> instead of <code>luaL_getn</code>
-and nothing instead of <code>luaL_setn</code>.
-</li>
-
-<li>
-Function <code>luaL_openlib</code> was replaced by <a href="#luaL_register"><code>luaL_register</code></a>.
-</li>
-
-<li>
-Function <code>luaL_checkudata</code> now throws an error when the given value
-is not a userdata of the expected type.
-(In Lua&nbsp;5.0 it returned <code>NULL</code>.)
-</li>
-
-</ul>
-
-
-
-
-<h1>8 - <a name="8">The Complete Syntax of Lua</a></h1>
-
-<p>
-Here is the complete syntax of Lua in extended BNF.
-(It does not describe operator precedences.)
-
-
-
-
-<pre>
-
- chunk ::= {stat [`<b>;</b>&acute;]} [laststat [`<b>;</b>&acute;]]
-
- block ::= chunk
-
- stat ::= varlist `<b>=</b>&acute; explist |
- functioncall |
- <b>do</b> block <b>end</b> |
- <b>while</b> exp <b>do</b> block <b>end</b> |
- <b>repeat</b> block <b>until</b> exp |
- <b>if</b> exp <b>then</b> block {<b>elseif</b> exp <b>then</b> block} [<b>else</b> block] <b>end</b> |
- <b>for</b> Name `<b>=</b>&acute; exp `<b>,</b>&acute; exp [`<b>,</b>&acute; exp] <b>do</b> block <b>end</b> |
- <b>for</b> namelist <b>in</b> explist <b>do</b> block <b>end</b> |
- <b>function</b> funcname funcbody |
- <b>local</b> <b>function</b> Name funcbody |
- <b>local</b> namelist [`<b>=</b>&acute; explist]
-
- laststat ::= <b>return</b> [explist] | <b>break</b>
-
- funcname ::= Name {`<b>.</b>&acute; Name} [`<b>:</b>&acute; Name]
-
- varlist ::= var {`<b>,</b>&acute; var}
-
- var ::= Name | prefixexp `<b>[</b>&acute; exp `<b>]</b>&acute; | prefixexp `<b>.</b>&acute; Name
-
- namelist ::= Name {`<b>,</b>&acute; Name}
-
- explist ::= {exp `<b>,</b>&acute;} exp
-
- exp ::= <b>nil</b> | <b>false</b> | <b>true</b> | Number | String | `<b>...</b>&acute; | function |
- prefixexp | tableconstructor | exp binop exp | unop exp
-
- prefixexp ::= var | functioncall | `<b>(</b>&acute; exp `<b>)</b>&acute;
-
- functioncall ::= prefixexp args | prefixexp `<b>:</b>&acute; Name args
-
- args ::= `<b>(</b>&acute; [explist] `<b>)</b>&acute; | tableconstructor | String
-
- function ::= <b>function</b> funcbody
-
- funcbody ::= `<b>(</b>&acute; [parlist] `<b>)</b>&acute; block <b>end</b>
-
- parlist ::= namelist [`<b>,</b>&acute; `<b>...</b>&acute;] | `<b>...</b>&acute;
-
- tableconstructor ::= `<b>{</b>&acute; [fieldlist] `<b>}</b>&acute;
-
- fieldlist ::= field {fieldsep field} [fieldsep]
-
- field ::= `<b>[</b>&acute; exp `<b>]</b>&acute; `<b>=</b>&acute; exp | Name `<b>=</b>&acute; exp | exp
-
- fieldsep ::= `<b>,</b>&acute; | `<b>;</b>&acute;
-
- binop ::= `<b>+</b>&acute; | `<b>-</b>&acute; | `<b>*</b>&acute; | `<b>/</b>&acute; | `<b>^</b>&acute; | `<b>%</b>&acute; | `<b>..</b>&acute; |
- `<b>&lt;</b>&acute; | `<b>&lt;=</b>&acute; | `<b>&gt;</b>&acute; | `<b>&gt;=</b>&acute; | `<b>==</b>&acute; | `<b>~=</b>&acute; |
- <b>and</b> | <b>or</b>
-
- unop ::= `<b>-</b>&acute; | <b>not</b> | `<b>#</b>&acute;
-
-</pre>
-
-<p>
-
-
-
-
-
-
-
-<HR>
-<SMALL>
-Last update:
-Mon Aug 18 13:25:46 BRT 2008
-</SMALL>
-<!--
-Last change: revised for Lua 5.1.4
--->
-
-</body></html>
-
diff --git a/crawl-ref/source/util/lua/doc/readme.html b/crawl-ref/source/util/lua/doc/readme.html
deleted file mode 100644
index 38be6dbbfc..0000000000
--- a/crawl-ref/source/util/lua/doc/readme.html
+++ /dev/null
@@ -1,40 +0,0 @@
-<HTML>
-<HEAD>
-<TITLE>Lua documentation</TITLE>
-<LINK REL="stylesheet" TYPE="text/css" HREF="lua.css">
-</HEAD>
-
-<BODY>
-
-<HR>
-<H1>
-<A HREF="http://www.lua.org/"><IMG SRC="logo.gif" ALT="Lua" BORDER=0></A>
-Documentation
-</H1>
-
-This is the documentation included in the source distribution of Lua 5.1.4.
-
-<UL>
-<LI><A HREF="contents.html">Reference manual</A>
-<LI><A HREF="lua.html">lua man page</A>
-<LI><A HREF="luac.html">luac man page</A>
-<LI><A HREF="../README">lua/README</A>
-<LI><A HREF="../etc/README">lua/etc/README</A>
-<LI><A HREF="../test/README">lua/test/README</A>
-</UL>
-
-Lua's
-<A HREF="http://www.lua.org/">official web site</A>
-contains updated documentation,
-especially the
-<A HREF="http://www.lua.org/manual/5.1/">reference manual</A>.
-<P>
-
-<HR>
-<SMALL>
-Last update:
-Tue Aug 12 14:46:07 BRT 2008
-</SMALL>
-
-</BODY>
-</HTML>
diff --git a/crawl-ref/source/util/lua/etc/Makefile b/crawl-ref/source/util/lua/etc/Makefile
deleted file mode 100644
index 6d00008d98..0000000000
--- a/crawl-ref/source/util/lua/etc/Makefile
+++ /dev/null
@@ -1,44 +0,0 @@
-# makefile for Lua etc
-
-TOP= ..
-LIB= $(TOP)/src
-INC= $(TOP)/src
-BIN= $(TOP)/src
-SRC= $(TOP)/src
-TST= $(TOP)/test
-
-CC= gcc
-CFLAGS= -O2 -Wall -I$(INC) $(MYCFLAGS)
-MYCFLAGS=
-MYLDFLAGS= -Wl,-E
-MYLIBS= -lm
-#MYLIBS= -lm -Wl,-E -ldl -lreadline -lhistory -lncurses
-RM= rm -f
-
-default:
- @echo 'Please choose a target: min noparser one strict clean'
-
-min: min.c
- $(CC) $(CFLAGS) $@.c -L$(LIB) -llua $(MYLIBS)
- echo 'print"Hello there!"' | ./a.out
-
-noparser: noparser.o
- $(CC) noparser.o $(SRC)/lua.o -L$(LIB) -llua $(MYLIBS)
- $(BIN)/luac $(TST)/hello.lua
- -./a.out luac.out
- -./a.out -e'a=1'
-
-one:
- $(CC) $(CFLAGS) all.c $(MYLIBS)
- ./a.out $(TST)/hello.lua
-
-strict:
- -$(BIN)/lua -e 'print(a);b=2'
- -$(BIN)/lua -lstrict -e 'print(a)'
- -$(BIN)/lua -e 'function f() b=2 end f()'
- -$(BIN)/lua -lstrict -e 'function f() b=2 end f()'
-
-clean:
- $(RM) a.out core core.* *.o luac.out
-
-.PHONY: default min noparser one strict clean
diff --git a/crawl-ref/source/util/lua/etc/README b/crawl-ref/source/util/lua/etc/README
deleted file mode 100644
index 5149fc91d4..0000000000
--- a/crawl-ref/source/util/lua/etc/README
+++ /dev/null
@@ -1,37 +0,0 @@
-This directory contains some useful files and code.
-Unlike the code in ../src, everything here is in the public domain.
-
-If any of the makes fail, you're probably not using the same libraries
-used to build Lua. Set MYLIBS in Makefile accordingly.
-
-all.c
- Full Lua interpreter in a single file.
- Do "make one" for a demo.
-
-lua.hpp
- Lua header files for C++ using 'extern "C"'.
-
-lua.ico
- A Lua icon for Windows (and web sites: save as favicon.ico).
- Drawn by hand by Markus Gritsch <gritsch@iue.tuwien.ac.at>.
-
-lua.pc
- pkg-config data for Lua
-
-luavs.bat
- Script to build Lua under "Visual Studio .NET Command Prompt".
- Run it from the toplevel as etc\luavs.bat.
-
-min.c
- A minimal Lua interpreter.
- Good for learning and for starting your own.
- Do "make min" for a demo.
-
-noparser.c
- Linking with noparser.o avoids loading the parsing modules in lualib.a.
- Do "make noparser" for a demo.
-
-strict.lua
- Traps uses of undeclared global variables.
- Do "make strict" for a demo.
-
diff --git a/crawl-ref/source/util/lua/etc/all.c b/crawl-ref/source/util/lua/etc/all.c
deleted file mode 100644
index dab68fac58..0000000000
--- a/crawl-ref/source/util/lua/etc/all.c
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
-* all.c -- Lua core, libraries and interpreter in a single file
-*/
-
-#define luaall_c
-
-#include "lapi.c"
-#include "lcode.c"
-#include "ldebug.c"
-#include "ldo.c"
-#include "ldump.c"
-#include "lfunc.c"
-#include "lgc.c"
-#include "llex.c"
-#include "lmem.c"
-#include "lobject.c"
-#include "lopcodes.c"
-#include "lparser.c"
-#include "lstate.c"
-#include "lstring.c"
-#include "ltable.c"
-#include "ltm.c"
-#include "lundump.c"
-#include "lvm.c"
-#include "lzio.c"
-
-#include "lauxlib.c"
-#include "lbaselib.c"
-#include "ldblib.c"
-#include "liolib.c"
-#include "linit.c"
-#include "lmathlib.c"
-#include "loadlib.c"
-#include "loslib.c"
-#include "lstrlib.c"
-#include "ltablib.c"
-
-#include "lua.c"
diff --git a/crawl-ref/source/util/lua/etc/lua.hpp b/crawl-ref/source/util/lua/etc/lua.hpp
deleted file mode 100644
index ec417f5946..0000000000
--- a/crawl-ref/source/util/lua/etc/lua.hpp
+++ /dev/null
@@ -1,9 +0,0 @@
-// lua.hpp
-// Lua header files for C++
-// <<extern "C">> not supplied automatically because Lua also compiles as C++
-
-extern "C" {
-#include "lua.h"
-#include "lualib.h"
-#include "lauxlib.h"
-}
diff --git a/crawl-ref/source/util/lua/etc/lua.ico b/crawl-ref/source/util/lua/etc/lua.ico
deleted file mode 100644
index ccbabc4e20..0000000000
--- a/crawl-ref/source/util/lua/etc/lua.ico
+++ /dev/null
Binary files differ
diff --git a/crawl-ref/source/util/lua/etc/lua.pc b/crawl-ref/source/util/lua/etc/lua.pc
deleted file mode 100644
index f52f55b012..0000000000
--- a/crawl-ref/source/util/lua/etc/lua.pc
+++ /dev/null
@@ -1,31 +0,0 @@
-# lua.pc -- pkg-config data for Lua
-
-# vars from install Makefile
-
-# grep '^V=' ../Makefile
-V= 5.1
-# grep '^R=' ../Makefile
-R= 5.1.4
-
-# grep '^INSTALL_.*=' ../Makefile | sed 's/INSTALL_TOP/prefix/'
-prefix= /usr/local
-INSTALL_BIN= ${prefix}/bin
-INSTALL_INC= ${prefix}/include
-INSTALL_LIB= ${prefix}/lib
-INSTALL_MAN= ${prefix}/man/man1
-INSTALL_LMOD= ${prefix}/share/lua/${V}
-INSTALL_CMOD= ${prefix}/lib/lua/${V}
-
-# canonical vars
-exec_prefix=${prefix}
-libdir=${exec_prefix}/lib
-includedir=${prefix}/include
-
-Name: Lua
-Description: An Extensible Extension Language
-Version: ${R}
-Requires:
-Libs: -L${libdir} -llua -lm
-Cflags: -I${includedir}
-
-# (end of lua.pc)
diff --git a/crawl-ref/source/util/lua/etc/luavs.bat b/crawl-ref/source/util/lua/etc/luavs.bat
deleted file mode 100644
index 08c2beddf6..0000000000
--- a/crawl-ref/source/util/lua/etc/luavs.bat
+++ /dev/null
@@ -1,28 +0,0 @@
-@rem Script to build Lua under "Visual Studio .NET Command Prompt".
-@rem Do not run from this directory; run it from the toplevel: etc\luavs.bat .
-@rem It creates lua51.dll, lua51.lib, lua.exe, and luac.exe in src.
-@rem (contributed by David Manura and Mike Pall)
-
-@setlocal
-@set MYCOMPILE=cl /nologo /MD /O2 /W3 /c /D_CRT_SECURE_NO_DEPRECATE
-@set MYLINK=link /nologo
-@set MYMT=mt /nologo
-
-cd src
-%MYCOMPILE% /DLUA_BUILD_AS_DLL l*.c
-del lua.obj luac.obj
-%MYLINK% /DLL /out:lua51.dll l*.obj
-if exist lua51.dll.manifest^
- %MYMT% -manifest lua51.dll.manifest -outputresource:lua51.dll;2
-%MYCOMPILE% /DLUA_BUILD_AS_DLL lua.c
-%MYLINK% /out:lua.exe lua.obj lua51.lib
-if exist lua.exe.manifest^
- %MYMT% -manifest lua.exe.manifest -outputresource:lua.exe
-%MYCOMPILE% l*.c print.c
-del lua.obj linit.obj lbaselib.obj ldblib.obj liolib.obj lmathlib.obj^
- loslib.obj ltablib.obj lstrlib.obj loadlib.obj
-%MYLINK% /out:luac.exe *.obj
-if exist luac.exe.manifest^
- %MYMT% -manifest luac.exe.manifest -outputresource:luac.exe
-del *.obj *.manifest
-cd ..
diff --git a/crawl-ref/source/util/lua/etc/min.c b/crawl-ref/source/util/lua/etc/min.c
deleted file mode 100644
index 6a85a4d10e..0000000000
--- a/crawl-ref/source/util/lua/etc/min.c
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
-* min.c -- a minimal Lua interpreter
-* loads stdin only with minimal error handling.
-* no interaction, and no standard library, only a "print" function.
-*/
-
-#include <stdio.h>
-
-#include "lua.h"
-#include "lauxlib.h"
-
-static int print(lua_State *L)
-{
- int n=lua_gettop(L);
- int i;
- for (i=1; i<=n; i++)
- {
- if (i>1) printf("\t");
- if (lua_isstring(L,i))
- printf("%s",lua_tostring(L,i));
- else if (lua_isnil(L,i))
- printf("%s","nil");
- else if (lua_isboolean(L,i))
- printf("%s",lua_toboolean(L,i) ? "true" : "false");
- else
- printf("%s:%p",luaL_typename(L,i),lua_topointer(L,i));
- }
- printf("\n");
- return 0;
-}
-
-int main(void)
-{
- lua_State *L=lua_open();
- lua_register(L,"print",print);
- if (luaL_dofile(L,NULL)!=0) fprintf(stderr,"%s\n",lua_tostring(L,-1));
- lua_close(L);
- return 0;
-}
diff --git a/crawl-ref/source/util/lua/etc/noparser.c b/crawl-ref/source/util/lua/etc/noparser.c
deleted file mode 100644
index 13ba546239..0000000000
--- a/crawl-ref/source/util/lua/etc/noparser.c
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
-* The code below can be used to make a Lua core that does not contain the
-* parsing modules (lcode, llex, lparser), which represent 35% of the total core.
-* You'll only be able to load binary files and strings, precompiled with luac.
-* (Of course, you'll have to build luac with the original parsing modules!)
-*
-* To use this module, simply compile it ("make noparser" does that) and list
-* its object file before the Lua libraries. The linker should then not load
-* the parsing modules. To try it, do "make luab".
-*
-* If you also want to avoid the dump module (ldump.o), define NODUMP.
-* #define NODUMP
-*/
-
-#define LUA_CORE
-
-#include "llex.h"
-#include "lparser.h"
-#include "lzio.h"
-
-LUAI_FUNC void luaX_init (lua_State *L) {
- UNUSED(L);
-}
-
-LUAI_FUNC Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, const char *name) {
- UNUSED(z);
- UNUSED(buff);
- UNUSED(name);
- lua_pushliteral(L,"parser not loaded");
- lua_error(L);
- return NULL;
-}
-
-#ifdef NODUMP
-#include "lundump.h"
-
-LUAI_FUNC int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip) {
- UNUSED(f);
- UNUSED(w);
- UNUSED(data);
- UNUSED(strip);
-#if 1
- UNUSED(L);
- return 0;
-#else
- lua_pushliteral(L,"dumper not loaded");
- lua_error(L);
-#endif
-}
-#endif
diff --git a/crawl-ref/source/util/lua/etc/strict.lua b/crawl-ref/source/util/lua/etc/strict.lua
deleted file mode 100644
index 604619dd2e..0000000000
--- a/crawl-ref/source/util/lua/etc/strict.lua
+++ /dev/null
@@ -1,41 +0,0 @@
---
--- strict.lua
--- checks uses of undeclared global variables
--- All global variables must be 'declared' through a regular assignment
--- (even assigning nil will do) in a main chunk before being used
--- anywhere or assigned to inside a function.
---
-
-local getinfo, error, rawset, rawget = debug.getinfo, error, rawset, rawget
-
-local mt = getmetatable(_G)
-if mt == nil then
- mt = {}
- setmetatable(_G, mt)
-end
-
-mt.__declared = {}
-
-local function what ()
- local d = getinfo(3, "S")
- return d and d.what or "C"
-end
-
-mt.__newindex = function (t, n, v)
- if not mt.__declared[n] then
- local w = what()
- if w ~= "main" and w ~= "C" then
- error("assign to undeclared variable '"..n.."'", 2)
- end
- mt.__declared[n] = true
- end
- rawset(t, n, v)
-end
-
-mt.__index = function (t, n)
- if not mt.__declared[n] and what() ~= "C" then
- error("variable '"..n.."' is not declared", 2)
- end
- return rawget(t, n)
-end
-
diff --git a/crawl-ref/source/util/lua/src/Makefile b/crawl-ref/source/util/lua/src/Makefile
deleted file mode 100644
index 7e9cd10f2f..0000000000
--- a/crawl-ref/source/util/lua/src/Makefile
+++ /dev/null
@@ -1,208 +0,0 @@
-# makefile for building Lua
-# see ../INSTALL for installation instructions
-# see ../Makefile and luaconf.h for further customization
-#
-# Modified for Dungeon Crawl Reference.
-
-# == CHANGE THE SETTINGS BELOW TO SUIT YOUR ENVIRONMENT =======================
-
-# Your platform. See PLATS for possible values.
-PLAT= none
-
-ifneq ($(findstring $(MAKEFLAGS),s),s)
-ifndef V
- QUIET_CC = @echo ' ' CC $@;
- QUIET_AR = @echo ' ' AR $@;
- QUIET_LINK = @echo ' ' LINK $@;
- export V
-endif
-endif
-
-CC ?= gcc
-CFLAGS ?= -O2 -Wall
-AR ?= ar rcu
-RANLIB = ranlib
-RM ?= rm -f
-LIBS = -lm $(MYLIBS)
-
-MYCFLAGS=
-MYLDFLAGS=
-MYLIBS=
-
-# == END OF USER SETTINGS. NO NEED TO CHANGE ANYTHING BELOW THIS LINE =========
-
-PLATS= aix ansi bsd freebsd generic linux macosx mingw posix solaris \
- crawl_dos crawl_unix crawl_mingw
-
-LUA_A= liblua.a
-CORE_O= lapi.o lcode.o ldebug.o ldo.o ldump.o lfunc.o lgc.o llex.o lmem.o \
- lobject.o lopcodes.o lparser.o lstate.o lstring.o ltable.o ltm.o \
- lundump.o lvm.o lzio.o
-LIB_O= lauxlib.o lbaselib.o ldblib.o liolib.o lmathlib.o loslib.o ltablib.o \
- lstrlib.o loadlib.o linit.o
-
-LUA_T= lua
-LUA_O= lua.o
-
-LUAC_T= luac
-LUAC_O= luac.o print.o
-
-ALL_O= $(CORE_O) $(LIB_O) $(LUA_O) $(LUAC_O)
-ALL_T= $(LUA_A) $(LUA_T) $(LUAC_T)
-ALL_A= $(LUA_A)
-
-default: $(PLAT)
-
-all: $(ALL_T)
-
-%.o: %.c
- $(QUIET_CC)$(CC) -c $(CFLAGS) -o $@ $<
-
-o: $(ALL_O)
-
-a: $(ALL_A)
-
-$(LUA_A): $(CORE_O) $(LIB_O)
- $(QUIET_AR)$(AR) $@ $?
- @$(RANLIB) $@
-
-$(LUA_T): $(LUA_O) $(LUA_A)
- $(QUIET_LINK)$(CC) -o $@ $(MYLDFLAGS) $(LUA_O) $(LUA_A) $(LIBS)
-
-$(LUAC_T): $(LUAC_O) $(LUA_A)
- $(QUIET_LINK)$(CC) -o $@ $(MYLDFLAGS) $(LUAC_O) $(LUA_A) $(LIBS)
-
-clean:
- $(RM) $(ALL_T) $(ALL_O)
-
-clean_win:
- del $(ALL_T) $(ALL_O)
-
-depend:
- @$(CC) $(CFLAGS) -MM l*.c print.c
-
-echo:
- @echo "PLAT = $(PLAT)"
- @echo "CC = $(CC)"
- @echo "CFLAGS = $(CFLAGS)"
- @echo "AR = $(AR)"
- @echo "RANLIB = $(RANLIB)"
- @echo "RM = $(RM)"
- @echo "MYCFLAGS = $(MYCFLAGS)"
- @echo "MYLDFLAGS = $(MYLDFLAGS)"
- @echo "MYLIBS = $(MYLIBS)"
-
-# convenience targets for popular platforms
-
-none:
- @echo "Please choose a platform:"
- @echo " $(PLATS)"
-
-aix:
- $(MAKE) all CC="xlc" CFLAGS="-O2 -DLUA_USE_POSIX -DLUA_USE_DLOPEN" MYLIBS="-ldl" MYLDFLAGS="-brtl -bexpall"
-
-ansi:
- $(MAKE) all MYCFLAGS=-DLUA_ANSI
-
-bsd:
- $(MAKE) all MYCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN" MYLIBS="-Wl,-E"
-
-freebsd:
- $(MAKE) all MYCFLAGS="-DLUA_USE_LINUX" MYLIBS="-Wl,-E -lreadline"
-
-generic:
- $(MAKE) all MYCFLAGS=
-
-linux:
- $(MAKE) all MYCFLAGS=-DLUA_USE_LINUX MYLIBS="-Wl,-E -ldl -lreadline -lhistory -lncurses"
-
-macosx:
- $(MAKE) all MYCFLAGS=-DLUA_USE_LINUX MYLIBS="-lreadline"
-# use this on Mac OS X 10.3-
-# $(MAKE) all MYCFLAGS=-DLUA_USE_MACOSX
-
-mingw:
- $(MAKE) "LUA_A=lua51.dll" "LUA_T=lua.exe" \
- "AR=$(CC) -shared -o" "RANLIB=strip --strip-unneeded" \
- "MYCFLAGS=-DLUA_BUILD_AS_DLL" "MYLIBS=" "MYLDFLAGS=-s" lua.exe
- $(MAKE) "LUAC_T=luac.exe" luac.exe
-
-crawl_unix:
- @$(MAKE) "LUA_A=liblua.a" \
- "MYCFLAGS=" "MYLIBS=" "MYLDFLAGS=" liblua.a
-
-crawl_mingw: crawl_unix
-
-crawl_dos: crawl_mingw
-
-posix:
- $(MAKE) all MYCFLAGS=-DLUA_USE_POSIX
-
-solaris:
- $(MAKE) all MYCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN" MYLIBS="-ldl"
-
-# list targets that do not create files (but not all makes understand .PHONY)
-.PHONY: all $(PLATS) default o a clean depend echo none
-
-# DO NOT DELETE
-
-lapi.o: lapi.c lua.h luaconf.h lapi.h lobject.h llimits.h ldebug.h \
- lstate.h ltm.h lzio.h lmem.h ldo.h lfunc.h lgc.h lstring.h ltable.h \
- lundump.h lvm.h
-lauxlib.o: lauxlib.c lua.h luaconf.h lauxlib.h
-lbaselib.o: lbaselib.c lua.h luaconf.h lauxlib.h lualib.h
-lcode.o: lcode.c lua.h luaconf.h lcode.h llex.h lobject.h llimits.h \
- lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h ldo.h lgc.h \
- ltable.h
-ldblib.o: ldblib.c lua.h luaconf.h lauxlib.h lualib.h
-ldebug.o: ldebug.c lua.h luaconf.h lapi.h lobject.h llimits.h lcode.h \
- llex.h lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h ldo.h \
- lfunc.h lstring.h lgc.h ltable.h lvm.h
-ldo.o: ldo.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h \
- lzio.h lmem.h ldo.h lfunc.h lgc.h lopcodes.h lparser.h lstring.h \
- ltable.h lundump.h lvm.h
-ldump.o: ldump.c lua.h luaconf.h lobject.h llimits.h lstate.h ltm.h \
- lzio.h lmem.h lundump.h
-lfunc.o: lfunc.c lua.h luaconf.h lfunc.h lobject.h llimits.h lgc.h lmem.h \
- lstate.h ltm.h lzio.h
-lgc.o: lgc.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h \
- lzio.h lmem.h ldo.h lfunc.h lgc.h lstring.h ltable.h
-linit.o: linit.c lua.h luaconf.h lualib.h lauxlib.h
-liolib.o: liolib.c lua.h luaconf.h lauxlib.h lualib.h
-llex.o: llex.c lua.h luaconf.h ldo.h lobject.h llimits.h lstate.h ltm.h \
- lzio.h lmem.h llex.h lparser.h lstring.h lgc.h ltable.h
-lmathlib.o: lmathlib.c lua.h luaconf.h lauxlib.h lualib.h
-lmem.o: lmem.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h \
- ltm.h lzio.h lmem.h ldo.h
-loadlib.o: loadlib.c lua.h luaconf.h lauxlib.h lualib.h
-lobject.o: lobject.c lua.h luaconf.h ldo.h lobject.h llimits.h lstate.h \
- ltm.h lzio.h lmem.h lstring.h lgc.h lvm.h
-lopcodes.o: lopcodes.c lopcodes.h llimits.h lua.h luaconf.h
-loslib.o: loslib.c lua.h luaconf.h lauxlib.h lualib.h
-lparser.o: lparser.c lua.h luaconf.h lcode.h llex.h lobject.h llimits.h \
- lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h ldo.h \
- lfunc.h lstring.h lgc.h ltable.h
-lstate.o: lstate.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h \
- ltm.h lzio.h lmem.h ldo.h lfunc.h lgc.h llex.h lstring.h ltable.h
-lstring.o: lstring.c lua.h luaconf.h lmem.h llimits.h lobject.h lstate.h \
- ltm.h lzio.h lstring.h lgc.h
-lstrlib.o: lstrlib.c lua.h luaconf.h lauxlib.h lualib.h
-ltable.o: ltable.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h \
- ltm.h lzio.h lmem.h ldo.h lgc.h ltable.h
-ltablib.o: ltablib.c lua.h luaconf.h lauxlib.h lualib.h
-ltm.o: ltm.c lua.h luaconf.h lobject.h llimits.h lstate.h ltm.h lzio.h \
- lmem.h lstring.h lgc.h ltable.h
-lua.o: lua.c lua.h luaconf.h lauxlib.h lualib.h
-luac.o: luac.c lua.h luaconf.h lauxlib.h ldo.h lobject.h llimits.h \
- lstate.h ltm.h lzio.h lmem.h lfunc.h lopcodes.h lstring.h lgc.h \
- lundump.h
-lundump.o: lundump.c lua.h luaconf.h ldebug.h lstate.h lobject.h \
- llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lstring.h lgc.h lundump.h
-lvm.o: lvm.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h \
- lzio.h lmem.h ldo.h lfunc.h lgc.h lopcodes.h lstring.h ltable.h lvm.h
-lzio.o: lzio.c lua.h luaconf.h llimits.h lmem.h lstate.h lobject.h ltm.h \
- lzio.h
-print.o: print.c ldebug.h lstate.h lua.h luaconf.h lobject.h llimits.h \
- ltm.h lzio.h lmem.h lopcodes.h lundump.h
-
-# (end of Makefile)
diff --git a/crawl-ref/source/util/lua/src/lapi.c b/crawl-ref/source/util/lua/src/lapi.c
deleted file mode 100644
index 5d5145d2eb..0000000000
--- a/crawl-ref/source/util/lua/src/lapi.c
+++ /dev/null
@@ -1,1087 +0,0 @@
-/*
-** $Id: lapi.c,v 2.55.1.5 2008/07/04 18:41:18 roberto Exp $
-** Lua API
-** See Copyright Notice in lua.h
-*/
-
-
-#include <assert.h>
-#include <math.h>
-#include <stdarg.h>
-#include <string.h>
-
-#define lapi_c
-#define LUA_CORE
-
-#include "lua.h"
-
-#include "lapi.h"
-#include "ldebug.h"
-#include "ldo.h"
-#include "lfunc.h"
-#include "lgc.h"
-#include "lmem.h"
-#include "lobject.h"
-#include "lstate.h"
-#include "lstring.h"
-#include "ltable.h"
-#include "ltm.h"
-#include "lundump.h"
-#include "lvm.h"
-
-
-
-const char lua_ident[] =
- "$Lua: " LUA_RELEASE " " LUA_COPYRIGHT " $\n"
- "$Authors: " LUA_AUTHORS " $\n"
- "$URL: www.lua.org $\n";
-
-
-
-#define api_checknelems(L, n) api_check(L, (n) <= (L->top - L->base))
-
-#define api_checkvalidindex(L, i) api_check(L, (i) != luaO_nilobject)
-
-#define api_incr_top(L) {api_check(L, L->top < L->ci->top); L->top++;}
-
-
-
-static TValue *index2adr (lua_State *L, int idx) {
- if (idx > 0) {
- TValue *o = L->base + (idx - 1);
- api_check(L, idx <= L->ci->top - L->base);
- if (o >= L->top) return cast(TValue *, luaO_nilobject);
- else return o;
- }
- else if (idx > LUA_REGISTRYINDEX) {
- api_check(L, idx != 0 && -idx <= L->top - L->base);
- return L->top + idx;
- }
- else switch (idx) { /* pseudo-indices */
- case LUA_REGISTRYINDEX: return registry(L);
- case LUA_ENVIRONINDEX: {
- Closure *func = curr_func(L);
- sethvalue(L, &L->env, func->c.env);
- return &L->env;
- }
- case LUA_GLOBALSINDEX: return gt(L);
- default: {
- Closure *func = curr_func(L);
- idx = LUA_GLOBALSINDEX - idx;
- return (idx <= func->c.nupvalues)
- ? &func->c.upvalue[idx-1]
- : cast(TValue *, luaO_nilobject);
- }
- }
-}
-
-
-static Table *getcurrenv (lua_State *L) {
- if (L->ci == L->base_ci) /* no enclosing function? */
- return hvalue(gt(L)); /* use global table as environment */
- else {
- Closure *func = curr_func(L);
- return func->c.env;
- }
-}
-
-
-void luaA_pushobject (lua_State *L, const TValue *o) {
- setobj2s(L, L->top, o);
- api_incr_top(L);
-}
-
-
-LUA_API int lua_checkstack (lua_State *L, int size) {
- int res = 1;
- lua_lock(L);
- if (size > LUAI_MAXCSTACK || (L->top - L->base + size) > LUAI_MAXCSTACK)
- res = 0; /* stack overflow */
- else if (size > 0) {
- luaD_checkstack(L, size);
- if (L->ci->top < L->top + size)
- L->ci->top = L->top + size;
- }
- lua_unlock(L);
- return res;
-}
-
-
-LUA_API void lua_xmove (lua_State *from, lua_State *to, int n) {
- int i;
- if (from == to) return;
- lua_lock(to);
- api_checknelems(from, n);
- api_check(from, G(from) == G(to));
- api_check(from, to->ci->top - to->top >= n);
- from->top -= n;
- for (i = 0; i < n; i++) {
- setobj2s(to, to->top++, from->top + i);
- }
- lua_unlock(to);
-}
-
-
-LUA_API void lua_setlevel (lua_State *from, lua_State *to) {
- to->nCcalls = from->nCcalls;
-}
-
-
-LUA_API lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf) {
- lua_CFunction old;
- lua_lock(L);
- old = G(L)->panic;
- G(L)->panic = panicf;
- lua_unlock(L);
- return old;
-}
-
-
-LUA_API lua_State *lua_newthread (lua_State *L) {
- lua_State *L1;
- lua_lock(L);
- luaC_checkGC(L);
- L1 = luaE_newthread(L);
- setthvalue(L, L->top, L1);
- api_incr_top(L);
- lua_unlock(L);
- luai_userstatethread(L, L1);
- return L1;
-}
-
-
-
-/*
-** basic stack manipulation
-*/
-
-
-LUA_API int lua_gettop (lua_State *L) {
- return cast_int(L->top - L->base);
-}
-
-
-LUA_API void lua_settop (lua_State *L, int idx) {
- lua_lock(L);
- if (idx >= 0) {
- api_check(L, idx <= L->stack_last - L->base);
- while (L->top < L->base + idx)
- setnilvalue(L->top++);
- L->top = L->base + idx;
- }
- else {
- api_check(L, -(idx+1) <= (L->top - L->base));
- L->top += idx+1; /* `subtract' index (index is negative) */
- }
- lua_unlock(L);
-}
-
-
-LUA_API void lua_remove (lua_State *L, int idx) {
- StkId p;
- lua_lock(L);
- p = index2adr(L, idx);
- api_checkvalidindex(L, p);
- while (++p < L->top) setobjs2s(L, p-1, p);
- L->top--;
- lua_unlock(L);
-}
-
-
-LUA_API void lua_insert (lua_State *L, int idx) {
- StkId p;
- StkId q;
- lua_lock(L);
- p = index2adr(L, idx);
- api_checkvalidindex(L, p);
- for (q = L->top; q>p; q--) setobjs2s(L, q, q-1);
- setobjs2s(L, p, L->top);
- lua_unlock(L);
-}
-
-
-LUA_API void lua_replace (lua_State *L, int idx) {
- StkId o;
- lua_lock(L);
- /* explicit test for incompatible code */
- if (idx == LUA_ENVIRONINDEX && L->ci == L->base_ci)
- luaG_runerror(L, "no calling environment");
- api_checknelems(L, 1);
- o = index2adr(L, idx);
- api_checkvalidindex(L, o);
- if (idx == LUA_ENVIRONINDEX) {
- Closure *func = curr_func(L);
- api_check(L, ttistable(L->top - 1));
- func->c.env = hvalue(L->top - 1);
- luaC_barrier(L, func, L->top - 1);
- }
- else {
- setobj(L, o, L->top - 1);
- if (idx < LUA_GLOBALSINDEX) /* function upvalue? */
- luaC_barrier(L, curr_func(L), L->top - 1);
- }
- L->top--;
- lua_unlock(L);
-}
-
-
-LUA_API void lua_pushvalue (lua_State *L, int idx) {
- lua_lock(L);
- setobj2s(L, L->top, index2adr(L, idx));
- api_incr_top(L);
- lua_unlock(L);
-}
-
-
-
-/*
-** access functions (stack -> C)
-*/
-
-
-LUA_API int lua_type (lua_State *L, int idx) {
- StkId o = index2adr(L, idx);
- return (o == luaO_nilobject) ? LUA_TNONE : ttype(o);
-}
-
-
-LUA_API const char *lua_typename (lua_State *L, int t) {
- UNUSED(L);
- return (t == LUA_TNONE) ? "no value" : luaT_typenames[t];
-}
-
-
-LUA_API int lua_iscfunction (lua_State *L, int idx) {
- StkId o = index2adr(L, idx);
- return iscfunction(o);
-}
-
-
-LUA_API int lua_isnumber (lua_State *L, int idx) {
- TValue n;
- const TValue *o = index2adr(L, idx);
- return tonumber(o, &n);
-}
-
-
-LUA_API int lua_isstring (lua_State *L, int idx) {
- int t = lua_type(L, idx);
- return (t == LUA_TSTRING || t == LUA_TNUMBER);
-}
-
-
-LUA_API int lua_isuserdata (lua_State *L, int idx) {
- const TValue *o = index2adr(L, idx);
- return (ttisuserdata(o) || ttislightuserdata(o));
-}
-
-
-LUA_API int lua_rawequal (lua_State *L, int index1, int index2) {
- StkId o1 = index2adr(L, index1);
- StkId o2 = index2adr(L, index2);
- return (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0
- : luaO_rawequalObj(o1, o2);
-}
-
-
-LUA_API int lua_equal (lua_State *L, int index1, int index2) {
- StkId o1, o2;
- int i;
- lua_lock(L); /* may call tag method */
- o1 = index2adr(L, index1);
- o2 = index2adr(L, index2);
- i = (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0 : equalobj(L, o1, o2);
- lua_unlock(L);
- return i;
-}
-
-
-LUA_API int lua_lessthan (lua_State *L, int index1, int index2) {
- StkId o1, o2;
- int i;
- lua_lock(L); /* may call tag method */
- o1 = index2adr(L, index1);
- o2 = index2adr(L, index2);
- i = (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0
- : luaV_lessthan(L, o1, o2);
- lua_unlock(L);
- return i;
-}
-
-
-
-LUA_API lua_Number lua_tonumber (lua_State *L, int idx) {
- TValue n;
- const TValue *o = index2adr(L, idx);
- if (tonumber(o, &n))
- return nvalue(o);
- else
- return 0;
-}
-
-
-LUA_API lua_Integer lua_tointeger (lua_State *L, int idx) {
- TValue n;
- const TValue *o = index2adr(L, idx);
- if (tonumber(o, &n)) {
- lua_Integer res;
- lua_Number num = nvalue(o);
- lua_number2integer(res, num);
- return res;
- }
- else
- return 0;
-}
-
-
-LUA_API int lua_toboolean (lua_State *L, int idx) {
- const TValue *o = index2adr(L, idx);
- return !l_isfalse(o);
-}
-
-
-LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) {
- StkId o = index2adr(L, idx);
- if (!ttisstring(o)) {
- lua_lock(L); /* `luaV_tostring' may create a new string */
- if (!luaV_tostring(L, o)) { /* conversion failed? */
- if (len != NULL) *len = 0;
- lua_unlock(L);
- return NULL;
- }
- luaC_checkGC(L);
- o = index2adr(L, idx); /* previous call may reallocate the stack */
- lua_unlock(L);
- }
- if (len != NULL) *len = tsvalue(o)->len;
- return svalue(o);
-}
-
-
-LUA_API size_t lua_objlen (lua_State *L, int idx) {
- StkId o = index2adr(L, idx);
- switch (ttype(o)) {
- case LUA_TSTRING: return tsvalue(o)->len;
- case LUA_TUSERDATA: return uvalue(o)->len;
- case LUA_TTABLE: return luaH_getn(hvalue(o));
- case LUA_TNUMBER: {
- size_t l;
- lua_lock(L); /* `luaV_tostring' may create a new string */
- l = (luaV_tostring(L, o) ? tsvalue(o)->len : 0);
- lua_unlock(L);
- return l;
- }
- default: return 0;
- }
-}
-
-
-LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) {
- StkId o = index2adr(L, idx);
- return (!iscfunction(o)) ? NULL : clvalue(o)->c.f;
-}
-
-
-LUA_API void *lua_touserdata (lua_State *L, int idx) {
- StkId o = index2adr(L, idx);
- switch (ttype(o)) {
- case LUA_TUSERDATA: return (rawuvalue(o) + 1);
- case LUA_TLIGHTUSERDATA: return pvalue(o);
- default: return NULL;
- }
-}
-
-
-LUA_API lua_State *lua_tothread (lua_State *L, int idx) {
- StkId o = index2adr(L, idx);
- return (!ttisthread(o)) ? NULL : thvalue(o);
-}
-
-
-LUA_API const void *lua_topointer (lua_State *L, int idx) {
- StkId o = index2adr(L, idx);
- switch (ttype(o)) {
- case LUA_TTABLE: return hvalue(o);
- case LUA_TFUNCTION: return clvalue(o);
- case LUA_TTHREAD: return thvalue(o);
- case LUA_TUSERDATA:
- case LUA_TLIGHTUSERDATA:
- return lua_touserdata(L, idx);
- default: return NULL;
- }
-}
-
-
-
-/*
-** push functions (C -> stack)
-*/
-
-
-LUA_API void lua_pushnil (lua_State *L) {
- lua_lock(L);
- setnilvalue(L->top);
- api_incr_top(L);
- lua_unlock(L);
-}
-
-
-LUA_API void lua_pushnumber (lua_State *L, lua_Number n) {
- lua_lock(L);
- setnvalue(L->top, n);
- api_incr_top(L);
- lua_unlock(L);
-}
-
-
-LUA_API void lua_pushinteger (lua_State *L, lua_Integer n) {
- lua_lock(L);
- setnvalue(L->top, cast_num(n));
- api_incr_top(L);
- lua_unlock(L);
-}
-
-
-LUA_API void lua_pushlstring (lua_State *L, const char *s, size_t len) {
- lua_lock(L);
- luaC_checkGC(L);
- setsvalue2s(L, L->top, luaS_newlstr(L, s, len));
- api_incr_top(L);
- lua_unlock(L);
-}
-
-
-LUA_API void lua_pushstring (lua_State *L, const char *s) {
- if (s == NULL)
- lua_pushnil(L);
- else
- lua_pushlstring(L, s, strlen(s));
-}
-
-
-LUA_API const char *lua_pushvfstring (lua_State *L, const char *fmt,
- va_list argp) {
- const char *ret;
- lua_lock(L);
- luaC_checkGC(L);
- ret = luaO_pushvfstring(L, fmt, argp);
- lua_unlock(L);
- return ret;
-}
-
-
-LUA_API const char *lua_pushfstring (lua_State *L, const char *fmt, ...) {
- const char *ret;
- va_list argp;
- lua_lock(L);
- luaC_checkGC(L);
- va_start(argp, fmt);
- ret = luaO_pushvfstring(L, fmt, argp);
- va_end(argp);
- lua_unlock(L);
- return ret;
-}
-
-
-LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
- Closure *cl;
- lua_lock(L);
- luaC_checkGC(L);
- api_checknelems(L, n);
- cl = luaF_newCclosure(L, n, getcurrenv(L));
- cl->c.f = fn;
- L->top -= n;
- while (n--)
- setobj2n(L, &cl->c.upvalue[n], L->top+n);
- setclvalue(L, L->top, cl);
- lua_assert(iswhite(obj2gco(cl)));
- api_incr_top(L);
- lua_unlock(L);
-}
-
-
-LUA_API void lua_pushboolean (lua_State *L, int b) {
- lua_lock(L);
- setbvalue(L->top, (b != 0)); /* ensure that true is 1 */
- api_incr_top(L);
- lua_unlock(L);
-}
-
-
-LUA_API void lua_pushlightuserdata (lua_State *L, void *p) {
- lua_lock(L);
- setpvalue(L->top, p);
- api_incr_top(L);
- lua_unlock(L);
-}
-
-
-LUA_API int lua_pushthread (lua_State *L) {
- lua_lock(L);
- setthvalue(L, L->top, L);
- api_incr_top(L);
- lua_unlock(L);
- return (G(L)->mainthread == L);
-}
-
-
-
-/*
-** get functions (Lua -> stack)
-*/
-
-
-LUA_API void lua_gettable (lua_State *L, int idx) {
- StkId t;
- lua_lock(L);
- t = index2adr(L, idx);
- api_checkvalidindex(L, t);
- luaV_gettable(L, t, L->top - 1, L->top - 1);
- lua_unlock(L);
-}
-
-
-LUA_API void lua_getfield (lua_State *L, int idx, const char *k) {
- StkId t;
- TValue key;
- lua_lock(L);
- t = index2adr(L, idx);
- api_checkvalidindex(L, t);
- setsvalue(L, &key, luaS_new(L, k));
- luaV_gettable(L, t, &key, L->top);
- api_incr_top(L);
- lua_unlock(L);
-}
-
-
-LUA_API void lua_rawget (lua_State *L, int idx) {
- StkId t;
- lua_lock(L);
- t = index2adr(L, idx);
- api_check(L, ttistable(t));
- setobj2s(L, L->top - 1, luaH_get(hvalue(t), L->top - 1));
- lua_unlock(L);
-}
-
-
-LUA_API void lua_rawgeti (lua_State *L, int idx, int n) {
- StkId o;
- lua_lock(L);
- o = index2adr(L, idx);
- api_check(L, ttistable(o));
- setobj2s(L, L->top, luaH_getnum(hvalue(o), n));
- api_incr_top(L);
- lua_unlock(L);
-}
-
-
-LUA_API void lua_createtable (lua_State *L, int narray, int nrec) {
- lua_lock(L);
- luaC_checkGC(L);
- sethvalue(L, L->top, luaH_new(L, narray, nrec));
- api_incr_top(L);
- lua_unlock(L);
-}
-
-
-LUA_API int lua_getmetatable (lua_State *L, int objindex) {
- const TValue *obj;
- Table *mt = NULL;
- int res;
- lua_lock(L);
- obj = index2adr(L, objindex);
- switch (ttype(obj)) {
- case LUA_TTABLE:
- mt = hvalue(obj)->metatable;
- break;
- case LUA_TUSERDATA:
- mt = uvalue(obj)->metatable;
- break;
- default:
- mt = G(L)->mt[ttype(obj)];
- break;
- }
- if (mt == NULL)
- res = 0;
- else {
- sethvalue(L, L->top, mt);
- api_incr_top(L);
- res = 1;
- }
- lua_unlock(L);
- return res;
-}
-
-
-LUA_API void lua_getfenv (lua_State *L, int idx) {
- StkId o;
- lua_lock(L);
- o = index2adr(L, idx);
- api_checkvalidindex(L, o);
- switch (ttype(o)) {
- case LUA_TFUNCTION:
- sethvalue(L, L->top, clvalue(o)->c.env);
- break;
- case LUA_TUSERDATA:
- sethvalue(L, L->top, uvalue(o)->env);
- break;
- case LUA_TTHREAD:
- setobj2s(L, L->top, gt(thvalue(o)));
- break;
- default:
- setnilvalue(L->top);
- break;
- }
- api_incr_top(L);
- lua_unlock(L);
-}
-
-
-/*
-** set functions (stack -> Lua)
-*/
-
-
-LUA_API void lua_settable (lua_State *L, int idx) {
- StkId t;
- lua_lock(L);
- api_checknelems(L, 2);
- t = index2adr(L, idx);
- api_checkvalidindex(L, t);
- luaV_settable(L, t, L->top - 2, L->top - 1);
- L->top -= 2; /* pop index and value */
- lua_unlock(L);
-}
-
-
-LUA_API void lua_setfield (lua_State *L, int idx, const char *k) {
- StkId t;
- TValue key;
- lua_lock(L);
- api_checknelems(L, 1);
- t = index2adr(L, idx);
- api_checkvalidindex(L, t);
- setsvalue(L, &key, luaS_new(L, k));
- luaV_settable(L, t, &key, L->top - 1);
- L->top--; /* pop value */
- lua_unlock(L);
-}
-
-
-LUA_API void lua_rawset (lua_State *L, int idx) {
- StkId t;
- lua_lock(L);
- api_checknelems(L, 2);
- t = index2adr(L, idx);
- api_check(L, ttistable(t));
- setobj2t(L, luaH_set(L, hvalue(t), L->top-2), L->top-1);
- luaC_barriert(L, hvalue(t), L->top-1);
- L->top -= 2;
- lua_unlock(L);
-}
-
-
-LUA_API void lua_rawseti (lua_State *L, int idx, int n) {
- StkId o;
- lua_lock(L);
- api_checknelems(L, 1);
- o = index2adr(L, idx);
- api_check(L, ttistable(o));
- setobj2t(L, luaH_setnum(L, hvalue(o), n), L->top-1);
- luaC_barriert(L, hvalue(o), L->top-1);
- L->top--;
- lua_unlock(L);
-}
-
-
-LUA_API int lua_setmetatable (lua_State *L, int objindex) {
- TValue *obj;
- Table *mt;
- lua_lock(L);
- api_checknelems(L, 1);
- obj = index2adr(L, objindex);
- api_checkvalidindex(L, obj);
- if (ttisnil(L->top - 1))
- mt = NULL;
- else {
- api_check(L, ttistable(L->top - 1));
- mt = hvalue(L->top - 1);
- }
- switch (ttype(obj)) {
- case LUA_TTABLE: {
- hvalue(obj)->metatable = mt;
- if (mt)
- luaC_objbarriert(L, hvalue(obj), mt);
- break;
- }
- case LUA_TUSERDATA: {
- uvalue(obj)->metatable = mt;
- if (mt)
- luaC_objbarrier(L, rawuvalue(obj), mt);
- break;
- }
- default: {
- G(L)->mt[ttype(obj)] = mt;
- break;
- }
- }
- L->top--;
- lua_unlock(L);
- return 1;
-}
-
-
-LUA_API int lua_setfenv (lua_State *L, int idx) {
- StkId o;
- int res = 1;
- lua_lock(L);
- api_checknelems(L, 1);
- o = index2adr(L, idx);
- api_checkvalidindex(L, o);
- api_check(L, ttistable(L->top - 1));
- switch (ttype(o)) {
- case LUA_TFUNCTION:
- clvalue(o)->c.env = hvalue(L->top - 1);
- break;
- case LUA_TUSERDATA:
- uvalue(o)->env = hvalue(L->top - 1);
- break;
- case LUA_TTHREAD:
- sethvalue(L, gt(thvalue(o)), hvalue(L->top - 1));
- break;
- default:
- res = 0;
- break;
- }
- if (res) luaC_objbarrier(L, gcvalue(o), hvalue(L->top - 1));
- L->top--;
- lua_unlock(L);
- return res;
-}
-
-
-/*
-** `load' and `call' functions (run Lua code)
-*/
-
-
-#define adjustresults(L,nres) \
- { if (nres == LUA_MULTRET && L->top >= L->ci->top) L->ci->top = L->top; }
-
-
-#define checkresults(L,na,nr) \
- api_check(L, (nr) == LUA_MULTRET || (L->ci->top - L->top >= (nr) - (na)))
-
-
-LUA_API void lua_call (lua_State *L, int nargs, int nresults) {
- StkId func;
- lua_lock(L);
- api_checknelems(L, nargs+1);
- checkresults(L, nargs, nresults);
- func = L->top - (nargs+1);
- luaD_call(L, func, nresults);
- adjustresults(L, nresults);
- lua_unlock(L);
-}
-
-
-
-/*
-** Execute a protected call.
-*/
-struct CallS { /* data to `f_call' */
- StkId func;
- int nresults;
-};
-
-
-static void f_call (lua_State *L, void *ud) {
- struct CallS *c = cast(struct CallS *, ud);
- luaD_call(L, c->func, c->nresults);
-}
-
-
-
-LUA_API int lua_pcall (lua_State *L, int nargs, int nresults, int errfunc) {
- struct CallS c;
- int status;
- ptrdiff_t func;
- lua_lock(L);
- api_checknelems(L, nargs+1);
- checkresults(L, nargs, nresults);
- if (errfunc == 0)
- func = 0;
- else {
- StkId o = index2adr(L, errfunc);
- api_checkvalidindex(L, o);
- func = savestack(L, o);
- }
- c.func = L->top - (nargs+1); /* function to be called */
- c.nresults = nresults;
- status = luaD_pcall(L, f_call, &c, savestack(L, c.func), func);
- adjustresults(L, nresults);
- lua_unlock(L);
- return status;
-}
-
-
-/*
-** Execute a protected C call.
-*/
-struct CCallS { /* data to `f_Ccall' */
- lua_CFunction func;
- void *ud;
-};
-
-
-static void f_Ccall (lua_State *L, void *ud) {
- struct CCallS *c = cast(struct CCallS *, ud);
- Closure *cl;
- cl = luaF_newCclosure(L, 0, getcurrenv(L));
- cl->c.f = c->func;
- setclvalue(L, L->top, cl); /* push function */
- api_incr_top(L);
- setpvalue(L->top, c->ud); /* push only argument */
- api_incr_top(L);
- luaD_call(L, L->top - 2, 0);
-}
-
-
-LUA_API int lua_cpcall (lua_State *L, lua_CFunction func, void *ud) {
- struct CCallS c;
- int status;
- lua_lock(L);
- c.func = func;
- c.ud = ud;
- status = luaD_pcall(L, f_Ccall, &c, savestack(L, L->top), 0);
- lua_unlock(L);
- return status;
-}
-
-
-LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data,
- const char *chunkname) {
- ZIO z;
- int status;
- lua_lock(L);
- if (!chunkname) chunkname = "?";
- luaZ_init(L, &z, reader, data);
- status = luaD_protectedparser(L, &z, chunkname);
- lua_unlock(L);
- return status;
-}
-
-
-LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data) {
- int status;
- TValue *o;
- lua_lock(L);
- api_checknelems(L, 1);
- o = L->top - 1;
- if (isLfunction(o))
- status = luaU_dump(L, clvalue(o)->l.p, writer, data, 0);
- else
- status = 1;
- lua_unlock(L);
- return status;
-}
-
-
-LUA_API int lua_status (lua_State *L) {
- return L->status;
-}
-
-
-/*
-** Garbage-collection function
-*/
-
-LUA_API int lua_gc (lua_State *L, int what, int data) {
- int res = 0;
- global_State *g;
- lua_lock(L);
- g = G(L);
- switch (what) {
- case LUA_GCSTOP: {
- g->GCthreshold = MAX_LUMEM;
- break;
- }
- case LUA_GCRESTART: {
- g->GCthreshold = g->totalbytes;
- break;
- }
- case LUA_GCCOLLECT: {
- luaC_fullgc(L);
- break;
- }
- case LUA_GCCOUNT: {
- /* GC values are expressed in Kbytes: #bytes/2^10 */
- res = cast_int(g->totalbytes >> 10);
- break;
- }
- case LUA_GCCOUNTB: {
- res = cast_int(g->totalbytes & 0x3ff);
- break;
- }
- case LUA_GCSTEP: {
- lu_mem a = (cast(lu_mem, data) << 10);
- if (a <= g->totalbytes)
- g->GCthreshold = g->totalbytes - a;
- else
- g->GCthreshold = 0;
- while (g->GCthreshold <= g->totalbytes) {
- luaC_step(L);
- if (g->gcstate == GCSpause) { /* end of cycle? */
- res = 1; /* signal it */
- break;
- }
- }
- break;
- }
- case LUA_GCSETPAUSE: {
- res = g->gcpause;
- g->gcpause = data;
- break;
- }
- case LUA_GCSETSTEPMUL: {
- res = g->gcstepmul;
- g->gcstepmul = data;
- break;
- }
- default: res = -1; /* invalid option */
- }
- lua_unlock(L);
- return res;
-}
-
-
-
-/*
-** miscellaneous functions
-*/
-
-
-LUA_API int lua_error (lua_State *L) {
- lua_lock(L);
- api_checknelems(L, 1);
- luaG_errormsg(L);
- lua_unlock(L);
- return 0; /* to avoid warnings */
-}
-
-
-LUA_API int lua_next (lua_State *L, int idx) {
- StkId t;
- int more;
- lua_lock(L);
- t = index2adr(L, idx);
- api_check(L, ttistable(t));
- more = luaH_next(L, hvalue(t), L->top - 1);
- if (more) {
- api_incr_top(L);
- }
- else /* no more elements */
- L->top -= 1; /* remove key */
- lua_unlock(L);
- return more;
-}
-
-
-LUA_API void lua_concat (lua_State *L, int n) {
- lua_lock(L);
- api_checknelems(L, n);
- if (n >= 2) {
- luaC_checkGC(L);
- luaV_concat(L, n, cast_int(L->top - L->base) - 1);
- L->top -= (n-1);
- }
- else if (n == 0) { /* push empty string */
- setsvalue2s(L, L->top, luaS_newlstr(L, "", 0));
- api_incr_top(L);
- }
- /* else n == 1; nothing to do */
- lua_unlock(L);
-}
-
-
-LUA_API lua_Alloc lua_getallocf (lua_State *L, void **ud) {
- lua_Alloc f;
- lua_lock(L);
- if (ud) *ud = G(L)->ud;
- f = G(L)->frealloc;
- lua_unlock(L);
- return f;
-}
-
-
-LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud) {
- lua_lock(L);
- G(L)->ud = ud;
- G(L)->frealloc = f;
- lua_unlock(L);
-}
-
-
-LUA_API void *lua_newuserdata (lua_State *L, size_t size) {
- Udata *u;
- lua_lock(L);
- luaC_checkGC(L);
- u = luaS_newudata(L, size, getcurrenv(L));
- setuvalue(L, L->top, u);
- api_incr_top(L);
- lua_unlock(L);
- return u + 1;
-}
-
-
-
-
-static const char *aux_upvalue (StkId fi, int n, TValue **val) {
- Closure *f;
- if (!ttisfunction(fi)) return NULL;
- f = clvalue(fi);
- if (f->c.isC) {
- if (!(1 <= n && n <= f->c.nupvalues)) return NULL;
- *val = &f->c.upvalue[n-1];
- return "";
- }
- else {
- Proto *p = f->l.p;
- if (!(1 <= n && n <= p->sizeupvalues)) return NULL;
- *val = f->l.upvals[n-1]->v;
- return getstr(p->upvalues[n-1]);
- }
-}
-
-
-LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) {
- const char *name;
- TValue *val;
- lua_lock(L);
- name = aux_upvalue(index2adr(L, funcindex), n, &val);
- if (name) {
- setobj2s(L, L->top, val);
- api_incr_top(L);
- }
- lua_unlock(L);
- return name;
-}
-
-
-LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) {
- const char *name;
- TValue *val;
- StkId fi;
- lua_lock(L);
- fi = index2adr(L, funcindex);
- api_checknelems(L, 1);
- name = aux_upvalue(fi, n, &val);
- if (name) {
- L->top--;
- setobj(L, val, L->top);
- luaC_barrier(L, clvalue(fi), L->top);
- }
- lua_unlock(L);
- return name;
-}
-
diff --git a/crawl-ref/source/util/lua/src/lapi.h b/crawl-ref/source/util/lua/src/lapi.h
deleted file mode 100644
index 2c3fab244e..0000000000
--- a/crawl-ref/source/util/lua/src/lapi.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
-** $Id: lapi.h,v 2.2.1.1 2007/12/27 13:02:25 roberto Exp $
-** Auxiliary functions from Lua API
-** See Copyright Notice in lua.h
-*/
-
-#ifndef lapi_h
-#define lapi_h
-
-
-#include "lobject.h"
-
-
-LUAI_FUNC void luaA_pushobject (lua_State *L, const TValue *o);
-
-#endif
diff --git a/crawl-ref/source/util/lua/src/lauxlib.c b/crawl-ref/source/util/lua/src/lauxlib.c
deleted file mode 100644
index 10f14e2c08..0000000000
--- a/crawl-ref/source/util/lua/src/lauxlib.c
+++ /dev/null
@@ -1,652 +0,0 @@
-/*
-** $Id: lauxlib.c,v 1.159.1.3 2008/01/21 13:20:51 roberto Exp $
-** Auxiliary functions for building Lua libraries
-** See Copyright Notice in lua.h
-*/
-
-
-#include <ctype.h>
-#include <errno.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-
-/* This file uses only the official API of Lua.
-** Any function declared here could be written as an application function.
-*/
-
-#define lauxlib_c
-#define LUA_LIB
-
-#include "lua.h"
-
-#include "lauxlib.h"
-
-
-#define FREELIST_REF 0 /* free list of references */
-
-
-/* convert a stack index to positive */
-#define abs_index(L, i) ((i) > 0 || (i) <= LUA_REGISTRYINDEX ? (i) : \
- lua_gettop(L) + (i) + 1)
-
-
-/*
-** {======================================================
-** Error-report functions
-** =======================================================
-*/
-
-
-LUALIB_API int luaL_argerror (lua_State *L, int narg, const char *extramsg) {
- lua_Debug ar;
- if (!lua_getstack(L, 0, &ar)) /* no stack frame? */
- return luaL_error(L, "bad argument #%d (%s)", narg, extramsg);
- lua_getinfo(L, "n", &ar);
- if (strcmp(ar.namewhat, "method") == 0) {
- narg--; /* do not count `self' */
- if (narg == 0) /* error is in the self argument itself? */
- return luaL_error(L, "calling " LUA_QS " on bad self (%s)",
- ar.name, extramsg);
- }
- if (ar.name == NULL)
- ar.name = "?";
- return luaL_error(L, "bad argument #%d to " LUA_QS " (%s)",
- narg, ar.name, extramsg);
-}
-
-
-LUALIB_API int luaL_typerror (lua_State *L, int narg, const char *tname) {
- const char *msg = lua_pushfstring(L, "%s expected, got %s",
- tname, luaL_typename(L, narg));
- return luaL_argerror(L, narg, msg);
-}
-
-
-static void tag_error (lua_State *L, int narg, int tag) {
- luaL_typerror(L, narg, lua_typename(L, tag));
-}
-
-
-LUALIB_API void luaL_where (lua_State *L, int level) {
- lua_Debug ar;
- if (lua_getstack(L, level, &ar)) { /* check function at level */
- lua_getinfo(L, "Sl", &ar); /* get info about it */
- if (ar.currentline > 0) { /* is there info? */
- lua_pushfstring(L, "%s:%d: ", ar.short_src, ar.currentline);
- return;
- }
- }
- lua_pushliteral(L, ""); /* else, no information available... */
-}
-
-
-LUALIB_API int luaL_error (lua_State *L, const char *fmt, ...) {
- va_list argp;
- va_start(argp, fmt);
- luaL_where(L, 1);
- lua_pushvfstring(L, fmt, argp);
- va_end(argp);
- lua_concat(L, 2);
- return lua_error(L);
-}
-
-/* }====================================================== */
-
-
-LUALIB_API int luaL_checkoption (lua_State *L, int narg, const char *def,
- const char *const lst[]) {
- const char *name = (def) ? luaL_optstring(L, narg, def) :
- luaL_checkstring(L, narg);
- int i;
- for (i=0; lst[i]; i++)
- if (strcmp(lst[i], name) == 0)
- return i;
- return luaL_argerror(L, narg,
- lua_pushfstring(L, "invalid option " LUA_QS, name));
-}
-
-
-LUALIB_API int luaL_newmetatable (lua_State *L, const char *tname) {
- lua_getfield(L, LUA_REGISTRYINDEX, tname); /* get registry.name */
- if (!lua_isnil(L, -1)) /* name already in use? */
- return 0; /* leave previous value on top, but return 0 */
- lua_pop(L, 1);
- lua_newtable(L); /* create metatable */
- lua_pushvalue(L, -1);
- lua_setfield(L, LUA_REGISTRYINDEX, tname); /* registry.name = metatable */
- return 1;
-}
-
-
-LUALIB_API void *luaL_checkudata (lua_State *L, int ud, const char *tname) {
- void *p = lua_touserdata(L, ud);
- if (p != NULL) { /* value is a userdata? */
- if (lua_getmetatable(L, ud)) { /* does it have a metatable? */
- lua_getfield(L, LUA_REGISTRYINDEX, tname); /* get correct metatable */
- if (lua_rawequal(L, -1, -2)) { /* does it have the correct mt? */
- lua_pop(L, 2); /* remove both metatables */
- return p;
- }
- }
- }
- luaL_typerror(L, ud, tname); /* else error */
- return NULL; /* to avoid warnings */
-}
-
-
-LUALIB_API void luaL_checkstack (lua_State *L, int space, const char *mes) {
- if (!lua_checkstack(L, space))
- luaL_error(L, "stack overflow (%s)", mes);
-}
-
-
-LUALIB_API void luaL_checktype (lua_State *L, int narg, int t) {
- if (lua_type(L, narg) != t)
- tag_error(L, narg, t);
-}
-
-
-LUALIB_API void luaL_checkany (lua_State *L, int narg) {
- if (lua_type(L, narg) == LUA_TNONE)
- luaL_argerror(L, narg, "value expected");
-}
-
-
-LUALIB_API const char *luaL_checklstring (lua_State *L, int narg, size_t *len) {
- const char *s = lua_tolstring(L, narg, len);
- if (!s) tag_error(L, narg, LUA_TSTRING);
- return s;
-}
-
-
-LUALIB_API const char *luaL_optlstring (lua_State *L, int narg,
- const char *def, size_t *len) {
- if (lua_isnoneornil(L, narg)) {
- if (len)
- *len = (def ? strlen(def) : 0);
- return def;
- }
- else return luaL_checklstring(L, narg, len);
-}
-
-
-LUALIB_API lua_Number luaL_checknumber (lua_State *L, int narg) {
- lua_Number d = lua_tonumber(L, narg);
- if (d == 0 && !lua_isnumber(L, narg)) /* avoid extra test when d is not 0 */
- tag_error(L, narg, LUA_TNUMBER);
- return d;
-}
-
-
-LUALIB_API lua_Number luaL_optnumber (lua_State *L, int narg, lua_Number def) {
- return luaL_opt(L, luaL_checknumber, narg, def);
-}
-
-
-LUALIB_API lua_Integer luaL_checkinteger (lua_State *L, int narg) {
- lua_Integer d = lua_tointeger(L, narg);
- if (d == 0 && !lua_isnumber(L, narg)) /* avoid extra test when d is not 0 */
- tag_error(L, narg, LUA_TNUMBER);
- return d;
-}
-
-
-LUALIB_API lua_Integer luaL_optinteger (lua_State *L, int narg,
- lua_Integer def) {
- return luaL_opt(L, luaL_checkinteger, narg, def);
-}
-
-
-LUALIB_API int luaL_getmetafield (lua_State *L, int obj, const char *event) {
- if (!lua_getmetatable(L, obj)) /* no metatable? */
- return 0;
- lua_pushstring(L, event);
- lua_rawget(L, -2);
- if (lua_isnil(L, -1)) {
- lua_pop(L, 2); /* remove metatable and metafield */
- return 0;
- }
- else {
- lua_remove(L, -2); /* remove only metatable */
- return 1;
- }
-}
-
-
-LUALIB_API int luaL_callmeta (lua_State *L, int obj, const char *event) {
- obj = abs_index(L, obj);
- if (!luaL_getmetafield(L, obj, event)) /* no metafield? */
- return 0;
- lua_pushvalue(L, obj);
- lua_call(L, 1, 1);
- return 1;
-}
-
-
-LUALIB_API void (luaL_register) (lua_State *L, const char *libname,
- const luaL_Reg *l) {
- luaI_openlib(L, libname, l, 0);
-}
-
-
-static int libsize (const luaL_Reg *l) {
- int size = 0;
- for (; l->name; l++) size++;
- return size;
-}
-
-
-LUALIB_API void luaI_openlib (lua_State *L, const char *libname,
- const luaL_Reg *l, int nup) {
- if (libname) {
- int size = libsize(l);
- /* check whether lib already exists */
- luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 1);
- lua_getfield(L, -1, libname); /* get _LOADED[libname] */
- if (!lua_istable(L, -1)) { /* not found? */
- lua_pop(L, 1); /* remove previous result */
- /* try global variable (and create one if it does not exist) */
- if (luaL_findtable(L, LUA_GLOBALSINDEX, libname, size) != NULL)
- luaL_error(L, "name conflict for module " LUA_QS, libname);
- lua_pushvalue(L, -1);
- lua_setfield(L, -3, libname); /* _LOADED[libname] = new table */
- }
- lua_remove(L, -2); /* remove _LOADED table */
- lua_insert(L, -(nup+1)); /* move library table to below upvalues */
- }
- for (; l->name; l++) {
- int i;
- for (i=0; i<nup; i++) /* copy upvalues to the top */
- lua_pushvalue(L, -nup);
- lua_pushcclosure(L, l->func, nup);
- lua_setfield(L, -(nup+2), l->name);
- }
- lua_pop(L, nup); /* remove upvalues */
-}
-
-
-
-/*
-** {======================================================
-** getn-setn: size for arrays
-** =======================================================
-*/
-
-#if defined(LUA_COMPAT_GETN)
-
-static int checkint (lua_State *L, int topop) {
- int n = (lua_type(L, -1) == LUA_TNUMBER) ? lua_tointeger(L, -1) : -1;
- lua_pop(L, topop);
- return n;
-}
-
-
-static void getsizes (lua_State *L) {
- lua_getfield(L, LUA_REGISTRYINDEX, "LUA_SIZES");
- if (lua_isnil(L, -1)) { /* no `size' table? */
- lua_pop(L, 1); /* remove nil */
- lua_newtable(L); /* create it */
- lua_pushvalue(L, -1); /* `size' will be its own metatable */
- lua_setmetatable(L, -2);
- lua_pushliteral(L, "kv");
- lua_setfield(L, -2, "__mode"); /* metatable(N).__mode = "kv" */
- lua_pushvalue(L, -1);
- lua_setfield(L, LUA_REGISTRYINDEX, "LUA_SIZES"); /* store in register */
- }
-}
-
-
-LUALIB_API void luaL_setn (lua_State *L, int t, int n) {
- t = abs_index(L, t);
- lua_pushliteral(L, "n");
- lua_rawget(L, t);
- if (checkint(L, 1) >= 0) { /* is there a numeric field `n'? */
- lua_pushliteral(L, "n"); /* use it */
- lua_pushinteger(L, n);
- lua_rawset(L, t);
- }
- else { /* use `sizes' */
- getsizes(L);
- lua_pushvalue(L, t);
- lua_pushinteger(L, n);
- lua_rawset(L, -3); /* sizes[t] = n */
- lua_pop(L, 1); /* remove `sizes' */
- }
-}
-
-
-LUALIB_API int luaL_getn (lua_State *L, int t) {
- int n;
- t = abs_index(L, t);
- lua_pushliteral(L, "n"); /* try t.n */
- lua_rawget(L, t);
- if ((n = checkint(L, 1)) >= 0) return n;
- getsizes(L); /* else try sizes[t] */
- lua_pushvalue(L, t);
- lua_rawget(L, -2);
- if ((n = checkint(L, 2)) >= 0) return n;
- return (int)lua_objlen(L, t);
-}
-
-#endif
-
-/* }====================================================== */
-
-
-
-LUALIB_API const char *luaL_gsub (lua_State *L, const char *s, const char *p,
- const char *r) {
- const char *wild;
- size_t l = strlen(p);
- luaL_Buffer b;
- luaL_buffinit(L, &b);
- while ((wild = strstr(s, p)) != NULL) {
- luaL_addlstring(&b, s, wild - s); /* push prefix */
- luaL_addstring(&b, r); /* push replacement in place of pattern */
- s = wild + l; /* continue after `p' */
- }
- luaL_addstring(&b, s); /* push last suffix */
- luaL_pushresult(&b);
- return lua_tostring(L, -1);
-}
-
-
-LUALIB_API const char *luaL_findtable (lua_State *L, int idx,
- const char *fname, int szhint) {
- const char *e;
- lua_pushvalue(L, idx);
- do {
- e = strchr(fname, '.');
- if (e == NULL) e = fname + strlen(fname);
- lua_pushlstring(L, fname, e - fname);
- lua_rawget(L, -2);
- if (lua_isnil(L, -1)) { /* no such field? */
- lua_pop(L, 1); /* remove this nil */
- lua_createtable(L, 0, (*e == '.' ? 1 : szhint)); /* new table for field */
- lua_pushlstring(L, fname, e - fname);
- lua_pushvalue(L, -2);
- lua_settable(L, -4); /* set new table into field */
- }
- else if (!lua_istable(L, -1)) { /* field has a non-table value? */
- lua_pop(L, 2); /* remove table and value */
- return fname; /* return problematic part of the name */
- }
- lua_remove(L, -2); /* remove previous table */
- fname = e + 1;
- } while (*e == '.');
- return NULL;
-}
-
-
-
-/*
-** {======================================================
-** Generic Buffer manipulation
-** =======================================================
-*/
-
-
-#define bufflen(B) ((B)->p - (B)->buffer)
-#define bufffree(B) ((size_t)(LUAL_BUFFERSIZE - bufflen(B)))
-
-#define LIMIT (LUA_MINSTACK/2)
-
-
-static int emptybuffer (luaL_Buffer *B) {
- size_t l = bufflen(B);
- if (l == 0) return 0; /* put nothing on stack */
- else {
- lua_pushlstring(B->L, B->buffer, l);
- B->p = B->buffer;
- B->lvl++;
- return 1;
- }
-}
-
-
-static void adjuststack (luaL_Buffer *B) {
- if (B->lvl > 1) {
- lua_State *L = B->L;
- int toget = 1; /* number of levels to concat */
- size_t toplen = lua_strlen(L, -1);
- do {
- size_t l = lua_strlen(L, -(toget+1));
- if (B->lvl - toget + 1 >= LIMIT || toplen > l) {
- toplen += l;
- toget++;
- }
- else break;
- } while (toget < B->lvl);
- lua_concat(L, toget);
- B->lvl = B->lvl - toget + 1;
- }
-}
-
-
-LUALIB_API char *luaL_prepbuffer (luaL_Buffer *B) {
- if (emptybuffer(B))
- adjuststack(B);
- return B->buffer;
-}
-
-
-LUALIB_API void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l) {
- while (l--)
- luaL_addchar(B, *s++);
-}
-
-
-LUALIB_API void luaL_addstring (luaL_Buffer *B, const char *s) {
- luaL_addlstring(B, s, strlen(s));
-}
-
-
-LUALIB_API void luaL_pushresult (luaL_Buffer *B) {
- emptybuffer(B);
- lua_concat(B->L, B->lvl);
- B->lvl = 1;
-}
-
-
-LUALIB_API void luaL_addvalue (luaL_Buffer *B) {
- lua_State *L = B->L;
- size_t vl;
- const char *s = lua_tolstring(L, -1, &vl);
- if (vl <= bufffree(B)) { /* fit into buffer? */
- memcpy(B->p, s, vl); /* put it there */
- B->p += vl;
- lua_pop(L, 1); /* remove from stack */
- }
- else {
- if (emptybuffer(B))
- lua_insert(L, -2); /* put buffer before new value */
- B->lvl++; /* add new value into B stack */
- adjuststack(B);
- }
-}
-
-
-LUALIB_API void luaL_buffinit (lua_State *L, luaL_Buffer *B) {
- B->L = L;
- B->p = B->buffer;
- B->lvl = 0;
-}
-
-/* }====================================================== */
-
-
-LUALIB_API int luaL_ref (lua_State *L, int t) {
- int ref;
- t = abs_index(L, t);
- if (lua_isnil(L, -1)) {
- lua_pop(L, 1); /* remove from stack */
- return LUA_REFNIL; /* `nil' has a unique fixed reference */
- }
- lua_rawgeti(L, t, FREELIST_REF); /* get first free element */
- ref = (int)lua_tointeger(L, -1); /* ref = t[FREELIST_REF] */
- lua_pop(L, 1); /* remove it from stack */
- if (ref != 0) { /* any free element? */
- lua_rawgeti(L, t, ref); /* remove it from list */
- lua_rawseti(L, t, FREELIST_REF); /* (t[FREELIST_REF] = t[ref]) */
- }
- else { /* no free elements */
- ref = (int)lua_objlen(L, t);
- ref++; /* create new reference */
- }
- lua_rawseti(L, t, ref);
- return ref;
-}
-
-
-LUALIB_API void luaL_unref (lua_State *L, int t, int ref) {
- if (ref >= 0) {
- t = abs_index(L, t);
- lua_rawgeti(L, t, FREELIST_REF);
- lua_rawseti(L, t, ref); /* t[ref] = t[FREELIST_REF] */
- lua_pushinteger(L, ref);
- lua_rawseti(L, t, FREELIST_REF); /* t[FREELIST_REF] = ref */
- }
-}
-
-
-
-/*
-** {======================================================
-** Load functions
-** =======================================================
-*/
-
-typedef struct LoadF {
- int extraline;
- FILE *f;
- char buff[LUAL_BUFFERSIZE];
-} LoadF;
-
-
-static const char *getF (lua_State *L, void *ud, size_t *size) {
- LoadF *lf = (LoadF *)ud;
- (void)L;
- if (lf->extraline) {
- lf->extraline = 0;
- *size = 1;
- return "\n";
- }
- if (feof(lf->f)) return NULL;
- *size = fread(lf->buff, 1, sizeof(lf->buff), lf->f);
- return (*size > 0) ? lf->buff : NULL;
-}
-
-
-static int errfile (lua_State *L, const char *what, int fnameindex) {
- const char *serr = strerror(errno);
- const char *filename = lua_tostring(L, fnameindex) + 1;
- lua_pushfstring(L, "cannot %s %s: %s", what, filename, serr);
- lua_remove(L, fnameindex);
- return LUA_ERRFILE;
-}
-
-
-LUALIB_API int luaL_loadfile (lua_State *L, const char *filename) {
- LoadF lf;
- int status, readstatus;
- int c;
- int fnameindex = lua_gettop(L) + 1; /* index of filename on the stack */
- lf.extraline = 0;
- if (filename == NULL) {
- lua_pushliteral(L, "=stdin");
- lf.f = stdin;
- }
- else {
- lua_pushfstring(L, "@%s", filename);
- lf.f = fopen(filename, "r");
- if (lf.f == NULL) return errfile(L, "open", fnameindex);
- }
- c = getc(lf.f);
- if (c == '#') { /* Unix exec. file? */
- lf.extraline = 1;
- while ((c = getc(lf.f)) != EOF && c != '\n') ; /* skip first line */
- if (c == '\n') c = getc(lf.f);
- }
- if (c == LUA_SIGNATURE[0] && filename) { /* binary file? */
- lf.f = freopen(filename, "rb", lf.f); /* reopen in binary mode */
- if (lf.f == NULL) return errfile(L, "reopen", fnameindex);
- /* skip eventual `#!...' */
- while ((c = getc(lf.f)) != EOF && c != LUA_SIGNATURE[0]) ;
- lf.extraline = 0;
- }
- ungetc(c, lf.f);
- status = lua_load(L, getF, &lf, lua_tostring(L, -1));
- readstatus = ferror(lf.f);
- if (filename) fclose(lf.f); /* close file (even in case of errors) */
- if (readstatus) {
- lua_settop(L, fnameindex); /* ignore results from `lua_load' */
- return errfile(L, "read", fnameindex);
- }
- lua_remove(L, fnameindex);
- return status;
-}
-
-
-typedef struct LoadS {
- const char *s;
- size_t size;
-} LoadS;
-
-
-static const char *getS (lua_State *L, void *ud, size_t *size) {
- LoadS *ls = (LoadS *)ud;
- (void)L;
- if (ls->size == 0) return NULL;
- *size = ls->size;
- ls->size = 0;
- return ls->s;
-}
-
-
-LUALIB_API int luaL_loadbuffer (lua_State *L, const char *buff, size_t size,
- const char *name) {
- LoadS ls;
- ls.s = buff;
- ls.size = size;
- return lua_load(L, getS, &ls, name);
-}
-
-
-LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s) {
- return luaL_loadbuffer(L, s, strlen(s), s);
-}
-
-
-
-/* }====================================================== */
-
-
-static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) {
- (void)ud;
- (void)osize;
- if (nsize == 0) {
- free(ptr);
- return NULL;
- }
- else
- return realloc(ptr, nsize);
-}
-
-
-static int panic (lua_State *L) {
- (void)L; /* to avoid warnings */
- fprintf(stderr, "PANIC: unprotected error in call to Lua API (%s)\n",
- lua_tostring(L, -1));
- return 0;
-}
-
-
-LUALIB_API lua_State *luaL_newstate (void) {
- lua_State *L = lua_newstate(l_alloc, NULL);
- if (L) lua_atpanic(L, &panic);
- return L;
-}
-
diff --git a/crawl-ref/source/util/lua/src/lauxlib.h b/crawl-ref/source/util/lua/src/lauxlib.h
deleted file mode 100644
index 34258235db..0000000000
--- a/crawl-ref/source/util/lua/src/lauxlib.h
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
-** $Id: lauxlib.h,v 1.88.1.1 2007/12/27 13:02:25 roberto Exp $
-** Auxiliary functions for building Lua libraries
-** See Copyright Notice in lua.h
-*/
-
-
-#ifndef lauxlib_h
-#define lauxlib_h
-
-
-#include <stddef.h>
-#include <stdio.h>
-
-#include "lua.h"
-
-
-#if defined(LUA_COMPAT_GETN)
-LUALIB_API int (luaL_getn) (lua_State *L, int t);
-LUALIB_API void (luaL_setn) (lua_State *L, int t, int n);
-#else
-#define luaL_getn(L,i) ((int)lua_objlen(L, i))
-#define luaL_setn(L,i,j) ((void)0) /* no op! */
-#endif
-
-#if defined(LUA_COMPAT_OPENLIB)
-#define luaI_openlib luaL_openlib
-#endif
-
-
-/* extra error code for `luaL_load' */
-#define LUA_ERRFILE (LUA_ERRERR+1)
-
-
-typedef struct luaL_Reg {
- const char *name;
- lua_CFunction func;
-} luaL_Reg;
-
-
-
-LUALIB_API void (luaI_openlib) (lua_State *L, const char *libname,
- const luaL_Reg *l, int nup);
-LUALIB_API void (luaL_register) (lua_State *L, const char *libname,
- const luaL_Reg *l);
-LUALIB_API int (luaL_getmetafield) (lua_State *L, int obj, const char *e);
-LUALIB_API int (luaL_callmeta) (lua_State *L, int obj, const char *e);
-LUALIB_API int (luaL_typerror) (lua_State *L, int narg, const char *tname);
-LUALIB_API int (luaL_argerror) (lua_State *L, int numarg, const char *extramsg);
-LUALIB_API const char *(luaL_checklstring) (lua_State *L, int numArg,
- size_t *l);
-LUALIB_API const char *(luaL_optlstring) (lua_State *L, int numArg,
- const char *def, size_t *l);
-LUALIB_API lua_Number (luaL_checknumber) (lua_State *L, int numArg);
-LUALIB_API lua_Number (luaL_optnumber) (lua_State *L, int nArg, lua_Number def);
-
-LUALIB_API lua_Integer (luaL_checkinteger) (lua_State *L, int numArg);
-LUALIB_API lua_Integer (luaL_optinteger) (lua_State *L, int nArg,
- lua_Integer def);
-
-LUALIB_API void (luaL_checkstack) (lua_State *L, int sz, const char *msg);
-LUALIB_API void (luaL_checktype) (lua_State *L, int narg, int t);
-LUALIB_API void (luaL_checkany) (lua_State *L, int narg);
-
-LUALIB_API int (luaL_newmetatable) (lua_State *L, const char *tname);
-LUALIB_API void *(luaL_checkudata) (lua_State *L, int ud, const char *tname);
-
-LUALIB_API void (luaL_where) (lua_State *L, int lvl);
-LUALIB_API int (luaL_error) (lua_State *L, const char *fmt, ...);
-
-LUALIB_API int (luaL_checkoption) (lua_State *L, int narg, const char *def,
- const char *const lst[]);
-
-LUALIB_API int (luaL_ref) (lua_State *L, int t);
-LUALIB_API void (luaL_unref) (lua_State *L, int t, int ref);
-
-LUALIB_API int (luaL_loadfile) (lua_State *L, const char *filename);
-LUALIB_API int (luaL_loadbuffer) (lua_State *L, const char *buff, size_t sz,
- const char *name);
-LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s);
-
-LUALIB_API lua_State *(luaL_newstate) (void);
-
-
-LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s, const char *p,
- const char *r);
-
-LUALIB_API const char *(luaL_findtable) (lua_State *L, int idx,
- const char *fname, int szhint);
-
-
-
-
-/*
-** ===============================================================
-** some useful macros
-** ===============================================================
-*/
-
-#define luaL_argcheck(L, cond,numarg,extramsg) \
- ((void)((cond) || luaL_argerror(L, (numarg), (extramsg))))
-#define luaL_checkstring(L,n) (luaL_checklstring(L, (n), NULL))
-#define luaL_optstring(L,n,d) (luaL_optlstring(L, (n), (d), NULL))
-#define luaL_checkint(L,n) ((int)luaL_checkinteger(L, (n)))
-#define luaL_optint(L,n,d) ((int)luaL_optinteger(L, (n), (d)))
-#define luaL_checklong(L,n) ((long)luaL_checkinteger(L, (n)))
-#define luaL_optlong(L,n,d) ((long)luaL_optinteger(L, (n), (d)))
-
-#define luaL_typename(L,i) lua_typename(L, lua_type(L,(i)))
-
-#define luaL_dofile(L, fn) \
- (luaL_loadfile(L, fn) || lua_pcall(L, 0, LUA_MULTRET, 0))
-
-#define luaL_dostring(L, s) \
- (luaL_loadstring(L, s) || lua_pcall(L, 0, LUA_MULTRET, 0))
-
-#define luaL_getmetatable(L,n) (lua_getfield(L, LUA_REGISTRYINDEX, (n)))
-
-#define luaL_opt(L,f,n,d) (lua_isnoneornil(L,(n)) ? (d) : f(L,(n)))
-
-/*
-** {======================================================
-** Generic Buffer manipulation
-** =======================================================
-*/
-
-
-
-typedef struct luaL_Buffer {
- char *p; /* current position in buffer */
- int lvl; /* number of strings in the stack (level) */
- lua_State *L;
- char buffer[LUAL_BUFFERSIZE];
-} luaL_Buffer;
-
-#define luaL_addchar(B,c) \
- ((void)((B)->p < ((B)->buffer+LUAL_BUFFERSIZE) || luaL_prepbuffer(B)), \
- (*(B)->p++ = (char)(c)))
-
-/* compatibility only */
-#define luaL_putchar(B,c) luaL_addchar(B,c)
-
-#define luaL_addsize(B,n) ((B)->p += (n))
-
-LUALIB_API void (luaL_buffinit) (lua_State *L, luaL_Buffer *B);
-LUALIB_API char *(luaL_prepbuffer) (luaL_Buffer *B);
-LUALIB_API void (luaL_addlstring) (luaL_Buffer *B, const char *s, size_t l);
-LUALIB_API void (luaL_addstring) (luaL_Buffer *B, const char *s);
-LUALIB_API void (luaL_addvalue) (luaL_Buffer *B);
-LUALIB_API void (luaL_pushresult) (luaL_Buffer *B);
-
-
-/* }====================================================== */
-
-
-/* compatibility with ref system */
-
-/* pre-defined references */
-#define LUA_NOREF (-2)
-#define LUA_REFNIL (-1)
-
-#define lua_ref(L,lock) ((lock) ? luaL_ref(L, LUA_REGISTRYINDEX) : \
- (lua_pushstring(L, "unlocked references are obsolete"), lua_error(L), 0))
-
-#define lua_unref(L,ref) luaL_unref(L, LUA_REGISTRYINDEX, (ref))
-
-#define lua_getref(L,ref) lua_rawgeti(L, LUA_REGISTRYINDEX, (ref))
-
-
-#define luaL_reg luaL_Reg
-
-#endif
-
-
diff --git a/crawl-ref/source/util/lua/src/lbaselib.c b/crawl-ref/source/util/lua/src/lbaselib.c
deleted file mode 100644
index 2a4c079d3b..0000000000
--- a/crawl-ref/source/util/lua/src/lbaselib.c
+++ /dev/null
@@ -1,653 +0,0 @@
-/*
-** $Id: lbaselib.c,v 1.191.1.6 2008/02/14 16:46:22 roberto Exp $
-** Basic library
-** See Copyright Notice in lua.h
-*/
-
-
-
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#define lbaselib_c
-#define LUA_LIB
-
-#include "lua.h"
-
-#include "lauxlib.h"
-#include "lualib.h"
-
-
-
-
-/*
-** If your system does not support `stdout', you can just remove this function.
-** If you need, you can define your own `print' function, following this
-** model but changing `fputs' to put the strings at a proper place
-** (a console window or a log file, for instance).
-*/
-static int luaB_print (lua_State *L) {
- int n = lua_gettop(L); /* number of arguments */
- int i;
- lua_getglobal(L, "tostring");
- for (i=1; i<=n; i++) {
- const char *s;
- lua_pushvalue(L, -1); /* function to be called */
- lua_pushvalue(L, i); /* value to print */
- lua_call(L, 1, 1);
- s = lua_tostring(L, -1); /* get result */
- if (s == NULL)
- return luaL_error(L, LUA_QL("tostring") " must return a string to "
- LUA_QL("print"));
- if (i>1) fputs("\t", stdout);
- fputs(s, stdout);
- lua_pop(L, 1); /* pop result */
- }
- fputs("\n", stdout);
- return 0;
-}
-
-
-static int luaB_tonumber (lua_State *L) {
- int base = luaL_optint(L, 2, 10);
- if (base == 10) { /* standard conversion */
- luaL_checkany(L, 1);
- if (lua_isnumber(L, 1)) {
- lua_pushnumber(L, lua_tonumber(L, 1));
- return 1;
- }
- }
- else {
- const char *s1 = luaL_checkstring(L, 1);
- char *s2;
- unsigned long n;
- luaL_argcheck(L, 2 <= base && base <= 36, 2, "base out of range");
- n = strtoul(s1, &s2, base);
- if (s1 != s2) { /* at least one valid digit? */
- while (isspace((unsigned char)(*s2))) s2++; /* skip trailing spaces */
- if (*s2 == '\0') { /* no invalid trailing characters? */
- lua_pushnumber(L, (lua_Number)n);
- return 1;
- }
- }
- }
- lua_pushnil(L); /* else not a number */
- return 1;
-}
-
-
-static int luaB_error (lua_State *L) {
- int level = luaL_optint(L, 2, 1);
- lua_settop(L, 1);
- if (lua_isstring(L, 1) && level > 0) { /* add extra information? */
- luaL_where(L, level);
- lua_pushvalue(L, 1);
- lua_concat(L, 2);
- }
- return lua_error(L);
-}
-
-
-static int luaB_getmetatable (lua_State *L) {
- luaL_checkany(L, 1);
- if (!lua_getmetatable(L, 1)) {
- lua_pushnil(L);
- return 1; /* no metatable */
- }
- luaL_getmetafield(L, 1, "__metatable");
- return 1; /* returns either __metatable field (if present) or metatable */
-}
-
-
-static int luaB_setmetatable (lua_State *L) {
- int t = lua_type(L, 2);
- luaL_checktype(L, 1, LUA_TTABLE);
- luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2,
- "nil or table expected");
- if (luaL_getmetafield(L, 1, "__metatable"))
- luaL_error(L, "cannot change a protected metatable");
- lua_settop(L, 2);
- lua_setmetatable(L, 1);
- return 1;
-}
-
-
-static void getfunc (lua_State *L, int opt) {
- if (lua_isfunction(L, 1)) lua_pushvalue(L, 1);
- else {
- lua_Debug ar;
- int level = opt ? luaL_optint(L, 1, 1) : luaL_checkint(L, 1);
- luaL_argcheck(L, level >= 0, 1, "level must be non-negative");
- if (lua_getstack(L, level, &ar) == 0)
- luaL_argerror(L, 1, "invalid level");
- lua_getinfo(L, "f", &ar);
- if (lua_isnil(L, -1))
- luaL_error(L, "no function environment for tail call at level %d",
- level);
- }
-}
-
-
-static int luaB_getfenv (lua_State *L) {
- getfunc(L, 1);
- if (lua_iscfunction(L, -1)) /* is a C function? */
- lua_pushvalue(L, LUA_GLOBALSINDEX); /* return the thread's global env. */
- else
- lua_getfenv(L, -1);
- return 1;
-}
-
-
-static int luaB_setfenv (lua_State *L) {
- luaL_checktype(L, 2, LUA_TTABLE);
- getfunc(L, 0);
- lua_pushvalue(L, 2);
- if (lua_isnumber(L, 1) && lua_tonumber(L, 1) == 0) {
- /* change environment of current thread */
- lua_pushthread(L);
- lua_insert(L, -2);
- lua_setfenv(L, -2);
- return 0;
- }
- else if (lua_iscfunction(L, -2) || lua_setfenv(L, -2) == 0)
- luaL_error(L,
- LUA_QL("setfenv") " cannot change environment of given object");
- return 1;
-}
-
-
-static int luaB_rawequal (lua_State *L) {
- luaL_checkany(L, 1);
- luaL_checkany(L, 2);
- lua_pushboolean(L, lua_rawequal(L, 1, 2));
- return 1;
-}
-
-
-static int luaB_rawget (lua_State *L) {
- luaL_checktype(L, 1, LUA_TTABLE);
- luaL_checkany(L, 2);
- lua_settop(L, 2);
- lua_rawget(L, 1);
- return 1;
-}
-
-static int luaB_rawset (lua_State *L) {
- luaL_checktype(L, 1, LUA_TTABLE);
- luaL_checkany(L, 2);
- luaL_checkany(L, 3);
- lua_settop(L, 3);
- lua_rawset(L, 1);
- return 1;
-}
-
-
-static int luaB_gcinfo (lua_State *L) {
- lua_pushinteger(L, lua_getgccount(L));
- return 1;
-}
-
-
-static int luaB_collectgarbage (lua_State *L) {
- static const char *const opts[] = {"stop", "restart", "collect",
- "count", "step", "setpause", "setstepmul", NULL};
- static const int optsnum[] = {LUA_GCSTOP, LUA_GCRESTART, LUA_GCCOLLECT,
- LUA_GCCOUNT, LUA_GCSTEP, LUA_GCSETPAUSE, LUA_GCSETSTEPMUL};
- int o = luaL_checkoption(L, 1, "collect", opts);
- int ex = luaL_optint(L, 2, 0);
- int res = lua_gc(L, optsnum[o], ex);
- switch (optsnum[o]) {
- case LUA_GCCOUNT: {
- int b = lua_gc(L, LUA_GCCOUNTB, 0);
- lua_pushnumber(L, res + ((lua_Number)b/1024));
- return 1;
- }
- case LUA_GCSTEP: {
- lua_pushboolean(L, res);
- return 1;
- }
- default: {
- lua_pushnumber(L, res);
- return 1;
- }
- }
-}
-
-
-static int luaB_type (lua_State *L) {
- luaL_checkany(L, 1);
- lua_pushstring(L, luaL_typename(L, 1));
- return 1;
-}
-
-
-static int luaB_next (lua_State *L) {
- luaL_checktype(L, 1, LUA_TTABLE);
- lua_settop(L, 2); /* create a 2nd argument if there isn't one */
- if (lua_next(L, 1))
- return 2;
- else {
- lua_pushnil(L);
- return 1;
- }
-}
-
-
-static int luaB_pairs (lua_State *L) {
- luaL_checktype(L, 1, LUA_TTABLE);
- lua_pushvalue(L, lua_upvalueindex(1)); /* return generator, */
- lua_pushvalue(L, 1); /* state, */
- lua_pushnil(L); /* and initial value */
- return 3;
-}
-
-
-static int ipairsaux (lua_State *L) {
- int i = luaL_checkint(L, 2);
- luaL_checktype(L, 1, LUA_TTABLE);
- i++; /* next value */
- lua_pushinteger(L, i);
- lua_rawgeti(L, 1, i);
- return (lua_isnil(L, -1)) ? 0 : 2;
-}
-
-
-static int luaB_ipairs (lua_State *L) {
- luaL_checktype(L, 1, LUA_TTABLE);
- lua_pushvalue(L, lua_upvalueindex(1)); /* return generator, */
- lua_pushvalue(L, 1); /* state, */
- lua_pushinteger(L, 0); /* and initial value */
- return 3;
-}
-
-
-static int load_aux (lua_State *L, int status) {
- if (status == 0) /* OK? */
- return 1;
- else {
- lua_pushnil(L);
- lua_insert(L, -2); /* put before error message */
- return 2; /* return nil plus error message */
- }
-}
-
-
-static int luaB_loadstring (lua_State *L) {
- size_t l;
- const char *s = luaL_checklstring(L, 1, &l);
- const char *chunkname = luaL_optstring(L, 2, s);
- return load_aux(L, luaL_loadbuffer(L, s, l, chunkname));
-}
-
-
-static int luaB_loadfile (lua_State *L) {
- const char *fname = luaL_optstring(L, 1, NULL);
- return load_aux(L, luaL_loadfile(L, fname));
-}
-
-
-/*
-** Reader for generic `load' function: `lua_load' uses the
-** stack for internal stuff, so the reader cannot change the
-** stack top. Instead, it keeps its resulting string in a
-** reserved slot inside the stack.
-*/
-static const char *generic_reader (lua_State *L, void *ud, size_t *size) {
- (void)ud; /* to avoid warnings */
- luaL_checkstack(L, 2, "too many nested functions");
- lua_pushvalue(L, 1); /* get function */
- lua_call(L, 0, 1); /* call it */
- if (lua_isnil(L, -1)) {
- *size = 0;
- return NULL;
- }
- else if (lua_isstring(L, -1)) {
- lua_replace(L, 3); /* save string in a reserved stack slot */
- return lua_tolstring(L, 3, size);
- }
- else luaL_error(L, "reader function must return a string");
- return NULL; /* to avoid warnings */
-}
-
-
-static int luaB_load (lua_State *L) {
- int status;
- const char *cname = luaL_optstring(L, 2, "=(load)");
- luaL_checktype(L, 1, LUA_TFUNCTION);
- lua_settop(L, 3); /* function, eventual name, plus one reserved slot */
- status = lua_load(L, generic_reader, NULL, cname);
- return load_aux(L, status);
-}
-
-
-static int luaB_dofile (lua_State *L) {
- const char *fname = luaL_optstring(L, 1, NULL);
- int n = lua_gettop(L);
- if (luaL_loadfile(L, fname) != 0) lua_error(L);
- lua_call(L, 0, LUA_MULTRET);
- return lua_gettop(L) - n;
-}
-
-
-static int luaB_assert (lua_State *L) {
- luaL_checkany(L, 1);
- if (!lua_toboolean(L, 1))
- return luaL_error(L, "%s", luaL_optstring(L, 2, "assertion failed!"));
- return lua_gettop(L);
-}
-
-
-static int luaB_unpack (lua_State *L) {
- int i, e, n;
- luaL_checktype(L, 1, LUA_TTABLE);
- i = luaL_optint(L, 2, 1);
- e = luaL_opt(L, luaL_checkint, 3, luaL_getn(L, 1));
- if (i > e) return 0; /* empty range */
- n = e - i + 1; /* number of elements */
- if (n <= 0 || !lua_checkstack(L, n)) /* n <= 0 means arith. overflow */
- return luaL_error(L, "too many results to unpack");
- lua_rawgeti(L, 1, i); /* push arg[i] (avoiding overflow problems) */
- while (i++ < e) /* push arg[i + 1...e] */
- lua_rawgeti(L, 1, i);
- return n;
-}
-
-
-static int luaB_select (lua_State *L) {
- int n = lua_gettop(L);
- if (lua_type(L, 1) == LUA_TSTRING && *lua_tostring(L, 1) == '#') {
- lua_pushinteger(L, n-1);
- return 1;
- }
- else {
- int i = luaL_checkint(L, 1);
- if (i < 0) i = n + i;
- else if (i > n) i = n;
- luaL_argcheck(L, 1 <= i, 1, "index out of range");
- return n - i;
- }
-}
-
-
-static int luaB_pcall (lua_State *L) {
- int status;
- luaL_checkany(L, 1);
- status = lua_pcall(L, lua_gettop(L) - 1, LUA_MULTRET, 0);
- lua_pushboolean(L, (status == 0));
- lua_insert(L, 1);
- return lua_gettop(L); /* return status + all results */
-}
-
-
-static int luaB_xpcall (lua_State *L) {
- int status;
- luaL_checkany(L, 2);
- lua_settop(L, 2);
- lua_insert(L, 1); /* put error function under function to be called */
- status = lua_pcall(L, 0, LUA_MULTRET, 1);
- lua_pushboolean(L, (status == 0));
- lua_replace(L, 1);
- return lua_gettop(L); /* return status + all results */
-}
-
-
-static int luaB_tostring (lua_State *L) {
- luaL_checkany(L, 1);
- if (luaL_callmeta(L, 1, "__tostring")) /* is there a metafield? */
- return 1; /* use its value */
- switch (lua_type(L, 1)) {
- case LUA_TNUMBER:
- lua_pushstring(L, lua_tostring(L, 1));
- break;
- case LUA_TSTRING:
- lua_pushvalue(L, 1);
- break;
- case LUA_TBOOLEAN:
- lua_pushstring(L, (lua_toboolean(L, 1) ? "true" : "false"));
- break;
- case LUA_TNIL:
- lua_pushliteral(L, "nil");
- break;
- default:
- lua_pushfstring(L, "%s: %p", luaL_typename(L, 1), lua_topointer(L, 1));
- break;
- }
- return 1;
-}
-
-
-static int luaB_newproxy (lua_State *L) {
- lua_settop(L, 1);
- lua_newuserdata(L, 0); /* create proxy */
- if (lua_toboolean(L, 1) == 0)
- return 1; /* no metatable */
- else if (lua_isboolean(L, 1)) {
- lua_newtable(L); /* create a new metatable `m' ... */
- lua_pushvalue(L, -1); /* ... and mark `m' as a valid metatable */
- lua_pushboolean(L, 1);
- lua_rawset(L, lua_upvalueindex(1)); /* weaktable[m] = true */
- }
- else {
- int validproxy = 0; /* to check if weaktable[metatable(u)] == true */
- if (lua_getmetatable(L, 1)) {
- lua_rawget(L, lua_upvalueindex(1));
- validproxy = lua_toboolean(L, -1);
- lua_pop(L, 1); /* remove value */
- }
- luaL_argcheck(L, validproxy, 1, "boolean or proxy expected");
- lua_getmetatable(L, 1); /* metatable is valid; get it */
- }
- lua_setmetatable(L, 2);
- return 1;
-}
-
-
-static const luaL_Reg base_funcs[] = {
- {"assert", luaB_assert},
- {"collectgarbage", luaB_collectgarbage},
- {"dofile", luaB_dofile},
- {"error", luaB_error},
- {"gcinfo", luaB_gcinfo},
- {"getfenv", luaB_getfenv},
- {"getmetatable", luaB_getmetatable},
- {"loadfile", luaB_loadfile},
- {"load", luaB_load},
- {"loadstring", luaB_loadstring},
- {"next", luaB_next},
- {"pcall", luaB_pcall},
- {"print", luaB_print},
- {"rawequal", luaB_rawequal},
- {"rawget", luaB_rawget},
- {"rawset", luaB_rawset},
- {"select", luaB_select},
- {"setfenv", luaB_setfenv},
- {"setmetatable", luaB_setmetatable},
- {"tonumber", luaB_tonumber},
- {"tostring", luaB_tostring},
- {"type", luaB_type},
- {"unpack", luaB_unpack},
- {"xpcall", luaB_xpcall},
- {NULL, NULL}
-};
-
-
-/*
-** {======================================================
-** Coroutine library
-** =======================================================
-*/
-
-#define CO_RUN 0 /* running */
-#define CO_SUS 1 /* suspended */
-#define CO_NOR 2 /* 'normal' (it resumed another coroutine) */
-#define CO_DEAD 3
-
-static const char *const statnames[] =
- {"running", "suspended", "normal", "dead"};
-
-static int costatus (lua_State *L, lua_State *co) {
- if (L == co) return CO_RUN;
- switch (lua_status(co)) {
- case LUA_YIELD:
- return CO_SUS;
- case 0: {
- lua_Debug ar;
- if (lua_getstack(co, 0, &ar) > 0) /* does it have frames? */
- return CO_NOR; /* it is running */
- else if (lua_gettop(co) == 0)
- return CO_DEAD;
- else
- return CO_SUS; /* initial state */
- }
- default: /* some error occured */
- return CO_DEAD;
- }
-}
-
-
-static int luaB_costatus (lua_State *L) {
- lua_State *co = lua_tothread(L, 1);
- luaL_argcheck(L, co, 1, "coroutine expected");
- lua_pushstring(L, statnames[costatus(L, co)]);
- return 1;
-}
-
-
-static int auxresume (lua_State *L, lua_State *co, int narg) {
- int status = costatus(L, co);
- if (!lua_checkstack(co, narg))
- luaL_error(L, "too many arguments to resume");
- if (status != CO_SUS) {
- lua_pushfstring(L, "cannot resume %s coroutine", statnames[status]);
- return -1; /* error flag */
- }
- lua_xmove(L, co, narg);
- lua_setlevel(L, co);
- status = lua_resume(co, narg);
- if (status == 0 || status == LUA_YIELD) {
- int nres = lua_gettop(co);
- if (!lua_checkstack(L, nres + 1))
- luaL_error(L, "too many results to resume");
- lua_xmove(co, L, nres); /* move yielded values */
- return nres;
- }
- else {
- lua_xmove(co, L, 1); /* move error message */
- return -1; /* error flag */
- }
-}
-
-
-static int luaB_coresume (lua_State *L) {
- lua_State *co = lua_tothread(L, 1);
- int r;
- luaL_argcheck(L, co, 1, "coroutine expected");
- r = auxresume(L, co, lua_gettop(L) - 1);
- if (r < 0) {
- lua_pushboolean(L, 0);
- lua_insert(L, -2);
- return 2; /* return false + error message */
- }
- else {
- lua_pushboolean(L, 1);
- lua_insert(L, -(r + 1));
- return r + 1; /* return true + `resume' returns */
- }
-}
-
-
-static int luaB_auxwrap (lua_State *L) {
- lua_State *co = lua_tothread(L, lua_upvalueindex(1));
- int r = auxresume(L, co, lua_gettop(L));
- if (r < 0) {
- if (lua_isstring(L, -1)) { /* error object is a string? */
- luaL_where(L, 1); /* add extra info */
- lua_insert(L, -2);
- lua_concat(L, 2);
- }
- lua_error(L); /* propagate error */
- }
- return r;
-}
-
-
-static int luaB_cocreate (lua_State *L) {
- lua_State *NL = lua_newthread(L);
- luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1), 1,
- "Lua function expected");
- lua_pushvalue(L, 1); /* move function to top */
- lua_xmove(L, NL, 1); /* move function from L to NL */
- return 1;
-}
-
-
-static int luaB_cowrap (lua_State *L) {
- luaB_cocreate(L);
- lua_pushcclosure(L, luaB_auxwrap, 1);
- return 1;
-}
-
-
-static int luaB_yield (lua_State *L) {
- return lua_yield(L, lua_gettop(L));
-}
-
-
-static int luaB_corunning (lua_State *L) {
- if (lua_pushthread(L))
- lua_pushnil(L); /* main thread is not a coroutine */
- return 1;
-}
-
-
-static const luaL_Reg co_funcs[] = {
- {"create", luaB_cocreate},
- {"resume", luaB_coresume},
- {"running", luaB_corunning},
- {"status", luaB_costatus},
- {"wrap", luaB_cowrap},
- {"yield", luaB_yield},
- {NULL, NULL}
-};
-
-/* }====================================================== */
-
-
-static void auxopen (lua_State *L, const char *name,
- lua_CFunction f, lua_CFunction u) {
- lua_pushcfunction(L, u);
- lua_pushcclosure(L, f, 1);
- lua_setfield(L, -2, name);
-}
-
-
-static void base_open (lua_State *L) {
- /* set global _G */
- lua_pushvalue(L, LUA_GLOBALSINDEX);
- lua_setglobal(L, "_G");
- /* open lib into global table */
- luaL_register(L, "_G", base_funcs);
- lua_pushliteral(L, LUA_VERSION);
- lua_setglobal(L, "_VERSION"); /* set global _VERSION */
- /* `ipairs' and `pairs' need auxliliary functions as upvalues */
- auxopen(L, "ipairs", luaB_ipairs, ipairsaux);
- auxopen(L, "pairs", luaB_pairs, luaB_next);
- /* `newproxy' needs a weaktable as upvalue */
- lua_createtable(L, 0, 1); /* new table `w' */
- lua_pushvalue(L, -1); /* `w' will be its own metatable */
- lua_setmetatable(L, -2);
- lua_pushliteral(L, "kv");
- lua_setfield(L, -2, "__mode"); /* metatable(w).__mode = "kv" */
- lua_pushcclosure(L, luaB_newproxy, 1);
- lua_setglobal(L, "newproxy"); /* set global `newproxy' */
-}
-
-
-LUALIB_API int luaopen_base (lua_State *L) {
- base_open(L);
- luaL_register(L, LUA_COLIBNAME, co_funcs);
- return 2;
-}
-
diff --git a/crawl-ref/source/util/lua/src/lcode.c b/crawl-ref/source/util/lua/src/lcode.c
deleted file mode 100644
index cff626b7fa..0000000000
--- a/crawl-ref/source/util/lua/src/lcode.c
+++ /dev/null
@@ -1,839 +0,0 @@
-/*
-** $Id: lcode.c,v 2.25.1.3 2007/12/28 15:32:23 roberto Exp $
-** Code generator for Lua
-** See Copyright Notice in lua.h
-*/
-
-
-#include <stdlib.h>
-
-#define lcode_c
-#define LUA_CORE
-
-#include "lua.h"
-
-#include "lcode.h"
-#include "ldebug.h"
-#include "ldo.h"
-#include "lgc.h"
-#include "llex.h"
-#include "lmem.h"
-#include "lobject.h"
-#include "lopcodes.h"
-#include "lparser.h"
-#include "ltable.h"
-
-
-#define hasjumps(e) ((e)->t != (e)->f)
-
-
-static int isnumeral(expdesc *e) {
- return (e->k == VKNUM && e->t == NO_JUMP && e->f == NO_JUMP);
-}
-
-
-void luaK_nil (FuncState *fs, int from, int n) {
- Instruction *previous;
- if (fs->pc > fs->lasttarget) { /* no jumps to current position? */
- if (fs->pc == 0) { /* function start? */
- if (from >= fs->nactvar)
- return; /* positions are already clean */
- }
- else {
- previous = &fs->f->code[fs->pc-1];
- if (GET_OPCODE(*previous) == OP_LOADNIL) {
- int pfrom = GETARG_A(*previous);
- int pto = GETARG_B(*previous);
- if (pfrom <= from && from <= pto+1) { /* can connect both? */
- if (from+n-1 > pto)
- SETARG_B(*previous, from+n-1);
- return;
- }
- }
- }
- }
- luaK_codeABC(fs, OP_LOADNIL, from, from+n-1, 0); /* else no optimization */
-}
-
-
-int luaK_jump (FuncState *fs) {
- int jpc = fs->jpc; /* save list of jumps to here */
- int j;
- fs->jpc = NO_JUMP;
- j = luaK_codeAsBx(fs, OP_JMP, 0, NO_JUMP);
- luaK_concat(fs, &j, jpc); /* keep them on hold */
- return j;
-}
-
-
-void luaK_ret (FuncState *fs, int first, int nret) {
- luaK_codeABC(fs, OP_RETURN, first, nret+1, 0);
-}
-
-
-static int condjump (FuncState *fs, OpCode op, int A, int B, int C) {
- luaK_codeABC(fs, op, A, B, C);
- return luaK_jump(fs);
-}
-
-
-static void fixjump (FuncState *fs, int pc, int dest) {
- Instruction *jmp = &fs->f->code[pc];
- int offset = dest-(pc+1);
- lua_assert(dest != NO_JUMP);
- if (abs(offset) > MAXARG_sBx)
- luaX_syntaxerror(fs->ls, "control structure too long");
- SETARG_sBx(*jmp, offset);
-}
-
-
-/*
-** returns current `pc' and marks it as a jump target (to avoid wrong
-** optimizations with consecutive instructions not in the same basic block).
-*/
-int luaK_getlabel (FuncState *fs) {
- fs->lasttarget = fs->pc;
- return fs->pc;
-}
-
-
-static int getjump (FuncState *fs, int pc) {
- int offset = GETARG_sBx(fs->f->code[pc]);
- if (offset == NO_JUMP) /* point to itself represents end of list */
- return NO_JUMP; /* end of list */
- else
- return (pc+1)+offset; /* turn offset into absolute position */
-}
-
-
-static Instruction *getjumpcontrol (FuncState *fs, int pc) {
- Instruction *pi = &fs->f->code[pc];
- if (pc >= 1 && testTMode(GET_OPCODE(*(pi-1))))
- return pi-1;
- else
- return pi;
-}
-
-
-/*
-** check whether list has any jump that do not produce a value
-** (or produce an inverted value)
-*/
-static int need_value (FuncState *fs, int list) {
- for (; list != NO_JUMP; list = getjump(fs, list)) {
- Instruction i = *getjumpcontrol(fs, list);
- if (GET_OPCODE(i) != OP_TESTSET) return 1;
- }
- return 0; /* not found */
-}
-
-
-static int patchtestreg (FuncState *fs, int node, int reg) {
- Instruction *i = getjumpcontrol(fs, node);
- if (GET_OPCODE(*i) != OP_TESTSET)
- return 0; /* cannot patch other instructions */
- if (reg != NO_REG && reg != GETARG_B(*i))
- SETARG_A(*i, reg);
- else /* no register to put value or register already has the value */
- *i = CREATE_ABC(OP_TEST, GETARG_B(*i), 0, GETARG_C(*i));
-
- return 1;
-}
-
-
-static void removevalues (FuncState *fs, int list) {
- for (; list != NO_JUMP; list = getjump(fs, list))
- patchtestreg(fs, list, NO_REG);
-}
-
-
-static void patchlistaux (FuncState *fs, int list, int vtarget, int reg,
- int dtarget) {
- while (list != NO_JUMP) {
- int next = getjump(fs, list);
- if (patchtestreg(fs, list, reg))
- fixjump(fs, list, vtarget);
- else
- fixjump(fs, list, dtarget); /* jump to default target */
- list = next;
- }
-}
-
-
-static void dischargejpc (FuncState *fs) {
- patchlistaux(fs, fs->jpc, fs->pc, NO_REG, fs->pc);
- fs->jpc = NO_JUMP;
-}
-
-
-void luaK_patchlist (FuncState *fs, int list, int target) {
- if (target == fs->pc)
- luaK_patchtohere(fs, list);
- else {
- lua_assert(target < fs->pc);
- patchlistaux(fs, list, target, NO_REG, target);
- }
-}
-
-
-void luaK_patchtohere (FuncState *fs, int list) {
- luaK_getlabel(fs);
- luaK_concat(fs, &fs->jpc, list);
-}
-
-
-void luaK_concat (FuncState *fs, int *l1, int l2) {
- if (l2 == NO_JUMP) return;
- else if (*l1 == NO_JUMP)
- *l1 = l2;
- else {
- int list = *l1;
- int next;
- while ((next = getjump(fs, list)) != NO_JUMP) /* find last element */
- list = next;
- fixjump(fs, list, l2);
- }
-}
-
-
-void luaK_checkstack (FuncState *fs, int n) {
- int newstack = fs->freereg + n;
- if (newstack > fs->f->maxstacksize) {
- if (newstack >= MAXSTACK)
- luaX_syntaxerror(fs->ls, "function or expression too complex");
- fs->f->maxstacksize = cast_byte(newstack);
- }
-}
-
-
-void luaK_reserveregs (FuncState *fs, int n) {
- luaK_checkstack(fs, n);
- fs->freereg += n;
-}
-
-
-static void freereg (FuncState *fs, int reg) {
- if (!ISK(reg) && reg >= fs->nactvar) {
- fs->freereg--;
- lua_assert(reg == fs->freereg);
- }
-}
-
-
-static void freeexp (FuncState *fs, expdesc *e) {
- if (e->k == VNONRELOC)
- freereg(fs, e->u.s.info);
-}
-
-
-static int addk (FuncState *fs, TValue *k, TValue *v) {
- lua_State *L = fs->L;
- TValue *idx = luaH_set(L, fs->h, k);
- Proto *f = fs->f;
- int oldsize = f->sizek;
- if (ttisnumber(idx)) {
- lua_assert(luaO_rawequalObj(&fs->f->k[cast_int(nvalue(idx))], v));
- return cast_int(nvalue(idx));
- }
- else { /* constant not found; create a new entry */
- setnvalue(idx, cast_num(fs->nk));
- luaM_growvector(L, f->k, fs->nk, f->sizek, TValue,
- MAXARG_Bx, "constant table overflow");
- while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]);
- setobj(L, &f->k[fs->nk], v);
- luaC_barrier(L, f, v);
- return fs->nk++;
- }
-}
-
-
-int luaK_stringK (FuncState *fs, TString *s) {
- TValue o;
- setsvalue(fs->L, &o, s);
- return addk(fs, &o, &o);
-}
-
-
-int luaK_numberK (FuncState *fs, lua_Number r) {
- TValue o;
- setnvalue(&o, r);
- return addk(fs, &o, &o);
-}
-
-
-static int boolK (FuncState *fs, int b) {
- TValue o;
- setbvalue(&o, b);
- return addk(fs, &o, &o);
-}
-
-
-static int nilK (FuncState *fs) {
- TValue k, v;
- setnilvalue(&v);
- /* cannot use nil as key; instead use table itself to represent nil */
- sethvalue(fs->L, &k, fs->h);
- return addk(fs, &k, &v);
-}
-
-
-void luaK_setreturns (FuncState *fs, expdesc *e, int nresults) {
- if (e->k == VCALL) { /* expression is an open function call? */
- SETARG_C(getcode(fs, e), nresults+1);
- }
- else if (e->k == VVARARG) {
- SETARG_B(getcode(fs, e), nresults+1);
- SETARG_A(getcode(fs, e), fs->freereg);
- luaK_reserveregs(fs, 1);
- }
-}
-
-
-void luaK_setoneret (FuncState *fs, expdesc *e) {
- if (e->k == VCALL) { /* expression is an open function call? */
- e->k = VNONRELOC;
- e->u.s.info = GETARG_A(getcode(fs, e));
- }
- else if (e->k == VVARARG) {
- SETARG_B(getcode(fs, e), 2);
- e->k = VRELOCABLE; /* can relocate its simple result */
- }
-}
-
-
-void luaK_dischargevars (FuncState *fs, expdesc *e) {
- switch (e->k) {
- case VLOCAL: {
- e->k = VNONRELOC;
- break;
- }
- case VUPVAL: {
- e->u.s.info = luaK_codeABC(fs, OP_GETUPVAL, 0, e->u.s.info, 0);
- e->k = VRELOCABLE;
- break;
- }
- case VGLOBAL: {
- e->u.s.info = luaK_codeABx(fs, OP_GETGLOBAL, 0, e->u.s.info);
- e->k = VRELOCABLE;
- break;
- }
- case VINDEXED: {
- freereg(fs, e->u.s.aux);
- freereg(fs, e->u.s.info);
- e->u.s.info = luaK_codeABC(fs, OP_GETTABLE, 0, e->u.s.info, e->u.s.aux);
- e->k = VRELOCABLE;
- break;
- }
- case VVARARG:
- case VCALL: {
- luaK_setoneret(fs, e);
- break;
- }
- default: break; /* there is one value available (somewhere) */
- }
-}
-
-
-static int code_label (FuncState *fs, int A, int b, int jump) {
- luaK_getlabel(fs); /* those instructions may be jump targets */
- return luaK_codeABC(fs, OP_LOADBOOL, A, b, jump);
-}
-
-
-static void discharge2reg (FuncState *fs, expdesc *e, int reg) {
- luaK_dischargevars(fs, e);
- switch (e->k) {
- case VNIL: {
- luaK_nil(fs, reg, 1);
- break;
- }
- case VFALSE: case VTRUE: {
- luaK_codeABC(fs, OP_LOADBOOL, reg, e->k == VTRUE, 0);
- break;
- }
- case VK: {
- luaK_codeABx(fs, OP_LOADK, reg, e->u.s.info);
- break;
- }
- case VKNUM: {
- luaK_codeABx(fs, OP_LOADK, reg, luaK_numberK(fs, e->u.nval));
- break;
- }
- case VRELOCABLE: {
- Instruction *pc = &getcode(fs, e);
- SETARG_A(*pc, reg);
- break;
- }
- case VNONRELOC: {
- if (reg != e->u.s.info)
- luaK_codeABC(fs, OP_MOVE, reg, e->u.s.info, 0);
- break;
- }
- default: {
- lua_assert(e->k == VVOID || e->k == VJMP);
- return; /* nothing to do... */
- }
- }
- e->u.s.info = reg;
- e->k = VNONRELOC;
-}
-
-
-static void discharge2anyreg (FuncState *fs, expdesc *e) {
- if (e->k != VNONRELOC) {
- luaK_reserveregs(fs, 1);
- discharge2reg(fs, e, fs->freereg-1);
- }
-}
-
-
-static void exp2reg (FuncState *fs, expdesc *e, int reg) {
- discharge2reg(fs, e, reg);
- if (e->k == VJMP)
- luaK_concat(fs, &e->t, e->u.s.info); /* put this jump in `t' list */
- if (hasjumps(e)) {
- int final; /* position after whole expression */
- int p_f = NO_JUMP; /* position of an eventual LOAD false */
- int p_t = NO_JUMP; /* position of an eventual LOAD true */
- if (need_value(fs, e->t) || need_value(fs, e->f)) {
- int fj = (e->k == VJMP) ? NO_JUMP : luaK_jump(fs);
- p_f = code_label(fs, reg, 0, 1);
- p_t = code_label(fs, reg, 1, 0);
- luaK_patchtohere(fs, fj);
- }
- final = luaK_getlabel(fs);
- patchlistaux(fs, e->f, final, reg, p_f);
- patchlistaux(fs, e->t, final, reg, p_t);
- }
- e->f = e->t = NO_JUMP;
- e->u.s.info = reg;
- e->k = VNONRELOC;
-}
-
-
-void luaK_exp2nextreg (FuncState *fs, expdesc *e) {
- luaK_dischargevars(fs, e);
- freeexp(fs, e);
- luaK_reserveregs(fs, 1);
- exp2reg(fs, e, fs->freereg - 1);
-}
-
-
-int luaK_exp2anyreg (FuncState *fs, expdesc *e) {
- luaK_dischargevars(fs, e);
- if (e->k == VNONRELOC) {
- if (!hasjumps(e)) return e->u.s.info; /* exp is already in a register */
- if (e->u.s.info >= fs->nactvar) { /* reg. is not a local? */
- exp2reg(fs, e, e->u.s.info); /* put value on it */
- return e->u.s.info;
- }
- }
- luaK_exp2nextreg(fs, e); /* default */
- return e->u.s.info;
-}
-
-
-void luaK_exp2val (FuncState *fs, expdesc *e) {
- if (hasjumps(e))
- luaK_exp2anyreg(fs, e);
- else
- luaK_dischargevars(fs, e);
-}
-
-
-int luaK_exp2RK (FuncState *fs, expdesc *e) {
- luaK_exp2val(fs, e);
- switch (e->k) {
- case VKNUM:
- case VTRUE:
- case VFALSE:
- case VNIL: {
- if (fs->nk <= MAXINDEXRK) { /* constant fit in RK operand? */
- e->u.s.info = (e->k == VNIL) ? nilK(fs) :
- (e->k == VKNUM) ? luaK_numberK(fs, e->u.nval) :
- boolK(fs, (e->k == VTRUE));
- e->k = VK;
- return RKASK(e->u.s.info);
- }
- else break;
- }
- case VK: {
- if (e->u.s.info <= MAXINDEXRK) /* constant fit in argC? */
- return RKASK(e->u.s.info);
- else break;
- }
- default: break;
- }
- /* not a constant in the right range: put it in a register */
- return luaK_exp2anyreg(fs, e);
-}
-
-
-void luaK_storevar (FuncState *fs, expdesc *var, expdesc *ex) {
- switch (var->k) {
- case VLOCAL: {
- freeexp(fs, ex);
- exp2reg(fs, ex, var->u.s.info);
- return;
- }
- case VUPVAL: {
- int e = luaK_exp2anyreg(fs, ex);
- luaK_codeABC(fs, OP_SETUPVAL, e, var->u.s.info, 0);
- break;
- }
- case VGLOBAL: {
- int e = luaK_exp2anyreg(fs, ex);
- luaK_codeABx(fs, OP_SETGLOBAL, e, var->u.s.info);
- break;
- }
- case VINDEXED: {
- int e = luaK_exp2RK(fs, ex);
- luaK_codeABC(fs, OP_SETTABLE, var->u.s.info, var->u.s.aux, e);
- break;
- }
- default: {
- lua_assert(0); /* invalid var kind to store */
- break;
- }
- }
- freeexp(fs, ex);
-}
-
-
-void luaK_self (FuncState *fs, expdesc *e, expdesc *key) {
- int func;
- luaK_exp2anyreg(fs, e);
- freeexp(fs, e);
- func = fs->freereg;
- luaK_reserveregs(fs, 2);
- luaK_codeABC(fs, OP_SELF, func, e->u.s.info, luaK_exp2RK(fs, key));
- freeexp(fs, key);
- e->u.s.info = func;
- e->k = VNONRELOC;
-}
-
-
-static void invertjump (FuncState *fs, expdesc *e) {
- Instruction *pc = getjumpcontrol(fs, e->u.s.info);
- lua_assert(testTMode(GET_OPCODE(*pc)) && GET_OPCODE(*pc) != OP_TESTSET &&
- GET_OPCODE(*pc) != OP_TEST);
- SETARG_A(*pc, !(GETARG_A(*pc)));
-}
-
-
-static int jumponcond (FuncState *fs, expdesc *e, int cond) {
- if (e->k == VRELOCABLE) {
- Instruction ie = getcode(fs, e);
- if (GET_OPCODE(ie) == OP_NOT) {
- fs->pc--; /* remove previous OP_NOT */
- return condjump(fs, OP_TEST, GETARG_B(ie), 0, !cond);
- }
- /* else go through */
- }
- discharge2anyreg(fs, e);
- freeexp(fs, e);
- return condjump(fs, OP_TESTSET, NO_REG, e->u.s.info, cond);
-}
-
-
-void luaK_goiftrue (FuncState *fs, expdesc *e) {
- int pc; /* pc of last jump */
- luaK_dischargevars(fs, e);
- switch (e->k) {
- case VK: case VKNUM: case VTRUE: {
- pc = NO_JUMP; /* always true; do nothing */
- break;
- }
- case VFALSE: {
- pc = luaK_jump(fs); /* always jump */
- break;
- }
- case VJMP: {
- invertjump(fs, e);
- pc = e->u.s.info;
- break;
- }
- default: {
- pc = jumponcond(fs, e, 0);
- break;
- }
- }
- luaK_concat(fs, &e->f, pc); /* insert last jump in `f' list */
- luaK_patchtohere(fs, e->t);
- e->t = NO_JUMP;
-}
-
-
-static void luaK_goiffalse (FuncState *fs, expdesc *e) {
- int pc; /* pc of last jump */
- luaK_dischargevars(fs, e);
- switch (e->k) {
- case VNIL: case VFALSE: {
- pc = NO_JUMP; /* always false; do nothing */
- break;
- }
- case VTRUE: {
- pc = luaK_jump(fs); /* always jump */
- break;
- }
- case VJMP: {
- pc = e->u.s.info;
- break;
- }
- default: {
- pc = jumponcond(fs, e, 1);
- break;
- }
- }
- luaK_concat(fs, &e->t, pc); /* insert last jump in `t' list */
- luaK_patchtohere(fs, e->f);
- e->f = NO_JUMP;
-}
-
-
-static void codenot (FuncState *fs, expdesc *e) {
- luaK_dischargevars(fs, e);
- switch (e->k) {
- case VNIL: case VFALSE: {
- e->k = VTRUE;
- break;
- }
- case VK: case VKNUM: case VTRUE: {
- e->k = VFALSE;
- break;
- }
- case VJMP: {
- invertjump(fs, e);
- break;
- }
- case VRELOCABLE:
- case VNONRELOC: {
- discharge2anyreg(fs, e);
- freeexp(fs, e);
- e->u.s.info = luaK_codeABC(fs, OP_NOT, 0, e->u.s.info, 0);
- e->k = VRELOCABLE;
- break;
- }
- default: {
- lua_assert(0); /* cannot happen */
- break;
- }
- }
- /* interchange true and false lists */
- { int temp = e->f; e->f = e->t; e->t = temp; }
- removevalues(fs, e->f);
- removevalues(fs, e->t);
-}
-
-
-void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) {
- t->u.s.aux = luaK_exp2RK(fs, k);
- t->k = VINDEXED;
-}
-
-
-static int constfolding (OpCode op, expdesc *e1, expdesc *e2) {
- lua_Number v1, v2, r;
- if (!isnumeral(e1) || !isnumeral(e2)) return 0;
- v1 = e1->u.nval;
- v2 = e2->u.nval;
- switch (op) {
- case OP_ADD: r = luai_numadd(v1, v2); break;
- case OP_SUB: r = luai_numsub(v1, v2); break;
- case OP_MUL: r = luai_nummul(v1, v2); break;
- case OP_DIV:
- if (v2 == 0) return 0; /* do not attempt to divide by 0 */
- r = luai_numdiv(v1, v2); break;
- case OP_MOD:
- if (v2 == 0) return 0; /* do not attempt to divide by 0 */
- r = luai_nummod(v1, v2); break;
- case OP_POW: r = luai_numpow(v1, v2); break;
- case OP_UNM: r = luai_numunm(v1); break;
- case OP_LEN: return 0; /* no constant folding for 'len' */
- default: lua_assert(0); r = 0; break;
- }
- if (luai_numisnan(r)) return 0; /* do not attempt to produce NaN */
- e1->u.nval = r;
- return 1;
-}
-
-
-static void codearith (FuncState *fs, OpCode op, expdesc *e1, expdesc *e2) {
- if (constfolding(op, e1, e2))
- return;
- else {
- int o2 = (op != OP_UNM && op != OP_LEN) ? luaK_exp2RK(fs, e2) : 0;
- int o1 = luaK_exp2RK(fs, e1);
- if (o1 > o2) {
- freeexp(fs, e1);
- freeexp(fs, e2);
- }
- else {
- freeexp(fs, e2);
- freeexp(fs, e1);
- }
- e1->u.s.info = luaK_codeABC(fs, op, 0, o1, o2);
- e1->k = VRELOCABLE;
- }
-}
-
-
-static void codecomp (FuncState *fs, OpCode op, int cond, expdesc *e1,
- expdesc *e2) {
- int o1 = luaK_exp2RK(fs, e1);
- int o2 = luaK_exp2RK(fs, e2);
- freeexp(fs, e2);
- freeexp(fs, e1);
- if (cond == 0 && op != OP_EQ) {
- int temp; /* exchange args to replace by `<' or `<=' */
- temp = o1; o1 = o2; o2 = temp; /* o1 <==> o2 */
- cond = 1;
- }
- e1->u.s.info = condjump(fs, op, cond, o1, o2);
- e1->k = VJMP;
-}
-
-
-void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e) {
- expdesc e2;
- e2.t = e2.f = NO_JUMP; e2.k = VKNUM; e2.u.nval = 0;
- switch (op) {
- case OPR_MINUS: {
- if (!isnumeral(e))
- luaK_exp2anyreg(fs, e); /* cannot operate on non-numeric constants */
- codearith(fs, OP_UNM, e, &e2);
- break;
- }
- case OPR_NOT: codenot(fs, e); break;
- case OPR_LEN: {
- luaK_exp2anyreg(fs, e); /* cannot operate on constants */
- codearith(fs, OP_LEN, e, &e2);
- break;
- }
- default: lua_assert(0);
- }
-}
-
-
-void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) {
- switch (op) {
- case OPR_AND: {
- luaK_goiftrue(fs, v);
- break;
- }
- case OPR_OR: {
- luaK_goiffalse(fs, v);
- break;
- }
- case OPR_CONCAT: {
- luaK_exp2nextreg(fs, v); /* operand must be on the `stack' */
- break;
- }
- case OPR_ADD: case OPR_SUB: case OPR_MUL: case OPR_DIV:
- case OPR_MOD: case OPR_POW: {
- if (!isnumeral(v)) luaK_exp2RK(fs, v);
- break;
- }
- default: {
- luaK_exp2RK(fs, v);
- break;
- }
- }
-}
-
-
-void luaK_posfix (FuncState *fs, BinOpr op, expdesc *e1, expdesc *e2) {
- switch (op) {
- case OPR_AND: {
- lua_assert(e1->t == NO_JUMP); /* list must be closed */
- luaK_dischargevars(fs, e2);
- luaK_concat(fs, &e2->f, e1->f);
- *e1 = *e2;
- break;
- }
- case OPR_OR: {
- lua_assert(e1->f == NO_JUMP); /* list must be closed */
- luaK_dischargevars(fs, e2);
- luaK_concat(fs, &e2->t, e1->t);
- *e1 = *e2;
- break;
- }
- case OPR_CONCAT: {
- luaK_exp2val(fs, e2);
- if (e2->k == VRELOCABLE && GET_OPCODE(getcode(fs, e2)) == OP_CONCAT) {
- lua_assert(e1->u.s.info == GETARG_B(getcode(fs, e2))-1);
- freeexp(fs, e1);
- SETARG_B(getcode(fs, e2), e1->u.s.info);
- e1->k = VRELOCABLE; e1->u.s.info = e2->u.s.info;
- }
- else {
- luaK_exp2nextreg(fs, e2); /* operand must be on the 'stack' */
- codearith(fs, OP_CONCAT, e1, e2);
- }
- break;
- }
- case OPR_ADD: codearith(fs, OP_ADD, e1, e2); break;
- case OPR_SUB: codearith(fs, OP_SUB, e1, e2); break;
- case OPR_MUL: codearith(fs, OP_MUL, e1, e2); break;
- case OPR_DIV: codearith(fs, OP_DIV, e1, e2); break;
- case OPR_MOD: codearith(fs, OP_MOD, e1, e2); break;
- case OPR_POW: codearith(fs, OP_POW, e1, e2); break;
- case OPR_EQ: codecomp(fs, OP_EQ, 1, e1, e2); break;
- case OPR_NE: codecomp(fs, OP_EQ, 0, e1, e2); break;
- case OPR_LT: codecomp(fs, OP_LT, 1, e1, e2); break;
- case OPR_LE: codecomp(fs, OP_LE, 1, e1, e2); break;
- case OPR_GT: codecomp(fs, OP_LT, 0, e1, e2); break;
- case OPR_GE: codecomp(fs, OP_LE, 0, e1, e2); break;
- default: lua_assert(0);
- }
-}
-
-
-void luaK_fixline (FuncState *fs, int line) {
- fs->f->lineinfo[fs->pc - 1] = line;
-}
-
-
-static int luaK_code (FuncState *fs, Instruction i, int line) {
- Proto *f = fs->f;
- dischargejpc(fs); /* `pc' will change */
- /* put new instruction in code array */
- luaM_growvector(fs->L, f->code, fs->pc, f->sizecode, Instruction,
- MAX_INT, "code size overflow");
- f->code[fs->pc] = i;
- /* save corresponding line information */
- luaM_growvector(fs->L, f->lineinfo, fs->pc, f->sizelineinfo, int,
- MAX_INT, "code size overflow");
- f->lineinfo[fs->pc] = line;
- return fs->pc++;
-}
-
-
-int luaK_codeABC (FuncState *fs, OpCode o, int a, int b, int c) {
- lua_assert(getOpMode(o) == iABC);
- lua_assert(getBMode(o) != OpArgN || b == 0);
- lua_assert(getCMode(o) != OpArgN || c == 0);
- return luaK_code(fs, CREATE_ABC(o, a, b, c), fs->ls->lastline);
-}
-
-
-int luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) {
- lua_assert(getOpMode(o) == iABx || getOpMode(o) == iAsBx);
- lua_assert(getCMode(o) == OpArgN);
- return luaK_code(fs, CREATE_ABx(o, a, bc), fs->ls->lastline);
-}
-
-
-void luaK_setlist (FuncState *fs, int base, int nelems, int tostore) {
- int c = (nelems - 1)/LFIELDS_PER_FLUSH + 1;
- int b = (tostore == LUA_MULTRET) ? 0 : tostore;
- lua_assert(tostore != 0);
- if (c <= MAXARG_C)
- luaK_codeABC(fs, OP_SETLIST, base, b, c);
- else {
- luaK_codeABC(fs, OP_SETLIST, base, b, 0);
- luaK_code(fs, cast(Instruction, c), fs->ls->lastline);
- }
- fs->freereg = base + 1; /* free registers with list values */
-}
-
diff --git a/crawl-ref/source/util/lua/src/lcode.h b/crawl-ref/source/util/lua/src/lcode.h
deleted file mode 100644
index b941c60721..0000000000
--- a/crawl-ref/source/util/lua/src/lcode.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
-** $Id: lcode.h,v 1.48.1.1 2007/12/27 13:02:25 roberto Exp $
-** Code generator for Lua
-** See Copyright Notice in lua.h
-*/
-
-#ifndef lcode_h
-#define lcode_h
-
-#include "llex.h"
-#include "lobject.h"
-#include "lopcodes.h"
-#include "lparser.h"
-
-
-/*
-** Marks the end of a patch list. It is an invalid value both as an absolute
-** address, and as a list link (would link an element to itself).
-*/
-#define NO_JUMP (-1)
-
-
-/*
-** grep "ORDER OPR" if you change these enums
-*/
-typedef enum BinOpr {
- OPR_ADD, OPR_SUB, OPR_MUL, OPR_DIV, OPR_MOD, OPR_POW,
- OPR_CONCAT,
- OPR_NE, OPR_EQ,
- OPR_LT, OPR_LE, OPR_GT, OPR_GE,
- OPR_AND, OPR_OR,
- OPR_NOBINOPR
-} BinOpr;
-
-
-typedef enum UnOpr { OPR_MINUS, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr;
-
-
-#define getcode(fs,e) ((fs)->f->code[(e)->u.s.info])
-
-#define luaK_codeAsBx(fs,o,A,sBx) luaK_codeABx(fs,o,A,(sBx)+MAXARG_sBx)
-
-#define luaK_setmultret(fs,e) luaK_setreturns(fs, e, LUA_MULTRET)
-
-LUAI_FUNC int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bx);
-LUAI_FUNC int luaK_codeABC (FuncState *fs, OpCode o, int A, int B, int C);
-LUAI_FUNC void luaK_fixline (FuncState *fs, int line);
-LUAI_FUNC void luaK_nil (FuncState *fs, int from, int n);
-LUAI_FUNC void luaK_reserveregs (FuncState *fs, int n);
-LUAI_FUNC void luaK_checkstack (FuncState *fs, int n);
-LUAI_FUNC int luaK_stringK (FuncState *fs, TString *s);
-LUAI_FUNC int luaK_numberK (FuncState *fs, lua_Number r);
-LUAI_FUNC void luaK_dischargevars (FuncState *fs, expdesc *e);
-LUAI_FUNC int luaK_exp2anyreg (FuncState *fs, expdesc *e);
-LUAI_FUNC void luaK_exp2nextreg (FuncState *fs, expdesc *e);
-LUAI_FUNC void luaK_exp2val (FuncState *fs, expdesc *e);
-LUAI_FUNC int luaK_exp2RK (FuncState *fs, expdesc *e);
-LUAI_FUNC void luaK_self (FuncState *fs, expdesc *e, expdesc *key);
-LUAI_FUNC void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k);
-LUAI_FUNC void luaK_goiftrue (FuncState *fs, expdesc *e);
-LUAI_FUNC void luaK_storevar (FuncState *fs, expdesc *var, expdesc *e);
-LUAI_FUNC void luaK_setreturns (FuncState *fs, expdesc *e, int nresults);
-LUAI_FUNC void luaK_setoneret (FuncState *fs, expdesc *e);
-LUAI_FUNC int luaK_jump (FuncState *fs);
-LUAI_FUNC void luaK_ret (FuncState *fs, int first, int nret);
-LUAI_FUNC void luaK_patchlist (FuncState *fs, int list, int target);
-LUAI_FUNC void luaK_patchtohere (FuncState *fs, int list);
-LUAI_FUNC void luaK_concat (FuncState *fs, int *l1, int l2);
-LUAI_FUNC int luaK_getlabel (FuncState *fs);
-LUAI_FUNC void luaK_prefix (FuncState *fs, UnOpr op, expdesc *v);
-LUAI_FUNC void luaK_infix (FuncState *fs, BinOpr op, expdesc *v);
-LUAI_FUNC void luaK_posfix (FuncState *fs, BinOpr op, expdesc *v1, expdesc *v2);
-LUAI_FUNC void luaK_setlist (FuncState *fs, int base, int nelems, int tostore);
-
-
-#endif
diff --git a/crawl-ref/source/util/lua/src/ldblib.c b/crawl-ref/source/util/lua/src/ldblib.c
deleted file mode 100644
index 67de1222a9..0000000000
--- a/crawl-ref/source/util/lua/src/ldblib.c
+++ /dev/null
@@ -1,397 +0,0 @@
-/*
-** $Id: ldblib.c,v 1.104.1.3 2008/01/21 13:11:21 roberto Exp $
-** Interface from Lua to its debug API
-** See Copyright Notice in lua.h
-*/
-
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#define ldblib_c
-#define LUA_LIB
-
-#include "lua.h"
-
-#include "lauxlib.h"
-#include "lualib.h"
-
-
-
-static int db_getregistry (lua_State *L) {
- lua_pushvalue(L, LUA_REGISTRYINDEX);
- return 1;
-}
-
-
-static int db_getmetatable (lua_State *L) {
- luaL_checkany(L, 1);
- if (!lua_getmetatable(L, 1)) {
- lua_pushnil(L); /* no metatable */
- }
- return 1;
-}
-
-
-static int db_setmetatable (lua_State *L) {
- int t = lua_type(L, 2);
- luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2,
- "nil or table expected");
- lua_settop(L, 2);
- lua_pushboolean(L, lua_setmetatable(L, 1));
- return 1;
-}
-
-
-static int db_getfenv (lua_State *L) {
- lua_getfenv(L, 1);
- return 1;
-}
-
-
-static int db_setfenv (lua_State *L) {
- luaL_checktype(L, 2, LUA_TTABLE);
- lua_settop(L, 2);
- if (lua_setfenv(L, 1) == 0)
- luaL_error(L, LUA_QL("setfenv")
- " cannot change environment of given object");
- return 1;
-}
-
-
-static void settabss (lua_State *L, const char *i, const char *v) {
- lua_pushstring(L, v);
- lua_setfield(L, -2, i);
-}
-
-
-static void settabsi (lua_State *L, const char *i, int v) {
- lua_pushinteger(L, v);
- lua_setfield(L, -2, i);
-}
-
-
-static lua_State *getthread (lua_State *L, int *arg) {
- if (lua_isthread(L, 1)) {
- *arg = 1;
- return lua_tothread(L, 1);
- }
- else {
- *arg = 0;
- return L;
- }
-}
-
-
-static void treatstackoption (lua_State *L, lua_State *L1, const char *fname) {
- if (L == L1) {
- lua_pushvalue(L, -2);
- lua_remove(L, -3);
- }
- else
- lua_xmove(L1, L, 1);
- lua_setfield(L, -2, fname);
-}
-
-
-static int db_getinfo (lua_State *L) {
- lua_Debug ar;
- int arg;
- lua_State *L1 = getthread(L, &arg);
- const char *options = luaL_optstring(L, arg+2, "flnSu");
- if (lua_isnumber(L, arg+1)) {
- if (!lua_getstack(L1, (int)lua_tointeger(L, arg+1), &ar)) {
- lua_pushnil(L); /* level out of range */
- return 1;
- }
- }
- else if (lua_isfunction(L, arg+1)) {
- lua_pushfstring(L, ">%s", options);
- options = lua_tostring(L, -1);
- lua_pushvalue(L, arg+1);
- lua_xmove(L, L1, 1);
- }
- else
- return luaL_argerror(L, arg+1, "function or level expected");
- if (!lua_getinfo(L1, options, &ar))
- return luaL_argerror(L, arg+2, "invalid option");
- lua_createtable(L, 0, 2);
- if (strchr(options, 'S')) {
- settabss(L, "source", ar.source);
- settabss(L, "short_src", ar.short_src);
- settabsi(L, "linedefined", ar.linedefined);
- settabsi(L, "lastlinedefined", ar.lastlinedefined);
- settabss(L, "what", ar.what);
- }
- if (strchr(options, 'l'))
- settabsi(L, "currentline", ar.currentline);
- if (strchr(options, 'u'))
- settabsi(L, "nups", ar.nups);
- if (strchr(options, 'n')) {
- settabss(L, "name", ar.name);
- settabss(L, "namewhat", ar.namewhat);
- }
- if (strchr(options, 'L'))
- treatstackoption(L, L1, "activelines");
- if (strchr(options, 'f'))
- treatstackoption(L, L1, "func");
- return 1; /* return table */
-}
-
-
-static int db_getlocal (lua_State *L) {
- int arg;
- lua_State *L1 = getthread(L, &arg);
- lua_Debug ar;
- const char *name;
- if (!lua_getstack(L1, luaL_checkint(L, arg+1), &ar)) /* out of range? */
- return luaL_argerror(L, arg+1, "level out of range");
- name = lua_getlocal(L1, &ar, luaL_checkint(L, arg+2));
- if (name) {
- lua_xmove(L1, L, 1);
- lua_pushstring(L, name);
- lua_pushvalue(L, -2);
- return 2;
- }
- else {
- lua_pushnil(L);
- return 1;
- }
-}
-
-
-static int db_setlocal (lua_State *L) {
- int arg;
- lua_State *L1 = getthread(L, &arg);
- lua_Debug ar;
- if (!lua_getstack(L1, luaL_checkint(L, arg+1), &ar)) /* out of range? */
- return luaL_argerror(L, arg+1, "level out of range");
- luaL_checkany(L, arg+3);
- lua_settop(L, arg+3);
- lua_xmove(L, L1, 1);
- lua_pushstring(L, lua_setlocal(L1, &ar, luaL_checkint(L, arg+2)));
- return 1;
-}
-
-
-static int auxupvalue (lua_State *L, int get) {
- const char *name;
- int n = luaL_checkint(L, 2);
- luaL_checktype(L, 1, LUA_TFUNCTION);
- if (lua_iscfunction(L, 1)) return 0; /* cannot touch C upvalues from Lua */
- name = get ? lua_getupvalue(L, 1, n) : lua_setupvalue(L, 1, n);
- if (name == NULL) return 0;
- lua_pushstring(L, name);
- lua_insert(L, -(get+1));
- return get + 1;
-}
-
-
-static int db_getupvalue (lua_State *L) {
- return auxupvalue(L, 1);
-}
-
-
-static int db_setupvalue (lua_State *L) {
- luaL_checkany(L, 3);
- return auxupvalue(L, 0);
-}
-
-
-
-static const char KEY_HOOK = 'h';
-
-
-static void hookf (lua_State *L, lua_Debug *ar) {
- static const char *const hooknames[] =
- {"call", "return", "line", "count", "tail return"};
- lua_pushlightuserdata(L, (void *)&KEY_HOOK);
- lua_rawget(L, LUA_REGISTRYINDEX);
- lua_pushlightuserdata(L, L);
- lua_rawget(L, -2);
- if (lua_isfunction(L, -1)) {
- lua_pushstring(L, hooknames[(int)ar->event]);
- if (ar->currentline >= 0)
- lua_pushinteger(L, ar->currentline);
- else lua_pushnil(L);
- lua_assert(lua_getinfo(L, "lS", ar));
- lua_call(L, 2, 0);
- }
-}
-
-
-static int makemask (const char *smask, int count) {
- int mask = 0;
- if (strchr(smask, 'c')) mask |= LUA_MASKCALL;
- if (strchr(smask, 'r')) mask |= LUA_MASKRET;
- if (strchr(smask, 'l')) mask |= LUA_MASKLINE;
- if (count > 0) mask |= LUA_MASKCOUNT;
- return mask;
-}
-
-
-static char *unmakemask (int mask, char *smask) {
- int i = 0;
- if (mask & LUA_MASKCALL) smask[i++] = 'c';
- if (mask & LUA_MASKRET) smask[i++] = 'r';
- if (mask & LUA_MASKLINE) smask[i++] = 'l';
- smask[i] = '\0';
- return smask;
-}
-
-
-static void gethooktable (lua_State *L) {
- lua_pushlightuserdata(L, (void *)&KEY_HOOK);
- lua_rawget(L, LUA_REGISTRYINDEX);
- if (!lua_istable(L, -1)) {
- lua_pop(L, 1);
- lua_createtable(L, 0, 1);
- lua_pushlightuserdata(L, (void *)&KEY_HOOK);
- lua_pushvalue(L, -2);
- lua_rawset(L, LUA_REGISTRYINDEX);
- }
-}
-
-
-static int db_sethook (lua_State *L) {
- int arg, mask, count;
- lua_Hook func;
- lua_State *L1 = getthread(L, &arg);
- if (lua_isnoneornil(L, arg+1)) {
- lua_settop(L, arg+1);
- func = NULL; mask = 0; count = 0; /* turn off hooks */
- }
- else {
- const char *smask = luaL_checkstring(L, arg+2);
- luaL_checktype(L, arg+1, LUA_TFUNCTION);
- count = luaL_optint(L, arg+3, 0);
- func = hookf; mask = makemask(smask, count);
- }
- gethooktable(L);
- lua_pushlightuserdata(L, L1);
- lua_pushvalue(L, arg+1);
- lua_rawset(L, -3); /* set new hook */
- lua_pop(L, 1); /* remove hook table */
- lua_sethook(L1, func, mask, count); /* set hooks */
- return 0;
-}
-
-
-static int db_gethook (lua_State *L) {
- int arg;
- lua_State *L1 = getthread(L, &arg);
- char buff[5];
- int mask = lua_gethookmask(L1);
- lua_Hook hook = lua_gethook(L1);
- if (hook != NULL && hook != hookf) /* external hook? */
- lua_pushliteral(L, "external hook");
- else {
- gethooktable(L);
- lua_pushlightuserdata(L, L1);
- lua_rawget(L, -2); /* get hook */
- lua_remove(L, -2); /* remove hook table */
- }
- lua_pushstring(L, unmakemask(mask, buff));
- lua_pushinteger(L, lua_gethookcount(L1));
- return 3;
-}
-
-
-static int db_debug (lua_State *L) {
- for (;;) {
- char buffer[250];
- fputs("lua_debug> ", stderr);
- if (fgets(buffer, sizeof(buffer), stdin) == 0 ||
- strcmp(buffer, "cont\n") == 0)
- return 0;
- if (luaL_loadbuffer(L, buffer, strlen(buffer), "=(debug command)") ||
- lua_pcall(L, 0, 0, 0)) {
- fputs(lua_tostring(L, -1), stderr);
- fputs("\n", stderr);
- }
- lua_settop(L, 0); /* remove eventual returns */
- }
-}
-
-
-#define LEVELS1 12 /* size of the first part of the stack */
-#define LEVELS2 10 /* size of the second part of the stack */
-
-static int db_errorfb (lua_State *L) {
- int level;
- int firstpart = 1; /* still before eventual `...' */
- int arg;
- lua_State *L1 = getthread(L, &arg);
- lua_Debug ar;
- if (lua_isnumber(L, arg+2)) {
- level = (int)lua_tointeger(L, arg+2);
- lua_pop(L, 1);
- }
- else
- level = (L == L1) ? 1 : 0; /* level 0 may be this own function */
- if (lua_gettop(L) == arg)
- lua_pushliteral(L, "");
- else if (!lua_isstring(L, arg+1)) return 1; /* message is not a string */
- else lua_pushliteral(L, "\n");
- lua_pushliteral(L, "stack traceback:");
- while (lua_getstack(L1, level++, &ar)) {
- if (level > LEVELS1 && firstpart) {
- /* no more than `LEVELS2' more levels? */
- if (!lua_getstack(L1, level+LEVELS2, &ar))
- level--; /* keep going */
- else {
- lua_pushliteral(L, "\n\t..."); /* too many levels */
- while (lua_getstack(L1, level+LEVELS2, &ar)) /* find last levels */
- level++;
- }
- firstpart = 0;
- continue;
- }
- lua_pushliteral(L, "\n\t");
- lua_getinfo(L1, "Snl", &ar);
- lua_pushfstring(L, "%s:", ar.short_src);
- if (ar.currentline > 0)
- lua_pushfstring(L, "%d:", ar.currentline);
- if (*ar.namewhat != '\0') /* is there a name? */
- lua_pushfstring(L, " in function " LUA_QS, ar.name);
- else {
- if (*ar.what == 'm') /* main? */
- lua_pushfstring(L, " in main chunk");
- else if (*ar.what == 'C' || *ar.what == 't')
- lua_pushliteral(L, " ?"); /* C function or tail call */
- else
- lua_pushfstring(L, " in function <%s:%d>",
- ar.short_src, ar.linedefined);
- }
- lua_concat(L, lua_gettop(L) - arg);
- }
- lua_concat(L, lua_gettop(L) - arg);
- return 1;
-}
-
-
-static const luaL_Reg dblib[] = {
- {"debug", db_debug},
- {"getfenv", db_getfenv},
- {"gethook", db_gethook},
- {"getinfo", db_getinfo},
- {"getlocal", db_getlocal},
- {"getregistry", db_getregistry},
- {"getmetatable", db_getmetatable},
- {"getupvalue", db_getupvalue},
- {"setfenv", db_setfenv},
- {"sethook", db_sethook},
- {"setlocal", db_setlocal},
- {"setmetatable", db_setmetatable},
- {"setupvalue", db_setupvalue},
- {"traceback", db_errorfb},
- {NULL, NULL}
-};
-
-
-LUALIB_API int luaopen_debug (lua_State *L) {
- luaL_register(L, LUA_DBLIBNAME, dblib);
- return 1;
-}
-
diff --git a/crawl-ref/source/util/lua/src/ldebug.c b/crawl-ref/source/util/lua/src/ldebug.c
deleted file mode 100644
index 50ad3d3803..0000000000
--- a/crawl-ref/source/util/lua/src/ldebug.c
+++ /dev/null
@@ -1,638 +0,0 @@
-/*
-** $Id: ldebug.c,v 2.29.1.6 2008/05/08 16:56:26 roberto Exp $
-** Debug Interface
-** See Copyright Notice in lua.h
-*/
-
-
-#include <stdarg.h>
-#include <stddef.h>
-#include <string.h>
-
-
-#define ldebug_c
-#define LUA_CORE
-
-#include "lua.h"
-
-#include "lapi.h"
-#include "lcode.h"
-#include "ldebug.h"
-#include "ldo.h"
-#include "lfunc.h"
-#include "lobject.h"
-#include "lopcodes.h"
-#include "lstate.h"
-#include "lstring.h"
-#include "ltable.h"
-#include "ltm.h"
-#include "lvm.h"
-
-
-
-static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name);
-
-
-static int currentpc (lua_State *L, CallInfo *ci) {
- if (!isLua(ci)) return -1; /* function is not a Lua function? */
- if (ci == L->ci)
- ci->savedpc = L->savedpc;
- return pcRel(ci->savedpc, ci_func(ci)->l.p);
-}
-
-
-static int currentline (lua_State *L, CallInfo *ci) {
- int pc = currentpc(L, ci);
- if (pc < 0)
- return -1; /* only active lua functions have current-line information */
- else
- return getline(ci_func(ci)->l.p, pc);
-}
-
-
-/*
-** this function can be called asynchronous (e.g. during a signal)
-*/
-LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count) {
- if (func == NULL || mask == 0) { /* turn off hooks? */
- mask = 0;
- func = NULL;
- }
- L->hook = func;
- L->basehookcount = count;
- resethookcount(L);
- L->hookmask = cast_byte(mask);
- return 1;
-}
-
-
-LUA_API lua_Hook lua_gethook (lua_State *L) {
- return L->hook;
-}
-
-
-LUA_API int lua_gethookmask (lua_State *L) {
- return L->hookmask;
-}
-
-
-LUA_API int lua_gethookcount (lua_State *L) {
- return L->basehookcount;
-}
-
-
-LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) {
- int status;
- CallInfo *ci;
- lua_lock(L);
- for (ci = L->ci; level > 0 && ci > L->base_ci; ci--) {
- level--;
- if (f_isLua(ci)) /* Lua function? */
- level -= ci->tailcalls; /* skip lost tail calls */
- }
- if (level == 0 && ci > L->base_ci) { /* level found? */
- status = 1;
- ar->i_ci = cast_int(ci - L->base_ci);
- }
- else if (level < 0) { /* level is of a lost tail call? */
- status = 1;
- ar->i_ci = 0;
- }
- else status = 0; /* no such level */
- lua_unlock(L);
- return status;
-}
-
-
-static Proto *getluaproto (CallInfo *ci) {
- return (isLua(ci) ? ci_func(ci)->l.p : NULL);
-}
-
-
-static const char *findlocal (lua_State *L, CallInfo *ci, int n) {
- const char *name;
- Proto *fp = getluaproto(ci);
- if (fp && (name = luaF_getlocalname(fp, n, currentpc(L, ci))) != NULL)
- return name; /* is a local variable in a Lua function */
- else {
- StkId limit = (ci == L->ci) ? L->top : (ci+1)->func;
- if (limit - ci->base >= n && n > 0) /* is 'n' inside 'ci' stack? */
- return "(*temporary)";
- else
- return NULL;
- }
-}
-
-
-LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) {
- CallInfo *ci = L->base_ci + ar->i_ci;
- const char *name = findlocal(L, ci, n);
- lua_lock(L);
- if (name)
- luaA_pushobject(L, ci->base + (n - 1));
- lua_unlock(L);
- return name;
-}
-
-
-LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) {
- CallInfo *ci = L->base_ci + ar->i_ci;
- const char *name = findlocal(L, ci, n);
- lua_lock(L);
- if (name)
- setobjs2s(L, ci->base + (n - 1), L->top - 1);
- L->top--; /* pop value */
- lua_unlock(L);
- return name;
-}
-
-
-static void funcinfo (lua_Debug *ar, Closure *cl) {
- if (cl->c.isC) {
- ar->source = "=[C]";
- ar->linedefined = -1;
- ar->lastlinedefined = -1;
- ar->what = "C";
- }
- else {
- ar->source = getstr(cl->l.p->source);
- ar->linedefined = cl->l.p->linedefined;
- ar->lastlinedefined = cl->l.p->lastlinedefined;
- ar->what = (ar->linedefined == 0) ? "main" : "Lua";
- }
- luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE);
-}
-
-
-static void info_tailcall (lua_Debug *ar) {
- ar->name = ar->namewhat = "";
- ar->what = "tail";
- ar->lastlinedefined = ar->linedefined = ar->currentline = -1;
- ar->source = "=(tail call)";
- luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE);
- ar->nups = 0;
-}
-
-
-static void collectvalidlines (lua_State *L, Closure *f) {
- if (f == NULL || f->c.isC) {
- setnilvalue(L->top);
- }
- else {
- Table *t = luaH_new(L, 0, 0);
- int *lineinfo = f->l.p->lineinfo;
- int i;
- for (i=0; i<f->l.p->sizelineinfo; i++)
- setbvalue(luaH_setnum(L, t, lineinfo[i]), 1);
- sethvalue(L, L->top, t);
- }
- incr_top(L);
-}
-
-
-static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar,
- Closure *f, CallInfo *ci) {
- int status = 1;
- if (f == NULL) {
- info_tailcall(ar);
- return status;
- }
- for (; *what; what++) {
- switch (*what) {
- case 'S': {
- funcinfo(ar, f);
- break;
- }
- case 'l': {
- ar->currentline = (ci) ? currentline(L, ci) : -1;
- break;
- }
- case 'u': {
- ar->nups = f->c.nupvalues;
- break;
- }
- case 'n': {
- ar->namewhat = (ci) ? getfuncname(L, ci, &ar->name) : NULL;
- if (ar->namewhat == NULL) {
- ar->namewhat = ""; /* not found */
- ar->name = NULL;
- }
- break;
- }
- case 'L':
- case 'f': /* handled by lua_getinfo */
- break;
- default: status = 0; /* invalid option */
- }
- }
- return status;
-}
-
-
-LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
- int status;
- Closure *f = NULL;
- CallInfo *ci = NULL;
- lua_lock(L);
- if (*what == '>') {
- StkId func = L->top - 1;
- luai_apicheck(L, ttisfunction(func));
- what++; /* skip the '>' */
- f = clvalue(func);
- L->top--; /* pop function */
- }
- else if (ar->i_ci != 0) { /* no tail call? */
- ci = L->base_ci + ar->i_ci;
- lua_assert(ttisfunction(ci->func));
- f = clvalue(ci->func);
- }
- status = auxgetinfo(L, what, ar, f, ci);
- if (strchr(what, 'f')) {
- if (f == NULL) setnilvalue(L->top);
- else setclvalue(L, L->top, f);
- incr_top(L);
- }
- if (strchr(what, 'L'))
- collectvalidlines(L, f);
- lua_unlock(L);
- return status;
-}
-
-
-/*
-** {======================================================
-** Symbolic Execution and code checker
-** =======================================================
-*/
-
-#define check(x) if (!(x)) return 0;
-
-#define checkjump(pt,pc) check(0 <= pc && pc < pt->sizecode)
-
-#define checkreg(pt,reg) check((reg) < (pt)->maxstacksize)
-
-
-
-static int precheck (const Proto *pt) {
- check(pt->maxstacksize <= MAXSTACK);
- check(pt->numparams+(pt->is_vararg & VARARG_HASARG) <= pt->maxstacksize);
- check(!(pt->is_vararg & VARARG_NEEDSARG) ||
- (pt->is_vararg & VARARG_HASARG));
- check(pt->sizeupvalues <= pt->nups);
- check(pt->sizelineinfo == pt->sizecode || pt->sizelineinfo == 0);
- check(pt->sizecode > 0 && GET_OPCODE(pt->code[pt->sizecode-1]) == OP_RETURN);
- return 1;
-}
-
-
-#define checkopenop(pt,pc) luaG_checkopenop((pt)->code[(pc)+1])
-
-int luaG_checkopenop (Instruction i) {
- switch (GET_OPCODE(i)) {
- case OP_CALL:
- case OP_TAILCALL:
- case OP_RETURN:
- case OP_SETLIST: {
- check(GETARG_B(i) == 0);
- return 1;
- }
- default: return 0; /* invalid instruction after an open call */
- }
-}
-
-
-static int checkArgMode (const Proto *pt, int r, enum OpArgMask mode) {
- switch (mode) {
- case OpArgN: check(r == 0); break;
- case OpArgU: break;
- case OpArgR: checkreg(pt, r); break;
- case OpArgK:
- check(ISK(r) ? INDEXK(r) < pt->sizek : r < pt->maxstacksize);
- break;
- }
- return 1;
-}
-
-
-static Instruction symbexec (const Proto *pt, int lastpc, int reg) {
- int pc;
- int last; /* stores position of last instruction that changed `reg' */
- last = pt->sizecode-1; /* points to final return (a `neutral' instruction) */
- check(precheck(pt));
- for (pc = 0; pc < lastpc; pc++) {
- Instruction i = pt->code[pc];
- OpCode op = GET_OPCODE(i);
- int a = GETARG_A(i);
- int b = 0;
- int c = 0;
- check(op < NUM_OPCODES);
- checkreg(pt, a);
- switch (getOpMode(op)) {
- case iABC: {
- b = GETARG_B(i);
- c = GETARG_C(i);
- check(checkArgMode(pt, b, getBMode(op)));
- check(checkArgMode(pt, c, getCMode(op)));
- break;
- }
- case iABx: {
- b = GETARG_Bx(i);
- if (getBMode(op) == OpArgK) check(b < pt->sizek);
- break;
- }
- case iAsBx: {
- b = GETARG_sBx(i);
- if (getBMode(op) == OpArgR) {
- int dest = pc+1+b;
- check(0 <= dest && dest < pt->sizecode);
- if (dest > 0) {
- int j;
- /* check that it does not jump to a setlist count; this
- is tricky, because the count from a previous setlist may
- have the same value of an invalid setlist; so, we must
- go all the way back to the first of them (if any) */
- for (j = 0; j < dest; j++) {
- Instruction d = pt->code[dest-1-j];
- if (!(GET_OPCODE(d) == OP_SETLIST && GETARG_C(d) == 0)) break;
- }
- /* if 'j' is even, previous value is not a setlist (even if
- it looks like one) */
- check((j&1) == 0);
- }
- }
- break;
- }
- }
- if (testAMode(op)) {
- if (a == reg) last = pc; /* change register `a' */
- }
- if (testTMode(op)) {
- check(pc+2 < pt->sizecode); /* check skip */
- check(GET_OPCODE(pt->code[pc+1]) == OP_JMP);
- }
- switch (op) {
- case OP_LOADBOOL: {
- if (c == 1) { /* does it jump? */
- check(pc+2 < pt->sizecode); /* check its jump */
- check(GET_OPCODE(pt->code[pc+1]) != OP_SETLIST ||
- GETARG_C(pt->code[pc+1]) != 0);
- }
- break;
- }
- case OP_LOADNIL: {
- if (a <= reg && reg <= b)
- last = pc; /* set registers from `a' to `b' */
- break;
- }
- case OP_GETUPVAL:
- case OP_SETUPVAL: {
- check(b < pt->nups);
- break;
- }
- case OP_GETGLOBAL:
- case OP_SETGLOBAL: {
- check(ttisstring(&pt->k[b]));
- break;
- }
- case OP_SELF: {
- checkreg(pt, a+1);
- if (reg == a+1) last = pc;
- break;
- }
- case OP_CONCAT: {
- check(b < c); /* at least two operands */
- break;
- }
- case OP_TFORLOOP: {
- check(c >= 1); /* at least one result (control variable) */
- checkreg(pt, a+2+c); /* space for results */
- if (reg >= a+2) last = pc; /* affect all regs above its base */
- break;
- }
- case OP_FORLOOP:
- case OP_FORPREP:
- checkreg(pt, a+3);
- /* go through */
- case OP_JMP: {
- int dest = pc+1+b;
- /* not full check and jump is forward and do not skip `lastpc'? */
- if (reg != NO_REG && pc < dest && dest <= lastpc)
- pc += b; /* do the jump */
- break;
- }
- case OP_CALL:
- case OP_TAILCALL: {
- if (b != 0) {
- checkreg(pt, a+b-1);
- }
- c--; /* c = num. returns */
- if (c == LUA_MULTRET) {
- check(checkopenop(pt, pc));
- }
- else if (c != 0)
- checkreg(pt, a+c-1);
- if (reg >= a) last = pc; /* affect all registers above base */
- break;
- }
- case OP_RETURN: {
- b--; /* b = num. returns */
- if (b > 0) checkreg(pt, a+b-1);
- break;
- }
- case OP_SETLIST: {
- if (b > 0) checkreg(pt, a + b);
- if (c == 0) {
- pc++;
- check(pc < pt->sizecode - 1);
- }
- break;
- }
- case OP_CLOSURE: {
- int nup, j;
- check(b < pt->sizep);
- nup = pt->p[b]->nups;
- check(pc + nup < pt->sizecode);
- for (j = 1; j <= nup; j++) {
- OpCode op1 = GET_OPCODE(pt->code[pc + j]);
- check(op1 == OP_GETUPVAL || op1 == OP_MOVE);
- }
- if (reg != NO_REG) /* tracing? */
- pc += nup; /* do not 'execute' these pseudo-instructions */
- break;
- }
- case OP_VARARG: {
- check((pt->is_vararg & VARARG_ISVARARG) &&
- !(pt->is_vararg & VARARG_NEEDSARG));
- b--;
- if (b == LUA_MULTRET) check(checkopenop(pt, pc));
- checkreg(pt, a+b-1);
- break;
- }
- default: break;
- }
- }
- return pt->code[last];
-}
-
-#undef check
-#undef checkjump
-#undef checkreg
-
-/* }====================================================== */
-
-
-int luaG_checkcode (const Proto *pt) {
- return (symbexec(pt, pt->sizecode, NO_REG) != 0);
-}
-
-
-static const char *kname (Proto *p, int c) {
- if (ISK(c) && ttisstring(&p->k[INDEXK(c)]))
- return svalue(&p->k[INDEXK(c)]);
- else
- return "?";
-}
-
-
-static const char *getobjname (lua_State *L, CallInfo *ci, int stackpos,
- const char **name) {
- if (isLua(ci)) { /* a Lua function? */
- Proto *p = ci_func(ci)->l.p;
- int pc = currentpc(L, ci);
- Instruction i;
- *name = luaF_getlocalname(p, stackpos+1, pc);
- if (*name) /* is a local? */
- return "local";
- i = symbexec(p, pc, stackpos); /* try symbolic execution */
- lua_assert(pc != -1);
- switch (GET_OPCODE(i)) {
- case OP_GETGLOBAL: {
- int g = GETARG_Bx(i); /* global index */
- lua_assert(ttisstring(&p->k[g]));
- *name = svalue(&p->k[g]);
- return "global";
- }
- case OP_MOVE: {
- int a = GETARG_A(i);
- int b = GETARG_B(i); /* move from `b' to `a' */
- if (b < a)
- return getobjname(L, ci, b, name); /* get name for `b' */
- break;
- }
- case OP_GETTABLE: {
- int k = GETARG_C(i); /* key index */
- *name = kname(p, k);
- return "field";
- }
- case OP_GETUPVAL: {
- int u = GETARG_B(i); /* upvalue index */
- *name = p->upvalues ? getstr(p->upvalues[u]) : "?";
- return "upvalue";
- }
- case OP_SELF: {
- int k = GETARG_C(i); /* key index */
- *name = kname(p, k);
- return "method";
- }
- default: break;
- }
- }
- return NULL; /* no useful name found */
-}
-
-
-static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) {
- Instruction i;
- if ((isLua(ci) && ci->tailcalls > 0) || !isLua(ci - 1))
- return NULL; /* calling function is not Lua (or is unknown) */
- ci--; /* calling function */
- i = ci_func(ci)->l.p->code[currentpc(L, ci)];
- if (GET_OPCODE(i) == OP_CALL || GET_OPCODE(i) == OP_TAILCALL ||
- GET_OPCODE(i) == OP_TFORLOOP)
- return getobjname(L, ci, GETARG_A(i), name);
- else
- return NULL; /* no useful name can be found */
-}
-
-
-/* only ANSI way to check whether a pointer points to an array */
-static int isinstack (CallInfo *ci, const TValue *o) {
- StkId p;
- for (p = ci->base; p < ci->top; p++)
- if (o == p) return 1;
- return 0;
-}
-
-
-void luaG_typeerror (lua_State *L, const TValue *o, const char *op) {
- const char *name = NULL;
- const char *t = luaT_typenames[ttype(o)];
- const char *kind = (isinstack(L->ci, o)) ?
- getobjname(L, L->ci, cast_int(o - L->base), &name) :
- NULL;
- if (kind)
- luaG_runerror(L, "attempt to %s %s " LUA_QS " (a %s value)",
- op, kind, name, t);
- else
- luaG_runerror(L, "attempt to %s a %s value", op, t);
-}
-
-
-void luaG_concaterror (lua_State *L, StkId p1, StkId p2) {
- if (ttisstring(p1) || ttisnumber(p1)) p1 = p2;
- lua_assert(!ttisstring(p1) && !ttisnumber(p1));
- luaG_typeerror(L, p1, "concatenate");
-}
-
-
-void luaG_aritherror (lua_State *L, const TValue *p1, const TValue *p2) {
- TValue temp;
- if (luaV_tonumber(p1, &temp) == NULL)
- p2 = p1; /* first operand is wrong */
- luaG_typeerror(L, p2, "perform arithmetic on");
-}
-
-
-int luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p2) {
- const char *t1 = luaT_typenames[ttype(p1)];
- const char *t2 = luaT_typenames[ttype(p2)];
- if (t1[2] == t2[2])
- luaG_runerror(L, "attempt to compare two %s values", t1);
- else
- luaG_runerror(L, "attempt to compare %s with %s", t1, t2);
- return 0;
-}
-
-
-static void addinfo (lua_State *L, const char *msg) {
- CallInfo *ci = L->ci;
- if (isLua(ci)) { /* is Lua code? */
- char buff[LUA_IDSIZE]; /* add file:line information */
- int line = currentline(L, ci);
- luaO_chunkid(buff, getstr(getluaproto(ci)->source), LUA_IDSIZE);
- luaO_pushfstring(L, "%s:%d: %s", buff, line, msg);
- }
-}
-
-
-void luaG_errormsg (lua_State *L) {
- if (L->errfunc != 0) { /* is there an error handling function? */
- StkId errfunc = restorestack(L, L->errfunc);
- if (!ttisfunction(errfunc)) luaD_throw(L, LUA_ERRERR);
- setobjs2s(L, L->top, L->top - 1); /* move argument */
- setobjs2s(L, L->top - 1, errfunc); /* push function */
- incr_top(L);
- luaD_call(L, L->top - 2, 1); /* call it */
- }
- luaD_throw(L, LUA_ERRRUN);
-}
-
-
-void luaG_runerror (lua_State *L, const char *fmt, ...) {
- va_list argp;
- va_start(argp, fmt);
- addinfo(L, luaO_pushvfstring(L, fmt, argp));
- va_end(argp);
- luaG_errormsg(L);
-}
-
diff --git a/crawl-ref/source/util/lua/src/ldebug.h b/crawl-ref/source/util/lua/src/ldebug.h
deleted file mode 100644
index ba28a97248..0000000000
--- a/crawl-ref/source/util/lua/src/ldebug.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
-** $Id: ldebug.h,v 2.3.1.1 2007/12/27 13:02:25 roberto Exp $
-** Auxiliary functions from Debug Interface module
-** See Copyright Notice in lua.h
-*/
-
-#ifndef ldebug_h
-#define ldebug_h
-
-
-#include "lstate.h"
-
-
-#define pcRel(pc, p) (cast(int, (pc) - (p)->code) - 1)
-
-#define getline(f,pc) (((f)->lineinfo) ? (f)->lineinfo[pc] : 0)
-
-#define resethookcount(L) (L->hookcount = L->basehookcount)
-
-
-LUAI_FUNC void luaG_typeerror (lua_State *L, const TValue *o,
- const char *opname);
-LUAI_FUNC void luaG_concaterror (lua_State *L, StkId p1, StkId p2);
-LUAI_FUNC void luaG_aritherror (lua_State *L, const TValue *p1,
- const TValue *p2);
-LUAI_FUNC int luaG_ordererror (lua_State *L, const TValue *p1,
- const TValue *p2);
-LUAI_FUNC void luaG_runerror (lua_State *L, const char *fmt, ...);
-LUAI_FUNC void luaG_errormsg (lua_State *L);
-LUAI_FUNC int luaG_checkcode (const Proto *pt);
-LUAI_FUNC int luaG_checkopenop (Instruction i);
-
-#endif
diff --git a/crawl-ref/source/util/lua/src/ldo.c b/crawl-ref/source/util/lua/src/ldo.c
deleted file mode 100644
index 8de05f728e..0000000000
--- a/crawl-ref/source/util/lua/src/ldo.c
+++ /dev/null
@@ -1,518 +0,0 @@
-/*
-** $Id: ldo.c,v 2.38.1.3 2008/01/18 22:31:22 roberto Exp $
-** Stack and Call structure of Lua
-** See Copyright Notice in lua.h
-*/
-
-
-#include <setjmp.h>
-#include <stdlib.h>
-#include <string.h>
-
-#define ldo_c
-#define LUA_CORE
-
-#include "lua.h"
-
-#include "ldebug.h"
-#include "ldo.h"
-#include "lfunc.h"
-#include "lgc.h"
-#include "lmem.h"
-#include "lobject.h"
-#include "lopcodes.h"
-#include "lparser.h"
-#include "lstate.h"
-#include "lstring.h"
-#include "ltable.h"
-#include "ltm.h"
-#include "lundump.h"
-#include "lvm.h"
-#include "lzio.h"
-
-
-
-
-/*
-** {======================================================
-** Error-recovery functions
-** =======================================================
-*/
-
-
-/* chain list of long jump buffers */
-struct lua_longjmp {
- struct lua_longjmp *previous;
- luai_jmpbuf b;
- volatile int status; /* error code */
-};
-
-
-void luaD_seterrorobj (lua_State *L, int errcode, StkId oldtop) {
- switch (errcode) {
- case LUA_ERRMEM: {
- setsvalue2s(L, oldtop, luaS_newliteral(L, MEMERRMSG));
- break;
- }
- case LUA_ERRERR: {
- setsvalue2s(L, oldtop, luaS_newliteral(L, "error in error handling"));
- break;
- }
- case LUA_ERRSYNTAX:
- case LUA_ERRRUN: {
- setobjs2s(L, oldtop, L->top - 1); /* error message on current top */
- break;
- }
- }
- L->top = oldtop + 1;
-}
-
-
-static void restore_stack_limit (lua_State *L) {
- lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK - 1);
- if (L->size_ci > LUAI_MAXCALLS) { /* there was an overflow? */
- int inuse = cast_int(L->ci - L->base_ci);
- if (inuse + 1 < LUAI_MAXCALLS) /* can `undo' overflow? */
- luaD_reallocCI(L, LUAI_MAXCALLS);
- }
-}
-
-
-static void resetstack (lua_State *L, int status) {
- L->ci = L->base_ci;
- L->base = L->ci->base;
- luaF_close(L, L->base); /* close eventual pending closures */
- luaD_seterrorobj(L, status, L->base);
- L->nCcalls = L->baseCcalls;
- L->allowhook = 1;
- restore_stack_limit(L);
- L->errfunc = 0;
- L->errorJmp = NULL;
-}
-
-
-void luaD_throw (lua_State *L, int errcode) {
- if (L->errorJmp) {
- L->errorJmp->status = errcode;
- LUAI_THROW(L, L->errorJmp);
- }
- else {
- L->status = cast_byte(errcode);
- if (G(L)->panic) {
- resetstack(L, errcode);
- lua_unlock(L);
- G(L)->panic(L);
- }
- exit(EXIT_FAILURE);
- }
-}
-
-
-int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) {
- struct lua_longjmp lj;
- lj.status = 0;
- lj.previous = L->errorJmp; /* chain new error handler */
- L->errorJmp = &lj;
- LUAI_TRY(L, &lj,
- (*f)(L, ud);
- );
- L->errorJmp = lj.previous; /* restore old error handler */
- return lj.status;
-}
-
-/* }====================================================== */
-
-
-static void correctstack (lua_State *L, TValue *oldstack) {
- CallInfo *ci;
- GCObject *up;
- L->top = (L->top - oldstack) + L->stack;
- for (up = L->openupval; up != NULL; up = up->gch.next)
- gco2uv(up)->v = (gco2uv(up)->v - oldstack) + L->stack;
- for (ci = L->base_ci; ci <= L->ci; ci++) {
- ci->top = (ci->top - oldstack) + L->stack;
- ci->base = (ci->base - oldstack) + L->stack;
- ci->func = (ci->func - oldstack) + L->stack;
- }
- L->base = (L->base - oldstack) + L->stack;
-}
-
-
-void luaD_reallocstack (lua_State *L, int newsize) {
- TValue *oldstack = L->stack;
- int realsize = newsize + 1 + EXTRA_STACK;
- lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK - 1);
- luaM_reallocvector(L, L->stack, L->stacksize, realsize, TValue);
- L->stacksize = realsize;
- L->stack_last = L->stack+newsize;
- correctstack(L, oldstack);
-}
-
-
-void luaD_reallocCI (lua_State *L, int newsize) {
- CallInfo *oldci = L->base_ci;
- luaM_reallocvector(L, L->base_ci, L->size_ci, newsize, CallInfo);
- L->size_ci = newsize;
- L->ci = (L->ci - oldci) + L->base_ci;
- L->end_ci = L->base_ci + L->size_ci - 1;
-}
-
-
-void luaD_growstack (lua_State *L, int n) {
- if (n <= L->stacksize) /* double size is enough? */
- luaD_reallocstack(L, 2*L->stacksize);
- else
- luaD_reallocstack(L, L->stacksize + n);
-}
-
-
-static CallInfo *growCI (lua_State *L) {
- if (L->size_ci > LUAI_MAXCALLS) /* overflow while handling overflow? */
- luaD_throw(L, LUA_ERRERR);
- else {
- luaD_reallocCI(L, 2*L->size_ci);
- if (L->size_ci > LUAI_MAXCALLS)
- luaG_runerror(L, "stack overflow");
- }
- return ++L->ci;
-}
-
-
-void luaD_callhook (lua_State *L, int event, int line) {
- lua_Hook hook = L->hook;
- if (hook && L->allowhook) {
- ptrdiff_t top = savestack(L, L->top);
- ptrdiff_t ci_top = savestack(L, L->ci->top);
- lua_Debug ar;
- ar.event = event;
- ar.currentline = line;
- if (event == LUA_HOOKTAILRET)
- ar.i_ci = 0; /* tail call; no debug information about it */
- else
- ar.i_ci = cast_int(L->ci - L->base_ci);
- luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */
- L->ci->top = L->top + LUA_MINSTACK;
- lua_assert(L->ci->top <= L->stack_last);
- L->allowhook = 0; /* cannot call hooks inside a hook */
- lua_unlock(L);
- (*hook)(L, &ar);
- lua_lock(L);
- lua_assert(!L->allowhook);
- L->allowhook = 1;
- L->ci->top = restorestack(L, ci_top);
- L->top = restorestack(L, top);
- }
-}
-
-
-static StkId adjust_varargs (lua_State *L, Proto *p, int actual) {
- int i;
- int nfixargs = p->numparams;
- Table *htab = NULL;
- StkId base, fixed;
- for (; actual < nfixargs; ++actual)
- setnilvalue(L->top++);
-#if defined(LUA_COMPAT_VARARG)
- if (p->is_vararg & VARARG_NEEDSARG) { /* compat. with old-style vararg? */
- int nvar = actual - nfixargs; /* number of extra arguments */
- lua_assert(p->is_vararg & VARARG_HASARG);
- luaC_checkGC(L);
- htab = luaH_new(L, nvar, 1); /* create `arg' table */
- for (i=0; i<nvar; i++) /* put extra arguments into `arg' table */
- setobj2n(L, luaH_setnum(L, htab, i+1), L->top - nvar + i);
- /* store counter in field `n' */
- setnvalue(luaH_setstr(L, htab, luaS_newliteral(L, "n")), cast_num(nvar));
- }
-#endif
- /* move fixed parameters to final position */
- fixed = L->top - actual; /* first fixed argument */
- base = L->top; /* final position of first argument */
- for (i=0; i<nfixargs; i++) {
- setobjs2s(L, L->top++, fixed+i);
- setnilvalue(fixed+i);
- }
- /* add `arg' parameter */
- if (htab) {
- sethvalue(L, L->top++, htab);
- lua_assert(iswhite(obj2gco(htab)));
- }
- return base;
-}
-
-
-static StkId tryfuncTM (lua_State *L, StkId func) {
- const TValue *tm = luaT_gettmbyobj(L, func, TM_CALL);
- StkId p;
- ptrdiff_t funcr = savestack(L, func);
- if (!ttisfunction(tm))
- luaG_typeerror(L, func, "call");
- /* Open a hole inside the stack at `func' */
- for (p = L->top; p > func; p--) setobjs2s(L, p, p-1);
- incr_top(L);
- func = restorestack(L, funcr); /* previous call may change stack */
- setobj2s(L, func, tm); /* tag method is the new function to be called */
- return func;
-}
-
-
-
-#define inc_ci(L) \
- ((L->ci == L->end_ci) ? growCI(L) : \
- (condhardstacktests(luaD_reallocCI(L, L->size_ci)), ++L->ci))
-
-
-int luaD_precall (lua_State *L, StkId func, int nresults) {
- LClosure *cl;
- ptrdiff_t funcr;
- if (!ttisfunction(func)) /* `func' is not a function? */
- func = tryfuncTM(L, func); /* check the `function' tag method */
- funcr = savestack(L, func);
- cl = &clvalue(func)->l;
- L->ci->savedpc = L->savedpc;
- if (!cl->isC) { /* Lua function? prepare its call */
- CallInfo *ci;
- StkId st, base;
- Proto *p = cl->p;
- luaD_checkstack(L, p->maxstacksize);
- func = restorestack(L, funcr);
- if (!p->is_vararg) { /* no varargs? */
- base = func + 1;
- if (L->top > base + p->numparams)
- L->top = base + p->numparams;
- }
- else { /* vararg function */
- int nargs = cast_int(L->top - func) - 1;
- base = adjust_varargs(L, p, nargs);
- func = restorestack(L, funcr); /* previous call may change the stack */
- }
- ci = inc_ci(L); /* now `enter' new function */
- ci->func = func;
- L->base = ci->base = base;
- ci->top = L->base + p->maxstacksize;
- lua_assert(ci->top <= L->stack_last);
- L->savedpc = p->code; /* starting point */
- ci->tailcalls = 0;
- ci->nresults = nresults;
- for (st = L->top; st < ci->top; st++)
- setnilvalue(st);
- L->top = ci->top;
- if (L->hookmask & LUA_MASKCALL) {
- L->savedpc++; /* hooks assume 'pc' is already incremented */
- luaD_callhook(L, LUA_HOOKCALL, -1);
- L->savedpc--; /* correct 'pc' */
- }
- return PCRLUA;
- }
- else { /* if is a C function, call it */
- CallInfo *ci;
- int n;
- luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */
- ci = inc_ci(L); /* now `enter' new function */
- ci->func = restorestack(L, funcr);
- L->base = ci->base = ci->func + 1;
- ci->top = L->top + LUA_MINSTACK;
- lua_assert(ci->top <= L->stack_last);
- ci->nresults = nresults;
- if (L->hookmask & LUA_MASKCALL)
- luaD_callhook(L, LUA_HOOKCALL, -1);
- lua_unlock(L);
- n = (*curr_func(L)->c.f)(L); /* do the actual call */
- lua_lock(L);
- if (n < 0) /* yielding? */
- return PCRYIELD;
- else {
- luaD_poscall(L, L->top - n);
- return PCRC;
- }
- }
-}
-
-
-static StkId callrethooks (lua_State *L, StkId firstResult) {
- ptrdiff_t fr = savestack(L, firstResult); /* next call may change stack */
- luaD_callhook(L, LUA_HOOKRET, -1);
- if (f_isLua(L->ci)) { /* Lua function? */
- while ((L->hookmask & LUA_MASKRET) && L->ci->tailcalls--) /* tail calls */
- luaD_callhook(L, LUA_HOOKTAILRET, -1);
- }
- return restorestack(L, fr);
-}
-
-
-int luaD_poscall (lua_State *L, StkId firstResult) {
- StkId res;
- int wanted, i;
- CallInfo *ci;
- if (L->hookmask & LUA_MASKRET)
- firstResult = callrethooks(L, firstResult);
- ci = L->ci--;
- res = ci->func; /* res == final position of 1st result */
- wanted = ci->nresults;
- L->base = (ci - 1)->base; /* restore base */
- L->savedpc = (ci - 1)->savedpc; /* restore savedpc */
- /* move results to correct place */
- for (i = wanted; i != 0 && firstResult < L->top; i--)
- setobjs2s(L, res++, firstResult++);
- while (i-- > 0)
- setnilvalue(res++);
- L->top = res;
- return (wanted - LUA_MULTRET); /* 0 iff wanted == LUA_MULTRET */
-}
-
-
-/*
-** Call a function (C or Lua). The function to be called is at *func.
-** The arguments are on the stack, right after the function.
-** When returns, all the results are on the stack, starting at the original
-** function position.
-*/
-void luaD_call (lua_State *L, StkId func, int nResults) {
- if (++L->nCcalls >= LUAI_MAXCCALLS) {
- if (L->nCcalls == LUAI_MAXCCALLS)
- luaG_runerror(L, "C stack overflow");
- else if (L->nCcalls >= (LUAI_MAXCCALLS + (LUAI_MAXCCALLS>>3)))
- luaD_throw(L, LUA_ERRERR); /* error while handing stack error */
- }
- if (luaD_precall(L, func, nResults) == PCRLUA) /* is a Lua function? */
- luaV_execute(L, 1); /* call it */
- L->nCcalls--;
- luaC_checkGC(L);
-}
-
-
-static void resume (lua_State *L, void *ud) {
- StkId firstArg = cast(StkId, ud);
- CallInfo *ci = L->ci;
- if (L->status == 0) { /* start coroutine? */
- lua_assert(ci == L->base_ci && firstArg > L->base);
- if (luaD_precall(L, firstArg - 1, LUA_MULTRET) != PCRLUA)
- return;
- }
- else { /* resuming from previous yield */
- lua_assert(L->status == LUA_YIELD);
- L->status = 0;
- if (!f_isLua(ci)) { /* `common' yield? */
- /* finish interrupted execution of `OP_CALL' */
- lua_assert(GET_OPCODE(*((ci-1)->savedpc - 1)) == OP_CALL ||
- GET_OPCODE(*((ci-1)->savedpc - 1)) == OP_TAILCALL);
- if (luaD_poscall(L, firstArg)) /* complete it... */
- L->top = L->ci->top; /* and correct top if not multiple results */
- }
- else /* yielded inside a hook: just continue its execution */
- L->base = L->ci->base;
- }
- luaV_execute(L, cast_int(L->ci - L->base_ci));
-}
-
-
-static int resume_error (lua_State *L, const char *msg) {
- L->top = L->ci->base;
- setsvalue2s(L, L->top, luaS_new(L, msg));
- incr_top(L);
- lua_unlock(L);
- return LUA_ERRRUN;
-}
-
-
-LUA_API int lua_resume (lua_State *L, int nargs) {
- int status;
- lua_lock(L);
- if (L->status != LUA_YIELD && (L->status != 0 || L->ci != L->base_ci))
- return resume_error(L, "cannot resume non-suspended coroutine");
- if (L->nCcalls >= LUAI_MAXCCALLS)
- return resume_error(L, "C stack overflow");
- luai_userstateresume(L, nargs);
- lua_assert(L->errfunc == 0);
- L->baseCcalls = ++L->nCcalls;
- status = luaD_rawrunprotected(L, resume, L->top - nargs);
- if (status != 0) { /* error? */
- L->status = cast_byte(status); /* mark thread as `dead' */
- luaD_seterrorobj(L, status, L->top);
- L->ci->top = L->top;
- }
- else {
- lua_assert(L->nCcalls == L->baseCcalls);
- status = L->status;
- }
- --L->nCcalls;
- lua_unlock(L);
- return status;
-}
-
-
-LUA_API int lua_yield (lua_State *L, int nresults) {
- luai_userstateyield(L, nresults);
- lua_lock(L);
- if (L->nCcalls > L->baseCcalls)
- luaG_runerror(L, "attempt to yield across metamethod/C-call boundary");
- L->base = L->top - nresults; /* protect stack slots below */
- L->status = LUA_YIELD;
- lua_unlock(L);
- return -1;
-}
-
-
-int luaD_pcall (lua_State *L, Pfunc func, void *u,
- ptrdiff_t old_top, ptrdiff_t ef) {
- int status;
- unsigned short oldnCcalls = L->nCcalls;
- ptrdiff_t old_ci = saveci(L, L->ci);
- lu_byte old_allowhooks = L->allowhook;
- ptrdiff_t old_errfunc = L->errfunc;
- L->errfunc = ef;
- status = luaD_rawrunprotected(L, func, u);
- if (status != 0) { /* an error occurred? */
- StkId oldtop = restorestack(L, old_top);
- luaF_close(L, oldtop); /* close eventual pending closures */
- luaD_seterrorobj(L, status, oldtop);
- L->nCcalls = oldnCcalls;
- L->ci = restoreci(L, old_ci);
- L->base = L->ci->base;
- L->savedpc = L->ci->savedpc;
- L->allowhook = old_allowhooks;
- restore_stack_limit(L);
- }
- L->errfunc = old_errfunc;
- return status;
-}
-
-
-
-/*
-** Execute a protected parser.
-*/
-struct SParser { /* data to `f_parser' */
- ZIO *z;
- Mbuffer buff; /* buffer to be used by the scanner */
- const char *name;
-};
-
-static void f_parser (lua_State *L, void *ud) {
- int i;
- Proto *tf;
- Closure *cl;
- struct SParser *p = cast(struct SParser *, ud);
- int c = luaZ_lookahead(p->z);
- luaC_checkGC(L);
- tf = ((c == LUA_SIGNATURE[0]) ? luaU_undump : luaY_parser)(L, p->z,
- &p->buff, p->name);
- cl = luaF_newLclosure(L, tf->nups, hvalue(gt(L)));
- cl->l.p = tf;
- for (i = 0; i < tf->nups; i++) /* initialize eventual upvalues */
- cl->l.upvals[i] = luaF_newupval(L);
- setclvalue(L, L->top, cl);
- incr_top(L);
-}
-
-
-int luaD_protectedparser (lua_State *L, ZIO *z, const char *name) {
- struct SParser p;
- int status;
- p.z = z; p.name = name;
- luaZ_initbuffer(L, &p.buff);
- status = luaD_pcall(L, f_parser, &p, savestack(L, L->top), L->errfunc);
- luaZ_freebuffer(L, &p.buff);
- return status;
-}
-
-
diff --git a/crawl-ref/source/util/lua/src/ldo.h b/crawl-ref/source/util/lua/src/ldo.h
deleted file mode 100644
index 98fddac59f..0000000000
--- a/crawl-ref/source/util/lua/src/ldo.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
-** $Id: ldo.h,v 2.7.1.1 2007/12/27 13:02:25 roberto Exp $
-** Stack and Call structure of Lua
-** See Copyright Notice in lua.h
-*/
-
-#ifndef ldo_h
-#define ldo_h
-
-
-#include "lobject.h"
-#include "lstate.h"
-#include "lzio.h"
-
-
-#define luaD_checkstack(L,n) \
- if ((char *)L->stack_last - (char *)L->top <= (n)*(int)sizeof(TValue)) \
- luaD_growstack(L, n); \
- else condhardstacktests(luaD_reallocstack(L, L->stacksize - EXTRA_STACK - 1));
-
-
-#define incr_top(L) {luaD_checkstack(L,1); L->top++;}
-
-#define savestack(L,p) ((char *)(p) - (char *)L->stack)
-#define restorestack(L,n) ((TValue *)((char *)L->stack + (n)))
-
-#define saveci(L,p) ((char *)(p) - (char *)L->base_ci)
-#define restoreci(L,n) ((CallInfo *)((char *)L->base_ci + (n)))
-
-
-/* results from luaD_precall */
-#define PCRLUA 0 /* initiated a call to a Lua function */
-#define PCRC 1 /* did a call to a C function */
-#define PCRYIELD 2 /* C funtion yielded */
-
-
-/* type of protected functions, to be ran by `runprotected' */
-typedef void (*Pfunc) (lua_State *L, void *ud);
-
-LUAI_FUNC int luaD_protectedparser (lua_State *L, ZIO *z, const char *name);
-LUAI_FUNC void luaD_callhook (lua_State *L, int event, int line);
-LUAI_FUNC int luaD_precall (lua_State *L, StkId func, int nresults);
-LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults);
-LUAI_FUNC int luaD_pcall (lua_State *L, Pfunc func, void *u,
- ptrdiff_t oldtop, ptrdiff_t ef);
-LUAI_FUNC int luaD_poscall (lua_State *L, StkId firstResult);
-LUAI_FUNC void luaD_reallocCI (lua_State *L, int newsize);
-LUAI_FUNC void luaD_reallocstack (lua_State *L, int newsize);
-LUAI_FUNC void luaD_growstack (lua_State *L, int n);
-
-LUAI_FUNC void luaD_throw (lua_State *L, int errcode);
-LUAI_FUNC int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud);
-
-LUAI_FUNC void luaD_seterrorobj (lua_State *L, int errcode, StkId oldtop);
-
-#endif
-
diff --git a/crawl-ref/source/util/lua/src/ldump.c b/crawl-ref/source/util/lua/src/ldump.c
deleted file mode 100644
index 7ff01cc565..0000000000
--- a/crawl-ref/source/util/lua/src/ldump.c
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
-** $Id: ldump.c,v 2.8.1.1 2007/12/27 13:02:25 roberto Exp $
-** save precompiled Lua chunks
-** See Copyright Notice in lua.h
-*/
-
-#include <stddef.h>
-
-#define ldump_c
-#define LUA_CORE
-
-#include "lua.h"
-
-#include "lobject.h"
-#include "lstate.h"
-#include "lundump.h"
-
-typedef struct {
- lua_State* L;
- lua_Writer writer;
- void* data;
- int strip;
- int status;
-} DumpState;
-
-#define DumpMem(b,n,size,D) DumpBlock(b,(n)*(size),D)
-#define DumpVar(x,D) DumpMem(&x,1,sizeof(x),D)
-
-static void DumpBlock(const void* b, size_t size, DumpState* D)
-{
- if (D->status==0)
- {
- lua_unlock(D->L);
- D->status=(*D->writer)(D->L,b,size,D->data);
- lua_lock(D->L);
- }
-}
-
-static void DumpChar(int y, DumpState* D)
-{
- char x=(char)y;
- DumpVar(x,D);
-}
-
-static void DumpInt(int x, DumpState* D)
-{
- DumpVar(x,D);
-}
-
-static void DumpNumber(lua_Number x, DumpState* D)
-{
- DumpVar(x,D);
-}
-
-static void DumpVector(const void* b, int n, size_t size, DumpState* D)
-{
- DumpInt(n,D);
- DumpMem(b,n,size,D);
-}
-
-static void DumpString(const TString* s, DumpState* D)
-{
- if (s==NULL || getstr(s)==NULL)
- {
- unsigned int size=0;
- DumpVar(size,D);
- }
- else
- {
- unsigned int size=s->tsv.len+1; /* include trailing '\0' */
- DumpVar(size,D);
- DumpBlock(getstr(s),size,D);
- }
-}
-
-#define DumpCode(f,D) DumpVector(f->code,f->sizecode,sizeof(Instruction),D)
-
-static void DumpFunction(const Proto* f, const TString* p, DumpState* D);
-
-static void DumpConstants(const Proto* f, DumpState* D)
-{
- int i,n=f->sizek;
- DumpInt(n,D);
- for (i=0; i<n; i++)
- {
- const TValue* o=&f->k[i];
- DumpChar(ttype(o),D);
- switch (ttype(o))
- {
- case LUA_TNIL:
- break;
- case LUA_TBOOLEAN:
- DumpChar(bvalue(o),D);
- break;
- case LUA_TNUMBER:
- DumpNumber(nvalue(o),D);
- break;
- case LUA_TSTRING:
- DumpString(rawtsvalue(o),D);
- break;
- default:
- lua_assert(0); /* cannot happen */
- break;
- }
- }
- n=f->sizep;
- DumpInt(n,D);
- for (i=0; i<n; i++) DumpFunction(f->p[i],f->source,D);
-}
-
-static void DumpDebug(const Proto* f, DumpState* D)
-{
- int i,n;
- n= (D->strip) ? 0 : f->sizelineinfo;
- DumpVector(f->lineinfo,n,sizeof(int),D);
- n= (D->strip) ? 0 : f->sizelocvars;
- DumpInt(n,D);
- for (i=0; i<n; i++)
- {
- DumpString(f->locvars[i].varname,D);
- DumpInt(f->locvars[i].startpc,D);
- DumpInt(f->locvars[i].endpc,D);
- }
- n= (D->strip) ? 0 : f->sizeupvalues;
- DumpInt(n,D);
- for (i=0; i<n; i++) DumpString(f->upvalues[i],D);
-}
-
-static void DumpFunction(const Proto* f, const TString* p, DumpState* D)
-{
- DumpString((f->source==p || D->strip) ? NULL : f->source,D);
- DumpInt(f->linedefined,D);
- DumpInt(f->lastlinedefined,D);
- DumpChar(f->nups,D);
- DumpChar(f->numparams,D);
- DumpChar(f->is_vararg,D);
- DumpChar(f->maxstacksize,D);
- DumpCode(f,D);
- DumpConstants(f,D);
- DumpDebug(f,D);
-}
-
-static void DumpHeader(DumpState* D)
-{
- char h[LUAC_HEADERSIZE];
- luaU_header(h);
- DumpBlock(h,LUAC_HEADERSIZE,D);
-}
-
-/*
-** dump Lua function as precompiled chunk
-*/
-int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip)
-{
- DumpState D;
- D.L=L;
- D.writer=w;
- D.data=data;
- D.strip=strip;
- D.status=0;
- DumpHeader(&D);
- DumpFunction(f,NULL,&D);
- return D.status;
-}
diff --git a/crawl-ref/source/util/lua/src/lfunc.c b/crawl-ref/source/util/lua/src/lfunc.c
deleted file mode 100644
index 813e88f583..0000000000
--- a/crawl-ref/source/util/lua/src/lfunc.c
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
-** $Id: lfunc.c,v 2.12.1.2 2007/12/28 14:58:43 roberto Exp $
-** Auxiliary functions to manipulate prototypes and closures
-** See Copyright Notice in lua.h
-*/
-
-
-#include <stddef.h>
-
-#define lfunc_c
-#define LUA_CORE
-
-#include "lua.h"
-
-#include "lfunc.h"
-#include "lgc.h"
-#include "lmem.h"
-#include "lobject.h"
-#include "lstate.h"
-
-
-
-Closure *luaF_newCclosure (lua_State *L, int nelems, Table *e) {
- Closure *c = cast(Closure *, luaM_malloc(L, sizeCclosure(nelems)));
- luaC_link(L, obj2gco(c), LUA_TFUNCTION);
- c->c.isC = 1;
- c->c.env = e;
- c->c.nupvalues = cast_byte(nelems);
- return c;
-}
-
-
-Closure *luaF_newLclosure (lua_State *L, int nelems, Table *e) {
- Closure *c = cast(Closure *, luaM_malloc(L, sizeLclosure(nelems)));
- luaC_link(L, obj2gco(c), LUA_TFUNCTION);
- c->l.isC = 0;
- c->l.env = e;
- c->l.nupvalues = cast_byte(nelems);
- while (nelems--) c->l.upvals[nelems] = NULL;
- return c;
-}
-
-
-UpVal *luaF_newupval (lua_State *L) {
- UpVal *uv = luaM_new(L, UpVal);
- luaC_link(L, obj2gco(uv), LUA_TUPVAL);
- uv->v = &uv->u.value;
- setnilvalue(uv->v);
- return uv;
-}
-
-
-UpVal *luaF_findupval (lua_State *L, StkId level) {
- global_State *g = G(L);
- GCObject **pp = &L->openupval;
- UpVal *p;
- UpVal *uv;
- while (*pp != NULL && (p = ngcotouv(*pp))->v >= level) {
- lua_assert(p->v != &p->u.value);
- if (p->v == level) { /* found a corresponding upvalue? */
- if (isdead(g, obj2gco(p))) /* is it dead? */
- changewhite(obj2gco(p)); /* ressurect it */
- return p;
- }
- pp = &p->next;
- }
- uv = luaM_new(L, UpVal); /* not found: create a new one */
- uv->tt = LUA_TUPVAL;
- uv->marked = luaC_white(g);
- uv->v = level; /* current value lives in the stack */
- uv->next = *pp; /* chain it in the proper position */
- *pp = obj2gco(uv);
- uv->u.l.prev = &g->uvhead; /* double link it in `uvhead' list */
- uv->u.l.next = g->uvhead.u.l.next;
- uv->u.l.next->u.l.prev = uv;
- g->uvhead.u.l.next = uv;
- lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv);
- return uv;
-}
-
-
-static void unlinkupval (UpVal *uv) {
- lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv);
- uv->u.l.next->u.l.prev = uv->u.l.prev; /* remove from `uvhead' list */
- uv->u.l.prev->u.l.next = uv->u.l.next;
-}
-
-
-void luaF_freeupval (lua_State *L, UpVal *uv) {
- if (uv->v != &uv->u.value) /* is it open? */
- unlinkupval(uv); /* remove from open list */
- luaM_free(L, uv); /* free upvalue */
-}
-
-
-void luaF_close (lua_State *L, StkId level) {
- UpVal *uv;
- global_State *g = G(L);
- while (L->openupval != NULL && (uv = ngcotouv(L->openupval))->v >= level) {
- GCObject *o = obj2gco(uv);
- lua_assert(!isblack(o) && uv->v != &uv->u.value);
- L->openupval = uv->next; /* remove from `open' list */
- if (isdead(g, o))
- luaF_freeupval(L, uv); /* free upvalue */
- else {
- unlinkupval(uv);
- setobj(L, &uv->u.value, uv->v);
- uv->v = &uv->u.value; /* now current value lives here */
- luaC_linkupval(L, uv); /* link upvalue into `gcroot' list */
- }
- }
-}
-
-
-Proto *luaF_newproto (lua_State *L) {
- Proto *f = luaM_new(L, Proto);
- luaC_link(L, obj2gco(f), LUA_TPROTO);
- f->k = NULL;
- f->sizek = 0;
- f->p = NULL;
- f->sizep = 0;
- f->code = NULL;
- f->sizecode = 0;
- f->sizelineinfo = 0;
- f->sizeupvalues = 0;
- f->nups = 0;
- f->upvalues = NULL;
- f->numparams = 0;
- f->is_vararg = 0;
- f->maxstacksize = 0;
- f->lineinfo = NULL;
- f->sizelocvars = 0;
- f->locvars = NULL;
- f->linedefined = 0;
- f->lastlinedefined = 0;
- f->source = NULL;
- return f;
-}
-
-
-void luaF_freeproto (lua_State *L, Proto *f) {
- luaM_freearray(L, f->code, f->sizecode, Instruction);
- luaM_freearray(L, f->p, f->sizep, Proto *);
- luaM_freearray(L, f->k, f->sizek, TValue);
- luaM_freearray(L, f->lineinfo, f->sizelineinfo, int);
- luaM_freearray(L, f->locvars, f->sizelocvars, struct LocVar);
- luaM_freearray(L, f->upvalues, f->sizeupvalues, TString *);
- luaM_free(L, f);
-}
-
-
-void luaF_freeclosure (lua_State *L, Closure *c) {
- int size = (c->c.isC) ? sizeCclosure(c->c.nupvalues) :
- sizeLclosure(c->l.nupvalues);
- luaM_freemem(L, c, size);
-}
-
-
-/*
-** Look for n-th local variable at line `line' in function `func'.
-** Returns NULL if not found.
-*/
-const char *luaF_getlocalname (const Proto *f, int local_number, int pc) {
- int i;
- for (i = 0; i<f->sizelocvars && f->locvars[i].startpc <= pc; i++) {
- if (pc < f->locvars[i].endpc) { /* is variable active? */
- local_number--;
- if (local_number == 0)
- return getstr(f->locvars[i].varname);
- }
- }
- return NULL; /* not found */
-}
-
diff --git a/crawl-ref/source/util/lua/src/lfunc.h b/crawl-ref/source/util/lua/src/lfunc.h
deleted file mode 100644
index a68cf5151c..0000000000
--- a/crawl-ref/source/util/lua/src/lfunc.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
-** $Id: lfunc.h,v 2.4.1.1 2007/12/27 13:02:25 roberto Exp $
-** Auxiliary functions to manipulate prototypes and closures
-** See Copyright Notice in lua.h
-*/
-
-#ifndef lfunc_h
-#define lfunc_h
-
-
-#include "lobject.h"
-
-
-#define sizeCclosure(n) (cast(int, sizeof(CClosure)) + \
- cast(int, sizeof(TValue)*((n)-1)))
-
-#define sizeLclosure(n) (cast(int, sizeof(LClosure)) + \
- cast(int, sizeof(TValue *)*((n)-1)))
-
-
-LUAI_FUNC Proto *luaF_newproto (lua_State *L);
-LUAI_FUNC Closure *luaF_newCclosure (lua_State *L, int nelems, Table *e);
-LUAI_FUNC Closure *luaF_newLclosure (lua_State *L, int nelems, Table *e);
-LUAI_FUNC UpVal *luaF_newupval (lua_State *L);
-LUAI_FUNC UpVal *luaF_findupval (lua_State *L, StkId level);
-LUAI_FUNC void luaF_close (lua_State *L, StkId level);
-LUAI_FUNC void luaF_freeproto (lua_State *L, Proto *f);
-LUAI_FUNC void luaF_freeclosure (lua_State *L, Closure *c);
-LUAI_FUNC void luaF_freeupval (lua_State *L, UpVal *uv);
-LUAI_FUNC const char *luaF_getlocalname (const Proto *func, int local_number,
- int pc);
-
-
-#endif
diff --git a/crawl-ref/source/util/lua/src/lgc.c b/crawl-ref/source/util/lua/src/lgc.c
deleted file mode 100644
index d9e0b78294..0000000000
--- a/crawl-ref/source/util/lua/src/lgc.c
+++ /dev/null
@@ -1,711 +0,0 @@
-/*
-** $Id: lgc.c,v 2.38.1.1 2007/12/27 13:02:25 roberto Exp $
-** Garbage Collector
-** See Copyright Notice in lua.h
-*/
-
-#include <string.h>
-
-#define lgc_c
-#define LUA_CORE
-
-#include "lua.h"
-
-#include "ldebug.h"
-#include "ldo.h"
-#include "lfunc.h"
-#include "lgc.h"
-#include "lmem.h"
-#include "lobject.h"
-#include "lstate.h"
-#include "lstring.h"
-#include "ltable.h"
-#include "ltm.h"
-
-
-#define GCSTEPSIZE 1024u
-#define GCSWEEPMAX 40
-#define GCSWEEPCOST 10
-#define GCFINALIZECOST 100
-
-
-#define maskmarks cast_byte(~(bitmask(BLACKBIT)|WHITEBITS))
-
-#define makewhite(g,x) \
- ((x)->gch.marked = cast_byte(((x)->gch.marked & maskmarks) | luaC_white(g)))
-
-#define white2gray(x) reset2bits((x)->gch.marked, WHITE0BIT, WHITE1BIT)
-#define black2gray(x) resetbit((x)->gch.marked, BLACKBIT)
-
-#define stringmark(s) reset2bits((s)->tsv.marked, WHITE0BIT, WHITE1BIT)
-
-
-#define isfinalized(u) testbit((u)->marked, FINALIZEDBIT)
-#define markfinalized(u) l_setbit((u)->marked, FINALIZEDBIT)
-
-
-#define KEYWEAK bitmask(KEYWEAKBIT)
-#define VALUEWEAK bitmask(VALUEWEAKBIT)
-
-
-
-#define markvalue(g,o) { checkconsistency(o); \
- if (iscollectable(o) && iswhite(gcvalue(o))) reallymarkobject(g,gcvalue(o)); }
-
-#define markobject(g,t) { if (iswhite(obj2gco(t))) \
- reallymarkobject(g, obj2gco(t)); }
-
-
-#define setthreshold(g) (g->GCthreshold = (g->estimate/100) * g->gcpause)
-
-
-static void removeentry (Node *n) {
- lua_assert(ttisnil(gval(n)));
- if (iscollectable(gkey(n)))
- setttype(gkey(n), LUA_TDEADKEY); /* dead key; remove it */
-}
-
-
-static void reallymarkobject (global_State *g, GCObject *o) {
- lua_assert(iswhite(o) && !isdead(g, o));
- white2gray(o);
- switch (o->gch.tt) {
- case LUA_TSTRING: {
- return;
- }
- case LUA_TUSERDATA: {
- Table *mt = gco2u(o)->metatable;
- gray2black(o); /* udata are never gray */
- if (mt) markobject(g, mt);
- markobject(g, gco2u(o)->env);
- return;
- }
- case LUA_TUPVAL: {
- UpVal *uv = gco2uv(o);
- markvalue(g, uv->v);
- if (uv->v == &uv->u.value) /* closed? */
- gray2black(o); /* open upvalues are never black */
- return;
- }
- case LUA_TFUNCTION: {
- gco2cl(o)->c.gclist = g->gray;
- g->gray = o;
- break;
- }
- case LUA_TTABLE: {
- gco2h(o)->gclist = g->gray;
- g->gray = o;
- break;
- }
- case LUA_TTHREAD: {
- gco2th(o)->gclist = g->gray;
- g->gray = o;
- break;
- }
- case LUA_TPROTO: {
- gco2p(o)->gclist = g->gray;
- g->gray = o;
- break;
- }
- default: lua_assert(0);
- }
-}
-
-
-static void marktmu (global_State *g) {
- GCObject *u = g->tmudata;
- if (u) {
- do {
- u = u->gch.next;
- makewhite(g, u); /* may be marked, if left from previous GC */
- reallymarkobject(g, u);
- } while (u != g->tmudata);
- }
-}
-
-
-/* move `dead' udata that need finalization to list `tmudata' */
-size_t luaC_separateudata (lua_State *L, int all) {
- global_State *g = G(L);
- size_t deadmem = 0;
- GCObject **p = &g->mainthread->next;
- GCObject *curr;
- while ((curr = *p) != NULL) {
- if (!(iswhite(curr) || all) || isfinalized(gco2u(curr)))
- p = &curr->gch.next; /* don't bother with them */
- else if (fasttm(L, gco2u(curr)->metatable, TM_GC) == NULL) {
- markfinalized(gco2u(curr)); /* don't need finalization */
- p = &curr->gch.next;
- }
- else { /* must call its gc method */
- deadmem += sizeudata(gco2u(curr));
- markfinalized(gco2u(curr));
- *p = curr->gch.next;
- /* link `curr' at the end of `tmudata' list */
- if (g->tmudata == NULL) /* list is empty? */
- g->tmudata = curr->gch.next = curr; /* creates a circular list */
- else {
- curr->gch.next = g->tmudata->gch.next;
- g->tmudata->gch.next = curr;
- g->tmudata = curr;
- }
- }
- }
- return deadmem;
-}
-
-
-static int traversetable (global_State *g, Table *h) {
- int i;
- int weakkey = 0;
- int weakvalue = 0;
- const TValue *mode;
- if (h->metatable)
- markobject(g, h->metatable);
- mode = gfasttm(g, h->metatable, TM_MODE);
- if (mode && ttisstring(mode)) { /* is there a weak mode? */
- weakkey = (strchr(svalue(mode), 'k') != NULL);
- weakvalue = (strchr(svalue(mode), 'v') != NULL);
- if (weakkey || weakvalue) { /* is really weak? */
- h->marked &= ~(KEYWEAK | VALUEWEAK); /* clear bits */
- h->marked |= cast_byte((weakkey << KEYWEAKBIT) |
- (weakvalue << VALUEWEAKBIT));
- h->gclist = g->weak; /* must be cleared after GC, ... */
- g->weak = obj2gco(h); /* ... so put in the appropriate list */
- }
- }
- if (weakkey && weakvalue) return 1;
- if (!weakvalue) {
- i = h->sizearray;
- while (i--)
- markvalue(g, &h->array[i]);
- }
- i = sizenode(h);
- while (i--) {
- Node *n = gnode(h, i);
- lua_assert(ttype(gkey(n)) != LUA_TDEADKEY || ttisnil(gval(n)));
- if (ttisnil(gval(n)))
- removeentry(n); /* remove empty entries */
- else {
- lua_assert(!ttisnil(gkey(n)));
- if (!weakkey) markvalue(g, gkey(n));
- if (!weakvalue) markvalue(g, gval(n));
- }
- }
- return weakkey || weakvalue;
-}
-
-
-/*
-** All marks are conditional because a GC may happen while the
-** prototype is still being created
-*/
-static void traverseproto (global_State *g, Proto *f) {
- int i;
- if (f->source) stringmark(f->source);
- for (i=0; i<f->sizek; i++) /* mark literals */
- markvalue(g, &f->k[i]);
- for (i=0; i<f->sizeupvalues; i++) { /* mark upvalue names */
- if (f->upvalues[i])
- stringmark(f->upvalues[i]);
- }
- for (i=0; i<f->sizep; i++) { /* mark nested protos */
- if (f->p[i])
- markobject(g, f->p[i]);
- }
- for (i=0; i<f->sizelocvars; i++) { /* mark local-variable names */
- if (f->locvars[i].varname)
- stringmark(f->locvars[i].varname);
- }
-}
-
-
-
-static void traverseclosure (global_State *g, Closure *cl) {
- markobject(g, cl->c.env);
- if (cl->c.isC) {
- int i;
- for (i=0; i<cl->c.nupvalues; i++) /* mark its upvalues */
- markvalue(g, &cl->c.upvalue[i]);
- }
- else {
- int i;
- lua_assert(cl->l.nupvalues == cl->l.p->nups);
- markobject(g, cl->l.p);
- for (i=0; i<cl->l.nupvalues; i++) /* mark its upvalues */
- markobject(g, cl->l.upvals[i]);
- }
-}
-
-
-static void checkstacksizes (lua_State *L, StkId max) {
- int ci_used = cast_int(L->ci - L->base_ci); /* number of `ci' in use */
- int s_used = cast_int(max - L->stack); /* part of stack in use */
- if (L->size_ci > LUAI_MAXCALLS) /* handling overflow? */
- return; /* do not touch the stacks */
- if (4*ci_used < L->size_ci && 2*BASIC_CI_SIZE < L->size_ci)
- luaD_reallocCI(L, L->size_ci/2); /* still big enough... */
- condhardstacktests(luaD_reallocCI(L, ci_used + 1));
- if (4*s_used < L->stacksize &&
- 2*(BASIC_STACK_SIZE+EXTRA_STACK) < L->stacksize)
- luaD_reallocstack(L, L->stacksize/2); /* still big enough... */
- condhardstacktests(luaD_reallocstack(L, s_used));
-}
-
-
-static void traversestack (global_State *g, lua_State *l) {
- StkId o, lim;
- CallInfo *ci;
- markvalue(g, gt(l));
- lim = l->top;
- for (ci = l->base_ci; ci <= l->ci; ci++) {
- lua_assert(ci->top <= l->stack_last);
- if (lim < ci->top) lim = ci->top;
- }
- for (o = l->stack; o < l->top; o++)
- markvalue(g, o);
- for (; o <= lim; o++)
- setnilvalue(o);
- checkstacksizes(l, lim);
-}
-
-
-/*
-** traverse one gray object, turning it to black.
-** Returns `quantity' traversed.
-*/
-static l_mem propagatemark (global_State *g) {
- GCObject *o = g->gray;
- lua_assert(isgray(o));
- gray2black(o);
- switch (o->gch.tt) {
- case LUA_TTABLE: {
- Table *h = gco2h(o);
- g->gray = h->gclist;
- if (traversetable(g, h)) /* table is weak? */
- black2gray(o); /* keep it gray */
- return sizeof(Table) + sizeof(TValue) * h->sizearray +
- sizeof(Node) * sizenode(h);
- }
- case LUA_TFUNCTION: {
- Closure *cl = gco2cl(o);
- g->gray = cl->c.gclist;
- traverseclosure(g, cl);
- return (cl->c.isC) ? sizeCclosure(cl->c.nupvalues) :
- sizeLclosure(cl->l.nupvalues);
- }
- case LUA_TTHREAD: {
- lua_State *th = gco2th(o);
- g->gray = th->gclist;
- th->gclist = g->grayagain;
- g->grayagain = o;
- black2gray(o);
- traversestack(g, th);
- return sizeof(lua_State) + sizeof(TValue) * th->stacksize +
- sizeof(CallInfo) * th->size_ci;
- }
- case LUA_TPROTO: {
- Proto *p = gco2p(o);
- g->gray = p->gclist;
- traverseproto(g, p);
- return sizeof(Proto) + sizeof(Instruction) * p->sizecode +
- sizeof(Proto *) * p->sizep +
- sizeof(TValue) * p->sizek +
- sizeof(int) * p->sizelineinfo +
- sizeof(LocVar) * p->sizelocvars +
- sizeof(TString *) * p->sizeupvalues;
- }
- default: lua_assert(0); return 0;
- }
-}
-
-
-static size_t propagateall (global_State *g) {
- size_t m = 0;
- while (g->gray) m += propagatemark(g);
- return m;
-}
-
-
-/*
-** The next function tells whether a key or value can be cleared from
-** a weak table. Non-collectable objects are never removed from weak
-** tables. Strings behave as `values', so are never removed too. for
-** other objects: if really collected, cannot keep them; for userdata
-** being finalized, keep them in keys, but not in values
-*/
-static int iscleared (const TValue *o, int iskey) {
- if (!iscollectable(o)) return 0;
- if (ttisstring(o)) {
- stringmark(rawtsvalue(o)); /* strings are `values', so are never weak */
- return 0;
- }
- return iswhite(gcvalue(o)) ||
- (ttisuserdata(o) && (!iskey && isfinalized(uvalue(o))));
-}
-
-
-/*
-** clear collected entries from weaktables
-*/
-static void cleartable (GCObject *l) {
- while (l) {
- Table *h = gco2h(l);
- int i = h->sizearray;
- lua_assert(testbit(h->marked, VALUEWEAKBIT) ||
- testbit(h->marked, KEYWEAKBIT));
- if (testbit(h->marked, VALUEWEAKBIT)) {
- while (i--) {
- TValue *o = &h->array[i];
- if (iscleared(o, 0)) /* value was collected? */
- setnilvalue(o); /* remove value */
- }
- }
- i = sizenode(h);
- while (i--) {
- Node *n = gnode(h, i);
- if (!ttisnil(gval(n)) && /* non-empty entry? */
- (iscleared(key2tval(n), 1) || iscleared(gval(n), 0))) {
- setnilvalue(gval(n)); /* remove value ... */
- removeentry(n); /* remove entry from table */
- }
- }
- l = h->gclist;
- }
-}
-
-
-static void freeobj (lua_State *L, GCObject *o) {
- switch (o->gch.tt) {
- case LUA_TPROTO: luaF_freeproto(L, gco2p(o)); break;
- case LUA_TFUNCTION: luaF_freeclosure(L, gco2cl(o)); break;
- case LUA_TUPVAL: luaF_freeupval(L, gco2uv(o)); break;
- case LUA_TTABLE: luaH_free(L, gco2h(o)); break;
- case LUA_TTHREAD: {
- lua_assert(gco2th(o) != L && gco2th(o) != G(L)->mainthread);
- luaE_freethread(L, gco2th(o));
- break;
- }
- case LUA_TSTRING: {
- G(L)->strt.nuse--;
- luaM_freemem(L, o, sizestring(gco2ts(o)));
- break;
- }
- case LUA_TUSERDATA: {
- luaM_freemem(L, o, sizeudata(gco2u(o)));
- break;
- }
- default: lua_assert(0);
- }
-}
-
-
-
-#define sweepwholelist(L,p) sweeplist(L,p,MAX_LUMEM)
-
-
-static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) {
- GCObject *curr;
- global_State *g = G(L);
- int deadmask = otherwhite(g);
- while ((curr = *p) != NULL && count-- > 0) {
- if (curr->gch.tt == LUA_TTHREAD) /* sweep open upvalues of each thread */
- sweepwholelist(L, &gco2th(curr)->openupval);
- if ((curr->gch.marked ^ WHITEBITS) & deadmask) { /* not dead? */
- lua_assert(!isdead(g, curr) || testbit(curr->gch.marked, FIXEDBIT));
- makewhite(g, curr); /* make it white (for next cycle) */
- p = &curr->gch.next;
- }
- else { /* must erase `curr' */
- lua_assert(isdead(g, curr) || deadmask == bitmask(SFIXEDBIT));
- *p = curr->gch.next;
- if (curr == g->rootgc) /* is the first element of the list? */
- g->rootgc = curr->gch.next; /* adjust first */
- freeobj(L, curr);
- }
- }
- return p;
-}
-
-
-static void checkSizes (lua_State *L) {
- global_State *g = G(L);
- /* check size of string hash */
- if (g->strt.nuse < cast(lu_int32, g->strt.size/4) &&
- g->strt.size > MINSTRTABSIZE*2)
- luaS_resize(L, g->strt.size/2); /* table is too big */
- /* check size of buffer */
- if (luaZ_sizebuffer(&g->buff) > LUA_MINBUFFER*2) { /* buffer too big? */
- size_t newsize = luaZ_sizebuffer(&g->buff) / 2;
- luaZ_resizebuffer(L, &g->buff, newsize);
- }
-}
-
-
-static void GCTM (lua_State *L) {
- global_State *g = G(L);
- GCObject *o = g->tmudata->gch.next; /* get first element */
- Udata *udata = rawgco2u(o);
- const TValue *tm;
- /* remove udata from `tmudata' */
- if (o == g->tmudata) /* last element? */
- g->tmudata = NULL;
- else
- g->tmudata->gch.next = udata->uv.next;
- udata->uv.next = g->mainthread->next; /* return it to `root' list */
- g->mainthread->next = o;
- makewhite(g, o);
- tm = fasttm(L, udata->uv.metatable, TM_GC);
- if (tm != NULL) {
- lu_byte oldah = L->allowhook;
- lu_mem oldt = g->GCthreshold;
- L->allowhook = 0; /* stop debug hooks during GC tag method */
- g->GCthreshold = 2*g->totalbytes; /* avoid GC steps */
- setobj2s(L, L->top, tm);
- setuvalue(L, L->top+1, udata);
- L->top += 2;
- luaD_call(L, L->top - 2, 0);
- L->allowhook = oldah; /* restore hooks */
- g->GCthreshold = oldt; /* restore threshold */
- }
-}
-
-
-/*
-** Call all GC tag methods
-*/
-void luaC_callGCTM (lua_State *L) {
- while (G(L)->tmudata)
- GCTM(L);
-}
-
-
-void luaC_freeall (lua_State *L) {
- global_State *g = G(L);
- int i;
- g->currentwhite = WHITEBITS | bitmask(SFIXEDBIT); /* mask to collect all elements */
- sweepwholelist(L, &g->rootgc);
- for (i = 0; i < g->strt.size; i++) /* free all string lists */
- sweepwholelist(L, &g->strt.hash[i]);
-}
-
-
-static void markmt (global_State *g) {
- int i;
- for (i=0; i<NUM_TAGS; i++)
- if (g->mt[i]) markobject(g, g->mt[i]);
-}
-
-
-/* mark root set */
-static void markroot (lua_State *L) {
- global_State *g = G(L);
- g->gray = NULL;
- g->grayagain = NULL;
- g->weak = NULL;
- markobject(g, g->mainthread);
- /* make global table be traversed before main stack */
- markvalue(g, gt(g->mainthread));
- markvalue(g, registry(L));
- markmt(g);
- g->gcstate = GCSpropagate;
-}
-
-
-static void remarkupvals (global_State *g) {
- UpVal *uv;
- for (uv = g->uvhead.u.l.next; uv != &g->uvhead; uv = uv->u.l.next) {
- lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv);
- if (isgray(obj2gco(uv)))
- markvalue(g, uv->v);
- }
-}
-
-
-static void atomic (lua_State *L) {
- global_State *g = G(L);
- size_t udsize; /* total size of userdata to be finalized */
- /* remark occasional upvalues of (maybe) dead threads */
- remarkupvals(g);
- /* traverse objects cautch by write barrier and by 'remarkupvals' */
- propagateall(g);
- /* remark weak tables */
- g->gray = g->weak;
- g->weak = NULL;
- lua_assert(!iswhite(obj2gco(g->mainthread)));
- markobject(g, L); /* mark running thread */
- markmt(g); /* mark basic metatables (again) */
- propagateall(g);
- /* remark gray again */
- g->gray = g->grayagain;
- g->grayagain = NULL;
- propagateall(g);
- udsize = luaC_separateudata(L, 0); /* separate userdata to be finalized */
- marktmu(g); /* mark `preserved' userdata */
- udsize += propagateall(g); /* remark, to propagate `preserveness' */
- cleartable(g->weak); /* remove collected objects from weak tables */
- /* flip current white */
- g->currentwhite = cast_byte(otherwhite(g));
- g->sweepstrgc = 0;
- g->sweepgc = &g->rootgc;
- g->gcstate = GCSsweepstring;
- g->estimate = g->totalbytes - udsize; /* first estimate */
-}
-
-
-static l_mem singlestep (lua_State *L) {
- global_State *g = G(L);
- /*lua_checkmemory(L);*/
- switch (g->gcstate) {
- case GCSpause: {
- markroot(L); /* start a new collection */
- return 0;
- }
- case GCSpropagate: {
- if (g->gray)
- return propagatemark(g);
- else { /* no more `gray' objects */
- atomic(L); /* finish mark phase */
- return 0;
- }
- }
- case GCSsweepstring: {
- lu_mem old = g->totalbytes;
- sweepwholelist(L, &g->strt.hash[g->sweepstrgc++]);
- if (g->sweepstrgc >= g->strt.size) /* nothing more to sweep? */
- g->gcstate = GCSsweep; /* end sweep-string phase */
- lua_assert(old >= g->totalbytes);
- g->estimate -= old - g->totalbytes;
- return GCSWEEPCOST;
- }
- case GCSsweep: {
- lu_mem old = g->totalbytes;
- g->sweepgc = sweeplist(L, g->sweepgc, GCSWEEPMAX);
- if (*g->sweepgc == NULL) { /* nothing more to sweep? */
- checkSizes(L);
- g->gcstate = GCSfinalize; /* end sweep phase */
- }
- lua_assert(old >= g->totalbytes);
- g->estimate -= old - g->totalbytes;
- return GCSWEEPMAX*GCSWEEPCOST;
- }
- case GCSfinalize: {
- if (g->tmudata) {
- GCTM(L);
- if (g->estimate > GCFINALIZECOST)
- g->estimate -= GCFINALIZECOST;
- return GCFINALIZECOST;
- }
- else {
- g->gcstate = GCSpause; /* end collection */
- g->gcdept = 0;
- return 0;
- }
- }
- default: lua_assert(0); return 0;
- }
-}
-
-
-void luaC_step (lua_State *L) {
- global_State *g = G(L);
- l_mem lim = (GCSTEPSIZE/100) * g->gcstepmul;
- if (lim == 0)
- lim = (MAX_LUMEM-1)/2; /* no limit */
- g->gcdept += g->totalbytes - g->GCthreshold;
- do {
- lim -= singlestep(L);
- if (g->gcstate == GCSpause)
- break;
- } while (lim > 0);
- if (g->gcstate != GCSpause) {
- if (g->gcdept < GCSTEPSIZE)
- g->GCthreshold = g->totalbytes + GCSTEPSIZE; /* - lim/g->gcstepmul;*/
- else {
- g->gcdept -= GCSTEPSIZE;
- g->GCthreshold = g->totalbytes;
- }
- }
- else {
- lua_assert(g->totalbytes >= g->estimate);
- setthreshold(g);
- }
-}
-
-
-void luaC_fullgc (lua_State *L) {
- global_State *g = G(L);
- if (g->gcstate <= GCSpropagate) {
- /* reset sweep marks to sweep all elements (returning them to white) */
- g->sweepstrgc = 0;
- g->sweepgc = &g->rootgc;
- /* reset other collector lists */
- g->gray = NULL;
- g->grayagain = NULL;
- g->weak = NULL;
- g->gcstate = GCSsweepstring;
- }
- lua_assert(g->gcstate != GCSpause && g->gcstate != GCSpropagate);
- /* finish any pending sweep phase */
- while (g->gcstate != GCSfinalize) {
- lua_assert(g->gcstate == GCSsweepstring || g->gcstate == GCSsweep);
- singlestep(L);
- }
- markroot(L);
- while (g->gcstate != GCSpause) {
- singlestep(L);
- }
- setthreshold(g);
-}
-
-
-void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v) {
- global_State *g = G(L);
- lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o));
- lua_assert(g->gcstate != GCSfinalize && g->gcstate != GCSpause);
- lua_assert(ttype(&o->gch) != LUA_TTABLE);
- /* must keep invariant? */
- if (g->gcstate == GCSpropagate)
- reallymarkobject(g, v); /* restore invariant */
- else /* don't mind */
- makewhite(g, o); /* mark as white just to avoid other barriers */
-}
-
-
-void luaC_barrierback (lua_State *L, Table *t) {
- global_State *g = G(L);
- GCObject *o = obj2gco(t);
- lua_assert(isblack(o) && !isdead(g, o));
- lua_assert(g->gcstate != GCSfinalize && g->gcstate != GCSpause);
- black2gray(o); /* make table gray (again) */
- t->gclist = g->grayagain;
- g->grayagain = o;
-}
-
-
-void luaC_link (lua_State *L, GCObject *o, lu_byte tt) {
- global_State *g = G(L);
- o->gch.next = g->rootgc;
- g->rootgc = o;
- o->gch.marked = luaC_white(g);
- o->gch.tt = tt;
-}
-
-
-void luaC_linkupval (lua_State *L, UpVal *uv) {
- global_State *g = G(L);
- GCObject *o = obj2gco(uv);
- o->gch.next = g->rootgc; /* link upvalue into `rootgc' list */
- g->rootgc = o;
- if (isgray(o)) {
- if (g->gcstate == GCSpropagate) {
- gray2black(o); /* closed upvalues need barrier */
- luaC_barrier(L, uv, uv->v);
- }
- else { /* sweep phase: sweep it (turning it into white) */
- makewhite(g, o);
- lua_assert(g->gcstate != GCSfinalize && g->gcstate != GCSpause);
- }
- }
-}
-
diff --git a/crawl-ref/source/util/lua/src/lgc.h b/crawl-ref/source/util/lua/src/lgc.h
deleted file mode 100644
index 5a8dc605b3..0000000000
--- a/crawl-ref/source/util/lua/src/lgc.h
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
-** $Id: lgc.h,v 2.15.1.1 2007/12/27 13:02:25 roberto Exp $
-** Garbage Collector
-** See Copyright Notice in lua.h
-*/
-
-#ifndef lgc_h
-#define lgc_h
-
-
-#include "lobject.h"
-
-
-/*
-** Possible states of the Garbage Collector
-*/
-#define GCSpause 0
-#define GCSpropagate 1
-#define GCSsweepstring 2
-#define GCSsweep 3
-#define GCSfinalize 4
-
-
-/*
-** some userful bit tricks
-*/
-#define resetbits(x,m) ((x) &= cast(lu_byte, ~(m)))
-#define setbits(x,m) ((x) |= (m))
-#define testbits(x,m) ((x) & (m))
-#define bitmask(b) (1<<(b))
-#define bit2mask(b1,b2) (bitmask(b1) | bitmask(b2))
-#define l_setbit(x,b) setbits(x, bitmask(b))
-#define resetbit(x,b) resetbits(x, bitmask(b))
-#define testbit(x,b) testbits(x, bitmask(b))
-#define set2bits(x,b1,b2) setbits(x, (bit2mask(b1, b2)))
-#define reset2bits(x,b1,b2) resetbits(x, (bit2mask(b1, b2)))
-#define test2bits(x,b1,b2) testbits(x, (bit2mask(b1, b2)))
-
-
-
-/*
-** Layout for bit use in `marked' field:
-** bit 0 - object is white (type 0)
-** bit 1 - object is white (type 1)
-** bit 2 - object is black
-** bit 3 - for userdata: has been finalized
-** bit 3 - for tables: has weak keys
-** bit 4 - for tables: has weak values
-** bit 5 - object is fixed (should not be collected)
-** bit 6 - object is "super" fixed (only the main thread)
-*/
-
-
-#define WHITE0BIT 0
-#define WHITE1BIT 1
-#define BLACKBIT 2
-#define FINALIZEDBIT 3
-#define KEYWEAKBIT 3
-#define VALUEWEAKBIT 4
-#define FIXEDBIT 5
-#define SFIXEDBIT 6
-#define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT)
-
-
-#define iswhite(x) test2bits((x)->gch.marked, WHITE0BIT, WHITE1BIT)
-#define isblack(x) testbit((x)->gch.marked, BLACKBIT)
-#define isgray(x) (!isblack(x) && !iswhite(x))
-
-#define otherwhite(g) (g->currentwhite ^ WHITEBITS)
-#define isdead(g,v) ((v)->gch.marked & otherwhite(g) & WHITEBITS)
-
-#define changewhite(x) ((x)->gch.marked ^= WHITEBITS)
-#define gray2black(x) l_setbit((x)->gch.marked, BLACKBIT)
-
-#define valiswhite(x) (iscollectable(x) && iswhite(gcvalue(x)))
-
-#define luaC_white(g) cast(lu_byte, (g)->currentwhite & WHITEBITS)
-
-
-#define luaC_checkGC(L) { \
- condhardstacktests(luaD_reallocstack(L, L->stacksize - EXTRA_STACK - 1)); \
- if (G(L)->totalbytes >= G(L)->GCthreshold) \
- luaC_step(L); }
-
-
-#define luaC_barrier(L,p,v) { if (valiswhite(v) && isblack(obj2gco(p))) \
- luaC_barrierf(L,obj2gco(p),gcvalue(v)); }
-
-#define luaC_barriert(L,t,v) { if (valiswhite(v) && isblack(obj2gco(t))) \
- luaC_barrierback(L,t); }
-
-#define luaC_objbarrier(L,p,o) \
- { if (iswhite(obj2gco(o)) && isblack(obj2gco(p))) \
- luaC_barrierf(L,obj2gco(p),obj2gco(o)); }
-
-#define luaC_objbarriert(L,t,o) \
- { if (iswhite(obj2gco(o)) && isblack(obj2gco(t))) luaC_barrierback(L,t); }
-
-LUAI_FUNC size_t luaC_separateudata (lua_State *L, int all);
-LUAI_FUNC void luaC_callGCTM (lua_State *L);
-LUAI_FUNC void luaC_freeall (lua_State *L);
-LUAI_FUNC void luaC_step (lua_State *L);
-LUAI_FUNC void luaC_fullgc (lua_State *L);
-LUAI_FUNC void luaC_link (lua_State *L, GCObject *o, lu_byte tt);
-LUAI_FUNC void luaC_linkupval (lua_State *L, UpVal *uv);
-LUAI_FUNC void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v);
-LUAI_FUNC void luaC_barrierback (lua_State *L, Table *t);
-
-
-#endif
diff --git a/crawl-ref/source/util/lua/src/linit.c b/crawl-ref/source/util/lua/src/linit.c
deleted file mode 100644
index c1f90dfab7..0000000000
--- a/crawl-ref/source/util/lua/src/linit.c
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
-** $Id: linit.c,v 1.14.1.1 2007/12/27 13:02:25 roberto Exp $
-** Initialization of libraries for lua.c
-** See Copyright Notice in lua.h
-*/
-
-
-#define linit_c
-#define LUA_LIB
-
-#include "lua.h"
-
-#include "lualib.h"
-#include "lauxlib.h"
-
-
-static const luaL_Reg lualibs[] = {
- {"", luaopen_base},
- {LUA_LOADLIBNAME, luaopen_package},
- {LUA_TABLIBNAME, luaopen_table},
- {LUA_IOLIBNAME, luaopen_io},
- {LUA_OSLIBNAME, luaopen_os},
- {LUA_STRLIBNAME, luaopen_string},
- {LUA_MATHLIBNAME, luaopen_math},
- {LUA_DBLIBNAME, luaopen_debug},
- {NULL, NULL}
-};
-
-
-LUALIB_API void luaL_openlibs (lua_State *L) {
- const luaL_Reg *lib = lualibs;
- for (; lib->func; lib++) {
- lua_pushcfunction(L, lib->func);
- lua_pushstring(L, lib->name);
- lua_call(L, 1, 0);
- }
-}
-
diff --git a/crawl-ref/source/util/lua/src/liolib.c b/crawl-ref/source/util/lua/src/liolib.c
deleted file mode 100644
index e79ed1cb2e..0000000000
--- a/crawl-ref/source/util/lua/src/liolib.c
+++ /dev/null
@@ -1,553 +0,0 @@
-/*
-** $Id: liolib.c,v 2.73.1.3 2008/01/18 17:47:43 roberto Exp $
-** Standard I/O (and system) library
-** See Copyright Notice in lua.h
-*/
-
-
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#define liolib_c
-#define LUA_LIB
-
-#include "lua.h"
-
-#include "lauxlib.h"
-#include "lualib.h"
-
-
-
-#define IO_INPUT 1
-#define IO_OUTPUT 2
-
-
-static const char *const fnames[] = {"input", "output"};
-
-
-static int pushresult (lua_State *L, int i, const char *filename) {
- int en = errno; /* calls to Lua API may change this value */
- if (i) {
- lua_pushboolean(L, 1);
- return 1;
- }
- else {
- lua_pushnil(L);
- if (filename)
- lua_pushfstring(L, "%s: %s", filename, strerror(en));
- else
- lua_pushfstring(L, "%s", strerror(en));
- lua_pushinteger(L, en);
- return 3;
- }
-}
-
-
-static void fileerror (lua_State *L, int arg, const char *filename) {
- lua_pushfstring(L, "%s: %s", filename, strerror(errno));
- luaL_argerror(L, arg, lua_tostring(L, -1));
-}
-
-
-#define tofilep(L) ((FILE **)luaL_checkudata(L, 1, LUA_FILEHANDLE))
-
-
-static int io_type (lua_State *L) {
- void *ud;
- luaL_checkany(L, 1);
- ud = lua_touserdata(L, 1);
- lua_getfield(L, LUA_REGISTRYINDEX, LUA_FILEHANDLE);
- if (ud == NULL || !lua_getmetatable(L, 1) || !lua_rawequal(L, -2, -1))
- lua_pushnil(L); /* not a file */
- else if (*((FILE **)ud) == NULL)
- lua_pushliteral(L, "closed file");
- else
- lua_pushliteral(L, "file");
- return 1;
-}
-
-
-static FILE *tofile (lua_State *L) {
- FILE **f = tofilep(L);
- if (*f == NULL)
- luaL_error(L, "attempt to use a closed file");
- return *f;
-}
-
-
-
-/*
-** When creating file handles, always creates a `closed' file handle
-** before opening the actual file; so, if there is a memory error, the
-** file is not left opened.
-*/
-static FILE **newfile (lua_State *L) {
- FILE **pf = (FILE **)lua_newuserdata(L, sizeof(FILE *));
- *pf = NULL; /* file handle is currently `closed' */
- luaL_getmetatable(L, LUA_FILEHANDLE);
- lua_setmetatable(L, -2);
- return pf;
-}
-
-
-/*
-** function to (not) close the standard files stdin, stdout, and stderr
-*/
-static int io_noclose (lua_State *L) {
- lua_pushnil(L);
- lua_pushliteral(L, "cannot close standard file");
- return 2;
-}
-
-
-/*
-** function to close 'popen' files
-*/
-static int io_pclose (lua_State *L) {
- FILE **p = tofilep(L);
- int ok = lua_pclose(L, *p);
- *p = NULL;
- return pushresult(L, ok, NULL);
-}
-
-
-/*
-** function to close regular files
-*/
-static int io_fclose (lua_State *L) {
- FILE **p = tofilep(L);
- int ok = (fclose(*p) == 0);
- *p = NULL;
- return pushresult(L, ok, NULL);
-}
-
-
-static int aux_close (lua_State *L) {
- lua_getfenv(L, 1);
- lua_getfield(L, -1, "__close");
- return (lua_tocfunction(L, -1))(L);
-}
-
-
-static int io_close (lua_State *L) {
- if (lua_isnone(L, 1))
- lua_rawgeti(L, LUA_ENVIRONINDEX, IO_OUTPUT);
- tofile(L); /* make sure argument is a file */
- return aux_close(L);
-}
-
-
-static int io_gc (lua_State *L) {
- FILE *f = *tofilep(L);
- /* ignore closed files */
- if (f != NULL)
- aux_close(L);
- return 0;
-}
-
-
-static int io_tostring (lua_State *L) {
- FILE *f = *tofilep(L);
- if (f == NULL)
- lua_pushliteral(L, "file (closed)");
- else
- lua_pushfstring(L, "file (%p)", f);
- return 1;
-}
-
-
-static int io_open (lua_State *L) {
- const char *filename = luaL_checkstring(L, 1);
- const char *mode = luaL_optstring(L, 2, "r");
- FILE **pf = newfile(L);
- *pf = fopen(filename, mode);
- return (*pf == NULL) ? pushresult(L, 0, filename) : 1;
-}
-
-
-/*
-** this function has a separated environment, which defines the
-** correct __close for 'popen' files
-*/
-static int io_popen (lua_State *L) {
- const char *filename = luaL_checkstring(L, 1);
- const char *mode = luaL_optstring(L, 2, "r");
- FILE **pf = newfile(L);
- *pf = lua_popen(L, filename, mode);
- return (*pf == NULL) ? pushresult(L, 0, filename) : 1;
-}
-
-
-static int io_tmpfile (lua_State *L) {
- FILE **pf = newfile(L);
- *pf = tmpfile();
- return (*pf == NULL) ? pushresult(L, 0, NULL) : 1;
-}
-
-
-static FILE *getiofile (lua_State *L, int findex) {
- FILE *f;
- lua_rawgeti(L, LUA_ENVIRONINDEX, findex);
- f = *(FILE **)lua_touserdata(L, -1);
- if (f == NULL)
- luaL_error(L, "standard %s file is closed", fnames[findex - 1]);
- return f;
-}
-
-
-static int g_iofile (lua_State *L, int f, const char *mode) {
- if (!lua_isnoneornil(L, 1)) {
- const char *filename = lua_tostring(L, 1);
- if (filename) {
- FILE **pf = newfile(L);
- *pf = fopen(filename, mode);
- if (*pf == NULL)
- fileerror(L, 1, filename);
- }
- else {
- tofile(L); /* check that it's a valid file handle */
- lua_pushvalue(L, 1);
- }
- lua_rawseti(L, LUA_ENVIRONINDEX, f);
- }
- /* return current value */
- lua_rawgeti(L, LUA_ENVIRONINDEX, f);
- return 1;
-}
-
-
-static int io_input (lua_State *L) {
- return g_iofile(L, IO_INPUT, "r");
-}
-
-
-static int io_output (lua_State *L) {
- return g_iofile(L, IO_OUTPUT, "w");
-}
-
-
-static int io_readline (lua_State *L);
-
-
-static void aux_lines (lua_State *L, int idx, int toclose) {
- lua_pushvalue(L, idx);
- lua_pushboolean(L, toclose); /* close/not close file when finished */
- lua_pushcclosure(L, io_readline, 2);
-}
-
-
-static int f_lines (lua_State *L) {
- tofile(L); /* check that it's a valid file handle */
- aux_lines(L, 1, 0);
- return 1;
-}
-
-
-static int io_lines (lua_State *L) {
- if (lua_isnoneornil(L, 1)) { /* no arguments? */
- /* will iterate over default input */
- lua_rawgeti(L, LUA_ENVIRONINDEX, IO_INPUT);
- return f_lines(L);
- }
- else {
- const char *filename = luaL_checkstring(L, 1);
- FILE **pf = newfile(L);
- *pf = fopen(filename, "r");
- if (*pf == NULL)
- fileerror(L, 1, filename);
- aux_lines(L, lua_gettop(L), 1);
- return 1;
- }
-}
-
-
-/*
-** {======================================================
-** READ
-** =======================================================
-*/
-
-
-static int read_number (lua_State *L, FILE *f) {
- lua_Number d;
- if (fscanf(f, LUA_NUMBER_SCAN, &d) == 1) {
- lua_pushnumber(L, d);
- return 1;
- }
- else return 0; /* read fails */
-}
-
-
-static int test_eof (lua_State *L, FILE *f) {
- int c = getc(f);
- ungetc(c, f);
- lua_pushlstring(L, NULL, 0);
- return (c != EOF);
-}
-
-
-static int read_line (lua_State *L, FILE *f) {
- luaL_Buffer b;
- luaL_buffinit(L, &b);
- for (;;) {
- size_t l;
- char *p = luaL_prepbuffer(&b);
- if (fgets(p, LUAL_BUFFERSIZE, f) == NULL) { /* eof? */
- luaL_pushresult(&b); /* close buffer */
- return (lua_objlen(L, -1) > 0); /* check whether read something */
- }
- l = strlen(p);
- if (l == 0 || p[l-1] != '\n')
- luaL_addsize(&b, l);
- else {
- luaL_addsize(&b, l - 1); /* do not include `eol' */
- luaL_pushresult(&b); /* close buffer */
- return 1; /* read at least an `eol' */
- }
- }
-}
-
-
-static int read_chars (lua_State *L, FILE *f, size_t n) {
- size_t rlen; /* how much to read */
- size_t nr; /* number of chars actually read */
- luaL_Buffer b;
- luaL_buffinit(L, &b);
- rlen = LUAL_BUFFERSIZE; /* try to read that much each time */
- do {
- char *p = luaL_prepbuffer(&b);
- if (rlen > n) rlen = n; /* cannot read more than asked */
- nr = fread(p, sizeof(char), rlen, f);
- luaL_addsize(&b, nr);
- n -= nr; /* still have to read `n' chars */
- } while (n > 0 && nr == rlen); /* until end of count or eof */
- luaL_pushresult(&b); /* close buffer */
- return (n == 0 || lua_objlen(L, -1) > 0);
-}
-
-
-static int g_read (lua_State *L, FILE *f, int first) {
- int nargs = lua_gettop(L) - 1;
- int success;
- int n;
- clearerr(f);
- if (nargs == 0) { /* no arguments? */
- success = read_line(L, f);
- n = first+1; /* to return 1 result */
- }
- else { /* ensure stack space for all results and for auxlib's buffer */
- luaL_checkstack(L, nargs+LUA_MINSTACK, "too many arguments");
- success = 1;
- for (n = first; nargs-- && success; n++) {
- if (lua_type(L, n) == LUA_TNUMBER) {
- size_t l = (size_t)lua_tointeger(L, n);
- success = (l == 0) ? test_eof(L, f) : read_chars(L, f, l);
- }
- else {
- const char *p = lua_tostring(L, n);
- luaL_argcheck(L, p && p[0] == '*', n, "invalid option");
- switch (p[1]) {
- case 'n': /* number */
- success = read_number(L, f);
- break;
- case 'l': /* line */
- success = read_line(L, f);
- break;
- case 'a': /* file */
- read_chars(L, f, ~((size_t)0)); /* read MAX_SIZE_T chars */
- success = 1; /* always success */
- break;
- default:
- return luaL_argerror(L, n, "invalid format");
- }
- }
- }
- }
- if (ferror(f))
- return pushresult(L, 0, NULL);
- if (!success) {
- lua_pop(L, 1); /* remove last result */
- lua_pushnil(L); /* push nil instead */
- }
- return n - first;
-}
-
-
-static int io_read (lua_State *L) {
- return g_read(L, getiofile(L, IO_INPUT), 1);
-}
-
-
-static int f_read (lua_State *L) {
- return g_read(L, tofile(L), 2);
-}
-
-
-static int io_readline (lua_State *L) {
- FILE *f = *(FILE **)lua_touserdata(L, lua_upvalueindex(1));
- int sucess;
- if (f == NULL) /* file is already closed? */
- luaL_error(L, "file is already closed");
- sucess = read_line(L, f);
- if (ferror(f))
- return luaL_error(L, "%s", strerror(errno));
- if (sucess) return 1;
- else { /* EOF */
- if (lua_toboolean(L, lua_upvalueindex(2))) { /* generator created file? */
- lua_settop(L, 0);
- lua_pushvalue(L, lua_upvalueindex(1));
- aux_close(L); /* close it */
- }
- return 0;
- }
-}
-
-/* }====================================================== */
-
-
-static int g_write (lua_State *L, FILE *f, int arg) {
- int nargs = lua_gettop(L) - 1;
- int status = 1;
- for (; nargs--; arg++) {
- if (lua_type(L, arg) == LUA_TNUMBER) {
- /* optimization: could be done exactly as for strings */
- status = status &&
- fprintf(f, LUA_NUMBER_FMT, lua_tonumber(L, arg)) > 0;
- }
- else {
- size_t l;
- const char *s = luaL_checklstring(L, arg, &l);
- status = status && (fwrite(s, sizeof(char), l, f) == l);
- }
- }
- return pushresult(L, status, NULL);
-}
-
-
-static int io_write (lua_State *L) {
- return g_write(L, getiofile(L, IO_OUTPUT), 1);
-}
-
-
-static int f_write (lua_State *L) {
- return g_write(L, tofile(L), 2);
-}
-
-
-static int f_seek (lua_State *L) {
- static const int mode[] = {SEEK_SET, SEEK_CUR, SEEK_END};
- static const char *const modenames[] = {"set", "cur", "end", NULL};
- FILE *f = tofile(L);
- int op = luaL_checkoption(L, 2, "cur", modenames);
- long offset = luaL_optlong(L, 3, 0);
- op = fseek(f, offset, mode[op]);
- if (op)
- return pushresult(L, 0, NULL); /* error */
- else {
- lua_pushinteger(L, ftell(f));
- return 1;
- }
-}
-
-
-static int f_setvbuf (lua_State *L) {
- static const int mode[] = {_IONBF, _IOFBF, _IOLBF};
- static const char *const modenames[] = {"no", "full", "line", NULL};
- FILE *f = tofile(L);
- int op = luaL_checkoption(L, 2, NULL, modenames);
- lua_Integer sz = luaL_optinteger(L, 3, LUAL_BUFFERSIZE);
- int res = setvbuf(f, NULL, mode[op], sz);
- return pushresult(L, res == 0, NULL);
-}
-
-
-
-static int io_flush (lua_State *L) {
- return pushresult(L, fflush(getiofile(L, IO_OUTPUT)) == 0, NULL);
-}
-
-
-static int f_flush (lua_State *L) {
- return pushresult(L, fflush(tofile(L)) == 0, NULL);
-}
-
-
-static const luaL_Reg iolib[] = {
- {"close", io_close},
- {"flush", io_flush},
- {"input", io_input},
- {"lines", io_lines},
- {"open", io_open},
- {"output", io_output},
- {"popen", io_popen},
- {"read", io_read},
- {"tmpfile", io_tmpfile},
- {"type", io_type},
- {"write", io_write},
- {NULL, NULL}
-};
-
-
-static const luaL_Reg flib[] = {
- {"close", io_close},
- {"flush", f_flush},
- {"lines", f_lines},
- {"read", f_read},
- {"seek", f_seek},
- {"setvbuf", f_setvbuf},
- {"write", f_write},
- {"__gc", io_gc},
- {"__tostring", io_tostring},
- {NULL, NULL}
-};
-
-
-static void createmeta (lua_State *L) {
- luaL_newmetatable(L, LUA_FILEHANDLE); /* create metatable for file handles */
- lua_pushvalue(L, -1); /* push metatable */
- lua_setfield(L, -2, "__index"); /* metatable.__index = metatable */
- luaL_register(L, NULL, flib); /* file methods */
-}
-
-
-static void createstdfile (lua_State *L, FILE *f, int k, const char *fname) {
- *newfile(L) = f;
- if (k > 0) {
- lua_pushvalue(L, -1);
- lua_rawseti(L, LUA_ENVIRONINDEX, k);
- }
- lua_pushvalue(L, -2); /* copy environment */
- lua_setfenv(L, -2); /* set it */
- lua_setfield(L, -3, fname);
-}
-
-
-static void newfenv (lua_State *L, lua_CFunction cls) {
- lua_createtable(L, 0, 1);
- lua_pushcfunction(L, cls);
- lua_setfield(L, -2, "__close");
-}
-
-
-LUALIB_API int luaopen_io (lua_State *L) {
- createmeta(L);
- /* create (private) environment (with fields IO_INPUT, IO_OUTPUT, __close) */
- newfenv(L, io_fclose);
- lua_replace(L, LUA_ENVIRONINDEX);
- /* open library */
- luaL_register(L, LUA_IOLIBNAME, iolib);
- /* create (and set) default files */
- newfenv(L, io_noclose); /* close function for default files */
- createstdfile(L, stdin, IO_INPUT, "stdin");
- createstdfile(L, stdout, IO_OUTPUT, "stdout");
- createstdfile(L, stderr, 0, "stderr");
- lua_pop(L, 1); /* pop environment for default files */
- lua_getfield(L, -1, "popen");
- newfenv(L, io_pclose); /* create environment for 'popen' */
- lua_setfenv(L, -2); /* set fenv for 'popen' */
- lua_pop(L, 1); /* pop 'popen' */
- return 1;
-}
-
diff --git a/crawl-ref/source/util/lua/src/llex.c b/crawl-ref/source/util/lua/src/llex.c
deleted file mode 100644
index 6dc319358c..0000000000
--- a/crawl-ref/source/util/lua/src/llex.c
+++ /dev/null
@@ -1,461 +0,0 @@
-/*
-** $Id: llex.c,v 2.20.1.1 2007/12/27 13:02:25 roberto Exp $
-** Lexical Analyzer
-** See Copyright Notice in lua.h
-*/
-
-
-#include <ctype.h>
-#include <locale.h>
-#include <string.h>
-
-#define llex_c
-#define LUA_CORE
-
-#include "lua.h"
-
-#include "ldo.h"
-#include "llex.h"
-#include "lobject.h"
-#include "lparser.h"
-#include "lstate.h"
-#include "lstring.h"
-#include "ltable.h"
-#include "lzio.h"
-
-
-
-#define next(ls) (ls->current = zgetc(ls->z))
-
-
-
-
-#define currIsNewline(ls) (ls->current == '\n' || ls->current == '\r')
-
-
-/* ORDER RESERVED */
-const char *const luaX_tokens [] = {
- "and", "break", "do", "else", "elseif",
- "end", "false", "for", "function", "if",
- "in", "local", "nil", "not", "or", "repeat",
- "return", "then", "true", "until", "while",
- "..", "...", "==", ">=", "<=", "~=",
- "<number>", "<name>", "<string>", "<eof>",
- NULL
-};
-
-
-#define save_and_next(ls) (save(ls, ls->current), next(ls))
-
-
-static void save (LexState *ls, int c) {
- Mbuffer *b = ls->buff;
- if (b->n + 1 > b->buffsize) {
- size_t newsize;
- if (b->buffsize >= MAX_SIZET/2)
- luaX_lexerror(ls, "lexical element too long", 0);
- newsize = b->buffsize * 2;
- luaZ_resizebuffer(ls->L, b, newsize);
- }
- b->buffer[b->n++] = cast(char, c);
-}
-
-
-void luaX_init (lua_State *L) {
- int i;
- for (i=0; i<NUM_RESERVED; i++) {
- TString *ts = luaS_new(L, luaX_tokens[i]);
- luaS_fix(ts); /* reserved words are never collected */
- lua_assert(strlen(luaX_tokens[i])+1 <= TOKEN_LEN);
- ts->tsv.reserved = cast_byte(i+1); /* reserved word */
- }
-}
-
-
-#define MAXSRC 80
-
-
-const char *luaX_token2str (LexState *ls, int token) {
- if (token < FIRST_RESERVED) {
- lua_assert(token == cast(unsigned char, token));
- return (iscntrl(token)) ? luaO_pushfstring(ls->L, "char(%d)", token) :
- luaO_pushfstring(ls->L, "%c", token);
- }
- else
- return luaX_tokens[token-FIRST_RESERVED];
-}
-
-
-static const char *txtToken (LexState *ls, int token) {
- switch (token) {
- case TK_NAME:
- case TK_STRING:
- case TK_NUMBER:
- save(ls, '\0');
- return luaZ_buffer(ls->buff);
- default:
- return luaX_token2str(ls, token);
- }
-}
-
-
-void luaX_lexerror (LexState *ls, const char *msg, int token) {
- char buff[MAXSRC];
- luaO_chunkid(buff, getstr(ls->source), MAXSRC);
- msg = luaO_pushfstring(ls->L, "%s:%d: %s", buff, ls->linenumber, msg);
- if (token)
- luaO_pushfstring(ls->L, "%s near " LUA_QS, msg, txtToken(ls, token));
- luaD_throw(ls->L, LUA_ERRSYNTAX);
-}
-
-
-void luaX_syntaxerror (LexState *ls, const char *msg) {
- luaX_lexerror(ls, msg, ls->t.token);
-}
-
-
-TString *luaX_newstring (LexState *ls, const char *str, size_t l) {
- lua_State *L = ls->L;
- TString *ts = luaS_newlstr(L, str, l);
- TValue *o = luaH_setstr(L, ls->fs->h, ts); /* entry for `str' */
- if (ttisnil(o))
- setbvalue(o, 1); /* make sure `str' will not be collected */
- return ts;
-}
-
-
-static void inclinenumber (LexState *ls) {
- int old = ls->current;
- lua_assert(currIsNewline(ls));
- next(ls); /* skip `\n' or `\r' */
- if (currIsNewline(ls) && ls->current != old)
- next(ls); /* skip `\n\r' or `\r\n' */
- if (++ls->linenumber >= MAX_INT)
- luaX_syntaxerror(ls, "chunk has too many lines");
-}
-
-
-void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, TString *source) {
- ls->decpoint = '.';
- ls->L = L;
- ls->lookahead.token = TK_EOS; /* no look-ahead token */
- ls->z = z;
- ls->fs = NULL;
- ls->linenumber = 1;
- ls->lastline = 1;
- ls->source = source;
- luaZ_resizebuffer(ls->L, ls->buff, LUA_MINBUFFER); /* initialize buffer */
- next(ls); /* read first char */
-}
-
-
-
-/*
-** =======================================================
-** LEXICAL ANALYZER
-** =======================================================
-*/
-
-
-
-static int check_next (LexState *ls, const char *set) {
- if (!strchr(set, ls->current))
- return 0;
- save_and_next(ls);
- return 1;
-}
-
-
-static void buffreplace (LexState *ls, char from, char to) {
- size_t n = luaZ_bufflen(ls->buff);
- char *p = luaZ_buffer(ls->buff);
- while (n--)
- if (p[n] == from) p[n] = to;
-}
-
-
-static void trydecpoint (LexState *ls, SemInfo *seminfo) {
- /* format error: try to update decimal point separator */
- struct lconv *cv = localeconv();
- char old = ls->decpoint;
- ls->decpoint = (cv ? cv->decimal_point[0] : '.');
- buffreplace(ls, old, ls->decpoint); /* try updated decimal separator */
- if (!luaO_str2d(luaZ_buffer(ls->buff), &seminfo->r)) {
- /* format error with correct decimal point: no more options */
- buffreplace(ls, ls->decpoint, '.'); /* undo change (for error message) */
- luaX_lexerror(ls, "malformed number", TK_NUMBER);
- }
-}
-
-
-/* LUA_NUMBER */
-static void read_numeral (LexState *ls, SemInfo *seminfo) {
- lua_assert(isdigit(ls->current));
- do {
- save_and_next(ls);
- } while (isdigit(ls->current) || ls->current == '.');
- if (check_next(ls, "Ee")) /* `E'? */
- check_next(ls, "+-"); /* optional exponent sign */
- while (isalnum(ls->current) || ls->current == '_')
- save_and_next(ls);
- save(ls, '\0');
- buffreplace(ls, '.', ls->decpoint); /* follow locale for decimal point */
- if (!luaO_str2d(luaZ_buffer(ls->buff), &seminfo->r)) /* format error? */
- trydecpoint(ls, seminfo); /* try to update decimal point separator */
-}
-
-
-static int skip_sep (LexState *ls) {
- int count = 0;
- int s = ls->current;
- lua_assert(s == '[' || s == ']');
- save_and_next(ls);
- while (ls->current == '=') {
- save_and_next(ls);
- count++;
- }
- return (ls->current == s) ? count : (-count) - 1;
-}
-
-
-static void read_long_string (LexState *ls, SemInfo *seminfo, int sep) {
- int cont = 0;
- (void)(cont); /* avoid warnings when `cont' is not used */
- save_and_next(ls); /* skip 2nd `[' */
- if (currIsNewline(ls)) /* string starts with a newline? */
- inclinenumber(ls); /* skip it */
- for (;;) {
- switch (ls->current) {
- case EOZ:
- luaX_lexerror(ls, (seminfo) ? "unfinished long string" :
- "unfinished long comment", TK_EOS);
- break; /* to avoid warnings */
-#if defined(LUA_COMPAT_LSTR)
- case '[': {
- if (skip_sep(ls) == sep) {
- save_and_next(ls); /* skip 2nd `[' */
- cont++;
-#if LUA_COMPAT_LSTR == 1
- if (sep == 0)
- luaX_lexerror(ls, "nesting of [[...]] is deprecated", '[');
-#endif
- }
- break;
- }
-#endif
- case ']': {
- if (skip_sep(ls) == sep) {
- save_and_next(ls); /* skip 2nd `]' */
-#if defined(LUA_COMPAT_LSTR) && LUA_COMPAT_LSTR == 2
- cont--;
- if (sep == 0 && cont >= 0) break;
-#endif
- goto endloop;
- }
- break;
- }
- case '\n':
- case '\r': {
- save(ls, '\n');
- inclinenumber(ls);
- if (!seminfo) luaZ_resetbuffer(ls->buff); /* avoid wasting space */
- break;
- }
- default: {
- if (seminfo) save_and_next(ls);
- else next(ls);
- }
- }
- } endloop:
- if (seminfo)
- seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + (2 + sep),
- luaZ_bufflen(ls->buff) - 2*(2 + sep));
-}
-
-
-static void read_string (LexState *ls, int del, SemInfo *seminfo) {
- save_and_next(ls);
- while (ls->current != del) {
- switch (ls->current) {
- case EOZ:
- luaX_lexerror(ls, "unfinished string", TK_EOS);
- continue; /* to avoid warnings */
- case '\n':
- case '\r':
- luaX_lexerror(ls, "unfinished string", TK_STRING);
- continue; /* to avoid warnings */
- case '\\': {
- int c;
- next(ls); /* do not save the `\' */
- switch (ls->current) {
- case 'a': c = '\a'; break;
- case 'b': c = '\b'; break;
- case 'f': c = '\f'; break;
- case 'n': c = '\n'; break;
- case 'r': c = '\r'; break;
- case 't': c = '\t'; break;
- case 'v': c = '\v'; break;
- case '\n': /* go through */
- case '\r': save(ls, '\n'); inclinenumber(ls); continue;
- case EOZ: continue; /* will raise an error next loop */
- default: {
- if (!isdigit(ls->current))
- save_and_next(ls); /* handles \\, \", \', and \? */
- else { /* \xxx */
- int i = 0;
- c = 0;
- do {
- c = 10*c + (ls->current-'0');
- next(ls);
- } while (++i<3 && isdigit(ls->current));
- if (c > UCHAR_MAX)
- luaX_lexerror(ls, "escape sequence too large", TK_STRING);
- save(ls, c);
- }
- continue;
- }
- }
- save(ls, c);
- next(ls);
- continue;
- }
- default:
- save_and_next(ls);
- }
- }
- save_and_next(ls); /* skip delimiter */
- seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + 1,
- luaZ_bufflen(ls->buff) - 2);
-}
-
-
-static int llex (LexState *ls, SemInfo *seminfo) {
- luaZ_resetbuffer(ls->buff);
- for (;;) {
- switch (ls->current) {
- case '\n':
- case '\r': {
- inclinenumber(ls);
- continue;
- }
- case '-': {
- next(ls);
- if (ls->current != '-') return '-';
- /* else is a comment */
- next(ls);
- if (ls->current == '[') {
- int sep = skip_sep(ls);
- luaZ_resetbuffer(ls->buff); /* `skip_sep' may dirty the buffer */
- if (sep >= 0) {
- read_long_string(ls, NULL, sep); /* long comment */
- luaZ_resetbuffer(ls->buff);
- continue;
- }
- }
- /* else short comment */
- while (!currIsNewline(ls) && ls->current != EOZ)
- next(ls);
- continue;
- }
- case '[': {
- int sep = skip_sep(ls);
- if (sep >= 0) {
- read_long_string(ls, seminfo, sep);
- return TK_STRING;
- }
- else if (sep == -1) return '[';
- else luaX_lexerror(ls, "invalid long string delimiter", TK_STRING);
- }
- case '=': {
- next(ls);
- if (ls->current != '=') return '=';
- else { next(ls); return TK_EQ; }
- }
- case '<': {
- next(ls);
- if (ls->current != '=') return '<';
- else { next(ls); return TK_LE; }
- }
- case '>': {
- next(ls);
- if (ls->current != '=') return '>';
- else { next(ls); return TK_GE; }
- }
- case '~': {
- next(ls);
- if (ls->current != '=') return '~';
- else { next(ls); return TK_NE; }
- }
- case '"':
- case '\'': {
- read_string(ls, ls->current, seminfo);
- return TK_STRING;
- }
- case '.': {
- save_and_next(ls);
- if (check_next(ls, ".")) {
- if (check_next(ls, "."))
- return TK_DOTS; /* ... */
- else return TK_CONCAT; /* .. */
- }
- else if (!isdigit(ls->current)) return '.';
- else {
- read_numeral(ls, seminfo);
- return TK_NUMBER;
- }
- }
- case EOZ: {
- return TK_EOS;
- }
- default: {
- if (isspace(ls->current)) {
- lua_assert(!currIsNewline(ls));
- next(ls);
- continue;
- }
- else if (isdigit(ls->current)) {
- read_numeral(ls, seminfo);
- return TK_NUMBER;
- }
- else if (isalpha(ls->current) || ls->current == '_') {
- /* identifier or reserved word */
- TString *ts;
- do {
- save_and_next(ls);
- } while (isalnum(ls->current) || ls->current == '_');
- ts = luaX_newstring(ls, luaZ_buffer(ls->buff),
- luaZ_bufflen(ls->buff));
- if (ts->tsv.reserved > 0) /* reserved word? */
- return ts->tsv.reserved - 1 + FIRST_RESERVED;
- else {
- seminfo->ts = ts;
- return TK_NAME;
- }
- }
- else {
- int c = ls->current;
- next(ls);
- return c; /* single-char tokens (+ - / ...) */
- }
- }
- }
- }
-}
-
-
-void luaX_next (LexState *ls) {
- ls->lastline = ls->linenumber;
- if (ls->lookahead.token != TK_EOS) { /* is there a look-ahead token? */
- ls->t = ls->lookahead; /* use this one */
- ls->lookahead.token = TK_EOS; /* and discharge it */
- }
- else
- ls->t.token = llex(ls, &ls->t.seminfo); /* read next token */
-}
-
-
-void luaX_lookahead (LexState *ls) {
- lua_assert(ls->lookahead.token == TK_EOS);
- ls->lookahead.token = llex(ls, &ls->lookahead.seminfo);
-}
-
diff --git a/crawl-ref/source/util/lua/src/llex.h b/crawl-ref/source/util/lua/src/llex.h
deleted file mode 100644
index a9201cee48..0000000000
--- a/crawl-ref/source/util/lua/src/llex.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
-** $Id: llex.h,v 1.58.1.1 2007/12/27 13:02:25 roberto Exp $
-** Lexical Analyzer
-** See Copyright Notice in lua.h
-*/
-
-#ifndef llex_h
-#define llex_h
-
-#include "lobject.h"
-#include "lzio.h"
-
-
-#define FIRST_RESERVED 257
-
-/* maximum length of a reserved word */
-#define TOKEN_LEN (sizeof("function")/sizeof(char))
-
-
-/*
-* WARNING: if you change the order of this enumeration,
-* grep "ORDER RESERVED"
-*/
-enum RESERVED {
- /* terminal symbols denoted by reserved words */
- TK_AND = FIRST_RESERVED, TK_BREAK,
- TK_DO, TK_ELSE, TK_ELSEIF, TK_END, TK_FALSE, TK_FOR, TK_FUNCTION,
- TK_IF, TK_IN, TK_LOCAL, TK_NIL, TK_NOT, TK_OR, TK_REPEAT,
- TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE,
- /* other terminal symbols */
- TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, TK_NUMBER,
- TK_NAME, TK_STRING, TK_EOS
-};
-
-/* number of reserved words */
-#define NUM_RESERVED (cast(int, TK_WHILE-FIRST_RESERVED+1))
-
-
-/* array with token `names' */
-LUAI_DATA const char *const luaX_tokens [];
-
-
-typedef union {
- lua_Number r;
- TString *ts;
-} SemInfo; /* semantics information */
-
-
-typedef struct Token {
- int token;
- SemInfo seminfo;
-} Token;
-
-
-typedef struct LexState {
- int current; /* current character (charint) */
- int linenumber; /* input line counter */
- int lastline; /* line of last token `consumed' */
- Token t; /* current token */
- Token lookahead; /* look ahead token */
- struct FuncState *fs; /* `FuncState' is private to the parser */
- struct lua_State *L;
- ZIO *z; /* input stream */
- Mbuffer *buff; /* buffer for tokens */
- TString *source; /* current source name */
- char decpoint; /* locale decimal point */
-} LexState;
-
-
-LUAI_FUNC void luaX_init (lua_State *L);
-LUAI_FUNC void luaX_setinput (lua_State *L, LexState *ls, ZIO *z,
- TString *source);
-LUAI_FUNC TString *luaX_newstring (LexState *ls, const char *str, size_t l);
-LUAI_FUNC void luaX_next (LexState *ls);
-LUAI_FUNC void luaX_lookahead (LexState *ls);
-LUAI_FUNC void luaX_lexerror (LexState *ls, const char *msg, int token);
-LUAI_FUNC void luaX_syntaxerror (LexState *ls, const char *s);
-LUAI_FUNC const char *luaX_token2str (LexState *ls, int token);
-
-
-#endif
diff --git a/crawl-ref/source/util/lua/src/llimits.h b/crawl-ref/source/util/lua/src/llimits.h
deleted file mode 100644
index ca8dcb7224..0000000000
--- a/crawl-ref/source/util/lua/src/llimits.h
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
-** $Id: llimits.h,v 1.69.1.1 2007/12/27 13:02:25 roberto Exp $
-** Limits, basic types, and some other `installation-dependent' definitions
-** See Copyright Notice in lua.h
-*/
-
-#ifndef llimits_h
-#define llimits_h
-
-
-#include <limits.h>
-#include <stddef.h>
-
-
-#include "lua.h"
-
-
-typedef LUAI_UINT32 lu_int32;
-
-typedef LUAI_UMEM lu_mem;
-
-typedef LUAI_MEM l_mem;
-
-
-
-/* chars used as small naturals (so that `char' is reserved for characters) */
-typedef unsigned char lu_byte;
-
-
-#define MAX_SIZET ((size_t)(~(size_t)0)-2)
-
-#define MAX_LUMEM ((lu_mem)(~(lu_mem)0)-2)
-
-
-#define MAX_INT (INT_MAX-2) /* maximum value of an int (-2 for safety) */
-
-/*
-** conversion of pointer to integer
-** this is for hashing only; there is no problem if the integer
-** cannot hold the whole pointer value
-*/
-#define IntPoint(p) ((unsigned int)(lu_mem)(p))
-
-
-
-/* type to ensure maximum alignment */
-typedef LUAI_USER_ALIGNMENT_T L_Umaxalign;
-
-
-/* result of a `usual argument conversion' over lua_Number */
-typedef LUAI_UACNUMBER l_uacNumber;
-
-
-/* internal assertions for in-house debugging */
-#ifdef lua_assert
-
-#define check_exp(c,e) (lua_assert(c), (e))
-#define api_check(l,e) lua_assert(e)
-
-#else
-
-#define lua_assert(c) ((void)0)
-#define check_exp(c,e) (e)
-#define api_check luai_apicheck
-
-#endif
-
-
-#ifndef UNUSED
-#define UNUSED(x) ((void)(x)) /* to avoid warnings */
-#endif
-
-
-#ifndef cast
-#define cast(t, exp) ((t)(exp))
-#endif
-
-#define cast_byte(i) cast(lu_byte, (i))
-#define cast_num(i) cast(lua_Number, (i))
-#define cast_int(i) cast(int, (i))
-
-
-
-/*
-** type for virtual-machine instructions
-** must be an unsigned with (at least) 4 bytes (see details in lopcodes.h)
-*/
-typedef lu_int32 Instruction;
-
-
-
-/* maximum stack for a Lua function */
-#define MAXSTACK 250
-
-
-
-/* minimum size for the string table (must be power of 2) */
-#ifndef MINSTRTABSIZE
-#define MINSTRTABSIZE 32
-#endif
-
-
-/* minimum size for string buffer */
-#ifndef LUA_MINBUFFER
-#define LUA_MINBUFFER 32
-#endif
-
-
-#ifndef lua_lock
-#define lua_lock(L) ((void) 0)
-#define lua_unlock(L) ((void) 0)
-#endif
-
-#ifndef luai_threadyield
-#define luai_threadyield(L) {lua_unlock(L); lua_lock(L);}
-#endif
-
-
-/*
-** macro to control inclusion of some hard tests on stack reallocation
-*/
-#ifndef HARDSTACKTESTS
-#define condhardstacktests(x) ((void)0)
-#else
-#define condhardstacktests(x) x
-#endif
-
-#endif
diff --git a/crawl-ref/source/util/lua/src/lmathlib.c b/crawl-ref/source/util/lua/src/lmathlib.c
deleted file mode 100644
index 441fbf736c..0000000000
--- a/crawl-ref/source/util/lua/src/lmathlib.c
+++ /dev/null
@@ -1,263 +0,0 @@
-/*
-** $Id: lmathlib.c,v 1.67.1.1 2007/12/27 13:02:25 roberto Exp $
-** Standard mathematical library
-** See Copyright Notice in lua.h
-*/
-
-
-#include <stdlib.h>
-#include <math.h>
-
-#define lmathlib_c
-#define LUA_LIB
-
-#include "lua.h"
-
-#include "lauxlib.h"
-#include "lualib.h"
-
-
-#undef PI
-#define PI (3.14159265358979323846)
-#define RADIANS_PER_DEGREE (PI/180.0)
-
-
-
-static int math_abs (lua_State *L) {
- lua_pushnumber(L, fabs(luaL_checknumber(L, 1)));
- return 1;
-}
-
-static int math_sin (lua_State *L) {
- lua_pushnumber(L, sin(luaL_checknumber(L, 1)));
- return 1;
-}
-
-static int math_sinh (lua_State *L) {
- lua_pushnumber(L, sinh(luaL_checknumber(L, 1)));
- return 1;
-}
-
-static int math_cos (lua_State *L) {
- lua_pushnumber(L, cos(luaL_checknumber(L, 1)));
- return 1;
-}
-
-static int math_cosh (lua_State *L) {
- lua_pushnumber(L, cosh(luaL_checknumber(L, 1)));
- return 1;
-}
-
-static int math_tan (lua_State *L) {
- lua_pushnumber(L, tan(luaL_checknumber(L, 1)));
- return 1;
-}
-
-static int math_tanh (lua_State *L) {
- lua_pushnumber(L, tanh(luaL_checknumber(L, 1)));
- return 1;
-}
-
-static int math_asin (lua_State *L) {
- lua_pushnumber(L, asin(luaL_checknumber(L, 1)));
- return 1;
-}
-
-static int math_acos (lua_State *L) {
- lua_pushnumber(L, acos(luaL_checknumber(L, 1)));
- return 1;
-}
-
-static int math_atan (lua_State *L) {
- lua_pushnumber(L, atan(luaL_checknumber(L, 1)));
- return 1;
-}
-
-static int math_atan2 (lua_State *L) {
- lua_pushnumber(L, atan2(luaL_checknumber(L, 1), luaL_checknumber(L, 2)));
- return 1;
-}
-
-static int math_ceil (lua_State *L) {
- lua_pushnumber(L, ceil(luaL_checknumber(L, 1)));
- return 1;
-}
-
-static int math_floor (lua_State *L) {
- lua_pushnumber(L, floor(luaL_checknumber(L, 1)));
- return 1;
-}
-
-static int math_fmod (lua_State *L) {
- lua_pushnumber(L, fmod(luaL_checknumber(L, 1), luaL_checknumber(L, 2)));
- return 1;
-}
-
-static int math_modf (lua_State *L) {
- double ip;
- double fp = modf(luaL_checknumber(L, 1), &ip);
- lua_pushnumber(L, ip);
- lua_pushnumber(L, fp);
- return 2;
-}
-
-static int math_sqrt (lua_State *L) {
- lua_pushnumber(L, sqrt(luaL_checknumber(L, 1)));
- return 1;
-}
-
-static int math_pow (lua_State *L) {
- lua_pushnumber(L, pow(luaL_checknumber(L, 1), luaL_checknumber(L, 2)));
- return 1;
-}
-
-static int math_log (lua_State *L) {
- lua_pushnumber(L, log(luaL_checknumber(L, 1)));
- return 1;
-}
-
-static int math_log10 (lua_State *L) {
- lua_pushnumber(L, log10(luaL_checknumber(L, 1)));
- return 1;
-}
-
-static int math_exp (lua_State *L) {
- lua_pushnumber(L, exp(luaL_checknumber(L, 1)));
- return 1;
-}
-
-static int math_deg (lua_State *L) {
- lua_pushnumber(L, luaL_checknumber(L, 1)/RADIANS_PER_DEGREE);
- return 1;
-}
-
-static int math_rad (lua_State *L) {
- lua_pushnumber(L, luaL_checknumber(L, 1)*RADIANS_PER_DEGREE);
- return 1;
-}
-
-static int math_frexp (lua_State *L) {
- int e;
- lua_pushnumber(L, frexp(luaL_checknumber(L, 1), &e));
- lua_pushinteger(L, e);
- return 2;
-}
-
-static int math_ldexp (lua_State *L) {
- lua_pushnumber(L, ldexp(luaL_checknumber(L, 1), luaL_checkint(L, 2)));
- return 1;
-}
-
-
-
-static int math_min (lua_State *L) {
- int n = lua_gettop(L); /* number of arguments */
- lua_Number dmin = luaL_checknumber(L, 1);
- int i;
- for (i=2; i<=n; i++) {
- lua_Number d = luaL_checknumber(L, i);
- if (d < dmin)
- dmin = d;
- }
- lua_pushnumber(L, dmin);
- return 1;
-}
-
-
-static int math_max (lua_State *L) {
- int n = lua_gettop(L); /* number of arguments */
- lua_Number dmax = luaL_checknumber(L, 1);
- int i;
- for (i=2; i<=n; i++) {
- lua_Number d = luaL_checknumber(L, i);
- if (d > dmax)
- dmax = d;
- }
- lua_pushnumber(L, dmax);
- return 1;
-}
-
-
-static int math_random (lua_State *L) {
- /* the `%' avoids the (rare) case of r==1, and is needed also because on
- some systems (SunOS!) `rand()' may return a value larger than RAND_MAX */
- lua_Number r = (lua_Number)(rand()%RAND_MAX) / (lua_Number)RAND_MAX;
- switch (lua_gettop(L)) { /* check number of arguments */
- case 0: { /* no arguments */
- lua_pushnumber(L, r); /* Number between 0 and 1 */
- break;
- }
- case 1: { /* only upper limit */
- int u = luaL_checkint(L, 1);
- luaL_argcheck(L, 1<=u, 1, "interval is empty");
- lua_pushnumber(L, floor(r*u)+1); /* int between 1 and `u' */
- break;
- }
- case 2: { /* lower and upper limits */
- int l = luaL_checkint(L, 1);
- int u = luaL_checkint(L, 2);
- luaL_argcheck(L, l<=u, 2, "interval is empty");
- lua_pushnumber(L, floor(r*(u-l+1))+l); /* int between `l' and `u' */
- break;
- }
- default: return luaL_error(L, "wrong number of arguments");
- }
- return 1;
-}
-
-
-static int math_randomseed (lua_State *L) {
- srand(luaL_checkint(L, 1));
- return 0;
-}
-
-
-static const luaL_Reg mathlib[] = {
- {"abs", math_abs},
- {"acos", math_acos},
- {"asin", math_asin},
- {"atan2", math_atan2},
- {"atan", math_atan},
- {"ceil", math_ceil},
- {"cosh", math_cosh},
- {"cos", math_cos},
- {"deg", math_deg},
- {"exp", math_exp},
- {"floor", math_floor},
- {"fmod", math_fmod},
- {"frexp", math_frexp},
- {"ldexp", math_ldexp},
- {"log10", math_log10},
- {"log", math_log},
- {"max", math_max},
- {"min", math_min},
- {"modf", math_modf},
- {"pow", math_pow},
- {"rad", math_rad},
- {"random", math_random},
- {"randomseed", math_randomseed},
- {"sinh", math_sinh},
- {"sin", math_sin},
- {"sqrt", math_sqrt},
- {"tanh", math_tanh},
- {"tan", math_tan},
- {NULL, NULL}
-};
-
-
-/*
-** Open math library
-*/
-LUALIB_API int luaopen_math (lua_State *L) {
- luaL_register(L, LUA_MATHLIBNAME, mathlib);
- lua_pushnumber(L, PI);
- lua_setfield(L, -2, "pi");
- lua_pushnumber(L, HUGE_VAL);
- lua_setfield(L, -2, "huge");
-#if defined(LUA_COMPAT_MOD)
- lua_getfield(L, -1, "fmod");
- lua_setfield(L, -2, "mod");
-#endif
- return 1;
-}
-
diff --git a/crawl-ref/source/util/lua/src/lmem.c b/crawl-ref/source/util/lua/src/lmem.c
deleted file mode 100644
index ae7d8c965f..0000000000
--- a/crawl-ref/source/util/lua/src/lmem.c
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
-** $Id: lmem.c,v 1.70.1.1 2007/12/27 13:02:25 roberto Exp $
-** Interface to Memory Manager
-** See Copyright Notice in lua.h
-*/
-
-
-#include <stddef.h>
-
-#define lmem_c
-#define LUA_CORE
-
-#include "lua.h"
-
-#include "ldebug.h"
-#include "ldo.h"
-#include "lmem.h"
-#include "lobject.h"
-#include "lstate.h"
-
-
-
-/*
-** About the realloc function:
-** void * frealloc (void *ud, void *ptr, size_t osize, size_t nsize);
-** (`osize' is the old size, `nsize' is the new size)
-**
-** Lua ensures that (ptr == NULL) iff (osize == 0).
-**
-** * frealloc(ud, NULL, 0, x) creates a new block of size `x'
-**
-** * frealloc(ud, p, x, 0) frees the block `p'
-** (in this specific case, frealloc must return NULL).
-** particularly, frealloc(ud, NULL, 0, 0) does nothing
-** (which is equivalent to free(NULL) in ANSI C)
-**
-** frealloc returns NULL if it cannot create or reallocate the area
-** (any reallocation to an equal or smaller size cannot fail!)
-*/
-
-
-
-#define MINSIZEARRAY 4
-
-
-void *luaM_growaux_ (lua_State *L, void *block, int *size, size_t size_elems,
- int limit, const char *errormsg) {
- void *newblock;
- int newsize;
- if (*size >= limit/2) { /* cannot double it? */
- if (*size >= limit) /* cannot grow even a little? */
- luaG_runerror(L, errormsg);
- newsize = limit; /* still have at least one free place */
- }
- else {
- newsize = (*size)*2;
- if (newsize < MINSIZEARRAY)
- newsize = MINSIZEARRAY; /* minimum size */
- }
- newblock = luaM_reallocv(L, block, *size, newsize, size_elems);
- *size = newsize; /* update only when everything else is OK */
- return newblock;
-}
-
-
-void *luaM_toobig (lua_State *L) {
- luaG_runerror(L, "memory allocation error: block too big");
- return NULL; /* to avoid warnings */
-}
-
-
-
-/*
-** generic allocation routine.
-*/
-void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) {
- global_State *g = G(L);
- lua_assert((osize == 0) == (block == NULL));
- block = (*g->frealloc)(g->ud, block, osize, nsize);
- if (block == NULL && nsize > 0)
- luaD_throw(L, LUA_ERRMEM);
- lua_assert((nsize == 0) == (block == NULL));
- g->totalbytes = (g->totalbytes - osize) + nsize;
- return block;
-}
-
diff --git a/crawl-ref/source/util/lua/src/lmem.h b/crawl-ref/source/util/lua/src/lmem.h
deleted file mode 100644
index 7c2dcb3220..0000000000
--- a/crawl-ref/source/util/lua/src/lmem.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
-** $Id: lmem.h,v 1.31.1.1 2007/12/27 13:02:25 roberto Exp $
-** Interface to Memory Manager
-** See Copyright Notice in lua.h
-*/
-
-#ifndef lmem_h
-#define lmem_h
-
-
-#include <stddef.h>
-
-#include "llimits.h"
-#include "lua.h"
-
-#define MEMERRMSG "not enough memory"
-
-
-#define luaM_reallocv(L,b,on,n,e) \
- ((cast(size_t, (n)+1) <= MAX_SIZET/(e)) ? /* +1 to avoid warnings */ \
- luaM_realloc_(L, (b), (on)*(e), (n)*(e)) : \
- luaM_toobig(L))
-
-#define luaM_freemem(L, b, s) luaM_realloc_(L, (b), (s), 0)
-#define luaM_free(L, b) luaM_realloc_(L, (b), sizeof(*(b)), 0)
-#define luaM_freearray(L, b, n, t) luaM_reallocv(L, (b), n, 0, sizeof(t))
-
-#define luaM_malloc(L,t) luaM_realloc_(L, NULL, 0, (t))
-#define luaM_new(L,t) cast(t *, luaM_malloc(L, sizeof(t)))
-#define luaM_newvector(L,n,t) \
- cast(t *, luaM_reallocv(L, NULL, 0, n, sizeof(t)))
-
-#define luaM_growvector(L,v,nelems,size,t,limit,e) \
- if ((nelems)+1 > (size)) \
- ((v)=cast(t *, luaM_growaux_(L,v,&(size),sizeof(t),limit,e)))
-
-#define luaM_reallocvector(L, v,oldn,n,t) \
- ((v)=cast(t *, luaM_reallocv(L, v, oldn, n, sizeof(t))))
-
-
-LUAI_FUNC void *luaM_realloc_ (lua_State *L, void *block, size_t oldsize,
- size_t size);
-LUAI_FUNC void *luaM_toobig (lua_State *L);
-LUAI_FUNC void *luaM_growaux_ (lua_State *L, void *block, int *size,
- size_t size_elem, int limit,
- const char *errormsg);
-
-#endif
-
diff --git a/crawl-ref/source/util/lua/src/loadlib.c b/crawl-ref/source/util/lua/src/loadlib.c
deleted file mode 100644
index 0d401eba1c..0000000000
--- a/crawl-ref/source/util/lua/src/loadlib.c
+++ /dev/null
@@ -1,666 +0,0 @@
-/*
-** $Id: loadlib.c,v 1.52.1.3 2008/08/06 13:29:28 roberto Exp $
-** Dynamic library loader for Lua
-** See Copyright Notice in lua.h
-**
-** This module contains an implementation of loadlib for Unix systems
-** that have dlfcn, an implementation for Darwin (Mac OS X), an
-** implementation for Windows, and a stub for other systems.
-*/
-
-
-#include <stdlib.h>
-#include <string.h>
-
-
-#define loadlib_c
-#define LUA_LIB
-
-#include "lua.h"
-
-#include "lauxlib.h"
-#include "lualib.h"
-
-
-/* prefix for open functions in C libraries */
-#define LUA_POF "luaopen_"
-
-/* separator for open functions in C libraries */
-#define LUA_OFSEP "_"
-
-
-#define LIBPREFIX "LOADLIB: "
-
-#define POF LUA_POF
-#define LIB_FAIL "open"
-
-
-/* error codes for ll_loadfunc */
-#define ERRLIB 1
-#define ERRFUNC 2
-
-#define setprogdir(L) ((void)0)
-
-
-static void ll_unloadlib (void *lib);
-static void *ll_load (lua_State *L, const char *path);
-static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym);
-
-
-
-#if defined(LUA_DL_DLOPEN)
-/*
-** {========================================================================
-** This is an implementation of loadlib based on the dlfcn interface.
-** The dlfcn interface is available in Linux, SunOS, Solaris, IRIX, FreeBSD,
-** NetBSD, AIX 4.2, HPUX 11, and probably most other Unix flavors, at least
-** as an emulation layer on top of native functions.
-** =========================================================================
-*/
-
-#include <dlfcn.h>
-
-static void ll_unloadlib (void *lib) {
- dlclose(lib);
-}
-
-
-static void *ll_load (lua_State *L, const char *path) {
- void *lib = dlopen(path, RTLD_NOW);
- if (lib == NULL) lua_pushstring(L, dlerror());
- return lib;
-}
-
-
-static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
- lua_CFunction f = (lua_CFunction)dlsym(lib, sym);
- if (f == NULL) lua_pushstring(L, dlerror());
- return f;
-}
-
-/* }====================================================== */
-
-
-
-#elif defined(LUA_DL_DLL)
-/*
-** {======================================================================
-** This is an implementation of loadlib for Windows using native functions.
-** =======================================================================
-*/
-
-#include <windows.h>
-
-
-#undef setprogdir
-
-static void setprogdir (lua_State *L) {
- char buff[MAX_PATH + 1];
- char *lb;
- DWORD nsize = sizeof(buff)/sizeof(char);
- DWORD n = GetModuleFileNameA(NULL, buff, nsize);
- if (n == 0 || n == nsize || (lb = strrchr(buff, '\\')) == NULL)
- luaL_error(L, "unable to get ModuleFileName");
- else {
- *lb = '\0';
- luaL_gsub(L, lua_tostring(L, -1), LUA_EXECDIR, buff);
- lua_remove(L, -2); /* remove original string */
- }
-}
-
-
-static void pusherror (lua_State *L) {
- int error = GetLastError();
- char buffer[128];
- if (FormatMessageA(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM,
- NULL, error, 0, buffer, sizeof(buffer), NULL))
- lua_pushstring(L, buffer);
- else
- lua_pushfstring(L, "system error %d\n", error);
-}
-
-static void ll_unloadlib (void *lib) {
- FreeLibrary((HINSTANCE)lib);
-}
-
-
-static void *ll_load (lua_State *L, const char *path) {
- HINSTANCE lib = LoadLibraryA(path);
- if (lib == NULL) pusherror(L);
- return lib;
-}
-
-
-static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
- lua_CFunction f = (lua_CFunction)GetProcAddress((HINSTANCE)lib, sym);
- if (f == NULL) pusherror(L);
- return f;
-}
-
-/* }====================================================== */
-
-
-
-#elif defined(LUA_DL_DYLD)
-/*
-** {======================================================================
-** Native Mac OS X / Darwin Implementation
-** =======================================================================
-*/
-
-#include <mach-o/dyld.h>
-
-
-/* Mac appends a `_' before C function names */
-#undef POF
-#define POF "_" LUA_POF
-
-
-static void pusherror (lua_State *L) {
- const char *err_str;
- const char *err_file;
- NSLinkEditErrors err;
- int err_num;
- NSLinkEditError(&err, &err_num, &err_file, &err_str);
- lua_pushstring(L, err_str);
-}
-
-
-static const char *errorfromcode (NSObjectFileImageReturnCode ret) {
- switch (ret) {
- case NSObjectFileImageInappropriateFile:
- return "file is not a bundle";
- case NSObjectFileImageArch:
- return "library is for wrong CPU type";
- case NSObjectFileImageFormat:
- return "bad format";
- case NSObjectFileImageAccess:
- return "cannot access file";
- case NSObjectFileImageFailure:
- default:
- return "unable to load library";
- }
-}
-
-
-static void ll_unloadlib (void *lib) {
- NSUnLinkModule((NSModule)lib, NSUNLINKMODULE_OPTION_RESET_LAZY_REFERENCES);
-}
-
-
-static void *ll_load (lua_State *L, const char *path) {
- NSObjectFileImage img;
- NSObjectFileImageReturnCode ret;
- /* this would be a rare case, but prevents crashing if it happens */
- if(!_dyld_present()) {
- lua_pushliteral(L, "dyld not present");
- return NULL;
- }
- ret = NSCreateObjectFileImageFromFile(path, &img);
- if (ret == NSObjectFileImageSuccess) {
- NSModule mod = NSLinkModule(img, path, NSLINKMODULE_OPTION_PRIVATE |
- NSLINKMODULE_OPTION_RETURN_ON_ERROR);
- NSDestroyObjectFileImage(img);
- if (mod == NULL) pusherror(L);
- return mod;
- }
- lua_pushstring(L, errorfromcode(ret));
- return NULL;
-}
-
-
-static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
- NSSymbol nss = NSLookupSymbolInModule((NSModule)lib, sym);
- if (nss == NULL) {
- lua_pushfstring(L, "symbol " LUA_QS " not found", sym);
- return NULL;
- }
- return (lua_CFunction)NSAddressOfSymbol(nss);
-}
-
-/* }====================================================== */
-
-
-
-#else
-/*
-** {======================================================
-** Fallback for other systems
-** =======================================================
-*/
-
-#undef LIB_FAIL
-#define LIB_FAIL "absent"
-
-
-#define DLMSG "dynamic libraries not enabled; check your Lua installation"
-
-
-static void ll_unloadlib (void *lib) {
- (void)lib; /* to avoid warnings */
-}
-
-
-static void *ll_load (lua_State *L, const char *path) {
- (void)path; /* to avoid warnings */
- lua_pushliteral(L, DLMSG);
- return NULL;
-}
-
-
-static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
- (void)lib; (void)sym; /* to avoid warnings */
- lua_pushliteral(L, DLMSG);
- return NULL;
-}
-
-/* }====================================================== */
-#endif
-
-
-
-static void **ll_register (lua_State *L, const char *path) {
- void **plib;
- lua_pushfstring(L, "%s%s", LIBPREFIX, path);
- lua_gettable(L, LUA_REGISTRYINDEX); /* check library in registry? */
- if (!lua_isnil(L, -1)) /* is there an entry? */
- plib = (void **)lua_touserdata(L, -1);
- else { /* no entry yet; create one */
- lua_pop(L, 1);
- plib = (void **)lua_newuserdata(L, sizeof(const void *));
- *plib = NULL;
- luaL_getmetatable(L, "_LOADLIB");
- lua_setmetatable(L, -2);
- lua_pushfstring(L, "%s%s", LIBPREFIX, path);
- lua_pushvalue(L, -2);
- lua_settable(L, LUA_REGISTRYINDEX);
- }
- return plib;
-}
-
-
-/*
-** __gc tag method: calls library's `ll_unloadlib' function with the lib
-** handle
-*/
-static int gctm (lua_State *L) {
- void **lib = (void **)luaL_checkudata(L, 1, "_LOADLIB");
- if (*lib) ll_unloadlib(*lib);
- *lib = NULL; /* mark library as closed */
- return 0;
-}
-
-
-static int ll_loadfunc (lua_State *L, const char *path, const char *sym) {
- void **reg = ll_register(L, path);
- if (*reg == NULL) *reg = ll_load(L, path);
- if (*reg == NULL)
- return ERRLIB; /* unable to load library */
- else {
- lua_CFunction f = ll_sym(L, *reg, sym);
- if (f == NULL)
- return ERRFUNC; /* unable to find function */
- lua_pushcfunction(L, f);
- return 0; /* return function */
- }
-}
-
-
-static int ll_loadlib (lua_State *L) {
- const char *path = luaL_checkstring(L, 1);
- const char *init = luaL_checkstring(L, 2);
- int stat = ll_loadfunc(L, path, init);
- if (stat == 0) /* no errors? */
- return 1; /* return the loaded function */
- else { /* error; error message is on stack top */
- lua_pushnil(L);
- lua_insert(L, -2);
- lua_pushstring(L, (stat == ERRLIB) ? LIB_FAIL : "init");
- return 3; /* return nil, error message, and where */
- }
-}
-
-
-
-/*
-** {======================================================
-** 'require' function
-** =======================================================
-*/
-
-
-static int readable (const char *filename) {
- FILE *f = fopen(filename, "r"); /* try to open file */
- if (f == NULL) return 0; /* open failed */
- fclose(f);
- return 1;
-}
-
-
-static const char *pushnexttemplate (lua_State *L, const char *path) {
- const char *l;
- while (*path == *LUA_PATHSEP) path++; /* skip separators */
- if (*path == '\0') return NULL; /* no more templates */
- l = strchr(path, *LUA_PATHSEP); /* find next separator */
- if (l == NULL) l = path + strlen(path);
- lua_pushlstring(L, path, l - path); /* template */
- return l;
-}
-
-
-static const char *findfile (lua_State *L, const char *name,
- const char *pname) {
- const char *path;
- name = luaL_gsub(L, name, ".", LUA_DIRSEP);
- lua_getfield(L, LUA_ENVIRONINDEX, pname);
- path = lua_tostring(L, -1);
- if (path == NULL)
- luaL_error(L, LUA_QL("package.%s") " must be a string", pname);
- lua_pushliteral(L, ""); /* error accumulator */
- while ((path = pushnexttemplate(L, path)) != NULL) {
- const char *filename;
- filename = luaL_gsub(L, lua_tostring(L, -1), LUA_PATH_MARK, name);
- lua_remove(L, -2); /* remove path template */
- if (readable(filename)) /* does file exist and is readable? */
- return filename; /* return that file name */
- lua_pushfstring(L, "\n\tno file " LUA_QS, filename);
- lua_remove(L, -2); /* remove file name */
- lua_concat(L, 2); /* add entry to possible error message */
- }
- return NULL; /* not found */
-}
-
-
-static void loaderror (lua_State *L, const char *filename) {
- luaL_error(L, "error loading module " LUA_QS " from file " LUA_QS ":\n\t%s",
- lua_tostring(L, 1), filename, lua_tostring(L, -1));
-}
-
-
-static int loader_Lua (lua_State *L) {
- const char *filename;
- const char *name = luaL_checkstring(L, 1);
- filename = findfile(L, name, "path");
- if (filename == NULL) return 1; /* library not found in this path */
- if (luaL_loadfile(L, filename) != 0)
- loaderror(L, filename);
- return 1; /* library loaded successfully */
-}
-
-
-static const char *mkfuncname (lua_State *L, const char *modname) {
- const char *funcname;
- const char *mark = strchr(modname, *LUA_IGMARK);
- if (mark) modname = mark + 1;
- funcname = luaL_gsub(L, modname, ".", LUA_OFSEP);
- funcname = lua_pushfstring(L, POF"%s", funcname);
- lua_remove(L, -2); /* remove 'gsub' result */
- return funcname;
-}
-
-
-static int loader_C (lua_State *L) {
- const char *funcname;
- const char *name = luaL_checkstring(L, 1);
- const char *filename = findfile(L, name, "cpath");
- if (filename == NULL) return 1; /* library not found in this path */
- funcname = mkfuncname(L, name);
- if (ll_loadfunc(L, filename, funcname) != 0)
- loaderror(L, filename);
- return 1; /* library loaded successfully */
-}
-
-
-static int loader_Croot (lua_State *L) {
- const char *funcname;
- const char *filename;
- const char *name = luaL_checkstring(L, 1);
- const char *p = strchr(name, '.');
- int stat;
- if (p == NULL) return 0; /* is root */
- lua_pushlstring(L, name, p - name);
- filename = findfile(L, lua_tostring(L, -1), "cpath");
- if (filename == NULL) return 1; /* root not found */
- funcname = mkfuncname(L, name);
- if ((stat = ll_loadfunc(L, filename, funcname)) != 0) {
- if (stat != ERRFUNC) loaderror(L, filename); /* real error */
- lua_pushfstring(L, "\n\tno module " LUA_QS " in file " LUA_QS,
- name, filename);
- return 1; /* function not found */
- }
- return 1;
-}
-
-
-static int loader_preload (lua_State *L) {
- const char *name = luaL_checkstring(L, 1);
- lua_getfield(L, LUA_ENVIRONINDEX, "preload");
- if (!lua_istable(L, -1))
- luaL_error(L, LUA_QL("package.preload") " must be a table");
- lua_getfield(L, -1, name);
- if (lua_isnil(L, -1)) /* not found? */
- lua_pushfstring(L, "\n\tno field package.preload['%s']", name);
- return 1;
-}
-
-
-static const int sentinel_ = 0;
-#define sentinel ((void *)&sentinel_)
-
-
-static int ll_require (lua_State *L) {
- const char *name = luaL_checkstring(L, 1);
- int i;
- lua_settop(L, 1); /* _LOADED table will be at index 2 */
- lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
- lua_getfield(L, 2, name);
- if (lua_toboolean(L, -1)) { /* is it there? */
- if (lua_touserdata(L, -1) == sentinel) /* check loops */
- luaL_error(L, "loop or previous error loading module " LUA_QS, name);
- return 1; /* package is already loaded */
- }
- /* else must load it; iterate over available loaders */
- lua_getfield(L, LUA_ENVIRONINDEX, "loaders");
- if (!lua_istable(L, -1))
- luaL_error(L, LUA_QL("package.loaders") " must be a table");
- lua_pushliteral(L, ""); /* error message accumulator */
- for (i=1; ; i++) {
- lua_rawgeti(L, -2, i); /* get a loader */
- if (lua_isnil(L, -1))
- luaL_error(L, "module " LUA_QS " not found:%s",
- name, lua_tostring(L, -2));
- lua_pushstring(L, name);
- lua_call(L, 1, 1); /* call it */
- if (lua_isfunction(L, -1)) /* did it find module? */
- break; /* module loaded successfully */
- else if (lua_isstring(L, -1)) /* loader returned error message? */
- lua_concat(L, 2); /* accumulate it */
- else
- lua_pop(L, 1);
- }
- lua_pushlightuserdata(L, sentinel);
- lua_setfield(L, 2, name); /* _LOADED[name] = sentinel */
- lua_pushstring(L, name); /* pass name as argument to module */
- lua_call(L, 1, 1); /* run loaded module */
- if (!lua_isnil(L, -1)) /* non-nil return? */
- lua_setfield(L, 2, name); /* _LOADED[name] = returned value */
- lua_getfield(L, 2, name);
- if (lua_touserdata(L, -1) == sentinel) { /* module did not set a value? */
- lua_pushboolean(L, 1); /* use true as result */
- lua_pushvalue(L, -1); /* extra copy to be returned */
- lua_setfield(L, 2, name); /* _LOADED[name] = true */
- }
- return 1;
-}
-
-/* }====================================================== */
-
-
-
-/*
-** {======================================================
-** 'module' function
-** =======================================================
-*/
-
-
-static void setfenv (lua_State *L) {
- lua_Debug ar;
- if (lua_getstack(L, 1, &ar) == 0 ||
- lua_getinfo(L, "f", &ar) == 0 || /* get calling function */
- lua_iscfunction(L, -1))
- luaL_error(L, LUA_QL("module") " not called from a Lua function");
- lua_pushvalue(L, -2);
- lua_setfenv(L, -2);
- lua_pop(L, 1);
-}
-
-
-static void dooptions (lua_State *L, int n) {
- int i;
- for (i = 2; i <= n; i++) {
- lua_pushvalue(L, i); /* get option (a function) */
- lua_pushvalue(L, -2); /* module */
- lua_call(L, 1, 0);
- }
-}
-
-
-static void modinit (lua_State *L, const char *modname) {
- const char *dot;
- lua_pushvalue(L, -1);
- lua_setfield(L, -2, "_M"); /* module._M = module */
- lua_pushstring(L, modname);
- lua_setfield(L, -2, "_NAME");
- dot = strrchr(modname, '.'); /* look for last dot in module name */
- if (dot == NULL) dot = modname;
- else dot++;
- /* set _PACKAGE as package name (full module name minus last part) */
- lua_pushlstring(L, modname, dot - modname);
- lua_setfield(L, -2, "_PACKAGE");
-}
-
-
-static int ll_module (lua_State *L) {
- const char *modname = luaL_checkstring(L, 1);
- int loaded = lua_gettop(L) + 1; /* index of _LOADED table */
- lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
- lua_getfield(L, loaded, modname); /* get _LOADED[modname] */
- if (!lua_istable(L, -1)) { /* not found? */
- lua_pop(L, 1); /* remove previous result */
- /* try global variable (and create one if it does not exist) */
- if (luaL_findtable(L, LUA_GLOBALSINDEX, modname, 1) != NULL)
- return luaL_error(L, "name conflict for module " LUA_QS, modname);
- lua_pushvalue(L, -1);
- lua_setfield(L, loaded, modname); /* _LOADED[modname] = new table */
- }
- /* check whether table already has a _NAME field */
- lua_getfield(L, -1, "_NAME");
- if (!lua_isnil(L, -1)) /* is table an initialized module? */
- lua_pop(L, 1);
- else { /* no; initialize it */
- lua_pop(L, 1);
- modinit(L, modname);
- }
- lua_pushvalue(L, -1);
- setfenv(L);
- dooptions(L, loaded - 1);
- return 0;
-}
-
-
-static int ll_seeall (lua_State *L) {
- luaL_checktype(L, 1, LUA_TTABLE);
- if (!lua_getmetatable(L, 1)) {
- lua_createtable(L, 0, 1); /* create new metatable */
- lua_pushvalue(L, -1);
- lua_setmetatable(L, 1);
- }
- lua_pushvalue(L, LUA_GLOBALSINDEX);
- lua_setfield(L, -2, "__index"); /* mt.__index = _G */
- return 0;
-}
-
-
-/* }====================================================== */
-
-
-
-/* auxiliary mark (for internal use) */
-#define AUXMARK "\1"
-
-static void setpath (lua_State *L, const char *fieldname, const char *envname,
- const char *def) {
- const char *path = getenv(envname);
- if (path == NULL) /* no environment variable? */
- lua_pushstring(L, def); /* use default */
- else {
- /* replace ";;" by ";AUXMARK;" and then AUXMARK by default path */
- path = luaL_gsub(L, path, LUA_PATHSEP LUA_PATHSEP,
- LUA_PATHSEP AUXMARK LUA_PATHSEP);
- luaL_gsub(L, path, AUXMARK, def);
- lua_remove(L, -2);
- }
- setprogdir(L);
- lua_setfield(L, -2, fieldname);
-}
-
-
-static const luaL_Reg pk_funcs[] = {
- {"loadlib", ll_loadlib},
- {"seeall", ll_seeall},
- {NULL, NULL}
-};
-
-
-static const luaL_Reg ll_funcs[] = {
- {"module", ll_module},
- {"require", ll_require},
- {NULL, NULL}
-};
-
-
-static const lua_CFunction loaders[] =
- {loader_preload, loader_Lua, loader_C, loader_Croot, NULL};
-
-
-LUALIB_API int luaopen_package (lua_State *L) {
- int i;
- /* create new type _LOADLIB */
- luaL_newmetatable(L, "_LOADLIB");
- lua_pushcfunction(L, gctm);
- lua_setfield(L, -2, "__gc");
- /* create `package' table */
- luaL_register(L, LUA_LOADLIBNAME, pk_funcs);
-#if defined(LUA_COMPAT_LOADLIB)
- lua_getfield(L, -1, "loadlib");
- lua_setfield(L, LUA_GLOBALSINDEX, "loadlib");
-#endif
- lua_pushvalue(L, -1);
- lua_replace(L, LUA_ENVIRONINDEX);
- /* create `loaders' table */
- lua_createtable(L, 0, sizeof(loaders)/sizeof(loaders[0]) - 1);
- /* fill it with pre-defined loaders */
- for (i=0; loaders[i] != NULL; i++) {
- lua_pushcfunction(L, loaders[i]);
- lua_rawseti(L, -2, i+1);
- }
- lua_setfield(L, -2, "loaders"); /* put it in field `loaders' */
- setpath(L, "path", LUA_PATH, LUA_PATH_DEFAULT); /* set field `path' */
- setpath(L, "cpath", LUA_CPATH, LUA_CPATH_DEFAULT); /* set field `cpath' */
- /* store config information */
- lua_pushliteral(L, LUA_DIRSEP "\n" LUA_PATHSEP "\n" LUA_PATH_MARK "\n"
- LUA_EXECDIR "\n" LUA_IGMARK);
- lua_setfield(L, -2, "config");
- /* set field `loaded' */
- luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 2);
- lua_setfield(L, -2, "loaded");
- /* set field `preload' */
- lua_newtable(L);
- lua_setfield(L, -2, "preload");
- lua_pushvalue(L, LUA_GLOBALSINDEX);
- luaL_register(L, NULL, ll_funcs); /* open lib into global table */
- lua_pop(L, 1);
- return 1; /* return 'package' table */
-}
-
diff --git a/crawl-ref/source/util/lua/src/lobject.c b/crawl-ref/source/util/lua/src/lobject.c
deleted file mode 100644
index 4ff50732a4..0000000000
--- a/crawl-ref/source/util/lua/src/lobject.c
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
-** $Id: lobject.c,v 2.22.1.1 2007/12/27 13:02:25 roberto Exp $
-** Some generic functions over Lua objects
-** See Copyright Notice in lua.h
-*/
-
-#include <ctype.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#define lobject_c
-#define LUA_CORE
-
-#include "lua.h"
-
-#include "ldo.h"
-#include "lmem.h"
-#include "lobject.h"
-#include "lstate.h"
-#include "lstring.h"
-#include "lvm.h"
-
-
-
-const TValue luaO_nilobject_ = {{NULL}, LUA_TNIL};
-
-
-/*
-** converts an integer to a "floating point byte", represented as
-** (eeeeexxx), where the real value is (1xxx) * 2^(eeeee - 1) if
-** eeeee != 0 and (xxx) otherwise.
-*/
-int luaO_int2fb (unsigned int x) {
- int e = 0; /* expoent */
- while (x >= 16) {
- x = (x+1) >> 1;
- e++;
- }
- if (x < 8) return x;
- else return ((e+1) << 3) | (cast_int(x) - 8);
-}
-
-
-/* converts back */
-int luaO_fb2int (int x) {
- int e = (x >> 3) & 31;
- if (e == 0) return x;
- else return ((x & 7)+8) << (e - 1);
-}
-
-
-int luaO_log2 (unsigned int x) {
- static const lu_byte log_2[256] = {
- 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
- 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
- 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
- 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
- 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
- 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
- 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
- 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8
- };
- int l = -1;
- while (x >= 256) { l += 8; x >>= 8; }
- return l + log_2[x];
-
-}
-
-
-int luaO_rawequalObj (const TValue *t1, const TValue *t2) {
- if (ttype(t1) != ttype(t2)) return 0;
- else switch (ttype(t1)) {
- case LUA_TNIL:
- return 1;
- case LUA_TNUMBER:
- return luai_numeq(nvalue(t1), nvalue(t2));
- case LUA_TBOOLEAN:
- return bvalue(t1) == bvalue(t2); /* boolean true must be 1 !! */
- case LUA_TLIGHTUSERDATA:
- return pvalue(t1) == pvalue(t2);
- default:
- lua_assert(iscollectable(t1));
- return gcvalue(t1) == gcvalue(t2);
- }
-}
-
-
-int luaO_str2d (const char *s, lua_Number *result) {
- char *endptr;
- *result = lua_str2number(s, &endptr);
- if (endptr == s) return 0; /* conversion failed */
- if (*endptr == 'x' || *endptr == 'X') /* maybe an hexadecimal constant? */
- *result = cast_num(strtoul(s, &endptr, 16));
- if (*endptr == '\0') return 1; /* most common case */
- while (isspace(cast(unsigned char, *endptr))) endptr++;
- if (*endptr != '\0') return 0; /* invalid trailing characters? */
- return 1;
-}
-
-
-
-static void pushstr (lua_State *L, const char *str) {
- setsvalue2s(L, L->top, luaS_new(L, str));
- incr_top(L);
-}
-
-
-/* this function handles only `%d', `%c', %f, %p, and `%s' formats */
-const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {
- int n = 1;
- pushstr(L, "");
- for (;;) {
- const char *e = strchr(fmt, '%');
- if (e == NULL) break;
- setsvalue2s(L, L->top, luaS_newlstr(L, fmt, e-fmt));
- incr_top(L);
- switch (*(e+1)) {
- case 's': {
- const char *s = va_arg(argp, char *);
- if (s == NULL) s = "(null)";
- pushstr(L, s);
- break;
- }
- case 'c': {
- char buff[2];
- buff[0] = cast(char, va_arg(argp, int));
- buff[1] = '\0';
- pushstr(L, buff);
- break;
- }
- case 'd': {
- setnvalue(L->top, cast_num(va_arg(argp, int)));
- incr_top(L);
- break;
- }
- case 'f': {
- setnvalue(L->top, cast_num(va_arg(argp, l_uacNumber)));
- incr_top(L);
- break;
- }
- case 'p': {
- char buff[4*sizeof(void *) + 8]; /* should be enough space for a `%p' */
- sprintf(buff, "%p", va_arg(argp, void *));
- pushstr(L, buff);
- break;
- }
- case '%': {
- pushstr(L, "%");
- break;
- }
- default: {
- char buff[3];
- buff[0] = '%';
- buff[1] = *(e+1);
- buff[2] = '\0';
- pushstr(L, buff);
- break;
- }
- }
- n += 2;
- fmt = e+2;
- }
- pushstr(L, fmt);
- luaV_concat(L, n+1, cast_int(L->top - L->base) - 1);
- L->top -= n;
- return svalue(L->top - 1);
-}
-
-
-const char *luaO_pushfstring (lua_State *L, const char *fmt, ...) {
- const char *msg;
- va_list argp;
- va_start(argp, fmt);
- msg = luaO_pushvfstring(L, fmt, argp);
- va_end(argp);
- return msg;
-}
-
-
-void luaO_chunkid (char *out, const char *source, size_t bufflen) {
- if (*source == '=') {
- strncpy(out, source+1, bufflen); /* remove first char */
- out[bufflen-1] = '\0'; /* ensures null termination */
- }
- else { /* out = "source", or "...source" */
- if (*source == '@') {
- size_t l;
- source++; /* skip the `@' */
- bufflen -= sizeof(" '...' ");
- l = strlen(source);
- strcpy(out, "");
- if (l > bufflen) {
- source += (l-bufflen); /* get last part of file name */
- strcat(out, "...");
- }
- strcat(out, source);
- }
- else { /* out = [string "string"] */
- size_t len = strcspn(source, "\n\r"); /* stop at first newline */
- bufflen -= sizeof(" [string \"...\"] ");
- if (len > bufflen) len = bufflen;
- strcpy(out, "[string \"");
- if (source[len] != '\0') { /* must truncate? */
- strncat(out, source, len);
- strcat(out, "...");
- }
- else
- strcat(out, source);
- strcat(out, "\"]");
- }
- }
-}
diff --git a/crawl-ref/source/util/lua/src/lobject.h b/crawl-ref/source/util/lua/src/lobject.h
deleted file mode 100644
index f1e447ef3b..0000000000
--- a/crawl-ref/source/util/lua/src/lobject.h
+++ /dev/null
@@ -1,381 +0,0 @@
-/*
-** $Id: lobject.h,v 2.20.1.2 2008/08/06 13:29:48 roberto Exp $
-** Type definitions for Lua objects
-** See Copyright Notice in lua.h
-*/
-
-
-#ifndef lobject_h
-#define lobject_h
-
-
-#include <stdarg.h>
-
-
-#include "llimits.h"
-#include "lua.h"
-
-
-/* tags for values visible from Lua */
-#define LAST_TAG LUA_TTHREAD
-
-#define NUM_TAGS (LAST_TAG+1)
-
-
-/*
-** Extra tags for non-values
-*/
-#define LUA_TPROTO (LAST_TAG+1)
-#define LUA_TUPVAL (LAST_TAG+2)
-#define LUA_TDEADKEY (LAST_TAG+3)
-
-
-/*
-** Union of all collectable objects
-*/
-typedef union GCObject GCObject;
-
-
-/*
-** Common Header for all collectable objects (in macro form, to be
-** included in other objects)
-*/
-#define CommonHeader GCObject *next; lu_byte tt; lu_byte marked
-
-
-/*
-** Common header in struct form
-*/
-typedef struct GCheader {
- CommonHeader;
-} GCheader;
-
-
-
-
-/*
-** Union of all Lua values
-*/
-typedef union {
- GCObject *gc;
- void *p;
- lua_Number n;
- int b;
-} Value;
-
-
-/*
-** Tagged Values
-*/
-
-#define TValuefields Value value; int tt
-
-typedef struct lua_TValue {
- TValuefields;
-} TValue;
-
-
-/* Macros to test type */
-#define ttisnil(o) (ttype(o) == LUA_TNIL)
-#define ttisnumber(o) (ttype(o) == LUA_TNUMBER)
-#define ttisstring(o) (ttype(o) == LUA_TSTRING)
-#define ttistable(o) (ttype(o) == LUA_TTABLE)
-#define ttisfunction(o) (ttype(o) == LUA_TFUNCTION)
-#define ttisboolean(o) (ttype(o) == LUA_TBOOLEAN)
-#define ttisuserdata(o) (ttype(o) == LUA_TUSERDATA)
-#define ttisthread(o) (ttype(o) == LUA_TTHREAD)
-#define ttislightuserdata(o) (ttype(o) == LUA_TLIGHTUSERDATA)
-
-/* Macros to access values */
-#define ttype(o) ((o)->tt)
-#define gcvalue(o) check_exp(iscollectable(o), (o)->value.gc)
-#define pvalue(o) check_exp(ttislightuserdata(o), (o)->value.p)
-#define nvalue(o) check_exp(ttisnumber(o), (o)->value.n)
-#define rawtsvalue(o) check_exp(ttisstring(o), &(o)->value.gc->ts)
-#define tsvalue(o) (&rawtsvalue(o)->tsv)
-#define rawuvalue(o) check_exp(ttisuserdata(o), &(o)->value.gc->u)
-#define uvalue(o) (&rawuvalue(o)->uv)
-#define clvalue(o) check_exp(ttisfunction(o), &(o)->value.gc->cl)
-#define hvalue(o) check_exp(ttistable(o), &(o)->value.gc->h)
-#define bvalue(o) check_exp(ttisboolean(o), (o)->value.b)
-#define thvalue(o) check_exp(ttisthread(o), &(o)->value.gc->th)
-
-#define l_isfalse(o) (ttisnil(o) || (ttisboolean(o) && bvalue(o) == 0))
-
-/*
-** for internal debug only
-*/
-#define checkconsistency(obj) \
- lua_assert(!iscollectable(obj) || (ttype(obj) == (obj)->value.gc->gch.tt))
-
-#define checkliveness(g,obj) \
- lua_assert(!iscollectable(obj) || \
- ((ttype(obj) == (obj)->value.gc->gch.tt) && !isdead(g, (obj)->value.gc)))
-
-
-/* Macros to set values */
-#define setnilvalue(obj) ((obj)->tt=LUA_TNIL)
-
-#define setnvalue(obj,x) \
- { TValue *i_o=(obj); i_o->value.n=(x); i_o->tt=LUA_TNUMBER; }
-
-#define setpvalue(obj,x) \
- { TValue *i_o=(obj); i_o->value.p=(x); i_o->tt=LUA_TLIGHTUSERDATA; }
-
-#define setbvalue(obj,x) \
- { TValue *i_o=(obj); i_o->value.b=(x); i_o->tt=LUA_TBOOLEAN; }
-
-#define setsvalue(L,obj,x) \
- { TValue *i_o=(obj); \
- i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TSTRING; \
- checkliveness(G(L),i_o); }
-
-#define setuvalue(L,obj,x) \
- { TValue *i_o=(obj); \
- i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TUSERDATA; \
- checkliveness(G(L),i_o); }
-
-#define setthvalue(L,obj,x) \
- { TValue *i_o=(obj); \
- i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TTHREAD; \
- checkliveness(G(L),i_o); }
-
-#define setclvalue(L,obj,x) \
- { TValue *i_o=(obj); \
- i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TFUNCTION; \
- checkliveness(G(L),i_o); }
-
-#define sethvalue(L,obj,x) \
- { TValue *i_o=(obj); \
- i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TTABLE; \
- checkliveness(G(L),i_o); }
-
-#define setptvalue(L,obj,x) \
- { TValue *i_o=(obj); \
- i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TPROTO; \
- checkliveness(G(L),i_o); }
-
-
-
-
-#define setobj(L,obj1,obj2) \
- { const TValue *o2=(obj2); TValue *o1=(obj1); \
- o1->value = o2->value; o1->tt=o2->tt; \
- checkliveness(G(L),o1); }
-
-
-/*
-** different types of sets, according to destination
-*/
-
-/* from stack to (same) stack */
-#define setobjs2s setobj
-/* to stack (not from same stack) */
-#define setobj2s setobj
-#define setsvalue2s setsvalue
-#define sethvalue2s sethvalue
-#define setptvalue2s setptvalue
-/* from table to same table */
-#define setobjt2t setobj
-/* to table */
-#define setobj2t setobj
-/* to new object */
-#define setobj2n setobj
-#define setsvalue2n setsvalue
-
-#define setttype(obj, tt) (ttype(obj) = (tt))
-
-
-#define iscollectable(o) (ttype(o) >= LUA_TSTRING)
-
-
-
-typedef TValue *StkId; /* index to stack elements */
-
-
-/*
-** String headers for string table
-*/
-typedef union TString {
- L_Umaxalign dummy; /* ensures maximum alignment for strings */
- struct {
- CommonHeader;
- lu_byte reserved;
- unsigned int hash;
- size_t len;
- } tsv;
-} TString;
-
-
-#define getstr(ts) cast(const char *, (ts) + 1)
-#define svalue(o) getstr(rawtsvalue(o))
-
-
-
-typedef union Udata {
- L_Umaxalign dummy; /* ensures maximum alignment for `local' udata */
- struct {
- CommonHeader;
- struct Table *metatable;
- struct Table *env;
- size_t len;
- } uv;
-} Udata;
-
-
-
-
-/*
-** Function Prototypes
-*/
-typedef struct Proto {
- CommonHeader;
- TValue *k; /* constants used by the function */
- Instruction *code;
- struct Proto **p; /* functions defined inside the function */
- int *lineinfo; /* map from opcodes to source lines */
- struct LocVar *locvars; /* information about local variables */
- TString **upvalues; /* upvalue names */
- TString *source;
- int sizeupvalues;
- int sizek; /* size of `k' */
- int sizecode;
- int sizelineinfo;
- int sizep; /* size of `p' */
- int sizelocvars;
- int linedefined;
- int lastlinedefined;
- GCObject *gclist;
- lu_byte nups; /* number of upvalues */
- lu_byte numparams;
- lu_byte is_vararg;
- lu_byte maxstacksize;
-} Proto;
-
-
-/* masks for new-style vararg */
-#define VARARG_HASARG 1
-#define VARARG_ISVARARG 2
-#define VARARG_NEEDSARG 4
-
-
-typedef struct LocVar {
- TString *varname;
- int startpc; /* first point where variable is active */
- int endpc; /* first point where variable is dead */
-} LocVar;
-
-
-
-/*
-** Upvalues
-*/
-
-typedef struct UpVal {
- CommonHeader;
- TValue *v; /* points to stack or to its own value */
- union {
- TValue value; /* the value (when closed) */
- struct { /* double linked list (when open) */
- struct UpVal *prev;
- struct UpVal *next;
- } l;
- } u;
-} UpVal;
-
-
-/*
-** Closures
-*/
-
-#define ClosureHeader \
- CommonHeader; lu_byte isC; lu_byte nupvalues; GCObject *gclist; \
- struct Table *env
-
-typedef struct CClosure {
- ClosureHeader;
- lua_CFunction f;
- TValue upvalue[1];
-} CClosure;
-
-
-typedef struct LClosure {
- ClosureHeader;
- struct Proto *p;
- UpVal *upvals[1];
-} LClosure;
-
-
-typedef union Closure {
- CClosure c;
- LClosure l;
-} Closure;
-
-
-#define iscfunction(o) (ttype(o) == LUA_TFUNCTION && clvalue(o)->c.isC)
-#define isLfunction(o) (ttype(o) == LUA_TFUNCTION && !clvalue(o)->c.isC)
-
-
-/*
-** Tables
-*/
-
-typedef union TKey {
- struct {
- TValuefields;
- struct Node *next; /* for chaining */
- } nk;
- TValue tvk;
-} TKey;
-
-
-typedef struct Node {
- TValue i_val;
- TKey i_key;
-} Node;
-
-
-typedef struct Table {
- CommonHeader;
- lu_byte flags; /* 1<<p means tagmethod(p) is not present */
- lu_byte lsizenode; /* log2 of size of `node' array */
- struct Table *metatable;
- TValue *array; /* array part */
- Node *node;
- Node *lastfree; /* any free position is before this position */
- GCObject *gclist;
- int sizearray; /* size of `array' array */
-} Table;
-
-
-
-/*
-** `module' operation for hashing (size is always a power of 2)
-*/
-#define lmod(s,size) \
- (check_exp((size&(size-1))==0, (cast(int, (s) & ((size)-1)))))
-
-
-#define twoto(x) (1<<(x))
-#define sizenode(t) (twoto((t)->lsizenode))
-
-
-#define luaO_nilobject (&luaO_nilobject_)
-
-LUAI_DATA const TValue luaO_nilobject_;
-
-#define ceillog2(x) (luaO_log2((x)-1) + 1)
-
-LUAI_FUNC int luaO_log2 (unsigned int x);
-LUAI_FUNC int luaO_int2fb (unsigned int x);
-LUAI_FUNC int luaO_fb2int (int x);
-LUAI_FUNC int luaO_rawequalObj (const TValue *t1, const TValue *t2);
-LUAI_FUNC int luaO_str2d (const char *s, lua_Number *result);
-LUAI_FUNC const char *luaO_pushvfstring (lua_State *L, const char *fmt,
- va_list argp);
-LUAI_FUNC const char *luaO_pushfstring (lua_State *L, const char *fmt, ...);
-LUAI_FUNC void luaO_chunkid (char *out, const char *source, size_t len);
-
-
-#endif
-
diff --git a/crawl-ref/source/util/lua/src/lopcodes.c b/crawl-ref/source/util/lua/src/lopcodes.c
deleted file mode 100644
index 4cc745230b..0000000000
--- a/crawl-ref/source/util/lua/src/lopcodes.c
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
-** $Id: lopcodes.c,v 1.37.1.1 2007/12/27 13:02:25 roberto Exp $
-** See Copyright Notice in lua.h
-*/
-
-
-#define lopcodes_c
-#define LUA_CORE
-
-
-#include "lopcodes.h"
-
-
-/* ORDER OP */
-
-const char *const luaP_opnames[NUM_OPCODES+1] = {
- "MOVE",
- "LOADK",
- "LOADBOOL",
- "LOADNIL",
- "GETUPVAL",
- "GETGLOBAL",
- "GETTABLE",
- "SETGLOBAL",
- "SETUPVAL",
- "SETTABLE",
- "NEWTABLE",
- "SELF",
- "ADD",
- "SUB",
- "MUL",
- "DIV",
- "MOD",
- "POW",
- "UNM",
- "NOT",
- "LEN",
- "CONCAT",
- "JMP",
- "EQ",
- "LT",
- "LE",
- "TEST",
- "TESTSET",
- "CALL",
- "TAILCALL",
- "RETURN",
- "FORLOOP",
- "FORPREP",
- "TFORLOOP",
- "SETLIST",
- "CLOSE",
- "CLOSURE",
- "VARARG",
- NULL
-};
-
-
-#define opmode(t,a,b,c,m) (((t)<<7) | ((a)<<6) | ((b)<<4) | ((c)<<2) | (m))
-
-const lu_byte luaP_opmodes[NUM_OPCODES] = {
-/* T A B C mode opcode */
- opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_MOVE */
- ,opmode(0, 1, OpArgK, OpArgN, iABx) /* OP_LOADK */
- ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_LOADBOOL */
- ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LOADNIL */
- ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_GETUPVAL */
- ,opmode(0, 1, OpArgK, OpArgN, iABx) /* OP_GETGLOBAL */
- ,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_GETTABLE */
- ,opmode(0, 0, OpArgK, OpArgN, iABx) /* OP_SETGLOBAL */
- ,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_SETUPVAL */
- ,opmode(0, 0, OpArgK, OpArgK, iABC) /* OP_SETTABLE */
- ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_NEWTABLE */
- ,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_SELF */
- ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_ADD */
- ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_SUB */
- ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MUL */
- ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_DIV */
- ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MOD */
- ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_POW */
- ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_UNM */
- ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_NOT */
- ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LEN */
- ,opmode(0, 1, OpArgR, OpArgR, iABC) /* OP_CONCAT */
- ,opmode(0, 0, OpArgR, OpArgN, iAsBx) /* OP_JMP */
- ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_EQ */
- ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LT */
- ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LE */
- ,opmode(1, 1, OpArgR, OpArgU, iABC) /* OP_TEST */
- ,opmode(1, 1, OpArgR, OpArgU, iABC) /* OP_TESTSET */
- ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_CALL */
- ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_TAILCALL */
- ,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_RETURN */
- ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORLOOP */
- ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORPREP */
- ,opmode(1, 0, OpArgN, OpArgU, iABC) /* OP_TFORLOOP */
- ,opmode(0, 0, OpArgU, OpArgU, iABC) /* OP_SETLIST */
- ,opmode(0, 0, OpArgN, OpArgN, iABC) /* OP_CLOSE */
- ,opmode(0, 1, OpArgU, OpArgN, iABx) /* OP_CLOSURE */
- ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_VARARG */
-};
-
diff --git a/crawl-ref/source/util/lua/src/lopcodes.h b/crawl-ref/source/util/lua/src/lopcodes.h
deleted file mode 100644
index 41224d6ee1..0000000000
--- a/crawl-ref/source/util/lua/src/lopcodes.h
+++ /dev/null
@@ -1,268 +0,0 @@
-/*
-** $Id: lopcodes.h,v 1.125.1.1 2007/12/27 13:02:25 roberto Exp $
-** Opcodes for Lua virtual machine
-** See Copyright Notice in lua.h
-*/
-
-#ifndef lopcodes_h
-#define lopcodes_h
-
-#include "llimits.h"
-
-
-/*===========================================================================
- We assume that instructions are unsigned numbers.
- All instructions have an opcode in the first 6 bits.
- Instructions can have the following fields:
- `A' : 8 bits
- `B' : 9 bits
- `C' : 9 bits
- `Bx' : 18 bits (`B' and `C' together)
- `sBx' : signed Bx
-
- A signed argument is represented in excess K; that is, the number
- value is the unsigned value minus K. K is exactly the maximum value
- for that argument (so that -max is represented by 0, and +max is
- represented by 2*max), which is half the maximum for the corresponding
- unsigned argument.
-===========================================================================*/
-
-
-enum OpMode {iABC, iABx, iAsBx}; /* basic instruction format */
-
-
-/*
-** size and position of opcode arguments.
-*/
-#define SIZE_C 9
-#define SIZE_B 9
-#define SIZE_Bx (SIZE_C + SIZE_B)
-#define SIZE_A 8
-
-#define SIZE_OP 6
-
-#define POS_OP 0
-#define POS_A (POS_OP + SIZE_OP)
-#define POS_C (POS_A + SIZE_A)
-#define POS_B (POS_C + SIZE_C)
-#define POS_Bx POS_C
-
-
-/*
-** limits for opcode arguments.
-** we use (signed) int to manipulate most arguments,
-** so they must fit in LUAI_BITSINT-1 bits (-1 for sign)
-*/
-#if SIZE_Bx < LUAI_BITSINT-1
-#define MAXARG_Bx ((1<<SIZE_Bx)-1)
-#define MAXARG_sBx (MAXARG_Bx>>1) /* `sBx' is signed */
-#else
-#define MAXARG_Bx MAX_INT
-#define MAXARG_sBx MAX_INT
-#endif
-
-
-#define MAXARG_A ((1<<SIZE_A)-1)
-#define MAXARG_B ((1<<SIZE_B)-1)
-#define MAXARG_C ((1<<SIZE_C)-1)
-
-
-/* creates a mask with `n' 1 bits at position `p' */
-#define MASK1(n,p) ((~((~(Instruction)0)<<n))<<p)
-
-/* creates a mask with `n' 0 bits at position `p' */
-#define MASK0(n,p) (~MASK1(n,p))
-
-/*
-** the following macros help to manipulate instructions
-*/
-
-#define GET_OPCODE(i) (cast(OpCode, ((i)>>POS_OP) & MASK1(SIZE_OP,0)))
-#define SET_OPCODE(i,o) ((i) = (((i)&MASK0(SIZE_OP,POS_OP)) | \
- ((cast(Instruction, o)<<POS_OP)&MASK1(SIZE_OP,POS_OP))))
-
-#define GETARG_A(i) (cast(int, ((i)>>POS_A) & MASK1(SIZE_A,0)))
-#define SETARG_A(i,u) ((i) = (((i)&MASK0(SIZE_A,POS_A)) | \
- ((cast(Instruction, u)<<POS_A)&MASK1(SIZE_A,POS_A))))
-
-#define GETARG_B(i) (cast(int, ((i)>>POS_B) & MASK1(SIZE_B,0)))
-#define SETARG_B(i,b) ((i) = (((i)&MASK0(SIZE_B,POS_B)) | \
- ((cast(Instruction, b)<<POS_B)&MASK1(SIZE_B,POS_B))))
-
-#define GETARG_C(i) (cast(int, ((i)>>POS_C) & MASK1(SIZE_C,0)))
-#define SETARG_C(i,b) ((i) = (((i)&MASK0(SIZE_C,POS_C)) | \
- ((cast(Instruction, b)<<POS_C)&MASK1(SIZE_C,POS_C))))
-
-#define GETARG_Bx(i) (cast(int, ((i)>>POS_Bx) & MASK1(SIZE_Bx,0)))
-#define SETARG_Bx(i,b) ((i) = (((i)&MASK0(SIZE_Bx,POS_Bx)) | \
- ((cast(Instruction, b)<<POS_Bx)&MASK1(SIZE_Bx,POS_Bx))))
-
-#define GETARG_sBx(i) (GETARG_Bx(i)-MAXARG_sBx)
-#define SETARG_sBx(i,b) SETARG_Bx((i),cast(unsigned int, (b)+MAXARG_sBx))
-
-
-#define CREATE_ABC(o,a,b,c) ((cast(Instruction, o)<<POS_OP) \
- | (cast(Instruction, a)<<POS_A) \
- | (cast(Instruction, b)<<POS_B) \
- | (cast(Instruction, c)<<POS_C))
-
-#define CREATE_ABx(o,a,bc) ((cast(Instruction, o)<<POS_OP) \
- | (cast(Instruction, a)<<POS_A) \
- | (cast(Instruction, bc)<<POS_Bx))
-
-
-/*
-** Macros to operate RK indices
-*/
-
-/* this bit 1 means constant (0 means register) */
-#define BITRK (1 << (SIZE_B - 1))
-
-/* test whether value is a constant */
-#define ISK(x) ((x) & BITRK)
-
-/* gets the index of the constant */
-#define INDEXK(r) ((int)(r) & ~BITRK)
-
-#define MAXINDEXRK (BITRK - 1)
-
-/* code a constant index as a RK value */
-#define RKASK(x) ((x) | BITRK)
-
-
-/*
-** invalid register that fits in 8 bits
-*/
-#define NO_REG MAXARG_A
-
-
-/*
-** R(x) - register
-** Kst(x) - constant (in constant table)
-** RK(x) == if ISK(x) then Kst(INDEXK(x)) else R(x)
-*/
-
-
-/*
-** grep "ORDER OP" if you change these enums
-*/
-
-typedef enum {
-/*----------------------------------------------------------------------
-name args description
-------------------------------------------------------------------------*/
-OP_MOVE,/* A B R(A) := R(B) */
-OP_LOADK,/* A Bx R(A) := Kst(Bx) */
-OP_LOADBOOL,/* A B C R(A) := (Bool)B; if (C) pc++ */
-OP_LOADNIL,/* A B R(A) := ... := R(B) := nil */
-OP_GETUPVAL,/* A B R(A) := UpValue[B] */
-
-OP_GETGLOBAL,/* A Bx R(A) := Gbl[Kst(Bx)] */
-OP_GETTABLE,/* A B C R(A) := R(B)[RK(C)] */
-
-OP_SETGLOBAL,/* A Bx Gbl[Kst(Bx)] := R(A) */
-OP_SETUPVAL,/* A B UpValue[B] := R(A) */
-OP_SETTABLE,/* A B C R(A)[RK(B)] := RK(C) */
-
-OP_NEWTABLE,/* A B C R(A) := {} (size = B,C) */
-
-OP_SELF,/* A B C R(A+1) := R(B); R(A) := R(B)[RK(C)] */
-
-OP_ADD,/* A B C R(A) := RK(B) + RK(C) */
-OP_SUB,/* A B C R(A) := RK(B) - RK(C) */
-OP_MUL,/* A B C R(A) := RK(B) * RK(C) */
-OP_DIV,/* A B C R(A) := RK(B) / RK(C) */
-OP_MOD,/* A B C R(A) := RK(B) % RK(C) */
-OP_POW,/* A B C R(A) := RK(B) ^ RK(C) */
-OP_UNM,/* A B R(A) := -R(B) */
-OP_NOT,/* A B R(A) := not R(B) */
-OP_LEN,/* A B R(A) := length of R(B) */
-
-OP_CONCAT,/* A B C R(A) := R(B).. ... ..R(C) */
-
-OP_JMP,/* sBx pc+=sBx */
-
-OP_EQ,/* A B C if ((RK(B) == RK(C)) ~= A) then pc++ */
-OP_LT,/* A B C if ((RK(B) < RK(C)) ~= A) then pc++ */
-OP_LE,/* A B C if ((RK(B) <= RK(C)) ~= A) then pc++ */
-
-OP_TEST,/* A C if not (R(A) <=> C) then pc++ */
-OP_TESTSET,/* A B C if (R(B) <=> C) then R(A) := R(B) else pc++ */
-
-OP_CALL,/* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */
-OP_TAILCALL,/* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */
-OP_RETURN,/* A B return R(A), ... ,R(A+B-2) (see note) */
-
-OP_FORLOOP,/* A sBx R(A)+=R(A+2);
- if R(A) <?= R(A+1) then { pc+=sBx; R(A+3)=R(A) }*/
-OP_FORPREP,/* A sBx R(A)-=R(A+2); pc+=sBx */
-
-OP_TFORLOOP,/* A C R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2));
- if R(A+3) ~= nil then R(A+2)=R(A+3) else pc++ */
-OP_SETLIST,/* A B C R(A)[(C-1)*FPF+i] := R(A+i), 1 <= i <= B */
-
-OP_CLOSE,/* A close all variables in the stack up to (>=) R(A)*/
-OP_CLOSURE,/* A Bx R(A) := closure(KPROTO[Bx], R(A), ... ,R(A+n)) */
-
-OP_VARARG/* A B R(A), R(A+1), ..., R(A+B-1) = vararg */
-} OpCode;
-
-
-#define NUM_OPCODES (cast(int, OP_VARARG) + 1)
-
-
-
-/*===========================================================================
- Notes:
- (*) In OP_CALL, if (B == 0) then B = top. C is the number of returns - 1,
- and can be 0: OP_CALL then sets `top' to last_result+1, so
- next open instruction (OP_CALL, OP_RETURN, OP_SETLIST) may use `top'.
-
- (*) In OP_VARARG, if (B == 0) then use actual number of varargs and
- set top (like in OP_CALL with C == 0).
-
- (*) In OP_RETURN, if (B == 0) then return up to `top'
-
- (*) In OP_SETLIST, if (B == 0) then B = `top';
- if (C == 0) then next `instruction' is real C
-
- (*) For comparisons, A specifies what condition the test should accept
- (true or false).
-
- (*) All `skips' (pc++) assume that next instruction is a jump
-===========================================================================*/
-
-
-/*
-** masks for instruction properties. The format is:
-** bits 0-1: op mode
-** bits 2-3: C arg mode
-** bits 4-5: B arg mode
-** bit 6: instruction set register A
-** bit 7: operator is a test
-*/
-
-enum OpArgMask {
- OpArgN, /* argument is not used */
- OpArgU, /* argument is used */
- OpArgR, /* argument is a register or a jump offset */
- OpArgK /* argument is a constant or register/constant */
-};
-
-LUAI_DATA const lu_byte luaP_opmodes[NUM_OPCODES];
-
-#define getOpMode(m) (cast(enum OpMode, luaP_opmodes[m] & 3))
-#define getBMode(m) (cast(enum OpArgMask, (luaP_opmodes[m] >> 4) & 3))
-#define getCMode(m) (cast(enum OpArgMask, (luaP_opmodes[m] >> 2) & 3))
-#define testAMode(m) (luaP_opmodes[m] & (1 << 6))
-#define testTMode(m) (luaP_opmodes[m] & (1 << 7))
-
-
-LUAI_DATA const char *const luaP_opnames[NUM_OPCODES+1]; /* opcode names */
-
-
-/* number of list items to accumulate before a SETLIST instruction */
-#define LFIELDS_PER_FLUSH 50
-
-
-#endif
diff --git a/crawl-ref/source/util/lua/src/loslib.c b/crawl-ref/source/util/lua/src/loslib.c
deleted file mode 100644
index da06a572ac..0000000000
--- a/crawl-ref/source/util/lua/src/loslib.c
+++ /dev/null
@@ -1,243 +0,0 @@
-/*
-** $Id: loslib.c,v 1.19.1.3 2008/01/18 16:38:18 roberto Exp $
-** Standard Operating System library
-** See Copyright Notice in lua.h
-*/
-
-
-#include <errno.h>
-#include <locale.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-
-#define loslib_c
-#define LUA_LIB
-
-#include "lua.h"
-
-#include "lauxlib.h"
-#include "lualib.h"
-
-
-static int os_pushresult (lua_State *L, int i, const char *filename) {
- int en = errno; /* calls to Lua API may change this value */
- if (i) {
- lua_pushboolean(L, 1);
- return 1;
- }
- else {
- lua_pushnil(L);
- lua_pushfstring(L, "%s: %s", filename, strerror(en));
- lua_pushinteger(L, en);
- return 3;
- }
-}
-
-
-static int os_execute (lua_State *L) {
- lua_pushinteger(L, system(luaL_optstring(L, 1, NULL)));
- return 1;
-}
-
-
-static int os_remove (lua_State *L) {
- const char *filename = luaL_checkstring(L, 1);
- return os_pushresult(L, remove(filename) == 0, filename);
-}
-
-
-static int os_rename (lua_State *L) {
- const char *fromname = luaL_checkstring(L, 1);
- const char *toname = luaL_checkstring(L, 2);
- return os_pushresult(L, rename(fromname, toname) == 0, fromname);
-}
-
-
-static int os_tmpname (lua_State *L) {
- char buff[LUA_TMPNAMBUFSIZE];
- int err;
- lua_tmpnam(buff, err);
- if (err)
- return luaL_error(L, "unable to generate a unique filename");
- lua_pushstring(L, buff);
- return 1;
-}
-
-
-static int os_getenv (lua_State *L) {
- lua_pushstring(L, getenv(luaL_checkstring(L, 1))); /* if NULL push nil */
- return 1;
-}
-
-
-static int os_clock (lua_State *L) {
- lua_pushnumber(L, ((lua_Number)clock())/(lua_Number)CLOCKS_PER_SEC);
- return 1;
-}
-
-
-/*
-** {======================================================
-** Time/Date operations
-** { year=%Y, month=%m, day=%d, hour=%H, min=%M, sec=%S,
-** wday=%w+1, yday=%j, isdst=? }
-** =======================================================
-*/
-
-static void setfield (lua_State *L, const char *key, int value) {
- lua_pushinteger(L, value);
- lua_setfield(L, -2, key);
-}
-
-static void setboolfield (lua_State *L, const char *key, int value) {
- if (value < 0) /* undefined? */
- return; /* does not set field */
- lua_pushboolean(L, value);
- lua_setfield(L, -2, key);
-}
-
-static int getboolfield (lua_State *L, const char *key) {
- int res;
- lua_getfield(L, -1, key);
- res = lua_isnil(L, -1) ? -1 : lua_toboolean(L, -1);
- lua_pop(L, 1);
- return res;
-}
-
-
-static int getfield (lua_State *L, const char *key, int d) {
- int res;
- lua_getfield(L, -1, key);
- if (lua_isnumber(L, -1))
- res = (int)lua_tointeger(L, -1);
- else {
- if (d < 0)
- return luaL_error(L, "field " LUA_QS " missing in date table", key);
- res = d;
- }
- lua_pop(L, 1);
- return res;
-}
-
-
-static int os_date (lua_State *L) {
- const char *s = luaL_optstring(L, 1, "%c");
- time_t t = luaL_opt(L, (time_t)luaL_checknumber, 2, time(NULL));
- struct tm *stm;
- if (*s == '!') { /* UTC? */
- stm = gmtime(&t);
- s++; /* skip `!' */
- }
- else
- stm = localtime(&t);
- if (stm == NULL) /* invalid date? */
- lua_pushnil(L);
- else if (strcmp(s, "*t") == 0) {
- lua_createtable(L, 0, 9); /* 9 = number of fields */
- setfield(L, "sec", stm->tm_sec);
- setfield(L, "min", stm->tm_min);
- setfield(L, "hour", stm->tm_hour);
- setfield(L, "day", stm->tm_mday);
- setfield(L, "month", stm->tm_mon+1);
- setfield(L, "year", stm->tm_year+1900);
- setfield(L, "wday", stm->tm_wday+1);
- setfield(L, "yday", stm->tm_yday+1);
- setboolfield(L, "isdst", stm->tm_isdst);
- }
- else {
- char cc[3];
- luaL_Buffer b;
- cc[0] = '%'; cc[2] = '\0';
- luaL_buffinit(L, &b);
- for (; *s; s++) {
- if (*s != '%' || *(s + 1) == '\0') /* no conversion specifier? */
- luaL_addchar(&b, *s);
- else {
- size_t reslen;
- char buff[200]; /* should be big enough for any conversion result */
- cc[1] = *(++s);
- reslen = strftime(buff, sizeof(buff), cc, stm);
- luaL_addlstring(&b, buff, reslen);
- }
- }
- luaL_pushresult(&b);
- }
- return 1;
-}
-
-
-static int os_time (lua_State *L) {
- time_t t;
- if (lua_isnoneornil(L, 1)) /* called without args? */
- t = time(NULL); /* get current time */
- else {
- struct tm ts;
- luaL_checktype(L, 1, LUA_TTABLE);
- lua_settop(L, 1); /* make sure table is at the top */
- ts.tm_sec = getfield(L, "sec", 0);
- ts.tm_min = getfield(L, "min", 0);
- ts.tm_hour = getfield(L, "hour", 12);
- ts.tm_mday = getfield(L, "day", -1);
- ts.tm_mon = getfield(L, "month", -1) - 1;
- ts.tm_year = getfield(L, "year", -1) - 1900;
- ts.tm_isdst = getboolfield(L, "isdst");
- t = mktime(&ts);
- }
- if (t == (time_t)(-1))
- lua_pushnil(L);
- else
- lua_pushnumber(L, (lua_Number)t);
- return 1;
-}
-
-
-static int os_difftime (lua_State *L) {
- lua_pushnumber(L, difftime((time_t)(luaL_checknumber(L, 1)),
- (time_t)(luaL_optnumber(L, 2, 0))));
- return 1;
-}
-
-/* }====================================================== */
-
-
-static int os_setlocale (lua_State *L) {
- static const int cat[] = {LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY,
- LC_NUMERIC, LC_TIME};
- static const char *const catnames[] = {"all", "collate", "ctype", "monetary",
- "numeric", "time", NULL};
- const char *l = luaL_optstring(L, 1, NULL);
- int op = luaL_checkoption(L, 2, "all", catnames);
- lua_pushstring(L, setlocale(cat[op], l));
- return 1;
-}
-
-
-static int os_exit (lua_State *L) {
- exit(luaL_optint(L, 1, EXIT_SUCCESS));
-}
-
-static const luaL_Reg syslib[] = {
- {"clock", os_clock},
- {"date", os_date},
- {"difftime", os_difftime},
- {"execute", os_execute},
- {"exit", os_exit},
- {"getenv", os_getenv},
- {"remove", os_remove},
- {"rename", os_rename},
- {"setlocale", os_setlocale},
- {"time", os_time},
- {"tmpname", os_tmpname},
- {NULL, NULL}
-};
-
-/* }====================================================== */
-
-
-
-LUALIB_API int luaopen_os (lua_State *L) {
- luaL_register(L, LUA_OSLIBNAME, syslib);
- return 1;
-}
-
diff --git a/crawl-ref/source/util/lua/src/lparser.c b/crawl-ref/source/util/lua/src/lparser.c
deleted file mode 100644
index 1e2a9a88b7..0000000000
--- a/crawl-ref/source/util/lua/src/lparser.c
+++ /dev/null
@@ -1,1339 +0,0 @@
-/*
-** $Id: lparser.c,v 2.42.1.3 2007/12/28 15:32:23 roberto Exp $
-** Lua Parser
-** See Copyright Notice in lua.h
-*/
-
-
-#include <string.h>
-
-#define lparser_c
-#define LUA_CORE
-
-#include "lua.h"
-
-#include "lcode.h"
-#include "ldebug.h"
-#include "ldo.h"
-#include "lfunc.h"
-#include "llex.h"
-#include "lmem.h"
-#include "lobject.h"
-#include "lopcodes.h"
-#include "lparser.h"
-#include "lstate.h"
-#include "lstring.h"
-#include "ltable.h"
-
-
-
-#define hasmultret(k) ((k) == VCALL || (k) == VVARARG)
-
-#define getlocvar(fs, i) ((fs)->f->locvars[(fs)->actvar[i]])
-
-#define luaY_checklimit(fs,v,l,m) if ((v)>(l)) errorlimit(fs,l,m)
-
-
-/*
-** nodes for block list (list of active blocks)
-*/
-typedef struct BlockCnt {
- struct BlockCnt *previous; /* chain */
- int breaklist; /* list of jumps out of this loop */
- lu_byte nactvar; /* # active locals outside the breakable structure */
- lu_byte upval; /* true if some variable in the block is an upvalue */
- lu_byte isbreakable; /* true if `block' is a loop */
-} BlockCnt;
-
-
-
-/*
-** prototypes for recursive non-terminal functions
-*/
-static void chunk (LexState *ls);
-static void expr (LexState *ls, expdesc *v);
-
-
-static void anchor_token (LexState *ls) {
- if (ls->t.token == TK_NAME || ls->t.token == TK_STRING) {
- TString *ts = ls->t.seminfo.ts;
- luaX_newstring(ls, getstr(ts), ts->tsv.len);
- }
-}
-
-
-static void error_expected (LexState *ls, int token) {
- luaX_syntaxerror(ls,
- luaO_pushfstring(ls->L, LUA_QS " expected", luaX_token2str(ls, token)));
-}
-
-
-static void errorlimit (FuncState *fs, int limit, const char *what) {
- const char *msg = (fs->f->linedefined == 0) ?
- luaO_pushfstring(fs->L, "main function has more than %d %s", limit, what) :
- luaO_pushfstring(fs->L, "function at line %d has more than %d %s",
- fs->f->linedefined, limit, what);
- luaX_lexerror(fs->ls, msg, 0);
-}
-
-
-static int testnext (LexState *ls, int c) {
- if (ls->t.token == c) {
- luaX_next(ls);
- return 1;
- }
- else return 0;
-}
-
-
-static void check (LexState *ls, int c) {
- if (ls->t.token != c)
- error_expected(ls, c);
-}
-
-static void checknext (LexState *ls, int c) {
- check(ls, c);
- luaX_next(ls);
-}
-
-
-#define check_condition(ls,c,msg) { if (!(c)) luaX_syntaxerror(ls, msg); }
-
-
-
-static void check_match (LexState *ls, int what, int who, int where) {
- if (!testnext(ls, what)) {
- if (where == ls->linenumber)
- error_expected(ls, what);
- else {
- luaX_syntaxerror(ls, luaO_pushfstring(ls->L,
- LUA_QS " expected (to close " LUA_QS " at line %d)",
- luaX_token2str(ls, what), luaX_token2str(ls, who), where));
- }
- }
-}
-
-
-static TString *str_checkname (LexState *ls) {
- TString *ts;
- check(ls, TK_NAME);
- ts = ls->t.seminfo.ts;
- luaX_next(ls);
- return ts;
-}
-
-
-static void init_exp (expdesc *e, expkind k, int i) {
- e->f = e->t = NO_JUMP;
- e->k = k;
- e->u.s.info = i;
-}
-
-
-static void codestring (LexState *ls, expdesc *e, TString *s) {
- init_exp(e, VK, luaK_stringK(ls->fs, s));
-}
-
-
-static void checkname(LexState *ls, expdesc *e) {
- codestring(ls, e, str_checkname(ls));
-}
-
-
-static int registerlocalvar (LexState *ls, TString *varname) {
- FuncState *fs = ls->fs;
- Proto *f = fs->f;
- int oldsize = f->sizelocvars;
- luaM_growvector(ls->L, f->locvars, fs->nlocvars, f->sizelocvars,
- LocVar, SHRT_MAX, "too many local variables");
- while (oldsize < f->sizelocvars) f->locvars[oldsize++].varname = NULL;
- f->locvars[fs->nlocvars].varname = varname;
- luaC_objbarrier(ls->L, f, varname);
- return fs->nlocvars++;
-}
-
-
-#define new_localvarliteral(ls,v,n) \
- new_localvar(ls, luaX_newstring(ls, "" v, (sizeof(v)/sizeof(char))-1), n)
-
-
-static void new_localvar (LexState *ls, TString *name, int n) {
- FuncState *fs = ls->fs;
- luaY_checklimit(fs, fs->nactvar+n+1, LUAI_MAXVARS, "local variables");
- fs->actvar[fs->nactvar+n] = cast(unsigned short, registerlocalvar(ls, name));
-}
-
-
-static void adjustlocalvars (LexState *ls, int nvars) {
- FuncState *fs = ls->fs;
- fs->nactvar = cast_byte(fs->nactvar + nvars);
- for (; nvars; nvars--) {
- getlocvar(fs, fs->nactvar - nvars).startpc = fs->pc;
- }
-}
-
-
-static void removevars (LexState *ls, int tolevel) {
- FuncState *fs = ls->fs;
- while (fs->nactvar > tolevel)
- getlocvar(fs, --fs->nactvar).endpc = fs->pc;
-}
-
-
-static int indexupvalue (FuncState *fs, TString *name, expdesc *v) {
- int i;
- Proto *f = fs->f;
- int oldsize = f->sizeupvalues;
- for (i=0; i<f->nups; i++) {
- if (fs->upvalues[i].k == v->k && fs->upvalues[i].info == v->u.s.info) {
- lua_assert(f->upvalues[i] == name);
- return i;
- }
- }
- /* new one */
- luaY_checklimit(fs, f->nups + 1, LUAI_MAXUPVALUES, "upvalues");
- luaM_growvector(fs->L, f->upvalues, f->nups, f->sizeupvalues,
- TString *, MAX_INT, "");
- while (oldsize < f->sizeupvalues) f->upvalues[oldsize++] = NULL;
- f->upvalues[f->nups] = name;
- luaC_objbarrier(fs->L, f, name);
- lua_assert(v->k == VLOCAL || v->k == VUPVAL);
- fs->upvalues[f->nups].k = cast_byte(v->k);
- fs->upvalues[f->nups].info = cast_byte(v->u.s.info);
- return f->nups++;
-}
-
-
-static int searchvar (FuncState *fs, TString *n) {
- int i;
- for (i=fs->nactvar-1; i >= 0; i--) {
- if (n == getlocvar(fs, i).varname)
- return i;
- }
- return -1; /* not found */
-}
-
-
-static void markupval (FuncState *fs, int level) {
- BlockCnt *bl = fs->bl;
- while (bl && bl->nactvar > level) bl = bl->previous;
- if (bl) bl->upval = 1;
-}
-
-
-static int singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) {
- if (fs == NULL) { /* no more levels? */
- init_exp(var, VGLOBAL, NO_REG); /* default is global variable */
- return VGLOBAL;
- }
- else {
- int v = searchvar(fs, n); /* look up at current level */
- if (v >= 0) {
- init_exp(var, VLOCAL, v);
- if (!base)
- markupval(fs, v); /* local will be used as an upval */
- return VLOCAL;
- }
- else { /* not found at current level; try upper one */
- if (singlevaraux(fs->prev, n, var, 0) == VGLOBAL)
- return VGLOBAL;
- var->u.s.info = indexupvalue(fs, n, var); /* else was LOCAL or UPVAL */
- var->k = VUPVAL; /* upvalue in this level */
- return VUPVAL;
- }
- }
-}
-
-
-static void singlevar (LexState *ls, expdesc *var) {
- TString *varname = str_checkname(ls);
- FuncState *fs = ls->fs;
- if (singlevaraux(fs, varname, var, 1) == VGLOBAL)
- var->u.s.info = luaK_stringK(fs, varname); /* info points to global name */
-}
-
-
-static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) {
- FuncState *fs = ls->fs;
- int extra = nvars - nexps;
- if (hasmultret(e->k)) {
- extra++; /* includes call itself */
- if (extra < 0) extra = 0;
- luaK_setreturns(fs, e, extra); /* last exp. provides the difference */
- if (extra > 1) luaK_reserveregs(fs, extra-1);
- }
- else {
- if (e->k != VVOID) luaK_exp2nextreg(fs, e); /* close last expression */
- if (extra > 0) {
- int reg = fs->freereg;
- luaK_reserveregs(fs, extra);
- luaK_nil(fs, reg, extra);
- }
- }
-}
-
-
-static void enterlevel (LexState *ls) {
- if (++ls->L->nCcalls > LUAI_MAXCCALLS)
- luaX_lexerror(ls, "chunk has too many syntax levels", 0);
-}
-
-
-#define leavelevel(ls) ((ls)->L->nCcalls--)
-
-
-static void enterblock (FuncState *fs, BlockCnt *bl, lu_byte isbreakable) {
- bl->breaklist = NO_JUMP;
- bl->isbreakable = isbreakable;
- bl->nactvar = fs->nactvar;
- bl->upval = 0;
- bl->previous = fs->bl;
- fs->bl = bl;
- lua_assert(fs->freereg == fs->nactvar);
-}
-
-
-static void leaveblock (FuncState *fs) {
- BlockCnt *bl = fs->bl;
- fs->bl = bl->previous;
- removevars(fs->ls, bl->nactvar);
- if (bl->upval)
- luaK_codeABC(fs, OP_CLOSE, bl->nactvar, 0, 0);
- /* a block either controls scope or breaks (never both) */
- lua_assert(!bl->isbreakable || !bl->upval);
- lua_assert(bl->nactvar == fs->nactvar);
- fs->freereg = fs->nactvar; /* free registers */
- luaK_patchtohere(fs, bl->breaklist);
-}
-
-
-static void pushclosure (LexState *ls, FuncState *func, expdesc *v) {
- FuncState *fs = ls->fs;
- Proto *f = fs->f;
- int oldsize = f->sizep;
- int i;
- luaM_growvector(ls->L, f->p, fs->np, f->sizep, Proto *,
- MAXARG_Bx, "constant table overflow");
- while (oldsize < f->sizep) f->p[oldsize++] = NULL;
- f->p[fs->np++] = func->f;
- luaC_objbarrier(ls->L, f, func->f);
- init_exp(v, VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np-1));
- for (i=0; i<func->f->nups; i++) {
- OpCode o = (func->upvalues[i].k == VLOCAL) ? OP_MOVE : OP_GETUPVAL;
- luaK_codeABC(fs, o, 0, func->upvalues[i].info, 0);
- }
-}
-
-
-static void open_func (LexState *ls, FuncState *fs) {
- lua_State *L = ls->L;
- Proto *f = luaF_newproto(L);
- fs->f = f;
- fs->prev = ls->fs; /* linked list of funcstates */
- fs->ls = ls;
- fs->L = L;
- ls->fs = fs;
- fs->pc = 0;
- fs->lasttarget = -1;
- fs->jpc = NO_JUMP;
- fs->freereg = 0;
- fs->nk = 0;
- fs->np = 0;
- fs->nlocvars = 0;
- fs->nactvar = 0;
- fs->bl = NULL;
- f->source = ls->source;
- f->maxstacksize = 2; /* registers 0/1 are always valid */
- fs->h = luaH_new(L, 0, 0);
- /* anchor table of constants and prototype (to avoid being collected) */
- sethvalue2s(L, L->top, fs->h);
- incr_top(L);
- setptvalue2s(L, L->top, f);
- incr_top(L);
-}
-
-
-static void close_func (LexState *ls) {
- lua_State *L = ls->L;
- FuncState *fs = ls->fs;
- Proto *f = fs->f;
- removevars(ls, 0);
- luaK_ret(fs, 0, 0); /* final return */
- luaM_reallocvector(L, f->code, f->sizecode, fs->pc, Instruction);
- f->sizecode = fs->pc;
- luaM_reallocvector(L, f->lineinfo, f->sizelineinfo, fs->pc, int);
- f->sizelineinfo = fs->pc;
- luaM_reallocvector(L, f->k, f->sizek, fs->nk, TValue);
- f->sizek = fs->nk;
- luaM_reallocvector(L, f->p, f->sizep, fs->np, Proto *);
- f->sizep = fs->np;
- luaM_reallocvector(L, f->locvars, f->sizelocvars, fs->nlocvars, LocVar);
- f->sizelocvars = fs->nlocvars;
- luaM_reallocvector(L, f->upvalues, f->sizeupvalues, f->nups, TString *);
- f->sizeupvalues = f->nups;
- lua_assert(luaG_checkcode(f));
- lua_assert(fs->bl == NULL);
- ls->fs = fs->prev;
- L->top -= 2; /* remove table and prototype from the stack */
- /* last token read was anchored in defunct function; must reanchor it */
- if (fs) anchor_token(ls);
-}
-
-
-Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, const char *name) {
- struct LexState lexstate;
- struct FuncState funcstate;
- lexstate.buff = buff;
- luaX_setinput(L, &lexstate, z, luaS_new(L, name));
- open_func(&lexstate, &funcstate);
- funcstate.f->is_vararg = VARARG_ISVARARG; /* main func. is always vararg */
- luaX_next(&lexstate); /* read first token */
- chunk(&lexstate);
- check(&lexstate, TK_EOS);
- close_func(&lexstate);
- lua_assert(funcstate.prev == NULL);
- lua_assert(funcstate.f->nups == 0);
- lua_assert(lexstate.fs == NULL);
- return funcstate.f;
-}
-
-
-
-/*============================================================*/
-/* GRAMMAR RULES */
-/*============================================================*/
-
-
-static void field (LexState *ls, expdesc *v) {
- /* field -> ['.' | ':'] NAME */
- FuncState *fs = ls->fs;
- expdesc key;
- luaK_exp2anyreg(fs, v);
- luaX_next(ls); /* skip the dot or colon */
- checkname(ls, &key);
- luaK_indexed(fs, v, &key);
-}
-
-
-static void yindex (LexState *ls, expdesc *v) {
- /* index -> '[' expr ']' */
- luaX_next(ls); /* skip the '[' */
- expr(ls, v);
- luaK_exp2val(ls->fs, v);
- checknext(ls, ']');
-}
-
-
-/*
-** {======================================================================
-** Rules for Constructors
-** =======================================================================
-*/
-
-
-struct ConsControl {
- expdesc v; /* last list item read */
- expdesc *t; /* table descriptor */
- int nh; /* total number of `record' elements */
- int na; /* total number of array elements */
- int tostore; /* number of array elements pending to be stored */
-};
-
-
-static void recfield (LexState *ls, struct ConsControl *cc) {
- /* recfield -> (NAME | `['exp1`]') = exp1 */
- FuncState *fs = ls->fs;
- int reg = ls->fs->freereg;
- expdesc key, val;
- int rkkey;
- if (ls->t.token == TK_NAME) {
- luaY_checklimit(fs, cc->nh, MAX_INT, "items in a constructor");
- checkname(ls, &key);
- }
- else /* ls->t.token == '[' */
- yindex(ls, &key);
- cc->nh++;
- checknext(ls, '=');
- rkkey = luaK_exp2RK(fs, &key);
- expr(ls, &val);
- luaK_codeABC(fs, OP_SETTABLE, cc->t->u.s.info, rkkey, luaK_exp2RK(fs, &val));
- fs->freereg = reg; /* free registers */
-}
-
-
-static void closelistfield (FuncState *fs, struct ConsControl *cc) {
- if (cc->v.k == VVOID) return; /* there is no list item */
- luaK_exp2nextreg(fs, &cc->v);
- cc->v.k = VVOID;
- if (cc->tostore == LFIELDS_PER_FLUSH) {
- luaK_setlist(fs, cc->t->u.s.info, cc->na, cc->tostore); /* flush */
- cc->tostore = 0; /* no more items pending */
- }
-}
-
-
-static void lastlistfield (FuncState *fs, struct ConsControl *cc) {
- if (cc->tostore == 0) return;
- if (hasmultret(cc->v.k)) {
- luaK_setmultret(fs, &cc->v);
- luaK_setlist(fs, cc->t->u.s.info, cc->na, LUA_MULTRET);
- cc->na--; /* do not count last expression (unknown number of elements) */
- }
- else {
- if (cc->v.k != VVOID)
- luaK_exp2nextreg(fs, &cc->v);
- luaK_setlist(fs, cc->t->u.s.info, cc->na, cc->tostore);
- }
-}
-
-
-static void listfield (LexState *ls, struct ConsControl *cc) {
- expr(ls, &cc->v);
- luaY_checklimit(ls->fs, cc->na, MAX_INT, "items in a constructor");
- cc->na++;
- cc->tostore++;
-}
-
-
-static void constructor (LexState *ls, expdesc *t) {
- /* constructor -> ?? */
- FuncState *fs = ls->fs;
- int line = ls->linenumber;
- int pc = luaK_codeABC(fs, OP_NEWTABLE, 0, 0, 0);
- struct ConsControl cc;
- cc.na = cc.nh = cc.tostore = 0;
- cc.t = t;
- init_exp(t, VRELOCABLE, pc);
- init_exp(&cc.v, VVOID, 0); /* no value (yet) */
- luaK_exp2nextreg(ls->fs, t); /* fix it at stack top (for gc) */
- checknext(ls, '{');
- do {
- lua_assert(cc.v.k == VVOID || cc.tostore > 0);
- if (ls->t.token == '}') break;
- closelistfield(fs, &cc);
- switch(ls->t.token) {
- case TK_NAME: { /* may be listfields or recfields */
- luaX_lookahead(ls);
- if (ls->lookahead.token != '=') /* expression? */
- listfield(ls, &cc);
- else
- recfield(ls, &cc);
- break;
- }
- case '[': { /* constructor_item -> recfield */
- recfield(ls, &cc);
- break;
- }
- default: { /* constructor_part -> listfield */
- listfield(ls, &cc);
- break;
- }
- }
- } while (testnext(ls, ',') || testnext(ls, ';'));
- check_match(ls, '}', '{', line);
- lastlistfield(fs, &cc);
- SETARG_B(fs->f->code[pc], luaO_int2fb(cc.na)); /* set initial array size */
- SETARG_C(fs->f->code[pc], luaO_int2fb(cc.nh)); /* set initial table size */
-}
-
-/* }====================================================================== */
-
-
-
-static void parlist (LexState *ls) {
- /* parlist -> [ param { `,' param } ] */
- FuncState *fs = ls->fs;
- Proto *f = fs->f;
- int nparams = 0;
- f->is_vararg = 0;
- if (ls->t.token != ')') { /* is `parlist' not empty? */
- do {
- switch (ls->t.token) {
- case TK_NAME: { /* param -> NAME */
- new_localvar(ls, str_checkname(ls), nparams++);
- break;
- }
- case TK_DOTS: { /* param -> `...' */
- luaX_next(ls);
-#if defined(LUA_COMPAT_VARARG)
- /* use `arg' as default name */
- new_localvarliteral(ls, "arg", nparams++);
- f->is_vararg = VARARG_HASARG | VARARG_NEEDSARG;
-#endif
- f->is_vararg |= VARARG_ISVARARG;
- break;
- }
- default: luaX_syntaxerror(ls, "<name> or " LUA_QL("...") " expected");
- }
- } while (!f->is_vararg && testnext(ls, ','));
- }
- adjustlocalvars(ls, nparams);
- f->numparams = cast_byte(fs->nactvar - (f->is_vararg & VARARG_HASARG));
- luaK_reserveregs(fs, fs->nactvar); /* reserve register for parameters */
-}
-
-
-static void body (LexState *ls, expdesc *e, int needself, int line) {
- /* body -> `(' parlist `)' chunk END */
- FuncState new_fs;
- open_func(ls, &new_fs);
- new_fs.f->linedefined = line;
- checknext(ls, '(');
- if (needself) {
- new_localvarliteral(ls, "self", 0);
- adjustlocalvars(ls, 1);
- }
- parlist(ls);
- checknext(ls, ')');
- chunk(ls);
- new_fs.f->lastlinedefined = ls->linenumber;
- check_match(ls, TK_END, TK_FUNCTION, line);
- close_func(ls);
- pushclosure(ls, &new_fs, e);
-}
-
-
-static int explist1 (LexState *ls, expdesc *v) {
- /* explist1 -> expr { `,' expr } */
- int n = 1; /* at least one expression */
- expr(ls, v);
- while (testnext(ls, ',')) {
- luaK_exp2nextreg(ls->fs, v);
- expr(ls, v);
- n++;
- }
- return n;
-}
-
-
-static void funcargs (LexState *ls, expdesc *f) {
- FuncState *fs = ls->fs;
- expdesc args;
- int base, nparams;
- int line = ls->linenumber;
- switch (ls->t.token) {
- case '(': { /* funcargs -> `(' [ explist1 ] `)' */
- if (line != ls->lastline)
- luaX_syntaxerror(ls,"ambiguous syntax (function call x new statement)");
- luaX_next(ls);
- if (ls->t.token == ')') /* arg list is empty? */
- args.k = VVOID;
- else {
- explist1(ls, &args);
- luaK_setmultret(fs, &args);
- }
- check_match(ls, ')', '(', line);
- break;
- }
- case '{': { /* funcargs -> constructor */
- constructor(ls, &args);
- break;
- }
- case TK_STRING: { /* funcargs -> STRING */
- codestring(ls, &args, ls->t.seminfo.ts);
- luaX_next(ls); /* must use `seminfo' before `next' */
- break;
- }
- default: {
- luaX_syntaxerror(ls, "function arguments expected");
- return;
- }
- }
- lua_assert(f->k == VNONRELOC);
- base = f->u.s.info; /* base register for call */
- if (hasmultret(args.k))
- nparams = LUA_MULTRET; /* open call */
- else {
- if (args.k != VVOID)
- luaK_exp2nextreg(fs, &args); /* close last argument */
- nparams = fs->freereg - (base+1);
- }
- init_exp(f, VCALL, luaK_codeABC(fs, OP_CALL, base, nparams+1, 2));
- luaK_fixline(fs, line);
- fs->freereg = base+1; /* call remove function and arguments and leaves
- (unless changed) one result */
-}
-
-
-
-
-/*
-** {======================================================================
-** Expression parsing
-** =======================================================================
-*/
-
-
-static void prefixexp (LexState *ls, expdesc *v) {
- /* prefixexp -> NAME | '(' expr ')' */
- switch (ls->t.token) {
- case '(': {
- int line = ls->linenumber;
- luaX_next(ls);
- expr(ls, v);
- check_match(ls, ')', '(', line);
- luaK_dischargevars(ls->fs, v);
- return;
- }
- case TK_NAME: {
- singlevar(ls, v);
- return;
- }
- default: {
- luaX_syntaxerror(ls, "unexpected symbol");
- return;
- }
- }
-}
-
-
-static void primaryexp (LexState *ls, expdesc *v) {
- /* primaryexp ->
- prefixexp { `.' NAME | `[' exp `]' | `:' NAME funcargs | funcargs } */
- FuncState *fs = ls->fs;
- prefixexp(ls, v);
- for (;;) {
- switch (ls->t.token) {
- case '.': { /* field */
- field(ls, v);
- break;
- }
- case '[': { /* `[' exp1 `]' */
- expdesc key;
- luaK_exp2anyreg(fs, v);
- yindex(ls, &key);
- luaK_indexed(fs, v, &key);
- break;
- }
- case ':': { /* `:' NAME funcargs */
- expdesc key;
- luaX_next(ls);
- checkname(ls, &key);
- luaK_self(fs, v, &key);
- funcargs(ls, v);
- break;
- }
- case '(': case TK_STRING: case '{': { /* funcargs */
- luaK_exp2nextreg(fs, v);
- funcargs(ls, v);
- break;
- }
- default: return;
- }
- }
-}
-
-
-static void simpleexp (LexState *ls, expdesc *v) {
- /* simpleexp -> NUMBER | STRING | NIL | true | false | ... |
- constructor | FUNCTION body | primaryexp */
- switch (ls->t.token) {
- case TK_NUMBER: {
- init_exp(v, VKNUM, 0);
- v->u.nval = ls->t.seminfo.r;
- break;
- }
- case TK_STRING: {
- codestring(ls, v, ls->t.seminfo.ts);
- break;
- }
- case TK_NIL: {
- init_exp(v, VNIL, 0);
- break;
- }
- case TK_TRUE: {
- init_exp(v, VTRUE, 0);
- break;
- }
- case TK_FALSE: {
- init_exp(v, VFALSE, 0);
- break;
- }
- case TK_DOTS: { /* vararg */
- FuncState *fs = ls->fs;
- check_condition(ls, fs->f->is_vararg,
- "cannot use " LUA_QL("...") " outside a vararg function");
- fs->f->is_vararg &= ~VARARG_NEEDSARG; /* don't need 'arg' */
- init_exp(v, VVARARG, luaK_codeABC(fs, OP_VARARG, 0, 1, 0));
- break;
- }
- case '{': { /* constructor */
- constructor(ls, v);
- return;
- }
- case TK_FUNCTION: {
- luaX_next(ls);
- body(ls, v, 0, ls->linenumber);
- return;
- }
- default: {
- primaryexp(ls, v);
- return;
- }
- }
- luaX_next(ls);
-}
-
-
-static UnOpr getunopr (int op) {
- switch (op) {
- case TK_NOT: return OPR_NOT;
- case '-': return OPR_MINUS;
- case '#': return OPR_LEN;
- default: return OPR_NOUNOPR;
- }
-}
-
-
-static BinOpr getbinopr (int op) {
- switch (op) {
- case '+': return OPR_ADD;
- case '-': return OPR_SUB;
- case '*': return OPR_MUL;
- case '/': return OPR_DIV;
- case '%': return OPR_MOD;
- case '^': return OPR_POW;
- case TK_CONCAT: return OPR_CONCAT;
- case TK_NE: return OPR_NE;
- case TK_EQ: return OPR_EQ;
- case '<': return OPR_LT;
- case TK_LE: return OPR_LE;
- case '>': return OPR_GT;
- case TK_GE: return OPR_GE;
- case TK_AND: return OPR_AND;
- case TK_OR: return OPR_OR;
- default: return OPR_NOBINOPR;
- }
-}
-
-
-static const struct {
- lu_byte left; /* left priority for each binary operator */
- lu_byte right; /* right priority */
-} priority[] = { /* ORDER OPR */
- {6, 6}, {6, 6}, {7, 7}, {7, 7}, {7, 7}, /* `+' `-' `/' `%' */
- {10, 9}, {5, 4}, /* power and concat (right associative) */
- {3, 3}, {3, 3}, /* equality and inequality */
- {3, 3}, {3, 3}, {3, 3}, {3, 3}, /* order */
- {2, 2}, {1, 1} /* logical (and/or) */
-};
-
-#define UNARY_PRIORITY 8 /* priority for unary operators */
-
-
-/*
-** subexpr -> (simpleexp | unop subexpr) { binop subexpr }
-** where `binop' is any binary operator with a priority higher than `limit'
-*/
-static BinOpr subexpr (LexState *ls, expdesc *v, unsigned int limit) {
- BinOpr op;
- UnOpr uop;
- enterlevel(ls);
- uop = getunopr(ls->t.token);
- if (uop != OPR_NOUNOPR) {
- luaX_next(ls);
- subexpr(ls, v, UNARY_PRIORITY);
- luaK_prefix(ls->fs, uop, v);
- }
- else simpleexp(ls, v);
- /* expand while operators have priorities higher than `limit' */
- op = getbinopr(ls->t.token);
- while (op != OPR_NOBINOPR && priority[op].left > limit) {
- expdesc v2;
- BinOpr nextop;
- luaX_next(ls);
- luaK_infix(ls->fs, op, v);
- /* read sub-expression with higher priority */
- nextop = subexpr(ls, &v2, priority[op].right);
- luaK_posfix(ls->fs, op, v, &v2);
- op = nextop;
- }
- leavelevel(ls);
- return op; /* return first untreated operator */
-}
-
-
-static void expr (LexState *ls, expdesc *v) {
- subexpr(ls, v, 0);
-}
-
-/* }==================================================================== */
-
-
-
-/*
-** {======================================================================
-** Rules for Statements
-** =======================================================================
-*/
-
-
-static int block_follow (int token) {
- switch (token) {
- case TK_ELSE: case TK_ELSEIF: case TK_END:
- case TK_UNTIL: case TK_EOS:
- return 1;
- default: return 0;
- }
-}
-
-
-static void block (LexState *ls) {
- /* block -> chunk */
- FuncState *fs = ls->fs;
- BlockCnt bl;
- enterblock(fs, &bl, 0);
- chunk(ls);
- lua_assert(bl.breaklist == NO_JUMP);
- leaveblock(fs);
-}
-
-
-/*
-** structure to chain all variables in the left-hand side of an
-** assignment
-*/
-struct LHS_assign {
- struct LHS_assign *prev;
- expdesc v; /* variable (global, local, upvalue, or indexed) */
-};
-
-
-/*
-** check whether, in an assignment to a local variable, the local variable
-** is needed in a previous assignment (to a table). If so, save original
-** local value in a safe place and use this safe copy in the previous
-** assignment.
-*/
-static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v) {
- FuncState *fs = ls->fs;
- int extra = fs->freereg; /* eventual position to save local variable */
- int conflict = 0;
- for (; lh; lh = lh->prev) {
- if (lh->v.k == VINDEXED) {
- if (lh->v.u.s.info == v->u.s.info) { /* conflict? */
- conflict = 1;
- lh->v.u.s.info = extra; /* previous assignment will use safe copy */
- }
- if (lh->v.u.s.aux == v->u.s.info) { /* conflict? */
- conflict = 1;
- lh->v.u.s.aux = extra; /* previous assignment will use safe copy */
- }
- }
- }
- if (conflict) {
- luaK_codeABC(fs, OP_MOVE, fs->freereg, v->u.s.info, 0); /* make copy */
- luaK_reserveregs(fs, 1);
- }
-}
-
-
-static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) {
- expdesc e;
- check_condition(ls, VLOCAL <= lh->v.k && lh->v.k <= VINDEXED,
- "syntax error");
- if (testnext(ls, ',')) { /* assignment -> `,' primaryexp assignment */
- struct LHS_assign nv;
- nv.prev = lh;
- primaryexp(ls, &nv.v);
- if (nv.v.k == VLOCAL)
- check_conflict(ls, lh, &nv.v);
- luaY_checklimit(ls->fs, nvars, LUAI_MAXCCALLS - ls->L->nCcalls,
- "variables in assignment");
- assignment(ls, &nv, nvars+1);
- }
- else { /* assignment -> `=' explist1 */
- int nexps;
- checknext(ls, '=');
- nexps = explist1(ls, &e);
- if (nexps != nvars) {
- adjust_assign(ls, nvars, nexps, &e);
- if (nexps > nvars)
- ls->fs->freereg -= nexps - nvars; /* remove extra values */
- }
- else {
- luaK_setoneret(ls->fs, &e); /* close last expression */
- luaK_storevar(ls->fs, &lh->v, &e);
- return; /* avoid default */
- }
- }
- init_exp(&e, VNONRELOC, ls->fs->freereg-1); /* default assignment */
- luaK_storevar(ls->fs, &lh->v, &e);
-}
-
-
-static int cond (LexState *ls) {
- /* cond -> exp */
- expdesc v;
- expr(ls, &v); /* read condition */
- if (v.k == VNIL) v.k = VFALSE; /* `falses' are all equal here */
- luaK_goiftrue(ls->fs, &v);
- return v.f;
-}
-
-
-static void breakstat (LexState *ls) {
- FuncState *fs = ls->fs;
- BlockCnt *bl = fs->bl;
- int upval = 0;
- while (bl && !bl->isbreakable) {
- upval |= bl->upval;
- bl = bl->previous;
- }
- if (!bl)
- luaX_syntaxerror(ls, "no loop to break");
- if (upval)
- luaK_codeABC(fs, OP_CLOSE, bl->nactvar, 0, 0);
- luaK_concat(fs, &bl->breaklist, luaK_jump(fs));
-}
-
-
-static void whilestat (LexState *ls, int line) {
- /* whilestat -> WHILE cond DO block END */
- FuncState *fs = ls->fs;
- int whileinit;
- int condexit;
- BlockCnt bl;
- luaX_next(ls); /* skip WHILE */
- whileinit = luaK_getlabel(fs);
- condexit = cond(ls);
- enterblock(fs, &bl, 1);
- checknext(ls, TK_DO);
- block(ls);
- luaK_patchlist(fs, luaK_jump(fs), whileinit);
- check_match(ls, TK_END, TK_WHILE, line);
- leaveblock(fs);
- luaK_patchtohere(fs, condexit); /* false conditions finish the loop */
-}
-
-
-static void repeatstat (LexState *ls, int line) {
- /* repeatstat -> REPEAT block UNTIL cond */
- int condexit;
- FuncState *fs = ls->fs;
- int repeat_init = luaK_getlabel(fs);
- BlockCnt bl1, bl2;
- enterblock(fs, &bl1, 1); /* loop block */
- enterblock(fs, &bl2, 0); /* scope block */
- luaX_next(ls); /* skip REPEAT */
- chunk(ls);
- check_match(ls, TK_UNTIL, TK_REPEAT, line);
- condexit = cond(ls); /* read condition (inside scope block) */
- if (!bl2.upval) { /* no upvalues? */
- leaveblock(fs); /* finish scope */
- luaK_patchlist(ls->fs, condexit, repeat_init); /* close the loop */
- }
- else { /* complete semantics when there are upvalues */
- breakstat(ls); /* if condition then break */
- luaK_patchtohere(ls->fs, condexit); /* else... */
- leaveblock(fs); /* finish scope... */
- luaK_patchlist(ls->fs, luaK_jump(fs), repeat_init); /* and repeat */
- }
- leaveblock(fs); /* finish loop */
-}
-
-
-static int exp1 (LexState *ls) {
- expdesc e;
- int k;
- expr(ls, &e);
- k = e.k;
- luaK_exp2nextreg(ls->fs, &e);
- return k;
-}
-
-
-static void forbody (LexState *ls, int base, int line, int nvars, int isnum) {
- /* forbody -> DO block */
- BlockCnt bl;
- FuncState *fs = ls->fs;
- int prep, endfor;
- adjustlocalvars(ls, 3); /* control variables */
- checknext(ls, TK_DO);
- prep = isnum ? luaK_codeAsBx(fs, OP_FORPREP, base, NO_JUMP) : luaK_jump(fs);
- enterblock(fs, &bl, 0); /* scope for declared variables */
- adjustlocalvars(ls, nvars);
- luaK_reserveregs(fs, nvars);
- block(ls);
- leaveblock(fs); /* end of scope for declared variables */
- luaK_patchtohere(fs, prep);
- endfor = (isnum) ? luaK_codeAsBx(fs, OP_FORLOOP, base, NO_JUMP) :
- luaK_codeABC(fs, OP_TFORLOOP, base, 0, nvars);
- luaK_fixline(fs, line); /* pretend that `OP_FOR' starts the loop */
- luaK_patchlist(fs, (isnum ? endfor : luaK_jump(fs)), prep + 1);
-}
-
-
-static void fornum (LexState *ls, TString *varname, int line) {
- /* fornum -> NAME = exp1,exp1[,exp1] forbody */
- FuncState *fs = ls->fs;
- int base = fs->freereg;
- new_localvarliteral(ls, "(for index)", 0);
- new_localvarliteral(ls, "(for limit)", 1);
- new_localvarliteral(ls, "(for step)", 2);
- new_localvar(ls, varname, 3);
- checknext(ls, '=');
- exp1(ls); /* initial value */
- checknext(ls, ',');
- exp1(ls); /* limit */
- if (testnext(ls, ','))
- exp1(ls); /* optional step */
- else { /* default step = 1 */
- luaK_codeABx(fs, OP_LOADK, fs->freereg, luaK_numberK(fs, 1));
- luaK_reserveregs(fs, 1);
- }
- forbody(ls, base, line, 1, 1);
-}
-
-
-static void forlist (LexState *ls, TString *indexname) {
- /* forlist -> NAME {,NAME} IN explist1 forbody */
- FuncState *fs = ls->fs;
- expdesc e;
- int nvars = 0;
- int line;
- int base = fs->freereg;
- /* create control variables */
- new_localvarliteral(ls, "(for generator)", nvars++);
- new_localvarliteral(ls, "(for state)", nvars++);
- new_localvarliteral(ls, "(for control)", nvars++);
- /* create declared variables */
- new_localvar(ls, indexname, nvars++);
- while (testnext(ls, ','))
- new_localvar(ls, str_checkname(ls), nvars++);
- checknext(ls, TK_IN);
- line = ls->linenumber;
- adjust_assign(ls, 3, explist1(ls, &e), &e);
- luaK_checkstack(fs, 3); /* extra space to call generator */
- forbody(ls, base, line, nvars - 3, 0);
-}
-
-
-static void forstat (LexState *ls, int line) {
- /* forstat -> FOR (fornum | forlist) END */
- FuncState *fs = ls->fs;
- TString *varname;
- BlockCnt bl;
- enterblock(fs, &bl, 1); /* scope for loop and control variables */
- luaX_next(ls); /* skip `for' */
- varname = str_checkname(ls); /* first variable name */
- switch (ls->t.token) {
- case '=': fornum(ls, varname, line); break;
- case ',': case TK_IN: forlist(ls, varname); break;
- default: luaX_syntaxerror(ls, LUA_QL("=") " or " LUA_QL("in") " expected");
- }
- check_match(ls, TK_END, TK_FOR, line);
- leaveblock(fs); /* loop scope (`break' jumps to this point) */
-}
-
-
-static int test_then_block (LexState *ls) {
- /* test_then_block -> [IF | ELSEIF] cond THEN block */
- int condexit;
- luaX_next(ls); /* skip IF or ELSEIF */
- condexit = cond(ls);
- checknext(ls, TK_THEN);
- block(ls); /* `then' part */
- return condexit;
-}
-
-
-static void ifstat (LexState *ls, int line) {
- /* ifstat -> IF cond THEN block {ELSEIF cond THEN block} [ELSE block] END */
- FuncState *fs = ls->fs;
- int flist;
- int escapelist = NO_JUMP;
- flist = test_then_block(ls); /* IF cond THEN block */
- while (ls->t.token == TK_ELSEIF) {
- luaK_concat(fs, &escapelist, luaK_jump(fs));
- luaK_patchtohere(fs, flist);
- flist = test_then_block(ls); /* ELSEIF cond THEN block */
- }
- if (ls->t.token == TK_ELSE) {
- luaK_concat(fs, &escapelist, luaK_jump(fs));
- luaK_patchtohere(fs, flist);
- luaX_next(ls); /* skip ELSE (after patch, for correct line info) */
- block(ls); /* `else' part */
- }
- else
- luaK_concat(fs, &escapelist, flist);
- luaK_patchtohere(fs, escapelist);
- check_match(ls, TK_END, TK_IF, line);
-}
-
-
-static void localfunc (LexState *ls) {
- expdesc v, b;
- FuncState *fs = ls->fs;
- new_localvar(ls, str_checkname(ls), 0);
- init_exp(&v, VLOCAL, fs->freereg);
- luaK_reserveregs(fs, 1);
- adjustlocalvars(ls, 1);
- body(ls, &b, 0, ls->linenumber);
- luaK_storevar(fs, &v, &b);
- /* debug information will only see the variable after this point! */
- getlocvar(fs, fs->nactvar - 1).startpc = fs->pc;
-}
-
-
-static void localstat (LexState *ls) {
- /* stat -> LOCAL NAME {`,' NAME} [`=' explist1] */
- int nvars = 0;
- int nexps;
- expdesc e;
- do {
- new_localvar(ls, str_checkname(ls), nvars++);
- } while (testnext(ls, ','));
- if (testnext(ls, '='))
- nexps = explist1(ls, &e);
- else {
- e.k = VVOID;
- nexps = 0;
- }
- adjust_assign(ls, nvars, nexps, &e);
- adjustlocalvars(ls, nvars);
-}
-
-
-static int funcname (LexState *ls, expdesc *v) {
- /* funcname -> NAME {field} [`:' NAME] */
- int needself = 0;
- singlevar(ls, v);
- while (ls->t.token == '.')
- field(ls, v);
- if (ls->t.token == ':') {
- needself = 1;
- field(ls, v);
- }
- return needself;
-}
-
-
-static void funcstat (LexState *ls, int line) {
- /* funcstat -> FUNCTION funcname body */
- int needself;
- expdesc v, b;
- luaX_next(ls); /* skip FUNCTION */
- needself = funcname(ls, &v);
- body(ls, &b, needself, line);
- luaK_storevar(ls->fs, &v, &b);
- luaK_fixline(ls->fs, line); /* definition `happens' in the first line */
-}
-
-
-static void exprstat (LexState *ls) {
- /* stat -> func | assignment */
- FuncState *fs = ls->fs;
- struct LHS_assign v;
- primaryexp(ls, &v.v);
- if (v.v.k == VCALL) /* stat -> func */
- SETARG_C(getcode(fs, &v.v), 1); /* call statement uses no results */
- else { /* stat -> assignment */
- v.prev = NULL;
- assignment(ls, &v, 1);
- }
-}
-
-
-static void retstat (LexState *ls) {
- /* stat -> RETURN explist */
- FuncState *fs = ls->fs;
- expdesc e;
- int first, nret; /* registers with returned values */
- luaX_next(ls); /* skip RETURN */
- if (block_follow(ls->t.token) || ls->t.token == ';')
- first = nret = 0; /* return no values */
- else {
- nret = explist1(ls, &e); /* optional return values */
- if (hasmultret(e.k)) {
- luaK_setmultret(fs, &e);
- if (e.k == VCALL && nret == 1) { /* tail call? */
- SET_OPCODE(getcode(fs,&e), OP_TAILCALL);
- lua_assert(GETARG_A(getcode(fs,&e)) == fs->nactvar);
- }
- first = fs->nactvar;
- nret = LUA_MULTRET; /* return all values */
- }
- else {
- if (nret == 1) /* only one single value? */
- first = luaK_exp2anyreg(fs, &e);
- else {
- luaK_exp2nextreg(fs, &e); /* values must go to the `stack' */
- first = fs->nactvar; /* return all `active' values */
- lua_assert(nret == fs->freereg - first);
- }
- }
- }
- luaK_ret(fs, first, nret);
-}
-
-
-static int statement (LexState *ls) {
- int line = ls->linenumber; /* may be needed for error messages */
- switch (ls->t.token) {
- case TK_IF: { /* stat -> ifstat */
- ifstat(ls, line);
- return 0;
- }
- case TK_WHILE: { /* stat -> whilestat */
- whilestat(ls, line);
- return 0;
- }
- case TK_DO: { /* stat -> DO block END */
- luaX_next(ls); /* skip DO */
- block(ls);
- check_match(ls, TK_END, TK_DO, line);
- return 0;
- }
- case TK_FOR: { /* stat -> forstat */
- forstat(ls, line);
- return 0;
- }
- case TK_REPEAT: { /* stat -> repeatstat */
- repeatstat(ls, line);
- return 0;
- }
- case TK_FUNCTION: {
- funcstat(ls, line); /* stat -> funcstat */
- return 0;
- }
- case TK_LOCAL: { /* stat -> localstat */
- luaX_next(ls); /* skip LOCAL */
- if (testnext(ls, TK_FUNCTION)) /* local function? */
- localfunc(ls);
- else
- localstat(ls);
- return 0;
- }
- case TK_RETURN: { /* stat -> retstat */
- retstat(ls);
- return 1; /* must be last statement */
- }
- case TK_BREAK: { /* stat -> breakstat */
- luaX_next(ls); /* skip BREAK */
- breakstat(ls);
- return 1; /* must be last statement */
- }
- default: {
- exprstat(ls);
- return 0; /* to avoid warnings */
- }
- }
-}
-
-
-static void chunk (LexState *ls) {
- /* chunk -> { stat [`;'] } */
- int islast = 0;
- enterlevel(ls);
- while (!islast && !block_follow(ls->t.token)) {
- islast = statement(ls);
- testnext(ls, ';');
- lua_assert(ls->fs->f->maxstacksize >= ls->fs->freereg &&
- ls->fs->freereg >= ls->fs->nactvar);
- ls->fs->freereg = ls->fs->nactvar; /* free registers */
- }
- leavelevel(ls);
-}
-
-/* }====================================================================== */
diff --git a/crawl-ref/source/util/lua/src/lparser.h b/crawl-ref/source/util/lua/src/lparser.h
deleted file mode 100644
index 18836afd1c..0000000000
--- a/crawl-ref/source/util/lua/src/lparser.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
-** $Id: lparser.h,v 1.57.1.1 2007/12/27 13:02:25 roberto Exp $
-** Lua Parser
-** See Copyright Notice in lua.h
-*/
-
-#ifndef lparser_h
-#define lparser_h
-
-#include "llimits.h"
-#include "lobject.h"
-#include "lzio.h"
-
-
-/*
-** Expression descriptor
-*/
-
-typedef enum {
- VVOID, /* no value */
- VNIL,
- VTRUE,
- VFALSE,
- VK, /* info = index of constant in `k' */
- VKNUM, /* nval = numerical value */
- VLOCAL, /* info = local register */
- VUPVAL, /* info = index of upvalue in `upvalues' */
- VGLOBAL, /* info = index of table; aux = index of global name in `k' */
- VINDEXED, /* info = table register; aux = index register (or `k') */
- VJMP, /* info = instruction pc */
- VRELOCABLE, /* info = instruction pc */
- VNONRELOC, /* info = result register */
- VCALL, /* info = instruction pc */
- VVARARG /* info = instruction pc */
-} expkind;
-
-typedef struct expdesc {
- expkind k;
- union {
- struct { int info, aux; } s;
- lua_Number nval;
- } u;
- int t; /* patch list of `exit when true' */
- int f; /* patch list of `exit when false' */
-} expdesc;
-
-
-typedef struct upvaldesc {
- lu_byte k;
- lu_byte info;
-} upvaldesc;
-
-
-struct BlockCnt; /* defined in lparser.c */
-
-
-/* state needed to generate code for a given function */
-typedef struct FuncState {
- Proto *f; /* current function header */
- Table *h; /* table to find (and reuse) elements in `k' */
- struct FuncState *prev; /* enclosing function */
- struct LexState *ls; /* lexical state */
- struct lua_State *L; /* copy of the Lua state */
- struct BlockCnt *bl; /* chain of current blocks */
- int pc; /* next position to code (equivalent to `ncode') */
- int lasttarget; /* `pc' of last `jump target' */
- int jpc; /* list of pending jumps to `pc' */
- int freereg; /* first free register */
- int nk; /* number of elements in `k' */
- int np; /* number of elements in `p' */
- short nlocvars; /* number of elements in `locvars' */
- lu_byte nactvar; /* number of active local variables */
- upvaldesc upvalues[LUAI_MAXUPVALUES]; /* upvalues */
- unsigned short actvar[LUAI_MAXVARS]; /* declared-variable stack */
-} FuncState;
-
-
-LUAI_FUNC Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff,
- const char *name);
-
-
-#endif
diff --git a/crawl-ref/source/util/lua/src/lstate.c b/crawl-ref/source/util/lua/src/lstate.c
deleted file mode 100644
index 4313b83a0c..0000000000
--- a/crawl-ref/source/util/lua/src/lstate.c
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
-** $Id: lstate.c,v 2.36.1.2 2008/01/03 15:20:39 roberto Exp $
-** Global State
-** See Copyright Notice in lua.h
-*/
-
-
-#include <stddef.h>
-
-#define lstate_c
-#define LUA_CORE
-
-#include "lua.h"
-
-#include "ldebug.h"
-#include "ldo.h"
-#include "lfunc.h"
-#include "lgc.h"
-#include "llex.h"
-#include "lmem.h"
-#include "lstate.h"
-#include "lstring.h"
-#include "ltable.h"
-#include "ltm.h"
-
-
-#define state_size(x) (sizeof(x) + LUAI_EXTRASPACE)
-#define fromstate(l) (cast(lu_byte *, (l)) - LUAI_EXTRASPACE)
-#define tostate(l) (cast(lua_State *, cast(lu_byte *, l) + LUAI_EXTRASPACE))
-
-
-/*
-** Main thread combines a thread state and the global state
-*/
-typedef struct LG {
- lua_State l;
- global_State g;
-} LG;
-
-
-
-static void stack_init (lua_State *L1, lua_State *L) {
- /* initialize CallInfo array */
- L1->base_ci = luaM_newvector(L, BASIC_CI_SIZE, CallInfo);
- L1->ci = L1->base_ci;
- L1->size_ci = BASIC_CI_SIZE;
- L1->end_ci = L1->base_ci + L1->size_ci - 1;
- /* initialize stack array */
- L1->stack = luaM_newvector(L, BASIC_STACK_SIZE + EXTRA_STACK, TValue);
- L1->stacksize = BASIC_STACK_SIZE + EXTRA_STACK;
- L1->top = L1->stack;
- L1->stack_last = L1->stack+(L1->stacksize - EXTRA_STACK)-1;
- /* initialize first ci */
- L1->ci->func = L1->top;
- setnilvalue(L1->top++); /* `function' entry for this `ci' */
- L1->base = L1->ci->base = L1->top;
- L1->ci->top = L1->top + LUA_MINSTACK;
-}
-
-
-static void freestack (lua_State *L, lua_State *L1) {
- luaM_freearray(L, L1->base_ci, L1->size_ci, CallInfo);
- luaM_freearray(L, L1->stack, L1->stacksize, TValue);
-}
-
-
-/*
-** open parts that may cause memory-allocation errors
-*/
-static void f_luaopen (lua_State *L, void *ud) {
- global_State *g = G(L);
- UNUSED(ud);
- stack_init(L, L); /* init stack */
- sethvalue(L, gt(L), luaH_new(L, 0, 2)); /* table of globals */
- sethvalue(L, registry(L), luaH_new(L, 0, 2)); /* registry */
- luaS_resize(L, MINSTRTABSIZE); /* initial size of string table */
- luaT_init(L);
- luaX_init(L);
- luaS_fix(luaS_newliteral(L, MEMERRMSG));
- g->GCthreshold = 4*g->totalbytes;
-}
-
-
-static void preinit_state (lua_State *L, global_State *g) {
- G(L) = g;
- L->stack = NULL;
- L->stacksize = 0;
- L->errorJmp = NULL;
- L->hook = NULL;
- L->hookmask = 0;
- L->basehookcount = 0;
- L->allowhook = 1;
- resethookcount(L);
- L->openupval = NULL;
- L->size_ci = 0;
- L->nCcalls = L->baseCcalls = 0;
- L->status = 0;
- L->base_ci = L->ci = NULL;
- L->savedpc = NULL;
- L->errfunc = 0;
- setnilvalue(gt(L));
-}
-
-
-static void close_state (lua_State *L) {
- global_State *g = G(L);
- luaF_close(L, L->stack); /* close all upvalues for this thread */
- luaC_freeall(L); /* collect all objects */
- lua_assert(g->rootgc == obj2gco(L));
- lua_assert(g->strt.nuse == 0);
- luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size, TString *);
- luaZ_freebuffer(L, &g->buff);
- freestack(L, L);
- lua_assert(g->totalbytes == sizeof(LG));
- (*g->frealloc)(g->ud, fromstate(L), state_size(LG), 0);
-}
-
-
-lua_State *luaE_newthread (lua_State *L) {
- lua_State *L1 = tostate(luaM_malloc(L, state_size(lua_State)));
- luaC_link(L, obj2gco(L1), LUA_TTHREAD);
- preinit_state(L1, G(L));
- stack_init(L1, L); /* init stack */
- setobj2n(L, gt(L1), gt(L)); /* share table of globals */
- L1->hookmask = L->hookmask;
- L1->basehookcount = L->basehookcount;
- L1->hook = L->hook;
- resethookcount(L1);
- lua_assert(iswhite(obj2gco(L1)));
- return L1;
-}
-
-
-void luaE_freethread (lua_State *L, lua_State *L1) {
- luaF_close(L1, L1->stack); /* close all upvalues for this thread */
- lua_assert(L1->openupval == NULL);
- luai_userstatefree(L1);
- freestack(L, L1);
- luaM_freemem(L, fromstate(L1), state_size(lua_State));
-}
-
-
-LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
- int i;
- lua_State *L;
- global_State *g;
- void *l = (*f)(ud, NULL, 0, state_size(LG));
- if (l == NULL) return NULL;
- L = tostate(l);
- g = &((LG *)L)->g;
- L->next = NULL;
- L->tt = LUA_TTHREAD;
- g->currentwhite = bit2mask(WHITE0BIT, FIXEDBIT);
- L->marked = luaC_white(g);
- set2bits(L->marked, FIXEDBIT, SFIXEDBIT);
- preinit_state(L, g);
- g->frealloc = f;
- g->ud = ud;
- g->mainthread = L;
- g->uvhead.u.l.prev = &g->uvhead;
- g->uvhead.u.l.next = &g->uvhead;
- g->GCthreshold = 0; /* mark it as unfinished state */
- g->strt.size = 0;
- g->strt.nuse = 0;
- g->strt.hash = NULL;
- setnilvalue(registry(L));
- luaZ_initbuffer(L, &g->buff);
- g->panic = NULL;
- g->gcstate = GCSpause;
- g->rootgc = obj2gco(L);
- g->sweepstrgc = 0;
- g->sweepgc = &g->rootgc;
- g->gray = NULL;
- g->grayagain = NULL;
- g->weak = NULL;
- g->tmudata = NULL;
- g->totalbytes = sizeof(LG);
- g->gcpause = LUAI_GCPAUSE;
- g->gcstepmul = LUAI_GCMUL;
- g->gcdept = 0;
- for (i=0; i<NUM_TAGS; i++) g->mt[i] = NULL;
- if (luaD_rawrunprotected(L, f_luaopen, NULL) != 0) {
- /* memory allocation error: free partial state */
- close_state(L);
- L = NULL;
- }
- else
- luai_userstateopen(L);
- return L;
-}
-
-
-static void callallgcTM (lua_State *L, void *ud) {
- UNUSED(ud);
- luaC_callGCTM(L); /* call GC metamethods for all udata */
-}
-
-
-LUA_API void lua_close (lua_State *L) {
- L = G(L)->mainthread; /* only the main thread can be closed */
- lua_lock(L);
- luaF_close(L, L->stack); /* close all upvalues for this thread */
- luaC_separateudata(L, 1); /* separate udata that have GC metamethods */
- L->errfunc = 0; /* no error function during GC metamethods */
- do { /* repeat until no more errors */
- L->ci = L->base_ci;
- L->base = L->top = L->ci->base;
- L->nCcalls = L->baseCcalls = 0;
- } while (luaD_rawrunprotected(L, callallgcTM, NULL) != 0);
- lua_assert(G(L)->tmudata == NULL);
- luai_userstateclose(L);
- close_state(L);
-}
-
diff --git a/crawl-ref/source/util/lua/src/lstate.h b/crawl-ref/source/util/lua/src/lstate.h
deleted file mode 100644
index 3bc575b6bc..0000000000
--- a/crawl-ref/source/util/lua/src/lstate.h
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
-** $Id: lstate.h,v 2.24.1.2 2008/01/03 15:20:39 roberto Exp $
-** Global State
-** See Copyright Notice in lua.h
-*/
-
-#ifndef lstate_h
-#define lstate_h
-
-#include "lua.h"
-
-#include "lobject.h"
-#include "ltm.h"
-#include "lzio.h"
-
-
-
-struct lua_longjmp; /* defined in ldo.c */
-
-
-/* table of globals */
-#define gt(L) (&L->l_gt)
-
-/* registry */
-#define registry(L) (&G(L)->l_registry)
-
-
-/* extra stack space to handle TM calls and some other extras */
-#define EXTRA_STACK 5
-
-
-#define BASIC_CI_SIZE 8
-
-#define BASIC_STACK_SIZE (2*LUA_MINSTACK)
-
-
-
-typedef struct stringtable {
- GCObject **hash;
- lu_int32 nuse; /* number of elements */
- int size;
-} stringtable;
-
-
-/*
-** informations about a call
-*/
-typedef struct CallInfo {
- StkId base; /* base for this function */
- StkId func; /* function index in the stack */
- StkId top; /* top for this function */
- const Instruction *savedpc;
- int nresults; /* expected number of results from this function */
- int tailcalls; /* number of tail calls lost under this entry */
-} CallInfo;
-
-
-
-#define curr_func(L) (clvalue(L->ci->func))
-#define ci_func(ci) (clvalue((ci)->func))
-#define f_isLua(ci) (!ci_func(ci)->c.isC)
-#define isLua(ci) (ttisfunction((ci)->func) && f_isLua(ci))
-
-
-/*
-** `global state', shared by all threads of this state
-*/
-typedef struct global_State {
- stringtable strt; /* hash table for strings */
- lua_Alloc frealloc; /* function to reallocate memory */
- void *ud; /* auxiliary data to `frealloc' */
- lu_byte currentwhite;
- lu_byte gcstate; /* state of garbage collector */
- int sweepstrgc; /* position of sweep in `strt' */
- GCObject *rootgc; /* list of all collectable objects */
- GCObject **sweepgc; /* position of sweep in `rootgc' */
- GCObject *gray; /* list of gray objects */
- GCObject *grayagain; /* list of objects to be traversed atomically */
- GCObject *weak; /* list of weak tables (to be cleared) */
- GCObject *tmudata; /* last element of list of userdata to be GC */
- Mbuffer buff; /* temporary buffer for string concatentation */
- lu_mem GCthreshold;
- lu_mem totalbytes; /* number of bytes currently allocated */
- lu_mem estimate; /* an estimate of number of bytes actually in use */
- lu_mem gcdept; /* how much GC is `behind schedule' */
- int gcpause; /* size of pause between successive GCs */
- int gcstepmul; /* GC `granularity' */
- lua_CFunction panic; /* to be called in unprotected errors */
- TValue l_registry;
- struct lua_State *mainthread;
- UpVal uvhead; /* head of double-linked list of all open upvalues */
- struct Table *mt[NUM_TAGS]; /* metatables for basic types */
- TString *tmname[TM_N]; /* array with tag-method names */
-} global_State;
-
-
-/*
-** `per thread' state
-*/
-struct lua_State {
- CommonHeader;
- lu_byte status;
- StkId top; /* first free slot in the stack */
- StkId base; /* base of current function */
- global_State *l_G;
- CallInfo *ci; /* call info for current function */
- const Instruction *savedpc; /* `savedpc' of current function */
- StkId stack_last; /* last free slot in the stack */
- StkId stack; /* stack base */
- CallInfo *end_ci; /* points after end of ci array*/
- CallInfo *base_ci; /* array of CallInfo's */
- int stacksize;
- int size_ci; /* size of array `base_ci' */
- unsigned short nCcalls; /* number of nested C calls */
- unsigned short baseCcalls; /* nested C calls when resuming coroutine */
- lu_byte hookmask;
- lu_byte allowhook;
- int basehookcount;
- int hookcount;
- lua_Hook hook;
- TValue l_gt; /* table of globals */
- TValue env; /* temporary place for environments */
- GCObject *openupval; /* list of open upvalues in this stack */
- GCObject *gclist;
- struct lua_longjmp *errorJmp; /* current error recover point */
- ptrdiff_t errfunc; /* current error handling function (stack index) */
-};
-
-
-#define G(L) (L->l_G)
-
-
-/*
-** Union of all collectable objects
-*/
-union GCObject {
- GCheader gch;
- union TString ts;
- union Udata u;
- union Closure cl;
- struct Table h;
- struct Proto p;
- struct UpVal uv;
- struct lua_State th; /* thread */
-};
-
-
-/* macros to convert a GCObject into a specific value */
-#define rawgco2ts(o) check_exp((o)->gch.tt == LUA_TSTRING, &((o)->ts))
-#define gco2ts(o) (&rawgco2ts(o)->tsv)
-#define rawgco2u(o) check_exp((o)->gch.tt == LUA_TUSERDATA, &((o)->u))
-#define gco2u(o) (&rawgco2u(o)->uv)
-#define gco2cl(o) check_exp((o)->gch.tt == LUA_TFUNCTION, &((o)->cl))
-#define gco2h(o) check_exp((o)->gch.tt == LUA_TTABLE, &((o)->h))
-#define gco2p(o) check_exp((o)->gch.tt == LUA_TPROTO, &((o)->p))
-#define gco2uv(o) check_exp((o)->gch.tt == LUA_TUPVAL, &((o)->uv))
-#define ngcotouv(o) \
- check_exp((o) == NULL || (o)->gch.tt == LUA_TUPVAL, &((o)->uv))
-#define gco2th(o) check_exp((o)->gch.tt == LUA_TTHREAD, &((o)->th))
-
-/* macro to convert any Lua object into a GCObject */
-#define obj2gco(v) (cast(GCObject *, (v)))
-
-
-LUAI_FUNC lua_State *luaE_newthread (lua_State *L);
-LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1);
-
-#endif
-
diff --git a/crawl-ref/source/util/lua/src/lstring.c b/crawl-ref/source/util/lua/src/lstring.c
deleted file mode 100644
index 49113151cc..0000000000
--- a/crawl-ref/source/util/lua/src/lstring.c
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
-** $Id: lstring.c,v 2.8.1.1 2007/12/27 13:02:25 roberto Exp $
-** String table (keeps all strings handled by Lua)
-** See Copyright Notice in lua.h
-*/
-
-
-#include <string.h>
-
-#define lstring_c
-#define LUA_CORE
-
-#include "lua.h"
-
-#include "lmem.h"
-#include "lobject.h"
-#include "lstate.h"
-#include "lstring.h"
-
-
-
-void luaS_resize (lua_State *L, int newsize) {
- GCObject **newhash;
- stringtable *tb;
- int i;
- if (G(L)->gcstate == GCSsweepstring)
- return; /* cannot resize during GC traverse */
- newhash = luaM_newvector(L, newsize, GCObject *);
- tb = &G(L)->strt;
- for (i=0; i<newsize; i++) newhash[i] = NULL;
- /* rehash */
- for (i=0; i<tb->size; i++) {
- GCObject *p = tb->hash[i];
- while (p) { /* for each node in the list */
- GCObject *next = p->gch.next; /* save next */
- unsigned int h = gco2ts(p)->hash;
- int h1 = lmod(h, newsize); /* new position */
- lua_assert(cast_int(h%newsize) == lmod(h, newsize));
- p->gch.next = newhash[h1]; /* chain it */
- newhash[h1] = p;
- p = next;
- }
- }
- luaM_freearray(L, tb->hash, tb->size, TString *);
- tb->size = newsize;
- tb->hash = newhash;
-}
-
-
-static TString *newlstr (lua_State *L, const char *str, size_t l,
- unsigned int h) {
- TString *ts;
- stringtable *tb;
- if (l+1 > (MAX_SIZET - sizeof(TString))/sizeof(char))
- luaM_toobig(L);
- ts = cast(TString *, luaM_malloc(L, (l+1)*sizeof(char)+sizeof(TString)));
- ts->tsv.len = l;
- ts->tsv.hash = h;
- ts->tsv.marked = luaC_white(G(L));
- ts->tsv.tt = LUA_TSTRING;
- ts->tsv.reserved = 0;
- memcpy(ts+1, str, l*sizeof(char));
- ((char *)(ts+1))[l] = '\0'; /* ending 0 */
- tb = &G(L)->strt;
- h = lmod(h, tb->size);
- ts->tsv.next = tb->hash[h]; /* chain new entry */
- tb->hash[h] = obj2gco(ts);
- tb->nuse++;
- if (tb->nuse > cast(lu_int32, tb->size) && tb->size <= MAX_INT/2)
- luaS_resize(L, tb->size*2); /* too crowded */
- return ts;
-}
-
-
-TString *luaS_newlstr (lua_State *L, const char *str, size_t l) {
- GCObject *o;
- unsigned int h = cast(unsigned int, l); /* seed */
- size_t step = (l>>5)+1; /* if string is too long, don't hash all its chars */
- size_t l1;
- for (l1=l; l1>=step; l1-=step) /* compute hash */
- h = h ^ ((h<<5)+(h>>2)+cast(unsigned char, str[l1-1]));
- for (o = G(L)->strt.hash[lmod(h, G(L)->strt.size)];
- o != NULL;
- o = o->gch.next) {
- TString *ts = rawgco2ts(o);
- if (ts->tsv.len == l && (memcmp(str, getstr(ts), l) == 0)) {
- /* string may be dead */
- if (isdead(G(L), o)) changewhite(o);
- return ts;
- }
- }
- return newlstr(L, str, l, h); /* not found */
-}
-
-
-Udata *luaS_newudata (lua_State *L, size_t s, Table *e) {
- Udata *u;
- if (s > MAX_SIZET - sizeof(Udata))
- luaM_toobig(L);
- u = cast(Udata *, luaM_malloc(L, s + sizeof(Udata)));
- u->uv.marked = luaC_white(G(L)); /* is not finalized */
- u->uv.tt = LUA_TUSERDATA;
- u->uv.len = s;
- u->uv.metatable = NULL;
- u->uv.env = e;
- /* chain it on udata list (after main thread) */
- u->uv.next = G(L)->mainthread->next;
- G(L)->mainthread->next = obj2gco(u);
- return u;
-}
-
diff --git a/crawl-ref/source/util/lua/src/lstring.h b/crawl-ref/source/util/lua/src/lstring.h
deleted file mode 100644
index 73a2ff8b38..0000000000
--- a/crawl-ref/source/util/lua/src/lstring.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
-** $Id: lstring.h,v 1.43.1.1 2007/12/27 13:02:25 roberto Exp $
-** String table (keep all strings handled by Lua)
-** See Copyright Notice in lua.h
-*/
-
-#ifndef lstring_h
-#define lstring_h
-
-
-#include "lgc.h"
-#include "lobject.h"
-#include "lstate.h"
-
-
-#define sizestring(s) (sizeof(union TString)+((s)->len+1)*sizeof(char))
-
-#define sizeudata(u) (sizeof(union Udata)+(u)->len)
-
-#define luaS_new(L, s) (luaS_newlstr(L, s, strlen(s)))
-#define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, \
- (sizeof(s)/sizeof(char))-1))
-
-#define luaS_fix(s) l_setbit((s)->tsv.marked, FIXEDBIT)
-
-LUAI_FUNC void luaS_resize (lua_State *L, int newsize);
-LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s, Table *e);
-LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l);
-
-
-#endif
diff --git a/crawl-ref/source/util/lua/src/lstrlib.c b/crawl-ref/source/util/lua/src/lstrlib.c
deleted file mode 100644
index 1b4763d4ee..0000000000
--- a/crawl-ref/source/util/lua/src/lstrlib.c
+++ /dev/null
@@ -1,869 +0,0 @@
-/*
-** $Id: lstrlib.c,v 1.132.1.4 2008/07/11 17:27:21 roberto Exp $
-** Standard library for string operations and pattern-matching
-** See Copyright Notice in lua.h
-*/
-
-
-#include <ctype.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#define lstrlib_c
-#define LUA_LIB
-
-#include "lua.h"
-
-#include "lauxlib.h"
-#include "lualib.h"
-
-
-/* macro to `unsign' a character */
-#define uchar(c) ((unsigned char)(c))
-
-
-
-static int str_len (lua_State *L) {
- size_t l;
- luaL_checklstring(L, 1, &l);
- lua_pushinteger(L, l);
- return 1;
-}
-
-
-static ptrdiff_t posrelat (ptrdiff_t pos, size_t len) {
- /* relative string position: negative means back from end */
- if (pos < 0) pos += (ptrdiff_t)len + 1;
- return (pos >= 0) ? pos : 0;
-}
-
-
-static int str_sub (lua_State *L) {
- size_t l;
- const char *s = luaL_checklstring(L, 1, &l);
- ptrdiff_t start = posrelat(luaL_checkinteger(L, 2), l);
- ptrdiff_t end = posrelat(luaL_optinteger(L, 3, -1), l);
- if (start < 1) start = 1;
- if (end > (ptrdiff_t)l) end = (ptrdiff_t)l;
- if (start <= end)
- lua_pushlstring(L, s+start-1, end-start+1);
- else lua_pushliteral(L, "");
- return 1;
-}
-
-
-static int str_reverse (lua_State *L) {
- size_t l;
- luaL_Buffer b;
- const char *s = luaL_checklstring(L, 1, &l);
- luaL_buffinit(L, &b);
- while (l--) luaL_addchar(&b, s[l]);
- luaL_pushresult(&b);
- return 1;
-}
-
-
-static int str_lower (lua_State *L) {
- size_t l;
- size_t i;
- luaL_Buffer b;
- const char *s = luaL_checklstring(L, 1, &l);
- luaL_buffinit(L, &b);
- for (i=0; i<l; i++)
- luaL_addchar(&b, tolower(uchar(s[i])));
- luaL_pushresult(&b);
- return 1;
-}
-
-
-static int str_upper (lua_State *L) {
- size_t l;
- size_t i;
- luaL_Buffer b;
- const char *s = luaL_checklstring(L, 1, &l);
- luaL_buffinit(L, &b);
- for (i=0; i<l; i++)
- luaL_addchar(&b, toupper(uchar(s[i])));
- luaL_pushresult(&b);
- return 1;
-}
-
-static int str_rep (lua_State *L) {
- size_t l;
- luaL_Buffer b;
- const char *s = luaL_checklstring(L, 1, &l);
- int n = luaL_checkint(L, 2);
- luaL_buffinit(L, &b);
- while (n-- > 0)
- luaL_addlstring(&b, s, l);
- luaL_pushresult(&b);
- return 1;
-}
-
-
-static int str_byte (lua_State *L) {
- size_t l;
- const char *s = luaL_checklstring(L, 1, &l);
- ptrdiff_t posi = posrelat(luaL_optinteger(L, 2, 1), l);
- ptrdiff_t pose = posrelat(luaL_optinteger(L, 3, posi), l);
- int n, i;
- if (posi <= 0) posi = 1;
- if ((size_t)pose > l) pose = l;
- if (posi > pose) return 0; /* empty interval; return no values */
- n = (int)(pose - posi + 1);
- if (posi + n <= pose) /* overflow? */
- luaL_error(L, "string slice too long");
- luaL_checkstack(L, n, "string slice too long");
- for (i=0; i<n; i++)
- lua_pushinteger(L, uchar(s[posi+i-1]));
- return n;
-}
-
-
-static int str_char (lua_State *L) {
- int n = lua_gettop(L); /* number of arguments */
- int i;
- luaL_Buffer b;
- luaL_buffinit(L, &b);
- for (i=1; i<=n; i++) {
- int c = luaL_checkint(L, i);
- luaL_argcheck(L, uchar(c) == c, i, "invalid value");
- luaL_addchar(&b, uchar(c));
- }
- luaL_pushresult(&b);
- return 1;
-}
-
-
-static int writer (lua_State *L, const void* b, size_t size, void* B) {
- (void)L;
- luaL_addlstring((luaL_Buffer*) B, (const char *)b, size);
- return 0;
-}
-
-
-static int str_dump (lua_State *L) {
- luaL_Buffer b;
- luaL_checktype(L, 1, LUA_TFUNCTION);
- lua_settop(L, 1);
- luaL_buffinit(L,&b);
- if (lua_dump(L, writer, &b) != 0)
- luaL_error(L, "unable to dump given function");
- luaL_pushresult(&b);
- return 1;
-}
-
-
-
-/*
-** {======================================================
-** PATTERN MATCHING
-** =======================================================
-*/
-
-
-#define CAP_UNFINISHED (-1)
-#define CAP_POSITION (-2)
-
-typedef struct MatchState {
- const char *src_init; /* init of source string */
- const char *src_end; /* end (`\0') of source string */
- lua_State *L;
- int level; /* total number of captures (finished or unfinished) */
- struct {
- const char *init;
- ptrdiff_t len;
- } capture[LUA_MAXCAPTURES];
-} MatchState;
-
-
-#define L_ESC '%'
-#define SPECIALS "^$*+?.([%-"
-
-
-static int check_capture (MatchState *ms, int l) {
- l -= '1';
- if (l < 0 || l >= ms->level || ms->capture[l].len == CAP_UNFINISHED)
- return luaL_error(ms->L, "invalid capture index");
- return l;
-}
-
-
-static int capture_to_close (MatchState *ms) {
- int level = ms->level;
- for (level--; level>=0; level--)
- if (ms->capture[level].len == CAP_UNFINISHED) return level;
- return luaL_error(ms->L, "invalid pattern capture");
-}
-
-
-static const char *classend (MatchState *ms, const char *p) {
- switch (*p++) {
- case L_ESC: {
- if (*p == '\0')
- luaL_error(ms->L, "malformed pattern (ends with " LUA_QL("%%") ")");
- return p+1;
- }
- case '[': {
- if (*p == '^') p++;
- do { /* look for a `]' */
- if (*p == '\0')
- luaL_error(ms->L, "malformed pattern (missing " LUA_QL("]") ")");
- if (*(p++) == L_ESC && *p != '\0')
- p++; /* skip escapes (e.g. `%]') */
- } while (*p != ']');
- return p+1;
- }
- default: {
- return p;
- }
- }
-}
-
-
-static int match_class (int c, int cl) {
- int res;
- switch (tolower(cl)) {
- case 'a' : res = isalpha(c); break;
- case 'c' : res = iscntrl(c); break;
- case 'd' : res = isdigit(c); break;
- case 'l' : res = islower(c); break;
- case 'p' : res = ispunct(c); break;
- case 's' : res = isspace(c); break;
- case 'u' : res = isupper(c); break;
- case 'w' : res = isalnum(c); break;
- case 'x' : res = isxdigit(c); break;
- case 'z' : res = (c == 0); break;
- default: return (cl == c);
- }
- return (islower(cl) ? res : !res);
-}
-
-
-static int matchbracketclass (int c, const char *p, const char *ec) {
- int sig = 1;
- if (*(p+1) == '^') {
- sig = 0;
- p++; /* skip the `^' */
- }
- while (++p < ec) {
- if (*p == L_ESC) {
- p++;
- if (match_class(c, uchar(*p)))
- return sig;
- }
- else if ((*(p+1) == '-') && (p+2 < ec)) {
- p+=2;
- if (uchar(*(p-2)) <= c && c <= uchar(*p))
- return sig;
- }
- else if (uchar(*p) == c) return sig;
- }
- return !sig;
-}
-
-
-static int singlematch (int c, const char *p, const char *ep) {
- switch (*p) {
- case '.': return 1; /* matches any char */
- case L_ESC: return match_class(c, uchar(*(p+1)));
- case '[': return matchbracketclass(c, p, ep-1);
- default: return (uchar(*p) == c);
- }
-}
-
-
-static const char *match (MatchState *ms, const char *s, const char *p);
-
-
-static const char *matchbalance (MatchState *ms, const char *s,
- const char *p) {
- if (*p == 0 || *(p+1) == 0)
- luaL_error(ms->L, "unbalanced pattern");
- if (*s != *p) return NULL;
- else {
- int b = *p;
- int e = *(p+1);
- int cont = 1;
- while (++s < ms->src_end) {
- if (*s == e) {
- if (--cont == 0) return s+1;
- }
- else if (*s == b) cont++;
- }
- }
- return NULL; /* string ends out of balance */
-}
-
-
-static const char *max_expand (MatchState *ms, const char *s,
- const char *p, const char *ep) {
- ptrdiff_t i = 0; /* counts maximum expand for item */
- while ((s+i)<ms->src_end && singlematch(uchar(*(s+i)), p, ep))
- i++;
- /* keeps trying to match with the maximum repetitions */
- while (i>=0) {
- const char *res = match(ms, (s+i), ep+1);
- if (res) return res;
- i--; /* else didn't match; reduce 1 repetition to try again */
- }
- return NULL;
-}
-
-
-static const char *min_expand (MatchState *ms, const char *s,
- const char *p, const char *ep) {
- for (;;) {
- const char *res = match(ms, s, ep+1);
- if (res != NULL)
- return res;
- else if (s<ms->src_end && singlematch(uchar(*s), p, ep))
- s++; /* try with one more repetition */
- else return NULL;
- }
-}
-
-
-static const char *start_capture (MatchState *ms, const char *s,
- const char *p, int what) {
- const char *res;
- int level = ms->level;
- if (level >= LUA_MAXCAPTURES) luaL_error(ms->L, "too many captures");
- ms->capture[level].init = s;
- ms->capture[level].len = what;
- ms->level = level+1;
- if ((res=match(ms, s, p)) == NULL) /* match failed? */
- ms->level--; /* undo capture */
- return res;
-}
-
-
-static const char *end_capture (MatchState *ms, const char *s,
- const char *p) {
- int l = capture_to_close(ms);
- const char *res;
- ms->capture[l].len = s - ms->capture[l].init; /* close capture */
- if ((res = match(ms, s, p)) == NULL) /* match failed? */
- ms->capture[l].len = CAP_UNFINISHED; /* undo capture */
- return res;
-}
-
-
-static const char *match_capture (MatchState *ms, const char *s, int l) {
- size_t len;
- l = check_capture(ms, l);
- len = ms->capture[l].len;
- if ((size_t)(ms->src_end-s) >= len &&
- memcmp(ms->capture[l].init, s, len) == 0)
- return s+len;
- else return NULL;
-}
-
-
-static const char *match (MatchState *ms, const char *s, const char *p) {
- init: /* using goto's to optimize tail recursion */
- switch (*p) {
- case '(': { /* start capture */
- if (*(p+1) == ')') /* position capture? */
- return start_capture(ms, s, p+2, CAP_POSITION);
- else
- return start_capture(ms, s, p+1, CAP_UNFINISHED);
- }
- case ')': { /* end capture */
- return end_capture(ms, s, p+1);
- }
- case L_ESC: {
- switch (*(p+1)) {
- case 'b': { /* balanced string? */
- s = matchbalance(ms, s, p+2);
- if (s == NULL) return NULL;
- p+=4; goto init; /* else return match(ms, s, p+4); */
- }
- case 'f': { /* frontier? */
- const char *ep; char previous;
- p += 2;
- if (*p != '[')
- luaL_error(ms->L, "missing " LUA_QL("[") " after "
- LUA_QL("%%f") " in pattern");
- ep = classend(ms, p); /* points to what is next */
- previous = (s == ms->src_init) ? '\0' : *(s-1);
- if (matchbracketclass(uchar(previous), p, ep-1) ||
- !matchbracketclass(uchar(*s), p, ep-1)) return NULL;
- p=ep; goto init; /* else return match(ms, s, ep); */
- }
- default: {
- if (isdigit(uchar(*(p+1)))) { /* capture results (%0-%9)? */
- s = match_capture(ms, s, uchar(*(p+1)));
- if (s == NULL) return NULL;
- p+=2; goto init; /* else return match(ms, s, p+2) */
- }
- goto dflt; /* case default */
- }
- }
- }
- case '\0': { /* end of pattern */
- return s; /* match succeeded */
- }
- case '$': {
- if (*(p+1) == '\0') /* is the `$' the last char in pattern? */
- return (s == ms->src_end) ? s : NULL; /* check end of string */
- else goto dflt;
- }
- default: dflt: { /* it is a pattern item */
- const char *ep = classend(ms, p); /* points to what is next */
- int m = s<ms->src_end && singlematch(uchar(*s), p, ep);
- switch (*ep) {
- case '?': { /* optional */
- const char *res;
- if (m && ((res=match(ms, s+1, ep+1)) != NULL))
- return res;
- p=ep+1; goto init; /* else return match(ms, s, ep+1); */
- }
- case '*': { /* 0 or more repetitions */
- return max_expand(ms, s, p, ep);
- }
- case '+': { /* 1 or more repetitions */
- return (m ? max_expand(ms, s+1, p, ep) : NULL);
- }
- case '-': { /* 0 or more repetitions (minimum) */
- return min_expand(ms, s, p, ep);
- }
- default: {
- if (!m) return NULL;
- s++; p=ep; goto init; /* else return match(ms, s+1, ep); */
- }
- }
- }
- }
-}
-
-
-
-static const char *lmemfind (const char *s1, size_t l1,
- const char *s2, size_t l2) {
- if (l2 == 0) return s1; /* empty strings are everywhere */
- else if (l2 > l1) return NULL; /* avoids a negative `l1' */
- else {
- const char *init; /* to search for a `*s2' inside `s1' */
- l2--; /* 1st char will be checked by `memchr' */
- l1 = l1-l2; /* `s2' cannot be found after that */
- while (l1 > 0 && (init = (const char *)memchr(s1, *s2, l1)) != NULL) {
- init++; /* 1st char is already checked */
- if (memcmp(init, s2+1, l2) == 0)
- return init-1;
- else { /* correct `l1' and `s1' to try again */
- l1 -= init-s1;
- s1 = init;
- }
- }
- return NULL; /* not found */
- }
-}
-
-
-static void push_onecapture (MatchState *ms, int i, const char *s,
- const char *e) {
- if (i >= ms->level) {
- if (i == 0) /* ms->level == 0, too */
- lua_pushlstring(ms->L, s, e - s); /* add whole match */
- else
- luaL_error(ms->L, "invalid capture index");
- }
- else {
- ptrdiff_t l = ms->capture[i].len;
- if (l == CAP_UNFINISHED) luaL_error(ms->L, "unfinished capture");
- if (l == CAP_POSITION)
- lua_pushinteger(ms->L, ms->capture[i].init - ms->src_init + 1);
- else
- lua_pushlstring(ms->L, ms->capture[i].init, l);
- }
-}
-
-
-static int push_captures (MatchState *ms, const char *s, const char *e) {
- int i;
- int nlevels = (ms->level == 0 && s) ? 1 : ms->level;
- luaL_checkstack(ms->L, nlevels, "too many captures");
- for (i = 0; i < nlevels; i++)
- push_onecapture(ms, i, s, e);
- return nlevels; /* number of strings pushed */
-}
-
-
-static int str_find_aux (lua_State *L, int find) {
- size_t l1, l2;
- const char *s = luaL_checklstring(L, 1, &l1);
- const char *p = luaL_checklstring(L, 2, &l2);
- ptrdiff_t init = posrelat(luaL_optinteger(L, 3, 1), l1) - 1;
- if (init < 0) init = 0;
- else if ((size_t)(init) > l1) init = (ptrdiff_t)l1;
- if (find && (lua_toboolean(L, 4) || /* explicit request? */
- strpbrk(p, SPECIALS) == NULL)) { /* or no special characters? */
- /* do a plain search */
- const char *s2 = lmemfind(s+init, l1-init, p, l2);
- if (s2) {
- lua_pushinteger(L, s2-s+1);
- lua_pushinteger(L, s2-s+l2);
- return 2;
- }
- }
- else {
- MatchState ms;
- int anchor = (*p == '^') ? (p++, 1) : 0;
- const char *s1=s+init;
- ms.L = L;
- ms.src_init = s;
- ms.src_end = s+l1;
- do {
- const char *res;
- ms.level = 0;
- if ((res=match(&ms, s1, p)) != NULL) {
- if (find) {
- lua_pushinteger(L, s1-s+1); /* start */
- lua_pushinteger(L, res-s); /* end */
- return push_captures(&ms, NULL, 0) + 2;
- }
- else
- return push_captures(&ms, s1, res);
- }
- } while (s1++ < ms.src_end && !anchor);
- }
- lua_pushnil(L); /* not found */
- return 1;
-}
-
-
-static int str_find (lua_State *L) {
- return str_find_aux(L, 1);
-}
-
-
-static int str_match (lua_State *L) {
- return str_find_aux(L, 0);
-}
-
-
-static int gmatch_aux (lua_State *L) {
- MatchState ms;
- size_t ls;
- const char *s = lua_tolstring(L, lua_upvalueindex(1), &ls);
- const char *p = lua_tostring(L, lua_upvalueindex(2));
- const char *src;
- ms.L = L;
- ms.src_init = s;
- ms.src_end = s+ls;
- for (src = s + (size_t)lua_tointeger(L, lua_upvalueindex(3));
- src <= ms.src_end;
- src++) {
- const char *e;
- ms.level = 0;
- if ((e = match(&ms, src, p)) != NULL) {
- lua_Integer newstart = e-s;
- if (e == src) newstart++; /* empty match? go at least one position */
- lua_pushinteger(L, newstart);
- lua_replace(L, lua_upvalueindex(3));
- return push_captures(&ms, src, e);
- }
- }
- return 0; /* not found */
-}
-
-
-static int gmatch (lua_State *L) {
- luaL_checkstring(L, 1);
- luaL_checkstring(L, 2);
- lua_settop(L, 2);
- lua_pushinteger(L, 0);
- lua_pushcclosure(L, gmatch_aux, 3);
- return 1;
-}
-
-
-static int gfind_nodef (lua_State *L) {
- return luaL_error(L, LUA_QL("string.gfind") " was renamed to "
- LUA_QL("string.gmatch"));
-}
-
-
-static void add_s (MatchState *ms, luaL_Buffer *b, const char *s,
- const char *e) {
- size_t l, i;
- const char *news = lua_tolstring(ms->L, 3, &l);
- for (i = 0; i < l; i++) {
- if (news[i] != L_ESC)
- luaL_addchar(b, news[i]);
- else {
- i++; /* skip ESC */
- if (!isdigit(uchar(news[i])))
- luaL_addchar(b, news[i]);
- else if (news[i] == '0')
- luaL_addlstring(b, s, e - s);
- else {
- push_onecapture(ms, news[i] - '1', s, e);
- luaL_addvalue(b); /* add capture to accumulated result */
- }
- }
- }
-}
-
-
-static void add_value (MatchState *ms, luaL_Buffer *b, const char *s,
- const char *e) {
- lua_State *L = ms->L;
- switch (lua_type(L, 3)) {
- case LUA_TNUMBER:
- case LUA_TSTRING: {
- add_s(ms, b, s, e);
- return;
- }
- case LUA_TFUNCTION: {
- int n;
- lua_pushvalue(L, 3);
- n = push_captures(ms, s, e);
- lua_call(L, n, 1);
- break;
- }
- case LUA_TTABLE: {
- push_onecapture(ms, 0, s, e);
- lua_gettable(L, 3);
- break;
- }
- }
- if (!lua_toboolean(L, -1)) { /* nil or false? */
- lua_pop(L, 1);
- lua_pushlstring(L, s, e - s); /* keep original text */
- }
- else if (!lua_isstring(L, -1))
- luaL_error(L, "invalid replacement value (a %s)", luaL_typename(L, -1));
- luaL_addvalue(b); /* add result to accumulator */
-}
-
-
-static int str_gsub (lua_State *L) {
- size_t srcl;
- const char *src = luaL_checklstring(L, 1, &srcl);
- const char *p = luaL_checkstring(L, 2);
- int tr = lua_type(L, 3);
- int max_s = luaL_optint(L, 4, srcl+1);
- int anchor = (*p == '^') ? (p++, 1) : 0;
- int n = 0;
- MatchState ms;
- luaL_Buffer b;
- luaL_argcheck(L, tr == LUA_TNUMBER || tr == LUA_TSTRING ||
- tr == LUA_TFUNCTION || tr == LUA_TTABLE, 3,
- "string/function/table expected");
- luaL_buffinit(L, &b);
- ms.L = L;
- ms.src_init = src;
- ms.src_end = src+srcl;
- while (n < max_s) {
- const char *e;
- ms.level = 0;
- e = match(&ms, src, p);
- if (e) {
- n++;
- add_value(&ms, &b, src, e);
- }
- if (e && e>src) /* non empty match? */
- src = e; /* skip it */
- else if (src < ms.src_end)
- luaL_addchar(&b, *src++);
- else break;
- if (anchor) break;
- }
- luaL_addlstring(&b, src, ms.src_end-src);
- luaL_pushresult(&b);
- lua_pushinteger(L, n); /* number of substitutions */
- return 2;
-}
-
-/* }====================================================== */
-
-
-/* maximum size of each formatted item (> len(format('%99.99f', -1e308))) */
-#define MAX_ITEM 512
-/* valid flags in a format specification */
-#define FLAGS "-+ #0"
-/*
-** maximum size of each format specification (such as '%-099.99d')
-** (+10 accounts for %99.99x plus margin of error)
-*/
-#define MAX_FORMAT (sizeof(FLAGS) + sizeof(LUA_INTFRMLEN) + 10)
-
-
-static void addquoted (lua_State *L, luaL_Buffer *b, int arg) {
- size_t l;
- const char *s = luaL_checklstring(L, arg, &l);
- luaL_addchar(b, '"');
- while (l--) {
- switch (*s) {
- case '"': case '\\': case '\n': {
- luaL_addchar(b, '\\');
- luaL_addchar(b, *s);
- break;
- }
- case '\r': {
- luaL_addlstring(b, "\\r", 2);
- break;
- }
- case '\0': {
- luaL_addlstring(b, "\\000", 4);
- break;
- }
- default: {
- luaL_addchar(b, *s);
- break;
- }
- }
- s++;
- }
- luaL_addchar(b, '"');
-}
-
-static const char *scanformat (lua_State *L, const char *strfrmt, char *form) {
- const char *p = strfrmt;
- while (*p != '\0' && strchr(FLAGS, *p) != NULL) p++; /* skip flags */
- if ((size_t)(p - strfrmt) >= sizeof(FLAGS))
- luaL_error(L, "invalid format (repeated flags)");
- if (isdigit(uchar(*p))) p++; /* skip width */
- if (isdigit(uchar(*p))) p++; /* (2 digits at most) */
- if (*p == '.') {
- p++;
- if (isdigit(uchar(*p))) p++; /* skip precision */
- if (isdigit(uchar(*p))) p++; /* (2 digits at most) */
- }
- if (isdigit(uchar(*p)))
- luaL_error(L, "invalid format (width or precision too long)");
- *(form++) = '%';
- strncpy(form, strfrmt, p - strfrmt + 1);
- form += p - strfrmt + 1;
- *form = '\0';
- return p;
-}
-
-
-static void addintlen (char *form) {
- size_t l = strlen(form);
- char spec = form[l - 1];
- strcpy(form + l - 1, LUA_INTFRMLEN);
- form[l + sizeof(LUA_INTFRMLEN) - 2] = spec;
- form[l + sizeof(LUA_INTFRMLEN) - 1] = '\0';
-}
-
-
-static int str_format (lua_State *L) {
- int arg = 1;
- size_t sfl;
- const char *strfrmt = luaL_checklstring(L, arg, &sfl);
- const char *strfrmt_end = strfrmt+sfl;
- luaL_Buffer b;
- luaL_buffinit(L, &b);
- while (strfrmt < strfrmt_end) {
- if (*strfrmt != L_ESC)
- luaL_addchar(&b, *strfrmt++);
- else if (*++strfrmt == L_ESC)
- luaL_addchar(&b, *strfrmt++); /* %% */
- else { /* format item */
- char form[MAX_FORMAT]; /* to store the format (`%...') */
- char buff[MAX_ITEM]; /* to store the formatted item */
- arg++;
- strfrmt = scanformat(L, strfrmt, form);
- switch (*strfrmt++) {
- case 'c': {
- sprintf(buff, form, (int)luaL_checknumber(L, arg));
- break;
- }
- case 'd': case 'i': {
- addintlen(form);
- sprintf(buff, form, (LUA_INTFRM_T)luaL_checknumber(L, arg));
- break;
- }
- case 'o': case 'u': case 'x': case 'X': {
- addintlen(form);
- sprintf(buff, form, (unsigned LUA_INTFRM_T)luaL_checknumber(L, arg));
- break;
- }
- case 'e': case 'E': case 'f':
- case 'g': case 'G': {
- sprintf(buff, form, (double)luaL_checknumber(L, arg));
- break;
- }
- case 'q': {
- addquoted(L, &b, arg);
- continue; /* skip the 'addsize' at the end */
- }
- case 's': {
- size_t l;
- const char *s = luaL_checklstring(L, arg, &l);
- if (!strchr(form, '.') && l >= 100) {
- /* no precision and string is too long to be formatted;
- keep original string */
- lua_pushvalue(L, arg);
- luaL_addvalue(&b);
- continue; /* skip the `addsize' at the end */
- }
- else {
- sprintf(buff, form, s);
- break;
- }
- }
- default: { /* also treat cases `pnLlh' */
- return luaL_error(L, "invalid option " LUA_QL("%%%c") " to "
- LUA_QL("format"), *(strfrmt - 1));
- }
- }
- luaL_addlstring(&b, buff, strlen(buff));
- }
- }
- luaL_pushresult(&b);
- return 1;
-}
-
-
-static const luaL_Reg strlib[] = {
- {"byte", str_byte},
- {"char", str_char},
- {"dump", str_dump},
- {"find", str_find},
- {"format", str_format},
- {"gfind", gfind_nodef},
- {"gmatch", gmatch},
- {"gsub", str_gsub},
- {"len", str_len},
- {"lower", str_lower},
- {"match", str_match},
- {"rep", str_rep},
- {"reverse", str_reverse},
- {"sub", str_sub},
- {"upper", str_upper},
- {NULL, NULL}
-};
-
-
-static void createmetatable (lua_State *L) {
- lua_createtable(L, 0, 1); /* create metatable for strings */
- lua_pushliteral(L, ""); /* dummy string */
- lua_pushvalue(L, -2);
- lua_setmetatable(L, -2); /* set string metatable */
- lua_pop(L, 1); /* pop dummy string */
- lua_pushvalue(L, -2); /* string library... */
- lua_setfield(L, -2, "__index"); /* ...is the __index metamethod */
- lua_pop(L, 1); /* pop metatable */
-}
-
-
-/*
-** Open string library
-*/
-LUALIB_API int luaopen_string (lua_State *L) {
- luaL_register(L, LUA_STRLIBNAME, strlib);
-#if defined(LUA_COMPAT_GFIND)
- lua_getfield(L, -1, "gmatch");
- lua_setfield(L, -2, "gfind");
-#endif
- createmetatable(L);
- return 1;
-}
-
diff --git a/crawl-ref/source/util/lua/src/ltable.c b/crawl-ref/source/util/lua/src/ltable.c
deleted file mode 100644
index ec84f4fabc..0000000000
--- a/crawl-ref/source/util/lua/src/ltable.c
+++ /dev/null
@@ -1,588 +0,0 @@
-/*
-** $Id: ltable.c,v 2.32.1.2 2007/12/28 15:32:23 roberto Exp $
-** Lua tables (hash)
-** See Copyright Notice in lua.h
-*/
-
-
-/*
-** Implementation of tables (aka arrays, objects, or hash tables).
-** Tables keep its elements in two parts: an array part and a hash part.
-** Non-negative integer keys are all candidates to be kept in the array
-** part. The actual size of the array is the largest `n' such that at
-** least half the slots between 0 and n are in use.
-** Hash uses a mix of chained scatter table with Brent's variation.
-** A main invariant of these tables is that, if an element is not
-** in its main position (i.e. the `original' position that its hash gives
-** to it), then the colliding element is in its own main position.
-** Hence even when the load factor reaches 100%, performance remains good.
-*/
-
-#include <math.h>
-#include <string.h>
-
-#define ltable_c
-#define LUA_CORE
-
-#include "lua.h"
-
-#include "ldebug.h"
-#include "ldo.h"
-#include "lgc.h"
-#include "lmem.h"
-#include "lobject.h"
-#include "lstate.h"
-#include "ltable.h"
-
-
-/*
-** max size of array part is 2^MAXBITS
-*/
-#if LUAI_BITSINT > 26
-#define MAXBITS 26
-#else
-#define MAXBITS (LUAI_BITSINT-2)
-#endif
-
-#define MAXASIZE (1 << MAXBITS)
-
-
-#define hashpow2(t,n) (gnode(t, lmod((n), sizenode(t))))
-
-#define hashstr(t,str) hashpow2(t, (str)->tsv.hash)
-#define hashboolean(t,p) hashpow2(t, p)
-
-
-/*
-** for some types, it is better to avoid modulus by power of 2, as
-** they tend to have many 2 factors.
-*/
-#define hashmod(t,n) (gnode(t, ((n) % ((sizenode(t)-1)|1))))
-
-
-#define hashpointer(t,p) hashmod(t, IntPoint(p))
-
-
-/*
-** number of ints inside a lua_Number
-*/
-#define numints cast_int(sizeof(lua_Number)/sizeof(int))
-
-
-
-#define dummynode (&dummynode_)
-
-static const Node dummynode_ = {
- {{NULL}, LUA_TNIL}, /* value */
- {{{NULL}, LUA_TNIL, NULL}} /* key */
-};
-
-
-/*
-** hash for lua_Numbers
-*/
-static Node *hashnum (const Table *t, lua_Number n) {
- unsigned int a[numints];
- int i;
- if (luai_numeq(n, 0)) /* avoid problems with -0 */
- return gnode(t, 0);
- memcpy(a, &n, sizeof(a));
- for (i = 1; i < numints; i++) a[0] += a[i];
- return hashmod(t, a[0]);
-}
-
-
-
-/*
-** returns the `main' position of an element in a table (that is, the index
-** of its hash value)
-*/
-static Node *mainposition (const Table *t, const TValue *key) {
- switch (ttype(key)) {
- case LUA_TNUMBER:
- return hashnum(t, nvalue(key));
- case LUA_TSTRING:
- return hashstr(t, rawtsvalue(key));
- case LUA_TBOOLEAN:
- return hashboolean(t, bvalue(key));
- case LUA_TLIGHTUSERDATA:
- return hashpointer(t, pvalue(key));
- default:
- return hashpointer(t, gcvalue(key));
- }
-}
-
-
-/*
-** returns the index for `key' if `key' is an appropriate key to live in
-** the array part of the table, -1 otherwise.
-*/
-static int arrayindex (const TValue *key) {
- if (ttisnumber(key)) {
- lua_Number n = nvalue(key);
- int k;
- lua_number2int(k, n);
- if (luai_numeq(cast_num(k), n))
- return k;
- }
- return -1; /* `key' did not match some condition */
-}
-
-
-/*
-** returns the index of a `key' for table traversals. First goes all
-** elements in the array part, then elements in the hash part. The
-** beginning of a traversal is signalled by -1.
-*/
-static int findindex (lua_State *L, Table *t, StkId key) {
- int i;
- if (ttisnil(key)) return -1; /* first iteration */
- i = arrayindex(key);
- if (0 < i && i <= t->sizearray) /* is `key' inside array part? */
- return i-1; /* yes; that's the index (corrected to C) */
- else {
- Node *n = mainposition(t, key);
- do { /* check whether `key' is somewhere in the chain */
- /* key may be dead already, but it is ok to use it in `next' */
- if (luaO_rawequalObj(key2tval(n), key) ||
- (ttype(gkey(n)) == LUA_TDEADKEY && iscollectable(key) &&
- gcvalue(gkey(n)) == gcvalue(key))) {
- i = cast_int(n - gnode(t, 0)); /* key index in hash table */
- /* hash elements are numbered after array ones */
- return i + t->sizearray;
- }
- else n = gnext(n);
- } while (n);
- luaG_runerror(L, "invalid key to " LUA_QL("next")); /* key not found */
- return 0; /* to avoid warnings */
- }
-}
-
-
-int luaH_next (lua_State *L, Table *t, StkId key) {
- int i = findindex(L, t, key); /* find original element */
- for (i++; i < t->sizearray; i++) { /* try first array part */
- if (!ttisnil(&t->array[i])) { /* a non-nil value? */
- setnvalue(key, cast_num(i+1));
- setobj2s(L, key+1, &t->array[i]);
- return 1;
- }
- }
- for (i -= t->sizearray; i < sizenode(t); i++) { /* then hash part */
- if (!ttisnil(gval(gnode(t, i)))) { /* a non-nil value? */
- setobj2s(L, key, key2tval(gnode(t, i)));
- setobj2s(L, key+1, gval(gnode(t, i)));
- return 1;
- }
- }
- return 0; /* no more elements */
-}
-
-
-/*
-** {=============================================================
-** Rehash
-** ==============================================================
-*/
-
-
-static int computesizes (int nums[], int *narray) {
- int i;
- int twotoi; /* 2^i */
- int a = 0; /* number of elements smaller than 2^i */
- int na = 0; /* number of elements to go to array part */
- int n = 0; /* optimal size for array part */
- for (i = 0, twotoi = 1; twotoi/2 < *narray; i++, twotoi *= 2) {
- if (nums[i] > 0) {
- a += nums[i];
- if (a > twotoi/2) { /* more than half elements present? */
- n = twotoi; /* optimal size (till now) */
- na = a; /* all elements smaller than n will go to array part */
- }
- }
- if (a == *narray) break; /* all elements already counted */
- }
- *narray = n;
- lua_assert(*narray/2 <= na && na <= *narray);
- return na;
-}
-
-
-static int countint (const TValue *key, int *nums) {
- int k = arrayindex(key);
- if (0 < k && k <= MAXASIZE) { /* is `key' an appropriate array index? */
- nums[ceillog2(k)]++; /* count as such */
- return 1;
- }
- else
- return 0;
-}
-
-
-static int numusearray (const Table *t, int *nums) {
- int lg;
- int ttlg; /* 2^lg */
- int ause = 0; /* summation of `nums' */
- int i = 1; /* count to traverse all array keys */
- for (lg=0, ttlg=1; lg<=MAXBITS; lg++, ttlg*=2) { /* for each slice */
- int lc = 0; /* counter */
- int lim = ttlg;
- if (lim > t->sizearray) {
- lim = t->sizearray; /* adjust upper limit */
- if (i > lim)
- break; /* no more elements to count */
- }
- /* count elements in range (2^(lg-1), 2^lg] */
- for (; i <= lim; i++) {
- if (!ttisnil(&t->array[i-1]))
- lc++;
- }
- nums[lg] += lc;
- ause += lc;
- }
- return ause;
-}
-
-
-static int numusehash (const Table *t, int *nums, int *pnasize) {
- int totaluse = 0; /* total number of elements */
- int ause = 0; /* summation of `nums' */
- int i = sizenode(t);
- while (i--) {
- Node *n = &t->node[i];
- if (!ttisnil(gval(n))) {
- ause += countint(key2tval(n), nums);
- totaluse++;
- }
- }
- *pnasize += ause;
- return totaluse;
-}
-
-
-static void setarrayvector (lua_State *L, Table *t, int size) {
- int i;
- luaM_reallocvector(L, t->array, t->sizearray, size, TValue);
- for (i=t->sizearray; i<size; i++)
- setnilvalue(&t->array[i]);
- t->sizearray = size;
-}
-
-
-static void setnodevector (lua_State *L, Table *t, int size) {
- int lsize;
- if (size == 0) { /* no elements to hash part? */
- t->node = cast(Node *, dummynode); /* use common `dummynode' */
- lsize = 0;
- }
- else {
- int i;
- lsize = ceillog2(size);
- if (lsize > MAXBITS)
- luaG_runerror(L, "table overflow");
- size = twoto(lsize);
- t->node = luaM_newvector(L, size, Node);
- for (i=0; i<size; i++) {
- Node *n = gnode(t, i);
- gnext(n) = NULL;
- setnilvalue(gkey(n));
- setnilvalue(gval(n));
- }
- }
- t->lsizenode = cast_byte(lsize);
- t->lastfree = gnode(t, size); /* all positions are free */
-}
-
-
-static void resize (lua_State *L, Table *t, int nasize, int nhsize) {
- int i;
- int oldasize = t->sizearray;
- int oldhsize = t->lsizenode;
- Node *nold = t->node; /* save old hash ... */
- if (nasize > oldasize) /* array part must grow? */
- setarrayvector(L, t, nasize);
- /* create new hash part with appropriate size */
- setnodevector(L, t, nhsize);
- if (nasize < oldasize) { /* array part must shrink? */
- t->sizearray = nasize;
- /* re-insert elements from vanishing slice */
- for (i=nasize; i<oldasize; i++) {
- if (!ttisnil(&t->array[i]))
- setobjt2t(L, luaH_setnum(L, t, i+1), &t->array[i]);
- }
- /* shrink array */
- luaM_reallocvector(L, t->array, oldasize, nasize, TValue);
- }
- /* re-insert elements from hash part */
- for (i = twoto(oldhsize) - 1; i >= 0; i--) {
- Node *old = nold+i;
- if (!ttisnil(gval(old)))
- setobjt2t(L, luaH_set(L, t, key2tval(old)), gval(old));
- }
- if (nold != dummynode)
- luaM_freearray(L, nold, twoto(oldhsize), Node); /* free old array */
-}
-
-
-void luaH_resizearray (lua_State *L, Table *t, int nasize) {
- int nsize = (t->node == dummynode) ? 0 : sizenode(t);
- resize(L, t, nasize, nsize);
-}
-
-
-static void rehash (lua_State *L, Table *t, const TValue *ek) {
- int nasize, na;
- int nums[MAXBITS+1]; /* nums[i] = number of keys between 2^(i-1) and 2^i */
- int i;
- int totaluse;
- for (i=0; i<=MAXBITS; i++) nums[i] = 0; /* reset counts */
- nasize = numusearray(t, nums); /* count keys in array part */
- totaluse = nasize; /* all those keys are integer keys */
- totaluse += numusehash(t, nums, &nasize); /* count keys in hash part */
- /* count extra key */
- nasize += countint(ek, nums);
- totaluse++;
- /* compute new size for array part */
- na = computesizes(nums, &nasize);
- /* resize the table to new computed sizes */
- resize(L, t, nasize, totaluse - na);
-}
-
-
-
-/*
-** }=============================================================
-*/
-
-
-Table *luaH_new (lua_State *L, int narray, int nhash) {
- Table *t = luaM_new(L, Table);
- luaC_link(L, obj2gco(t), LUA_TTABLE);
- t->metatable = NULL;
- t->flags = cast_byte(~0);
- /* temporary values (kept only if some malloc fails) */
- t->array = NULL;
- t->sizearray = 0;
- t->lsizenode = 0;
- t->node = cast(Node *, dummynode);
- setarrayvector(L, t, narray);
- setnodevector(L, t, nhash);
- return t;
-}
-
-
-void luaH_free (lua_State *L, Table *t) {
- if (t->node != dummynode)
- luaM_freearray(L, t->node, sizenode(t), Node);
- luaM_freearray(L, t->array, t->sizearray, TValue);
- luaM_free(L, t);
-}
-
-
-static Node *getfreepos (Table *t) {
- while (t->lastfree-- > t->node) {
- if (ttisnil(gkey(t->lastfree)))
- return t->lastfree;
- }
- return NULL; /* could not find a free place */
-}
-
-
-
-/*
-** inserts a new key into a hash table; first, check whether key's main
-** position is free. If not, check whether colliding node is in its main
-** position or not: if it is not, move colliding node to an empty place and
-** put new key in its main position; otherwise (colliding node is in its main
-** position), new key goes to an empty position.
-*/
-static TValue *newkey (lua_State *L, Table *t, const TValue *key) {
- Node *mp = mainposition(t, key);
- if (!ttisnil(gval(mp)) || mp == dummynode) {
- Node *othern;
- Node *n = getfreepos(t); /* get a free place */
- if (n == NULL) { /* cannot find a free place? */
- rehash(L, t, key); /* grow table */
- return luaH_set(L, t, key); /* re-insert key into grown table */
- }
- lua_assert(n != dummynode);
- othern = mainposition(t, key2tval(mp));
- if (othern != mp) { /* is colliding node out of its main position? */
- /* yes; move colliding node into free position */
- while (gnext(othern) != mp) othern = gnext(othern); /* find previous */
- gnext(othern) = n; /* redo the chain with `n' in place of `mp' */
- *n = *mp; /* copy colliding node into free pos. (mp->next also goes) */
- gnext(mp) = NULL; /* now `mp' is free */
- setnilvalue(gval(mp));
- }
- else { /* colliding node is in its own main position */
- /* new node will go into free position */
- gnext(n) = gnext(mp); /* chain new position */
- gnext(mp) = n;
- mp = n;
- }
- }
- gkey(mp)->value = key->value; gkey(mp)->tt = key->tt;
- luaC_barriert(L, t, key);
- lua_assert(ttisnil(gval(mp)));
- return gval(mp);
-}
-
-
-/*
-** search function for integers
-*/
-const TValue *luaH_getnum (Table *t, int key) {
- /* (1 <= key && key <= t->sizearray) */
- if (cast(unsigned int, key-1) < cast(unsigned int, t->sizearray))
- return &t->array[key-1];
- else {
- lua_Number nk = cast_num(key);
- Node *n = hashnum(t, nk);
- do { /* check whether `key' is somewhere in the chain */
- if (ttisnumber(gkey(n)) && luai_numeq(nvalue(gkey(n)), nk))
- return gval(n); /* that's it */
- else n = gnext(n);
- } while (n);
- return luaO_nilobject;
- }
-}
-
-
-/*
-** search function for strings
-*/
-const TValue *luaH_getstr (Table *t, TString *key) {
- Node *n = hashstr(t, key);
- do { /* check whether `key' is somewhere in the chain */
- if (ttisstring(gkey(n)) && rawtsvalue(gkey(n)) == key)
- return gval(n); /* that's it */
- else n = gnext(n);
- } while (n);
- return luaO_nilobject;
-}
-
-
-/*
-** main search function
-*/
-const TValue *luaH_get (Table *t, const TValue *key) {
- switch (ttype(key)) {
- case LUA_TNIL: return luaO_nilobject;
- case LUA_TSTRING: return luaH_getstr(t, rawtsvalue(key));
- case LUA_TNUMBER: {
- int k;
- lua_Number n = nvalue(key);
- lua_number2int(k, n);
- if (luai_numeq(cast_num(k), nvalue(key))) /* index is int? */
- return luaH_getnum(t, k); /* use specialized version */
- /* else go through */
- }
- default: {
- Node *n = mainposition(t, key);
- do { /* check whether `key' is somewhere in the chain */
- if (luaO_rawequalObj(key2tval(n), key))
- return gval(n); /* that's it */
- else n = gnext(n);
- } while (n);
- return luaO_nilobject;
- }
- }
-}
-
-
-TValue *luaH_set (lua_State *L, Table *t, const TValue *key) {
- const TValue *p = luaH_get(t, key);
- t->flags = 0;
- if (p != luaO_nilobject)
- return cast(TValue *, p);
- else {
- if (ttisnil(key)) luaG_runerror(L, "table index is nil");
- else if (ttisnumber(key) && luai_numisnan(nvalue(key)))
- luaG_runerror(L, "table index is NaN");
- return newkey(L, t, key);
- }
-}
-
-
-TValue *luaH_setnum (lua_State *L, Table *t, int key) {
- const TValue *p = luaH_getnum(t, key);
- if (p != luaO_nilobject)
- return cast(TValue *, p);
- else {
- TValue k;
- setnvalue(&k, cast_num(key));
- return newkey(L, t, &k);
- }
-}
-
-
-TValue *luaH_setstr (lua_State *L, Table *t, TString *key) {
- const TValue *p = luaH_getstr(t, key);
- if (p != luaO_nilobject)
- return cast(TValue *, p);
- else {
- TValue k;
- setsvalue(L, &k, key);
- return newkey(L, t, &k);
- }
-}
-
-
-static int unbound_search (Table *t, unsigned int j) {
- unsigned int i = j; /* i is zero or a present index */
- j++;
- /* find `i' and `j' such that i is present and j is not */
- while (!ttisnil(luaH_getnum(t, j))) {
- i = j;
- j *= 2;
- if (j > cast(unsigned int, MAX_INT)) { /* overflow? */
- /* table was built with bad purposes: resort to linear search */
- i = 1;
- while (!ttisnil(luaH_getnum(t, i))) i++;
- return i - 1;
- }
- }
- /* now do a binary search between them */
- while (j - i > 1) {
- unsigned int m = (i+j)/2;
- if (ttisnil(luaH_getnum(t, m))) j = m;
- else i = m;
- }
- return i;
-}
-
-
-/*
-** Try to find a boundary in table `t'. A `boundary' is an integer index
-** such that t[i] is non-nil and t[i+1] is nil (and 0 if t[1] is nil).
-*/
-int luaH_getn (Table *t) {
- unsigned int j = t->sizearray;
- if (j > 0 && ttisnil(&t->array[j - 1])) {
- /* there is a boundary in the array part: (binary) search for it */
- unsigned int i = 0;
- while (j - i > 1) {
- unsigned int m = (i+j)/2;
- if (ttisnil(&t->array[m - 1])) j = m;
- else i = m;
- }
- return i;
- }
- /* else must find a boundary in hash part */
- else if (t->node == dummynode) /* hash part is empty? */
- return j; /* that is easy... */
- else return unbound_search(t, j);
-}
-
-
-
-#if defined(LUA_DEBUG)
-
-Node *luaH_mainposition (const Table *t, const TValue *key) {
- return mainposition(t, key);
-}
-
-int luaH_isdummy (Node *n) { return n == dummynode; }
-
-#endif
diff --git a/crawl-ref/source/util/lua/src/ltable.h b/crawl-ref/source/util/lua/src/ltable.h
deleted file mode 100644
index f5b9d5ead0..0000000000
--- a/crawl-ref/source/util/lua/src/ltable.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
-** $Id: ltable.h,v 2.10.1.1 2007/12/27 13:02:25 roberto Exp $
-** Lua tables (hash)
-** See Copyright Notice in lua.h
-*/
-
-#ifndef ltable_h
-#define ltable_h
-
-#include "lobject.h"
-
-
-#define gnode(t,i) (&(t)->node[i])
-#define gkey(n) (&(n)->i_key.nk)
-#define gval(n) (&(n)->i_val)
-#define gnext(n) ((n)->i_key.nk.next)
-
-#define key2tval(n) (&(n)->i_key.tvk)
-
-
-LUAI_FUNC const TValue *luaH_getnum (Table *t, int key);
-LUAI_FUNC TValue *luaH_setnum (lua_State *L, Table *t, int key);
-LUAI_FUNC const TValue *luaH_getstr (Table *t, TString *key);
-LUAI_FUNC TValue *luaH_setstr (lua_State *L, Table *t, TString *key);
-LUAI_FUNC const TValue *luaH_get (Table *t, const TValue *key);
-LUAI_FUNC TValue *luaH_set (lua_State *L, Table *t, const TValue *key);
-LUAI_FUNC Table *luaH_new (lua_State *L, int narray, int lnhash);
-LUAI_FUNC void luaH_resizearray (lua_State *L, Table *t, int nasize);
-LUAI_FUNC void luaH_free (lua_State *L, Table *t);
-LUAI_FUNC int luaH_next (lua_State *L, Table *t, StkId key);
-LUAI_FUNC int luaH_getn (Table *t);
-
-
-#if defined(LUA_DEBUG)
-LUAI_FUNC Node *luaH_mainposition (const Table *t, const TValue *key);
-LUAI_FUNC int luaH_isdummy (Node *n);
-#endif
-
-
-#endif
diff --git a/crawl-ref/source/util/lua/src/ltablib.c b/crawl-ref/source/util/lua/src/ltablib.c
deleted file mode 100644
index b6d9cb4ac7..0000000000
--- a/crawl-ref/source/util/lua/src/ltablib.c
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
-** $Id: ltablib.c,v 1.38.1.3 2008/02/14 16:46:58 roberto Exp $
-** Library for Table Manipulation
-** See Copyright Notice in lua.h
-*/
-
-
-#include <stddef.h>
-
-#define ltablib_c
-#define LUA_LIB
-
-#include "lua.h"
-
-#include "lauxlib.h"
-#include "lualib.h"
-
-
-#define aux_getn(L,n) (luaL_checktype(L, n, LUA_TTABLE), luaL_getn(L, n))
-
-
-static int foreachi (lua_State *L) {
- int i;
- int n = aux_getn(L, 1);
- luaL_checktype(L, 2, LUA_TFUNCTION);
- for (i=1; i <= n; i++) {
- lua_pushvalue(L, 2); /* function */
- lua_pushinteger(L, i); /* 1st argument */
- lua_rawgeti(L, 1, i); /* 2nd argument */
- lua_call(L, 2, 1);
- if (!lua_isnil(L, -1))
- return 1;
- lua_pop(L, 1); /* remove nil result */
- }
- return 0;
-}
-
-
-static int foreach (lua_State *L) {
- luaL_checktype(L, 1, LUA_TTABLE);
- luaL_checktype(L, 2, LUA_TFUNCTION);
- lua_pushnil(L); /* first key */
- while (lua_next(L, 1)) {
- lua_pushvalue(L, 2); /* function */
- lua_pushvalue(L, -3); /* key */
- lua_pushvalue(L, -3); /* value */
- lua_call(L, 2, 1);
- if (!lua_isnil(L, -1))
- return 1;
- lua_pop(L, 2); /* remove value and result */
- }
- return 0;
-}
-
-
-static int maxn (lua_State *L) {
- lua_Number max = 0;
- luaL_checktype(L, 1, LUA_TTABLE);
- lua_pushnil(L); /* first key */
- while (lua_next(L, 1)) {
- lua_pop(L, 1); /* remove value */
- if (lua_type(L, -1) == LUA_TNUMBER) {
- lua_Number v = lua_tonumber(L, -1);
- if (v > max) max = v;
- }
- }
- lua_pushnumber(L, max);
- return 1;
-}
-
-
-static int getn (lua_State *L) {
- lua_pushinteger(L, aux_getn(L, 1));
- return 1;
-}
-
-
-static int setn (lua_State *L) {
- luaL_checktype(L, 1, LUA_TTABLE);
-#ifndef luaL_setn
- luaL_setn(L, 1, luaL_checkint(L, 2));
-#else
- luaL_error(L, LUA_QL("setn") " is obsolete");
-#endif
- lua_pushvalue(L, 1);
- return 1;
-}
-
-
-static int tinsert (lua_State *L) {
- int e = aux_getn(L, 1) + 1; /* first empty element */
- int pos; /* where to insert new element */
- switch (lua_gettop(L)) {
- case 2: { /* called with only 2 arguments */
- pos = e; /* insert new element at the end */
- break;
- }
- case 3: {
- int i;
- pos = luaL_checkint(L, 2); /* 2nd argument is the position */
- if (pos > e) e = pos; /* `grow' array if necessary */
- for (i = e; i > pos; i--) { /* move up elements */
- lua_rawgeti(L, 1, i-1);
- lua_rawseti(L, 1, i); /* t[i] = t[i-1] */
- }
- break;
- }
- default: {
- return luaL_error(L, "wrong number of arguments to " LUA_QL("insert"));
- }
- }
- luaL_setn(L, 1, e); /* new size */
- lua_rawseti(L, 1, pos); /* t[pos] = v */
- return 0;
-}
-
-
-static int tremove (lua_State *L) {
- int e = aux_getn(L, 1);
- int pos = luaL_optint(L, 2, e);
- if (!(1 <= pos && pos <= e)) /* position is outside bounds? */
- return 0; /* nothing to remove */
- luaL_setn(L, 1, e - 1); /* t.n = n-1 */
- lua_rawgeti(L, 1, pos); /* result = t[pos] */
- for ( ;pos<e; pos++) {
- lua_rawgeti(L, 1, pos+1);
- lua_rawseti(L, 1, pos); /* t[pos] = t[pos+1] */
- }
- lua_pushnil(L);
- lua_rawseti(L, 1, e); /* t[e] = nil */
- return 1;
-}
-
-
-static void addfield (lua_State *L, luaL_Buffer *b, int i) {
- lua_rawgeti(L, 1, i);
- if (!lua_isstring(L, -1))
- luaL_error(L, "invalid value (%s) at index %d in table for "
- LUA_QL("concat"), luaL_typename(L, -1), i);
- luaL_addvalue(b);
-}
-
-
-static int tconcat (lua_State *L) {
- luaL_Buffer b;
- size_t lsep;
- int i, last;
- const char *sep = luaL_optlstring(L, 2, "", &lsep);
- luaL_checktype(L, 1, LUA_TTABLE);
- i = luaL_optint(L, 3, 1);
- last = luaL_opt(L, luaL_checkint, 4, luaL_getn(L, 1));
- luaL_buffinit(L, &b);
- for (; i < last; i++) {
- addfield(L, &b, i);
- luaL_addlstring(&b, sep, lsep);
- }
- if (i == last) /* add last value (if interval was not empty) */
- addfield(L, &b, i);
- luaL_pushresult(&b);
- return 1;
-}
-
-
-
-/*
-** {======================================================
-** Quicksort
-** (based on `Algorithms in MODULA-3', Robert Sedgewick;
-** Addison-Wesley, 1993.)
-*/
-
-
-static void set2 (lua_State *L, int i, int j) {
- lua_rawseti(L, 1, i);
- lua_rawseti(L, 1, j);
-}
-
-static int sort_comp (lua_State *L, int a, int b) {
- if (!lua_isnil(L, 2)) { /* function? */
- int res;
- lua_pushvalue(L, 2);
- lua_pushvalue(L, a-1); /* -1 to compensate function */
- lua_pushvalue(L, b-2); /* -2 to compensate function and `a' */
- lua_call(L, 2, 1);
- res = lua_toboolean(L, -1);
- lua_pop(L, 1);
- return res;
- }
- else /* a < b? */
- return lua_lessthan(L, a, b);
-}
-
-static void auxsort (lua_State *L, int l, int u) {
- while (l < u) { /* for tail recursion */
- int i, j;
- /* sort elements a[l], a[(l+u)/2] and a[u] */
- lua_rawgeti(L, 1, l);
- lua_rawgeti(L, 1, u);
- if (sort_comp(L, -1, -2)) /* a[u] < a[l]? */
- set2(L, l, u); /* swap a[l] - a[u] */
- else
- lua_pop(L, 2);
- if (u-l == 1) break; /* only 2 elements */
- i = (l+u)/2;
- lua_rawgeti(L, 1, i);
- lua_rawgeti(L, 1, l);
- if (sort_comp(L, -2, -1)) /* a[i]<a[l]? */
- set2(L, i, l);
- else {
- lua_pop(L, 1); /* remove a[l] */
- lua_rawgeti(L, 1, u);
- if (sort_comp(L, -1, -2)) /* a[u]<a[i]? */
- set2(L, i, u);
- else
- lua_pop(L, 2);
- }
- if (u-l == 2) break; /* only 3 elements */
- lua_rawgeti(L, 1, i); /* Pivot */
- lua_pushvalue(L, -1);
- lua_rawgeti(L, 1, u-1);
- set2(L, i, u-1);
- /* a[l] <= P == a[u-1] <= a[u], only need to sort from l+1 to u-2 */
- i = l; j = u-1;
- for (;;) { /* invariant: a[l..i] <= P <= a[j..u] */
- /* repeat ++i until a[i] >= P */
- while (lua_rawgeti(L, 1, ++i), sort_comp(L, -1, -2)) {
- if (i>u) luaL_error(L, "invalid order function for sorting");
- lua_pop(L, 1); /* remove a[i] */
- }
- /* repeat --j until a[j] <= P */
- while (lua_rawgeti(L, 1, --j), sort_comp(L, -3, -1)) {
- if (j<l) luaL_error(L, "invalid order function for sorting");
- lua_pop(L, 1); /* remove a[j] */
- }
- if (j<i) {
- lua_pop(L, 3); /* pop pivot, a[i], a[j] */
- break;
- }
- set2(L, i, j);
- }
- lua_rawgeti(L, 1, u-1);
- lua_rawgeti(L, 1, i);
- set2(L, u-1, i); /* swap pivot (a[u-1]) with a[i] */
- /* a[l..i-1] <= a[i] == P <= a[i+1..u] */
- /* adjust so that smaller half is in [j..i] and larger one in [l..u] */
- if (i-l < u-i) {
- j=l; i=i-1; l=i+2;
- }
- else {
- j=i+1; i=u; u=j-2;
- }
- auxsort(L, j, i); /* call recursively the smaller one */
- } /* repeat the routine for the larger one */
-}
-
-static int sort (lua_State *L) {
- int n = aux_getn(L, 1);
- luaL_checkstack(L, 40, ""); /* assume array is smaller than 2^40 */
- if (!lua_isnoneornil(L, 2)) /* is there a 2nd argument? */
- luaL_checktype(L, 2, LUA_TFUNCTION);
- lua_settop(L, 2); /* make sure there is two arguments */
- auxsort(L, 1, n);
- return 0;
-}
-
-/* }====================================================== */
-
-
-static const luaL_Reg tab_funcs[] = {
- {"concat", tconcat},
- {"foreach", foreach},
- {"foreachi", foreachi},
- {"getn", getn},
- {"maxn", maxn},
- {"insert", tinsert},
- {"remove", tremove},
- {"setn", setn},
- {"sort", sort},
- {NULL, NULL}
-};
-
-
-LUALIB_API int luaopen_table (lua_State *L) {
- luaL_register(L, LUA_TABLIBNAME, tab_funcs);
- return 1;
-}
-
diff --git a/crawl-ref/source/util/lua/src/ltm.c b/crawl-ref/source/util/lua/src/ltm.c
deleted file mode 100644
index c27f0f6fab..0000000000
--- a/crawl-ref/source/util/lua/src/ltm.c
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
-** $Id: ltm.c,v 2.8.1.1 2007/12/27 13:02:25 roberto Exp $
-** Tag methods
-** See Copyright Notice in lua.h
-*/
-
-
-#include <string.h>
-
-#define ltm_c
-#define LUA_CORE
-
-#include "lua.h"
-
-#include "lobject.h"
-#include "lstate.h"
-#include "lstring.h"
-#include "ltable.h"
-#include "ltm.h"
-
-
-
-const char *const luaT_typenames[] = {
- "nil", "boolean", "userdata", "number",
- "string", "table", "function", "userdata", "thread",
- "proto", "upval"
-};
-
-
-void luaT_init (lua_State *L) {
- static const char *const luaT_eventname[] = { /* ORDER TM */
- "__index", "__newindex",
- "__gc", "__mode", "__eq",
- "__add", "__sub", "__mul", "__div", "__mod",
- "__pow", "__unm", "__len", "__lt", "__le",
- "__concat", "__call"
- };
- int i;
- for (i=0; i<TM_N; i++) {
- G(L)->tmname[i] = luaS_new(L, luaT_eventname[i]);
- luaS_fix(G(L)->tmname[i]); /* never collect these names */
- }
-}
-
-
-/*
-** function to be used with macro "fasttm": optimized for absence of
-** tag methods
-*/
-const TValue *luaT_gettm (Table *events, TMS event, TString *ename) {
- const TValue *tm = luaH_getstr(events, ename);
- lua_assert(event <= TM_EQ);
- if (ttisnil(tm)) { /* no tag method? */
- events->flags |= cast_byte(1u<<event); /* cache this fact */
- return NULL;
- }
- else return tm;
-}
-
-
-const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, TMS event) {
- Table *mt;
- switch (ttype(o)) {
- case LUA_TTABLE:
- mt = hvalue(o)->metatable;
- break;
- case LUA_TUSERDATA:
- mt = uvalue(o)->metatable;
- break;
- default:
- mt = G(L)->mt[ttype(o)];
- }
- return (mt ? luaH_getstr(mt, G(L)->tmname[event]) : luaO_nilobject);
-}
-
diff --git a/crawl-ref/source/util/lua/src/ltm.h b/crawl-ref/source/util/lua/src/ltm.h
deleted file mode 100644
index 64343b781b..0000000000
--- a/crawl-ref/source/util/lua/src/ltm.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
-** $Id: ltm.h,v 2.6.1.1 2007/12/27 13:02:25 roberto Exp $
-** Tag methods
-** See Copyright Notice in lua.h
-*/
-
-#ifndef ltm_h
-#define ltm_h
-
-
-#include "lobject.h"
-
-
-/*
-* WARNING: if you change the order of this enumeration,
-* grep "ORDER TM"
-*/
-typedef enum {
- TM_INDEX,
- TM_NEWINDEX,
- TM_GC,
- TM_MODE,
- TM_EQ, /* last tag method with `fast' access */
- TM_ADD,
- TM_SUB,
- TM_MUL,
- TM_DIV,
- TM_MOD,
- TM_POW,
- TM_UNM,
- TM_LEN,
- TM_LT,
- TM_LE,
- TM_CONCAT,
- TM_CALL,
- TM_N /* number of elements in the enum */
-} TMS;
-
-
-
-#define gfasttm(g,et,e) ((et) == NULL ? NULL : \
- ((et)->flags & (1u<<(e))) ? NULL : luaT_gettm(et, e, (g)->tmname[e]))
-
-#define fasttm(l,et,e) gfasttm(G(l), et, e)
-
-LUAI_DATA const char *const luaT_typenames[];
-
-
-LUAI_FUNC const TValue *luaT_gettm (Table *events, TMS event, TString *ename);
-LUAI_FUNC const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o,
- TMS event);
-LUAI_FUNC void luaT_init (lua_State *L);
-
-#endif
diff --git a/crawl-ref/source/util/lua/src/lua.c b/crawl-ref/source/util/lua/src/lua.c
deleted file mode 100644
index 3a46609328..0000000000
--- a/crawl-ref/source/util/lua/src/lua.c
+++ /dev/null
@@ -1,392 +0,0 @@
-/*
-** $Id: lua.c,v 1.160.1.2 2007/12/28 15:32:23 roberto Exp $
-** Lua stand-alone interpreter
-** See Copyright Notice in lua.h
-*/
-
-
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#define lua_c
-
-#include "lua.h"
-
-#include "lauxlib.h"
-#include "lualib.h"
-
-
-
-static lua_State *globalL = NULL;
-
-static const char *progname = LUA_PROGNAME;
-
-
-
-static void lstop (lua_State *L, lua_Debug *ar) {
- (void)ar; /* unused arg. */
- lua_sethook(L, NULL, 0, 0);
- luaL_error(L, "interrupted!");
-}
-
-
-static void laction (int i) {
- signal(i, SIG_DFL); /* if another SIGINT happens before lstop,
- terminate process (default action) */
- lua_sethook(globalL, lstop, LUA_MASKCALL | LUA_MASKRET | LUA_MASKCOUNT, 1);
-}
-
-
-static void print_usage (void) {
- fprintf(stderr,
- "usage: %s [options] [script [args]].\n"
- "Available options are:\n"
- " -e stat execute string " LUA_QL("stat") "\n"
- " -l name require library " LUA_QL("name") "\n"
- " -i enter interactive mode after executing " LUA_QL("script") "\n"
- " -v show version information\n"
- " -- stop handling options\n"
- " - execute stdin and stop handling options\n"
- ,
- progname);
- fflush(stderr);
-}
-
-
-static void l_message (const char *pname, const char *msg) {
- if (pname) fprintf(stderr, "%s: ", pname);
- fprintf(stderr, "%s\n", msg);
- fflush(stderr);
-}
-
-
-static int report (lua_State *L, int status) {
- if (status && !lua_isnil(L, -1)) {
- const char *msg = lua_tostring(L, -1);
- if (msg == NULL) msg = "(error object is not a string)";
- l_message(progname, msg);
- lua_pop(L, 1);
- }
- return status;
-}
-
-
-static int traceback (lua_State *L) {
- if (!lua_isstring(L, 1)) /* 'message' not a string? */
- return 1; /* keep it intact */
- lua_getfield(L, LUA_GLOBALSINDEX, "debug");
- if (!lua_istable(L, -1)) {
- lua_pop(L, 1);
- return 1;
- }
- lua_getfield(L, -1, "traceback");
- if (!lua_isfunction(L, -1)) {
- lua_pop(L, 2);
- return 1;
- }
- lua_pushvalue(L, 1); /* pass error message */
- lua_pushinteger(L, 2); /* skip this function and traceback */
- lua_call(L, 2, 1); /* call debug.traceback */
- return 1;
-}
-
-
-static int docall (lua_State *L, int narg, int clear) {
- int status;
- int base = lua_gettop(L) - narg; /* function index */
- lua_pushcfunction(L, traceback); /* push traceback function */
- lua_insert(L, base); /* put it under chunk and args */
- signal(SIGINT, laction);
- status = lua_pcall(L, narg, (clear ? 0 : LUA_MULTRET), base);
- signal(SIGINT, SIG_DFL);
- lua_remove(L, base); /* remove traceback function */
- /* force a complete garbage collection in case of errors */
- if (status != 0) lua_gc(L, LUA_GCCOLLECT, 0);
- return status;
-}
-
-
-static void print_version (void) {
- l_message(NULL, LUA_RELEASE " " LUA_COPYRIGHT);
-}
-
-
-static int getargs (lua_State *L, char **argv, int n) {
- int narg;
- int i;
- int argc = 0;
- while (argv[argc]) argc++; /* count total number of arguments */
- narg = argc - (n + 1); /* number of arguments to the script */
- luaL_checkstack(L, narg + 3, "too many arguments to script");
- for (i=n+1; i < argc; i++)
- lua_pushstring(L, argv[i]);
- lua_createtable(L, narg, n + 1);
- for (i=0; i < argc; i++) {
- lua_pushstring(L, argv[i]);
- lua_rawseti(L, -2, i - n);
- }
- return narg;
-}
-
-
-static int dofile (lua_State *L, const char *name) {
- int status = luaL_loadfile(L, name) || docall(L, 0, 1);
- return report(L, status);
-}
-
-
-static int dostring (lua_State *L, const char *s, const char *name) {
- int status = luaL_loadbuffer(L, s, strlen(s), name) || docall(L, 0, 1);
- return report(L, status);
-}
-
-
-static int dolibrary (lua_State *L, const char *name) {
- lua_getglobal(L, "require");
- lua_pushstring(L, name);
- return report(L, docall(L, 1, 1));
-}
-
-
-static const char *get_prompt (lua_State *L, int firstline) {
- const char *p;
- lua_getfield(L, LUA_GLOBALSINDEX, firstline ? "_PROMPT" : "_PROMPT2");
- p = lua_tostring(L, -1);
- if (p == NULL) p = (firstline ? LUA_PROMPT : LUA_PROMPT2);
- lua_pop(L, 1); /* remove global */
- return p;
-}
-
-
-static int incomplete (lua_State *L, int status) {
- if (status == LUA_ERRSYNTAX) {
- size_t lmsg;
- const char *msg = lua_tolstring(L, -1, &lmsg);
- const char *tp = msg + lmsg - (sizeof(LUA_QL("<eof>")) - 1);
- if (strstr(msg, LUA_QL("<eof>")) == tp) {
- lua_pop(L, 1);
- return 1;
- }
- }
- return 0; /* else... */
-}
-
-
-static int pushline (lua_State *L, int firstline) {
- char buffer[LUA_MAXINPUT];
- char *b = buffer;
- size_t l;
- const char *prmt = get_prompt(L, firstline);
- if (lua_readline(L, b, prmt) == 0)
- return 0; /* no input */
- l = strlen(b);
- if (l > 0 && b[l-1] == '\n') /* line ends with newline? */
- b[l-1] = '\0'; /* remove it */
- if (firstline && b[0] == '=') /* first line starts with `=' ? */
- lua_pushfstring(L, "return %s", b+1); /* change it to `return' */
- else
- lua_pushstring(L, b);
- lua_freeline(L, b);
- return 1;
-}
-
-
-static int loadline (lua_State *L) {
- int status;
- lua_settop(L, 0);
- if (!pushline(L, 1))
- return -1; /* no input */
- for (;;) { /* repeat until gets a complete line */
- status = luaL_loadbuffer(L, lua_tostring(L, 1), lua_strlen(L, 1), "=stdin");
- if (!incomplete(L, status)) break; /* cannot try to add lines? */
- if (!pushline(L, 0)) /* no more input? */
- return -1;
- lua_pushliteral(L, "\n"); /* add a new line... */
- lua_insert(L, -2); /* ...between the two lines */
- lua_concat(L, 3); /* join them */
- }
- lua_saveline(L, 1);
- lua_remove(L, 1); /* remove line */
- return status;
-}
-
-
-static void dotty (lua_State *L) {
- int status;
- const char *oldprogname = progname;
- progname = NULL;
- while ((status = loadline(L)) != -1) {
- if (status == 0) status = docall(L, 0, 0);
- report(L, status);
- if (status == 0 && lua_gettop(L) > 0) { /* any result to print? */
- lua_getglobal(L, "print");
- lua_insert(L, 1);
- if (lua_pcall(L, lua_gettop(L)-1, 0, 0) != 0)
- l_message(progname, lua_pushfstring(L,
- "error calling " LUA_QL("print") " (%s)",
- lua_tostring(L, -1)));
- }
- }
- lua_settop(L, 0); /* clear stack */
- fputs("\n", stdout);
- fflush(stdout);
- progname = oldprogname;
-}
-
-
-static int handle_script (lua_State *L, char **argv, int n) {
- int status;
- const char *fname;
- int narg = getargs(L, argv, n); /* collect arguments */
- lua_setglobal(L, "arg");
- fname = argv[n];
- if (strcmp(fname, "-") == 0 && strcmp(argv[n-1], "--") != 0)
- fname = NULL; /* stdin */
- status = luaL_loadfile(L, fname);
- lua_insert(L, -(narg+1));
- if (status == 0)
- status = docall(L, narg, 0);
- else
- lua_pop(L, narg);
- return report(L, status);
-}
-
-
-/* check that argument has no extra characters at the end */
-#define notail(x) {if ((x)[2] != '\0') return -1;}
-
-
-static int collectargs (char **argv, int *pi, int *pv, int *pe) {
- int i;
- for (i = 1; argv[i] != NULL; i++) {
- if (argv[i][0] != '-') /* not an option? */
- return i;
- switch (argv[i][1]) { /* option */
- case '-':
- notail(argv[i]);
- return (argv[i+1] != NULL ? i+1 : 0);
- case '\0':
- return i;
- case 'i':
- notail(argv[i]);
- *pi = 1; /* go through */
- case 'v':
- notail(argv[i]);
- *pv = 1;
- break;
- case 'e':
- *pe = 1; /* go through */
- case 'l':
- if (argv[i][2] == '\0') {
- i++;
- if (argv[i] == NULL) return -1;
- }
- break;
- default: return -1; /* invalid option */
- }
- }
- return 0;
-}
-
-
-static int runargs (lua_State *L, char **argv, int n) {
- int i;
- for (i = 1; i < n; i++) {
- if (argv[i] == NULL) continue;
- lua_assert(argv[i][0] == '-');
- switch (argv[i][1]) { /* option */
- case 'e': {
- const char *chunk = argv[i] + 2;
- if (*chunk == '\0') chunk = argv[++i];
- lua_assert(chunk != NULL);
- if (dostring(L, chunk, "=(command line)") != 0)
- return 1;
- break;
- }
- case 'l': {
- const char *filename = argv[i] + 2;
- if (*filename == '\0') filename = argv[++i];
- lua_assert(filename != NULL);
- if (dolibrary(L, filename))
- return 1; /* stop if file fails */
- break;
- }
- default: break;
- }
- }
- return 0;
-}
-
-
-static int handle_luainit (lua_State *L) {
- const char *init = getenv(LUA_INIT);
- if (init == NULL) return 0; /* status OK */
- else if (init[0] == '@')
- return dofile(L, init+1);
- else
- return dostring(L, init, "=" LUA_INIT);
-}
-
-
-struct Smain {
- int argc;
- char **argv;
- int status;
-};
-
-
-static int pmain (lua_State *L) {
- struct Smain *s = (struct Smain *)lua_touserdata(L, 1);
- char **argv = s->argv;
- int script;
- int has_i = 0, has_v = 0, has_e = 0;
- globalL = L;
- if (argv[0] && argv[0][0]) progname = argv[0];
- lua_gc(L, LUA_GCSTOP, 0); /* stop collector during initialization */
- luaL_openlibs(L); /* open libraries */
- lua_gc(L, LUA_GCRESTART, 0);
- s->status = handle_luainit(L);
- if (s->status != 0) return 0;
- script = collectargs(argv, &has_i, &has_v, &has_e);
- if (script < 0) { /* invalid args? */
- print_usage();
- s->status = 1;
- return 0;
- }
- if (has_v) print_version();
- s->status = runargs(L, argv, (script > 0) ? script : s->argc);
- if (s->status != 0) return 0;
- if (script)
- s->status = handle_script(L, argv, script);
- if (s->status != 0) return 0;
- if (has_i)
- dotty(L);
- else if (script == 0 && !has_e && !has_v) {
- if (lua_stdin_is_tty()) {
- print_version();
- dotty(L);
- }
- else dofile(L, NULL); /* executes stdin as a file */
- }
- return 0;
-}
-
-
-int main (int argc, char **argv) {
- int status;
- struct Smain s;
- lua_State *L = lua_open(); /* create state */
- if (L == NULL) {
- l_message(argv[0], "cannot create state: not enough memory");
- return EXIT_FAILURE;
- }
- s.argc = argc;
- s.argv = argv;
- status = lua_cpcall(L, &pmain, &s);
- report(L, status);
- lua_close(L);
- return (status || s.status) ? EXIT_FAILURE : EXIT_SUCCESS;
-}
-
diff --git a/crawl-ref/source/util/lua/src/lua.h b/crawl-ref/source/util/lua/src/lua.h
deleted file mode 100644
index e4bdfd3b94..0000000000
--- a/crawl-ref/source/util/lua/src/lua.h
+++ /dev/null
@@ -1,388 +0,0 @@
-/*
-** $Id: lua.h,v 1.218.1.5 2008/08/06 13:30:12 roberto Exp $
-** Lua - An Extensible Extension Language
-** Lua.org, PUC-Rio, Brazil (http://www.lua.org)
-** See Copyright Notice at the end of this file
-*/
-
-
-#ifndef lua_h
-#define lua_h
-
-#include <stdarg.h>
-#include <stddef.h>
-
-
-#include "luaconf.h"
-
-
-#define LUA_VERSION "Lua 5.1"
-#define LUA_RELEASE "Lua 5.1.4"
-#define LUA_VERSION_NUM 501
-#define LUA_COPYRIGHT "Copyright (C) 1994-2008 Lua.org, PUC-Rio"
-#define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo & W. Celes"
-
-
-/* mark for precompiled code (`<esc>Lua') */
-#define LUA_SIGNATURE "\033Lua"
-
-/* option for multiple returns in `lua_pcall' and `lua_call' */
-#define LUA_MULTRET (-1)
-
-
-/*
-** pseudo-indices
-*/
-#define LUA_REGISTRYINDEX (-10000)
-#define LUA_ENVIRONINDEX (-10001)
-#define LUA_GLOBALSINDEX (-10002)
-#define lua_upvalueindex(i) (LUA_GLOBALSINDEX-(i))
-
-
-/* thread status; 0 is OK */
-#define LUA_YIELD 1
-#define LUA_ERRRUN 2
-#define LUA_ERRSYNTAX 3
-#define LUA_ERRMEM 4
-#define LUA_ERRERR 5
-
-
-typedef struct lua_State lua_State;
-
-typedef int (*lua_CFunction) (lua_State *L);
-
-
-/*
-** functions that read/write blocks when loading/dumping Lua chunks
-*/
-typedef const char * (*lua_Reader) (lua_State *L, void *ud, size_t *sz);
-
-typedef int (*lua_Writer) (lua_State *L, const void* p, size_t sz, void* ud);
-
-
-/*
-** prototype for memory-allocation functions
-*/
-typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize);
-
-
-/*
-** basic types
-*/
-#define LUA_TNONE (-1)
-
-#define LUA_TNIL 0
-#define LUA_TBOOLEAN 1
-#define LUA_TLIGHTUSERDATA 2
-#define LUA_TNUMBER 3
-#define LUA_TSTRING 4
-#define LUA_TTABLE 5
-#define LUA_TFUNCTION 6
-#define LUA_TUSERDATA 7
-#define LUA_TTHREAD 8
-
-
-
-/* minimum Lua stack available to a C function */
-#define LUA_MINSTACK 20
-
-
-/*
-** generic extra include file
-*/
-#if defined(LUA_USER_H)
-#include LUA_USER_H
-#endif
-
-
-/* type of numbers in Lua */
-typedef LUA_NUMBER lua_Number;
-
-
-/* type for integer functions */
-typedef LUA_INTEGER lua_Integer;
-
-
-
-/*
-** state manipulation
-*/
-LUA_API lua_State *(lua_newstate) (lua_Alloc f, void *ud);
-LUA_API void (lua_close) (lua_State *L);
-LUA_API lua_State *(lua_newthread) (lua_State *L);
-
-LUA_API lua_CFunction (lua_atpanic) (lua_State *L, lua_CFunction panicf);
-
-
-/*
-** basic stack manipulation
-*/
-LUA_API int (lua_gettop) (lua_State *L);
-LUA_API void (lua_settop) (lua_State *L, int idx);
-LUA_API void (lua_pushvalue) (lua_State *L, int idx);
-LUA_API void (lua_remove) (lua_State *L, int idx);
-LUA_API void (lua_insert) (lua_State *L, int idx);
-LUA_API void (lua_replace) (lua_State *L, int idx);
-LUA_API int (lua_checkstack) (lua_State *L, int sz);
-
-LUA_API void (lua_xmove) (lua_State *from, lua_State *to, int n);
-
-
-/*
-** access functions (stack -> C)
-*/
-
-LUA_API int (lua_isnumber) (lua_State *L, int idx);
-LUA_API int (lua_isstring) (lua_State *L, int idx);
-LUA_API int (lua_iscfunction) (lua_State *L, int idx);
-LUA_API int (lua_isuserdata) (lua_State *L, int idx);
-LUA_API int (lua_type) (lua_State *L, int idx);
-LUA_API const char *(lua_typename) (lua_State *L, int tp);
-
-LUA_API int (lua_equal) (lua_State *L, int idx1, int idx2);
-LUA_API int (lua_rawequal) (lua_State *L, int idx1, int idx2);
-LUA_API int (lua_lessthan) (lua_State *L, int idx1, int idx2);
-
-LUA_API lua_Number (lua_tonumber) (lua_State *L, int idx);
-LUA_API lua_Integer (lua_tointeger) (lua_State *L, int idx);
-LUA_API int (lua_toboolean) (lua_State *L, int idx);
-LUA_API const char *(lua_tolstring) (lua_State *L, int idx, size_t *len);
-LUA_API size_t (lua_objlen) (lua_State *L, int idx);
-LUA_API lua_CFunction (lua_tocfunction) (lua_State *L, int idx);
-LUA_API void *(lua_touserdata) (lua_State *L, int idx);
-LUA_API lua_State *(lua_tothread) (lua_State *L, int idx);
-LUA_API const void *(lua_topointer) (lua_State *L, int idx);
-
-
-/*
-** push functions (C -> stack)
-*/
-LUA_API void (lua_pushnil) (lua_State *L);
-LUA_API void (lua_pushnumber) (lua_State *L, lua_Number n);
-LUA_API void (lua_pushinteger) (lua_State *L, lua_Integer n);
-LUA_API void (lua_pushlstring) (lua_State *L, const char *s, size_t l);
-LUA_API void (lua_pushstring) (lua_State *L, const char *s);
-LUA_API const char *(lua_pushvfstring) (lua_State *L, const char *fmt,
- va_list argp);
-LUA_API const char *(lua_pushfstring) (lua_State *L, const char *fmt, ...);
-LUA_API void (lua_pushcclosure) (lua_State *L, lua_CFunction fn, int n);
-LUA_API void (lua_pushboolean) (lua_State *L, int b);
-LUA_API void (lua_pushlightuserdata) (lua_State *L, void *p);
-LUA_API int (lua_pushthread) (lua_State *L);
-
-
-/*
-** get functions (Lua -> stack)
-*/
-LUA_API void (lua_gettable) (lua_State *L, int idx);
-LUA_API void (lua_getfield) (lua_State *L, int idx, const char *k);
-LUA_API void (lua_rawget) (lua_State *L, int idx);
-LUA_API void (lua_rawgeti) (lua_State *L, int idx, int n);
-LUA_API void (lua_createtable) (lua_State *L, int narr, int nrec);
-LUA_API void *(lua_newuserdata) (lua_State *L, size_t sz);
-LUA_API int (lua_getmetatable) (lua_State *L, int objindex);
-LUA_API void (lua_getfenv) (lua_State *L, int idx);
-
-
-/*
-** set functions (stack -> Lua)
-*/
-LUA_API void (lua_settable) (lua_State *L, int idx);
-LUA_API void (lua_setfield) (lua_State *L, int idx, const char *k);
-LUA_API void (lua_rawset) (lua_State *L, int idx);
-LUA_API void (lua_rawseti) (lua_State *L, int idx, int n);
-LUA_API int (lua_setmetatable) (lua_State *L, int objindex);
-LUA_API int (lua_setfenv) (lua_State *L, int idx);
-
-
-/*
-** `load' and `call' functions (load and run Lua code)
-*/
-LUA_API void (lua_call) (lua_State *L, int nargs, int nresults);
-LUA_API int (lua_pcall) (lua_State *L, int nargs, int nresults, int errfunc);
-LUA_API int (lua_cpcall) (lua_State *L, lua_CFunction func, void *ud);
-LUA_API int (lua_load) (lua_State *L, lua_Reader reader, void *dt,
- const char *chunkname);
-
-LUA_API int (lua_dump) (lua_State *L, lua_Writer writer, void *data);
-
-
-/*
-** coroutine functions
-*/
-LUA_API int (lua_yield) (lua_State *L, int nresults);
-LUA_API int (lua_resume) (lua_State *L, int narg);
-LUA_API int (lua_status) (lua_State *L);
-
-/*
-** garbage-collection function and options
-*/
-
-#define LUA_GCSTOP 0
-#define LUA_GCRESTART 1
-#define LUA_GCCOLLECT 2
-#define LUA_GCCOUNT 3
-#define LUA_GCCOUNTB 4
-#define LUA_GCSTEP 5
-#define LUA_GCSETPAUSE 6
-#define LUA_GCSETSTEPMUL 7
-
-LUA_API int (lua_gc) (lua_State *L, int what, int data);
-
-
-/*
-** miscellaneous functions
-*/
-
-LUA_API int (lua_error) (lua_State *L);
-
-LUA_API int (lua_next) (lua_State *L, int idx);
-
-LUA_API void (lua_concat) (lua_State *L, int n);
-
-LUA_API lua_Alloc (lua_getallocf) (lua_State *L, void **ud);
-LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud);
-
-
-
-/*
-** ===============================================================
-** some useful macros
-** ===============================================================
-*/
-
-#define lua_pop(L,n) lua_settop(L, -(n)-1)
-
-#define lua_newtable(L) lua_createtable(L, 0, 0)
-
-#define lua_register(L,n,f) (lua_pushcfunction(L, (f)), lua_setglobal(L, (n)))
-
-#define lua_pushcfunction(L,f) lua_pushcclosure(L, (f), 0)
-
-#define lua_strlen(L,i) lua_objlen(L, (i))
-
-#define lua_isfunction(L,n) (lua_type(L, (n)) == LUA_TFUNCTION)
-#define lua_istable(L,n) (lua_type(L, (n)) == LUA_TTABLE)
-#define lua_islightuserdata(L,n) (lua_type(L, (n)) == LUA_TLIGHTUSERDATA)
-#define lua_isnil(L,n) (lua_type(L, (n)) == LUA_TNIL)
-#define lua_isboolean(L,n) (lua_type(L, (n)) == LUA_TBOOLEAN)
-#define lua_isthread(L,n) (lua_type(L, (n)) == LUA_TTHREAD)
-#define lua_isnone(L,n) (lua_type(L, (n)) == LUA_TNONE)
-#define lua_isnoneornil(L, n) (lua_type(L, (n)) <= 0)
-
-#define lua_pushliteral(L, s) \
- lua_pushlstring(L, "" s, (sizeof(s)/sizeof(char))-1)
-
-#define lua_setglobal(L,s) lua_setfield(L, LUA_GLOBALSINDEX, (s))
-#define lua_getglobal(L,s) lua_getfield(L, LUA_GLOBALSINDEX, (s))
-
-#define lua_tostring(L,i) lua_tolstring(L, (i), NULL)
-
-
-
-/*
-** compatibility macros and functions
-*/
-
-#define lua_open() luaL_newstate()
-
-#define lua_getregistry(L) lua_pushvalue(L, LUA_REGISTRYINDEX)
-
-#define lua_getgccount(L) lua_gc(L, LUA_GCCOUNT, 0)
-
-#define lua_Chunkreader lua_Reader
-#define lua_Chunkwriter lua_Writer
-
-
-/* hack */
-LUA_API void lua_setlevel (lua_State *from, lua_State *to);
-
-
-/*
-** {======================================================================
-** Debug API
-** =======================================================================
-*/
-
-
-/*
-** Event codes
-*/
-#define LUA_HOOKCALL 0
-#define LUA_HOOKRET 1
-#define LUA_HOOKLINE 2
-#define LUA_HOOKCOUNT 3
-#define LUA_HOOKTAILRET 4
-
-
-/*
-** Event masks
-*/
-#define LUA_MASKCALL (1 << LUA_HOOKCALL)
-#define LUA_MASKRET (1 << LUA_HOOKRET)
-#define LUA_MASKLINE (1 << LUA_HOOKLINE)
-#define LUA_MASKCOUNT (1 << LUA_HOOKCOUNT)
-
-typedef struct lua_Debug lua_Debug; /* activation record */
-
-
-/* Functions to be called by the debuger in specific events */
-typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar);
-
-
-LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar);
-LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar);
-LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n);
-LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n);
-LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n);
-LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n);
-
-LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count);
-LUA_API lua_Hook lua_gethook (lua_State *L);
-LUA_API int lua_gethookmask (lua_State *L);
-LUA_API int lua_gethookcount (lua_State *L);
-
-
-struct lua_Debug {
- int event;
- const char *name; /* (n) */
- const char *namewhat; /* (n) `global', `local', `field', `method' */
- const char *what; /* (S) `Lua', `C', `main', `tail' */
- const char *source; /* (S) */
- int currentline; /* (l) */
- int nups; /* (u) number of upvalues */
- int linedefined; /* (S) */
- int lastlinedefined; /* (S) */
- char short_src[LUA_IDSIZE]; /* (S) */
- /* private part */
- int i_ci; /* active function */
-};
-
-/* }====================================================================== */
-
-
-/******************************************************************************
-* Copyright (C) 1994-2008 Lua.org, PUC-Rio. All rights reserved.
-*
-* Permission is hereby granted, free of charge, to any person obtaining
-* a copy of this software and associated documentation files (the
-* "Software"), to deal in the Software without restriction, including
-* without limitation the rights to use, copy, modify, merge, publish,
-* distribute, sublicense, and/or sell copies of the Software, and to
-* permit persons to whom the Software is furnished to do so, subject to
-* the following conditions:
-*
-* The above copyright notice and this permission notice shall be
-* included in all copies or substantial portions of the Software.
-*
-* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-******************************************************************************/
-
-
-#endif
diff --git a/crawl-ref/source/util/lua/src/luac.c b/crawl-ref/source/util/lua/src/luac.c
deleted file mode 100644
index d07017391b..0000000000
--- a/crawl-ref/source/util/lua/src/luac.c
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
-** $Id: luac.c,v 1.54 2006/06/02 17:37:11 lhf Exp $
-** Lua compiler (saves bytecodes to files; also list bytecodes)
-** See Copyright Notice in lua.h
-*/
-
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#define luac_c
-#define LUA_CORE
-
-#include "lua.h"
-#include "lauxlib.h"
-
-#include "ldo.h"
-#include "lfunc.h"
-#include "lmem.h"
-#include "lobject.h"
-#include "lopcodes.h"
-#include "lstring.h"
-#include "lundump.h"
-
-#define PROGNAME "luac" /* default program name */
-#define OUTPUT PROGNAME ".out" /* default output file */
-
-static int listing=0; /* list bytecodes? */
-static int dumping=1; /* dump bytecodes? */
-static int stripping=0; /* strip debug information? */
-static char Output[]={ OUTPUT }; /* default output file name */
-static const char* output=Output; /* actual output file name */
-static const char* progname=PROGNAME; /* actual program name */
-
-static void fatal(const char* message)
-{
- fprintf(stderr,"%s: %s\n",progname,message);
- exit(EXIT_FAILURE);
-}
-
-static void cannot(const char* what)
-{
- fprintf(stderr,"%s: cannot %s %s: %s\n",progname,what,output,strerror(errno));
- exit(EXIT_FAILURE);
-}
-
-static void usage(const char* message)
-{
- if (*message=='-')
- fprintf(stderr,"%s: unrecognized option " LUA_QS "\n",progname,message);
- else
- fprintf(stderr,"%s: %s\n",progname,message);
- fprintf(stderr,
- "usage: %s [options] [filenames].\n"
- "Available options are:\n"
- " - process stdin\n"
- " -l list\n"
- " -o name output to file " LUA_QL("name") " (default is \"%s\")\n"
- " -p parse only\n"
- " -s strip debug information\n"
- " -v show version information\n"
- " -- stop handling options\n",
- progname,Output);
- exit(EXIT_FAILURE);
-}
-
-#define IS(s) (strcmp(argv[i],s)==0)
-
-static int doargs(int argc, char* argv[])
-{
- int i;
- int version=0;
- if (argv[0]!=NULL && *argv[0]!=0) progname=argv[0];
- for (i=1; i<argc; i++)
- {
- if (*argv[i]!='-') /* end of options; keep it */
- break;
- else if (IS("--")) /* end of options; skip it */
- {
- ++i;
- if (version) ++version;
- break;
- }
- else if (IS("-")) /* end of options; use stdin */
- break;
- else if (IS("-l")) /* list */
- ++listing;
- else if (IS("-o")) /* output file */
- {
- output=argv[++i];
- if (output==NULL || *output==0) usage(LUA_QL("-o") " needs argument");
- if (IS("-")) output=NULL;
- }
- else if (IS("-p")) /* parse only */
- dumping=0;
- else if (IS("-s")) /* strip debug information */
- stripping=1;
- else if (IS("-v")) /* show version */
- ++version;
- else /* unknown option */
- usage(argv[i]);
- }
- if (i==argc && (listing || !dumping))
- {
- dumping=0;
- argv[--i]=Output;
- }
- if (version)
- {
- printf("%s %s\n",LUA_RELEASE,LUA_COPYRIGHT);
- if (version==argc-1) exit(EXIT_SUCCESS);
- }
- return i;
-}
-
-#define toproto(L,i) (clvalue(L->top+(i))->l.p)
-
-static const Proto* combine(lua_State* L, int n)
-{
- if (n==1)
- return toproto(L,-1);
- else
- {
- int i,pc;
- Proto* f=luaF_newproto(L);
- setptvalue2s(L,L->top,f); incr_top(L);
- f->source=luaS_newliteral(L,"=(" PROGNAME ")");
- f->maxstacksize=1;
- pc=2*n+1;
- f->code=luaM_newvector(L,pc,Instruction);
- f->sizecode=pc;
- f->p=luaM_newvector(L,n,Proto*);
- f->sizep=n;
- pc=0;
- for (i=0; i<n; i++)
- {
- f->p[i]=toproto(L,i-n-1);
- f->code[pc++]=CREATE_ABx(OP_CLOSURE,0,i);
- f->code[pc++]=CREATE_ABC(OP_CALL,0,1,1);
- }
- f->code[pc++]=CREATE_ABC(OP_RETURN,0,1,0);
- return f;
- }
-}
-
-static int writer(lua_State* L, const void* p, size_t size, void* u)
-{
- UNUSED(L);
- return (fwrite(p,size,1,(FILE*)u)!=1) && (size!=0);
-}
-
-struct Smain {
- int argc;
- char** argv;
-};
-
-static int pmain(lua_State* L)
-{
- struct Smain* s = (struct Smain*)lua_touserdata(L, 1);
- int argc=s->argc;
- char** argv=s->argv;
- const Proto* f;
- int i;
- if (!lua_checkstack(L,argc)) fatal("too many input files");
- for (i=0; i<argc; i++)
- {
- const char* filename=IS("-") ? NULL : argv[i];
- if (luaL_loadfile(L,filename)!=0) fatal(lua_tostring(L,-1));
- }
- f=combine(L,argc);
- if (listing) luaU_print(f,listing>1);
- if (dumping)
- {
- FILE* D= (output==NULL) ? stdout : fopen(output,"wb");
- if (D==NULL) cannot("open");
- lua_lock(L);
- luaU_dump(L,f,writer,D,stripping);
- lua_unlock(L);
- if (ferror(D)) cannot("write");
- if (fclose(D)) cannot("close");
- }
- return 0;
-}
-
-int main(int argc, char* argv[])
-{
- lua_State* L;
- struct Smain s;
- int i=doargs(argc,argv);
- argc-=i; argv+=i;
- if (argc<=0) usage("no input files given");
- L=lua_open();
- if (L==NULL) fatal("not enough memory for state");
- s.argc=argc;
- s.argv=argv;
- if (lua_cpcall(L,pmain,&s)!=0) fatal(lua_tostring(L,-1));
- lua_close(L);
- return EXIT_SUCCESS;
-}
diff --git a/crawl-ref/source/util/lua/src/luaconf.h b/crawl-ref/source/util/lua/src/luaconf.h
deleted file mode 100644
index e2cb26163a..0000000000
--- a/crawl-ref/source/util/lua/src/luaconf.h
+++ /dev/null
@@ -1,763 +0,0 @@
-/*
-** $Id: luaconf.h,v 1.82.1.7 2008/02/11 16:25:08 roberto Exp $
-** Configuration file for Lua
-** See Copyright Notice in lua.h
-*/
-
-
-#ifndef lconfig_h
-#define lconfig_h
-
-#include <limits.h>
-#include <stddef.h>
-
-
-/*
-** ==================================================================
-** Search for "@@" to find all configurable definitions.
-** ===================================================================
-*/
-
-
-/*
-@@ LUA_ANSI controls the use of non-ansi features.
-** CHANGE it (define it) if you want Lua to avoid the use of any
-** non-ansi feature or library.
-*/
-#if defined(__STRICT_ANSI__)
-#define LUA_ANSI
-#endif
-
-
-#if !defined(LUA_ANSI) && defined(_WIN32)
-#define LUA_WIN
-#endif
-
-#if defined(LUA_USE_LINUX)
-#define LUA_USE_POSIX
-#define LUA_USE_DLOPEN /* needs an extra library: -ldl */
-#define LUA_USE_READLINE /* needs some extra libraries */
-#endif
-
-#if defined(LUA_USE_MACOSX)
-#define LUA_USE_POSIX
-#define LUA_DL_DYLD /* does not need extra library */
-#endif
-
-
-
-/*
-@@ LUA_USE_POSIX includes all functionallity listed as X/Open System
-@* Interfaces Extension (XSI).
-** CHANGE it (define it) if your system is XSI compatible.
-*/
-#if defined(LUA_USE_POSIX)
-#define LUA_USE_MKSTEMP
-#define LUA_USE_ISATTY
-#define LUA_USE_POPEN
-#define LUA_USE_ULONGJMP
-#endif
-
-
-/*
-@@ LUA_PATH and LUA_CPATH are the names of the environment variables that
-@* Lua check to set its paths.
-@@ LUA_INIT is the name of the environment variable that Lua
-@* checks for initialization code.
-** CHANGE them if you want different names.
-*/
-#define LUA_PATH "LUA_PATH"
-#define LUA_CPATH "LUA_CPATH"
-#define LUA_INIT "LUA_INIT"
-
-
-/*
-@@ LUA_PATH_DEFAULT is the default path that Lua uses to look for
-@* Lua libraries.
-@@ LUA_CPATH_DEFAULT is the default path that Lua uses to look for
-@* C libraries.
-** CHANGE them if your machine has a non-conventional directory
-** hierarchy or if you want to install your libraries in
-** non-conventional directories.
-*/
-#if defined(_WIN32)
-/*
-** In Windows, any exclamation mark ('!') in the path is replaced by the
-** path of the directory of the executable file of the current process.
-*/
-#define LUA_LDIR "!\\lua\\"
-#define LUA_CDIR "!\\"
-#define LUA_PATH_DEFAULT \
- ".\\?.lua;" LUA_LDIR"?.lua;" LUA_LDIR"?\\init.lua;" \
- LUA_CDIR"?.lua;" LUA_CDIR"?\\init.lua"
-#define LUA_CPATH_DEFAULT \
- ".\\?.dll;" LUA_CDIR"?.dll;" LUA_CDIR"loadall.dll"
-
-#else
-#define LUA_ROOT "/usr/local/"
-#define LUA_LDIR LUA_ROOT "share/lua/5.1/"
-#define LUA_CDIR LUA_ROOT "lib/lua/5.1/"
-#define LUA_PATH_DEFAULT \
- "./?.lua;" LUA_LDIR"?.lua;" LUA_LDIR"?/init.lua;" \
- LUA_CDIR"?.lua;" LUA_CDIR"?/init.lua"
-#define LUA_CPATH_DEFAULT \
- "./?.so;" LUA_CDIR"?.so;" LUA_CDIR"loadall.so"
-#endif
-
-
-/*
-@@ LUA_DIRSEP is the directory separator (for submodules).
-** CHANGE it if your machine does not use "/" as the directory separator
-** and is not Windows. (On Windows Lua automatically uses "\".)
-*/
-#if defined(_WIN32)
-#define LUA_DIRSEP "\\"
-#else
-#define LUA_DIRSEP "/"
-#endif
-
-
-/*
-@@ LUA_PATHSEP is the character that separates templates in a path.
-@@ LUA_PATH_MARK is the string that marks the substitution points in a
-@* template.
-@@ LUA_EXECDIR in a Windows path is replaced by the executable's
-@* directory.
-@@ LUA_IGMARK is a mark to ignore all before it when bulding the
-@* luaopen_ function name.
-** CHANGE them if for some reason your system cannot use those
-** characters. (E.g., if one of those characters is a common character
-** in file/directory names.) Probably you do not need to change them.
-*/
-#define LUA_PATHSEP ";"
-#define LUA_PATH_MARK "?"
-#define LUA_EXECDIR "!"
-#define LUA_IGMARK "-"
-
-
-/*
-@@ LUA_INTEGER is the integral type used by lua_pushinteger/lua_tointeger.
-** CHANGE that if ptrdiff_t is not adequate on your machine. (On most
-** machines, ptrdiff_t gives a good choice between int or long.)
-*/
-#define LUA_INTEGER ptrdiff_t
-
-
-/*
-@@ LUA_API is a mark for all core API functions.
-@@ LUALIB_API is a mark for all standard library functions.
-** CHANGE them if you need to define those functions in some special way.
-** For instance, if you want to create one Windows DLL with the core and
-** the libraries, you may want to use the following definition (define
-** LUA_BUILD_AS_DLL to get it).
-*/
-#if defined(LUA_BUILD_AS_DLL)
-
-#if defined(LUA_CORE) || defined(LUA_LIB)
-#define LUA_API __declspec(dllexport)
-#else
-#define LUA_API __declspec(dllimport)
-#endif
-
-#else
-
-#define LUA_API extern
-
-#endif
-
-/* more often than not the libs go together with the core */
-#define LUALIB_API LUA_API
-
-
-/*
-@@ LUAI_FUNC is a mark for all extern functions that are not to be
-@* exported to outside modules.
-@@ LUAI_DATA is a mark for all extern (const) variables that are not to
-@* be exported to outside modules.
-** CHANGE them if you need to mark them in some special way. Elf/gcc
-** (versions 3.2 and later) mark them as "hidden" to optimize access
-** when Lua is compiled as a shared library.
-*/
-#if defined(luaall_c)
-#define LUAI_FUNC static
-#define LUAI_DATA /* empty */
-
-#elif defined(__GNUC__) && ((__GNUC__*100 + __GNUC_MINOR__) >= 302) && \
- defined(__ELF__)
-#define LUAI_FUNC __attribute__((visibility("hidden"))) extern
-#define LUAI_DATA LUAI_FUNC
-
-#else
-#define LUAI_FUNC extern
-#define LUAI_DATA extern
-#endif
-
-
-
-/*
-@@ LUA_QL describes how error messages quote program elements.
-** CHANGE it if you want a different appearance.
-*/
-#define LUA_QL(x) "'" x "'"
-#define LUA_QS LUA_QL("%s")
-
-
-/*
-@@ LUA_IDSIZE gives the maximum size for the description of the source
-@* of a function in debug information.
-** CHANGE it if you want a different size.
-*/
-#define LUA_IDSIZE 60
-
-
-/*
-** {==================================================================
-** Stand-alone configuration
-** ===================================================================
-*/
-
-#if defined(lua_c) || defined(luaall_c)
-
-/*
-@@ lua_stdin_is_tty detects whether the standard input is a 'tty' (that
-@* is, whether we're running lua interactively).
-** CHANGE it if you have a better definition for non-POSIX/non-Windows
-** systems.
-*/
-#if defined(LUA_USE_ISATTY)
-#include <unistd.h>
-#define lua_stdin_is_tty() isatty(0)
-#elif defined(LUA_WIN)
-#include <io.h>
-#include <stdio.h>
-#define lua_stdin_is_tty() _isatty(_fileno(stdin))
-#else
-#define lua_stdin_is_tty() 1 /* assume stdin is a tty */
-#endif
-
-
-/*
-@@ LUA_PROMPT is the default prompt used by stand-alone Lua.
-@@ LUA_PROMPT2 is the default continuation prompt used by stand-alone Lua.
-** CHANGE them if you want different prompts. (You can also change the
-** prompts dynamically, assigning to globals _PROMPT/_PROMPT2.)
-*/
-#define LUA_PROMPT "> "
-#define LUA_PROMPT2 ">> "
-
-
-/*
-@@ LUA_PROGNAME is the default name for the stand-alone Lua program.
-** CHANGE it if your stand-alone interpreter has a different name and
-** your system is not able to detect that name automatically.
-*/
-#define LUA_PROGNAME "lua"
-
-
-/*
-@@ LUA_MAXINPUT is the maximum length for an input line in the
-@* stand-alone interpreter.
-** CHANGE it if you need longer lines.
-*/
-#define LUA_MAXINPUT 512
-
-
-/*
-@@ lua_readline defines how to show a prompt and then read a line from
-@* the standard input.
-@@ lua_saveline defines how to "save" a read line in a "history".
-@@ lua_freeline defines how to free a line read by lua_readline.
-** CHANGE them if you want to improve this functionality (e.g., by using
-** GNU readline and history facilities).
-*/
-#if defined(LUA_USE_READLINE)
-#include <stdio.h>
-#include <readline/readline.h>
-#include <readline/history.h>
-#define lua_readline(L,b,p) ((void)L, ((b)=readline(p)) != NULL)
-#define lua_saveline(L,idx) \
- if (lua_strlen(L,idx) > 0) /* non-empty line? */ \
- add_history(lua_tostring(L, idx)); /* add it to history */
-#define lua_freeline(L,b) ((void)L, free(b))
-#else
-#define lua_readline(L,b,p) \
- ((void)L, fputs(p, stdout), fflush(stdout), /* show prompt */ \
- fgets(b, LUA_MAXINPUT, stdin) != NULL) /* get line */
-#define lua_saveline(L,idx) { (void)L; (void)idx; }
-#define lua_freeline(L,b) { (void)L; (void)b; }
-#endif
-
-#endif
-
-/* }================================================================== */
-
-
-/*
-@@ LUAI_GCPAUSE defines the default pause between garbage-collector cycles
-@* as a percentage.
-** CHANGE it if you want the GC to run faster or slower (higher values
-** mean larger pauses which mean slower collection.) You can also change
-** this value dynamically.
-*/
-#define LUAI_GCPAUSE 200 /* 200% (wait memory to double before next GC) */
-
-
-/*
-@@ LUAI_GCMUL defines the default speed of garbage collection relative to
-@* memory allocation as a percentage.
-** CHANGE it if you want to change the granularity of the garbage
-** collection. (Higher values mean coarser collections. 0 represents
-** infinity, where each step performs a full collection.) You can also
-** change this value dynamically.
-*/
-#define LUAI_GCMUL 200 /* GC runs 'twice the speed' of memory allocation */
-
-
-
-/*
-@@ LUA_COMPAT_GETN controls compatibility with old getn behavior.
-** CHANGE it (define it) if you want exact compatibility with the
-** behavior of setn/getn in Lua 5.0.
-*/
-#undef LUA_COMPAT_GETN
-
-/*
-@@ LUA_COMPAT_LOADLIB controls compatibility about global loadlib.
-** CHANGE it to undefined as soon as you do not need a global 'loadlib'
-** function (the function is still available as 'package.loadlib').
-*/
-#undef LUA_COMPAT_LOADLIB
-
-/*
-@@ LUA_COMPAT_VARARG controls compatibility with old vararg feature.
-** CHANGE it to undefined as soon as your programs use only '...' to
-** access vararg parameters (instead of the old 'arg' table).
-*/
-#define LUA_COMPAT_VARARG
-
-/*
-@@ LUA_COMPAT_MOD controls compatibility with old math.mod function.
-** CHANGE it to undefined as soon as your programs use 'math.fmod' or
-** the new '%' operator instead of 'math.mod'.
-*/
-#define LUA_COMPAT_MOD
-
-/*
-@@ LUA_COMPAT_LSTR controls compatibility with old long string nesting
-@* facility.
-** CHANGE it to 2 if you want the old behaviour, or undefine it to turn
-** off the advisory error when nesting [[...]].
-*/
-#define LUA_COMPAT_LSTR 1
-
-/*
-@@ LUA_COMPAT_GFIND controls compatibility with old 'string.gfind' name.
-** CHANGE it to undefined as soon as you rename 'string.gfind' to
-** 'string.gmatch'.
-*/
-#define LUA_COMPAT_GFIND
-
-/*
-@@ LUA_COMPAT_OPENLIB controls compatibility with old 'luaL_openlib'
-@* behavior.
-** CHANGE it to undefined as soon as you replace to 'luaL_register'
-** your uses of 'luaL_openlib'
-*/
-#define LUA_COMPAT_OPENLIB
-
-
-
-/*
-@@ luai_apicheck is the assert macro used by the Lua-C API.
-** CHANGE luai_apicheck if you want Lua to perform some checks in the
-** parameters it gets from API calls. This may slow down the interpreter
-** a bit, but may be quite useful when debugging C code that interfaces
-** with Lua. A useful redefinition is to use assert.h.
-*/
-#if defined(LUA_USE_APICHECK)
-#include <assert.h>
-#define luai_apicheck(L,o) { (void)L; assert(o); }
-#else
-#define luai_apicheck(L,o) { (void)L; }
-#endif
-
-
-/*
-@@ LUAI_BITSINT defines the number of bits in an int.
-** CHANGE here if Lua cannot automatically detect the number of bits of
-** your machine. Probably you do not need to change this.
-*/
-/* avoid overflows in comparison */
-#if INT_MAX-20 < 32760
-#define LUAI_BITSINT 16
-#elif INT_MAX > 2147483640L
-/* int has at least 32 bits */
-#define LUAI_BITSINT 32
-#else
-#error "you must define LUA_BITSINT with number of bits in an integer"
-#endif
-
-
-/*
-@@ LUAI_UINT32 is an unsigned integer with at least 32 bits.
-@@ LUAI_INT32 is an signed integer with at least 32 bits.
-@@ LUAI_UMEM is an unsigned integer big enough to count the total
-@* memory used by Lua.
-@@ LUAI_MEM is a signed integer big enough to count the total memory
-@* used by Lua.
-** CHANGE here if for some weird reason the default definitions are not
-** good enough for your machine. (The definitions in the 'else'
-** part always works, but may waste space on machines with 64-bit
-** longs.) Probably you do not need to change this.
-*/
-#if LUAI_BITSINT >= 32
-#define LUAI_UINT32 unsigned int
-#define LUAI_INT32 int
-#define LUAI_MAXINT32 INT_MAX
-#define LUAI_UMEM size_t
-#define LUAI_MEM ptrdiff_t
-#else
-/* 16-bit ints */
-#define LUAI_UINT32 unsigned long
-#define LUAI_INT32 long
-#define LUAI_MAXINT32 LONG_MAX
-#define LUAI_UMEM unsigned long
-#define LUAI_MEM long
-#endif
-
-
-/*
-@@ LUAI_MAXCALLS limits the number of nested calls.
-** CHANGE it if you need really deep recursive calls. This limit is
-** arbitrary; its only purpose is to stop infinite recursion before
-** exhausting memory.
-*/
-#define LUAI_MAXCALLS 20000
-
-
-/*
-@@ LUAI_MAXCSTACK limits the number of Lua stack slots that a C function
-@* can use.
-** CHANGE it if you need lots of (Lua) stack space for your C
-** functions. This limit is arbitrary; its only purpose is to stop C
-** functions to consume unlimited stack space. (must be smaller than
-** -LUA_REGISTRYINDEX)
-*/
-#define LUAI_MAXCSTACK 8000
-
-
-
-/*
-** {==================================================================
-** CHANGE (to smaller values) the following definitions if your system
-** has a small C stack. (Or you may want to change them to larger
-** values if your system has a large C stack and these limits are
-** too rigid for you.) Some of these constants control the size of
-** stack-allocated arrays used by the compiler or the interpreter, while
-** others limit the maximum number of recursive calls that the compiler
-** or the interpreter can perform. Values too large may cause a C stack
-** overflow for some forms of deep constructs.
-** ===================================================================
-*/
-
-
-/*
-@@ LUAI_MAXCCALLS is the maximum depth for nested C calls (short) and
-@* syntactical nested non-terminals in a program.
-*/
-#define LUAI_MAXCCALLS 200
-
-
-/*
-@@ LUAI_MAXVARS is the maximum number of local variables per function
-@* (must be smaller than 250).
-*/
-#define LUAI_MAXVARS 200
-
-
-/*
-@@ LUAI_MAXUPVALUES is the maximum number of upvalues per function
-@* (must be smaller than 250).
-*/
-#define LUAI_MAXUPVALUES 60
-
-
-/*
-@@ LUAL_BUFFERSIZE is the buffer size used by the lauxlib buffer system.
-*/
-#define LUAL_BUFFERSIZE BUFSIZ
-
-/* }================================================================== */
-
-
-
-
-/*
-** {==================================================================
-@@ LUA_NUMBER is the type of numbers in Lua.
-** CHANGE the following definitions only if you want to build Lua
-** with a number type different from double. You may also need to
-** change lua_number2int & lua_number2integer.
-** ===================================================================
-*/
-
-#define LUA_NUMBER_DOUBLE
-#define LUA_NUMBER double
-
-/*
-@@ LUAI_UACNUMBER is the result of an 'usual argument conversion'
-@* over a number.
-*/
-#define LUAI_UACNUMBER double
-
-
-/*
-@@ LUA_NUMBER_SCAN is the format for reading numbers.
-@@ LUA_NUMBER_FMT is the format for writing numbers.
-@@ lua_number2str converts a number to a string.
-@@ LUAI_MAXNUMBER2STR is maximum size of previous conversion.
-@@ lua_str2number converts a string to a number.
-*/
-#define LUA_NUMBER_SCAN "%lf"
-#define LUA_NUMBER_FMT "%.14g"
-#define lua_number2str(s,n) sprintf((s), LUA_NUMBER_FMT, (n))
-#define LUAI_MAXNUMBER2STR 32 /* 16 digits, sign, point, and \0 */
-#define lua_str2number(s,p) strtod((s), (p))
-
-
-/*
-@@ The luai_num* macros define the primitive operations over numbers.
-*/
-#if defined(LUA_CORE)
-#include <math.h>
-#define luai_numadd(a,b) ((a)+(b))
-#define luai_numsub(a,b) ((a)-(b))
-#define luai_nummul(a,b) ((a)*(b))
-#define luai_numdiv(a,b) ((a)/(b))
-#define luai_nummod(a,b) ((a) - floor((a)/(b))*(b))
-#define luai_numpow(a,b) (pow(a,b))
-#define luai_numunm(a) (-(a))
-#define luai_numeq(a,b) ((a)==(b))
-#define luai_numlt(a,b) ((a)<(b))
-#define luai_numle(a,b) ((a)<=(b))
-#define luai_numisnan(a) (!luai_numeq((a), (a)))
-#endif
-
-
-/*
-@@ lua_number2int is a macro to convert lua_Number to int.
-@@ lua_number2integer is a macro to convert lua_Number to lua_Integer.
-** CHANGE them if you know a faster way to convert a lua_Number to
-** int (with any rounding method and without throwing errors) in your
-** system. In Pentium machines, a naive typecast from double to int
-** in C is extremely slow, so any alternative is worth trying.
-*/
-
-/* On a Pentium, resort to a trick */
-#if defined(LUA_NUMBER_DOUBLE) && !defined(LUA_ANSI) && !defined(__SSE2__) && \
- (defined(__i386) || defined (_M_IX86) || defined(__i386__))
-
-/* On a Microsoft compiler, use assembler */
-#if defined(_MSC_VER)
-
-#define lua_number2int(i,d) __asm fld d __asm fistp i
-#define lua_number2integer(i,n) lua_number2int(i, n)
-
-/* the next trick should work on any Pentium, but sometimes clashes
- with a DirectX idiosyncrasy */
-#else
-
-union luai_Cast { double l_d; long l_l; };
-#define lua_number2int(i,d) \
- { volatile union luai_Cast u; u.l_d = (d) + 6755399441055744.0; (i) = u.l_l; }
-#define lua_number2integer(i,n) lua_number2int(i, n)
-
-#endif
-
-
-/* this option always works, but may be slow */
-#else
-#define lua_number2int(i,d) ((i)=(int)(d))
-#define lua_number2integer(i,d) ((i)=(lua_Integer)(d))
-
-#endif
-
-/* }================================================================== */
-
-
-/*
-@@ LUAI_USER_ALIGNMENT_T is a type that requires maximum alignment.
-** CHANGE it if your system requires alignments larger than double. (For
-** instance, if your system supports long doubles and they must be
-** aligned in 16-byte boundaries, then you should add long double in the
-** union.) Probably you do not need to change this.
-*/
-#define LUAI_USER_ALIGNMENT_T union { double u; void *s; long l; }
-
-
-/*
-@@ LUAI_THROW/LUAI_TRY define how Lua does exception handling.
-** CHANGE them if you prefer to use longjmp/setjmp even with C++
-** or if want/don't to use _longjmp/_setjmp instead of regular
-** longjmp/setjmp. By default, Lua handles errors with exceptions when
-** compiling as C++ code, with _longjmp/_setjmp when asked to use them,
-** and with longjmp/setjmp otherwise.
-*/
-#if defined(__cplusplus)
-/* C++ exceptions */
-#define LUAI_THROW(L,c) throw(c)
-#define LUAI_TRY(L,c,a) try { a } catch(...) \
- { if ((c)->status == 0) (c)->status = -1; }
-#define luai_jmpbuf int /* dummy variable */
-
-#elif defined(LUA_USE_ULONGJMP)
-/* in Unix, try _longjmp/_setjmp (more efficient) */
-#define LUAI_THROW(L,c) _longjmp((c)->b, 1)
-#define LUAI_TRY(L,c,a) if (_setjmp((c)->b) == 0) { a }
-#define luai_jmpbuf jmp_buf
-
-#else
-/* default handling with long jumps */
-#define LUAI_THROW(L,c) longjmp((c)->b, 1)
-#define LUAI_TRY(L,c,a) if (setjmp((c)->b) == 0) { a }
-#define luai_jmpbuf jmp_buf
-
-#endif
-
-
-/*
-@@ LUA_MAXCAPTURES is the maximum number of captures that a pattern
-@* can do during pattern-matching.
-** CHANGE it if you need more captures. This limit is arbitrary.
-*/
-#define LUA_MAXCAPTURES 32
-
-
-/*
-@@ lua_tmpnam is the function that the OS library uses to create a
-@* temporary name.
-@@ LUA_TMPNAMBUFSIZE is the maximum size of a name created by lua_tmpnam.
-** CHANGE them if you have an alternative to tmpnam (which is considered
-** insecure) or if you want the original tmpnam anyway. By default, Lua
-** uses tmpnam except when POSIX is available, where it uses mkstemp.
-*/
-#if defined(loslib_c) || defined(luaall_c)
-
-#if defined(LUA_USE_MKSTEMP)
-#include <unistd.h>
-#define LUA_TMPNAMBUFSIZE 32
-#define lua_tmpnam(b,e) { \
- strcpy(b, "/tmp/lua_XXXXXX"); \
- e = mkstemp(b); \
- if (e != -1) close(e); \
- e = (e == -1); }
-
-#else
-#define LUA_TMPNAMBUFSIZE L_tmpnam
-#define lua_tmpnam(b,e) { e = (tmpnam(b) == NULL); }
-#endif
-
-#endif
-
-
-/*
-@@ lua_popen spawns a new process connected to the current one through
-@* the file streams.
-** CHANGE it if you have a way to implement it in your system.
-*/
-#if defined(LUA_USE_POPEN)
-
-#define lua_popen(L,c,m) ((void)L, fflush(NULL), popen(c,m))
-#define lua_pclose(L,file) ((void)L, (pclose(file) != -1))
-
-#elif defined(LUA_WIN)
-
-#define lua_popen(L,c,m) ((void)L, _popen(c,m))
-#define lua_pclose(L,file) ((void)L, (_pclose(file) != -1))
-
-#else
-
-#define lua_popen(L,c,m) ((void)((void)c, m), \
- luaL_error(L, LUA_QL("popen") " not supported"), (FILE*)0)
-#define lua_pclose(L,file) ((void)((void)L, file), 0)
-
-#endif
-
-/*
-@@ LUA_DL_* define which dynamic-library system Lua should use.
-** CHANGE here if Lua has problems choosing the appropriate
-** dynamic-library system for your platform (either Windows' DLL, Mac's
-** dyld, or Unix's dlopen). If your system is some kind of Unix, there
-** is a good chance that it has dlopen, so LUA_DL_DLOPEN will work for
-** it. To use dlopen you also need to adapt the src/Makefile (probably
-** adding -ldl to the linker options), so Lua does not select it
-** automatically. (When you change the makefile to add -ldl, you must
-** also add -DLUA_USE_DLOPEN.)
-** If you do not want any kind of dynamic library, undefine all these
-** options.
-** By default, _WIN32 gets LUA_DL_DLL and MAC OS X gets LUA_DL_DYLD.
-*/
-#if defined(LUA_USE_DLOPEN)
-#define LUA_DL_DLOPEN
-#endif
-
-#if defined(LUA_WIN)
-#define LUA_DL_DLL
-#endif
-
-
-/*
-@@ LUAI_EXTRASPACE allows you to add user-specific data in a lua_State
-@* (the data goes just *before* the lua_State pointer).
-** CHANGE (define) this if you really need that. This value must be
-** a multiple of the maximum alignment required for your machine.
-*/
-#define LUAI_EXTRASPACE 0
-
-
-/*
-@@ luai_userstate* allow user-specific actions on threads.
-** CHANGE them if you defined LUAI_EXTRASPACE and need to do something
-** extra when a thread is created/deleted/resumed/yielded.
-*/
-#define luai_userstateopen(L) ((void)L)
-#define luai_userstateclose(L) ((void)L)
-#define luai_userstatethread(L,L1) ((void)L)
-#define luai_userstatefree(L) ((void)L)
-#define luai_userstateresume(L,n) ((void)L)
-#define luai_userstateyield(L,n) ((void)L)
-
-
-/*
-@@ LUA_INTFRMLEN is the length modifier for integer conversions
-@* in 'string.format'.
-@@ LUA_INTFRM_T is the integer type correspoding to the previous length
-@* modifier.
-** CHANGE them if your system supports long long or does not support long.
-*/
-
-#if defined(LUA_USELONGLONG)
-
-#define LUA_INTFRMLEN "ll"
-#define LUA_INTFRM_T long long
-
-#else
-
-#define LUA_INTFRMLEN "l"
-#define LUA_INTFRM_T long
-
-#endif
-
-
-
-/* =================================================================== */
-
-/*
-** Local configuration. You can use this space to add your redefinitions
-** without modifying the main part of the file.
-*/
-
-
-
-#endif
-
diff --git a/crawl-ref/source/util/lua/src/lualib.h b/crawl-ref/source/util/lua/src/lualib.h
deleted file mode 100644
index 469417f670..0000000000
--- a/crawl-ref/source/util/lua/src/lualib.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
-** $Id: lualib.h,v 1.36.1.1 2007/12/27 13:02:25 roberto Exp $
-** Lua standard libraries
-** See Copyright Notice in lua.h
-*/
-
-
-#ifndef lualib_h
-#define lualib_h
-
-#include "lua.h"
-
-
-/* Key to file-handle type */
-#define LUA_FILEHANDLE "FILE*"
-
-
-#define LUA_COLIBNAME "coroutine"
-LUALIB_API int (luaopen_base) (lua_State *L);
-
-#define LUA_TABLIBNAME "table"
-LUALIB_API int (luaopen_table) (lua_State *L);
-
-#define LUA_IOLIBNAME "io"
-LUALIB_API int (luaopen_io) (lua_State *L);
-
-#define LUA_OSLIBNAME "os"
-LUALIB_API int (luaopen_os) (lua_State *L);
-
-#define LUA_STRLIBNAME "string"
-LUALIB_API int (luaopen_string) (lua_State *L);
-
-#define LUA_MATHLIBNAME "math"
-LUALIB_API int (luaopen_math) (lua_State *L);
-
-#define LUA_DBLIBNAME "debug"
-LUALIB_API int (luaopen_debug) (lua_State *L);
-
-#define LUA_LOADLIBNAME "package"
-LUALIB_API int (luaopen_package) (lua_State *L);
-
-
-/* open all previous libraries */
-LUALIB_API void (luaL_openlibs) (lua_State *L);
-
-
-
-#ifndef lua_assert
-#define lua_assert(x) ((void)0)
-#endif
-
-
-#endif
diff --git a/crawl-ref/source/util/lua/src/lundump.c b/crawl-ref/source/util/lua/src/lundump.c
deleted file mode 100644
index 69021ddae0..0000000000
--- a/crawl-ref/source/util/lua/src/lundump.c
+++ /dev/null
@@ -1,271 +0,0 @@
-/*
-** $Id: lundump.c,v 2.7.1.4 2008/04/04 19:51:41 roberto Exp $
-** load precompiled Lua chunks
-** See Copyright Notice in lua.h
-*/
-
-#include <string.h>
-
-#define lundump_c
-#define LUA_CORE
-
-#include "lua.h"
-
-#include "ldebug.h"
-#include "ldo.h"
-#include "lfunc.h"
-#include "lmem.h"
-#include "lobject.h"
-#include "lstring.h"
-#include "lundump.h"
-#include "lzio.h"
-
-typedef struct {
- lua_State* L;
- ZIO* Z;
- Mbuffer* b;
- const char* name;
- int swap;
-} LoadState;
-
-#ifdef LUAC_TRUST_BINARIES
-#define IF(c,s)
-#define error(S,s)
-#else
-#define IF(c,s) if (c) error(S,s)
-
-static void error(LoadState* S, const char* why)
-{
- luaO_pushfstring(S->L,"%s: %s in precompiled chunk",S->name,why);
- luaD_throw(S->L,LUA_ERRSYNTAX);
-}
-#endif
-
-#define LoadByte(S) (lu_byte)LoadChar(S)
-#define LoadVar(S,x) LoadMem(S,&x,1,sizeof(x))
-#define LoadVector(S,b,n,size) LoadMem(S,b,n,size)
-
-static void LoadBlock(LoadState* S, void* b, size_t size)
-{
- size_t r=luaZ_read(S->Z,b,size);
- IF (r!=0, "unexpected end");
-}
-
-static void LoadMem (LoadState* S, void* b, int n, size_t size)
-{
- LoadBlock(S,b,n*size);
- if (S->swap)
- {
- char* p=(char*) b;
- char c;
- switch (size)
- {
- case 1:
- break;
- case 2:
- while (n--)
- {
- c=p[0]; p[0]=p[1]; p[1]=c;
- p+=2;
- }
- break;
- case 4:
- while (n--)
- {
- c=p[0]; p[0]=p[3]; p[3]=c;
- c=p[1]; p[1]=p[2]; p[2]=c;
- p+=4;
- }
- break;
- case 8:
- while (n--)
- {
- c=p[0]; p[0]=p[7]; p[7]=c;
- c=p[1]; p[1]=p[6]; p[6]=c;
- c=p[2]; p[2]=p[5]; p[5]=c;
- c=p[3]; p[3]=p[4]; p[4]=c;
- p+=8;
- }
- break;
- default:
- IF(1, "bad size");
- break;
- }
- }
-}
-
-static int LoadChar(LoadState* S)
-{
- char x;
- LoadVar(S,x);
- return x;
-}
-
-static int LoadInt(LoadState* S)
-{
- int x;
- LoadVar(S,x);
- IF (x<0, "bad integer");
- return x;
-}
-
-static lua_Number LoadNumber(LoadState* S)
-{
- lua_Number x;
- LoadVar(S,x);
- return x;
-}
-
-static TString* LoadString(LoadState* S)
-{
- unsigned int size;
- LoadVar(S,size);
- if (size==0)
- return NULL;
- else
- {
- char* s=luaZ_openspace(S->L,S->b,size);
- LoadBlock(S,s,size);
- return luaS_newlstr(S->L,s,size-1); /* remove trailing '\0' */
- }
-}
-
-static void LoadCode(LoadState* S, Proto* f)
-{
- int n=LoadInt(S);
- f->code=luaM_newvector(S->L,n,Instruction);
- f->sizecode=n;
- LoadVector(S,f->code,n,sizeof(Instruction));
-}
-
-static Proto* LoadFunction(LoadState* S, TString* p);
-
-static void LoadConstants(LoadState* S, Proto* f)
-{
- int i,n;
- n=LoadInt(S);
- f->k=luaM_newvector(S->L,n,TValue);
- f->sizek=n;
- for (i=0; i<n; i++) setnilvalue(&f->k[i]);
- for (i=0; i<n; i++)
- {
- TValue* o=&f->k[i];
- int t=LoadChar(S);
- switch (t)
- {
- case LUA_TNIL:
- setnilvalue(o);
- break;
- case LUA_TBOOLEAN:
- setbvalue(o,LoadChar(S)!=0);
- break;
- case LUA_TNUMBER:
- setnvalue(o,LoadNumber(S));
- break;
- case LUA_TSTRING:
- setsvalue2n(S->L,o,LoadString(S));
- break;
- default:
- error(S,"bad constant");
- break;
- }
- }
- n=LoadInt(S);
- f->p=luaM_newvector(S->L,n,Proto*);
- f->sizep=n;
- for (i=0; i<n; i++) f->p[i]=NULL;
- for (i=0; i<n; i++) f->p[i]=LoadFunction(S,f->source);
-}
-
-static void LoadDebug(LoadState* S, Proto* f)
-{
- int i,n;
- n=LoadInt(S);
- f->lineinfo=luaM_newvector(S->L,n,int);
- f->sizelineinfo=n;
- LoadVector(S,f->lineinfo,n,sizeof(int));
- n=LoadInt(S);
- f->locvars=luaM_newvector(S->L,n,LocVar);
- f->sizelocvars=n;
- for (i=0; i<n; i++) f->locvars[i].varname=NULL;
- for (i=0; i<n; i++)
- {
- f->locvars[i].varname=LoadString(S);
- f->locvars[i].startpc=LoadInt(S);
- f->locvars[i].endpc=LoadInt(S);
- }
- n=LoadInt(S);
- f->upvalues=luaM_newvector(S->L,n,TString*);
- f->sizeupvalues=n;
- for (i=0; i<n; i++) f->upvalues[i]=NULL;
- for (i=0; i<n; i++) f->upvalues[i]=LoadString(S);
-}
-
-static Proto* LoadFunction(LoadState* S, TString* p)
-{
- Proto* f;
- if (++S->L->nCcalls > LUAI_MAXCCALLS) error(S,"code too deep");
- f=luaF_newproto(S->L);
- setptvalue2s(S->L,S->L->top,f); incr_top(S->L);
- f->source=LoadString(S); if (f->source==NULL) f->source=p;
- f->linedefined=LoadInt(S);
- f->lastlinedefined=LoadInt(S);
- f->nups=LoadByte(S);
- f->numparams=LoadByte(S);
- f->is_vararg=LoadByte(S);
- f->maxstacksize=LoadByte(S);
- LoadCode(S,f);
- LoadConstants(S,f);
- LoadDebug(S,f);
- IF (!luaG_checkcode(f), "bad code");
- S->L->top--;
- S->L->nCcalls--;
- return f;
-}
-
-static void LoadHeader(LoadState* S)
-{
- char h[LUAC_HEADERSIZE];
- char s[LUAC_HEADERSIZE];
- luaU_header(h);
- LoadBlock(S,s,LUAC_HEADERSIZE);
- S->swap=(s[6]!=h[6]); s[6]=h[6];
- IF (memcmp(h,s,LUAC_HEADERSIZE)!=0, "bad header");
-}
-
-/*
-** load precompiled chunk
-*/
-Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name)
-{
- LoadState S;
- if (*name=='@' || *name=='=')
- S.name=name+1;
- else if (*name==LUA_SIGNATURE[0])
- S.name="binary string";
- else
- S.name=name;
- S.L=L;
- S.Z=Z;
- S.b=buff;
- LoadHeader(&S);
- return LoadFunction(&S,luaS_newliteral(L,"=?"));
-}
-
-/*
-* make header
-*/
-void luaU_header (char* h)
-{
- int x=1;
- memcpy(h,LUA_SIGNATURE,sizeof(LUA_SIGNATURE)-1);
- h+=sizeof(LUA_SIGNATURE)-1;
- *h++=(char)LUAC_VERSION;
- *h++=(char)LUAC_FORMAT;
- *h++=(char)*(char*)&x; /* endianness */
- *h++=(char)sizeof(int);
- *h++=(char)sizeof(unsigned int);
- *h++=(char)sizeof(Instruction);
- *h++=(char)sizeof(lua_Number);
- *h++=(char)(((lua_Number)0.5)==0); /* is lua_Number integral? */
-}
diff --git a/crawl-ref/source/util/lua/src/lundump.h b/crawl-ref/source/util/lua/src/lundump.h
deleted file mode 100644
index c80189dbff..0000000000
--- a/crawl-ref/source/util/lua/src/lundump.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
-** $Id: lundump.h,v 1.37.1.1 2007/12/27 13:02:25 roberto Exp $
-** load precompiled Lua chunks
-** See Copyright Notice in lua.h
-*/
-
-#ifndef lundump_h
-#define lundump_h
-
-#include "lobject.h"
-#include "lzio.h"
-
-/* load one chunk; from lundump.c */
-LUAI_FUNC Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name);
-
-/* make header; from lundump.c */
-LUAI_FUNC void luaU_header (char* h);
-
-/* dump one chunk; from ldump.c */
-LUAI_FUNC int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip);
-
-#ifdef luac_c
-/* print one chunk; from print.c */
-LUAI_FUNC void luaU_print (const Proto* f, int full);
-#endif
-
-/* for header of binary files -- this is Lua 5.1 */
-#define LUAC_VERSION 0x51
-
-/* for header of binary files -- this is the official format */
-#define LUAC_FORMAT 0
-
-/* size of header of binary files */
-#define LUAC_HEADERSIZE 12
-
-#endif
diff --git a/crawl-ref/source/util/lua/src/lvm.c b/crawl-ref/source/util/lua/src/lvm.c
deleted file mode 100644
index ee3256ab94..0000000000
--- a/crawl-ref/source/util/lua/src/lvm.c
+++ /dev/null
@@ -1,763 +0,0 @@
-/*
-** $Id: lvm.c,v 2.63.1.3 2007/12/28 15:32:23 roberto Exp $
-** Lua virtual machine
-** See Copyright Notice in lua.h
-*/
-
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#define lvm_c
-#define LUA_CORE
-
-#include "lua.h"
-
-#include "ldebug.h"
-#include "ldo.h"
-#include "lfunc.h"
-#include "lgc.h"
-#include "lobject.h"
-#include "lopcodes.h"
-#include "lstate.h"
-#include "lstring.h"
-#include "ltable.h"
-#include "ltm.h"
-#include "lvm.h"
-
-
-
-/* limit for table tag-method chains (to avoid loops) */
-#define MAXTAGLOOP 100
-
-
-const TValue *luaV_tonumber (const TValue *obj, TValue *n) {
- lua_Number num;
- if (ttisnumber(obj)) return obj;
- if (ttisstring(obj) && luaO_str2d(svalue(obj), &num)) {
- setnvalue(n, num);
- return n;
- }
- else
- return NULL;
-}
-
-
-int luaV_tostring (lua_State *L, StkId obj) {
- if (!ttisnumber(obj))
- return 0;
- else {
- char s[LUAI_MAXNUMBER2STR];
- lua_Number n = nvalue(obj);
- lua_number2str(s, n);
- setsvalue2s(L, obj, luaS_new(L, s));
- return 1;
- }
-}
-
-
-static void traceexec (lua_State *L, const Instruction *pc) {
- lu_byte mask = L->hookmask;
- const Instruction *oldpc = L->savedpc;
- L->savedpc = pc;
- if ((mask & LUA_MASKCOUNT) && L->hookcount == 0) {
- resethookcount(L);
- luaD_callhook(L, LUA_HOOKCOUNT, -1);
- }
- if (mask & LUA_MASKLINE) {
- Proto *p = ci_func(L->ci)->l.p;
- int npc = pcRel(pc, p);
- int newline = getline(p, npc);
- /* call linehook when enter a new function, when jump back (loop),
- or when enter a new line */
- if (npc == 0 || pc <= oldpc || newline != getline(p, pcRel(oldpc, p)))
- luaD_callhook(L, LUA_HOOKLINE, newline);
- }
-}
-
-
-static void callTMres (lua_State *L, StkId res, const TValue *f,
- const TValue *p1, const TValue *p2) {
- ptrdiff_t result = savestack(L, res);
- setobj2s(L, L->top, f); /* push function */
- setobj2s(L, L->top+1, p1); /* 1st argument */
- setobj2s(L, L->top+2, p2); /* 2nd argument */
- luaD_checkstack(L, 3);
- L->top += 3;
- luaD_call(L, L->top - 3, 1);
- res = restorestack(L, result);
- L->top--;
- setobjs2s(L, res, L->top);
-}
-
-
-
-static void callTM (lua_State *L, const TValue *f, const TValue *p1,
- const TValue *p2, const TValue *p3) {
- setobj2s(L, L->top, f); /* push function */
- setobj2s(L, L->top+1, p1); /* 1st argument */
- setobj2s(L, L->top+2, p2); /* 2nd argument */
- setobj2s(L, L->top+3, p3); /* 3th argument */
- luaD_checkstack(L, 4);
- L->top += 4;
- luaD_call(L, L->top - 4, 0);
-}
-
-
-void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) {
- int loop;
- for (loop = 0; loop < MAXTAGLOOP; loop++) {
- const TValue *tm;
- if (ttistable(t)) { /* `t' is a table? */
- Table *h = hvalue(t);
- const TValue *res = luaH_get(h, key); /* do a primitive get */
- if (!ttisnil(res) || /* result is no nil? */
- (tm = fasttm(L, h->metatable, TM_INDEX)) == NULL) { /* or no TM? */
- setobj2s(L, val, res);
- return;
- }
- /* else will try the tag method */
- }
- else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_INDEX)))
- luaG_typeerror(L, t, "index");
- if (ttisfunction(tm)) {
- callTMres(L, val, tm, t, key);
- return;
- }
- t = tm; /* else repeat with `tm' */
- }
- luaG_runerror(L, "loop in gettable");
-}
-
-
-void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) {
- int loop;
- for (loop = 0; loop < MAXTAGLOOP; loop++) {
- const TValue *tm;
- if (ttistable(t)) { /* `t' is a table? */
- Table *h = hvalue(t);
- TValue *oldval = luaH_set(L, h, key); /* do a primitive set */
- if (!ttisnil(oldval) || /* result is no nil? */
- (tm = fasttm(L, h->metatable, TM_NEWINDEX)) == NULL) { /* or no TM? */
- setobj2t(L, oldval, val);
- luaC_barriert(L, h, val);
- return;
- }
- /* else will try the tag method */
- }
- else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX)))
- luaG_typeerror(L, t, "index");
- if (ttisfunction(tm)) {
- callTM(L, tm, t, key, val);
- return;
- }
- t = tm; /* else repeat with `tm' */
- }
- luaG_runerror(L, "loop in settable");
-}
-
-
-static int call_binTM (lua_State *L, const TValue *p1, const TValue *p2,
- StkId res, TMS event) {
- const TValue *tm = luaT_gettmbyobj(L, p1, event); /* try first operand */
- if (ttisnil(tm))
- tm = luaT_gettmbyobj(L, p2, event); /* try second operand */
- if (ttisnil(tm)) return 0;
- callTMres(L, res, tm, p1, p2);
- return 1;
-}
-
-
-static const TValue *get_compTM (lua_State *L, Table *mt1, Table *mt2,
- TMS event) {
- const TValue *tm1 = fasttm(L, mt1, event);
- const TValue *tm2;
- if (tm1 == NULL) return NULL; /* no metamethod */
- if (mt1 == mt2) return tm1; /* same metatables => same metamethods */
- tm2 = fasttm(L, mt2, event);
- if (tm2 == NULL) return NULL; /* no metamethod */
- if (luaO_rawequalObj(tm1, tm2)) /* same metamethods? */
- return tm1;
- return NULL;
-}
-
-
-static int call_orderTM (lua_State *L, const TValue *p1, const TValue *p2,
- TMS event) {
- const TValue *tm1 = luaT_gettmbyobj(L, p1, event);
- const TValue *tm2;
- if (ttisnil(tm1)) return -1; /* no metamethod? */
- tm2 = luaT_gettmbyobj(L, p2, event);
- if (!luaO_rawequalObj(tm1, tm2)) /* different metamethods? */
- return -1;
- callTMres(L, L->top, tm1, p1, p2);
- return !l_isfalse(L->top);
-}
-
-
-static int l_strcmp (const TString *ls, const TString *rs) {
- const char *l = getstr(ls);
- size_t ll = ls->tsv.len;
- const char *r = getstr(rs);
- size_t lr = rs->tsv.len;
- for (;;) {
- int temp = strcoll(l, r);
- if (temp != 0) return temp;
- else { /* strings are equal up to a `\0' */
- size_t len = strlen(l); /* index of first `\0' in both strings */
- if (len == lr) /* r is finished? */
- return (len == ll) ? 0 : 1;
- else if (len == ll) /* l is finished? */
- return -1; /* l is smaller than r (because r is not finished) */
- /* both strings longer than `len'; go on comparing (after the `\0') */
- len++;
- l += len; ll -= len; r += len; lr -= len;
- }
- }
-}
-
-
-int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) {
- int res;
- if (ttype(l) != ttype(r))
- return luaG_ordererror(L, l, r);
- else if (ttisnumber(l))
- return luai_numlt(nvalue(l), nvalue(r));
- else if (ttisstring(l))
- return l_strcmp(rawtsvalue(l), rawtsvalue(r)) < 0;
- else if ((res = call_orderTM(L, l, r, TM_LT)) != -1)
- return res;
- return luaG_ordererror(L, l, r);
-}
-
-
-static int lessequal (lua_State *L, const TValue *l, const TValue *r) {
- int res;
- if (ttype(l) != ttype(r))
- return luaG_ordererror(L, l, r);
- else if (ttisnumber(l))
- return luai_numle(nvalue(l), nvalue(r));
- else if (ttisstring(l))
- return l_strcmp(rawtsvalue(l), rawtsvalue(r)) <= 0;
- else if ((res = call_orderTM(L, l, r, TM_LE)) != -1) /* first try `le' */
- return res;
- else if ((res = call_orderTM(L, r, l, TM_LT)) != -1) /* else try `lt' */
- return !res;
- return luaG_ordererror(L, l, r);
-}
-
-
-int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2) {
- const TValue *tm;
- lua_assert(ttype(t1) == ttype(t2));
- switch (ttype(t1)) {
- case LUA_TNIL: return 1;
- case LUA_TNUMBER: return luai_numeq(nvalue(t1), nvalue(t2));
- case LUA_TBOOLEAN: return bvalue(t1) == bvalue(t2); /* true must be 1 !! */
- case LUA_TLIGHTUSERDATA: return pvalue(t1) == pvalue(t2);
- case LUA_TUSERDATA: {
- if (uvalue(t1) == uvalue(t2)) return 1;
- tm = get_compTM(L, uvalue(t1)->metatable, uvalue(t2)->metatable,
- TM_EQ);
- break; /* will try TM */
- }
- case LUA_TTABLE: {
- if (hvalue(t1) == hvalue(t2)) return 1;
- tm = get_compTM(L, hvalue(t1)->metatable, hvalue(t2)->metatable, TM_EQ);
- break; /* will try TM */
- }
- default: return gcvalue(t1) == gcvalue(t2);
- }
- if (tm == NULL) return 0; /* no TM? */
- callTMres(L, L->top, tm, t1, t2); /* call TM */
- return !l_isfalse(L->top);
-}
-
-
-void luaV_concat (lua_State *L, int total, int last) {
- do {
- StkId top = L->base + last + 1;
- int n = 2; /* number of elements handled in this pass (at least 2) */
- if (!(ttisstring(top-2) || ttisnumber(top-2)) || !tostring(L, top-1)) {
- if (!call_binTM(L, top-2, top-1, top-2, TM_CONCAT))
- luaG_concaterror(L, top-2, top-1);
- } else if (tsvalue(top-1)->len == 0) /* second op is empty? */
- (void)tostring(L, top - 2); /* result is first op (as string) */
- else {
- /* at least two string values; get as many as possible */
- size_t tl = tsvalue(top-1)->len;
- char *buffer;
- int i;
- /* collect total length */
- for (n = 1; n < total && tostring(L, top-n-1); n++) {
- size_t l = tsvalue(top-n-1)->len;
- if (l >= MAX_SIZET - tl) luaG_runerror(L, "string length overflow");
- tl += l;
- }
- buffer = luaZ_openspace(L, &G(L)->buff, tl);
- tl = 0;
- for (i=n; i>0; i--) { /* concat all strings */
- size_t l = tsvalue(top-i)->len;
- memcpy(buffer+tl, svalue(top-i), l);
- tl += l;
- }
- setsvalue2s(L, top-n, luaS_newlstr(L, buffer, tl));
- }
- total -= n-1; /* got `n' strings to create 1 new */
- last -= n-1;
- } while (total > 1); /* repeat until only 1 result left */
-}
-
-
-static void Arith (lua_State *L, StkId ra, const TValue *rb,
- const TValue *rc, TMS op) {
- TValue tempb, tempc;
- const TValue *b, *c;
- if ((b = luaV_tonumber(rb, &tempb)) != NULL &&
- (c = luaV_tonumber(rc, &tempc)) != NULL) {
- lua_Number nb = nvalue(b), nc = nvalue(c);
- switch (op) {
- case TM_ADD: setnvalue(ra, luai_numadd(nb, nc)); break;
- case TM_SUB: setnvalue(ra, luai_numsub(nb, nc)); break;
- case TM_MUL: setnvalue(ra, luai_nummul(nb, nc)); break;
- case TM_DIV: setnvalue(ra, luai_numdiv(nb, nc)); break;
- case TM_MOD: setnvalue(ra, luai_nummod(nb, nc)); break;
- case TM_POW: setnvalue(ra, luai_numpow(nb, nc)); break;
- case TM_UNM: setnvalue(ra, luai_numunm(nb)); break;
- default: lua_assert(0); break;
- }
- }
- else if (!call_binTM(L, rb, rc, ra, op))
- luaG_aritherror(L, rb, rc);
-}
-
-
-
-/*
-** some macros for common tasks in `luaV_execute'
-*/
-
-#define runtime_check(L, c) { if (!(c)) break; }
-
-#define RA(i) (base+GETARG_A(i))
-/* to be used after possible stack reallocation */
-#define RB(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgR, base+GETARG_B(i))
-#define RC(i) check_exp(getCMode(GET_OPCODE(i)) == OpArgR, base+GETARG_C(i))
-#define RKB(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgK, \
- ISK(GETARG_B(i)) ? k+INDEXK(GETARG_B(i)) : base+GETARG_B(i))
-#define RKC(i) check_exp(getCMode(GET_OPCODE(i)) == OpArgK, \
- ISK(GETARG_C(i)) ? k+INDEXK(GETARG_C(i)) : base+GETARG_C(i))
-#define KBx(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgK, k+GETARG_Bx(i))
-
-
-#define dojump(L,pc,i) {(pc) += (i); luai_threadyield(L);}
-
-
-#define Protect(x) { L->savedpc = pc; {x;}; base = L->base; }
-
-
-#define arith_op(op,tm) { \
- TValue *rb = RKB(i); \
- TValue *rc = RKC(i); \
- if (ttisnumber(rb) && ttisnumber(rc)) { \
- lua_Number nb = nvalue(rb), nc = nvalue(rc); \
- setnvalue(ra, op(nb, nc)); \
- } \
- else \
- Protect(Arith(L, ra, rb, rc, tm)); \
- }
-
-
-
-void luaV_execute (lua_State *L, int nexeccalls) {
- LClosure *cl;
- StkId base;
- TValue *k;
- const Instruction *pc;
- reentry: /* entry point */
- lua_assert(isLua(L->ci));
- pc = L->savedpc;
- cl = &clvalue(L->ci->func)->l;
- base = L->base;
- k = cl->p->k;
- /* main loop of interpreter */
- for (;;) {
- const Instruction i = *pc++;
- StkId ra;
- if ((L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)) &&
- (--L->hookcount == 0 || L->hookmask & LUA_MASKLINE)) {
- traceexec(L, pc);
- if (L->status == LUA_YIELD) { /* did hook yield? */
- L->savedpc = pc - 1;
- return;
- }
- base = L->base;
- }
- /* warning!! several calls may realloc the stack and invalidate `ra' */
- ra = RA(i);
- lua_assert(base == L->base && L->base == L->ci->base);
- lua_assert(base <= L->top && L->top <= L->stack + L->stacksize);
- lua_assert(L->top == L->ci->top || luaG_checkopenop(i));
- switch (GET_OPCODE(i)) {
- case OP_MOVE: {
- setobjs2s(L, ra, RB(i));
- continue;
- }
- case OP_LOADK: {
- setobj2s(L, ra, KBx(i));
- continue;
- }
- case OP_LOADBOOL: {
- setbvalue(ra, GETARG_B(i));
- if (GETARG_C(i)) pc++; /* skip next instruction (if C) */
- continue;
- }
- case OP_LOADNIL: {
- TValue *rb = RB(i);
- do {
- setnilvalue(rb--);
- } while (rb >= ra);
- continue;
- }
- case OP_GETUPVAL: {
- int b = GETARG_B(i);
- setobj2s(L, ra, cl->upvals[b]->v);
- continue;
- }
- case OP_GETGLOBAL: {
- TValue g;
- TValue *rb = KBx(i);
- sethvalue(L, &g, cl->env);
- lua_assert(ttisstring(rb));
- Protect(luaV_gettable(L, &g, rb, ra));
- continue;
- }
- case OP_GETTABLE: {
- Protect(luaV_gettable(L, RB(i), RKC(i), ra));
- continue;
- }
- case OP_SETGLOBAL: {
- TValue g;
- sethvalue(L, &g, cl->env);
- lua_assert(ttisstring(KBx(i)));
- Protect(luaV_settable(L, &g, KBx(i), ra));
- continue;
- }
- case OP_SETUPVAL: {
- UpVal *uv = cl->upvals[GETARG_B(i)];
- setobj(L, uv->v, ra);
- luaC_barrier(L, uv, ra);
- continue;
- }
- case OP_SETTABLE: {
- Protect(luaV_settable(L, ra, RKB(i), RKC(i)));
- continue;
- }
- case OP_NEWTABLE: {
- int b = GETARG_B(i);
- int c = GETARG_C(i);
- sethvalue(L, ra, luaH_new(L, luaO_fb2int(b), luaO_fb2int(c)));
- Protect(luaC_checkGC(L));
- continue;
- }
- case OP_SELF: {
- StkId rb = RB(i);
- setobjs2s(L, ra+1, rb);
- Protect(luaV_gettable(L, rb, RKC(i), ra));
- continue;
- }
- case OP_ADD: {
- arith_op(luai_numadd, TM_ADD);
- continue;
- }
- case OP_SUB: {
- arith_op(luai_numsub, TM_SUB);
- continue;
- }
- case OP_MUL: {
- arith_op(luai_nummul, TM_MUL);
- continue;
- }
- case OP_DIV: {
- arith_op(luai_numdiv, TM_DIV);
- continue;
- }
- case OP_MOD: {
- arith_op(luai_nummod, TM_MOD);
- continue;
- }
- case OP_POW: {
- arith_op(luai_numpow, TM_POW);
- continue;
- }
- case OP_UNM: {
- TValue *rb = RB(i);
- if (ttisnumber(rb)) {
- lua_Number nb = nvalue(rb);
- setnvalue(ra, luai_numunm(nb));
- }
- else {
- Protect(Arith(L, ra, rb, rb, TM_UNM));
- }
- continue;
- }
- case OP_NOT: {
- int res = l_isfalse(RB(i)); /* next assignment may change this value */
- setbvalue(ra, res);
- continue;
- }
- case OP_LEN: {
- const TValue *rb = RB(i);
- switch (ttype(rb)) {
- case LUA_TTABLE: {
- setnvalue(ra, cast_num(luaH_getn(hvalue(rb))));
- break;
- }
- case LUA_TSTRING: {
- setnvalue(ra, cast_num(tsvalue(rb)->len));
- break;
- }
- default: { /* try metamethod */
- Protect(
- if (!call_binTM(L, rb, luaO_nilobject, ra, TM_LEN))
- luaG_typeerror(L, rb, "get length of");
- )
- }
- }
- continue;
- }
- case OP_CONCAT: {
- int b = GETARG_B(i);
- int c = GETARG_C(i);
- Protect(luaV_concat(L, c-b+1, c); luaC_checkGC(L));
- setobjs2s(L, RA(i), base+b);
- continue;
- }
- case OP_JMP: {
- dojump(L, pc, GETARG_sBx(i));
- continue;
- }
- case OP_EQ: {
- TValue *rb = RKB(i);
- TValue *rc = RKC(i);
- Protect(
- if (equalobj(L, rb, rc) == GETARG_A(i))
- dojump(L, pc, GETARG_sBx(*pc));
- )
- pc++;
- continue;
- }
- case OP_LT: {
- Protect(
- if (luaV_lessthan(L, RKB(i), RKC(i)) == GETARG_A(i))
- dojump(L, pc, GETARG_sBx(*pc));
- )
- pc++;
- continue;
- }
- case OP_LE: {
- Protect(
- if (lessequal(L, RKB(i), RKC(i)) == GETARG_A(i))
- dojump(L, pc, GETARG_sBx(*pc));
- )
- pc++;
- continue;
- }
- case OP_TEST: {
- if (l_isfalse(ra) != GETARG_C(i))
- dojump(L, pc, GETARG_sBx(*pc));
- pc++;
- continue;
- }
- case OP_TESTSET: {
- TValue *rb = RB(i);
- if (l_isfalse(rb) != GETARG_C(i)) {
- setobjs2s(L, ra, rb);
- dojump(L, pc, GETARG_sBx(*pc));
- }
- pc++;
- continue;
- }
- case OP_CALL: {
- int b = GETARG_B(i);
- int nresults = GETARG_C(i) - 1;
- if (b != 0) L->top = ra+b; /* else previous instruction set top */
- L->savedpc = pc;
- switch (luaD_precall(L, ra, nresults)) {
- case PCRLUA: {
- nexeccalls++;
- goto reentry; /* restart luaV_execute over new Lua function */
- }
- case PCRC: {
- /* it was a C function (`precall' called it); adjust results */
- if (nresults >= 0) L->top = L->ci->top;
- base = L->base;
- continue;
- }
- default: {
- return; /* yield */
- }
- }
- }
- case OP_TAILCALL: {
- int b = GETARG_B(i);
- if (b != 0) L->top = ra+b; /* else previous instruction set top */
- L->savedpc = pc;
- lua_assert(GETARG_C(i) - 1 == LUA_MULTRET);
- switch (luaD_precall(L, ra, LUA_MULTRET)) {
- case PCRLUA: {
- /* tail call: put new frame in place of previous one */
- CallInfo *ci = L->ci - 1; /* previous frame */
- int aux;
- StkId func = ci->func;
- StkId pfunc = (ci+1)->func; /* previous function index */
- if (L->openupval) luaF_close(L, ci->base);
- L->base = ci->base = ci->func + ((ci+1)->base - pfunc);
- for (aux = 0; pfunc+aux < L->top; aux++) /* move frame down */
- setobjs2s(L, func+aux, pfunc+aux);
- ci->top = L->top = func+aux; /* correct top */
- lua_assert(L->top == L->base + clvalue(func)->l.p->maxstacksize);
- ci->savedpc = L->savedpc;
- ci->tailcalls++; /* one more call lost */
- L->ci--; /* remove new frame */
- goto reentry;
- }
- case PCRC: { /* it was a C function (`precall' called it) */
- base = L->base;
- continue;
- }
- default: {
- return; /* yield */
- }
- }
- }
- case OP_RETURN: {
- int b = GETARG_B(i);
- if (b != 0) L->top = ra+b-1;
- if (L->openupval) luaF_close(L, base);
- L->savedpc = pc;
- b = luaD_poscall(L, ra);
- if (--nexeccalls == 0) /* was previous function running `here'? */
- return; /* no: return */
- else { /* yes: continue its execution */
- if (b) L->top = L->ci->top;
- lua_assert(isLua(L->ci));
- lua_assert(GET_OPCODE(*((L->ci)->savedpc - 1)) == OP_CALL);
- goto reentry;
- }
- }
- case OP_FORLOOP: {
- lua_Number step = nvalue(ra+2);
- lua_Number idx = luai_numadd(nvalue(ra), step); /* increment index */
- lua_Number limit = nvalue(ra+1);
- if (luai_numlt(0, step) ? luai_numle(idx, limit)
- : luai_numle(limit, idx)) {
- dojump(L, pc, GETARG_sBx(i)); /* jump back */
- setnvalue(ra, idx); /* update internal index... */
- setnvalue(ra+3, idx); /* ...and external index */
- }
- continue;
- }
- case OP_FORPREP: {
- const TValue *init = ra;
- const TValue *plimit = ra+1;
- const TValue *pstep = ra+2;
- L->savedpc = pc; /* next steps may throw errors */
- if (!tonumber(init, ra))
- luaG_runerror(L, LUA_QL("for") " initial value must be a number");
- else if (!tonumber(plimit, ra+1))
- luaG_runerror(L, LUA_QL("for") " limit must be a number");
- else if (!tonumber(pstep, ra+2))
- luaG_runerror(L, LUA_QL("for") " step must be a number");
- setnvalue(ra, luai_numsub(nvalue(ra), nvalue(pstep)));
- dojump(L, pc, GETARG_sBx(i));
- continue;
- }
- case OP_TFORLOOP: {
- StkId cb = ra + 3; /* call base */
- setobjs2s(L, cb+2, ra+2);
- setobjs2s(L, cb+1, ra+1);
- setobjs2s(L, cb, ra);
- L->top = cb+3; /* func. + 2 args (state and index) */
- Protect(luaD_call(L, cb, GETARG_C(i)));
- L->top = L->ci->top;
- cb = RA(i) + 3; /* previous call may change the stack */
- if (!ttisnil(cb)) { /* continue loop? */
- setobjs2s(L, cb-1, cb); /* save control variable */
- dojump(L, pc, GETARG_sBx(*pc)); /* jump back */
- }
- pc++;
- continue;
- }
- case OP_SETLIST: {
- int n = GETARG_B(i);
- int c = GETARG_C(i);
- int last;
- Table *h;
- if (n == 0) {
- n = cast_int(L->top - ra) - 1;
- L->top = L->ci->top;
- }
- if (c == 0) c = cast_int(*pc++);
- runtime_check(L, ttistable(ra));
- h = hvalue(ra);
- last = ((c-1)*LFIELDS_PER_FLUSH) + n;
- if (last > h->sizearray) /* needs more space? */
- luaH_resizearray(L, h, last); /* pre-alloc it at once */
- for (; n > 0; n--) {
- TValue *val = ra+n;
- setobj2t(L, luaH_setnum(L, h, last--), val);
- luaC_barriert(L, h, val);
- }
- continue;
- }
- case OP_CLOSE: {
- luaF_close(L, ra);
- continue;
- }
- case OP_CLOSURE: {
- Proto *p;
- Closure *ncl;
- int nup, j;
- p = cl->p->p[GETARG_Bx(i)];
- nup = p->nups;
- ncl = luaF_newLclosure(L, nup, cl->env);
- ncl->l.p = p;
- for (j=0; j<nup; j++, pc++) {
- if (GET_OPCODE(*pc) == OP_GETUPVAL)
- ncl->l.upvals[j] = cl->upvals[GETARG_B(*pc)];
- else {
- lua_assert(GET_OPCODE(*pc) == OP_MOVE);
- ncl->l.upvals[j] = luaF_findupval(L, base + GETARG_B(*pc));
- }
- }
- setclvalue(L, ra, ncl);
- Protect(luaC_checkGC(L));
- continue;
- }
- case OP_VARARG: {
- int b = GETARG_B(i) - 1;
- int j;
- CallInfo *ci = L->ci;
- int n = cast_int(ci->base - ci->func) - cl->p->numparams - 1;
- if (b == LUA_MULTRET) {
- Protect(luaD_checkstack(L, n));
- ra = RA(i); /* previous call may change the stack */
- b = n;
- L->top = ra + n;
- }
- for (j = 0; j < b; j++) {
- if (j < n) {
- setobjs2s(L, ra + j, ci->base - n + j);
- }
- else {
- setnilvalue(ra + j);
- }
- }
- continue;
- }
- }
- }
-}
-
diff --git a/crawl-ref/source/util/lua/src/lvm.h b/crawl-ref/source/util/lua/src/lvm.h
deleted file mode 100644
index bfe4f5678d..0000000000
--- a/crawl-ref/source/util/lua/src/lvm.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
-** $Id: lvm.h,v 2.5.1.1 2007/12/27 13:02:25 roberto Exp $
-** Lua virtual machine
-** See Copyright Notice in lua.h
-*/
-
-#ifndef lvm_h
-#define lvm_h
-
-
-#include "ldo.h"
-#include "lobject.h"
-#include "ltm.h"
-
-
-#define tostring(L,o) ((ttype(o) == LUA_TSTRING) || (luaV_tostring(L, o)))
-
-#define tonumber(o,n) (ttype(o) == LUA_TNUMBER || \
- (((o) = luaV_tonumber(o,n)) != NULL))
-
-#define equalobj(L,o1,o2) \
- (ttype(o1) == ttype(o2) && luaV_equalval(L, o1, o2))
-
-
-LUAI_FUNC int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r);
-LUAI_FUNC int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2);
-LUAI_FUNC const TValue *luaV_tonumber (const TValue *obj, TValue *n);
-LUAI_FUNC int luaV_tostring (lua_State *L, StkId obj);
-LUAI_FUNC void luaV_gettable (lua_State *L, const TValue *t, TValue *key,
- StkId val);
-LUAI_FUNC void luaV_settable (lua_State *L, const TValue *t, TValue *key,
- StkId val);
-LUAI_FUNC void luaV_execute (lua_State *L, int nexeccalls);
-LUAI_FUNC void luaV_concat (lua_State *L, int total, int last);
-
-#endif
diff --git a/crawl-ref/source/util/lua/src/lzio.c b/crawl-ref/source/util/lua/src/lzio.c
deleted file mode 100644
index 293edd59b0..0000000000
--- a/crawl-ref/source/util/lua/src/lzio.c
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
-** $Id: lzio.c,v 1.31.1.1 2007/12/27 13:02:25 roberto Exp $
-** a generic input stream interface
-** See Copyright Notice in lua.h
-*/
-
-
-#include <string.h>
-
-#define lzio_c
-#define LUA_CORE
-
-#include "lua.h"
-
-#include "llimits.h"
-#include "lmem.h"
-#include "lstate.h"
-#include "lzio.h"
-
-
-int luaZ_fill (ZIO *z) {
- size_t size;
- lua_State *L = z->L;
- const char *buff;
- lua_unlock(L);
- buff = z->reader(L, z->data, &size);
- lua_lock(L);
- if (buff == NULL || size == 0) return EOZ;
- z->n = size - 1;
- z->p = buff;
- return char2int(*(z->p++));
-}
-
-
-int luaZ_lookahead (ZIO *z) {
- if (z->n == 0) {
- if (luaZ_fill(z) == EOZ)
- return EOZ;
- else {
- z->n++; /* luaZ_fill removed first byte; put back it */
- z->p--;
- }
- }
- return char2int(*z->p);
-}
-
-
-void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, void *data) {
- z->L = L;
- z->reader = reader;
- z->data = data;
- z->n = 0;
- z->p = NULL;
-}
-
-
-/* --------------------------------------------------------------- read --- */
-size_t luaZ_read (ZIO *z, void *b, size_t n) {
- while (n) {
- size_t m;
- if (luaZ_lookahead(z) == EOZ)
- return n; /* return number of missing bytes */
- m = (n <= z->n) ? n : z->n; /* min. between n and z->n */
- memcpy(b, z->p, m);
- z->n -= m;
- z->p += m;
- b = (char *)b + m;
- n -= m;
- }
- return 0;
-}
-
-/* ------------------------------------------------------------------------ */
-char *luaZ_openspace (lua_State *L, Mbuffer *buff, size_t n) {
- if (n > buff->buffsize) {
- if (n < LUA_MINBUFFER) n = LUA_MINBUFFER;
- luaZ_resizebuffer(L, buff, n);
- }
- return buff->buffer;
-}
-
-
diff --git a/crawl-ref/source/util/lua/src/lzio.h b/crawl-ref/source/util/lua/src/lzio.h
deleted file mode 100644
index 51d695d8c1..0000000000
--- a/crawl-ref/source/util/lua/src/lzio.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
-** $Id: lzio.h,v 1.21.1.1 2007/12/27 13:02:25 roberto Exp $
-** Buffered streams
-** See Copyright Notice in lua.h
-*/
-
-
-#ifndef lzio_h
-#define lzio_h
-
-#include "lua.h"
-
-#include "lmem.h"
-
-
-#define EOZ (-1) /* end of stream */
-
-typedef struct Zio ZIO;
-
-#define char2int(c) cast(int, cast(unsigned char, (c)))
-
-#define zgetc(z) (((z)->n--)>0 ? char2int(*(z)->p++) : luaZ_fill(z))
-
-typedef struct Mbuffer {
- char *buffer;
- size_t n;
- size_t buffsize;
-} Mbuffer;
-
-#define luaZ_initbuffer(L, buff) ((buff)->buffer = NULL, (buff)->buffsize = 0)
-
-#define luaZ_buffer(buff) ((buff)->buffer)
-#define luaZ_sizebuffer(buff) ((buff)->buffsize)
-#define luaZ_bufflen(buff) ((buff)->n)
-
-#define luaZ_resetbuffer(buff) ((buff)->n = 0)
-
-
-#define luaZ_resizebuffer(L, buff, size) \
- (luaM_reallocvector(L, (buff)->buffer, (buff)->buffsize, size, char), \
- (buff)->buffsize = size)
-
-#define luaZ_freebuffer(L, buff) luaZ_resizebuffer(L, buff, 0)
-
-
-LUAI_FUNC char *luaZ_openspace (lua_State *L, Mbuffer *buff, size_t n);
-LUAI_FUNC void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader,
- void *data);
-LUAI_FUNC size_t luaZ_read (ZIO* z, void* b, size_t n); /* read next n bytes */
-LUAI_FUNC int luaZ_lookahead (ZIO *z);
-
-
-
-/* --------- Private Part ------------------ */
-
-struct Zio {
- size_t n; /* bytes still unread */
- const char *p; /* current position in buffer */
- lua_Reader reader;
- void* data; /* additional data */
- lua_State *L; /* Lua state (for reader) */
-};
-
-
-LUAI_FUNC int luaZ_fill (ZIO *z);
-
-#endif
diff --git a/crawl-ref/source/util/lua/src/print.c b/crawl-ref/source/util/lua/src/print.c
deleted file mode 100644
index e240cfc3c6..0000000000
--- a/crawl-ref/source/util/lua/src/print.c
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
-** $Id: print.c,v 1.55a 2006/05/31 13:30:05 lhf Exp $
-** print bytecodes
-** See Copyright Notice in lua.h
-*/
-
-#include <ctype.h>
-#include <stdio.h>
-
-#define luac_c
-#define LUA_CORE
-
-#include "ldebug.h"
-#include "lobject.h"
-#include "lopcodes.h"
-#include "lundump.h"
-
-#define PrintFunction luaU_print
-
-#define Sizeof(x) ((int)sizeof(x))
-#define VOID(p) ((const void*)(p))
-
-static void PrintString(const TString* ts)
-{
- const char* s=getstr(ts);
- size_t i,n=ts->tsv.len;
- putchar('"');
- for (i=0; i<n; i++)
- {
- int c=s[i];
- switch (c)
- {
- case '"': printf("\\\""); break;
- case '\\': printf("\\\\"); break;
- case '\a': printf("\\a"); break;
- case '\b': printf("\\b"); break;
- case '\f': printf("\\f"); break;
- case '\n': printf("\\n"); break;
- case '\r': printf("\\r"); break;
- case '\t': printf("\\t"); break;
- case '\v': printf("\\v"); break;
- default: if (isprint((unsigned char)c))
- putchar(c);
- else
- printf("\\%03u",(unsigned char)c);
- }
- }
- putchar('"');
-}
-
-static void PrintConstant(const Proto* f, int i)
-{
- const TValue* o=&f->k[i];
- switch (ttype(o))
- {
- case LUA_TNIL:
- printf("nil");
- break;
- case LUA_TBOOLEAN:
- printf(bvalue(o) ? "true" : "false");
- break;
- case LUA_TNUMBER:
- printf(LUA_NUMBER_FMT,nvalue(o));
- break;
- case LUA_TSTRING:
- PrintString(rawtsvalue(o));
- break;
- default: /* cannot happen */
- printf("? type=%d",ttype(o));
- break;
- }
-}
-
-static void PrintCode(const Proto* f)
-{
- const Instruction* code=f->code;
- int pc,n=f->sizecode;
- for (pc=0; pc<n; pc++)
- {
- Instruction i=code[pc];
- OpCode o=GET_OPCODE(i);
- int a=GETARG_A(i);
- int b=GETARG_B(i);
- int c=GETARG_C(i);
- int bx=GETARG_Bx(i);
- int sbx=GETARG_sBx(i);
- int line=getline(f,pc);
- printf("\t%d\t",pc+1);
- if (line>0) printf("[%d]\t",line); else printf("[-]\t");
- printf("%-9s\t",luaP_opnames[o]);
- switch (getOpMode(o))
- {
- case iABC:
- printf("%d",a);
- if (getBMode(o)!=OpArgN) printf(" %d",ISK(b) ? (-1-INDEXK(b)) : b);
- if (getCMode(o)!=OpArgN) printf(" %d",ISK(c) ? (-1-INDEXK(c)) : c);
- break;
- case iABx:
- if (getBMode(o)==OpArgK) printf("%d %d",a,-1-bx); else printf("%d %d",a,bx);
- break;
- case iAsBx:
- if (o==OP_JMP) printf("%d",sbx); else printf("%d %d",a,sbx);
- break;
- }
- switch (o)
- {
- case OP_LOADK:
- printf("\t; "); PrintConstant(f,bx);
- break;
- case OP_GETUPVAL:
- case OP_SETUPVAL:
- printf("\t; %s", (f->sizeupvalues>0) ? getstr(f->upvalues[b]) : "-");
- break;
- case OP_GETGLOBAL:
- case OP_SETGLOBAL:
- printf("\t; %s",svalue(&f->k[bx]));
- break;
- case OP_GETTABLE:
- case OP_SELF:
- if (ISK(c)) { printf("\t; "); PrintConstant(f,INDEXK(c)); }
- break;
- case OP_SETTABLE:
- case OP_ADD:
- case OP_SUB:
- case OP_MUL:
- case OP_DIV:
- case OP_POW:
- case OP_EQ:
- case OP_LT:
- case OP_LE:
- if (ISK(b) || ISK(c))
- {
- printf("\t; ");
- if (ISK(b)) PrintConstant(f,INDEXK(b)); else printf("-");
- printf(" ");
- if (ISK(c)) PrintConstant(f,INDEXK(c)); else printf("-");
- }
- break;
- case OP_JMP:
- case OP_FORLOOP:
- case OP_FORPREP:
- printf("\t; to %d",sbx+pc+2);
- break;
- case OP_CLOSURE:
- printf("\t; %p",VOID(f->p[bx]));
- break;
- case OP_SETLIST:
- if (c==0) printf("\t; %d",(int)code[++pc]);
- else printf("\t; %d",c);
- break;
- default:
- break;
- }
- printf("\n");
- }
-}
-
-#define SS(x) (x==1)?"":"s"
-#define S(x) x,SS(x)
-
-static void PrintHeader(const Proto* f)
-{
- const char* s=getstr(f->source);
- if (*s=='@' || *s=='=')
- s++;
- else if (*s==LUA_SIGNATURE[0])
- s="(bstring)";
- else
- s="(string)";
- printf("\n%s <%s:%d,%d> (%d instruction%s, %d bytes at %p)\n",
- (f->linedefined==0)?"main":"function",s,
- f->linedefined,f->lastlinedefined,
- S(f->sizecode),f->sizecode*Sizeof(Instruction),VOID(f));
- printf("%d%s param%s, %d slot%s, %d upvalue%s, ",
- f->numparams,f->is_vararg?"+":"",SS(f->numparams),
- S(f->maxstacksize),S(f->nups));
- printf("%d local%s, %d constant%s, %d function%s\n",
- S(f->sizelocvars),S(f->sizek),S(f->sizep));
-}
-
-static void PrintConstants(const Proto* f)
-{
- int i,n=f->sizek;
- printf("constants (%d) for %p:\n",n,VOID(f));
- for (i=0; i<n; i++)
- {
- printf("\t%d\t",i+1);
- PrintConstant(f,i);
- printf("\n");
- }
-}
-
-static void PrintLocals(const Proto* f)
-{
- int i,n=f->sizelocvars;
- printf("locals (%d) for %p:\n",n,VOID(f));
- for (i=0; i<n; i++)
- {
- printf("\t%d\t%s\t%d\t%d\n",
- i,getstr(f->locvars[i].varname),f->locvars[i].startpc+1,f->locvars[i].endpc+1);
- }
-}
-
-static void PrintUpvalues(const Proto* f)
-{
- int i,n=f->sizeupvalues;
- printf("upvalues (%d) for %p:\n",n,VOID(f));
- if (f->upvalues==NULL) return;
- for (i=0; i<n; i++)
- {
- printf("\t%d\t%s\n",i,getstr(f->upvalues[i]));
- }
-}
-
-void PrintFunction(const Proto* f, int full)
-{
- int i,n=f->sizep;
- PrintHeader(f);
- PrintCode(f);
- if (full)
- {
- PrintConstants(f);
- PrintLocals(f);
- PrintUpvalues(f);
- }
- for (i=0; i<n; i++) PrintFunction(f->p[i],full);
-}
diff --git a/crawl-ref/source/util/lua/test/README b/crawl-ref/source/util/lua/test/README
deleted file mode 100644
index 0c7f38bc25..0000000000
--- a/crawl-ref/source/util/lua/test/README
+++ /dev/null
@@ -1,26 +0,0 @@
-These are simple tests for Lua. Some of them contain useful code.
-They are meant to be run to make sure Lua is built correctly and also
-to be read, to see how Lua programs look.
-
-Here is a one-line summary of each program:
-
- bisect.lua bisection method for solving non-linear equations
- cf.lua temperature conversion table (celsius to farenheit)
- echo.lua echo command line arguments
- env.lua environment variables as automatic global variables
- factorial.lua factorial without recursion
- fib.lua fibonacci function with cache
- fibfor.lua fibonacci numbers with coroutines and generators
- globals.lua report global variable usage
- hello.lua the first program in every language
- life.lua Conway's Game of Life
- luac.lua bare-bones luac
- printf.lua an implementation of printf
- readonly.lua make global variables readonly
- sieve.lua the sieve of of Eratosthenes programmed with coroutines
- sort.lua two implementations of a sort function
- table.lua make table, grouping all data for the same item
- trace-calls.lua trace calls
- trace-globals.lua trace assigments to global variables
- xd.lua hex dump
-
diff --git a/crawl-ref/source/util/lua/test/bisect.lua b/crawl-ref/source/util/lua/test/bisect.lua
deleted file mode 100644
index f91e69bfba..0000000000
--- a/crawl-ref/source/util/lua/test/bisect.lua
+++ /dev/null
@@ -1,27 +0,0 @@
--- bisection method for solving non-linear equations
-
-delta=1e-6 -- tolerance
-
-function bisect(f,a,b,fa,fb)
- local c=(a+b)/2
- io.write(n," c=",c," a=",a," b=",b,"\n")
- if c==a or c==b or math.abs(a-b)<delta then return c,b-a end
- n=n+1
- local fc=f(c)
- if fa*fc<0 then return bisect(f,a,c,fa,fc) else return bisect(f,c,b,fc,fb) end
-end
-
--- find root of f in the inverval [a,b]. needs f(a)*f(b)<0
-function solve(f,a,b)
- n=0
- local z,e=bisect(f,a,b,f(a),f(b))
- io.write(string.format("after %d steps, root is %.17g with error %.1e, f=%.1e\n",n,z,e,f(z)))
-end
-
--- our function
-function f(x)
- return x*x*x-x-1
-end
-
--- find zero in [1,2]
-solve(f,1,2)
diff --git a/crawl-ref/source/util/lua/test/cf.lua b/crawl-ref/source/util/lua/test/cf.lua
deleted file mode 100644
index 8cda54b981..0000000000
--- a/crawl-ref/source/util/lua/test/cf.lua
+++ /dev/null
@@ -1,16 +0,0 @@
--- temperature conversion table (celsius to farenheit)
-
-for c0=-20,50-1,10 do
- io.write("C ")
- for c=c0,c0+10-1 do
- io.write(string.format("%3.0f ",c))
- end
- io.write("\n")
-
- io.write("F ")
- for c=c0,c0+10-1 do
- f=(9/5)*c+32
- io.write(string.format("%3.0f ",f))
- end
- io.write("\n\n")
-end
diff --git a/crawl-ref/source/util/lua/test/echo.lua b/crawl-ref/source/util/lua/test/echo.lua
deleted file mode 100644
index 4313439a85..0000000000
--- a/crawl-ref/source/util/lua/test/echo.lua
+++ /dev/null
@@ -1,5 +0,0 @@
--- echo command line arguments
-
-for i=0,table.getn(arg) do
- print(i,arg[i])
-end
diff --git a/crawl-ref/source/util/lua/test/env.lua b/crawl-ref/source/util/lua/test/env.lua
deleted file mode 100644
index 9e62a57fbf..0000000000
--- a/crawl-ref/source/util/lua/test/env.lua
+++ /dev/null
@@ -1,7 +0,0 @@
--- read environment variables as if they were global variables
-
-local f=function (t,i) return os.getenv(i) end
-setmetatable(getfenv(),{__index=f})
-
--- an example
-print(a,USER,PATH)
diff --git a/crawl-ref/source/util/lua/test/factorial.lua b/crawl-ref/source/util/lua/test/factorial.lua
deleted file mode 100644
index 7c4cf0fa45..0000000000
--- a/crawl-ref/source/util/lua/test/factorial.lua
+++ /dev/null
@@ -1,32 +0,0 @@
--- function closures are powerful
-
--- traditional fixed-point operator from functional programming
-Y = function (g)
- local a = function (f) return f(f) end
- return a(function (f)
- return g(function (x)
- local c=f(f)
- return c(x)
- end)
- end)
-end
-
-
--- factorial without recursion
-F = function (f)
- return function (n)
- if n == 0 then return 1
- else return n*f(n-1) end
- end
- end
-
-factorial = Y(F) -- factorial is the fixed point of F
-
--- now test it
-function test(x)
- io.write(x,"! = ",factorial(x),"\n")
-end
-
-for n=0,16 do
- test(n)
-end
diff --git a/crawl-ref/source/util/lua/test/fib.lua b/crawl-ref/source/util/lua/test/fib.lua
deleted file mode 100644
index 97a921b132..0000000000
--- a/crawl-ref/source/util/lua/test/fib.lua
+++ /dev/null
@@ -1,40 +0,0 @@
--- fibonacci function with cache
-
--- very inefficient fibonacci function
-function fib(n)
- N=N+1
- if n<2 then
- return n
- else
- return fib(n-1)+fib(n-2)
- end
-end
-
--- a general-purpose value cache
-function cache(f)
- local c={}
- return function (x)
- local y=c[x]
- if not y then
- y=f(x)
- c[x]=y
- end
- return y
- end
-end
-
--- run and time it
-function test(s,f)
- N=0
- local c=os.clock()
- local v=f(n)
- local t=os.clock()-c
- print(s,n,v,t,N)
-end
-
-n=arg[1] or 24 -- for other values, do lua fib.lua XX
-n=tonumber(n)
-print("","n","value","time","evals")
-test("plain",fib)
-fib=cache(fib)
-test("cached",fib)
diff --git a/crawl-ref/source/util/lua/test/fibfor.lua b/crawl-ref/source/util/lua/test/fibfor.lua
deleted file mode 100644
index 8bbba39cd7..0000000000
--- a/crawl-ref/source/util/lua/test/fibfor.lua
+++ /dev/null
@@ -1,13 +0,0 @@
--- example of for with generator functions
-
-function generatefib (n)
- return coroutine.wrap(function ()
- local a,b = 1, 1
- while a <= n do
- coroutine.yield(a)
- a, b = b, a+b
- end
- end)
-end
-
-for i in generatefib(1000) do print(i) end
diff --git a/crawl-ref/source/util/lua/test/globals.lua b/crawl-ref/source/util/lua/test/globals.lua
deleted file mode 100644
index d4c20e1565..0000000000
--- a/crawl-ref/source/util/lua/test/globals.lua
+++ /dev/null
@@ -1,13 +0,0 @@
--- reads luac listings and reports global variable usage
--- lines where a global is written to are marked with "*"
--- typical usage: luac -p -l file.lua | lua globals.lua | sort | lua table.lua
-
-while 1 do
- local s=io.read()
- if s==nil then break end
- local ok,_,l,op,g=string.find(s,"%[%-?(%d*)%]%s*([GS])ETGLOBAL.-;%s+(.*)$")
- if ok then
- if op=="S" then op="*" else op="" end
- io.write(g,"\t",l,op,"\n")
- end
-end
diff --git a/crawl-ref/source/util/lua/test/hello.lua b/crawl-ref/source/util/lua/test/hello.lua
deleted file mode 100644
index 0925498f21..0000000000
--- a/crawl-ref/source/util/lua/test/hello.lua
+++ /dev/null
@@ -1,3 +0,0 @@
--- the first program in every language
-
-io.write("Hello world, from ",_VERSION,"!\n")
diff --git a/crawl-ref/source/util/lua/test/life.lua b/crawl-ref/source/util/lua/test/life.lua
deleted file mode 100644
index 911d9fe177..0000000000
--- a/crawl-ref/source/util/lua/test/life.lua
+++ /dev/null
@@ -1,111 +0,0 @@
--- life.lua
--- original by Dave Bollinger <DBollinger@compuserve.com> posted to lua-l
--- modified to use ANSI terminal escape sequences
--- modified to use for instead of while
-
-local write=io.write
-
-ALIVE="¥" DEAD="þ"
-ALIVE="O" DEAD="-"
-
-function delay() -- NOTE: SYSTEM-DEPENDENT, adjust as necessary
- for i=1,10000 do end
- -- local i=os.clock()+1 while(os.clock()<i) do end
-end
-
-function ARRAY2D(w,h)
- local t = {w=w,h=h}
- for y=1,h do
- t[y] = {}
- for x=1,w do
- t[y][x]=0
- end
- end
- return t
-end
-
-_CELLS = {}
-
--- give birth to a "shape" within the cell array
-function _CELLS:spawn(shape,left,top)
- for y=0,shape.h-1 do
- for x=0,shape.w-1 do
- self[top+y][left+x] = shape[y*shape.w+x+1]
- end
- end
-end
-
--- run the CA and produce the next generation
-function _CELLS:evolve(next)
- local ym1,y,yp1,yi=self.h-1,self.h,1,self.h
- while yi > 0 do
- local xm1,x,xp1,xi=self.w-1,self.w,1,self.w
- while xi > 0 do
- local sum = self[ym1][xm1] + self[ym1][x] + self[ym1][xp1] +
- self[y][xm1] + self[y][xp1] +
- self[yp1][xm1] + self[yp1][x] + self[yp1][xp1]
- next[y][x] = ((sum==2) and self[y][x]) or ((sum==3) and 1) or 0
- xm1,x,xp1,xi = x,xp1,xp1+1,xi-1
- end
- ym1,y,yp1,yi = y,yp1,yp1+1,yi-1
- end
-end
-
--- output the array to screen
-function _CELLS:draw()
- local out="" -- accumulate to reduce flicker
- for y=1,self.h do
- for x=1,self.w do
- out=out..(((self[y][x]>0) and ALIVE) or DEAD)
- end
- out=out.."\n"
- end
- write(out)
-end
-
--- constructor
-function CELLS(w,h)
- local c = ARRAY2D(w,h)
- c.spawn = _CELLS.spawn
- c.evolve = _CELLS.evolve
- c.draw = _CELLS.draw
- return c
-end
-
---
--- shapes suitable for use with spawn() above
---
-HEART = { 1,0,1,1,0,1,1,1,1; w=3,h=3 }
-GLIDER = { 0,0,1,1,0,1,0,1,1; w=3,h=3 }
-EXPLODE = { 0,1,0,1,1,1,1,0,1,0,1,0; w=3,h=4 }
-FISH = { 0,1,1,1,1,1,0,0,0,1,0,0,0,0,1,1,0,0,1,0; w=5,h=4 }
-BUTTERFLY = { 1,0,0,0,1,0,1,1,1,0,1,0,0,0,1,1,0,1,0,1,1,0,0,0,1; w=5,h=5 }
-
--- the main routine
-function LIFE(w,h)
- -- create two arrays
- local thisgen = CELLS(w,h)
- local nextgen = CELLS(w,h)
-
- -- create some life
- -- about 1000 generations of fun, then a glider steady-state
- thisgen:spawn(GLIDER,5,4)
- thisgen:spawn(EXPLODE,25,10)
- thisgen:spawn(FISH,4,12)
-
- -- run until break
- local gen=1
- write("\027[2J") -- ANSI clear screen
- while 1 do
- thisgen:evolve(nextgen)
- thisgen,nextgen = nextgen,thisgen
- write("\027[H") -- ANSI home cursor
- thisgen:draw()
- write("Life - generation ",gen,"\n")
- gen=gen+1
- if gen>2000 then break end
- --delay() -- no delay
- end
-end
-
-LIFE(40,20)
diff --git a/crawl-ref/source/util/lua/test/luac.lua b/crawl-ref/source/util/lua/test/luac.lua
deleted file mode 100644
index 96a0a97ce7..0000000000
--- a/crawl-ref/source/util/lua/test/luac.lua
+++ /dev/null
@@ -1,7 +0,0 @@
--- bare-bones luac in Lua
--- usage: lua luac.lua file.lua
-
-assert(arg[1]~=nil and arg[2]==nil,"usage: lua luac.lua file.lua")
-f=assert(io.open("luac.out","wb"))
-assert(f:write(string.dump(assert(loadfile(arg[1])))))
-assert(f:close())
diff --git a/crawl-ref/source/util/lua/test/printf.lua b/crawl-ref/source/util/lua/test/printf.lua
deleted file mode 100644
index 58c63ff518..0000000000
--- a/crawl-ref/source/util/lua/test/printf.lua
+++ /dev/null
@@ -1,7 +0,0 @@
--- an implementation of printf
-
-function printf(...)
- io.write(string.format(...))
-end
-
-printf("Hello %s from %s on %s\n",os.getenv"USER" or "there",_VERSION,os.date())
diff --git a/crawl-ref/source/util/lua/test/readonly.lua b/crawl-ref/source/util/lua/test/readonly.lua
deleted file mode 100644
index 85c0b4e013..0000000000
--- a/crawl-ref/source/util/lua/test/readonly.lua
+++ /dev/null
@@ -1,12 +0,0 @@
--- make global variables readonly
-
-local f=function (t,i) error("cannot redefine global variable `"..i.."'",2) end
-local g={}
-local G=getfenv()
-setmetatable(g,{__index=G,__newindex=f})
-setfenv(1,g)
-
--- an example
-rawset(g,"x",3)
-x=2
-y=1 -- cannot redefine `y'
diff --git a/crawl-ref/source/util/lua/test/sieve.lua b/crawl-ref/source/util/lua/test/sieve.lua
deleted file mode 100644
index 0871bb2125..0000000000
--- a/crawl-ref/source/util/lua/test/sieve.lua
+++ /dev/null
@@ -1,29 +0,0 @@
--- the sieve of of Eratosthenes programmed with coroutines
--- typical usage: lua -e N=1000 sieve.lua | column
-
--- generate all the numbers from 2 to n
-function gen (n)
- return coroutine.wrap(function ()
- for i=2,n do coroutine.yield(i) end
- end)
-end
-
--- filter the numbers generated by `g', removing multiples of `p'
-function filter (p, g)
- return coroutine.wrap(function ()
- while 1 do
- local n = g()
- if n == nil then return end
- if math.mod(n, p) ~= 0 then coroutine.yield(n) end
- end
- end)
-end
-
-N=N or 1000 -- from command line
-x = gen(N) -- generate primes up to N
-while 1 do
- local n = x() -- pick a number until done
- if n == nil then break end
- print(n) -- must be a prime number
- x = filter(n, x) -- now remove its multiples
-end
diff --git a/crawl-ref/source/util/lua/test/sort.lua b/crawl-ref/source/util/lua/test/sort.lua
deleted file mode 100644
index 0bcb15f837..0000000000
--- a/crawl-ref/source/util/lua/test/sort.lua
+++ /dev/null
@@ -1,66 +0,0 @@
--- two implementations of a sort function
--- this is an example only. Lua has now a built-in function "sort"
-
--- extracted from Programming Pearls, page 110
-function qsort(x,l,u,f)
- if l<u then
- local m=math.random(u-(l-1))+l-1 -- choose a random pivot in range l..u
- x[l],x[m]=x[m],x[l] -- swap pivot to first position
- local t=x[l] -- pivot value
- m=l
- local i=l+1
- while i<=u do
- -- invariant: x[l+1..m] < t <= x[m+1..i-1]
- if f(x[i],t) then
- m=m+1
- x[m],x[i]=x[i],x[m] -- swap x[i] and x[m]
- end
- i=i+1
- end
- x[l],x[m]=x[m],x[l] -- swap pivot to a valid place
- -- x[l+1..m-1] < x[m] <= x[m+1..u]
- qsort(x,l,m-1,f)
- qsort(x,m+1,u,f)
- end
-end
-
-function selectionsort(x,n,f)
- local i=1
- while i<=n do
- local m,j=i,i+1
- while j<=n do
- if f(x[j],x[m]) then m=j end
- j=j+1
- end
- x[i],x[m]=x[m],x[i] -- swap x[i] and x[m]
- i=i+1
- end
-end
-
-function show(m,x)
- io.write(m,"\n\t")
- local i=1
- while x[i] do
- io.write(x[i])
- i=i+1
- if x[i] then io.write(",") end
- end
- io.write("\n")
-end
-
-function testsorts(x)
- local n=1
- while x[n] do n=n+1 end; n=n-1 -- count elements
- show("original",x)
- qsort(x,1,n,function (x,y) return x<y end)
- show("after quicksort",x)
- selectionsort(x,n,function (x,y) return x>y end)
- show("after reverse selection sort",x)
- qsort(x,1,n,function (x,y) return x<y end)
- show("after quicksort again",x)
-end
-
--- array to be sorted
-x={"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"}
-
-testsorts(x)
diff --git a/crawl-ref/source/util/lua/test/table.lua b/crawl-ref/source/util/lua/test/table.lua
deleted file mode 100644
index 235089c04b..0000000000
--- a/crawl-ref/source/util/lua/test/table.lua
+++ /dev/null
@@ -1,12 +0,0 @@
--- make table, grouping all data for the same item
--- input is 2 columns (item, data)
-
-local A
-while 1 do
- local l=io.read()
- if l==nil then break end
- local _,_,a,b=string.find(l,'"?([_%w]+)"?%s*(.*)$')
- if a~=A then A=a io.write("\n",a,":") end
- io.write(" ",b)
-end
-io.write("\n")
diff --git a/crawl-ref/source/util/lua/test/trace-calls.lua b/crawl-ref/source/util/lua/test/trace-calls.lua
deleted file mode 100644
index 6d7a7b3b43..0000000000
--- a/crawl-ref/source/util/lua/test/trace-calls.lua
+++ /dev/null
@@ -1,32 +0,0 @@
--- trace calls
--- example: lua -ltrace-calls bisect.lua
-
-local level=0
-
-local function hook(event)
- local t=debug.getinfo(3)
- io.write(level," >>> ",string.rep(" ",level))
- if t~=nil and t.currentline>=0 then io.write(t.short_src,":",t.currentline," ") end
- t=debug.getinfo(2)
- if event=="call" then
- level=level+1
- else
- level=level-1 if level<0 then level=0 end
- end
- if t.what=="main" then
- if event=="call" then
- io.write("begin ",t.short_src)
- else
- io.write("end ",t.short_src)
- end
- elseif t.what=="Lua" then
--- table.foreach(t,print)
- io.write(event," ",t.name or "(Lua)"," <",t.linedefined,":",t.short_src,">")
- else
- io.write(event," ",t.name or "(C)"," [",t.what,"] ")
- end
- io.write("\n")
-end
-
-debug.sethook(hook,"cr")
-level=0
diff --git a/crawl-ref/source/util/lua/test/trace-globals.lua b/crawl-ref/source/util/lua/test/trace-globals.lua
deleted file mode 100644
index 295e670caa..0000000000
--- a/crawl-ref/source/util/lua/test/trace-globals.lua
+++ /dev/null
@@ -1,38 +0,0 @@
--- trace assigments to global variables
-
-do
- -- a tostring that quotes strings. note the use of the original tostring.
- local _tostring=tostring
- local tostring=function(a)
- if type(a)=="string" then
- return string.format("%q",a)
- else
- return _tostring(a)
- end
- end
-
- local log=function (name,old,new)
- local t=debug.getinfo(3,"Sl")
- local line=t.currentline
- io.write(t.short_src)
- if line>=0 then io.write(":",line) end
- io.write(": ",name," is now ",tostring(new)," (was ",tostring(old),")","\n")
- end
-
- local g={}
- local set=function (t,name,value)
- log(name,g[name],value)
- g[name]=value
- end
- setmetatable(getfenv(),{__index=g,__newindex=set})
-end
-
--- an example
-
-a=1
-b=2
-a=10
-b=20
-b=nil
-b=200
-print(a,b,c)
diff --git a/crawl-ref/source/util/lua/test/xd.lua b/crawl-ref/source/util/lua/test/xd.lua
deleted file mode 100644
index ebc3effc06..0000000000
--- a/crawl-ref/source/util/lua/test/xd.lua
+++ /dev/null
@@ -1,14 +0,0 @@
--- hex dump
--- usage: lua xd.lua < file
-
-local offset=0
-while true do
- local s=io.read(16)
- if s==nil then return end
- io.write(string.format("%08X ",offset))
- string.gsub(s,"(.)",
- function (c) io.write(string.format("%02X ",string.byte(c))) end)
- io.write(string.rep(" ",3*(16-string.len(s))))
- io.write(" ",string.gsub(s,"%c","."),"\n")
- offset=offset+16
-end
diff --git a/crawl-ref/source/util/pcre/132html b/crawl-ref/source/util/pcre/132html
deleted file mode 100644
index 43d1358172..0000000000
--- a/crawl-ref/source/util/pcre/132html
+++ /dev/null
@@ -1,296 +0,0 @@
-#! /usr/bin/perl -w
-
-# Script to turn PCRE man pages into HTML
-
-
-# Subroutine to handle font changes and other escapes
-
-sub do_line {
-my($s) = $_[0];
-
-$s =~ s/</&#60;/g; # Deal with < and >
-$s =~ s/>/&#62;/g;
-$s =~ s"\\fI(.*?)\\f[RP]"<i>$1</i>"g;
-$s =~ s"\\fB(.*?)\\f[RP]"<b>$1</b>"g;
-$s =~ s"\\e"\\"g;
-$s =~ s/(?<=Copyright )\(c\)/&copy;/g;
-$s;
-}
-
-# Subroutine to ensure not in a paragraph
-
-sub end_para {
-if ($inpara)
- {
- print TEMP "</PRE>\n" if ($inpre);
- print TEMP "</P>\n";
- }
-$inpara = $inpre = 0;
-$wrotetext = 0;
-}
-
-# Subroutine to start a new paragraph
-
-sub new_para {
-&end_para();
-print TEMP "<P>\n";
-$inpara = 1;
-}
-
-
-# Main program
-
-$innf = 0;
-$inpara = 0;
-$inpre = 0;
-$wrotetext = 0;
-$toc = 0;
-$ref = 1;
-
-while ($#ARGV >= 0 && $ARGV[0] =~ /^-/)
- {
- $toc = 1 if $ARGV[0] eq "-toc";
- shift;
- }
-
-# Initial output to STDOUT
-
-print <<End ;
-<html>
-<head>
-<title>$ARGV[0] specification</title>
-</head>
-<body bgcolor="#FFFFFF" text="#00005A" link="#0066FF" alink="#3399FF" vlink="#2222BB">
-<h1>$ARGV[0] man page</h1>
-<p>
-Return to the <a href="index.html">PCRE index page</a>.
-</p>
-<p>
-This page is part of the PCRE HTML documentation. It was generated automatically
-from the original man page. If there is any nonsense in it, please consult the
-man page, in case the conversion went wrong.
-<br>
-End
-
-print "<ul>\n" if ($toc);
-
-open(TEMP, ">/tmp/$$") || die "Can't open /tmp/$$ for output\n";
-
-while (<STDIN>)
- {
- # Handle lines beginning with a dot
-
- if (/^\./)
- {
- # Some of the PCRE man pages used to contain instances of .br. However,
- # they should have all been removed because they cause trouble in some
- # (other) automated systems that translate man pages to HTML. Complain if
- # we find .br or .in (another macro that is deprecated).
-
- if (/^\.br/ || /^\.in/)
- {
- print STDERR "\n*** Deprecated macro encountered - rewrite needed\n";
- print STDERR "*** $_\n";
- die "*** Processing abandoned\n";
- }
-
- # Instead of .br, relevent "literal" sections are enclosed in .nf/.fi.
-
- elsif (/^\.nf/)
- {
- $innf = 1;
- }
-
- elsif (/^\.fi/)
- {
- $innf = 0;
- }
-
- # Handling .sp is subtle. If it is inside a literal section, do nothing if
- # the next line is a non literal text line; similarly, if not inside a
- # literal section, do nothing if a literal follows. The point being that
- # the <pre> and </pre> that delimit literal sections will do the spacing.
- # Always skip if no previous output.
-
- elsif (/^\.sp/)
- {
- if ($wrotetext)
- {
- $_ = <STDIN>;
- if ($inpre)
- {
- print TEMP "\n" if (/^[\s.]/);
- }
- else
- {
- print TEMP "<br>\n<br>\n" if (!/^[\s.]/);
- }
- redo; # Now process the lookahead line we just read
- }
- }
- elsif (/^\.TP/ || /^\.PP/ || /^\.P/)
- {
- &new_para();
- }
- elsif (/^\.SH\s*("?)(.*)\1/)
- {
- # Ignore the NAME section
- if ($2 =~ /^NAME\b/)
- {
- <STDIN>;
- next;
- }
-
- &end_para();
- my($title) = &do_line($2);
- if ($toc)
- {
- printf("<li><a name=\"TOC%d\" href=\"#SEC%d\">$title</a>\n",
- $ref, $ref);
- printf TEMP ("<br><a name=\"SEC%d\" href=\"#TOC1\">$title</a><br>\n",
- $ref, $ref);
- $ref++;
- }
- else
- {
- print TEMP "<br><b>\n$title\n</b><br>\n";
- }
- }
- elsif (/^\.SS\s*("?)(.*)\1/)
- {
- &end_para();
- my($title) = &do_line($2);
- print TEMP "<br><b>\n$title\n</b><br>\n";
- }
- elsif (/^\.B\s*(.*)/)
- {
- &new_para() if (!$inpara);
- $_ = &do_line($1);
- s/"(.*?)"/$1/g;
- print TEMP "<b>$_</b>\n";
- $wrotetext = 1;
- }
- elsif (/^\.I\s*(.*)/)
- {
- &new_para() if (!$inpara);
- $_ = &do_line($1);
- s/"(.*?)"/$1/g;
- print TEMP "<i>$_</i>\n";
- $wrotetext = 1;
- }
-
- # A comment that starts "HREF" takes the next line as a name that
- # is turned into a hyperlink, using the text given, which might be
- # in a special font. If it ends in () or (digits) or punctuation, they
- # aren't part of the link.
-
- elsif (/^\.\\"\s*HREF/)
- {
- $_=<STDIN>;
- chomp;
- $_ = &do_line($_);
- $_ =~ s/\s+$//;
- $_ =~ /^(?:<.>)?([^<(]+)(?:\(\))?(?:<\/.>)?(?:\(\d+\))?[.,;:]?$/;
- print TEMP "<a href=\"$1.html\">$_</a>\n";
- }
-
- # A comment that starts "HTML" inserts literal HTML
-
- elsif (/^\.\\"\s*HTML\s*(.*)/)
- {
- print TEMP $1;
- }
-
- # A comment that starts < inserts that HTML at the end of the
- # *next* input line - so as not to get a newline between them.
-
- elsif (/^\.\\"\s*(<.*>)/)
- {
- my($markup) = $1;
- $_=<STDIN>;
- chomp;
- $_ = &do_line($_);
- $_ =~ s/\s+$//;
- print TEMP "$_$markup\n";
- }
-
- # A comment that starts JOIN joins the next two lines together, with one
- # space between them. Then that line is processed. This is used in some
- # displays where two lines are needed for the "man" version. JOINSH works
- # the same, except that it assumes this is a shell command, so removes
- # continuation backslashes.
-
- elsif (/^\.\\"\s*JOIN(SH)?/)
- {
- my($one,$two);
- $one = <STDIN>;
- $two = <STDIN>;
- $one =~ s/\s*\\e\s*$// if (defined($1));
- chomp($one);
- $two =~ s/^\s+//;
- $_ = "$one $two";
- redo; # Process the joined lines
- }
-
- # Ignore anything not recognized
-
- next;
- }
-
- # Line does not begin with a dot. Replace blank lines with new paragraphs
-
- if (/^\s*$/)
- {
- &end_para() if ($wrotetext);
- next;
- }
-
- # Convert fonts changes and output an ordinary line. Ensure that indented
- # lines are marked as literal.
-
- $_ = &do_line($_);
- &new_para() if (!$inpara);
-
- if (/^\s/)
- {
- if (!$inpre)
- {
- print TEMP "<pre>\n";
- $inpre = 1;
- }
- }
- elsif ($inpre)
- {
- print TEMP "</pre>\n";
- $inpre = 0;
- }
-
- # Add <br> to the end of a non-literal line if we are within .nf/.fi
-
- $_ .= "<br>\n" if (!$inpre && $innf);
-
- print TEMP;
- $wrotetext = 1;
- }
-
-# The TOC, if present, will have been written - terminate it
-
-print "</ul>\n" if ($toc);
-
-# Copy the remainder to the standard output
-
-close(TEMP);
-open(TEMP, "/tmp/$$") || die "Can't open /tmp/$$ for input\n";
-
-print while (<TEMP>);
-
-print <<End ;
-<p>
-Return to the <a href="index.html">PCRE index page</a>.
-</p>
-End
-
-close(TEMP);
-unlink("/tmp/$$");
-
-# End
diff --git a/crawl-ref/source/util/pcre/AUTHORS b/crawl-ref/source/util/pcre/AUTHORS
deleted file mode 100644
index 88b993b698..0000000000
--- a/crawl-ref/source/util/pcre/AUTHORS
+++ /dev/null
@@ -1,23 +0,0 @@
-THE MAIN PCRE LIBRARY
----------------------
-
-Written by: Philip Hazel
-Email local part: ph10
-Email domain: cam.ac.uk
-
-University of Cambridge Computing Service,
-Cambridge, England.
-
-Copyright (c) 1997-2008 University of Cambridge
-All rights reserved
-
-
-THE C++ WRAPPER LIBRARY
------------------------
-
-Written by: Google Inc.
-
-Copyright (c) 2007-2008 Google Inc
-All rights reserved
-
-####
diff --git a/crawl-ref/source/util/pcre/CMakeLists.txt b/crawl-ref/source/util/pcre/CMakeLists.txt
deleted file mode 100644
index b71198821b..0000000000
--- a/crawl-ref/source/util/pcre/CMakeLists.txt
+++ /dev/null
@@ -1,540 +0,0 @@
-# CMakeLists.txt
-#
-#
-# This file allows building PCRE with the CMake configuration and build
-# tool. Download CMake in source or binary form from http://www.cmake.org/
-#
-# Original listfile by Christian Ehrlicher <Ch.Ehrlicher@gmx.de>
-# Refined and expanded by Daniel Richard G. <skunk@iSKUNK.ORG>
-# 2007-09-14 mod by Sheri so 7.4 supported configuration options can be entered
-# 2007-09-19 Adjusted by PH to retain previous default settings
-# 2007-12-26 (a) On UNIX, use names libpcre instead of just pcre
-# (b) Ensure pcretest and pcregrep link with the local library,
-# not a previously-installed one.
-# (c) Add PCRE_SUPPORT_LIBREADLINE, PCRE_SUPPORT_LIBZ, and
-# PCRE_SUPPORT_LIBBZ2.
-# 2008-01-20 Brought up to date to include several new features by Christian
-# Ehrlicher.
-# 2008-01-22 Sheri added options for backward compatibility of library names when
-# building with minGW:
-# if "ON", NON_STANDARD_LIB_PREFIX causes shared libraries to
-# be built without "lib" as prefix. (The libraries will be named pcre.dll,
-# pcreposix.dll and pcrecpp.dll).
-# if "ON", NON_STANDARD_LIB_SUFFIX causes shared libraries to
-# be built with suffix of "-0.dll". (The libraries will be named
-# libpcre-0.dll, libpcreposix-0.dll and libpcrecpp-0.dll - same names
-# built by default with Configure and Make.
-# 2008-01-23 PH removed the automatic build of pcredemo.
-# 2008-04-22 PH modified READLINE support so it finds NCURSES when needed.
-
-PROJECT(PCRE C CXX)
-
-CMAKE_MINIMUM_REQUIRED(VERSION 2.4.6)
-
-SET(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake) # for FindReadline.cmake
-
-# external packages
-FIND_PACKAGE( BZip2 )
-FIND_PACKAGE( ZLIB )
-FIND_PACKAGE( Readline )
-
-# Configuration checks
-
-INCLUDE(CheckIncludeFile)
-INCLUDE(CheckIncludeFileCXX)
-INCLUDE(CheckFunctionExists)
-INCLUDE(CheckTypeSize)
-
-CHECK_INCLUDE_FILE(dirent.h HAVE_DIRENT_H)
-CHECK_INCLUDE_FILE(sys/stat.h HAVE_SYS_STAT_H)
-CHECK_INCLUDE_FILE(sys/types.h HAVE_SYS_TYPES_H)
-CHECK_INCLUDE_FILE(unistd.h HAVE_UNISTD_H)
-CHECK_INCLUDE_FILE(windows.h HAVE_WINDOWS_H)
-
-CHECK_INCLUDE_FILE_CXX(type_traits.h HAVE_TYPE_TRAITS_H)
-CHECK_INCLUDE_FILE_CXX(bits/type_traits.h HAVE_BITS_TYPE_TRAITS_H)
-
-CHECK_FUNCTION_EXISTS(bcopy HAVE_BCOPY)
-CHECK_FUNCTION_EXISTS(memmove HAVE_MEMMOVE)
-CHECK_FUNCTION_EXISTS(strerror HAVE_STRERROR)
-CHECK_FUNCTION_EXISTS(strtoll HAVE_STRTOLL)
-CHECK_FUNCTION_EXISTS(strtoq HAVE_STRTOQ)
-CHECK_FUNCTION_EXISTS(_strtoi64 HAVE__STRTOI64)
-
-CHECK_TYPE_SIZE("long long" LONG_LONG)
-CHECK_TYPE_SIZE("unsigned long long" UNSIGNED_LONG_LONG)
-
-# User-configurable options
-#
-# (Note: CMakeSetup displays these in alphabetical order, regardless of
-# the order we use here)
-
-SET(BUILD_SHARED_LIBS OFF CACHE BOOL
- "Build shared libraries instead of static ones.")
-
-OPTION(PCRE_BUILD_PCRECPP "Build the PCRE C++ library (pcrecpp)." ON)
-
-SET(PCRE_EBCDIC OFF CACHE BOOL
- "Use EBCDIC coding instead of ASCII. (This is rarely used outside of mainframe systems)")
-
-SET(PCRE_LINK_SIZE "2" CACHE STRING
- "Internal link size (2, 3 or 4 allowed). See LINK_SIZE in config.h.in for details.")
-
-SET(PCRE_MATCH_LIMIT "10000000" CACHE STRING
- "Default limit on internal looping. See MATCH_LIMIT in config.h.in for details.")
-
-SET(PCRE_MATCH_LIMIT_RECURSION "MATCH_LIMIT" CACHE STRING
- "Default limit on internal recursion. See MATCH_LIMIT_RECURSION in config.h.in for details.")
-
-SET(PCRE_NEWLINE "LF" CACHE STRING
- "What to recognize as a newline (one of CR, LF, CRLF, ANY, ANYCRLF).")
-
-SET(PCRE_NO_RECURSE OFF CACHE BOOL
- "If ON, then don't use stack recursion when matching. See NO_RECURSE in config.h.in for details.")
-
-SET(PCRE_POSIX_MALLOC_THRESHOLD "10" CACHE STRING
- "Threshold for malloc() usage. See POSIX_MALLOC_THRESHOLD in config.h.in for details.")
-
-SET(PCRE_SUPPORT_UNICODE_PROPERTIES OFF CACHE BOOL
- "Enable support for Unicode properties. (If set, UTF-8 support will be enabled as well)")
-
-SET(PCRE_SUPPORT_UTF8 OFF CACHE BOOL
- "Enable support for the Unicode UTF-8 encoding.")
-
-SET(PCRE_SUPPORT_BSR_ANYCRLF OFF CACHE BOOL
- "ON=Backslash-R matches only LF CR and CRLF, OFF=Backslash-R matches all Unicode Linebreaks")
-
-
-IF (MINGW)
- OPTION(NON_STANDARD_LIB_PREFIX
- "ON=Shared libraries built in mingw will be named pcre.dll, etc., instead of libpcre.dll, etc."
- OFF)
-
- OPTION(NON_STANDARD_LIB_SUFFIX
- "ON=Shared libraries built in mingw will be named libpcre-0.dll, etc., instead of libpcre.dll, etc."
- OFF)
-ENDIF(MINGW)
-
-# bzip2 lib
-IF(BZIP2_FOUND)
- OPTION (PCRE_SUPPORT_LIBBZ2 "Enable support for linking pcregrep with libbz2." ON)
-ENDIF(BZIP2_FOUND)
-IF(PCRE_SUPPORT_LIBBZ2)
- INCLUDE_DIRECTORIES(${BZIP2_INCLUDE_DIR})
-ENDIF(PCRE_SUPPORT_LIBBZ2)
-
-# zlib
-IF(ZLIB_FOUND)
- OPTION (PCRE_SUPPORT_LIBZ "Enable support for linking pcregrep with libz." ON)
-ENDIF(ZLIB_FOUND)
-IF(PCRE_SUPPORT_LIBZ)
- INCLUDE_DIRECTORIES(${ZLIB_INCLUDE_DIR})
-ENDIF(PCRE_SUPPORT_LIBZ)
-
-# readline lib
-IF(READLINE_FOUND)
- OPTION (PCRE_SUPPORT_LIBREADLINE "Enable support for linking pcretest with libreadline." ON)
-ENDIF(READLINE_FOUND)
-IF(PCRE_SUPPORT_LIBREADLINE)
- INCLUDE_DIRECTORIES(${READLINE_INCLUDE_DIR})
-ENDIF(PCRE_SUPPORT_LIBREADLINE)
-
-# Prepare build configuration
-
-SET(pcre_have_type_traits 0)
-SET(pcre_have_bits_type_traits 0)
-
-IF(HAVE_TYPE_TRAITS_H)
- SET(pcre_have_type_traits 1)
-ENDIF(HAVE_TYPE_TRAITS_H)
-
-IF(HAVE_BITS_TYPE_TRAITS_H)
- SET(pcre_have_bits_type_traits 1)
-ENDIF(HAVE_BITS_TYPE_TRAITS_H)
-
-SET(pcre_have_long_long 0)
-SET(pcre_have_ulong_long 0)
-
-IF(HAVE_LONG_LONG)
- SET(pcre_have_long_long 1)
-ENDIF(HAVE_LONG_LONG)
-
-IF(HAVE_UNSIGNED_LONG_LONG)
- SET(pcre_have_ulong_long 1)
-ENDIF(HAVE_UNSIGNED_LONG_LONG)
-
-IF(NOT BUILD_SHARED_LIBS)
- SET(PCRE_STATIC 1)
-ENDIF(NOT BUILD_SHARED_LIBS)
-
-IF(PCRE_SUPPORT_BSR_ANYCRLF)
- SET(BSR_ANYCRLF 1)
-ENDIF(PCRE_SUPPORT_BSR_ANYCRLF)
-
-IF(PCRE_SUPPORT_UTF8 OR PCRE_SUPPORT_UNICODE_PROPERTIES)
- SET(SUPPORT_UTF8 1)
-ENDIF(PCRE_SUPPORT_UTF8 OR PCRE_SUPPORT_UNICODE_PROPERTIES)
-
-IF(PCRE_SUPPORT_UNICODE_PROPERTIES)
- SET(SUPPORT_UCP 1)
-ENDIF(PCRE_SUPPORT_UNICODE_PROPERTIES)
-
-# This next one used to contain
-# SET(PCRETEST_LIBS ${READLINE_LIBRARY})
-# but I was advised to add the NCURSES test as well, along with
-# some modifications to cmake/FindReadline.cmake which should
-# make it possible to override the default if necessary. PH
-
-IF(PCRE_SUPPORT_LIBREADLINE)
- SET(SUPPORT_LIBREADLINE 1)
- SET(PCRETEST_LIBS ${READLINE_LIBRARY} ${NCURSES_LIBRARY})
-ENDIF(PCRE_SUPPORT_LIBREADLINE)
-
-IF(PCRE_SUPPORT_LIBZ)
- SET(SUPPORT_LIBZ 1)
- SET(PCREGREP_LIBS ${PCREGREP_LIBS} ${ZLIB_LIBRARIES})
-ENDIF(PCRE_SUPPORT_LIBZ)
-
-IF(PCRE_SUPPORT_LIBBZ2)
- SET(SUPPORT_LIBBZ2 1)
- SET(PCREGREP_LIBS ${PCREGREP_LIBS} ${BZIP2_LIBRARIES})
-ENDIF(PCRE_SUPPORT_LIBBZ2)
-
-SET(NEWLINE "")
-
-IF(PCRE_NEWLINE STREQUAL "LF")
- SET(NEWLINE "10")
-ENDIF(PCRE_NEWLINE STREQUAL "LF")
-IF(PCRE_NEWLINE STREQUAL "CR")
- SET(NEWLINE "13")
-ENDIF(PCRE_NEWLINE STREQUAL "CR")
-IF(PCRE_NEWLINE STREQUAL "CRLF")
- SET(NEWLINE "3338")
-ENDIF(PCRE_NEWLINE STREQUAL "CRLF")
-IF(PCRE_NEWLINE STREQUAL "ANY")
- SET(NEWLINE "-1")
-ENDIF(PCRE_NEWLINE STREQUAL "ANY")
-IF(PCRE_NEWLINE STREQUAL "ANYCRLF")
- SET(NEWLINE "-2")
-ENDIF(PCRE_NEWLINE STREQUAL "ANYCRLF")
-
-IF(NEWLINE STREQUAL "")
- MESSAGE(FATAL_ERROR "The PCRE_NEWLINE variable must be set to one of the following values: \"LF\", \"CR\", \"CRLF\", \"ANY\", \"ANYCRLF\".")
-ENDIF(NEWLINE STREQUAL "")
-
-IF(PCRE_EBCDIC)
- SET(EBCDIC 1)
-ENDIF(PCRE_EBCDIC)
-
-IF(PCRE_NO_RECURSE)
- SET(NO_RECURSE 1)
-ENDIF(PCRE_NO_RECURSE)
-
-# Output files
-
-CONFIGURE_FILE(config-cmake.h.in
- ${CMAKE_BINARY_DIR}/config.h
- @ONLY)
-
-CONFIGURE_FILE(pcre.h.generic
- ${CMAKE_BINARY_DIR}/pcre.h
- COPYONLY)
-
-# What about pcre-config and libpcre.pc?
-
-IF(PCRE_BUILD_PCRECPP)
- CONFIGURE_FILE(pcre_stringpiece.h.in
- ${CMAKE_BINARY_DIR}/pcre_stringpiece.h
- @ONLY)
-
- CONFIGURE_FILE(pcrecpparg.h.in
- ${CMAKE_BINARY_DIR}/pcrecpparg.h
- @ONLY)
-ENDIF(PCRE_BUILD_PCRECPP)
-
-# Character table generation
-
-OPTION(PCRE_REBUILD_CHARTABLES "Rebuild char tables" OFF)
-IF(PCRE_REBUILD_CHARTABLES)
- ADD_EXECUTABLE(dftables dftables.c)
-
- GET_TARGET_PROPERTY(DFTABLES_EXE dftables LOCATION)
-
- ADD_CUSTOM_COMMAND(
- COMMENT "Generating character tables (pcre_chartables.c) for current locale"
- DEPENDS dftables
- COMMAND ${DFTABLES_EXE}
- ARGS ${CMAKE_BINARY_DIR}/pcre_chartables.c
- OUTPUT ${CMAKE_BINARY_DIR}/pcre_chartables.c
- )
-ELSE(PCRE_REBUILD_CHARTABLES)
- CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/pcre_chartables.c.dist
- ${CMAKE_BINARY_DIR}/pcre_chartables.c
- COPYONLY)
-ENDIF(PCRE_REBUILD_CHARTABLES)
-
-# Source code
-
-SET(PCRE_HEADERS ${CMAKE_BINARY_DIR}/pcre.h)
-
-SET(PCRE_SOURCES
- ${CMAKE_BINARY_DIR}/pcre_chartables.c
- pcre_compile.c
- pcre_config.c
- pcre_dfa_exec.c
- pcre_exec.c
- pcre_fullinfo.c
- pcre_get.c
- pcre_globals.c
- pcre_info.c
- pcre_newline.c
- pcre_maketables.c
- pcre_ord2utf8.c
- pcre_refcount.c
- pcre_study.c
- pcre_tables.c
- pcre_try_flipped.c
- pcre_ucp_searchfuncs.c
- pcre_valid_utf8.c
- pcre_version.c
- pcre_xclass.c
-)
-
-SET(PCREPOSIX_HEADERS pcreposix.h)
-
-SET(PCREPOSIX_SOURCES pcreposix.c)
-
-SET(PCRECPP_HEADERS
- pcrecpp.h
- pcre_scanner.h
- ${CMAKE_BINARY_DIR}/pcrecpparg.h
- ${CMAKE_BINARY_DIR}/pcre_stringpiece.h
-)
-
-SET(PCRECPP_SOURCES
- pcrecpp.cc
- pcre_scanner.cc
- pcre_stringpiece.cc
-)
-
-# Build setup
-
-ADD_DEFINITIONS(-DHAVE_CONFIG_H)
-
-IF(MSVC)
- ADD_DEFINITIONS(-D_CRT_SECURE_NO_DEPRECATE)
-ENDIF(MSVC)
-
-SET(CMAKE_INCLUDE_CURRENT_DIR 1)
-# needed to make sure to not link debug libs
-# against release libs and vice versa
-IF(WIN32)
- SET(CMAKE_DEBUG_POSTFIX "d")
-ENDIF(WIN32)
-
-# Libraries
-# pcre
-ADD_LIBRARY(pcre ${PCRE_HEADERS} ${PCRE_SOURCES} ${CMAKE_BINARY_DIR}/config.h)
-ADD_LIBRARY(pcreposix ${PCREPOSIX_HEADERS} ${PCREPOSIX_SOURCES})
-TARGET_LINK_LIBRARIES(pcreposix pcre)
-IF(MINGW AND NOT PCRE_STATIC)
- IF(NON_STANDARD_LIB_PREFIX)
- SET_TARGET_PROPERTIES(pcre pcreposix
- PROPERTIES PREFIX ""
- )
- ENDIF(NON_STANDARD_LIB_PREFIX)
-
- IF(NON_STANDARD_LIB_SUFFIX)
- SET_TARGET_PROPERTIES(pcre pcreposix
- PROPERTIES SUFFIX "-0.dll"
- )
- ENDIF(NON_STANDARD_LIB_SUFFIX)
-ENDIF(MINGW AND NOT PCRE_STATIC)
-
-
-# pcrecpp
-IF(PCRE_BUILD_PCRECPP)
- ADD_LIBRARY(pcrecpp ${PCRECPP_HEADERS} ${PCRECPP_SOURCES})
- TARGET_LINK_LIBRARIES(pcrecpp pcre)
-
- IF(MINGW AND NOT PCRE_STATIC)
- IF(NON_STANDARD_LIB_PREFIX)
- SET_TARGET_PROPERTIES(pcrecpp
- PROPERTIES PREFIX ""
- )
- ENDIF(NON_STANDARD_LIB_PREFIX)
-
- IF(NON_STANDARD_LIB_SUFFIX)
- SET_TARGET_PROPERTIES(pcrecpp
- PROPERTIES SUFFIX "-0.dll"
- )
- ENDIF(NON_STANDARD_LIB_SUFFIX)
- ENDIF(MINGW AND NOT PCRE_STATIC)
-ENDIF(PCRE_BUILD_PCRECPP)
-
-
-# Executables
-
-ADD_EXECUTABLE(pcretest pcretest.c)
-TARGET_LINK_LIBRARIES(pcretest pcreposix ${PCRETEST_LIBS})
-
-ADD_EXECUTABLE(pcregrep pcregrep.c)
-TARGET_LINK_LIBRARIES(pcregrep pcreposix ${PCREGREP_LIBS})
-
-# Removed by PH (2008-01-23) because pcredemo shouldn't really be built
-# automatically, and it gave trouble in some environments anyway.
-# ADD_EXECUTABLE(pcredemo pcredemo.c)
-# TARGET_LINK_LIBRARIES(pcredemo pcreposix)
-# IF(NOT BUILD_SHARED_LIBS)
-# # make sure to not use declspec(dllimport) in static mode on windows
-# SET_TARGET_PROPERTIES(pcredemo PROPERTIES COMPILE_FLAGS "-DPCRE_STATIC")
-# ENDIF(NOT BUILD_SHARED_LIBS)
-
-IF(PCRE_BUILD_PCRECPP)
- ADD_EXECUTABLE(pcrecpp_unittest pcrecpp_unittest.cc)
- TARGET_LINK_LIBRARIES(pcrecpp_unittest pcrecpp)
-IF(MINGW AND NON_STANDARD_LIB_NAMES AND NOT PCRE_STATIC)
-SET_TARGET_PROPERTIES(pcrecpp
- PROPERTIES PREFIX ""
-)
-ENDIF(MINGW AND NON_STANDARD_LIB_NAMES AND NOT PCRE_STATIC)
-
-
- ADD_EXECUTABLE(pcre_scanner_unittest pcre_scanner_unittest.cc)
- TARGET_LINK_LIBRARIES(pcre_scanner_unittest pcrecpp)
-
- ADD_EXECUTABLE(pcre_stringpiece_unittest pcre_stringpiece_unittest.cc)
- TARGET_LINK_LIBRARIES(pcre_stringpiece_unittest pcrecpp)
-ENDIF(PCRE_BUILD_PCRECPP)
-
-# Testing
-
-ENABLE_TESTING()
-
-GET_TARGET_PROPERTY(PCREGREP_EXE pcregrep DEBUG_LOCATION)
-GET_TARGET_PROPERTY(PCRETEST_EXE pcretest DEBUG_LOCATION)
-
-# Write out a CTest configuration file that sets some needed environment
-# variables for the test scripts.
-#
-FILE(WRITE ${CMAKE_BINARY_DIR}/CTestCustom.ctest
-"# This is a generated file.
-SET(ENV{srcdir} ${CMAKE_SOURCE_DIR})
-SET(ENV{pcregrep} ${PCREGREP_EXE})
-SET(ENV{pcretest} ${PCRETEST_EXE})
-")
-
-IF(UNIX)
- ADD_TEST(pcre_test ${CMAKE_SOURCE_DIR}/RunTest)
- ADD_TEST(pcre_grep_test ${CMAKE_SOURCE_DIR}/RunGrepTest)
-ENDIF(UNIX)
-IF(WIN32)
- ADD_TEST(pcre_test cmd /C ${CMAKE_SOURCE_DIR}/RunTest.bat)
-ENDIF(WIN32)
-
-GET_TARGET_PROPERTY(PCRECPP_UNITTEST_EXE
- pcrecpp_unittest
- DEBUG_LOCATION)
-
-GET_TARGET_PROPERTY(PCRE_SCANNER_UNITTEST_EXE
- pcre_scanner_unittest
- DEBUG_LOCATION)
-
-GET_TARGET_PROPERTY(PCRE_STRINGPIECE_UNITTEST_EXE
- pcre_stringpiece_unittest
- DEBUG_LOCATION)
-
-ADD_TEST(pcrecpp_test ${PCRECPP_UNITTEST_EXE})
-ADD_TEST(pcre_scanner_test ${PCRE_SCANNER_UNITTEST_EXE})
-ADD_TEST(pcre_stringpiece_test ${PCRE_STRINGPIECE_UNITTEST_EXE})
-
-# Installation
-
-SET(CMAKE_INSTALL_ALWAYS 1)
-
-INSTALL(TARGETS pcre pcreposix pcregrep pcretest
- RUNTIME DESTINATION bin
- LIBRARY DESTINATION lib
- ARCHIVE DESTINATION lib)
-
-INSTALL(FILES ${PCRE_HEADERS} ${PCREPOSIX_HEADERS} DESTINATION include)
-
-FILE(GLOB html ${CMAKE_SOURCE_DIR}/doc/html/*.html)
-FILE(GLOB man1 ${CMAKE_SOURCE_DIR}/doc/*.1)
-FILE(GLOB man3 ${CMAKE_SOURCE_DIR}/doc/*.3)
-
-IF(PCRE_BUILD_PCRECPP)
- INSTALL(TARGETS pcrecpp
- RUNTIME DESTINATION bin
- LIBRARY DESTINATION lib
- ARCHIVE DESTINATION lib)
- INSTALL(FILES ${PCRECPP_HEADERS} DESTINATION include)
-ELSE(PCRE_BUILD_PCRECPP)
- # Remove pcrecpp.3
- FOREACH(man ${man3})
- GET_FILENAME_COMPONENT(man_tmp ${man} NAME)
- IF(NOT man_tmp STREQUAL "pcrecpp.3")
- SET(man3_new ${man3} ${man})
- ENDIF(NOT man_tmp STREQUAL "pcrecpp.3")
- ENDFOREACH(man ${man3})
- SET(man3 ${man3_new})
-ENDIF(PCRE_BUILD_PCRECPP)
-
-
-INSTALL(FILES ${man1} DESTINATION man/man1)
-INSTALL(FILES ${man3} DESTINATION man/man3)
-INSTALL(FILES ${html} DESTINATION share/doc/pcre/html)
-
-# help, only for nice output
-IF(BUILD_SHARED_LIBS)
- SET(BUILD_STATIC_LIBS OFF)
-ELSE(BUILD_SHARED_LIBS)
- SET(BUILD_STATIC_LIBS ON)
-ENDIF(BUILD_SHARED_LIBS)
-
-MESSAGE(STATUS "")
-MESSAGE(STATUS "")
-MESSAGE(STATUS "PCRE configuration summary:")
-MESSAGE(STATUS "")
-MESSAGE(STATUS " Install prefix .................. : " ${CMAKE_INSTALL_PREFIX})
-MESSAGE(STATUS " C compiler ...................... : " ${CMAKE_C_COMPILER})
-MESSAGE(STATUS " C++ compiler .................... : " ${CMAKE_CXX_COMPILER})
-MESSAGE(STATUS " C compiler flags ................ : " ${CMAKE_C_FLAGS}) #FIXME
-MESSAGE(STATUS " C++ compiler flags .............. : " ${CMAKE_CXX_FLAGS}) #FIXME
-MESSAGE(STATUS "")
-MESSAGE(STATUS " Build C++ library ............... : " ${PCRE_BUILD_PCRECPP})
-MESSAGE(STATUS " Enable UTF-8 support ............ : " ${PCRE_SUPPORT_UNICODE_PROPERTIES})
-MESSAGE(STATUS " Unicode properties .............. : " ${PCRE_SUPPORT_UNICODE_PROPERTIES})
-MESSAGE(STATUS " Newline char/sequence ........... : " ${PCRE_NEWLINE})
-MESSAGE(STATUS " \\R matches only ANYCRLF ......... : " ${PCRE_SUPPORT_BSR_ANYCRLF})
-MESSAGE(STATUS " EBCDIC coding ................... : " ${PCRE_EBCDIC})
-MESSAGE(STATUS " Rebuild char tables ............. : " ${PCRE_REBUILD_CHARTABLES})
-MESSAGE(STATUS " No stack recursion .............. : " ${PCRE_NO_RECURSE})
-MESSAGE(STATUS " POSIX mem threshold ............. : " ${PCRE_POSIX_MALLOC_THRESHOLD})
-MESSAGE(STATUS " Internal link size .............. : " ${PCRE_LINK_SIZE})
-MESSAGE(STATUS " Match limit ..................... : " ${PCRE_MATCH_LIMIT})
-MESSAGE(STATUS " Match limit recursion ........... : " ${PCRE_MATCH_LIMIT_RECURSION})
-MESSAGE(STATUS " Build shared libs ............... : " ${BUILD_SHARED_LIBS})
-MESSAGE(STATUS " Build static libs ............... : " ${BUILD_STATIC_LIBS})
-IF(ZLIB_FOUND)
- MESSAGE(STATUS " Link pcregrep with libz ......... : " ${PCRE_SUPPORT_LIBZ})
-ELSE(ZLIB_FOUND)
- MESSAGE(STATUS " Link pcregrep with libz ......... : None" )
-ENDIF(ZLIB_FOUND)
-IF(BZIP2_FOUND)
- MESSAGE(STATUS " Link pcregrep with libbz2 ....... : " ${PCRE_SUPPORT_LIBBZ2})
-ELSE(BZIP2_FOUND)
- MESSAGE(STATUS " Link pcregrep with libbz2 ....... : None" )
-ENDIF(BZIP2_FOUND)
-IF(NOT PCRE_SUPPORT_LIBREADLINE)
- MESSAGE(STATUS " Link pcretest with libreadline .. : None" )
-ELSE(NOT PCRE_SUPPORT_LIBREADLINE)
- MESSAGE(STATUS " Link pcretest with libreadline .. : " ${PCRE_SUPPORT_LIBREADLINE})
-ENDIF(NOT PCRE_SUPPORT_LIBREADLINE)
-IF(MINGW AND NOT PCRE_STATIC)
- MESSAGE(STATUS " Non-standard dll names (prefix) . : " ${NON_STANDARD_LIB_PREFIX})
- MESSAGE(STATUS " Non-standard dll names (suffix) . : " ${NON_STANDARD_LIB_SUFFIX})
-ENDIF(MINGW AND NOT PCRE_STATIC)
-MESSAGE(STATUS "")
-
-# end CMakeLists.txt
diff --git a/crawl-ref/source/util/pcre/COPYING b/crawl-ref/source/util/pcre/COPYING
deleted file mode 100644
index 58eed01b61..0000000000
--- a/crawl-ref/source/util/pcre/COPYING
+++ /dev/null
@@ -1,5 +0,0 @@
-PCRE LICENCE
-
-Please see the file LICENCE in the PCRE distribution for licensing details.
-
-End
diff --git a/crawl-ref/source/util/pcre/ChangeLog b/crawl-ref/source/util/pcre/ChangeLog
deleted file mode 100644
index 88c69f93eb..0000000000
--- a/crawl-ref/source/util/pcre/ChangeLog
+++ /dev/null
@@ -1,3308 +0,0 @@
-ChangeLog for PCRE
-------------------
-
-Version 7.7 07-May-08
----------------------
-
-1. Applied Craig's patch to sort out a long long problem: "If we can't convert
- a string to a long long, pretend we don't even have a long long." This is
- done by checking for the strtoq, strtoll, and _strtoi64 functions.
-
-2. Applied Craig's patch to pcrecpp.cc to restore ABI compatibility with
- pre-7.6 versions, which defined a global no_arg variable instead of putting
- it in the RE class. (See also #8 below.)
-
-3. Remove a line of dead code, identified by coverity and reported by Nuno
- Lopes.
-
-4. Fixed two related pcregrep bugs involving -r with --include or --exclude:
-
- (1) The include/exclude patterns were being applied to the whole pathnames
- of files, instead of just to the final components.
-
- (2) If there was more than one level of directory, the subdirectories were
- skipped unless they satisfied the include/exclude conditions. This is
- inconsistent with GNU grep (and could even be seen as contrary to the
- pcregrep specification - which I improved to make it absolutely clear).
- The action now is always to scan all levels of directory, and just
- apply the include/exclude patterns to regular files.
-
-5. Added the --include_dir and --exclude_dir patterns to pcregrep, and used
- --exclude_dir in the tests to avoid scanning .svn directories.
-
-6. Applied Craig's patch to the QuoteMeta function so that it escapes the
- NUL character as backslash + 0 rather than backslash + NUL, because PCRE
- doesn't support NULs in patterns.
-
-7. Added some missing "const"s to declarations of static tables in
- pcre_compile.c and pcre_dfa_exec.c.
-
-8. Applied Craig's patch to pcrecpp.cc to fix a problem in OS X that was
- caused by fix #2 above. (Subsequently also a second patch to fix the
- first patch. And a third patch - this was a messy problem.)
-
-9. Applied Craig's patch to remove the use of push_back().
-
-10. Applied Alan Lehotsky's patch to add REG_STARTEND support to the POSIX
- matching function regexec().
-
-11. Added support for the Oniguruma syntax \g<name>, \g<n>, \g'name', \g'n',
- which, however, unlike Perl's \g{...}, are subroutine calls, not back
- references. PCRE supports relative numbers with this syntax (I don't think
- Oniguruma does).
-
-12. Previously, a group with a zero repeat such as (...){0} was completely
- omitted from the compiled regex. However, this means that if the group
- was called as a subroutine from elsewhere in the pattern, things went wrong
- (an internal error was given). Such groups are now left in the compiled
- pattern, with a new opcode that causes them to be skipped at execution
- time.
-
-13. Added the PCRE_JAVASCRIPT_COMPAT option. This makes the following changes
- to the way PCRE behaves:
-
- (a) A lone ] character is dis-allowed (Perl treats it as data).
-
- (b) A back reference to an unmatched subpattern matches an empty string
- (Perl fails the current match path).
-
- (c) A data ] in a character class must be notated as \] because if the
- first data character in a class is ], it defines an empty class. (In
- Perl it is not possible to have an empty class.) The empty class []
- never matches; it forces failure and is equivalent to (*FAIL) or (?!).
- The negative empty class [^] matches any one character, independently
- of the DOTALL setting.
-
-14. A pattern such as /(?2)[]a()b](abc)/ which had a forward reference to a
- non-existent subpattern following a character class starting with ']' and
- containing () gave an internal compiling error instead of "reference to
- non-existent subpattern". Fortunately, when the pattern did exist, the
- compiled code was correct. (When scanning forwards to check for the
- existencd of the subpattern, it was treating the data ']' as terminating
- the class, so got the count wrong. When actually compiling, the reference
- was subsequently set up correctly.)
-
-15. The "always fail" assertion (?!) is optimzed to (*FAIL) by pcre_compile;
- it was being rejected as not supported by pcre_dfa_exec(), even though
- other assertions are supported. I have made pcre_dfa_exec() support
- (*FAIL).
-
-16. The implementation of 13c above involved the invention of a new opcode,
- OP_ALLANY, which is like OP_ANY but doesn't check the /s flag. Since /s
- cannot be changed at match time, I realized I could make a small
- improvement to matching performance by compiling OP_ALLANY instead of
- OP_ANY for "." when DOTALL was set, and then removing the runtime tests
- on the OP_ANY path.
-
-17. Compiling pcretest on Windows with readline support failed without the
- following two fixes: (1) Make the unistd.h include conditional on
- HAVE_UNISTD_H; (2) #define isatty and fileno as _isatty and _fileno.
-
-18. Changed CMakeLists.txt and cmake/FindReadline.cmake to arrange for the
- ncurses library to be included for pcretest when ReadLine support is
- requested, but also to allow for it to be overridden. This patch came from
- Daniel Bergström.
-
-19. There was a typo in the file ucpinternal.h where f0_rangeflag was defined
- as 0x00f00000 instead of 0x00800000. Luckily, this would not have caused
- any errors with the current Unicode tables. Thanks to Peter Kankowski for
- spotting this.
-
-
-Version 7.6 28-Jan-08
----------------------
-
-1. A character class containing a very large number of characters with
- codepoints greater than 255 (in UTF-8 mode, of course) caused a buffer
- overflow.
-
-2. Patch to cut out the "long long" test in pcrecpp_unittest when
- HAVE_LONG_LONG is not defined.
-
-3. Applied Christian Ehrlicher's patch to update the CMake build files to
- bring them up to date and include new features. This patch includes:
-
- - Fixed PH's badly added libz and libbz2 support.
- - Fixed a problem with static linking.
- - Added pcredemo. [But later removed - see 7 below.]
- - Fixed dftables problem and added an option.
- - Added a number of HAVE_XXX tests, including HAVE_WINDOWS_H and
- HAVE_LONG_LONG.
- - Added readline support for pcretest.
- - Added an listing of the option settings after cmake has run.
-
-4. A user submitted a patch to Makefile that makes it easy to create
- "pcre.dll" under mingw when using Configure/Make. I added stuff to
- Makefile.am that cause it to include this special target, without
- affecting anything else. Note that the same mingw target plus all
- the other distribution libraries and programs are now supported
- when configuring with CMake (see 6 below) instead of with
- Configure/Make.
-
-5. Applied Craig's patch that moves no_arg into the RE class in the C++ code.
- This is an attempt to solve the reported problem "pcrecpp::no_arg is not
- exported in the Windows port". It has not yet been confirmed that the patch
- solves the problem, but it does no harm.
-
-6. Applied Sheri's patch to CMakeLists.txt to add NON_STANDARD_LIB_PREFIX and
- NON_STANDARD_LIB_SUFFIX for dll names built with mingw when configured
- with CMake, and also correct the comment about stack recursion.
-
-7. Remove the automatic building of pcredemo from the ./configure system and
- from CMakeLists.txt. The whole idea of pcredemo.c is that it is an example
- of a program that users should build themselves after PCRE is installed, so
- building it automatically is not really right. What is more, it gave
- trouble in some build environments.
-
-8. Further tidies to CMakeLists.txt from Sheri and Christian.
-
-
-Version 7.5 10-Jan-08
----------------------
-
-1. Applied a patch from Craig: "This patch makes it possible to 'ignore'
- values in parens when parsing an RE using the C++ wrapper."
-
-2. Negative specials like \S did not work in character classes in UTF-8 mode.
- Characters greater than 255 were excluded from the class instead of being
- included.
-
-3. The same bug as (2) above applied to negated POSIX classes such as
- [:^space:].
-
-4. PCRECPP_STATIC was referenced in pcrecpp_internal.h, but nowhere was it
- defined or documented. It seems to have been a typo for PCRE_STATIC, so
- I have changed it.
-
-5. The construct (?&) was not diagnosed as a syntax error (it referenced the
- first named subpattern) and a construct such as (?&a) would reference the
- first named subpattern whose name started with "a" (in other words, the
- length check was missing). Both these problems are fixed. "Subpattern name
- expected" is now given for (?&) (a zero-length name), and this patch also
- makes it give the same error for \k'' (previously it complained that that
- was a reference to a non-existent subpattern).
-
-6. The erroneous patterns (?+-a) and (?-+a) give different error messages;
- this is right because (?- can be followed by option settings as well as by
- digits. I have, however, made the messages clearer.
-
-7. Patterns such as (?(1)a|b) (a pattern that contains fewer subpatterns
- than the number used in the conditional) now cause a compile-time error.
- This is actually not compatible with Perl, which accepts such patterns, but
- treats the conditional as always being FALSE (as PCRE used to), but it
- seems to me that giving a diagnostic is better.
-
-8. Change "alphameric" to the more common word "alphanumeric" in comments
- and messages.
-
-9. Fix two occurrences of "backslash" in comments that should have been
- "backspace".
-
-10. Remove two redundant lines of code that can never be obeyed (their function
- was moved elsewhere).
-
-11. The program that makes PCRE's Unicode character property table had a bug
- which caused it to generate incorrect table entries for sequences of
- characters that have the same character type, but are in different scripts.
- It amalgamated them into a single range, with the script of the first of
- them. In other words, some characters were in the wrong script. There were
- thirteen such cases, affecting characters in the following ranges:
-
- U+002b0 - U+002c1
- U+0060c - U+0060d
- U+0061e - U+00612
- U+0064b - U+0065e
- U+0074d - U+0076d
- U+01800 - U+01805
- U+01d00 - U+01d77
- U+01d9b - U+01dbf
- U+0200b - U+0200f
- U+030fc - U+030fe
- U+03260 - U+0327f
- U+0fb46 - U+0fbb1
- U+10450 - U+1049d
-
-12. The -o option (show only the matching part of a line) for pcregrep was not
- compatible with GNU grep in that, if there was more than one match in a
- line, it showed only the first of them. It now behaves in the same way as
- GNU grep.
-
-13. If the -o and -v options were combined for pcregrep, it printed a blank
- line for every non-matching line. GNU grep prints nothing, and pcregrep now
- does the same. The return code can be used to tell if there were any
- non-matching lines.
-
-14. Added --file-offsets and --line-offsets to pcregrep.
-
-15. The pattern (?=something)(?R) was not being diagnosed as a potentially
- infinitely looping recursion. The bug was that positive lookaheads were not
- being skipped when checking for a possible empty match (negative lookaheads
- and both kinds of lookbehind were skipped).
-
-16. Fixed two typos in the Windows-only code in pcregrep.c, and moved the
- inclusion of <windows.h> to before rather than after the definition of
- INVALID_FILE_ATTRIBUTES (patch from David Byron).
-
-17. Specifying a possessive quantifier with a specific limit for a Unicode
- character property caused pcre_compile() to compile bad code, which led at
- runtime to PCRE_ERROR_INTERNAL (-14). Examples of patterns that caused this
- are: /\p{Zl}{2,3}+/8 and /\p{Cc}{2}+/8. It was the possessive "+" that
- caused the error; without that there was no problem.
-
-18. Added --enable-pcregrep-libz and --enable-pcregrep-libbz2.
-
-19. Added --enable-pcretest-libreadline.
-
-20. In pcrecpp.cc, the variable 'count' was incremented twice in
- RE::GlobalReplace(). As a result, the number of replacements returned was
- double what it should be. I removed one of the increments, but Craig sent a
- later patch that removed the other one (the right fix) and added unit tests
- that check the return values (which was not done before).
-
-21. Several CMake things:
-
- (1) Arranged that, when cmake is used on Unix, the libraries end up with
- the names libpcre and libpcreposix, not just pcre and pcreposix.
-
- (2) The above change means that pcretest and pcregrep are now correctly
- linked with the newly-built libraries, not previously installed ones.
-
- (3) Added PCRE_SUPPORT_LIBREADLINE, PCRE_SUPPORT_LIBZ, PCRE_SUPPORT_LIBBZ2.
-
-22. In UTF-8 mode, with newline set to "any", a pattern such as .*a.*=.b.*
- crashed when matching a string such as a\x{2029}b (note that \x{2029} is a
- UTF-8 newline character). The key issue is that the pattern starts .*;
- this means that the match must be either at the beginning, or after a
- newline. The bug was in the code for advancing after a failed match and
- checking that the new position followed a newline. It was not taking
- account of UTF-8 characters correctly.
-
-23. PCRE was behaving differently from Perl in the way it recognized POSIX
- character classes. PCRE was not treating the sequence [:...:] as a
- character class unless the ... were all letters. Perl, however, seems to
- allow any characters between [: and :], though of course it rejects as
- unknown any "names" that contain non-letters, because all the known class
- names consist only of letters. Thus, Perl gives an error for [[:1234:]],
- for example, whereas PCRE did not - it did not recognize a POSIX character
- class. This seemed a bit dangerous, so the code has been changed to be
- closer to Perl. The behaviour is not identical to Perl, because PCRE will
- diagnose an unknown class for, for example, [[:l\ower:]] where Perl will
- treat it as [[:lower:]]. However, PCRE does now give "unknown" errors where
- Perl does, and where it didn't before.
-
-24. Rewrite so as to remove the single use of %n from pcregrep because in some
- Windows environments %n is disabled by default.
-
-
-Version 7.4 21-Sep-07
----------------------
-
-1. Change 7.3/28 was implemented for classes by looking at the bitmap. This
- means that a class such as [\s] counted as "explicit reference to CR or
- LF". That isn't really right - the whole point of the change was to try to
- help when there was an actual mention of one of the two characters. So now
- the change happens only if \r or \n (or a literal CR or LF) character is
- encountered.
-
-2. The 32-bit options word was also used for 6 internal flags, but the numbers
- of both had grown to the point where there were only 3 bits left.
- Fortunately, there was spare space in the data structure, and so I have
- moved the internal flags into a new 16-bit field to free up more option
- bits.
-
-3. The appearance of (?J) at the start of a pattern set the DUPNAMES option,
- but did not set the internal JCHANGED flag - either of these is enough to
- control the way the "get" function works - but the PCRE_INFO_JCHANGED
- facility is supposed to tell if (?J) was ever used, so now (?J) at the
- start sets both bits.
-
-4. Added options (at build time, compile time, exec time) to change \R from
- matching any Unicode line ending sequence to just matching CR, LF, or CRLF.
-
-5. doc/pcresyntax.html was missing from the distribution.
-
-6. Put back the definition of PCRE_ERROR_NULLWSLIMIT, for backward
- compatibility, even though it is no longer used.
-
-7. Added macro for snprintf to pcrecpp_unittest.cc and also for strtoll and
- strtoull to pcrecpp.cc to select the available functions in WIN32 when the
- windows.h file is present (where different names are used). [This was
- reversed later after testing - see 16 below.]
-
-8. Changed all #include <config.h> to #include "config.h". There were also
- some further <pcre.h> cases that I changed to "pcre.h".
-
-9. When pcregrep was used with the --colour option, it missed the line ending
- sequence off the lines that it output.
-
-10. It was pointed out to me that arrays of string pointers cause lots of
- relocations when a shared library is dynamically loaded. A technique of
- using a single long string with a table of offsets can drastically reduce
- these. I have refactored PCRE in four places to do this. The result is
- dramatic:
-
- Originally: 290
- After changing UCP table: 187
- After changing error message table: 43
- After changing table of "verbs" 36
- After changing table of Posix names 22
-
- Thanks to the folks working on Gregex for glib for this insight.
-
-11. --disable-stack-for-recursion caused compiling to fail unless -enable-
- unicode-properties was also set.
-
-12. Updated the tests so that they work when \R is defaulted to ANYCRLF.
-
-13. Added checks for ANY and ANYCRLF to pcrecpp.cc where it previously
- checked only for CRLF.
-
-14. Added casts to pcretest.c to avoid compiler warnings.
-
-15. Added Craig's patch to various pcrecpp modules to avoid compiler warnings.
-
-16. Added Craig's patch to remove the WINDOWS_H tests, that were not working,
- and instead check for _strtoi64 explicitly, and avoid the use of snprintf()
- entirely. This removes changes made in 7 above.
-
-17. The CMake files have been updated, and there is now more information about
- building with CMake in the NON-UNIX-USE document.
-
-
-Version 7.3 28-Aug-07
----------------------
-
- 1. In the rejigging of the build system that eventually resulted in 7.1, the
- line "#include <pcre.h>" was included in pcre_internal.h. The use of angle
- brackets there is not right, since it causes compilers to look for an
- installed pcre.h, not the version that is in the source that is being
- compiled (which of course may be different). I have changed it back to:
-
- #include "pcre.h"
-
- I have a vague recollection that the change was concerned with compiling in
- different directories, but in the new build system, that is taken care of
- by the VPATH setting the Makefile.
-
- 2. The pattern .*$ when run in not-DOTALL UTF-8 mode with newline=any failed
- when the subject happened to end in the byte 0x85 (e.g. if the last
- character was \x{1ec5}). *Character* 0x85 is one of the "any" newline
- characters but of course it shouldn't be taken as a newline when it is part
- of another character. The bug was that, for an unlimited repeat of . in
- not-DOTALL UTF-8 mode, PCRE was advancing by bytes rather than by
- characters when looking for a newline.
-
- 3. A small performance improvement in the DOTALL UTF-8 mode .* case.
-
- 4. Debugging: adjusted the names of opcodes for different kinds of parentheses
- in debug output.
-
- 5. Arrange to use "%I64d" instead of "%lld" and "%I64u" instead of "%llu" for
- long printing in the pcrecpp unittest when running under MinGW.
-
- 6. ESC_K was left out of the EBCDIC table.
-
- 7. Change 7.0/38 introduced a new limit on the number of nested non-capturing
- parentheses; I made it 1000, which seemed large enough. Unfortunately, the
- limit also applies to "virtual nesting" when a pattern is recursive, and in
- this case 1000 isn't so big. I have been able to remove this limit at the
- expense of backing off one optimization in certain circumstances. Normally,
- when pcre_exec() would call its internal match() function recursively and
- immediately return the result unconditionally, it uses a "tail recursion"
- feature to save stack. However, when a subpattern that can match an empty
- string has an unlimited repetition quantifier, it no longer makes this
- optimization. That gives it a stack frame in which to save the data for
- checking that an empty string has been matched. Previously this was taken
- from the 1000-entry workspace that had been reserved. So now there is no
- explicit limit, but more stack is used.
-
- 8. Applied Daniel's patches to solve problems with the import/export magic
- syntax that is required for Windows, and which was going wrong for the
- pcreposix and pcrecpp parts of the library. These were overlooked when this
- problem was solved for the main library.
-
- 9. There were some crude static tests to avoid integer overflow when computing
- the size of patterns that contain repeated groups with explicit upper
- limits. As the maximum quantifier is 65535, the maximum group length was
- set at 30,000 so that the product of these two numbers did not overflow a
- 32-bit integer. However, it turns out that people want to use groups that
- are longer than 30,000 bytes (though not repeat them that many times).
- Change 7.0/17 (the refactoring of the way the pattern size is computed) has
- made it possible to implement the integer overflow checks in a much more
- dynamic way, which I have now done. The artificial limitation on group
- length has been removed - we now have only the limit on the total length of
- the compiled pattern, which depends on the LINK_SIZE setting.
-
-10. Fixed a bug in the documentation for get/copy named substring when
- duplicate names are permitted. If none of the named substrings are set, the
- functions return PCRE_ERROR_NOSUBSTRING (7); the doc said they returned an
- empty string.
-
-11. Because Perl interprets \Q...\E at a high level, and ignores orphan \E
- instances, patterns such as [\Q\E] or [\E] or even [^\E] cause an error,
- because the ] is interpreted as the first data character and the
- terminating ] is not found. PCRE has been made compatible with Perl in this
- regard. Previously, it interpreted [\Q\E] as an empty class, and [\E] could
- cause memory overwriting.
-
-10. Like Perl, PCRE automatically breaks an unlimited repeat after an empty
- string has been matched (to stop an infinite loop). It was not recognizing
- a conditional subpattern that could match an empty string if that
- subpattern was within another subpattern. For example, it looped when
- trying to match (((?(1)X|))*) but it was OK with ((?(1)X|)*) where the
- condition was not nested. This bug has been fixed.
-
-12. A pattern like \X?\d or \P{L}?\d in non-UTF-8 mode could cause a backtrack
- past the start of the subject in the presence of bytes with the top bit
- set, for example "\x8aBCD".
-
-13. Added Perl 5.10 experimental backtracking controls (*FAIL), (*F), (*PRUNE),
- (*SKIP), (*THEN), (*COMMIT), and (*ACCEPT).
-
-14. Optimized (?!) to (*FAIL).
-
-15. Updated the test for a valid UTF-8 string to conform to the later RFC 3629.
- This restricts code points to be within the range 0 to 0x10FFFF, excluding
- the "low surrogate" sequence 0xD800 to 0xDFFF. Previously, PCRE allowed the
- full range 0 to 0x7FFFFFFF, as defined by RFC 2279. Internally, it still
- does: it's just the validity check that is more restrictive.
-
-16. Inserted checks for integer overflows during escape sequence (backslash)
- processing, and also fixed erroneous offset values for syntax errors during
- backslash processing.
-
-17. Fixed another case of looking too far back in non-UTF-8 mode (cf 12 above)
- for patterns like [\PPP\x8a]{1,}\x80 with the subject "A\x80".
-
-18. An unterminated class in a pattern like (?1)\c[ with a "forward reference"
- caused an overrun.
-
-19. A pattern like (?:[\PPa*]*){8,} which had an "extended class" (one with
- something other than just ASCII characters) inside a group that had an
- unlimited repeat caused a loop at compile time (while checking to see
- whether the group could match an empty string).
-
-20. Debugging a pattern containing \p or \P could cause a crash. For example,
- [\P{Any}] did so. (Error in the code for printing property names.)
-
-21. An orphan \E inside a character class could cause a crash.
-
-22. A repeated capturing bracket such as (A)? could cause a wild memory
- reference during compilation.
-
-23. There are several functions in pcre_compile() that scan along a compiled
- expression for various reasons (e.g. to see if it's fixed length for look
- behind). There were bugs in these functions when a repeated \p or \P was
- present in the pattern. These operators have additional parameters compared
- with \d, etc, and these were not being taken into account when moving along
- the compiled data. Specifically:
-
- (a) A item such as \p{Yi}{3} in a lookbehind was not treated as fixed
- length.
-
- (b) An item such as \pL+ within a repeated group could cause crashes or
- loops.
-
- (c) A pattern such as \p{Yi}+(\P{Yi}+)(?1) could give an incorrect
- "reference to non-existent subpattern" error.
-
- (d) A pattern like (\P{Yi}{2}\277)? could loop at compile time.
-
-24. A repeated \S or \W in UTF-8 mode could give wrong answers when multibyte
- characters were involved (for example /\S{2}/8g with "A\x{a3}BC").
-
-25. Using pcregrep in multiline, inverted mode (-Mv) caused it to loop.
-
-26. Patterns such as [\P{Yi}A] which include \p or \P and just one other
- character were causing crashes (broken optimization).
-
-27. Patterns such as (\P{Yi}*\277)* (group with possible zero repeat containing
- \p or \P) caused a compile-time loop.
-
-28. More problems have arisen in unanchored patterns when CRLF is a valid line
- break. For example, the unstudied pattern [\r\n]A does not match the string
- "\r\nA" because change 7.0/46 below moves the current point on by two
- characters after failing to match at the start. However, the pattern \nA
- *does* match, because it doesn't start till \n, and if [\r\n]A is studied,
- the same is true. There doesn't seem any very clean way out of this, but
- what I have chosen to do makes the common cases work: PCRE now takes note
- of whether there can be an explicit match for \r or \n anywhere in the
- pattern, and if so, 7.0/46 no longer applies. As part of this change,
- there's a new PCRE_INFO_HASCRORLF option for finding out whether a compiled
- pattern has explicit CR or LF references.
-
-29. Added (*CR) etc for changing newline setting at start of pattern.
-
-
-Version 7.2 19-Jun-07
----------------------
-
- 1. If the fr_FR locale cannot be found for test 3, try the "french" locale,
- which is apparently normally available under Windows.
-
- 2. Re-jig the pcregrep tests with different newline settings in an attempt
- to make them independent of the local environment's newline setting.
-
- 3. Add code to configure.ac to remove -g from the CFLAGS default settings.
-
- 4. Some of the "internals" tests were previously cut out when the link size
- was not 2, because the output contained actual offsets. The recent new
- "Z" feature of pcretest means that these can be cut out, making the tests
- usable with all link sizes.
-
- 5. Implemented Stan Switzer's goto replacement for longjmp() when not using
- stack recursion. This gives a massive performance boost under BSD, but just
- a small improvement under Linux. However, it saves one field in the frame
- in all cases.
-
- 6. Added more features from the forthcoming Perl 5.10:
-
- (a) (?-n) (where n is a string of digits) is a relative subroutine or
- recursion call. It refers to the nth most recently opened parentheses.
-
- (b) (?+n) is also a relative subroutine call; it refers to the nth next
- to be opened parentheses.
-
- (c) Conditions that refer to capturing parentheses can be specified
- relatively, for example, (?(-2)... or (?(+3)...
-
- (d) \K resets the start of the current match so that everything before
- is not part of it.
-
- (e) \k{name} is synonymous with \k<name> and \k'name' (.NET compatible).
-
- (f) \g{name} is another synonym - part of Perl 5.10's unification of
- reference syntax.
-
- (g) (?| introduces a group in which the numbering of parentheses in each
- alternative starts with the same number.
-
- (h) \h, \H, \v, and \V match horizontal and vertical whitespace.
-
- 7. Added two new calls to pcre_fullinfo(): PCRE_INFO_OKPARTIAL and
- PCRE_INFO_JCHANGED.
-
- 8. A pattern such as (.*(.)?)* caused pcre_exec() to fail by either not
- terminating or by crashing. Diagnosed by Viktor Griph; it was in the code
- for detecting groups that can match an empty string.
-
- 9. A pattern with a very large number of alternatives (more than several
- hundred) was running out of internal workspace during the pre-compile
- phase, where pcre_compile() figures out how much memory will be needed. A
- bit of new cunning has reduced the workspace needed for groups with
- alternatives. The 1000-alternative test pattern now uses 12 bytes of
- workspace instead of running out of the 4096 that are available.
-
-10. Inserted some missing (unsigned int) casts to get rid of compiler warnings.
-
-11. Applied patch from Google to remove an optimization that didn't quite work.
- The report of the bug said:
-
- pcrecpp::RE("a*").FullMatch("aaa") matches, while
- pcrecpp::RE("a*?").FullMatch("aaa") does not, and
- pcrecpp::RE("a*?\\z").FullMatch("aaa") does again.
-
-12. If \p or \P was used in non-UTF-8 mode on a character greater than 127
- it matched the wrong number of bytes.
-
-
-Version 7.1 24-Apr-07
----------------------
-
- 1. Applied Bob Rossi and Daniel G's patches to convert the build system to one
- that is more "standard", making use of automake and other Autotools. There
- is some re-arrangement of the files and adjustment of comments consequent
- on this.
-
- 2. Part of the patch fixed a problem with the pcregrep tests. The test of -r
- for recursive directory scanning broke on some systems because the files
- are not scanned in any specific order and on different systems the order
- was different. A call to "sort" has been inserted into RunGrepTest for the
- approprate test as a short-term fix. In the longer term there may be an
- alternative.
-
- 3. I had an email from Eric Raymond about problems translating some of PCRE's
- man pages to HTML (despite the fact that I distribute HTML pages, some
- people do their own conversions for various reasons). The problems
- concerned the use of low-level troff macros .br and .in. I have therefore
- removed all such uses from the man pages (some were redundant, some could
- be replaced by .nf/.fi pairs). The 132html script that I use to generate
- HTML has been updated to handle .nf/.fi and to complain if it encounters
- .br or .in.
-
- 4. Updated comments in configure.ac that get placed in config.h.in and also
- arranged for config.h to be included in the distribution, with the name
- config.h.generic, for the benefit of those who have to compile without
- Autotools (compare pcre.h, which is now distributed as pcre.h.generic).
-
- 5. Updated the support (such as it is) for Virtual Pascal, thanks to Stefan
- Weber: (1) pcre_internal.h was missing some function renames; (2) updated
- makevp.bat for the current PCRE, using the additional files
- makevp_c.txt, makevp_l.txt, and pcregexp.pas.
-
- 6. A Windows user reported a minor discrepancy with test 2, which turned out
- to be caused by a trailing space on an input line that had got lost in his
- copy. The trailing space was an accident, so I've just removed it.
-
- 7. Add -Wl,-R... flags in pcre-config.in for *BSD* systems, as I'm told
- that is needed.
-
- 8. Mark ucp_table (in ucptable.h) and ucp_gentype (in pcre_ucp_searchfuncs.c)
- as "const" (a) because they are and (b) because it helps the PHP
- maintainers who have recently made a script to detect big data structures
- in the php code that should be moved to the .rodata section. I remembered
- to update Builducptable as well, so it won't revert if ucptable.h is ever
- re-created.
-
- 9. Added some extra #ifdef SUPPORT_UTF8 conditionals into pcretest.c,
- pcre_printint.src, pcre_compile.c, pcre_study.c, and pcre_tables.c, in
- order to be able to cut out the UTF-8 tables in the latter when UTF-8
- support is not required. This saves 1.5-2K of code, which is important in
- some applications.
-
- Later: more #ifdefs are needed in pcre_ord2utf8.c and pcre_valid_utf8.c
- so as not to refer to the tables, even though these functions will never be
- called when UTF-8 support is disabled. Otherwise there are problems with a
- shared library.
-
-10. Fixed two bugs in the emulated memmove() function in pcre_internal.h:
-
- (a) It was defining its arguments as char * instead of void *.
-
- (b) It was assuming that all moves were upwards in memory; this was true
- a long time ago when I wrote it, but is no longer the case.
-
- The emulated memove() is provided for those environments that have neither
- memmove() nor bcopy(). I didn't think anyone used it these days, but that
- is clearly not the case, as these two bugs were recently reported.
-
-11. The script PrepareRelease is now distributed: it calls 132html, CleanTxt,
- and Detrail to create the HTML documentation, the .txt form of the man
- pages, and it removes trailing spaces from listed files. It also creates
- pcre.h.generic and config.h.generic from pcre.h and config.h. In the latter
- case, it wraps all the #defines with #ifndefs. This script should be run
- before "make dist".
-
-12. Fixed two fairly obscure bugs concerned with quantified caseless matching
- with Unicode property support.
-
- (a) For a maximizing quantifier, if the two different cases of the
- character were of different lengths in their UTF-8 codings (there are
- some cases like this - I found 11), and the matching function had to
- back up over a mixture of the two cases, it incorrectly assumed they
- were both the same length.
-
- (b) When PCRE was configured to use the heap rather than the stack for
- recursion during matching, it was not correctly preserving the data for
- the other case of a UTF-8 character when checking ahead for a match
- while processing a minimizing repeat. If the check also involved
- matching a wide character, but failed, corruption could cause an
- erroneous result when trying to check for a repeat of the original
- character.
-
-13. Some tidying changes to the testing mechanism:
-
- (a) The RunTest script now detects the internal link size and whether there
- is UTF-8 and UCP support by running ./pcretest -C instead of relying on
- values substituted by "configure". (The RunGrepTest script already did
- this for UTF-8.) The configure.ac script no longer substitutes the
- relevant variables.
-
- (b) The debugging options /B and /D in pcretest show the compiled bytecode
- with length and offset values. This means that the output is different
- for different internal link sizes. Test 2 is skipped for link sizes
- other than 2 because of this, bypassing the problem. Unfortunately,
- there was also a test in test 3 (the locale tests) that used /B and
- failed for link sizes other than 2. Rather than cut the whole test out,
- I have added a new /Z option to pcretest that replaces the length and
- offset values with spaces. This is now used to make test 3 independent
- of link size. (Test 2 will be tidied up later.)
-
-14. If erroroffset was passed as NULL to pcre_compile, it provoked a
- segmentation fault instead of returning the appropriate error message.
-
-15. In multiline mode when the newline sequence was set to "any", the pattern
- ^$ would give a match between the \r and \n of a subject such as "A\r\nB".
- This doesn't seem right; it now treats the CRLF combination as the line
- ending, and so does not match in that case. It's only a pattern such as ^$
- that would hit this one: something like ^ABC$ would have failed after \r
- and then tried again after \r\n.
-
-16. Changed the comparison command for RunGrepTest from "diff -u" to "diff -ub"
- in an attempt to make files that differ only in their line terminators
- compare equal. This works on Linux.
-
-17. Under certain error circumstances pcregrep might try to free random memory
- as it exited. This is now fixed, thanks to valgrind.
-
-19. In pcretest, if the pattern /(?m)^$/g<any> was matched against the string
- "abc\r\n\r\n", it found an unwanted second match after the second \r. This
- was because its rules for how to advance for /g after matching an empty
- string at the end of a line did not allow for this case. They now check for
- it specially.
-
-20. pcretest is supposed to handle patterns and data of any length, by
- extending its buffers when necessary. It was getting this wrong when the
- buffer for a data line had to be extended.
-
-21. Added PCRE_NEWLINE_ANYCRLF which is like ANY, but matches only CR, LF, or
- CRLF as a newline sequence.
-
-22. Code for handling Unicode properties in pcre_dfa_exec() wasn't being cut
- out by #ifdef SUPPORT_UCP. This did no harm, as it could never be used, but
- I have nevertheless tidied it up.
-
-23. Added some casts to kill warnings from HP-UX ia64 compiler.
-
-24. Added a man page for pcre-config.
-
-
-Version 7.0 19-Dec-06
----------------------
-
- 1. Fixed a signed/unsigned compiler warning in pcre_compile.c, shown up by
- moving to gcc 4.1.1.
-
- 2. The -S option for pcretest uses setrlimit(); I had omitted to #include
- sys/time.h, which is documented as needed for this function. It doesn't
- seem to matter on Linux, but it showed up on some releases of OS X.
-
- 3. It seems that there are systems where bytes whose values are greater than
- 127 match isprint() in the "C" locale. The "C" locale should be the
- default when a C program starts up. In most systems, only ASCII printing
- characters match isprint(). This difference caused the output from pcretest
- to vary, making some of the tests fail. I have changed pcretest so that:
-
- (a) When it is outputting text in the compiled version of a pattern, bytes
- other than 32-126 are always shown as hex escapes.
-
- (b) When it is outputting text that is a matched part of a subject string,
- it does the same, unless a different locale has been set for the match
- (using the /L modifier). In this case, it uses isprint() to decide.
-
- 4. Fixed a major bug that caused incorrect computation of the amount of memory
- required for a compiled pattern when options that changed within the
- pattern affected the logic of the preliminary scan that determines the
- length. The relevant options are -x, and -i in UTF-8 mode. The result was
- that the computed length was too small. The symptoms of this bug were
- either the PCRE error "internal error: code overflow" from pcre_compile(),
- or a glibc crash with a message such as "pcretest: free(): invalid next
- size (fast)". Examples of patterns that provoked this bug (shown in
- pcretest format) are:
-
- /(?-x: )/x
- /(?x)(?-x: \s*#\s*)/
- /((?i)[\x{c0}])/8
- /(?i:[\x{c0}])/8
-
- HOWEVER: Change 17 below makes this fix obsolete as the memory computation
- is now done differently.
-
- 5. Applied patches from Google to: (a) add a QuoteMeta function to the C++
- wrapper classes; (b) implement a new function in the C++ scanner that is
- more efficient than the old way of doing things because it avoids levels of
- recursion in the regex matching; (c) add a paragraph to the documentation
- for the FullMatch() function.
-
- 6. The escape sequence \n was being treated as whatever was defined as
- "newline". Not only was this contrary to the documentation, which states
- that \n is character 10 (hex 0A), but it also went horribly wrong when
- "newline" was defined as CRLF. This has been fixed.
-
- 7. In pcre_dfa_exec.c the value of an unsigned integer (the variable called c)
- was being set to -1 for the "end of line" case (supposedly a value that no
- character can have). Though this value is never used (the check for end of
- line is "zero bytes in current character"), it caused compiler complaints.
- I've changed it to 0xffffffff.
-
- 8. In pcre_version.c, the version string was being built by a sequence of
- C macros that, in the event of PCRE_PRERELEASE being defined as an empty
- string (as it is for production releases) called a macro with an empty
- argument. The C standard says the result of this is undefined. The gcc
- compiler treats it as an empty string (which was what was wanted) but it is
- reported that Visual C gives an error. The source has been hacked around to
- avoid this problem.
-
- 9. On the advice of a Windows user, included <io.h> and <fcntl.h> in Windows
- builds of pcretest, and changed the call to _setmode() to use _O_BINARY
- instead of 0x8000. Made all the #ifdefs test both _WIN32 and WIN32 (not all
- of them did).
-
-10. Originally, pcretest opened its input and output without "b"; then I was
- told that "b" was needed in some environments, so it was added for release
- 5.0 to both the input and output. (It makes no difference on Unix-like
- systems.) Later I was told that it is wrong for the input on Windows. I've
- now abstracted the modes into two macros, to make it easier to fiddle with
- them, and removed "b" from the input mode under Windows.
-
-11. Added pkgconfig support for the C++ wrapper library, libpcrecpp.
-
-12. Added -help and --help to pcretest as an official way of being reminded
- of the options.
-
-13. Removed some redundant semicolons after macro calls in pcrecpparg.h.in
- and pcrecpp.cc because they annoy compilers at high warning levels.
-
-14. A bit of tidying/refactoring in pcre_exec.c in the main bumpalong loop.
-
-15. Fixed an occurrence of == in configure.ac that should have been = (shell
- scripts are not C programs :-) and which was not noticed because it works
- on Linux.
-
-16. pcretest is supposed to handle any length of pattern and data line (as one
- line or as a continued sequence of lines) by extending its input buffer if
- necessary. This feature was broken for very long pattern lines, leading to
- a string of junk being passed to pcre_compile() if the pattern was longer
- than about 50K.
-
-17. I have done a major re-factoring of the way pcre_compile() computes the
- amount of memory needed for a compiled pattern. Previously, there was code
- that made a preliminary scan of the pattern in order to do this. That was
- OK when PCRE was new, but as the facilities have expanded, it has become
- harder and harder to keep it in step with the real compile phase, and there
- have been a number of bugs (see for example, 4 above). I have now found a
- cunning way of running the real compile function in a "fake" mode that
- enables it to compute how much memory it would need, while actually only
- ever using a few hundred bytes of working memory and without too many
- tests of the mode. This should make future maintenance and development
- easier. A side effect of this work is that the limit of 200 on the nesting
- depth of parentheses has been removed (though this was never a serious
- limitation, I suspect). However, there is a downside: pcre_compile() now
- runs more slowly than before (30% or more, depending on the pattern). I
- hope this isn't a big issue. There is no effect on runtime performance.
-
-18. Fixed a minor bug in pcretest: if a pattern line was not terminated by a
- newline (only possible for the last line of a file) and it was a
- pattern that set a locale (followed by /Lsomething), pcretest crashed.
-
-19. Added additional timing features to pcretest. (1) The -tm option now times
- matching only, not compiling. (2) Both -t and -tm can be followed, as a
- separate command line item, by a number that specifies the number of
- repeats to use when timing. The default is 50000; this gives better
- precision, but takes uncomfortably long for very large patterns.
-
-20. Extended pcre_study() to be more clever in cases where a branch of a
- subpattern has no definite first character. For example, (a*|b*)[cd] would
- previously give no result from pcre_study(). Now it recognizes that the
- first character must be a, b, c, or d.
-
-21. There was an incorrect error "recursive call could loop indefinitely" if
- a subpattern (or the entire pattern) that was being tested for matching an
- empty string contained only one non-empty item after a nested subpattern.
- For example, the pattern (?>\x{100}*)\d(?R) provoked this error
- incorrectly, because the \d was being skipped in the check.
-
-22. The pcretest program now has a new pattern option /B and a command line
- option -b, which is equivalent to adding /B to every pattern. This causes
- it to show the compiled bytecode, without the additional information that
- -d shows. The effect of -d is now the same as -b with -i (and similarly, /D
- is the same as /B/I).
-
-23. A new optimization is now able automatically to treat some sequences such
- as a*b as a*+b. More specifically, if something simple (such as a character
- or a simple class like \d) has an unlimited quantifier, and is followed by
- something that cannot possibly match the quantified thing, the quantifier
- is automatically "possessified".
-
-24. A recursive reference to a subpattern whose number was greater than 39
- went wrong under certain circumstances in UTF-8 mode. This bug could also
- have affected the operation of pcre_study().
-
-25. Realized that a little bit of performance could be had by replacing
- (c & 0xc0) == 0xc0 with c >= 0xc0 when processing UTF-8 characters.
-
-26. Timing data from pcretest is now shown to 4 decimal places instead of 3.
-
-27. Possessive quantifiers such as a++ were previously implemented by turning
- them into atomic groups such as ($>a+). Now they have their own opcodes,
- which improves performance. This includes the automatically created ones
- from 23 above.
-
-28. A pattern such as (?=(\w+))\1: which simulates an atomic group using a
- lookahead was broken if it was not anchored. PCRE was mistakenly expecting
- the first matched character to be a colon. This applied both to named and
- numbered groups.
-
-29. The ucpinternal.h header file was missing its idempotency #ifdef.
-
-30. I was sent a "project" file called libpcre.a.dev which I understand makes
- building PCRE on Windows easier, so I have included it in the distribution.
-
-31. There is now a check in pcretest against a ridiculously large number being
- returned by pcre_exec() or pcre_dfa_exec(). If this happens in a /g or /G
- loop, the loop is abandoned.
-
-32. Forward references to subpatterns in conditions such as (?(2)...) where
- subpattern 2 is defined later cause pcre_compile() to search forwards in
- the pattern for the relevant set of parentheses. This search went wrong
- when there were unescaped parentheses in a character class, parentheses
- escaped with \Q...\E, or parentheses in a #-comment in /x mode.
-
-33. "Subroutine" calls and backreferences were previously restricted to
- referencing subpatterns earlier in the regex. This restriction has now
- been removed.
-
-34. Added a number of extra features that are going to be in Perl 5.10. On the
- whole, these are just syntactic alternatives for features that PCRE had
- previously implemented using the Python syntax or my own invention. The
- other formats are all retained for compatibility.
-
- (a) Named groups can now be defined as (?<name>...) or (?'name'...) as well
- as (?P<name>...). The new forms, as well as being in Perl 5.10, are
- also .NET compatible.
-
- (b) A recursion or subroutine call to a named group can now be defined as
- (?&name) as well as (?P>name).
-
- (c) A backreference to a named group can now be defined as \k<name> or
- \k'name' as well as (?P=name). The new forms, as well as being in Perl
- 5.10, are also .NET compatible.
-
- (d) A conditional reference to a named group can now use the syntax
- (?(<name>) or (?('name') as well as (?(name).
-
- (e) A "conditional group" of the form (?(DEFINE)...) can be used to define
- groups (named and numbered) that are never evaluated inline, but can be
- called as "subroutines" from elsewhere. In effect, the DEFINE condition
- is always false. There may be only one alternative in such a group.
-
- (f) A test for recursion can be given as (?(R1).. or (?(R&name)... as well
- as the simple (?(R). The condition is true only if the most recent
- recursion is that of the given number or name. It does not search out
- through the entire recursion stack.
-
- (g) The escape \gN or \g{N} has been added, where N is a positive or
- negative number, specifying an absolute or relative reference.
-
-35. Tidied to get rid of some further signed/unsigned compiler warnings and
- some "unreachable code" warnings.
-
-36. Updated the Unicode property tables to Unicode version 5.0.0. Amongst other
- things, this adds five new scripts.
-
-37. Perl ignores orphaned \E escapes completely. PCRE now does the same.
- There were also incompatibilities regarding the handling of \Q..\E inside
- character classes, for example with patterns like [\Qa\E-\Qz\E] where the
- hyphen was adjacent to \Q or \E. I hope I've cleared all this up now.
-
-38. Like Perl, PCRE detects when an indefinitely repeated parenthesized group
- matches an empty string, and forcibly breaks the loop. There were bugs in
- this code in non-simple cases. For a pattern such as ^(a()*)* matched
- against aaaa the result was just "a" rather than "aaaa", for example. Two
- separate and independent bugs (that affected different cases) have been
- fixed.
-
-39. Refactored the code to abolish the use of different opcodes for small
- capturing bracket numbers. This is a tidy that I avoided doing when I
- removed the limit on the number of capturing brackets for 3.5 back in 2001.
- The new approach is not only tidier, it makes it possible to reduce the
- memory needed to fix the previous bug (38).
-
-40. Implemented PCRE_NEWLINE_ANY to recognize any of the Unicode newline
- sequences (http://unicode.org/unicode/reports/tr18/) as "newline" when
- processing dot, circumflex, or dollar metacharacters, or #-comments in /x
- mode.
-
-41. Add \R to match any Unicode newline sequence, as suggested in the Unicode
- report.
-
-42. Applied patch, originally from Ari Pollak, modified by Google, to allow
- copy construction and assignment in the C++ wrapper.
-
-43. Updated pcregrep to support "--newline=any". In the process, I fixed a
- couple of bugs that could have given wrong results in the "--newline=crlf"
- case.
-
-44. Added a number of casts and did some reorganization of signed/unsigned int
- variables following suggestions from Dair Grant. Also renamed the variable
- "this" as "item" because it is a C++ keyword.
-
-45. Arranged for dftables to add
-
- #include "pcre_internal.h"
-
- to pcre_chartables.c because without it, gcc 4.x may remove the array
- definition from the final binary if PCRE is built into a static library and
- dead code stripping is activated.
-
-46. For an unanchored pattern, if a match attempt fails at the start of a
- newline sequence, and the newline setting is CRLF or ANY, and the next two
- characters are CRLF, advance by two characters instead of one.
-
-
-Version 6.7 04-Jul-06
----------------------
-
- 1. In order to handle tests when input lines are enormously long, pcretest has
- been re-factored so that it automatically extends its buffers when
- necessary. The code is crude, but this _is_ just a test program. The
- default size has been increased from 32K to 50K.
-
- 2. The code in pcre_study() was using the value of the re argument before
- testing it for NULL. (Of course, in any sensible call of the function, it
- won't be NULL.)
-
- 3. The memmove() emulation function in pcre_internal.h, which is used on
- systems that lack both memmove() and bcopy() - that is, hardly ever -
- was missing a "static" storage class specifier.
-
- 4. When UTF-8 mode was not set, PCRE looped when compiling certain patterns
- containing an extended class (one that cannot be represented by a bitmap
- because it contains high-valued characters or Unicode property items, e.g.
- [\pZ]). Almost always one would set UTF-8 mode when processing such a
- pattern, but PCRE should not loop if you do not (it no longer does).
- [Detail: two cases were found: (a) a repeated subpattern containing an
- extended class; (b) a recursive reference to a subpattern that followed a
- previous extended class. It wasn't skipping over the extended class
- correctly when UTF-8 mode was not set.]
-
- 5. A negated single-character class was not being recognized as fixed-length
- in lookbehind assertions such as (?<=[^f]), leading to an incorrect
- compile error "lookbehind assertion is not fixed length".
-
- 6. The RunPerlTest auxiliary script was showing an unexpected difference
- between PCRE and Perl for UTF-8 tests. It turns out that it is hard to
- write a Perl script that can interpret lines of an input file either as
- byte characters or as UTF-8, which is what "perltest" was being required to
- do for the non-UTF-8 and UTF-8 tests, respectively. Essentially what you
- can't do is switch easily at run time between having the "use utf8;" pragma
- or not. In the end, I fudged it by using the RunPerlTest script to insert
- "use utf8;" explicitly for the UTF-8 tests.
-
- 7. In multiline (/m) mode, PCRE was matching ^ after a terminating newline at
- the end of the subject string, contrary to the documentation and to what
- Perl does. This was true of both matching functions. Now it matches only at
- the start of the subject and immediately after *internal* newlines.
-
- 8. A call of pcre_fullinfo() from pcretest to get the option bits was passing
- a pointer to an int instead of a pointer to an unsigned long int. This
- caused problems on 64-bit systems.
-
- 9. Applied a patch from the folks at Google to pcrecpp.cc, to fix "another
- instance of the 'standard' template library not being so standard".
-
-10. There was no check on the number of named subpatterns nor the maximum
- length of a subpattern name. The product of these values is used to compute
- the size of the memory block for a compiled pattern. By supplying a very
- long subpattern name and a large number of named subpatterns, the size
- computation could be caused to overflow. This is now prevented by limiting
- the length of names to 32 characters, and the number of named subpatterns
- to 10,000.
-
-11. Subpatterns that are repeated with specific counts have to be replicated in
- the compiled pattern. The size of memory for this was computed from the
- length of the subpattern and the repeat count. The latter is limited to
- 65535, but there was no limit on the former, meaning that integer overflow
- could in principle occur. The compiled length of a repeated subpattern is
- now limited to 30,000 bytes in order to prevent this.
-
-12. Added the optional facility to have named substrings with the same name.
-
-13. Added the ability to use a named substring as a condition, using the
- Python syntax: (?(name)yes|no). This overloads (?(R)... and names that
- are numbers (not recommended). Forward references are permitted.
-
-14. Added forward references in named backreferences (if you see what I mean).
-
-15. In UTF-8 mode, with the PCRE_DOTALL option set, a quantified dot in the
- pattern could run off the end of the subject. For example, the pattern
- "(?s)(.{1,5})"8 did this with the subject "ab".
-
-16. If PCRE_DOTALL or PCRE_MULTILINE were set, pcre_dfa_exec() behaved as if
- PCRE_CASELESS was set when matching characters that were quantified with ?
- or *.
-
-17. A character class other than a single negated character that had a minimum
- but no maximum quantifier - for example [ab]{6,} - was not handled
- correctly by pce_dfa_exec(). It would match only one character.
-
-18. A valid (though odd) pattern that looked like a POSIX character
- class but used an invalid character after [ (for example [[,abc,]]) caused
- pcre_compile() to give the error "Failed: internal error: code overflow" or
- in some cases to crash with a glibc free() error. This could even happen if
- the pattern terminated after [[ but there just happened to be a sequence of
- letters, a binary zero, and a closing ] in the memory that followed.
-
-19. Perl's treatment of octal escapes in the range \400 to \777 has changed
- over the years. Originally (before any Unicode support), just the bottom 8
- bits were taken. Thus, for example, \500 really meant \100. Nowadays the
- output from "man perlunicode" includes this:
-
- The regular expression compiler produces polymorphic opcodes. That
- is, the pattern adapts to the data and automatically switches to
- the Unicode character scheme when presented with Unicode data--or
- instead uses a traditional byte scheme when presented with byte
- data.
-
- Sadly, a wide octal escape does not cause a switch, and in a string with
- no other multibyte characters, these octal escapes are treated as before.
- Thus, in Perl, the pattern /\500/ actually matches \100 but the pattern
- /\500|\x{1ff}/ matches \500 or \777 because the whole thing is treated as a
- Unicode string.
-
- I have not perpetrated such confusion in PCRE. Up till now, it took just
- the bottom 8 bits, as in old Perl. I have now made octal escapes with
- values greater than \377 illegal in non-UTF-8 mode. In UTF-8 mode they
- translate to the appropriate multibyte character.
-
-29. Applied some refactoring to reduce the number of warnings from Microsoft
- and Borland compilers. This has included removing the fudge introduced
- seven years ago for the OS/2 compiler (see 2.02/2 below) because it caused
- a warning about an unused variable.
-
-21. PCRE has not included VT (character 0x0b) in the set of whitespace
- characters since release 4.0, because Perl (from release 5.004) does not.
- [Or at least, is documented not to: some releases seem to be in conflict
- with the documentation.] However, when a pattern was studied with
- pcre_study() and all its branches started with \s, PCRE still included VT
- as a possible starting character. Of course, this did no harm; it just
- caused an unnecessary match attempt.
-
-22. Removed a now-redundant internal flag bit that recorded the fact that case
- dependency changed within the pattern. This was once needed for "required
- byte" processing, but is no longer used. This recovers a now-scarce options
- bit. Also moved the least significant internal flag bit to the most-
- significant bit of the word, which was not previously used (hangover from
- the days when it was an int rather than a uint) to free up another bit for
- the future.
-
-23. Added support for CRLF line endings as well as CR and LF. As well as the
- default being selectable at build time, it can now be changed at runtime
- via the PCRE_NEWLINE_xxx flags. There are now options for pcregrep to
- specify that it is scanning data with non-default line endings.
-
-24. Changed the definition of CXXLINK to make it agree with the definition of
- LINK in the Makefile, by replacing LDFLAGS to CXXFLAGS.
-
-25. Applied Ian Taylor's patches to avoid using another stack frame for tail
- recursions. This makes a big different to stack usage for some patterns.
-
-26. If a subpattern containing a named recursion or subroutine reference such
- as (?P>B) was quantified, for example (xxx(?P>B)){3}, the calculation of
- the space required for the compiled pattern went wrong and gave too small a
- value. Depending on the environment, this could lead to "Failed: internal
- error: code overflow at offset 49" or "glibc detected double free or
- corruption" errors.
-
-27. Applied patches from Google (a) to support the new newline modes and (b) to
- advance over multibyte UTF-8 characters in GlobalReplace.
-
-28. Change free() to pcre_free() in pcredemo.c. Apparently this makes a
- difference for some implementation of PCRE in some Windows version.
-
-29. Added some extra testing facilities to pcretest:
-
- \q<number> in a data line sets the "match limit" value
- \Q<number> in a data line sets the "match recursion limt" value
- -S <number> sets the stack size, where <number> is in megabytes
-
- The -S option isn't available for Windows.
-
-
-Version 6.6 06-Feb-06
----------------------
-
- 1. Change 16(a) for 6.5 broke things, because PCRE_DATA_SCOPE was not defined
- in pcreposix.h. I have copied the definition from pcre.h.
-
- 2. Change 25 for 6.5 broke compilation in a build directory out-of-tree
- because pcre.h is no longer a built file.
-
- 3. Added Jeff Friedl's additional debugging patches to pcregrep. These are
- not normally included in the compiled code.
-
-
-Version 6.5 01-Feb-06
----------------------
-
- 1. When using the partial match feature with pcre_dfa_exec(), it was not
- anchoring the second and subsequent partial matches at the new starting
- point. This could lead to incorrect results. For example, with the pattern
- /1234/, partially matching against "123" and then "a4" gave a match.
-
- 2. Changes to pcregrep:
-
- (a) All non-match returns from pcre_exec() were being treated as failures
- to match the line. Now, unless the error is PCRE_ERROR_NOMATCH, an
- error message is output. Some extra information is given for the
- PCRE_ERROR_MATCHLIMIT and PCRE_ERROR_RECURSIONLIMIT errors, which are
- probably the only errors that are likely to be caused by users (by
- specifying a regex that has nested indefinite repeats, for instance).
- If there are more than 20 of these errors, pcregrep is abandoned.
-
- (b) A binary zero was treated as data while matching, but terminated the
- output line if it was written out. This has been fixed: binary zeroes
- are now no different to any other data bytes.
-
- (c) Whichever of the LC_ALL or LC_CTYPE environment variables is set is
- used to set a locale for matching. The --locale=xxxx long option has
- been added (no short equivalent) to specify a locale explicitly on the
- pcregrep command, overriding the environment variables.
-
- (d) When -B was used with -n, some line numbers in the output were one less
- than they should have been.
-
- (e) Added the -o (--only-matching) option.
-
- (f) If -A or -C was used with -c (count only), some lines of context were
- accidentally printed for the final match.
-
- (g) Added the -H (--with-filename) option.
-
- (h) The combination of options -rh failed to suppress file names for files
- that were found from directory arguments.
-
- (i) Added the -D (--devices) and -d (--directories) options.
-
- (j) Added the -F (--fixed-strings) option.
-
- (k) Allow "-" to be used as a file name for -f as well as for a data file.
-
- (l) Added the --colo(u)r option.
-
- (m) Added Jeffrey Friedl's -S testing option, but within #ifdefs so that it
- is not present by default.
-
- 3. A nasty bug was discovered in the handling of recursive patterns, that is,
- items such as (?R) or (?1), when the recursion could match a number of
- alternatives. If it matched one of the alternatives, but subsequently,
- outside the recursion, there was a failure, the code tried to back up into
- the recursion. However, because of the way PCRE is implemented, this is not
- possible, and the result was an incorrect result from the match.
-
- In order to prevent this happening, the specification of recursion has
- been changed so that all such subpatterns are automatically treated as
- atomic groups. Thus, for example, (?R) is treated as if it were (?>(?R)).
-
- 4. I had overlooked the fact that, in some locales, there are characters for
- which isalpha() is true but neither isupper() nor islower() are true. In
- the fr_FR locale, for instance, the \xAA and \xBA characters (ordmasculine
- and ordfeminine) are like this. This affected the treatment of \w and \W
- when they appeared in character classes, but not when they appeared outside
- a character class. The bit map for "word" characters is now created
- separately from the results of isalnum() instead of just taking it from the
- upper, lower, and digit maps. (Plus the underscore character, of course.)
-
- 5. The above bug also affected the handling of POSIX character classes such as
- [[:alpha:]] and [[:alnum:]]. These do not have their own bit maps in PCRE's
- permanent tables. Instead, the bit maps for such a class were previously
- created as the appropriate unions of the upper, lower, and digit bitmaps.
- Now they are created by subtraction from the [[:word:]] class, which has
- its own bitmap.
-
- 6. The [[:blank:]] character class matches horizontal, but not vertical space.
- It is created by subtracting the vertical space characters (\x09, \x0a,
- \x0b, \x0c) from the [[:space:]] bitmap. Previously, however, the
- subtraction was done in the overall bitmap for a character class, meaning
- that a class such as [\x0c[:blank:]] was incorrect because \x0c would not
- be recognized. This bug has been fixed.
-
- 7. Patches from the folks at Google:
-
- (a) pcrecpp.cc: "to handle a corner case that may or may not happen in
- real life, but is still worth protecting against".
-
- (b) pcrecpp.cc: "corrects a bug when negative radixes are used with
- regular expressions".
-
- (c) pcre_scanner.cc: avoid use of std::count() because not all systems
- have it.
-
- (d) Split off pcrecpparg.h from pcrecpp.h and had the former built by
- "configure" and the latter not, in order to fix a problem somebody had
- with compiling the Arg class on HP-UX.
-
- (e) Improve the error-handling of the C++ wrapper a little bit.
-
- (f) New tests for checking recursion limiting.
-
- 8. The pcre_memmove() function, which is used only if the environment does not
- have a standard memmove() function (and is therefore rarely compiled),
- contained two bugs: (a) use of int instead of size_t, and (b) it was not
- returning a result (though PCRE never actually uses the result).
-
- 9. In the POSIX regexec() interface, if nmatch is specified as a ridiculously
- large number - greater than INT_MAX/(3*sizeof(int)) - REG_ESPACE is
- returned instead of calling malloc() with an overflowing number that would
- most likely cause subsequent chaos.
-
-10. The debugging option of pcretest was not showing the NO_AUTO_CAPTURE flag.
-
-11. The POSIX flag REG_NOSUB is now supported. When a pattern that was compiled
- with this option is matched, the nmatch and pmatch options of regexec() are
- ignored.
-
-12. Added REG_UTF8 to the POSIX interface. This is not defined by POSIX, but is
- provided in case anyone wants to the the POSIX interface with UTF-8
- strings.
-
-13. Added CXXLDFLAGS to the Makefile parameters to provide settings only on the
- C++ linking (needed for some HP-UX environments).
-
-14. Avoid compiler warnings in get_ucpname() when compiled without UCP support
- (unused parameter) and in the pcre_printint() function (omitted "default"
- switch label when the default is to do nothing).
-
-15. Added some code to make it possible, when PCRE is compiled as a C++
- library, to replace subject pointers for pcre_exec() with a smart pointer
- class, thus making it possible to process discontinuous strings.
-
-16. The two macros PCRE_EXPORT and PCRE_DATA_SCOPE are confusing, and perform
- much the same function. They were added by different people who were trying
- to make PCRE easy to compile on non-Unix systems. It has been suggested
- that PCRE_EXPORT be abolished now that there is more automatic apparatus
- for compiling on Windows systems. I have therefore replaced it with
- PCRE_DATA_SCOPE. This is set automatically for Windows; if not set it
- defaults to "extern" for C or "extern C" for C++, which works fine on
- Unix-like systems. It is now possible to override the value of PCRE_DATA_
- SCOPE with something explicit in config.h. In addition:
-
- (a) pcreposix.h still had just "extern" instead of either of these macros;
- I have replaced it with PCRE_DATA_SCOPE.
-
- (b) Functions such as _pcre_xclass(), which are internal to the library,
- but external in the C sense, all had PCRE_EXPORT in their definitions.
- This is apparently wrong for the Windows case, so I have removed it.
- (It makes no difference on Unix-like systems.)
-
-17. Added a new limit, MATCH_LIMIT_RECURSION, which limits the depth of nesting
- of recursive calls to match(). This is different to MATCH_LIMIT because
- that limits the total number of calls to match(), not all of which increase
- the depth of recursion. Limiting the recursion depth limits the amount of
- stack (or heap if NO_RECURSE is set) that is used. The default can be set
- when PCRE is compiled, and changed at run time. A patch from Google adds
- this functionality to the C++ interface.
-
-18. Changes to the handling of Unicode character properties:
-
- (a) Updated the table to Unicode 4.1.0.
-
- (b) Recognize characters that are not in the table as "Cn" (undefined).
-
- (c) I revised the way the table is implemented to a much improved format
- which includes recognition of ranges. It now supports the ranges that
- are defined in UnicodeData.txt, and it also amalgamates other
- characters into ranges. This has reduced the number of entries in the
- table from around 16,000 to around 3,000, thus reducing its size
- considerably. I realized I did not need to use a tree structure after
- all - a binary chop search is just as efficient. Having reduced the
- number of entries, I extended their size from 6 bytes to 8 bytes to
- allow for more data.
-
- (d) Added support for Unicode script names via properties such as \p{Han}.
-
-19. In UTF-8 mode, a backslash followed by a non-Ascii character was not
- matching that character.
-
-20. When matching a repeated Unicode property with a minimum greater than zero,
- (for example \pL{2,}), PCRE could look past the end of the subject if it
- reached it while seeking the minimum number of characters. This could
- happen only if some of the characters were more than one byte long, because
- there is a check for at least the minimum number of bytes.
-
-21. Refactored the implementation of \p and \P so as to be more general, to
- allow for more different types of property in future. This has changed the
- compiled form incompatibly. Anybody with saved compiled patterns that use
- \p or \P will have to recompile them.
-
-22. Added "Any" and "L&" to the supported property types.
-
-23. Recognize \x{...} as a code point specifier, even when not in UTF-8 mode,
- but give a compile time error if the value is greater than 0xff.
-
-24. The man pages for pcrepartial, pcreprecompile, and pcre_compile2 were
- accidentally not being installed or uninstalled.
-
-25. The pcre.h file was built from pcre.h.in, but the only changes that were
- made were to insert the current release number. This seemed silly, because
- it made things harder for people building PCRE on systems that don't run
- "configure". I have turned pcre.h into a distributed file, no longer built
- by "configure", with the version identification directly included. There is
- no longer a pcre.h.in file.
-
- However, this change necessitated a change to the pcre-config script as
- well. It is built from pcre-config.in, and one of the substitutions was the
- release number. I have updated configure.ac so that ./configure now finds
- the release number by grepping pcre.h.
-
-26. Added the ability to run the tests under valgrind.
-
-
-Version 6.4 05-Sep-05
----------------------
-
- 1. Change 6.0/10/(l) to pcregrep introduced a bug that caused separator lines
- "--" to be printed when multiple files were scanned, even when none of the
- -A, -B, or -C options were used. This is not compatible with Gnu grep, so I
- consider it to be a bug, and have restored the previous behaviour.
-
- 2. A couple of code tidies to get rid of compiler warnings.
-
- 3. The pcretest program used to cheat by referring to symbols in the library
- whose names begin with _pcre_. These are internal symbols that are not
- really supposed to be visible externally, and in some environments it is
- possible to suppress them. The cheating is now confined to including
- certain files from the library's source, which is a bit cleaner.
-
- 4. Renamed pcre.in as pcre.h.in to go with pcrecpp.h.in; it also makes the
- file's purpose clearer.
-
- 5. Reorganized pcre_ucp_findchar().
-
-
-Version 6.3 15-Aug-05
----------------------
-
- 1. The file libpcre.pc.in did not have general read permission in the tarball.
-
- 2. There were some problems when building without C++ support:
-
- (a) If C++ support was not built, "make install" and "make test" still
- tried to test it.
-
- (b) There were problems when the value of CXX was explicitly set. Some
- changes have been made to try to fix these, and ...
-
- (c) --disable-cpp can now be used to explicitly disable C++ support.
-
- (d) The use of @CPP_OBJ@ directly caused a blank line preceded by a
- backslash in a target when C++ was disabled. This confuses some
- versions of "make", apparently. Using an intermediate variable solves
- this. (Same for CPP_LOBJ.)
-
- 3. $(LINK_FOR_BUILD) now includes $(CFLAGS_FOR_BUILD) and $(LINK)
- (non-Windows) now includes $(CFLAGS) because these flags are sometimes
- necessary on certain architectures.
-
- 4. Added a setting of -export-symbols-regex to the link command to remove
- those symbols that are exported in the C sense, but actually are local
- within the library, and not documented. Their names all begin with
- "_pcre_". This is not a perfect job, because (a) we have to except some
- symbols that pcretest ("illegally") uses, and (b) the facility isn't always
- available (and never for static libraries). I have made a note to try to
- find a way round (a) in the future.
-
-
-Version 6.2 01-Aug-05
----------------------
-
- 1. There was no test for integer overflow of quantifier values. A construction
- such as {1111111111111111} would give undefined results. What is worse, if
- a minimum quantifier for a parenthesized subpattern overflowed and became
- negative, the calculation of the memory size went wrong. This could have
- led to memory overwriting.
-
- 2. Building PCRE using VPATH was broken. Hopefully it is now fixed.
-
- 3. Added "b" to the 2nd argument of fopen() in dftables.c, for non-Unix-like
- operating environments where this matters.
-
- 4. Applied Giuseppe Maxia's patch to add additional features for controlling
- PCRE options from within the C++ wrapper.
-
- 5. Named capturing subpatterns were not being correctly counted when a pattern
- was compiled. This caused two problems: (a) If there were more than 100
- such subpatterns, the calculation of the memory needed for the whole
- compiled pattern went wrong, leading to an overflow error. (b) Numerical
- back references of the form \12, where the number was greater than 9, were
- not recognized as back references, even though there were sufficient
- previous subpatterns.
-
- 6. Two minor patches to pcrecpp.cc in order to allow it to compile on older
- versions of gcc, e.g. 2.95.4.
-
-
-Version 6.1 21-Jun-05
----------------------
-
- 1. There was one reference to the variable "posix" in pcretest.c that was not
- surrounded by "#if !defined NOPOSIX".
-
- 2. Make it possible to compile pcretest without DFA support, UTF8 support, or
- the cross-check on the old pcre_info() function, for the benefit of the
- cut-down version of PCRE that is currently imported into Exim.
-
- 3. A (silly) pattern starting with (?i)(?-i) caused an internal space
- allocation error. I've done the easy fix, which wastes 2 bytes for sensible
- patterns that start (?i) but I don't think that matters. The use of (?i) is
- just an example; this all applies to the other options as well.
-
- 4. Since libtool seems to echo the compile commands it is issuing, the output
- from "make" can be reduced a bit by putting "@" in front of each libtool
- compile command.
-
- 5. Patch from the folks at Google for configure.in to be a bit more thorough
- in checking for a suitable C++ installation before trying to compile the
- C++ stuff. This should fix a reported problem when a compiler was present,
- but no suitable headers.
-
- 6. The man pages all had just "PCRE" as their title. I have changed them to
- be the relevant file name. I have also arranged that these names are
- retained in the file doc/pcre.txt, which is a concatenation in text format
- of all the man pages except the little individual ones for each function.
-
- 7. The NON-UNIX-USE file had not been updated for the different set of source
- files that come with release 6. I also added a few comments about the C++
- wrapper.
-
-
-Version 6.0 07-Jun-05
----------------------
-
- 1. Some minor internal re-organization to help with my DFA experiments.
-
- 2. Some missing #ifdef SUPPORT_UCP conditionals in pcretest and printint that
- didn't matter for the library itself when fully configured, but did matter
- when compiling without UCP support, or within Exim, where the ucp files are
- not imported.
-
- 3. Refactoring of the library code to split up the various functions into
- different source modules. The addition of the new DFA matching code (see
- below) to a single monolithic source would have made it really too
- unwieldy, quite apart from causing all the code to be include in a
- statically linked application, when only some functions are used. This is
- relevant even without the DFA addition now that patterns can be compiled in
- one application and matched in another.
-
- The downside of splitting up is that there have to be some external
- functions and data tables that are used internally in different modules of
- the library but which are not part of the API. These have all had their
- names changed to start with "_pcre_" so that they are unlikely to clash
- with other external names.
-
- 4. Added an alternate matching function, pcre_dfa_exec(), which matches using
- a different (DFA) algorithm. Although it is slower than the original
- function, it does have some advantages for certain types of matching
- problem.
-
- 5. Upgrades to pcretest in order to test the features of pcre_dfa_exec(),
- including restarting after a partial match.
-
- 6. A patch for pcregrep that defines INVALID_FILE_ATTRIBUTES if it is not
- defined when compiling for Windows was sent to me. I have put it into the
- code, though I have no means of testing or verifying it.
-
- 7. Added the pcre_refcount() auxiliary function.
-
- 8. Added the PCRE_FIRSTLINE option. This constrains an unanchored pattern to
- match before or at the first newline in the subject string. In pcretest,
- the /f option on a pattern can be used to set this.
-
- 9. A repeated \w when used in UTF-8 mode with characters greater than 256
- would behave wrongly. This has been present in PCRE since release 4.0.
-
-10. A number of changes to the pcregrep command:
-
- (a) Refactored how -x works; insert ^(...)$ instead of setting
- PCRE_ANCHORED and checking the length, in preparation for adding
- something similar for -w.
-
- (b) Added the -w (match as a word) option.
-
- (c) Refactored the way lines are read and buffered so as to have more
- than one at a time available.
-
- (d) Implemented a pcregrep test script.
-
- (e) Added the -M (multiline match) option. This allows patterns to match
- over several lines of the subject. The buffering ensures that at least
- 8K, or the rest of the document (whichever is the shorter) is available
- for matching (and similarly the previous 8K for lookbehind assertions).
-
- (f) Changed the --help output so that it now says
-
- -w, --word-regex(p)
-
- instead of two lines, one with "regex" and the other with "regexp"
- because that confused at least one person since the short forms are the
- same. (This required a bit of code, as the output is generated
- automatically from a table. It wasn't just a text change.)
-
- (g) -- can be used to terminate pcregrep options if the next thing isn't an
- option but starts with a hyphen. Could be a pattern or a path name
- starting with a hyphen, for instance.
-
- (h) "-" can be given as a file name to represent stdin.
-
- (i) When file names are being printed, "(standard input)" is used for
- the standard input, for compatibility with GNU grep. Previously
- "<stdin>" was used.
-
- (j) The option --label=xxx can be used to supply a name to be used for
- stdin when file names are being printed. There is no short form.
-
- (k) Re-factored the options decoding logic because we are going to add
- two more options that take data. Such options can now be given in four
- different ways, e.g. "-fname", "-f name", "--file=name", "--file name".
-
- (l) Added the -A, -B, and -C options for requesting that lines of context
- around matches be printed.
-
- (m) Added the -L option to print the names of files that do not contain
- any matching lines, that is, the complement of -l.
-
- (n) The return code is 2 if any file cannot be opened, but pcregrep does
- continue to scan other files.
-
- (o) The -s option was incorrectly implemented. For compatibility with other
- greps, it now suppresses the error message for a non-existent or non-
- accessible file (but not the return code). There is a new option called
- -q that suppresses the output of matching lines, which was what -s was
- previously doing.
-
- (p) Added --include and --exclude options to specify files for inclusion
- and exclusion when recursing.
-
-11. The Makefile was not using the Autoconf-supported LDFLAGS macro properly.
- Hopefully, it now does.
-
-12. Missing cast in pcre_study().
-
-13. Added an "uninstall" target to the makefile.
-
-14. Replaced "extern" in the function prototypes in Makefile.in with
- "PCRE_DATA_SCOPE", which defaults to 'extern' or 'extern "C"' in the Unix
- world, but is set differently for Windows.
-
-15. Added a second compiling function called pcre_compile2(). The only
- difference is that it has an extra argument, which is a pointer to an
- integer error code. When there is a compile-time failure, this is set
- non-zero, in addition to the error test pointer being set to point to an
- error message. The new argument may be NULL if no error number is required
- (but then you may as well call pcre_compile(), which is now just a
- wrapper). This facility is provided because some applications need a
- numeric error indication, but it has also enabled me to tidy up the way
- compile-time errors are handled in the POSIX wrapper.
-
-16. Added VPATH=.libs to the makefile; this should help when building with one
- prefix path and installing with another. (Or so I'm told by someone who
- knows more about this stuff than I do.)
-
-17. Added a new option, REG_DOTALL, to the POSIX function regcomp(). This
- passes PCRE_DOTALL to the pcre_compile() function, making the "." character
- match everything, including newlines. This is not POSIX-compatible, but
- somebody wanted the feature. From pcretest it can be activated by using
- both the P and the s flags.
-
-18. AC_PROG_LIBTOOL appeared twice in Makefile.in. Removed one.
-
-19. libpcre.pc was being incorrectly installed as executable.
-
-20. A couple of places in pcretest check for end-of-line by looking for '\n';
- it now also looks for '\r' so that it will work unmodified on Windows.
-
-21. Added Google's contributed C++ wrapper to the distribution.
-
-22. Added some untidy missing memory free() calls in pcretest, to keep
- Electric Fence happy when testing.
-
-
-
-Version 5.0 13-Sep-04
----------------------
-
- 1. Internal change: literal characters are no longer packed up into items
- containing multiple characters in a single byte-string. Each character
- is now matched using a separate opcode. However, there may be more than one
- byte in the character in UTF-8 mode.
-
- 2. The pcre_callout_block structure has two new fields: pattern_position and
- next_item_length. These contain the offset in the pattern to the next match
- item, and its length, respectively.
-
- 3. The PCRE_AUTO_CALLOUT option for pcre_compile() requests the automatic
- insertion of callouts before each pattern item. Added the /C option to
- pcretest to make use of this.
-
- 4. On the advice of a Windows user, the lines
-
- #if defined(_WIN32) || defined(WIN32)
- _setmode( _fileno( stdout ), 0x8000 );
- #endif /* defined(_WIN32) || defined(WIN32) */
-
- have been added to the source of pcretest. This apparently does useful
- magic in relation to line terminators.
-
- 5. Changed "r" and "w" in the calls to fopen() in pcretest to "rb" and "wb"
- for the benefit of those environments where the "b" makes a difference.
-
- 6. The icc compiler has the same options as gcc, but "configure" doesn't seem
- to know about it. I have put a hack into configure.in that adds in code
- to set GCC=yes if CC=icc. This seems to end up at a point in the
- generated configure script that is early enough to affect the setting of
- compiler options, which is what is needed, but I have no means of testing
- whether it really works. (The user who reported this had patched the
- generated configure script, which of course I cannot do.)
-
- LATER: After change 22 below (new libtool files), the configure script
- seems to know about icc (and also ecc). Therefore, I have commented out
- this hack in configure.in.
-
- 7. Added support for pkg-config (2 patches were sent in).
-
- 8. Negated POSIX character classes that used a combination of internal tables
- were completely broken. These were [[:^alpha:]], [[:^alnum:]], and
- [[:^ascii]]. Typically, they would match almost any characters. The other
- POSIX classes were not broken in this way.
-
- 9. Matching the pattern "\b.*?" against "ab cd", starting at offset 1, failed
- to find the match, as PCRE was deluded into thinking that the match had to
- start at the start point or following a newline. The same bug applied to
- patterns with negative forward assertions or any backward assertions
- preceding ".*" at the start, unless the pattern required a fixed first
- character. This was a failing pattern: "(?!.bcd).*". The bug is now fixed.
-
-10. In UTF-8 mode, when moving forwards in the subject after a failed match
- starting at the last subject character, bytes beyond the end of the subject
- string were read.
-
-11. Renamed the variable "class" as "classbits" to make life easier for C++
- users. (Previously there was a macro definition, but it apparently wasn't
- enough.)
-
-12. Added the new field "tables" to the extra data so that tables can be passed
- in at exec time, or the internal tables can be re-selected. This allows
- a compiled regex to be saved and re-used at a later time by a different
- program that might have everything at different addresses.
-
-13. Modified the pcre-config script so that, when run on Solaris, it shows a
- -R library as well as a -L library.
-
-14. The debugging options of pcretest (-d on the command line or D on a
- pattern) showed incorrect output for anything following an extended class
- that contained multibyte characters and which was followed by a quantifier.
-
-15. Added optional support for general category Unicode character properties
- via the \p, \P, and \X escapes. Unicode property support implies UTF-8
- support. It adds about 90K to the size of the library. The meanings of the
- inbuilt class escapes such as \d and \s have NOT been changed.
-
-16. Updated pcredemo.c to include calls to free() to release the memory for the
- compiled pattern.
-
-17. The generated file chartables.c was being created in the source directory
- instead of in the building directory. This caused the build to fail if the
- source directory was different from the building directory, and was
- read-only.
-
-18. Added some sample Win commands from Mark Tetrode into the NON-UNIX-USE
- file. No doubt somebody will tell me if they don't make sense... Also added
- Dan Mooney's comments about building on OpenVMS.
-
-19. Added support for partial matching via the PCRE_PARTIAL option for
- pcre_exec() and the \P data escape in pcretest.
-
-20. Extended pcretest with 3 new pattern features:
-
- (i) A pattern option of the form ">rest-of-line" causes pcretest to
- write the compiled pattern to the file whose name is "rest-of-line".
- This is a straight binary dump of the data, with the saved pointer to
- the character tables forced to be NULL. The study data, if any, is
- written too. After writing, pcretest reads a new pattern.
-
- (ii) If, instead of a pattern, "<rest-of-line" is given, pcretest reads a
- compiled pattern from the given file. There must not be any
- occurrences of "<" in the file name (pretty unlikely); if there are,
- pcretest will instead treat the initial "<" as a pattern delimiter.
- After reading in the pattern, pcretest goes on to read data lines as
- usual.
-
- (iii) The F pattern option causes pcretest to flip the bytes in the 32-bit
- and 16-bit fields in a compiled pattern, to simulate a pattern that
- was compiled on a host of opposite endianness.
-
-21. The pcre-exec() function can now cope with patterns that were compiled on
- hosts of opposite endianness, with this restriction:
-
- As for any compiled expression that is saved and used later, the tables
- pointer field cannot be preserved; the extra_data field in the arguments
- to pcre_exec() should be used to pass in a tables address if a value
- other than the default internal tables were used at compile time.
-
-22. Calling pcre_exec() with a negative value of the "ovecsize" parameter is
- now diagnosed as an error. Previously, most of the time, a negative number
- would have been treated as zero, but if in addition "ovector" was passed as
- NULL, a crash could occur.
-
-23. Updated the files ltmain.sh, config.sub, config.guess, and aclocal.m4 with
- new versions from the libtool 1.5 distribution (the last one is a copy of
- a file called libtool.m4). This seems to have fixed the need to patch
- "configure" to support Darwin 1.3 (which I used to do). However, I still
- had to patch ltmain.sh to ensure that ${SED} is set (it isn't on my
- workstation).
-
-24. Changed the PCRE licence to be the more standard "BSD" licence.
-
-
-Version 4.5 01-Dec-03
----------------------
-
- 1. There has been some re-arrangement of the code for the match() function so
- that it can be compiled in a version that does not call itself recursively.
- Instead, it keeps those local variables that need separate instances for
- each "recursion" in a frame on the heap, and gets/frees frames whenever it
- needs to "recurse". Keeping track of where control must go is done by means
- of setjmp/longjmp. The whole thing is implemented by a set of macros that
- hide most of the details from the main code, and operates only if
- NO_RECURSE is defined while compiling pcre.c. If PCRE is built using the
- "configure" mechanism, "--disable-stack-for-recursion" turns on this way of
- operating.
-
- To make it easier for callers to provide specially tailored get/free
- functions for this usage, two new functions, pcre_stack_malloc, and
- pcre_stack_free, are used. They are always called in strict stacking order,
- and the size of block requested is always the same.
-
- The PCRE_CONFIG_STACKRECURSE info parameter can be used to find out whether
- PCRE has been compiled to use the stack or the heap for recursion. The
- -C option of pcretest uses this to show which version is compiled.
-
- A new data escape \S, is added to pcretest; it causes the amounts of store
- obtained and freed by both kinds of malloc/free at match time to be added
- to the output.
-
- 2. Changed the locale test to use "fr_FR" instead of "fr" because that's
- what's available on my current Linux desktop machine.
-
- 3. When matching a UTF-8 string, the test for a valid string at the start has
- been extended. If start_offset is not zero, PCRE now checks that it points
- to a byte that is the start of a UTF-8 character. If not, it returns
- PCRE_ERROR_BADUTF8_OFFSET (-11). Note: the whole string is still checked;
- this is necessary because there may be backward assertions in the pattern.
- When matching the same subject several times, it may save resources to use
- PCRE_NO_UTF8_CHECK on all but the first call if the string is long.
-
- 4. The code for checking the validity of UTF-8 strings has been tightened so
- that it rejects (a) strings containing 0xfe or 0xff bytes and (b) strings
- containing "overlong sequences".
-
- 5. Fixed a bug (appearing twice) that I could not find any way of exploiting!
- I had written "if ((digitab[*p++] && chtab_digit) == 0)" where the "&&"
- should have been "&", but it just so happened that all the cases this let
- through by mistake were picked up later in the function.
-
- 6. I had used a variable called "isblank" - this is a C99 function, causing
- some compilers to warn. To avoid this, I renamed it (as "blankclass").
-
- 7. Cosmetic: (a) only output another newline at the end of pcretest if it is
- prompting; (b) run "./pcretest /dev/null" at the start of the test script
- so the version is shown; (c) stop "make test" echoing "./RunTest".
-
- 8. Added patches from David Burgess to enable PCRE to run on EBCDIC systems.
-
- 9. The prototype for memmove() for systems that don't have it was using
- size_t, but the inclusion of the header that defines size_t was later. I've
- moved the #includes for the C headers earlier to avoid this.
-
-10. Added some adjustments to the code to make it easier to compiler on certain
- special systems:
-
- (a) Some "const" qualifiers were missing.
- (b) Added the macro EXPORT before all exported functions; by default this
- is defined to be empty.
- (c) Changed the dftables auxiliary program (that builds chartables.c) so
- that it reads its output file name as an argument instead of writing
- to the standard output and assuming this can be redirected.
-
-11. In UTF-8 mode, if a recursive reference (e.g. (?1)) followed a character
- class containing characters with values greater than 255, PCRE compilation
- went into a loop.
-
-12. A recursive reference to a subpattern that was within another subpattern
- that had a minimum quantifier of zero caused PCRE to crash. For example,
- (x(y(?2))z)? provoked this bug with a subject that got as far as the
- recursion. If the recursively-called subpattern itself had a zero repeat,
- that was OK.
-
-13. In pcretest, the buffer for reading a data line was set at 30K, but the
- buffer into which it was copied (for escape processing) was still set at
- 1024, so long lines caused crashes.
-
-14. A pattern such as /[ab]{1,3}+/ failed to compile, giving the error
- "internal error: code overflow...". This applied to any character class
- that was followed by a possessive quantifier.
-
-15. Modified the Makefile to add libpcre.la as a prerequisite for
- libpcreposix.la because I was told this is needed for a parallel build to
- work.
-
-16. If a pattern that contained .* following optional items at the start was
- studied, the wrong optimizing data was generated, leading to matching
- errors. For example, studying /[ab]*.*c/ concluded, erroneously, that any
- matching string must start with a or b or c. The correct conclusion for
- this pattern is that a match can start with any character.
-
-
-Version 4.4 13-Aug-03
----------------------
-
- 1. In UTF-8 mode, a character class containing characters with values between
- 127 and 255 was not handled correctly if the compiled pattern was studied.
- In fixing this, I have also improved the studying algorithm for such
- classes (slightly).
-
- 2. Three internal functions had redundant arguments passed to them. Removal
- might give a very teeny performance improvement.
-
- 3. Documentation bug: the value of the capture_top field in a callout is *one
- more than* the number of the hightest numbered captured substring.
-
- 4. The Makefile linked pcretest and pcregrep with -lpcre, which could result
- in incorrectly linking with a previously installed version. They now link
- explicitly with libpcre.la.
-
- 5. configure.in no longer needs to recognize Cygwin specially.
-
- 6. A problem in pcre.in for Windows platforms is fixed.
-
- 7. If a pattern was successfully studied, and the -d (or /D) flag was given to
- pcretest, it used to include the size of the study block as part of its
- output. Unfortunately, the structure contains a field that has a different
- size on different hardware architectures. This meant that the tests that
- showed this size failed. As the block is currently always of a fixed size,
- this information isn't actually particularly useful in pcretest output, so
- I have just removed it.
-
- 8. Three pre-processor statements accidentally did not start in column 1.
- Sadly, there are *still* compilers around that complain, even though
- standard C has not required this for well over a decade. Sigh.
-
- 9. In pcretest, the code for checking callouts passed small integers in the
- callout_data field, which is a void * field. However, some picky compilers
- complained about the casts involved for this on 64-bit systems. Now
- pcretest passes the address of the small integer instead, which should get
- rid of the warnings.
-
-10. By default, when in UTF-8 mode, PCRE now checks for valid UTF-8 strings at
- both compile and run time, and gives an error if an invalid UTF-8 sequence
- is found. There is a option for disabling this check in cases where the
- string is known to be correct and/or the maximum performance is wanted.
-
-11. In response to a bug report, I changed one line in Makefile.in from
-
- -Wl,--out-implib,.libs/lib@WIN_PREFIX@pcreposix.dll.a \
- to
- -Wl,--out-implib,.libs/@WIN_PREFIX@libpcreposix.dll.a \
-
- to look similar to other lines, but I have no way of telling whether this
- is the right thing to do, as I do not use Windows. No doubt I'll get told
- if it's wrong...
-
-
-Version 4.3 21-May-03
----------------------
-
-1. Two instances of @WIN_PREFIX@ omitted from the Windows targets in the
- Makefile.
-
-2. Some refactoring to improve the quality of the code:
-
- (i) The utf8_table... variables are now declared "const".
-
- (ii) The code for \cx, which used the "case flipping" table to upper case
- lower case letters, now just substracts 32. This is ASCII-specific,
- but the whole concept of \cx is ASCII-specific, so it seems
- reasonable.
-
- (iii) PCRE was using its character types table to recognize decimal and
- hexadecimal digits in the pattern. This is silly, because it handles
- only 0-9, a-f, and A-F, but the character types table is locale-
- specific, which means strange things might happen. A private
- table is now used for this - though it costs 256 bytes, a table is
- much faster than multiple explicit tests. Of course, the standard
- character types table is still used for matching digits in subject
- strings against \d.
-
- (iv) Strictly, the identifier ESC_t is reserved by POSIX (all identifiers
- ending in _t are). So I've renamed it as ESC_tee.
-
-3. The first argument for regexec() in the POSIX wrapper should have been
- defined as "const".
-
-4. Changed pcretest to use malloc() for its buffers so that they can be
- Electric Fenced for debugging.
-
-5. There were several places in the code where, in UTF-8 mode, PCRE would try
- to read one or more bytes before the start of the subject string. Often this
- had no effect on PCRE's behaviour, but in some circumstances it could
- provoke a segmentation fault.
-
-6. A lookbehind at the start of a pattern in UTF-8 mode could also cause PCRE
- to try to read one or more bytes before the start of the subject string.
-
-7. A lookbehind in a pattern matched in non-UTF-8 mode on a PCRE compiled with
- UTF-8 support could misbehave in various ways if the subject string
- contained bytes with the 0x80 bit set and the 0x40 bit unset in a lookbehind
- area. (PCRE was not checking for the UTF-8 mode flag, and trying to move
- back over UTF-8 characters.)
-
-
-Version 4.2 14-Apr-03
----------------------
-
-1. Typo "#if SUPPORT_UTF8" instead of "#ifdef SUPPORT_UTF8" fixed.
-
-2. Changes to the building process, supplied by Ronald Landheer-Cieslak
- [ON_WINDOWS]: new variable, "#" on non-Windows platforms
- [NOT_ON_WINDOWS]: new variable, "#" on Windows platforms
- [WIN_PREFIX]: new variable, "cyg" for Cygwin
- * Makefile.in: use autoconf substitution for OBJEXT, EXEEXT, BUILD_OBJEXT
- and BUILD_EXEEXT
- Note: automatic setting of the BUILD variables is not yet working
- set CPPFLAGS and BUILD_CPPFLAGS (but don't use yet) - should be used at
- compile-time but not at link-time
- [LINK]: use for linking executables only
- make different versions for Windows and non-Windows
- [LINKLIB]: new variable, copy of UNIX-style LINK, used for linking
- libraries
- [LINK_FOR_BUILD]: new variable
- [OBJEXT]: use throughout
- [EXEEXT]: use throughout
- <winshared>: new target
- <wininstall>: new target
- <dftables.o>: use native compiler
- <dftables>: use native linker
- <install>: handle Windows platform correctly
- <clean>: ditto
- <check>: ditto
- copy DLL to top builddir before testing
-
- As part of these changes, -no-undefined was removed again. This was reported
- to give trouble on HP-UX 11.0, so getting rid of it seems like a good idea
- in any case.
-
-3. Some tidies to get rid of compiler warnings:
-
- . In the match_data structure, match_limit was an unsigned long int, whereas
- match_call_count was an int. I've made them both unsigned long ints.
-
- . In pcretest the fact that a const uschar * doesn't automatically cast to
- a void * provoked a warning.
-
- . Turning on some more compiler warnings threw up some "shadow" variables
- and a few more missing casts.
-
-4. If PCRE was complied with UTF-8 support, but called without the PCRE_UTF8
- option, a class that contained a single character with a value between 128
- and 255 (e.g. /[\xFF]/) caused PCRE to crash.
-
-5. If PCRE was compiled with UTF-8 support, but called without the PCRE_UTF8
- option, a class that contained several characters, but with at least one
- whose value was between 128 and 255 caused PCRE to crash.
-
-
-Version 4.1 12-Mar-03
----------------------
-
-1. Compiling with gcc -pedantic found a couple of places where casts were
-needed, and a string in dftables.c that was longer than standard compilers are
-required to support.
-
-2. Compiling with Sun's compiler found a few more places where the code could
-be tidied up in order to avoid warnings.
-
-3. The variables for cross-compiling were called HOST_CC and HOST_CFLAGS; the
-first of these names is deprecated in the latest Autoconf in favour of the name
-CC_FOR_BUILD, because "host" is typically used to mean the system on which the
-compiled code will be run. I can't find a reference for HOST_CFLAGS, but by
-analogy I have changed it to CFLAGS_FOR_BUILD.
-
-4. Added -no-undefined to the linking command in the Makefile, because this is
-apparently helpful for Windows. To make it work, also added "-L. -lpcre" to the
-linking step for the pcreposix library.
-
-5. PCRE was failing to diagnose the case of two named groups with the same
-name.
-
-6. A problem with one of PCRE's optimizations was discovered. PCRE remembers a
-literal character that is needed in the subject for a match, and scans along to
-ensure that it is present before embarking on the full matching process. This
-saves time in cases of nested unlimited repeats that are never going to match.
-Problem: the scan can take a lot of time if the subject is very long (e.g.
-megabytes), thus penalizing straightforward matches. It is now done only if the
-amount of subject to be scanned is less than 1000 bytes.
-
-7. A lesser problem with the same optimization is that it was recording the
-first character of an anchored pattern as "needed", thus provoking a search
-right along the subject, even when the first match of the pattern was going to
-fail. The "needed" character is now not set for anchored patterns, unless it
-follows something in the pattern that is of non-fixed length. Thus, it still
-fulfils its original purpose of finding quick non-matches in cases of nested
-unlimited repeats, but isn't used for simple anchored patterns such as /^abc/.
-
-
-Version 4.0 17-Feb-03
----------------------
-
-1. If a comment in an extended regex that started immediately after a meta-item
-extended to the end of string, PCRE compiled incorrect data. This could lead to
-all kinds of weird effects. Example: /#/ was bad; /()#/ was bad; /a#/ was not.
-
-2. Moved to autoconf 2.53 and libtool 1.4.2.
-
-3. Perl 5.8 no longer needs "use utf8" for doing UTF-8 things. Consequently,
-the special perltest8 script is no longer needed - all the tests can be run
-from a single perltest script.
-
-4. From 5.004, Perl has not included the VT character (0x0b) in the set defined
-by \s. It has now been removed in PCRE. This means it isn't recognized as
-whitespace in /x regexes too, which is the same as Perl. Note that the POSIX
-class [:space:] *does* include VT, thereby creating a mess.
-
-5. Added the class [:blank:] (a GNU extension from Perl 5.8) to match only
-space and tab.
-
-6. Perl 5.005 was a long time ago. It's time to amalgamate the tests that use
-its new features into the main test script, reducing the number of scripts.
-
-7. Perl 5.8 has changed the meaning of patterns like /a(?i)b/. Earlier versions
-were backward compatible, and made the (?i) apply to the whole pattern, as if
-/i were given. Now it behaves more logically, and applies the option setting
-only to what follows. PCRE has been changed to follow suit. However, if it
-finds options settings right at the start of the pattern, it extracts them into
-the global options, as before. Thus, they show up in the info data.
-
-8. Added support for the \Q...\E escape sequence. Characters in between are
-treated as literals. This is slightly different from Perl in that $ and @ are
-also handled as literals inside the quotes. In Perl, they will cause variable
-interpolation. Note the following examples:
-
- Pattern PCRE matches Perl matches
-
- \Qabc$xyz\E abc$xyz abc followed by the contents of $xyz
- \Qabc\$xyz\E abc\$xyz abc\$xyz
- \Qabc\E\$\Qxyz\E abc$xyz abc$xyz
-
-For compatibility with Perl, \Q...\E sequences are recognized inside character
-classes as well as outside them.
-
-9. Re-organized 3 code statements in pcretest to avoid "overflow in
-floating-point constant arithmetic" warnings from a Microsoft compiler. Added a
-(size_t) cast to one statement in pcretest and one in pcreposix to avoid
-signed/unsigned warnings.
-
-10. SunOS4 doesn't have strtoul(). This was used only for unpicking the -o
-option for pcretest, so I've replaced it by a simple function that does just
-that job.
-
-11. pcregrep was ending with code 0 instead of 2 for the commands "pcregrep" or
-"pcregrep -".
-
-12. Added "possessive quantifiers" ?+, *+, ++, and {,}+ which come from Sun's
-Java package. This provides some syntactic sugar for simple cases of what my
-documentation calls "once-only subpatterns". A pattern such as x*+ is the same
-as (?>x*). In other words, if what is inside (?>...) is just a single repeated
-item, you can use this simplified notation. Note that only makes sense with
-greedy quantifiers. Consequently, the use of the possessive quantifier forces
-greediness, whatever the setting of the PCRE_UNGREEDY option.
-
-13. A change of greediness default within a pattern was not taking effect at
-the current level for patterns like /(b+(?U)a+)/. It did apply to parenthesized
-subpatterns that followed. Patterns like /b+(?U)a+/ worked because the option
-was abstracted outside.
-
-14. PCRE now supports the \G assertion. It is true when the current matching
-position is at the start point of the match. This differs from \A when the
-starting offset is non-zero. Used with the /g option of pcretest (or similar
-code), it works in the same way as it does for Perl's /g option. If all
-alternatives of a regex begin with \G, the expression is anchored to the start
-match position, and the "anchored" flag is set in the compiled expression.
-
-15. Some bugs concerning the handling of certain option changes within patterns
-have been fixed. These applied to options other than (?ims). For example,
-"a(?x: b c )d" did not match "XabcdY" but did match "Xa b c dY". It should have
-been the other way round. Some of this was related to change 7 above.
-
-16. PCRE now gives errors for /[.x.]/ and /[=x=]/ as unsupported POSIX
-features, as Perl does. Previously, PCRE gave the warnings only for /[[.x.]]/
-and /[[=x=]]/. PCRE now also gives an error for /[:name:]/ because it supports
-POSIX classes only within a class (e.g. /[[:alpha:]]/).
-
-17. Added support for Perl's \C escape. This matches one byte, even in UTF8
-mode. Unlike ".", it always matches newline, whatever the setting of
-PCRE_DOTALL. However, PCRE does not permit \C to appear in lookbehind
-assertions. Perl allows it, but it doesn't (in general) work because it can't
-calculate the length of the lookbehind. At least, that's the case for Perl
-5.8.0 - I've been told they are going to document that it doesn't work in
-future.
-
-18. Added an error diagnosis for escapes that PCRE does not support: these are
-\L, \l, \N, \P, \p, \U, \u, and \X.
-
-19. Although correctly diagnosing a missing ']' in a character class, PCRE was
-reading past the end of the pattern in cases such as /[abcd/.
-
-20. PCRE was getting more memory than necessary for patterns with classes that
-contained both POSIX named classes and other characters, e.g. /[[:space:]abc/.
-
-21. Added some code, conditional on #ifdef VPCOMPAT, to make life easier for
-compiling PCRE for use with Virtual Pascal.
-
-22. Small fix to the Makefile to make it work properly if the build is done
-outside the source tree.
-
-23. Added a new extension: a condition to go with recursion. If a conditional
-subpattern starts with (?(R) the "true" branch is used if recursion has
-happened, whereas the "false" branch is used only at the top level.
-
-24. When there was a very long string of literal characters (over 255 bytes
-without UTF support, over 250 bytes with UTF support), the computation of how
-much memory was required could be incorrect, leading to segfaults or other
-strange effects.
-
-25. PCRE was incorrectly assuming anchoring (either to start of subject or to
-start of line for a non-DOTALL pattern) when a pattern started with (.*) and
-there was a subsequent back reference to those brackets. This meant that, for
-example, /(.*)\d+\1/ failed to match "abc123bc". Unfortunately, it isn't
-possible to check for precisely this case. All we can do is abandon the
-optimization if .* occurs inside capturing brackets when there are any back
-references whatsoever. (See below for a better fix that came later.)
-
-26. The handling of the optimization for finding the first character of a
-non-anchored pattern, and for finding a character that is required later in the
-match were failing in some cases. This didn't break the matching; it just
-failed to optimize when it could. The way this is done has been re-implemented.
-
-27. Fixed typo in error message for invalid (?R item (it said "(?p").
-
-28. Added a new feature that provides some of the functionality that Perl
-provides with (?{...}). The facility is termed a "callout". The way it is done
-in PCRE is for the caller to provide an optional function, by setting
-pcre_callout to its entry point. Like pcre_malloc and pcre_free, this is a
-global variable. By default it is unset, which disables all calling out. To get
-the function called, the regex must include (?C) at appropriate points. This
-is, in fact, equivalent to (?C0), and any number <= 255 may be given with (?C).
-This provides a means of identifying different callout points. When PCRE
-reaches such a point in the regex, if pcre_callout has been set, the external
-function is called. It is provided with data in a structure called
-pcre_callout_block, which is defined in pcre.h. If the function returns 0,
-matching continues; if it returns a non-zero value, the match at the current
-point fails. However, backtracking will occur if possible. [This was changed
-later and other features added - see item 49 below.]
-
-29. pcretest is upgraded to test the callout functionality. It provides a
-callout function that displays information. By default, it shows the start of
-the match and the current position in the text. There are some new data escapes
-to vary what happens:
-
- \C+ in addition, show current contents of captured substrings
- \C- do not supply a callout function
- \C!n return 1 when callout number n is reached
- \C!n!m return 1 when callout number n is reached for the mth time
-
-30. If pcregrep was called with the -l option and just a single file name, it
-output "<stdin>" if a match was found, instead of the file name.
-
-31. Improve the efficiency of the POSIX API to PCRE. If the number of capturing
-slots is less than POSIX_MALLOC_THRESHOLD, use a block on the stack to pass to
-pcre_exec(). This saves a malloc/free per call. The default value of
-POSIX_MALLOC_THRESHOLD is 10; it can be changed by --with-posix-malloc-threshold
-when configuring.
-
-32. The default maximum size of a compiled pattern is 64K. There have been a
-few cases of people hitting this limit. The code now uses macros to handle the
-storing of links as offsets within the compiled pattern. It defaults to 2-byte
-links, but this can be changed to 3 or 4 bytes by --with-link-size when
-configuring. Tests 2 and 5 work only with 2-byte links because they output
-debugging information about compiled patterns.
-
-33. Internal code re-arrangements:
-
-(a) Moved the debugging function for printing out a compiled regex into
- its own source file (printint.c) and used #include to pull it into
- pcretest.c and, when DEBUG is defined, into pcre.c, instead of having two
- separate copies.
-
-(b) Defined the list of op-code names for debugging as a macro in
- internal.h so that it is next to the definition of the opcodes.
-
-(c) Defined a table of op-code lengths for simpler skipping along compiled
- code. This is again a macro in internal.h so that it is next to the
- definition of the opcodes.
-
-34. Added support for recursive calls to individual subpatterns, along the
-lines of Robin Houston's patch (but implemented somewhat differently).
-
-35. Further mods to the Makefile to help Win32. Also, added code to pcregrep to
-allow it to read and process whole directories in Win32. This code was
-contributed by Lionel Fourquaux; it has not been tested by me.
-
-36. Added support for named subpatterns. The Python syntax (?P<name>...) is
-used to name a group. Names consist of alphanumerics and underscores, and must
-be unique. Back references use the syntax (?P=name) and recursive calls use
-(?P>name) which is a PCRE extension to the Python extension. Groups still have
-numbers. The function pcre_fullinfo() can be used after compilation to extract
-a name/number map. There are three relevant calls:
-
- PCRE_INFO_NAMEENTRYSIZE yields the size of each entry in the map
- PCRE_INFO_NAMECOUNT yields the number of entries
- PCRE_INFO_NAMETABLE yields a pointer to the map.
-
-The map is a vector of fixed-size entries. The size of each entry depends on
-the length of the longest name used. The first two bytes of each entry are the
-group number, most significant byte first. There follows the corresponding
-name, zero terminated. The names are in alphabetical order.
-
-37. Make the maximum literal string in the compiled code 250 for the non-UTF-8
-case instead of 255. Making it the same both with and without UTF-8 support
-means that the same test output works with both.
-
-38. There was a case of malloc(0) in the POSIX testing code in pcretest. Avoid
-calling malloc() with a zero argument.
-
-39. Change 25 above had to resort to a heavy-handed test for the .* anchoring
-optimization. I've improved things by keeping a bitmap of backreferences with
-numbers 1-31 so that if .* occurs inside capturing brackets that are not in
-fact referenced, the optimization can be applied. It is unlikely that a
-relevant occurrence of .* (i.e. one which might indicate anchoring or forcing
-the match to follow \n) will appear inside brackets with a number greater than
-31, but if it does, any back reference > 31 suppresses the optimization.
-
-40. Added a new compile-time option PCRE_NO_AUTO_CAPTURE. This has the effect
-of disabling numbered capturing parentheses. Any opening parenthesis that is
-not followed by ? behaves as if it were followed by ?: but named parentheses
-can still be used for capturing (and they will acquire numbers in the usual
-way).
-
-41. Redesigned the return codes from the match() function into yes/no/error so
-that errors can be passed back from deep inside the nested calls. A malloc
-failure while inside a recursive subpattern call now causes the
-PCRE_ERROR_NOMEMORY return instead of quietly going wrong.
-
-42. It is now possible to set a limit on the number of times the match()
-function is called in a call to pcre_exec(). This facility makes it possible to
-limit the amount of recursion and backtracking, though not in a directly
-obvious way, because the match() function is used in a number of different
-circumstances. The count starts from zero for each position in the subject
-string (for non-anchored patterns). The default limit is, for compatibility, a
-large number, namely 10 000 000. You can change this in two ways:
-
-(a) When configuring PCRE before making, you can use --with-match-limit=n
- to set a default value for the compiled library.
-
-(b) For each call to pcre_exec(), you can pass a pcre_extra block in which
- a different value is set. See 45 below.
-
-If the limit is exceeded, pcre_exec() returns PCRE_ERROR_MATCHLIMIT.
-
-43. Added a new function pcre_config(int, void *) to enable run-time extraction
-of things that can be changed at compile time. The first argument specifies
-what is wanted and the second points to where the information is to be placed.
-The current list of available information is:
-
- PCRE_CONFIG_UTF8
-
-The output is an integer that is set to one if UTF-8 support is available;
-otherwise it is set to zero.
-
- PCRE_CONFIG_NEWLINE
-
-The output is an integer that it set to the value of the code that is used for
-newline. It is either LF (10) or CR (13).
-
- PCRE_CONFIG_LINK_SIZE
-
-The output is an integer that contains the number of bytes used for internal
-linkage in compiled expressions. The value is 2, 3, or 4. See item 32 above.
-
- PCRE_CONFIG_POSIX_MALLOC_THRESHOLD
-
-The output is an integer that contains the threshold above which the POSIX
-interface uses malloc() for output vectors. See item 31 above.
-
- PCRE_CONFIG_MATCH_LIMIT
-
-The output is an unsigned integer that contains the default limit of the number
-of match() calls in a pcre_exec() execution. See 42 above.
-
-44. pcretest has been upgraded by the addition of the -C option. This causes it
-to extract all the available output from the new pcre_config() function, and to
-output it. The program then exits immediately.
-
-45. A need has arisen to pass over additional data with calls to pcre_exec() in
-order to support additional features. One way would have been to define
-pcre_exec2() (for example) with extra arguments, but this would not have been
-extensible, and would also have required all calls to the original function to
-be mapped to the new one. Instead, I have chosen to extend the mechanism that
-is used for passing in "extra" data from pcre_study().
-
-The pcre_extra structure is now exposed and defined in pcre.h. It currently
-contains the following fields:
-
- flags a bitmap indicating which of the following fields are set
- study_data opaque data from pcre_study()
- match_limit a way of specifying a limit on match() calls for a specific
- call to pcre_exec()
- callout_data data for callouts (see 49 below)
-
-The flag bits are also defined in pcre.h, and are
-
- PCRE_EXTRA_STUDY_DATA
- PCRE_EXTRA_MATCH_LIMIT
- PCRE_EXTRA_CALLOUT_DATA
-
-The pcre_study() function now returns one of these new pcre_extra blocks, with
-the actual study data pointed to by the study_data field, and the
-PCRE_EXTRA_STUDY_DATA flag set. This can be passed directly to pcre_exec() as
-before. That is, this change is entirely upwards-compatible and requires no
-change to existing code.
-
-If you want to pass in additional data to pcre_exec(), you can either place it
-in a pcre_extra block provided by pcre_study(), or create your own pcre_extra
-block.
-
-46. pcretest has been extended to test the PCRE_EXTRA_MATCH_LIMIT feature. If a
-data string contains the escape sequence \M, pcretest calls pcre_exec() several
-times with different match limits, until it finds the minimum value needed for
-pcre_exec() to complete. The value is then output. This can be instructive; for
-most simple matches the number is quite small, but for pathological cases it
-gets very large very quickly.
-
-47. There's a new option for pcre_fullinfo() called PCRE_INFO_STUDYSIZE. It
-returns the size of the data block pointed to by the study_data field in a
-pcre_extra block, that is, the value that was passed as the argument to
-pcre_malloc() when PCRE was getting memory in which to place the information
-created by pcre_study(). The fourth argument should point to a size_t variable.
-pcretest has been extended so that this information is shown after a successful
-pcre_study() call when information about the compiled regex is being displayed.
-
-48. Cosmetic change to Makefile: there's no need to have / after $(DESTDIR)
-because what follows is always an absolute path. (Later: it turns out that this
-is more than cosmetic for MinGW, because it doesn't like empty path
-components.)
-
-49. Some changes have been made to the callout feature (see 28 above):
-
-(i) A callout function now has three choices for what it returns:
-
- 0 => success, carry on matching
- > 0 => failure at this point, but backtrack if possible
- < 0 => serious error, return this value from pcre_exec()
-
- Negative values should normally be chosen from the set of PCRE_ERROR_xxx
- values. In particular, returning PCRE_ERROR_NOMATCH forces a standard
- "match failed" error. The error number PCRE_ERROR_CALLOUT is reserved for
- use by callout functions. It will never be used by PCRE itself.
-
-(ii) The pcre_extra structure (see 45 above) has a void * field called
- callout_data, with corresponding flag bit PCRE_EXTRA_CALLOUT_DATA. The
- pcre_callout_block structure has a field of the same name. The contents of
- the field passed in the pcre_extra structure are passed to the callout
- function in the corresponding field in the callout block. This makes it
- easier to use the same callout-containing regex from multiple threads. For
- testing, the pcretest program has a new data escape
-
- \C*n pass the number n (may be negative) as callout_data
-
- If the callout function in pcretest receives a non-zero value as
- callout_data, it returns that value.
-
-50. Makefile wasn't handling CFLAGS properly when compiling dftables. Also,
-there were some redundant $(CFLAGS) in commands that are now specified as
-$(LINK), which already includes $(CFLAGS).
-
-51. Extensions to UTF-8 support are listed below. These all apply when (a) PCRE
-has been compiled with UTF-8 support *and* pcre_compile() has been compiled
-with the PCRE_UTF8 flag. Patterns that are compiled without that flag assume
-one-byte characters throughout. Note that case-insensitive matching applies
-only to characters whose values are less than 256. PCRE doesn't support the
-notion of cases for higher-valued characters.
-
-(i) A character class whose characters are all within 0-255 is handled as
- a bit map, and the map is inverted for negative classes. Previously, a
- character > 255 always failed to match such a class; however it should
- match if the class was a negative one (e.g. [^ab]). This has been fixed.
-
-(ii) A negated character class with a single character < 255 is coded as
- "not this character" (OP_NOT). This wasn't working properly when the test
- character was multibyte, either singly or repeated.
-
-(iii) Repeats of multibyte characters are now handled correctly in UTF-8
- mode, for example: \x{100}{2,3}.
-
-(iv) The character escapes \b, \B, \d, \D, \s, \S, \w, and \W (either
- singly or repeated) now correctly test multibyte characters. However,
- PCRE doesn't recognize any characters with values greater than 255 as
- digits, spaces, or word characters. Such characters always match \D, \S,
- and \W, and never match \d, \s, or \w.
-
-(v) Classes may now contain characters and character ranges with values
- greater than 255. For example: [ab\x{100}-\x{400}].
-
-(vi) pcregrep now has a --utf-8 option (synonym -u) which makes it call
- PCRE in UTF-8 mode.
-
-52. The info request value PCRE_INFO_FIRSTCHAR has been renamed
-PCRE_INFO_FIRSTBYTE because it is a byte value. However, the old name is
-retained for backwards compatibility. (Note that LASTLITERAL is also a byte
-value.)
-
-53. The single man page has become too large. I have therefore split it up into
-a number of separate man pages. These also give rise to individual HTML pages;
-these are now put in a separate directory, and there is an index.html page that
-lists them all. Some hyperlinking between the pages has been installed.
-
-54. Added convenience functions for handling named capturing parentheses.
-
-55. Unknown escapes inside character classes (e.g. [\M]) and escapes that
-aren't interpreted therein (e.g. [\C]) are literals in Perl. This is now also
-true in PCRE, except when the PCRE_EXTENDED option is set, in which case they
-are faulted.
-
-56. Introduced HOST_CC and HOST_CFLAGS which can be set in the environment when
-calling configure. These values are used when compiling the dftables.c program
-which is run to generate the source of the default character tables. They
-default to the values of CC and CFLAGS. If you are cross-compiling PCRE,
-you will need to set these values.
-
-57. Updated the building process for Windows DLL, as provided by Fred Cox.
-
-
-Version 3.9 02-Jan-02
----------------------
-
-1. A bit of extraneous text had somehow crept into the pcregrep documentation.
-
-2. If --disable-static was given, the building process failed when trying to
-build pcretest and pcregrep. (For some reason it was using libtool to compile
-them, which is not right, as they aren't part of the library.)
-
-
-Version 3.8 18-Dec-01
----------------------
-
-1. The experimental UTF-8 code was completely screwed up. It was packing the
-bytes in the wrong order. How dumb can you get?
-
-
-Version 3.7 29-Oct-01
----------------------
-
-1. In updating pcretest to check change 1 of version 3.6, I screwed up.
-This caused pcretest, when used on the test data, to segfault. Unfortunately,
-this didn't happen under Solaris 8, where I normally test things.
-
-2. The Makefile had to be changed to make it work on BSD systems, where 'make'
-doesn't seem to recognize that ./xxx and xxx are the same file. (This entry
-isn't in ChangeLog distributed with 3.7 because I forgot when I hastily made
-this fix an hour or so after the initial 3.7 release.)
-
-
-Version 3.6 23-Oct-01
----------------------
-
-1. Crashed with /(sens|respons)e and \1ibility/ and "sense and sensibility" if
-offsets passed as NULL with zero offset count.
-
-2. The config.guess and config.sub files had not been updated when I moved to
-the latest autoconf.
-
-
-Version 3.5 15-Aug-01
----------------------
-
-1. Added some missing #if !defined NOPOSIX conditionals in pcretest.c that
-had been forgotten.
-
-2. By using declared but undefined structures, we can avoid using "void"
-definitions in pcre.h while keeping the internal definitions of the structures
-private.
-
-3. The distribution is now built using autoconf 2.50 and libtool 1.4. From a
-user point of view, this means that both static and shared libraries are built
-by default, but this can be individually controlled. More of the work of
-handling this static/shared cases is now inside libtool instead of PCRE's make
-file.
-
-4. The pcretest utility is now installed along with pcregrep because it is
-useful for users (to test regexs) and by doing this, it automatically gets
-relinked by libtool. The documentation has been turned into a man page, so
-there are now .1, .txt, and .html versions in /doc.
-
-5. Upgrades to pcregrep:
- (i) Added long-form option names like gnu grep.
- (ii) Added --help to list all options with an explanatory phrase.
- (iii) Added -r, --recursive to recurse into sub-directories.
- (iv) Added -f, --file to read patterns from a file.
-
-6. pcre_exec() was referring to its "code" argument before testing that
-argument for NULL (and giving an error if it was NULL).
-
-7. Upgraded Makefile.in to allow for compiling in a different directory from
-the source directory.
-
-8. Tiny buglet in pcretest: when pcre_fullinfo() was called to retrieve the
-options bits, the pointer it was passed was to an int instead of to an unsigned
-long int. This mattered only on 64-bit systems.
-
-9. Fixed typo (3.4/1) in pcre.h again. Sigh. I had changed pcre.h (which is
-generated) instead of pcre.in, which it its source. Also made the same change
-in several of the .c files.
-
-10. A new release of gcc defines printf() as a macro, which broke pcretest
-because it had an ifdef in the middle of a string argument for printf(). Fixed
-by using separate calls to printf().
-
-11. Added --enable-newline-is-cr and --enable-newline-is-lf to the configure
-script, to force use of CR or LF instead of \n in the source. On non-Unix
-systems, the value can be set in config.h.
-
-12. The limit of 200 on non-capturing parentheses is a _nesting_ limit, not an
-absolute limit. Changed the text of the error message to make this clear, and
-likewise updated the man page.
-
-13. The limit of 99 on the number of capturing subpatterns has been removed.
-The new limit is 65535, which I hope will not be a "real" limit.
-
-
-Version 3.4 22-Aug-00
----------------------
-
-1. Fixed typo in pcre.h: unsigned const char * changed to const unsigned char *.
-
-2. Diagnose condition (?(0) as an error instead of crashing on matching.
-
-
-Version 3.3 01-Aug-00
----------------------
-
-1. If an octal character was given, but the value was greater than \377, it
-was not getting masked to the least significant bits, as documented. This could
-lead to crashes in some systems.
-
-2. Perl 5.6 (if not earlier versions) accepts classes like [a-\d] and treats
-the hyphen as a literal. PCRE used to give an error; it now behaves like Perl.
-
-3. Added the functions pcre_free_substring() and pcre_free_substring_list().
-These just pass their arguments on to (pcre_free)(), but they are provided
-because some uses of PCRE bind it to non-C systems that can call its functions,
-but cannot call free() or pcre_free() directly.
-
-4. Add "make test" as a synonym for "make check". Corrected some comments in
-the Makefile.
-
-5. Add $(DESTDIR)/ in front of all the paths in the "install" target in the
-Makefile.
-
-6. Changed the name of pgrep to pcregrep, because Solaris has introduced a
-command called pgrep for grepping around the active processes.
-
-7. Added the beginnings of support for UTF-8 character strings.
-
-8. Arranged for the Makefile to pass over the settings of CC, CFLAGS, and
-RANLIB to ./ltconfig so that they are used by libtool. I think these are all
-the relevant ones. (AR is not passed because ./ltconfig does its own figuring
-out for the ar command.)
-
-
-Version 3.2 12-May-00
----------------------
-
-This is purely a bug fixing release.
-
-1. If the pattern /((Z)+|A)*/ was matched agained ZABCDEFG it matched Z instead
-of ZA. This was just one example of several cases that could provoke this bug,
-which was introduced by change 9 of version 2.00. The code for breaking
-infinite loops after an iteration that matches an empty string was't working
-correctly.
-
-2. The pcretest program was not imitating Perl correctly for the pattern /a*/g
-when matched against abbab (for example). After matching an empty string, it
-wasn't forcing anchoring when setting PCRE_NOTEMPTY for the next attempt; this
-caused it to match further down the string than it should.
-
-3. The code contained an inclusion of sys/types.h. It isn't clear why this
-was there because it doesn't seem to be needed, and it causes trouble on some
-systems, as it is not a Standard C header. It has been removed.
-
-4. Made 4 silly changes to the source to avoid stupid compiler warnings that
-were reported on the Macintosh. The changes were from
-
- while ((c = *(++ptr)) != 0 && c != '\n');
-to
- while ((c = *(++ptr)) != 0 && c != '\n') ;
-
-Totally extraordinary, but if that's what it takes...
-
-5. PCRE is being used in one environment where neither memmove() nor bcopy() is
-available. Added HAVE_BCOPY and an autoconf test for it; if neither
-HAVE_MEMMOVE nor HAVE_BCOPY is set, use a built-in emulation function which
-assumes the way PCRE uses memmove() (always moving upwards).
-
-6. PCRE is being used in one environment where strchr() is not available. There
-was only one use in pcre.c, and writing it out to avoid strchr() probably gives
-faster code anyway.
-
-
-Version 3.1 09-Feb-00
----------------------
-
-The only change in this release is the fixing of some bugs in Makefile.in for
-the "install" target:
-
-(1) It was failing to install pcreposix.h.
-
-(2) It was overwriting the pcre.3 man page with the pcreposix.3 man page.
-
-
-Version 3.0 01-Feb-00
----------------------
-
-1. Add support for the /+ modifier to perltest (to output $` like it does in
-pcretest).
-
-2. Add support for the /g modifier to perltest.
-
-3. Fix pcretest so that it behaves even more like Perl for /g when the pattern
-matches null strings.
-
-4. Fix perltest so that it doesn't do unwanted things when fed an empty
-pattern. Perl treats empty patterns specially - it reuses the most recent
-pattern, which is not what we want. Replace // by /(?#)/ in order to avoid this
-effect.
-
-5. The POSIX interface was broken in that it was just handing over the POSIX
-captured string vector to pcre_exec(), but (since release 2.00) PCRE has
-required a bigger vector, with some working space on the end. This means that
-the POSIX wrapper now has to get and free some memory, and copy the results.
-
-6. Added some simple autoconf support, placing the test data and the
-documentation in separate directories, re-organizing some of the
-information files, and making it build pcre-config (a GNU standard). Also added
-libtool support for building PCRE as a shared library, which is now the
-default.
-
-7. Got rid of the leading zero in the definition of PCRE_MINOR because 08 and
-09 are not valid octal constants. Single digits will be used for minor values
-less than 10.
-
-8. Defined REG_EXTENDED and REG_NOSUB as zero in the POSIX header, so that
-existing programs that set these in the POSIX interface can use PCRE without
-modification.
-
-9. Added a new function, pcre_fullinfo() with an extensible interface. It can
-return all that pcre_info() returns, plus additional data. The pcre_info()
-function is retained for compatibility, but is considered to be obsolete.
-
-10. Added experimental recursion feature (?R) to handle one common case that
-Perl 5.6 will be able to do with (?p{...}).
-
-11. Added support for POSIX character classes like [:alpha:], which Perl is
-adopting.
-
-
-Version 2.08 31-Aug-99
-----------------------
-
-1. When startoffset was not zero and the pattern began with ".*", PCRE was not
-trying to match at the startoffset position, but instead was moving forward to
-the next newline as if a previous match had failed.
-
-2. pcretest was not making use of PCRE_NOTEMPTY when repeating for /g and /G,
-and could get into a loop if a null string was matched other than at the start
-of the subject.
-
-3. Added definitions of PCRE_MAJOR and PCRE_MINOR to pcre.h so the version can
-be distinguished at compile time, and for completeness also added PCRE_DATE.
-
-5. Added Paul Sokolovsky's minor changes to make it easy to compile a Win32 DLL
-in GnuWin32 environments.
-
-
-Version 2.07 29-Jul-99
-----------------------
-
-1. The documentation is now supplied in plain text form and HTML as well as in
-the form of man page sources.
-
-2. C++ compilers don't like assigning (void *) values to other pointer types.
-In particular this affects malloc(). Although there is no problem in Standard
-C, I've put in casts to keep C++ compilers happy.
-
-3. Typo on pcretest.c; a cast of (unsigned char *) in the POSIX regexec() call
-should be (const char *).
-
-4. If NOPOSIX is defined, pcretest.c compiles without POSIX support. This may
-be useful for non-Unix systems who don't want to bother with the POSIX stuff.
-However, I haven't made this a standard facility. The documentation doesn't
-mention it, and the Makefile doesn't support it.
-
-5. The Makefile now contains an "install" target, with editable destinations at
-the top of the file. The pcretest program is not installed.
-
-6. pgrep -V now gives the PCRE version number and date.
-
-7. Fixed bug: a zero repetition after a literal string (e.g. /abcde{0}/) was
-causing the entire string to be ignored, instead of just the last character.
-
-8. If a pattern like /"([^\\"]+|\\.)*"/ is applied in the normal way to a
-non-matching string, it can take a very, very long time, even for strings of
-quite modest length, because of the nested recursion. PCRE now does better in
-some of these cases. It does this by remembering the last required literal
-character in the pattern, and pre-searching the subject to ensure it is present
-before running the real match. In other words, it applies a heuristic to detect
-some types of certain failure quickly, and in the above example, if presented
-with a string that has no trailing " it gives "no match" very quickly.
-
-9. A new runtime option PCRE_NOTEMPTY causes null string matches to be ignored;
-other alternatives are tried instead.
-
-
-Version 2.06 09-Jun-99
-----------------------
-
-1. Change pcretest's output for amount of store used to show just the code
-space, because the remainder (the data block) varies in size between 32-bit and
-64-bit systems.
-
-2. Added an extra argument to pcre_exec() to supply an offset in the subject to
-start matching at. This allows lookbehinds to work when searching for multiple
-occurrences in a string.
-
-3. Added additional options to pcretest for testing multiple occurrences:
-
- /+ outputs the rest of the string that follows a match
- /g loops for multiple occurrences, using the new startoffset argument
- /G loops for multiple occurrences by passing an incremented pointer
-
-4. PCRE wasn't doing the "first character" optimization for patterns starting
-with \b or \B, though it was doing it for other lookbehind assertions. That is,
-it wasn't noticing that a match for a pattern such as /\bxyz/ has to start with
-the letter 'x'. On long subject strings, this gives a significant speed-up.
-
-
-Version 2.05 21-Apr-99
-----------------------
-
-1. Changed the type of magic_number from int to long int so that it works
-properly on 16-bit systems.
-
-2. Fixed a bug which caused patterns starting with .* not to work correctly
-when the subject string contained newline characters. PCRE was assuming
-anchoring for such patterns in all cases, which is not correct because .* will
-not pass a newline unless PCRE_DOTALL is set. It now assumes anchoring only if
-DOTALL is set at top level; otherwise it knows that patterns starting with .*
-must be retried after every newline in the subject.
-
-
-Version 2.04 18-Feb-99
-----------------------
-
-1. For parenthesized subpatterns with repeats whose minimum was zero, the
-computation of the store needed to hold the pattern was incorrect (too large).
-If such patterns were nested a few deep, this could multiply and become a real
-problem.
-
-2. Added /M option to pcretest to show the memory requirement of a specific
-pattern. Made -m a synonym of -s (which does this globally) for compatibility.
-
-3. Subpatterns of the form (regex){n,m} (i.e. limited maximum) were being
-compiled in such a way that the backtracking after subsequent failure was
-pessimal. Something like (a){0,3} was compiled as (a)?(a)?(a)? instead of
-((a)((a)(a)?)?)? with disastrous performance if the maximum was of any size.
-
-
-Version 2.03 02-Feb-99
-----------------------
-
-1. Fixed typo and small mistake in man page.
-
-2. Added 4th condition (GPL supersedes if conflict) and created separate
-LICENCE file containing the conditions.
-
-3. Updated pcretest so that patterns such as /abc\/def/ work like they do in
-Perl, that is the internal \ allows the delimiter to be included in the
-pattern. Locked out the use of \ as a delimiter. If \ immediately follows
-the final delimiter, add \ to the end of the pattern (to test the error).
-
-4. Added the convenience functions for extracting substrings after a successful
-match. Updated pcretest to make it able to test these functions.
-
-
-Version 2.02 14-Jan-99
-----------------------
-
-1. Initialized the working variables associated with each extraction so that
-their saving and restoring doesn't refer to uninitialized store.
-
-2. Put dummy code into study.c in order to trick the optimizer of the IBM C
-compiler for OS/2 into generating correct code. Apparently IBM isn't going to
-fix the problem.
-
-3. Pcretest: the timing code wasn't using LOOPREPEAT for timing execution
-calls, and wasn't printing the correct value for compiling calls. Increased the
-default value of LOOPREPEAT, and the number of significant figures in the
-times.
-
-4. Changed "/bin/rm" in the Makefile to "-rm" so it works on Windows NT.
-
-5. Renamed "deftables" as "dftables" to get it down to 8 characters, to avoid
-a building problem on Windows NT with a FAT file system.
-
-
-Version 2.01 21-Oct-98
-----------------------
-
-1. Changed the API for pcre_compile() to allow for the provision of a pointer
-to character tables built by pcre_maketables() in the current locale. If NULL
-is passed, the default tables are used.
-
-
-Version 2.00 24-Sep-98
-----------------------
-
-1. Since the (>?) facility is in Perl 5.005, don't require PCRE_EXTRA to enable
-it any more.
-
-2. Allow quantification of (?>) groups, and make it work correctly.
-
-3. The first character computation wasn't working for (?>) groups.
-
-4. Correct the implementation of \Z (it is permitted to match on the \n at the
-end of the subject) and add 5.005's \z, which really does match only at the
-very end of the subject.
-
-5. Remove the \X "cut" facility; Perl doesn't have it, and (?> is neater.
-
-6. Remove the ability to specify CASELESS, MULTILINE, DOTALL, and
-DOLLAR_END_ONLY at runtime, to make it possible to implement the Perl 5.005
-localized options. All options to pcre_study() were also removed.
-
-7. Add other new features from 5.005:
-
- $(?<= positive lookbehind
- $(?<! negative lookbehind
- (?imsx-imsx) added the unsetting capability
- such a setting is global if at outer level; local otherwise
- (?imsx-imsx:) non-capturing groups with option setting
- (?(cond)re|re) conditional pattern matching
-
- A backreference to itself in a repeated group matches the previous
- captured string.
-
-8. General tidying up of studying (both automatic and via "study")
-consequential on the addition of new assertions.
-
-9. As in 5.005, unlimited repeated groups that could match an empty substring
-are no longer faulted at compile time. Instead, the loop is forcibly broken at
-runtime if any iteration does actually match an empty substring.
-
-10. Include the RunTest script in the distribution.
-
-11. Added tests from the Perl 5.005_02 distribution. This showed up a few
-discrepancies, some of which were old and were also with respect to 5.004. They
-have now been fixed.
-
-
-Version 1.09 28-Apr-98
-----------------------
-
-1. A negated single character class followed by a quantifier with a minimum
-value of one (e.g. [^x]{1,6} ) was not compiled correctly. This could lead to
-program crashes, or just wrong answers. This did not apply to negated classes
-containing more than one character, or to minima other than one.
-
-
-Version 1.08 27-Mar-98
-----------------------
-
-1. Add PCRE_UNGREEDY to invert the greediness of quantifiers.
-
-2. Add (?U) and (?X) to set PCRE_UNGREEDY and PCRE_EXTRA respectively. The
-latter must appear before anything that relies on it in the pattern.
-
-
-Version 1.07 16-Feb-98
-----------------------
-
-1. A pattern such as /((a)*)*/ was not being diagnosed as in error (unlimited
-repeat of a potentially empty string).
-
-
-Version 1.06 23-Jan-98
-----------------------
-
-1. Added Markus Oberhumer's little patches for C++.
-
-2. Literal strings longer than 255 characters were broken.
-
-
-Version 1.05 23-Dec-97
-----------------------
-
-1. Negated character classes containing more than one character were failing if
-PCRE_CASELESS was set at run time.
-
-
-Version 1.04 19-Dec-97
-----------------------
-
-1. Corrected the man page, where some "const" qualifiers had been omitted.
-
-2. Made debugging output print "{0,xxx}" instead of just "{,xxx}" to agree with
-input syntax.
-
-3. Fixed memory leak which occurred when a regex with back references was
-matched with an offsets vector that wasn't big enough. The temporary memory
-that is used in this case wasn't being freed if the match failed.
-
-4. Tidied pcretest to ensure it frees memory that it gets.
-
-5. Temporary memory was being obtained in the case where the passed offsets
-vector was exactly big enough.
-
-6. Corrected definition of offsetof() from change 5 below.
-
-7. I had screwed up change 6 below and broken the rules for the use of
-setjmp(). Now fixed.
-
-
-Version 1.03 18-Dec-97
-----------------------
-
-1. A erroneous regex with a missing opening parenthesis was correctly
-diagnosed, but PCRE attempted to access brastack[-1], which could cause crashes
-on some systems.
-
-2. Replaced offsetof(real_pcre, code) by offsetof(real_pcre, code[0]) because
-it was reported that one broken compiler failed on the former because "code" is
-also an independent variable.
-
-3. The erroneous regex a[]b caused an array overrun reference.
-
-4. A regex ending with a one-character negative class (e.g. /[^k]$/) did not
-fail on data ending with that character. (It was going on too far, and checking
-the next character, typically a binary zero.) This was specific to the
-optimized code for single-character negative classes.
-
-5. Added a contributed patch from the TIN world which does the following:
-
- + Add an undef for memmove, in case the the system defines a macro for it.
-
- + Add a definition of offsetof(), in case there isn't one. (I don't know
- the reason behind this - offsetof() is part of the ANSI standard - but
- it does no harm).
-
- + Reduce the ifdef's in pcre.c using macro DPRINTF, thereby eliminating
- most of the places where whitespace preceded '#'. I have given up and
- allowed the remaining 2 cases to be at the margin.
-
- + Rename some variables in pcre to eliminate shadowing. This seems very
- pedantic, but does no harm, of course.
-
-6. Moved the call to setjmp() into its own function, to get rid of warnings
-from gcc -Wall, and avoided calling it at all unless PCRE_EXTRA is used.
-
-7. Constructs such as \d{8,} were compiling into the equivalent of
-\d{8}\d{0,65527} instead of \d{8}\d* which didn't make much difference to the
-outcome, but in this particular case used more store than had been allocated,
-which caused the bug to be discovered because it threw up an internal error.
-
-8. The debugging code in both pcre and pcretest for outputting the compiled
-form of a regex was going wrong in the case of back references followed by
-curly-bracketed repeats.
-
-
-Version 1.02 12-Dec-97
-----------------------
-
-1. Typos in pcre.3 and comments in the source fixed.
-
-2. Applied a contributed patch to get rid of places where it used to remove
-'const' from variables, and fixed some signed/unsigned and uninitialized
-variable warnings.
-
-3. Added the "runtest" target to Makefile.
-
-4. Set default compiler flag to -O2 rather than just -O.
-
-
-Version 1.01 19-Nov-97
-----------------------
-
-1. PCRE was failing to diagnose unlimited repeat of empty string for patterns
-like /([ab]*)*/, that is, for classes with more than one character in them.
-
-2. Likewise, it wasn't diagnosing patterns with "once-only" subpatterns, such
-as /((?>a*))*/ (a PCRE_EXTRA facility).
-
-
-Version 1.00 18-Nov-97
-----------------------
-
-1. Added compile-time macros to support systems such as SunOS4 which don't have
-memmove() or strerror() but have other things that can be used instead.
-
-2. Arranged that "make clean" removes the executables.
-
-
-Version 0.99 27-Oct-97
-----------------------
-
-1. Fixed bug in code for optimizing classes with only one character. It was
-initializing a 32-byte map regardless, which could cause it to run off the end
-of the memory it had got.
-
-2. Added, conditional on PCRE_EXTRA, the proposed (?>REGEX) construction.
-
-
-Version 0.98 22-Oct-97
-----------------------
-
-1. Fixed bug in code for handling temporary memory usage when there are more
-back references than supplied space in the ovector. This could cause segfaults.
-
-
-Version 0.97 21-Oct-97
-----------------------
-
-1. Added the \X "cut" facility, conditional on PCRE_EXTRA.
-
-2. Optimized negated single characters not to use a bit map.
-
-3. Brought error texts together as macro definitions; clarified some of them;
-fixed one that was wrong - it said "range out of order" when it meant "invalid
-escape sequence".
-
-4. Changed some char * arguments to const char *.
-
-5. Added PCRE_NOTBOL and PCRE_NOTEOL (from POSIX).
-
-6. Added the POSIX-style API wrapper in pcreposix.a and testing facilities in
-pcretest.
-
-
-Version 0.96 16-Oct-97
-----------------------
-
-1. Added a simple "pgrep" utility to the distribution.
-
-2. Fixed an incompatibility with Perl: "{" is now treated as a normal character
-unless it appears in one of the precise forms "{ddd}", "{ddd,}", or "{ddd,ddd}"
-where "ddd" means "one or more decimal digits".
-
-3. Fixed serious bug. If a pattern had a back reference, but the call to
-pcre_exec() didn't supply a large enough ovector to record the related
-identifying subpattern, the match always failed. PCRE now remembers the number
-of the largest back reference, and gets some temporary memory in which to save
-the offsets during matching if necessary, in order to ensure that
-backreferences always work.
-
-4. Increased the compatibility with Perl in a number of ways:
-
- (a) . no longer matches \n by default; an option PCRE_DOTALL is provided
- to request this handling. The option can be set at compile or exec time.
-
- (b) $ matches before a terminating newline by default; an option
- PCRE_DOLLAR_ENDONLY is provided to override this (but not in multiline
- mode). The option can be set at compile or exec time.
-
- (c) The handling of \ followed by a digit other than 0 is now supposed to be
- the same as Perl's. If the decimal number it represents is less than 10
- or there aren't that many previous left capturing parentheses, an octal
- escape is read. Inside a character class, it's always an octal escape,
- even if it is a single digit.
-
- (d) An escaped but undefined alphabetic character is taken as a literal,
- unless PCRE_EXTRA is set. Currently this just reserves the remaining
- escapes.
-
- (e) {0} is now permitted. (The previous item is removed from the compiled
- pattern).
-
-5. Changed all the names of code files so that the basic parts are no longer
-than 10 characters, and abolished the teeny "globals.c" file.
-
-6. Changed the handling of character classes; they are now done with a 32-byte
-bit map always.
-
-7. Added the -d and /D options to pcretest to make it possible to look at the
-internals of compilation without having to recompile pcre.
-
-
-Version 0.95 23-Sep-97
-----------------------
-
-1. Fixed bug in pre-pass concerning escaped "normal" characters such as \x5c or
-\x20 at the start of a run of normal characters. These were being treated as
-real characters, instead of the source characters being re-checked.
-
-
-Version 0.94 18-Sep-97
-----------------------
-
-1. The functions are now thread-safe, with the caveat that the global variables
-containing pointers to malloc() and free() or alternative functions are the
-same for all threads.
-
-2. Get pcre_study() to generate a bitmap of initial characters for non-
-anchored patterns when this is possible, and use it if passed to pcre_exec().
-
-
-Version 0.93 15-Sep-97
-----------------------
-
-1. /(b)|(:+)/ was computing an incorrect first character.
-
-2. Add pcre_study() to the API and the passing of pcre_extra to pcre_exec(),
-but not actually doing anything yet.
-
-3. Treat "-" characters in classes that cannot be part of ranges as literals,
-as Perl does (e.g. [-az] or [az-]).
-
-4. Set the anchored flag if a branch starts with .* or .*? because that tests
-all possible positions.
-
-5. Split up into different modules to avoid including unneeded functions in a
-compiled binary. However, compile and exec are still in one module. The "study"
-function is split off.
-
-6. The character tables are now in a separate module whose source is generated
-by an auxiliary program - but can then be edited by hand if required. There are
-now no calls to isalnum(), isspace(), isdigit(), isxdigit(), tolower() or
-toupper() in the code.
-
-7. Turn the malloc/free funtions variables into pcre_malloc and pcre_free and
-make them global. Abolish the function for setting them, as the caller can now
-set them directly.
-
-
-Version 0.92 11-Sep-97
-----------------------
-
-1. A repeat with a fixed maximum and a minimum of 1 for an ordinary character
-(e.g. /a{1,3}/) was broken (I mis-optimized it).
-
-2. Caseless matching was not working in character classes if the characters in
-the pattern were in upper case.
-
-3. Make ranges like [W-c] work in the same way as Perl for caseless matching.
-
-4. Make PCRE_ANCHORED public and accept as a compile option.
-
-5. Add an options word to pcre_exec() and accept PCRE_ANCHORED and
-PCRE_CASELESS at run time. Add escapes \A and \I to pcretest to cause it to
-pass them.
-
-6. Give an error if bad option bits passed at compile or run time.
-
-7. Add PCRE_MULTILINE at compile and exec time, and (?m) as well. Add \M to
-pcretest to cause it to pass that flag.
-
-8. Add pcre_info(), to get the number of identifying subpatterns, the stored
-options, and the first character, if set.
-
-9. Recognize C+ or C{n,m} where n >= 1 as providing a fixed starting character.
-
-
-Version 0.91 10-Sep-97
-----------------------
-
-1. PCRE was failing to diagnose unlimited repeats of subpatterns that could
-match the empty string as in /(a*)*/. It was looping and ultimately crashing.
-
-2. PCRE was looping on encountering an indefinitely repeated back reference to
-a subpattern that had matched an empty string, e.g. /(a|)\1*/. It now does what
-Perl does - treats the match as successful.
-
-****
diff --git a/crawl-ref/source/util/pcre/CleanTxt b/crawl-ref/source/util/pcre/CleanTxt
deleted file mode 100644
index 1f42519c8d..0000000000
--- a/crawl-ref/source/util/pcre/CleanTxt
+++ /dev/null
@@ -1,113 +0,0 @@
-#! /usr/bin/perl -w
-
-# Script to take the output of nroff -man and remove all the backspacing and
-# the page footers and the screen commands etc so that it is more usefully
-# readable online. In fact, in the latest nroff, intermediate footers don't
-# seem to be generated any more.
-
-$blankcount = 0;
-$lastwascut = 0;
-$firstheader = 1;
-
-# Input on STDIN; output to STDOUT.
-
-while (<STDIN>)
- {
- s/\x1b\[\d+m//g; # Remove screen controls "ESC [ number m"
- s/.\x8//g; # Remove "char, backspace"
-
- # Handle header lines. Retain only the first one we encounter, but remove
- # the blank line that follows. Any others (e.g. at end of document) and the
- # following blank line are dropped.
-
- if (/^PCRE(\w*)\(([13])\)\s+PCRE\1\(\2\)$/)
- {
- if ($firstheader)
- {
- $firstheader = 0;
- print;
- $lastprinted = $_;
- $lastwascut = 0;
- }
- $_=<STDIN>; # Remove a blank that follows
- next;
- }
-
- # Count runs of empty lines
-
- if (/^\s*$/)
- {
- $blankcount++;
- $lastwascut = 0;
- next;
- }
-
- # If a chunk of lines has been cut out (page footer) and the next line
- # has a different indentation, put back one blank line.
-
- if ($lastwascut && $blankcount < 1 && defined($lastprinted))
- {
- ($a) = $lastprinted =~ /^(\s*)/;
- ($b) = $_ =~ /^(\s*)/;
- $blankcount++ if ($a ne $b);
- }
-
- # We get here only when we have a non-blank line in hand. If it was preceded
- # by 3 or more blank lines, read the next 3 lines and see if they are blank.
- # If so, remove all 7 lines, and remember that we have just done a cut.
-
- if ($blankcount >= 3)
- {
- for ($i = 0; $i < 3; $i++)
- {
- $next[$i] = <STDIN>;
- $next[$i] = "" if !defined $next[$i];
- $next[$i] =~ s/\x1b\[\d+m//g; # Remove screen controls "ESC [ number m"
- $next[$i] =~ s/.\x8//g; # Remove "char, backspace"
- }
-
- # Cut out chunks of the form <3 blanks><non-blank><3 blanks>
-
- if ($next[0] =~ /^\s*$/ &&
- $next[1] =~ /^\s*$/ &&
- $next[2] =~ /^\s*$/)
- {
- $blankcount -= 3;
- $lastwascut = 1;
- }
-
- # Otherwise output the saved blanks, the current, and the next three
- # lines. Remember the last printed line.
-
- else
- {
- for ($i = 0; $i < $blankcount; $i++) { print "\n"; }
- print;
- for ($i = 0; $i < 3; $i++)
- {
- $next[$i] =~ s/.\x8//g;
- print $next[$i];
- $lastprinted = $_;
- }
- $lastwascut = 0;
- $blankcount = 0;
- }
- }
-
- # This non-blank line is not preceded by 3 or more blank lines. Output
- # any blanks there are, and the line. Remember it. Force two blank lines
- # before headings.
-
- else
- {
- $blankcount = 2 if /^\S/ && !/^Last updated/ && !/^Copyright/ &&
- defined($lastprinted);
- for ($i = 0; $i < $blankcount; $i++) { print "\n"; }
- print;
- $lastprinted = $_;
- $lastwascut = 0;
- $blankcount = 0;
- }
- }
-
-# End
diff --git a/crawl-ref/source/util/pcre/Detrail b/crawl-ref/source/util/pcre/Detrail
deleted file mode 100644
index 1c5c7e9cae..0000000000
--- a/crawl-ref/source/util/pcre/Detrail
+++ /dev/null
@@ -1,35 +0,0 @@
-#!/usr/bin/perl
-
-# This is a script for removing trailing whitespace from lines in files that
-# are listed on the command line.
-
-# This subroutine does the work for one file.
-
-sub detrail {
-my($file) = $_[0];
-my($changed) = 0;
-open(IN, "$file") || die "Can't open $file for input";
-@lines = <IN>;
-close(IN);
-foreach (@lines)
- {
- if (/\s+\n$/)
- {
- s/\s+\n$/\n/;
- $changed = 1;
- }
- }
-if ($changed)
- {
- open(OUT, ">$file") || die "Can't open $file for output";
- print OUT @lines;
- close(OUT);
- }
-}
-
-# This is the main program
-
-$, = ""; # Output field separator
-for ($i = 0; $i < @ARGV; $i++) { &detrail($ARGV[$i]); }
-
-# End
diff --git a/crawl-ref/source/util/pcre/HACKING b/crawl-ref/source/util/pcre/HACKING
deleted file mode 100644
index 1f30d4c487..0000000000
--- a/crawl-ref/source/util/pcre/HACKING
+++ /dev/null
@@ -1,418 +0,0 @@
-Technical Notes about PCRE
---------------------------
-
-These are very rough technical notes that record potentially useful information
-about PCRE internals.
-
-Historical note 1
------------------
-
-Many years ago I implemented some regular expression functions to an algorithm
-suggested by Martin Richards. These were not Unix-like in form, and were quite
-restricted in what they could do by comparison with Perl. The interesting part
-about the algorithm was that the amount of space required to hold the compiled
-form of an expression was known in advance. The code to apply an expression did
-not operate by backtracking, as the original Henry Spencer code and current
-Perl code does, but instead checked all possibilities simultaneously by keeping
-a list of current states and checking all of them as it advanced through the
-subject string. In the terminology of Jeffrey Friedl's book, it was a "DFA
-algorithm", though it was not a traditional Finite State Machine (FSM). When
-the pattern was all used up, all remaining states were possible matches, and
-the one matching the longest subset of the subject string was chosen. This did
-not necessarily maximize the individual wild portions of the pattern, as is
-expected in Unix and Perl-style regular expressions.
-
-Historical note 2
------------------
-
-By contrast, the code originally written by Henry Spencer (which was
-subsequently heavily modified for Perl) compiles the expression twice: once in
-a dummy mode in order to find out how much store will be needed, and then for
-real. (The Perl version probably doesn't do this any more; I'm talking about
-the original library.) The execution function operates by backtracking and
-maximizing (or, optionally, minimizing in Perl) the amount of the subject that
-matches individual wild portions of the pattern. This is an "NFA algorithm" in
-Friedl's terminology.
-
-OK, here's the real stuff
--------------------------
-
-For the set of functions that form the "basic" PCRE library (which are
-unrelated to those mentioned above), I tried at first to invent an algorithm
-that used an amount of store bounded by a multiple of the number of characters
-in the pattern, to save on compiling time. However, because of the greater
-complexity in Perl regular expressions, I couldn't do this. In any case, a
-first pass through the pattern is helpful for other reasons.
-
-Computing the memory requirement: how it was
---------------------------------------------
-
-Up to and including release 6.7, PCRE worked by running a very degenerate first
-pass to calculate a maximum store size, and then a second pass to do the real
-compile - which might use a bit less than the predicted amount of memory. The
-idea was that this would turn out faster than the Henry Spencer code because
-the first pass is degenerate and the second pass can just store stuff straight
-into the vector, which it knows is big enough.
-
-Computing the memory requirement: how it is
--------------------------------------------
-
-By the time I was working on a potential 6.8 release, the degenerate first pass
-had become very complicated and hard to maintain. Indeed one of the early
-things I did for 6.8 was to fix Yet Another Bug in the memory computation. Then
-I had a flash of inspiration as to how I could run the real compile function in
-a "fake" mode that enables it to compute how much memory it would need, while
-actually only ever using a few hundred bytes of working memory, and without too
-many tests of the mode that might slow it down. So I re-factored the compiling
-functions to work this way. This got rid of about 600 lines of source. It
-should make future maintenance and development easier. As this was such a major
-change, I never released 6.8, instead upping the number to 7.0 (other quite
-major changes are also present in the 7.0 release).
-
-A side effect of this work is that the previous limit of 200 on the nesting
-depth of parentheses was removed. However, there is a downside: pcre_compile()
-runs more slowly than before (30% or more, depending on the pattern) because it
-is doing a full analysis of the pattern. My hope is that this is not a big
-issue.
-
-Traditional matching function
------------------------------
-
-The "traditional", and original, matching function is called pcre_exec(), and
-it implements an NFA algorithm, similar to the original Henry Spencer algorithm
-and the way that Perl works. Not surprising, since it is intended to be as
-compatible with Perl as possible. This is the function most users of PCRE will
-use most of the time.
-
-Supplementary matching function
--------------------------------
-
-From PCRE 6.0, there is also a supplementary matching function called
-pcre_dfa_exec(). This implements a DFA matching algorithm that searches
-simultaneously for all possible matches that start at one point in the subject
-string. (Going back to my roots: see Historical Note 1 above.) This function
-intreprets the same compiled pattern data as pcre_exec(); however, not all the
-facilities are available, and those that are do not always work in quite the
-same way. See the user documentation for details.
-
-The algorithm that is used for pcre_dfa_exec() is not a traditional FSM,
-because it may have a number of states active at one time. More work would be
-needed at compile time to produce a traditional FSM where only one state is
-ever active at once. I believe some other regex matchers work this way.
-
-
-Format of compiled patterns
----------------------------
-
-The compiled form of a pattern is a vector of bytes, containing items of
-variable length. The first byte in an item is an opcode, and the length of the
-item is either implicit in the opcode or contained in the data bytes that
-follow it.
-
-In many cases below LINK_SIZE data values are specified for offsets within the
-compiled pattern. The default value for LINK_SIZE is 2, but PCRE can be
-compiled to use 3-byte or 4-byte values for these offsets (impairing the
-performance). This is necessary only when patterns whose compiled length is
-greater than 64K are going to be processed. In this description, we assume the
-"normal" compilation options. Data values that are counts (e.g. for
-quantifiers) are always just two bytes long.
-
-A list of the opcodes follows:
-
-Opcodes with no following data
-------------------------------
-
-These items are all just one byte long
-
- OP_END end of pattern
- OP_ANY match any one character other than newline
- OP_ALLANY match any one character, including newline
- OP_ANYBYTE match any single byte, even in UTF-8 mode
- OP_SOD match start of data: \A
- OP_SOM, start of match (subject + offset): \G
- OP_SET_SOM, set start of match (\K)
- OP_CIRC ^ (start of data, or after \n in multiline)
- OP_NOT_WORD_BOUNDARY \W
- OP_WORD_BOUNDARY \w
- OP_NOT_DIGIT \D
- OP_DIGIT \d
- OP_NOT_HSPACE \H
- OP_HSPACE \h
- OP_NOT_WHITESPACE \S
- OP_WHITESPACE \s
- OP_NOT_VSPACE \V
- OP_VSPACE \v
- OP_NOT_WORDCHAR \W
- OP_WORDCHAR \w
- OP_EODN match end of data or \n at end: \Z
- OP_EOD match end of data: \z
- OP_DOLL $ (end of data, or before \n in multiline)
- OP_EXTUNI match an extended Unicode character
- OP_ANYNL match any Unicode newline sequence
-
- OP_ACCEPT )
- OP_COMMIT )
- OP_FAIL ) These are Perl 5.10's "backtracking
- OP_PRUNE ) control verbs".
- OP_SKIP )
- OP_THEN )
-
-
-Repeating single characters
----------------------------
-
-The common repeats (*, +, ?) when applied to a single character use the
-following opcodes:
-
- OP_STAR
- OP_MINSTAR
- OP_POSSTAR
- OP_PLUS
- OP_MINPLUS
- OP_POSPLUS
- OP_QUERY
- OP_MINQUERY
- OP_POSQUERY
-
-In ASCII mode, these are two-byte items; in UTF-8 mode, the length is variable.
-Those with "MIN" in their name are the minimizing versions. Those with "POS" in
-their names are possessive versions. Each is followed by the character that is
-to be repeated. Other repeats make use of
-
- OP_UPTO
- OP_MINUPTO
- OP_POSUPTO
- OP_EXACT
-
-which are followed by a two-byte count (most significant first) and the
-repeated character. OP_UPTO matches from 0 to the given number. A repeat with a
-non-zero minimum and a fixed maximum is coded as an OP_EXACT followed by an
-OP_UPTO (or OP_MINUPTO or OPT_POSUPTO).
-
-
-Repeating character types
--------------------------
-
-Repeats of things like \d are done exactly as for single characters, except
-that instead of a character, the opcode for the type is stored in the data
-byte. The opcodes are:
-
- OP_TYPESTAR
- OP_TYPEMINSTAR
- OP_TYPEPOSSTAR
- OP_TYPEPLUS
- OP_TYPEMINPLUS
- OP_TYPEPOSPLUS
- OP_TYPEQUERY
- OP_TYPEMINQUERY
- OP_TYPEPOSQUERY
- OP_TYPEUPTO
- OP_TYPEMINUPTO
- OP_TYPEPOSUPTO
- OP_TYPEEXACT
-
-
-Match by Unicode property
--------------------------
-
-OP_PROP and OP_NOTPROP are used for positive and negative matches of a
-character by testing its Unicode property (the \p and \P escape sequences).
-Each is followed by two bytes that encode the desired property as a type and a
-value.
-
-Repeats of these items use the OP_TYPESTAR etc. set of opcodes, followed by
-three bytes: OP_PROP or OP_NOTPROP and then the desired property type and
-value.
-
-
-Matching literal characters
----------------------------
-
-The OP_CHAR opcode is followed by a single character that is to be matched
-casefully. For caseless matching, OP_CHARNC is used. In UTF-8 mode, the
-character may be more than one byte long. (Earlier versions of PCRE used
-multi-character strings, but this was changed to allow some new features to be
-added.)
-
-
-Character classes
------------------
-
-If there is only one character, OP_CHAR or OP_CHARNC is used for a positive
-class, and OP_NOT for a negative one (that is, for something like [^a]).
-However, in UTF-8 mode, the use of OP_NOT applies only to characters with
-values < 128, because OP_NOT is confined to single bytes.
-
-Another set of repeating opcodes (OP_NOTSTAR etc.) are used for a repeated,
-negated, single-character class. The normal ones (OP_STAR etc.) are used for a
-repeated positive single-character class.
-
-When there's more than one character in a class and all the characters are less
-than 256, OP_CLASS is used for a positive class, and OP_NCLASS for a negative
-one. In either case, the opcode is followed by a 32-byte bit map containing a 1
-bit for every character that is acceptable. The bits are counted from the least
-significant end of each byte.
-
-The reason for having both OP_CLASS and OP_NCLASS is so that, in UTF-8 mode,
-subject characters with values greater than 256 can be handled correctly. For
-OP_CLASS they don't match, whereas for OP_NCLASS they do.
-
-For classes containing characters with values > 255, OP_XCLASS is used. It
-optionally uses a bit map (if any characters lie within it), followed by a list
-of pairs and single characters. There is a flag character than indicates
-whether it's a positive or a negative class.
-
-
-Back references
----------------
-
-OP_REF is followed by two bytes containing the reference number.
-
-
-Repeating character classes and back references
------------------------------------------------
-
-Single-character classes are handled specially (see above). This section
-applies to OP_CLASS and OP_REF. In both cases, the repeat information follows
-the base item. The matching code looks at the following opcode to see if it is
-one of
-
- OP_CRSTAR
- OP_CRMINSTAR
- OP_CRPLUS
- OP_CRMINPLUS
- OP_CRQUERY
- OP_CRMINQUERY
- OP_CRRANGE
- OP_CRMINRANGE
-
-All but the last two are just single-byte items. The others are followed by
-four bytes of data, comprising the minimum and maximum repeat counts. There are
-no special possessive opcodes for these repeats; a possessive repeat is
-compiled into an atomic group.
-
-
-Brackets and alternation
-------------------------
-
-A pair of non-capturing (round) brackets is wrapped round each expression at
-compile time, so alternation always happens in the context of brackets.
-
-[Note for North Americans: "bracket" to some English speakers, including
-myself, can be round, square, curly, or pointy. Hence this usage.]
-
-Non-capturing brackets use the opcode OP_BRA. Originally PCRE was limited to 99
-capturing brackets and it used a different opcode for each one. From release
-3.5, the limit was removed by putting the bracket number into the data for
-higher-numbered brackets. From release 7.0 all capturing brackets are handled
-this way, using the single opcode OP_CBRA.
-
-A bracket opcode is followed by LINK_SIZE bytes which give the offset to the
-next alternative OP_ALT or, if there aren't any branches, to the matching
-OP_KET opcode. Each OP_ALT is followed by LINK_SIZE bytes giving the offset to
-the next one, or to the OP_KET opcode. For capturing brackets, the bracket
-number immediately follows the offset, always as a 2-byte item.
-
-OP_KET is used for subpatterns that do not repeat indefinitely, while
-OP_KETRMIN and OP_KETRMAX are used for indefinite repetitions, minimally or
-maximally respectively. All three are followed by LINK_SIZE bytes giving (as a
-positive number) the offset back to the matching bracket opcode.
-
-If a subpattern is quantified such that it is permitted to match zero times, it
-is preceded by one of OP_BRAZERO, OP_BRAMINZERO, or OP_SKIPZERO. These are
-single-byte opcodes that tell the matcher that skipping the following
-subpattern entirely is a valid branch. In the case of the first two, not
-skipping the pattern is also valid (greedy and non-greedy). The third is used
-when a pattern has the quantifier {0,0}. It cannot be entirely discarded,
-because it may be called as a subroutine from elsewhere in the regex.
-
-A subpattern with an indefinite maximum repetition is replicated in the
-compiled data its minimum number of times (or once with OP_BRAZERO if the
-minimum is zero), with the final copy terminating with OP_KETRMIN or OP_KETRMAX
-as appropriate.
-
-A subpattern with a bounded maximum repetition is replicated in a nested
-fashion up to the maximum number of times, with OP_BRAZERO or OP_BRAMINZERO
-before each replication after the minimum, so that, for example, (abc){2,5} is
-compiled as (abc)(abc)((abc)((abc)(abc)?)?)?, except that each bracketed group
-has the same number.
-
-When a repeated subpattern has an unbounded upper limit, it is checked to see
-whether it could match an empty string. If this is the case, the opcode in the
-final replication is changed to OP_SBRA or OP_SCBRA. This tells the matcher
-that it needs to check for matching an empty string when it hits OP_KETRMIN or
-OP_KETRMAX, and if so, to break the loop.
-
-
-Assertions
-----------
-
-Forward assertions are just like other subpatterns, but starting with one of
-the opcodes OP_ASSERT or OP_ASSERT_NOT. Backward assertions use the opcodes
-OP_ASSERTBACK and OP_ASSERTBACK_NOT, and the first opcode inside the assertion
-is OP_REVERSE, followed by a two byte count of the number of characters to move
-back the pointer in the subject string. When operating in UTF-8 mode, the count
-is a character count rather than a byte count. A separate count is present in
-each alternative of a lookbehind assertion, allowing them to have different
-fixed lengths.
-
-
-Once-only (atomic) subpatterns
-------------------------------
-
-These are also just like other subpatterns, but they start with the opcode
-OP_ONCE. The check for matching an empty string in an unbounded repeat is
-handled entirely at runtime, so there is just this one opcode.
-
-
-Conditional subpatterns
------------------------
-
-These are like other subpatterns, but they start with the opcode OP_COND, or
-OP_SCOND for one that might match an empty string in an unbounded repeat. If
-the condition is a back reference, this is stored at the start of the
-subpattern using the opcode OP_CREF followed by two bytes containing the
-reference number. If the condition is "in recursion" (coded as "(?(R)"), or "in
-recursion of group x" (coded as "(?(Rx)"), the group number is stored at the
-start of the subpattern using the opcode OP_RREF, and a value of zero for "the
-whole pattern". For a DEFINE condition, just the single byte OP_DEF is used (it
-has no associated data). Otherwise, a conditional subpattern always starts with
-one of the assertions.
-
-
-Recursion
----------
-
-Recursion either matches the current regex, or some subexpression. The opcode
-OP_RECURSE is followed by an value which is the offset to the starting bracket
-from the start of the whole pattern. From release 6.5, OP_RECURSE is
-automatically wrapped inside OP_ONCE brackets (because otherwise some patterns
-broke it). OP_RECURSE is also used for "subroutine" calls, even though they
-are not strictly a recursion.
-
-
-Callout
--------
-
-OP_CALLOUT is followed by one byte of data that holds a callout number in the
-range 0 to 254 for manual callouts, or 255 for an automatic callout. In both
-cases there follows a two-byte value giving the offset in the pattern to the
-start of the following item, and another two-byte item giving the length of the
-next item.
-
-
-Changing options
-----------------
-
-If any of the /i, /m, or /s options are changed within a pattern, an OP_OPT
-opcode is compiled, followed by one byte containing the new settings of these
-flags. If there are several alternatives, there is an occurrence of OP_OPT at
-the start of all those following the first options change, to set appropriate
-options for the start of the alternative. Immediately after the end of the
-group there is another such item to reset the flags to their previous values. A
-change of flag right at the very start of the pattern can be handled entirely
-at compile time, and so does not cause anything to be put into the compiled
-data.
-
-Philip Hazel
-April 2008
diff --git a/crawl-ref/source/util/pcre/INSTALL b/crawl-ref/source/util/pcre/INSTALL
deleted file mode 100644
index d3c5b40a94..0000000000
--- a/crawl-ref/source/util/pcre/INSTALL
+++ /dev/null
@@ -1,237 +0,0 @@
-Installation Instructions
-*************************
-
-Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005,
-2006, 2007 Free Software Foundation, Inc.
-
-This file is free documentation; the Free Software Foundation gives
-unlimited permission to copy, distribute and modify it.
-
-Basic Installation
-==================
-
-Briefly, the shell commands `./configure; make; make install' should
-configure, build, and install this package. The following
-more-detailed instructions are generic; see the `README' file for
-instructions specific to this package.
-
- The `configure' shell script attempts to guess correct values for
-various system-dependent variables used during compilation. It uses
-those values to create a `Makefile' in each directory of the package.
-It may also create one or more `.h' files containing system-dependent
-definitions. Finally, it creates a shell script `config.status' that
-you can run in the future to recreate the current configuration, and a
-file `config.log' containing compiler output (useful mainly for
-debugging `configure').
-
- It can also use an optional file (typically called `config.cache'
-and enabled with `--cache-file=config.cache' or simply `-C') that saves
-the results of its tests to speed up reconfiguring. Caching is
-disabled by default to prevent problems with accidental use of stale
-cache files.
-
- If you need to do unusual things to compile the package, please try
-to figure out how `configure' could check whether to do them, and mail
-diffs or instructions to the address given in the `README' so they can
-be considered for the next release. If you are using the cache, and at
-some point `config.cache' contains results you don't want to keep, you
-may remove or edit it.
-
- The file `configure.ac' (or `configure.in') is used to create
-`configure' by a program called `autoconf'. You need `configure.ac' if
-you want to change it or regenerate `configure' using a newer version
-of `autoconf'.
-
-The simplest way to compile this package is:
-
- 1. `cd' to the directory containing the package's source code and type
- `./configure' to configure the package for your system.
-
- Running `configure' might take a while. While running, it prints
- some messages telling which features it is checking for.
-
- 2. Type `make' to compile the package.
-
- 3. Optionally, type `make check' to run any self-tests that come with
- the package.
-
- 4. Type `make install' to install the programs and any data files and
- documentation.
-
- 5. You can remove the program binaries and object files from the
- source code directory by typing `make clean'. To also remove the
- files that `configure' created (so you can compile the package for
- a different kind of computer), type `make distclean'. There is
- also a `make maintainer-clean' target, but that is intended mainly
- for the package's developers. If you use it, you may have to get
- all sorts of other programs in order to regenerate files that came
- with the distribution.
-
- 6. Often, you can also type `make uninstall' to remove the installed
- files again.
-
-Compilers and Options
-=====================
-
-Some systems require unusual options for compilation or linking that the
-`configure' script does not know about. Run `./configure --help' for
-details on some of the pertinent environment variables.
-
- You can give `configure' initial values for configuration parameters
-by setting variables in the command line or in the environment. Here
-is an example:
-
- ./configure CC=c99 CFLAGS=-g LIBS=-lposix
-
- *Note Defining Variables::, for more details.
-
-Compiling For Multiple Architectures
-====================================
-
-You can compile the package for more than one kind of computer at the
-same time, by placing the object files for each architecture in their
-own directory. To do this, you can use GNU `make'. `cd' to the
-directory where you want the object files and executables to go and run
-the `configure' script. `configure' automatically checks for the
-source code in the directory that `configure' is in and in `..'.
-
- With a non-GNU `make', it is safer to compile the package for one
-architecture at a time in the source code directory. After you have
-installed the package for one architecture, use `make distclean' before
-reconfiguring for another architecture.
-
-Installation Names
-==================
-
-By default, `make install' installs the package's commands under
-`/usr/local/bin', include files under `/usr/local/include', etc. You
-can specify an installation prefix other than `/usr/local' by giving
-`configure' the option `--prefix=PREFIX'.
-
- You can specify separate installation prefixes for
-architecture-specific files and architecture-independent files. If you
-pass the option `--exec-prefix=PREFIX' to `configure', the package uses
-PREFIX as the prefix for installing programs and libraries.
-Documentation and other data files still use the regular prefix.
-
- In addition, if you use an unusual directory layout you can give
-options like `--bindir=DIR' to specify different values for particular
-kinds of files. Run `configure --help' for a list of the directories
-you can set and what kinds of files go in them.
-
- If the package supports it, you can cause programs to be installed
-with an extra prefix or suffix on their names by giving `configure' the
-option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
-
-Optional Features
-=================
-
-Some packages pay attention to `--enable-FEATURE' options to
-`configure', where FEATURE indicates an optional part of the package.
-They may also pay attention to `--with-PACKAGE' options, where PACKAGE
-is something like `gnu-as' or `x' (for the X Window System). The
-`README' should mention any `--enable-' and `--with-' options that the
-package recognizes.
-
- For packages that use the X Window System, `configure' can usually
-find the X include and library files automatically, but if it doesn't,
-you can use the `configure' options `--x-includes=DIR' and
-`--x-libraries=DIR' to specify their locations.
-
-Specifying the System Type
-==========================
-
-There may be some features `configure' cannot figure out automatically,
-but needs to determine by the type of machine the package will run on.
-Usually, assuming the package is built to be run on the _same_
-architectures, `configure' can figure that out, but if it prints a
-message saying it cannot guess the machine type, give it the
-`--build=TYPE' option. TYPE can either be a short name for the system
-type, such as `sun4', or a canonical name which has the form:
-
- CPU-COMPANY-SYSTEM
-
-where SYSTEM can have one of these forms:
-
- OS KERNEL-OS
-
- See the file `config.sub' for the possible values of each field. If
-`config.sub' isn't included in this package, then this package doesn't
-need to know the machine type.
-
- If you are _building_ compiler tools for cross-compiling, you should
-use the option `--target=TYPE' to select the type of system they will
-produce code for.
-
- If you want to _use_ a cross compiler, that generates code for a
-platform different from the build platform, you should specify the
-"host" platform (i.e., that on which the generated programs will
-eventually be run) with `--host=TYPE'.
-
-Sharing Defaults
-================
-
-If you want to set default values for `configure' scripts to share, you
-can create a site shell script called `config.site' that gives default
-values for variables like `CC', `cache_file', and `prefix'.
-`configure' looks for `PREFIX/share/config.site' if it exists, then
-`PREFIX/etc/config.site' if it exists. Or, you can set the
-`CONFIG_SITE' environment variable to the location of the site script.
-A warning: not all `configure' scripts look for a site script.
-
-Defining Variables
-==================
-
-Variables not defined in a site shell script can be set in the
-environment passed to `configure'. However, some packages may run
-configure again during the build, and the customized values of these
-variables may be lost. In order to avoid this problem, you should set
-them in the `configure' command line, using `VAR=value'. For example:
-
- ./configure CC=/usr/local2/bin/gcc
-
-causes the specified `gcc' to be used as the C compiler (unless it is
-overridden in the site shell script).
-
-Unfortunately, this technique does not work for `CONFIG_SHELL' due to
-an Autoconf bug. Until the bug is fixed you can use this workaround:
-
- CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash
-
-`configure' Invocation
-======================
-
-`configure' recognizes the following options to control how it operates.
-
-`--help'
-`-h'
- Print a summary of the options to `configure', and exit.
-
-`--version'
-`-V'
- Print the version of Autoconf used to generate the `configure'
- script, and exit.
-
-`--cache-file=FILE'
- Enable the cache: use and save the results of the tests in FILE,
- traditionally `config.cache'. FILE defaults to `/dev/null' to
- disable caching.
-
-`--config-cache'
-`-C'
- Alias for `--cache-file=config.cache'.
-
-`--quiet'
-`--silent'
-`-q'
- Do not print messages saying which checks are being made. To
- suppress all normal output, redirect it to `/dev/null' (any error
- messages will still be shown).
-
-`--srcdir=DIR'
- Look for the package's source code in directory DIR. Usually
- `configure' can determine that directory automatically.
-
-`configure' also accepts some other, not widely useful, options. Run
-`configure --help' for more details.
-
diff --git a/crawl-ref/source/util/pcre/LICENCE b/crawl-ref/source/util/pcre/LICENCE
deleted file mode 100644
index 03fabc6aef..0000000000
--- a/crawl-ref/source/util/pcre/LICENCE
+++ /dev/null
@@ -1,68 +0,0 @@
-PCRE LICENCE
-------------
-
-PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
-Release 7 of PCRE is distributed under the terms of the "BSD" licence, as
-specified below. The documentation for PCRE, supplied in the "doc"
-directory, is distributed under the same terms as the software itself.
-
-The basic library functions are written in C and are freestanding. Also
-included in the distribution is a set of C++ wrapper functions.
-
-
-THE BASIC LIBRARY FUNCTIONS
----------------------------
-
-Written by: Philip Hazel
-Email local part: ph10
-Email domain: cam.ac.uk
-
-University of Cambridge Computing Service,
-Cambridge, England.
-
-Copyright (c) 1997-2008 University of Cambridge
-All rights reserved.
-
-
-THE C++ WRAPPER FUNCTIONS
--------------------------
-
-Contributed by: Google Inc.
-
-Copyright (c) 2007-2008, Google Inc.
-All rights reserved.
-
-
-THE "BSD" LICENCE
------------------
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the name of Google
- Inc. nor the names of their contributors may be used to endorse or
- promote products derived from this software without specific prior
- written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-
-End
diff --git a/crawl-ref/source/util/pcre/Makefile b/crawl-ref/source/util/pcre/Makefile
deleted file mode 100644
index 78602c2085..0000000000
--- a/crawl-ref/source/util/pcre/Makefile
+++ /dev/null
@@ -1,55 +0,0 @@
-# -*- Makefile -*- for PCRE (Win32, MinGW)
-
-ifneq ($(findstring $(MAKEFLAGS),s),s)
-ifndef V
- QUIET_CC = @echo ' ' CC $@;
- QUIET_AR = @echo ' ' AR $@;
- export V
-endif
-endif
-
-OBJECTS := \
- pcre_chartables.o \
- pcre_compile.o \
- pcre_config.o \
- pcre_dfa_exec.o \
- pcre_exec.o \
- pcre_fullinfo.o \
- pcre_get.o \
- pcre_globals.o \
- pcre_info.o \
- pcre_maketables.o \
- pcre_newline.o \
- pcre_ord2utf8.o \
- pcre_refcount.o \
- pcre_study.o \
- pcre_tables.o \
- pcre_try_flipped.o \
- pcre_ucp_searchfuncs.o \
- pcre_valid_utf8.o \
- pcre_version.o \
- pcre_xclass.o
-
-CC ?= gcc
-AR := ar rcu
-RANLIB := ranlib
-DEL := rm -f
-
-CFLAGS += -I. -DHAVE_CONFIG_H
-LDFLAGS :=
-
-LIBNAME := libpcre.a
-
-all: $(LIBNAME)
-
-clean:
- $(DEL) $(LIBNAME)
- $(DEL) $(OBJECTS)
-
-$(LIBNAME) : $(OBJECTS)
- $(QUIET_AR)$(AR) $@ $?
- @$(RANLIB) $@
-
-%.o: %.c
- $(QUIET_CC)$(CC) $(CFLAGS) -o $@ -c $<
-
diff --git a/crawl-ref/source/util/pcre/Makefile.am b/crawl-ref/source/util/pcre/Makefile.am
deleted file mode 100644
index ec4b4799f2..0000000000
--- a/crawl-ref/source/util/pcre/Makefile.am
+++ /dev/null
@@ -1,392 +0,0 @@
-## Process this file with automake to produce Makefile.in.
-
-dist_doc_DATA = \
- doc/pcre.txt \
- doc/pcre-config.txt \
- doc/pcregrep.txt \
- doc/pcretest.txt \
- AUTHORS \
- COPYING \
- ChangeLog \
- LICENCE \
- NEWS \
- README
-
-dist_html_DATA = \
- doc/html/index.html \
- doc/html/pcre.html \
- doc/html/pcre-config.html \
- doc/html/pcre_compile.html \
- doc/html/pcre_compile2.html \
- doc/html/pcre_config.html \
- doc/html/pcre_copy_named_substring.html \
- doc/html/pcre_copy_substring.html \
- doc/html/pcre_dfa_exec.html \
- doc/html/pcre_exec.html \
- doc/html/pcre_free_substring.html \
- doc/html/pcre_free_substring_list.html \
- doc/html/pcre_fullinfo.html \
- doc/html/pcre_get_named_substring.html \
- doc/html/pcre_get_stringnumber.html \
- doc/html/pcre_get_stringtable_entries.html \
- doc/html/pcre_get_substring.html \
- doc/html/pcre_get_substring_list.html \
- doc/html/pcre_info.html \
- doc/html/pcre_maketables.html \
- doc/html/pcre_refcount.html \
- doc/html/pcre_study.html \
- doc/html/pcre_version.html \
- doc/html/pcreapi.html \
- doc/html/pcrebuild.html \
- doc/html/pcrecallout.html \
- doc/html/pcrecompat.html \
- doc/html/pcregrep.html \
- doc/html/pcrematching.html \
- doc/html/pcrepartial.html \
- doc/html/pcrepattern.html \
- doc/html/pcreperform.html \
- doc/html/pcreposix.html \
- doc/html/pcreprecompile.html \
- doc/html/pcresample.html \
- doc/html/pcrestack.html \
- doc/html/pcresyntax.html \
- doc/html/pcretest.html
-
-pcrecpp_html = doc/html/pcrecpp.html
-dist_noinst_DATA = $(pcrecpp_html)
-
-if WITH_PCRE_CPP
-html_DATA = $(pcrecpp_html)
-endif
-
-# The Libtool libraries to install. We'll add to this later.
-lib_LTLIBRARIES =
-
-# Unit tests you want to run when people type 'make check'.
-# TESTS is for binary unit tests, check_SCRIPTS for script-based tests
-TESTS =
-check_SCRIPTS =
-dist_noinst_SCRIPTS =
-
-# Some of the binaries we make are to be installed, and others are
-# (non-user-visible) helper programs needed to build libpcre.
-bin_PROGRAMS =
-noinst_PROGRAMS =
-
-# Additional files to delete on 'make clean' and 'make maintainer-clean'.
-CLEANFILES =
-MAINTAINERCLEANFILES =
-
-# Additional files to bundle with the distribution, over and above what
-# the Autotools include by default.
-EXTRA_DIST =
-
-# These files contain maintenance information
-EXTRA_DIST += \
- doc/perltest.txt \
- NON-UNIX-USE \
- HACKING
-
-# These files are used in the preparation of a release
-EXTRA_DIST += \
- PrepareRelease \
- CleanTxt \
- Detrail \
- 132html \
- doc/index.html.src
-
-# These files are to do with building for Virtual Pascal
-EXTRA_DIST += \
- makevp.bat \
- makevp_c.txt \
- makevp_l.txt \
- pcregexp.pas
-
-# These files are usable versions of pcre.h and config.h that are distributed
-# for the benefit of people who are building PCRE manually, without the
-# Autotools support.
-EXTRA_DIST += \
- pcre.h.generic \
- config.h.generic
-
-pcre.h.generic: configure.ac
- rm -f $@
- cp -p pcre.h $@
-
-MAINTAINERCLEANFILES += pcre.h.generic
-
-# These are the header files we'll install. We do not distribute pcre.h because
-# it is generated from pcre.h.in.
-nodist_include_HEADERS = \
- pcre.h
-include_HEADERS = \
- pcreposix.h
-
-# These additional headers will be be installed if C++ support is enabled. We
-# do not distribute pcrecpparg.h or pcre_stringpiece.h, as these are generated
-# from corresponding .h.in files (which we do distribute).
-if WITH_PCRE_CPP
-nodist_include_HEADERS += \
- pcrecpparg.h \
- pcre_stringpiece.h
-include_HEADERS += \
- pcrecpp.h \
- pcre_scanner.h
-endif # WITH_PCRE_CPP
-
-bin_SCRIPTS = pcre-config
-
-## ---------------------------------------------------------------
-## The dftables program is used to rebuild character tables before compiling
-## PCRE, if --enable-rebuild-chartables is specified. It is not a user-visible
-## program. The default (when --enable-rebuild-chartables is not specified) is
-## to copy a distributed set of tables that are defined for ASCII code. In this
-## case, dftables is not needed.
-
-if WITH_REBUILD_CHARTABLES
-
-noinst_PROGRAMS += dftables
-dftables_SOURCES = dftables.c
-
-pcre_chartables.c: dftables$(EXEEXT)
- ./dftables$(EXEEXT) $@
-else
-
-pcre_chartables.c: $(srcdir)/pcre_chartables.c.dist
- rm -f $@
- $(LN_S) $(srcdir)/pcre_chartables.c.dist $@
-
-endif # WITH_REBUILD_CHARTABLES
-
-
-## The main pcre library
-lib_LTLIBRARIES += libpcre.la
-libpcre_la_SOURCES = \
- pcre_compile.c \
- pcre_config.c \
- pcre_dfa_exec.c \
- pcre_exec.c \
- pcre_fullinfo.c \
- pcre_get.c \
- pcre_globals.c \
- pcre_info.c \
- pcre_internal.h \
- pcre_maketables.c \
- pcre_newline.c \
- pcre_ord2utf8.c \
- pcre_refcount.c \
- pcre_study.c \
- pcre_tables.c \
- pcre_try_flipped.c \
- pcre_ucp_searchfuncs.c \
- pcre_valid_utf8.c \
- pcre_version.c \
- pcre_xclass.c \
- ucp.h \
- ucpinternal.h \
- ucptable.h
-
-## This file is generated as part of the building process, so don't distribute.
-nodist_libpcre_la_SOURCES = \
- pcre_chartables.c
-
-# The pcre_printint.src file is #included by some source files, so it must be
-# distributed. The pcre_chartables.c.dist file is the default version of
-# pcre_chartables.c, used unless --enable-rebuild-chartables is specified.
-EXTRA_DIST += pcre_printint.src pcre_chartables.c.dist
-
-libpcre_la_LDFLAGS = $(EXTRA_LIBPCRE_LDFLAGS)
-
-CLEANFILES += pcre_chartables.c
-
-## A version of the main pcre library that has a posix re API.
-lib_LTLIBRARIES += libpcreposix.la
-libpcreposix_la_SOURCES = \
- pcreposix.c
-libpcreposix_la_LDFLAGS = $(EXTRA_LIBPCREPOSIX_LDFLAGS)
-libpcreposix_la_LIBADD = libpcre.la
-
-## There's a C++ library as well.
-if WITH_PCRE_CPP
-
-lib_LTLIBRARIES += libpcrecpp.la
-libpcrecpp_la_SOURCES = \
- pcrecpp_internal.h \
- pcrecpp.cc \
- pcre_scanner.cc \
- pcre_stringpiece.cc
-libpcrecpp_la_LDFLAGS = $(EXTRA_LIBPCRECPP_LDFLAGS)
-libpcrecpp_la_LIBADD = libpcre.la
-
-TESTS += pcrecpp_unittest
-noinst_PROGRAMS += pcrecpp_unittest
-pcrecpp_unittest_SOURCES = pcrecpp_unittest.cc
-pcrecpp_unittest_LDADD = libpcrecpp.la
-
-TESTS += pcre_scanner_unittest
-noinst_PROGRAMS += pcre_scanner_unittest
-pcre_scanner_unittest_SOURCES = pcre_scanner_unittest.cc
-pcre_scanner_unittest_LDADD = libpcrecpp.la
-
-TESTS += pcre_stringpiece_unittest
-noinst_PROGRAMS += pcre_stringpiece_unittest
-pcre_stringpiece_unittest_SOURCES = pcre_stringpiece_unittest.cc
-pcre_stringpiece_unittest_LDADD = libpcrecpp.la
-
-endif # WITH_PCRE_CPP
-
-## The main unit tests
-
-# Each unit test is a binary plus a script that runs that binary in various
-# ways. We install these test binaries in case folks find it helpful.
-
-TESTS += RunTest
-dist_noinst_SCRIPTS += RunTest
-EXTRA_DIST += RunTest.bat
-bin_PROGRAMS += pcretest
-pcretest_SOURCES = pcretest.c
-pcretest_LDADD = libpcreposix.la
-
-TESTS += RunGrepTest
-dist_noinst_SCRIPTS += RunGrepTest
-bin_PROGRAMS += pcregrep
-pcregrep_SOURCES = pcregrep.c
-pcregrep_LDADD = libpcreposix.la
-
-EXTRA_DIST += \
- testdata/grepinput \
- testdata/grepinput8 \
- testdata/grepinputv \
- testdata/grepinputx \
- testdata/greplist \
- testdata/grepoutput \
- testdata/grepoutput8 \
- testdata/grepoutputN \
- testdata/testinput1 \
- testdata/testinput2 \
- testdata/testinput3 \
- testdata/testinput4 \
- testdata/testinput5 \
- testdata/testinput6 \
- testdata/testinput7 \
- testdata/testinput8 \
- testdata/testinput9 \
- testdata/testinput10 \
- testdata/testoutput1 \
- testdata/testoutput2 \
- testdata/testoutput3 \
- testdata/testoutput4 \
- testdata/testoutput5 \
- testdata/testoutput6 \
- testdata/testoutput7 \
- testdata/testoutput8 \
- testdata/testoutput9 \
- testdata/testoutput10 \
- testdata/wintestinput3 \
- testdata/wintestoutput3 \
- perltest.pl
-
-CLEANFILES += \
- testsavedregex \
- teststderr \
- testtry \
- testNinput
-
-
-# PCRE demonstration program. No longer built automatcally. The point is that
-# the users should build it themselves. So just distribute the source.
-# noinst_PROGRAMS += pcredemo
-# pcredemo_SOURCES = pcredemo.c
-# pcredemo_LDADD = libpcre.la
-
-EXTRA_DIST += pcredemo.c
-
-
-## Utility rules, documentation, etc.
-
-# A compatibility line, the old build system worked with 'make test'
-test: check ;
-
-
-# A PCRE user submitted the following addition, saying that it "will allow
-# anyone using the 'mingw32' compiler to simply type 'make pcre.dll' and get a
-# nice DLL for Windows use". (It is used by the pcre.dll target.)
-DLL_OBJS= pcre_compile.o pcre_config.o \
- pcre_dfa_exec.o pcre_exec.o pcre_fullinfo.o pcre_get.o \
- pcre_globals.o pcre_info.o pcre_maketables.o \
- pcre_newline.o pcre_ord2utf8.o pcre_refcount.o \
- pcre_study.o pcre_tables.o pcre_try_flipped.o \
- pcre_ucp_searchfuncs.o pcre_valid_utf8.o pcre_version.o \
- pcre_chartables.o \
- pcre_xclass.o
-
-# A PCRE user submitted the following addition, saying that it "will allow
-# anyone using the 'mingw32' compiler to simply type 'make pcre.dll' and get a
-# nice DLL for Windows use".
-pcre.dll: $(DLL_OBJS)
- $(CC) -shared -o pcre.dll -Wl,"--strip-all" -Wl,"--export-all-symbols" $(DLL_OBJS)
-
-
-# We have .pc files for pkg-config users.
-pkgconfigdir = $(libdir)/pkgconfig
-pkgconfig_DATA = libpcre.pc
-if WITH_PCRE_CPP
-pkgconfig_DATA += libpcrecpp.pc
-endif
-
-dist_man_MANS = \
- doc/pcre.3 \
- doc/pcre-config.1 \
- doc/pcre_compile.3 \
- doc/pcre_compile2.3 \
- doc/pcre_config.3 \
- doc/pcre_copy_named_substring.3 \
- doc/pcre_copy_substring.3 \
- doc/pcre_dfa_exec.3 \
- doc/pcre_exec.3 \
- doc/pcre_free_substring.3 \
- doc/pcre_free_substring_list.3 \
- doc/pcre_fullinfo.3 \
- doc/pcre_get_named_substring.3 \
- doc/pcre_get_stringnumber.3 \
- doc/pcre_get_stringtable_entries.3 \
- doc/pcre_get_substring.3 \
- doc/pcre_get_substring_list.3 \
- doc/pcre_info.3 \
- doc/pcre_maketables.3 \
- doc/pcre_refcount.3 \
- doc/pcre_study.3 \
- doc/pcre_version.3 \
- doc/pcreapi.3 \
- doc/pcrebuild.3 \
- doc/pcrecallout.3 \
- doc/pcrecompat.3 \
- doc/pcregrep.1 \
- doc/pcrematching.3 \
- doc/pcrepartial.3 \
- doc/pcrepattern.3 \
- doc/pcreperform.3 \
- doc/pcreposix.3 \
- doc/pcreprecompile.3 \
- doc/pcresample.3 \
- doc/pcrestack.3 \
- doc/pcresyntax.3 \
- doc/pcretest.1
-
-pcrecpp_man = doc/pcrecpp.3
-EXTRA_DIST += $(pcrecpp_man)
-
-if WITH_PCRE_CPP
-man_MANS = $(pcrecpp_man)
-endif
-
-## CMake support
-
-EXTRA_DIST += \
- cmake/COPYING-CMAKE-SCRIPTS \
- cmake/FindPackageHandleStandardArgs.cmake \
- cmake/FindReadline.cmake \
- CMakeLists.txt \
- config-cmake.h.in
-
-## end Makefile.am
diff --git a/crawl-ref/source/util/pcre/Makefile.in b/crawl-ref/source/util/pcre/Makefile.in
deleted file mode 100644
index ee690f6a40..0000000000
--- a/crawl-ref/source/util/pcre/Makefile.in
+++ /dev/null
@@ -1,1436 +0,0 @@
-# Makefile.in generated by automake 1.10.1 from Makefile.am.
-# @configure_input@
-
-# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
-# This Makefile.in is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
-# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-# PARTICULAR PURPOSE.
-
-@SET_MAKE@
-
-
-
-
-
-VPATH = @srcdir@
-pkgdatadir = $(datadir)/@PACKAGE@
-pkglibdir = $(libdir)/@PACKAGE@
-pkgincludedir = $(includedir)/@PACKAGE@
-am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
-install_sh_DATA = $(install_sh) -c -m 644
-install_sh_PROGRAM = $(install_sh) -c
-install_sh_SCRIPT = $(install_sh) -c
-INSTALL_HEADER = $(INSTALL_DATA)
-transform = $(program_transform_name)
-NORMAL_INSTALL = :
-PRE_INSTALL = :
-POST_INSTALL = :
-NORMAL_UNINSTALL = :
-PRE_UNINSTALL = :
-POST_UNINSTALL = :
-build_triplet = @build@
-host_triplet = @host@
-TESTS = $(am__EXEEXT_2) RunTest RunGrepTest
-bin_PROGRAMS = pcretest$(EXEEXT) pcregrep$(EXEEXT)
-noinst_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2)
-
-# These additional headers will be be installed if C++ support is enabled. We
-# do not distribute pcrecpparg.h or pcre_stringpiece.h, as these are generated
-# from corresponding .h.in files (which we do distribute).
-@WITH_PCRE_CPP_TRUE@am__append_1 = \
-@WITH_PCRE_CPP_TRUE@ pcrecpparg.h \
-@WITH_PCRE_CPP_TRUE@ pcre_stringpiece.h
-
-@WITH_PCRE_CPP_TRUE@am__append_2 = \
-@WITH_PCRE_CPP_TRUE@ pcrecpp.h \
-@WITH_PCRE_CPP_TRUE@ pcre_scanner.h
-
-@WITH_REBUILD_CHARTABLES_TRUE@am__append_3 = dftables
-@WITH_PCRE_CPP_TRUE@am__append_4 = libpcrecpp.la
-@WITH_PCRE_CPP_TRUE@am__append_5 = pcrecpp_unittest \
-@WITH_PCRE_CPP_TRUE@ pcre_scanner_unittest \
-@WITH_PCRE_CPP_TRUE@ pcre_stringpiece_unittest
-@WITH_PCRE_CPP_TRUE@am__append_6 = pcrecpp_unittest \
-@WITH_PCRE_CPP_TRUE@ pcre_scanner_unittest \
-@WITH_PCRE_CPP_TRUE@ pcre_stringpiece_unittest
-@WITH_PCRE_CPP_TRUE@am__append_7 = libpcrecpp.pc
-subdir = .
-DIST_COMMON = README $(am__configure_deps) $(am__include_HEADERS_DIST) \
- $(dist_doc_DATA) $(dist_html_DATA) $(dist_man_MANS) \
- $(dist_noinst_DATA) $(dist_noinst_SCRIPTS) \
- $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
- $(srcdir)/config.h.in $(srcdir)/libpcre.pc.in \
- $(srcdir)/libpcrecpp.pc.in $(srcdir)/pcre-config.in \
- $(srcdir)/pcre.h.in $(srcdir)/pcre_stringpiece.h.in \
- $(srcdir)/pcrecpparg.h.in $(top_srcdir)/configure AUTHORS \
- COPYING ChangeLog INSTALL NEWS config.guess config.sub depcomp \
- install-sh ltmain.sh missing
-ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/configure.ac
-am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
- $(ACLOCAL_M4)
-am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
- configure.lineno config.status.lineno
-mkinstalldirs = $(install_sh) -d
-CONFIG_HEADER = config.h
-CONFIG_CLEAN_FILES = libpcre.pc libpcrecpp.pc pcre-config pcre.h \
- pcre_stringpiece.h pcrecpparg.h
-am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
-am__vpath_adj = case $$p in \
- $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
- *) f=$$p;; \
- esac;
-am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
-am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" \
- "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" \
- "$(DESTDIR)$(man3dir)" "$(DESTDIR)$(docdir)" \
- "$(DESTDIR)$(htmldir)" "$(DESTDIR)$(htmldir)" \
- "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(includedir)" \
- "$(DESTDIR)$(includedir)"
-libLTLIBRARIES_INSTALL = $(INSTALL)
-LTLIBRARIES = $(lib_LTLIBRARIES)
-libpcre_la_LIBADD =
-am_libpcre_la_OBJECTS = pcre_compile.lo pcre_config.lo \
- pcre_dfa_exec.lo pcre_exec.lo pcre_fullinfo.lo pcre_get.lo \
- pcre_globals.lo pcre_info.lo pcre_maketables.lo \
- pcre_newline.lo pcre_ord2utf8.lo pcre_refcount.lo \
- pcre_study.lo pcre_tables.lo pcre_try_flipped.lo \
- pcre_ucp_searchfuncs.lo pcre_valid_utf8.lo pcre_version.lo \
- pcre_xclass.lo
-nodist_libpcre_la_OBJECTS = pcre_chartables.lo
-libpcre_la_OBJECTS = $(am_libpcre_la_OBJECTS) \
- $(nodist_libpcre_la_OBJECTS)
-libpcre_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
- $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
- $(libpcre_la_LDFLAGS) $(LDFLAGS) -o $@
-@WITH_PCRE_CPP_TRUE@libpcrecpp_la_DEPENDENCIES = libpcre.la
-am__libpcrecpp_la_SOURCES_DIST = pcrecpp_internal.h pcrecpp.cc \
- pcre_scanner.cc pcre_stringpiece.cc
-@WITH_PCRE_CPP_TRUE@am_libpcrecpp_la_OBJECTS = pcrecpp.lo \
-@WITH_PCRE_CPP_TRUE@ pcre_scanner.lo pcre_stringpiece.lo
-libpcrecpp_la_OBJECTS = $(am_libpcrecpp_la_OBJECTS)
-libpcrecpp_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
- $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
- $(CXXFLAGS) $(libpcrecpp_la_LDFLAGS) $(LDFLAGS) -o $@
-@WITH_PCRE_CPP_TRUE@am_libpcrecpp_la_rpath = -rpath $(libdir)
-libpcreposix_la_DEPENDENCIES = libpcre.la
-am_libpcreposix_la_OBJECTS = pcreposix.lo
-libpcreposix_la_OBJECTS = $(am_libpcreposix_la_OBJECTS)
-libpcreposix_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
- $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
- $(libpcreposix_la_LDFLAGS) $(LDFLAGS) -o $@
-binPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
-@WITH_REBUILD_CHARTABLES_TRUE@am__EXEEXT_1 = dftables$(EXEEXT)
-@WITH_PCRE_CPP_TRUE@am__EXEEXT_2 = pcrecpp_unittest$(EXEEXT) \
-@WITH_PCRE_CPP_TRUE@ pcre_scanner_unittest$(EXEEXT) \
-@WITH_PCRE_CPP_TRUE@ pcre_stringpiece_unittest$(EXEEXT)
-PROGRAMS = $(bin_PROGRAMS) $(noinst_PROGRAMS)
-am__dftables_SOURCES_DIST = dftables.c
-@WITH_REBUILD_CHARTABLES_TRUE@am_dftables_OBJECTS = \
-@WITH_REBUILD_CHARTABLES_TRUE@ dftables.$(OBJEXT)
-dftables_OBJECTS = $(am_dftables_OBJECTS)
-dftables_LDADD = $(LDADD)
-am__pcre_scanner_unittest_SOURCES_DIST = pcre_scanner_unittest.cc
-@WITH_PCRE_CPP_TRUE@am_pcre_scanner_unittest_OBJECTS = \
-@WITH_PCRE_CPP_TRUE@ pcre_scanner_unittest.$(OBJEXT)
-pcre_scanner_unittest_OBJECTS = $(am_pcre_scanner_unittest_OBJECTS)
-@WITH_PCRE_CPP_TRUE@pcre_scanner_unittest_DEPENDENCIES = \
-@WITH_PCRE_CPP_TRUE@ libpcrecpp.la
-am__pcre_stringpiece_unittest_SOURCES_DIST = \
- pcre_stringpiece_unittest.cc
-@WITH_PCRE_CPP_TRUE@am_pcre_stringpiece_unittest_OBJECTS = \
-@WITH_PCRE_CPP_TRUE@ pcre_stringpiece_unittest.$(OBJEXT)
-pcre_stringpiece_unittest_OBJECTS = \
- $(am_pcre_stringpiece_unittest_OBJECTS)
-@WITH_PCRE_CPP_TRUE@pcre_stringpiece_unittest_DEPENDENCIES = \
-@WITH_PCRE_CPP_TRUE@ libpcrecpp.la
-am__pcrecpp_unittest_SOURCES_DIST = pcrecpp_unittest.cc
-@WITH_PCRE_CPP_TRUE@am_pcrecpp_unittest_OBJECTS = \
-@WITH_PCRE_CPP_TRUE@ pcrecpp_unittest.$(OBJEXT)
-pcrecpp_unittest_OBJECTS = $(am_pcrecpp_unittest_OBJECTS)
-@WITH_PCRE_CPP_TRUE@pcrecpp_unittest_DEPENDENCIES = libpcrecpp.la
-am_pcregrep_OBJECTS = pcregrep.$(OBJEXT)
-pcregrep_OBJECTS = $(am_pcregrep_OBJECTS)
-pcregrep_DEPENDENCIES = libpcreposix.la
-am_pcretest_OBJECTS = pcretest.$(OBJEXT)
-pcretest_OBJECTS = $(am_pcretest_OBJECTS)
-pcretest_DEPENDENCIES = libpcreposix.la
-binSCRIPT_INSTALL = $(INSTALL_SCRIPT)
-SCRIPTS = $(bin_SCRIPTS) $(dist_noinst_SCRIPTS)
-DEFAULT_INCLUDES = -I.@am__isrc@
-depcomp = $(SHELL) $(top_srcdir)/depcomp
-am__depfiles_maybe = depfiles
-COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
- $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
-LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
- --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
- $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
-CCLD = $(CC)
-LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
- --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
- $(LDFLAGS) -o $@
-CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
- $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
-LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
- --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
- $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
-CXXLD = $(CXX)
-CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
- --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \
- $(LDFLAGS) -o $@
-SOURCES = $(libpcre_la_SOURCES) $(nodist_libpcre_la_SOURCES) \
- $(libpcrecpp_la_SOURCES) $(libpcreposix_la_SOURCES) \
- $(dftables_SOURCES) $(pcre_scanner_unittest_SOURCES) \
- $(pcre_stringpiece_unittest_SOURCES) \
- $(pcrecpp_unittest_SOURCES) $(pcregrep_SOURCES) \
- $(pcretest_SOURCES)
-DIST_SOURCES = $(libpcre_la_SOURCES) $(am__libpcrecpp_la_SOURCES_DIST) \
- $(libpcreposix_la_SOURCES) $(am__dftables_SOURCES_DIST) \
- $(am__pcre_scanner_unittest_SOURCES_DIST) \
- $(am__pcre_stringpiece_unittest_SOURCES_DIST) \
- $(am__pcrecpp_unittest_SOURCES_DIST) $(pcregrep_SOURCES) \
- $(pcretest_SOURCES)
-man1dir = $(mandir)/man1
-man3dir = $(mandir)/man3
-NROFF = nroff
-MANS = $(dist_man_MANS) $(man_MANS)
-dist_docDATA_INSTALL = $(INSTALL_DATA)
-dist_htmlDATA_INSTALL = $(INSTALL_DATA)
-htmlDATA_INSTALL = $(INSTALL_DATA)
-pkgconfigDATA_INSTALL = $(INSTALL_DATA)
-DATA = $(dist_doc_DATA) $(dist_html_DATA) $(dist_noinst_DATA) \
- $(html_DATA) $(pkgconfig_DATA)
-am__include_HEADERS_DIST = pcreposix.h pcrecpp.h pcre_scanner.h
-includeHEADERS_INSTALL = $(INSTALL_HEADER)
-nodist_includeHEADERS_INSTALL = $(INSTALL_HEADER)
-HEADERS = $(include_HEADERS) $(nodist_include_HEADERS)
-ETAGS = etags
-CTAGS = ctags
-DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
-distdir = $(PACKAGE)-$(VERSION)
-top_distdir = $(distdir)
-am__remove_distdir = \
- { test ! -d $(distdir) \
- || { find $(distdir) -type d ! -perm -200 -exec chmod u+w {} ';' \
- && rm -fr $(distdir); }; }
-DIST_ARCHIVES = $(distdir).tar.gz $(distdir).tar.bz2 $(distdir).zip
-GZIP_ENV = --best
-distuninstallcheck_listfiles = find . -type f -print
-distcleancheck_listfiles = find . -type f -print
-ACLOCAL = @ACLOCAL@
-AMTAR = @AMTAR@
-AR = @AR@
-AS = @AS@
-AUTOCONF = @AUTOCONF@
-AUTOHEADER = @AUTOHEADER@
-AUTOMAKE = @AUTOMAKE@
-AWK = @AWK@
-CC = @CC@
-CCDEPMODE = @CCDEPMODE@
-CFLAGS = @CFLAGS@
-CPP = @CPP@
-CPPFLAGS = @CPPFLAGS@
-CXX = @CXX@
-CXXCPP = @CXXCPP@
-CXXDEPMODE = @CXXDEPMODE@
-CXXFLAGS = @CXXFLAGS@
-CYGPATH_W = @CYGPATH_W@
-DEFS = @DEFS@
-DEPDIR = @DEPDIR@
-DISTCHECK_CONFIGURE_FLAGS = @DISTCHECK_CONFIGURE_FLAGS@
-DLLTOOL = @DLLTOOL@
-DSYMUTIL = @DSYMUTIL@
-ECHO = @ECHO@
-ECHO_C = @ECHO_C@
-ECHO_N = @ECHO_N@
-ECHO_T = @ECHO_T@
-EGREP = @EGREP@
-EXEEXT = @EXEEXT@
-EXTRA_LIBPCRECPP_LDFLAGS = @EXTRA_LIBPCRECPP_LDFLAGS@
-EXTRA_LIBPCREPOSIX_LDFLAGS = @EXTRA_LIBPCREPOSIX_LDFLAGS@
-EXTRA_LIBPCRE_LDFLAGS = @EXTRA_LIBPCRE_LDFLAGS@
-F77 = @F77@
-FFLAGS = @FFLAGS@
-GREP = @GREP@
-INSTALL = @INSTALL@
-INSTALL_DATA = @INSTALL_DATA@
-INSTALL_PROGRAM = @INSTALL_PROGRAM@
-INSTALL_SCRIPT = @INSTALL_SCRIPT@
-INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
-LDFLAGS = @LDFLAGS@
-LIBOBJS = @LIBOBJS@
-LIBS = @LIBS@
-LIBTOOL = @LIBTOOL@
-LN_S = @LN_S@
-LTLIBOBJS = @LTLIBOBJS@
-MAKEINFO = @MAKEINFO@
-MKDIR_P = @MKDIR_P@
-NMEDIT = @NMEDIT@
-OBJDUMP = @OBJDUMP@
-OBJEXT = @OBJEXT@
-PACKAGE = @PACKAGE@
-PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
-PACKAGE_NAME = @PACKAGE_NAME@
-PACKAGE_STRING = @PACKAGE_STRING@
-PACKAGE_TARNAME = @PACKAGE_TARNAME@
-PACKAGE_VERSION = @PACKAGE_VERSION@
-PATH_SEPARATOR = @PATH_SEPARATOR@
-PCRE_DATE = @PCRE_DATE@
-PCRE_MAJOR = @PCRE_MAJOR@
-PCRE_MINOR = @PCRE_MINOR@
-PCRE_PRERELEASE = @PCRE_PRERELEASE@
-RANLIB = @RANLIB@
-SED = @SED@
-SET_MAKE = @SET_MAKE@
-SHELL = @SHELL@
-STRIP = @STRIP@
-VERSION = @VERSION@
-abs_builddir = @abs_builddir@
-abs_srcdir = @abs_srcdir@
-abs_top_builddir = @abs_top_builddir@
-abs_top_srcdir = @abs_top_srcdir@
-ac_ct_CC = @ac_ct_CC@
-ac_ct_CXX = @ac_ct_CXX@
-ac_ct_F77 = @ac_ct_F77@
-am__include = @am__include@
-am__leading_dot = @am__leading_dot@
-am__quote = @am__quote@
-am__tar = @am__tar@
-am__untar = @am__untar@
-bindir = @bindir@
-build = @build@
-build_alias = @build_alias@
-build_cpu = @build_cpu@
-build_os = @build_os@
-build_vendor = @build_vendor@
-builddir = @builddir@
-datadir = @datadir@
-datarootdir = @datarootdir@
-docdir = @docdir@
-dvidir = @dvidir@
-exec_prefix = @exec_prefix@
-host = @host@
-host_alias = @host_alias@
-host_cpu = @host_cpu@
-host_os = @host_os@
-host_vendor = @host_vendor@
-htmldir = @htmldir@
-includedir = @includedir@
-infodir = @infodir@
-install_sh = @install_sh@
-libdir = @libdir@
-libexecdir = @libexecdir@
-localedir = @localedir@
-localstatedir = @localstatedir@
-mandir = @mandir@
-mkdir_p = @mkdir_p@
-oldincludedir = @oldincludedir@
-pcre_have_bits_type_traits = @pcre_have_bits_type_traits@
-pcre_have_long_long = @pcre_have_long_long@
-pcre_have_type_traits = @pcre_have_type_traits@
-pcre_have_ulong_long = @pcre_have_ulong_long@
-pdfdir = @pdfdir@
-prefix = @prefix@
-program_transform_name = @program_transform_name@
-psdir = @psdir@
-sbindir = @sbindir@
-sharedstatedir = @sharedstatedir@
-srcdir = @srcdir@
-sysconfdir = @sysconfdir@
-target_alias = @target_alias@
-top_builddir = @top_builddir@
-top_srcdir = @top_srcdir@
-dist_doc_DATA = \
- doc/pcre.txt \
- doc/pcre-config.txt \
- doc/pcregrep.txt \
- doc/pcretest.txt \
- AUTHORS \
- COPYING \
- ChangeLog \
- LICENCE \
- NEWS \
- README
-
-dist_html_DATA = \
- doc/html/index.html \
- doc/html/pcre.html \
- doc/html/pcre-config.html \
- doc/html/pcre_compile.html \
- doc/html/pcre_compile2.html \
- doc/html/pcre_config.html \
- doc/html/pcre_copy_named_substring.html \
- doc/html/pcre_copy_substring.html \
- doc/html/pcre_dfa_exec.html \
- doc/html/pcre_exec.html \
- doc/html/pcre_free_substring.html \
- doc/html/pcre_free_substring_list.html \
- doc/html/pcre_fullinfo.html \
- doc/html/pcre_get_named_substring.html \
- doc/html/pcre_get_stringnumber.html \
- doc/html/pcre_get_stringtable_entries.html \
- doc/html/pcre_get_substring.html \
- doc/html/pcre_get_substring_list.html \
- doc/html/pcre_info.html \
- doc/html/pcre_maketables.html \
- doc/html/pcre_refcount.html \
- doc/html/pcre_study.html \
- doc/html/pcre_version.html \
- doc/html/pcreapi.html \
- doc/html/pcrebuild.html \
- doc/html/pcrecallout.html \
- doc/html/pcrecompat.html \
- doc/html/pcregrep.html \
- doc/html/pcrematching.html \
- doc/html/pcrepartial.html \
- doc/html/pcrepattern.html \
- doc/html/pcreperform.html \
- doc/html/pcreposix.html \
- doc/html/pcreprecompile.html \
- doc/html/pcresample.html \
- doc/html/pcrestack.html \
- doc/html/pcresyntax.html \
- doc/html/pcretest.html
-
-pcrecpp_html = doc/html/pcrecpp.html
-dist_noinst_DATA = $(pcrecpp_html)
-@WITH_PCRE_CPP_TRUE@html_DATA = $(pcrecpp_html)
-
-# The Libtool libraries to install. We'll add to this later.
-lib_LTLIBRARIES = libpcre.la libpcreposix.la $(am__append_4)
-check_SCRIPTS =
-dist_noinst_SCRIPTS = RunTest RunGrepTest
-
-# Additional files to delete on 'make clean' and 'make maintainer-clean'.
-CLEANFILES = pcre_chartables.c testsavedregex teststderr testtry \
- testNinput
-MAINTAINERCLEANFILES = pcre.h.generic
-
-# Additional files to bundle with the distribution, over and above what
-# the Autotools include by default.
-
-# These files contain maintenance information
-
-# These files are used in the preparation of a release
-
-# These files are to do with building for Virtual Pascal
-
-# These files are usable versions of pcre.h and config.h that are distributed
-# for the benefit of people who are building PCRE manually, without the
-# Autotools support.
-
-# The pcre_printint.src file is #included by some source files, so it must be
-# distributed. The pcre_chartables.c.dist file is the default version of
-# pcre_chartables.c, used unless --enable-rebuild-chartables is specified.
-
-# PCRE demonstration program. No longer built automatcally. The point is that
-# the users should build it themselves. So just distribute the source.
-# noinst_PROGRAMS += pcredemo
-# pcredemo_SOURCES = pcredemo.c
-# pcredemo_LDADD = libpcre.la
-EXTRA_DIST = doc/perltest.txt NON-UNIX-USE HACKING PrepareRelease \
- CleanTxt Detrail 132html doc/index.html.src makevp.bat \
- makevp_c.txt makevp_l.txt pcregexp.pas pcre.h.generic \
- config.h.generic pcre_printint.src pcre_chartables.c.dist \
- RunTest.bat testdata/grepinput testdata/grepinput8 \
- testdata/grepinputv testdata/grepinputx testdata/greplist \
- testdata/grepoutput testdata/grepoutput8 testdata/grepoutputN \
- testdata/testinput1 testdata/testinput2 testdata/testinput3 \
- testdata/testinput4 testdata/testinput5 testdata/testinput6 \
- testdata/testinput7 testdata/testinput8 testdata/testinput9 \
- testdata/testinput10 testdata/testoutput1 testdata/testoutput2 \
- testdata/testoutput3 testdata/testoutput4 testdata/testoutput5 \
- testdata/testoutput6 testdata/testoutput7 testdata/testoutput8 \
- testdata/testoutput9 testdata/testoutput10 \
- testdata/wintestinput3 testdata/wintestoutput3 perltest.pl \
- pcredemo.c $(pcrecpp_man) cmake/COPYING-CMAKE-SCRIPTS \
- cmake/FindPackageHandleStandardArgs.cmake \
- cmake/FindReadline.cmake CMakeLists.txt config-cmake.h.in
-
-# These are the header files we'll install. We do not distribute pcre.h because
-# it is generated from pcre.h.in.
-nodist_include_HEADERS = pcre.h $(am__append_1)
-include_HEADERS = pcreposix.h $(am__append_2)
-bin_SCRIPTS = pcre-config
-@WITH_REBUILD_CHARTABLES_TRUE@dftables_SOURCES = dftables.c
-libpcre_la_SOURCES = \
- pcre_compile.c \
- pcre_config.c \
- pcre_dfa_exec.c \
- pcre_exec.c \
- pcre_fullinfo.c \
- pcre_get.c \
- pcre_globals.c \
- pcre_info.c \
- pcre_internal.h \
- pcre_maketables.c \
- pcre_newline.c \
- pcre_ord2utf8.c \
- pcre_refcount.c \
- pcre_study.c \
- pcre_tables.c \
- pcre_try_flipped.c \
- pcre_ucp_searchfuncs.c \
- pcre_valid_utf8.c \
- pcre_version.c \
- pcre_xclass.c \
- ucp.h \
- ucpinternal.h \
- ucptable.h
-
-nodist_libpcre_la_SOURCES = \
- pcre_chartables.c
-
-libpcre_la_LDFLAGS = $(EXTRA_LIBPCRE_LDFLAGS)
-libpcreposix_la_SOURCES = \
- pcreposix.c
-
-libpcreposix_la_LDFLAGS = $(EXTRA_LIBPCREPOSIX_LDFLAGS)
-libpcreposix_la_LIBADD = libpcre.la
-@WITH_PCRE_CPP_TRUE@libpcrecpp_la_SOURCES = \
-@WITH_PCRE_CPP_TRUE@ pcrecpp_internal.h \
-@WITH_PCRE_CPP_TRUE@ pcrecpp.cc \
-@WITH_PCRE_CPP_TRUE@ pcre_scanner.cc \
-@WITH_PCRE_CPP_TRUE@ pcre_stringpiece.cc
-
-@WITH_PCRE_CPP_TRUE@libpcrecpp_la_LDFLAGS = $(EXTRA_LIBPCRECPP_LDFLAGS)
-@WITH_PCRE_CPP_TRUE@libpcrecpp_la_LIBADD = libpcre.la
-@WITH_PCRE_CPP_TRUE@pcrecpp_unittest_SOURCES = pcrecpp_unittest.cc
-@WITH_PCRE_CPP_TRUE@pcrecpp_unittest_LDADD = libpcrecpp.la
-@WITH_PCRE_CPP_TRUE@pcre_scanner_unittest_SOURCES = pcre_scanner_unittest.cc
-@WITH_PCRE_CPP_TRUE@pcre_scanner_unittest_LDADD = libpcrecpp.la
-@WITH_PCRE_CPP_TRUE@pcre_stringpiece_unittest_SOURCES = pcre_stringpiece_unittest.cc
-@WITH_PCRE_CPP_TRUE@pcre_stringpiece_unittest_LDADD = libpcrecpp.la
-pcretest_SOURCES = pcretest.c
-pcretest_LDADD = libpcreposix.la
-pcregrep_SOURCES = pcregrep.c
-pcregrep_LDADD = libpcreposix.la
-
-# A PCRE user submitted the following addition, saying that it "will allow
-# anyone using the 'mingw32' compiler to simply type 'make pcre.dll' and get a
-# nice DLL for Windows use". (It is used by the pcre.dll target.)
-DLL_OBJS = pcre_compile.o pcre_config.o \
- pcre_dfa_exec.o pcre_exec.o pcre_fullinfo.o pcre_get.o \
- pcre_globals.o pcre_info.o pcre_maketables.o \
- pcre_newline.o pcre_ord2utf8.o pcre_refcount.o \
- pcre_study.o pcre_tables.o pcre_try_flipped.o \
- pcre_ucp_searchfuncs.o pcre_valid_utf8.o pcre_version.o \
- pcre_chartables.o \
- pcre_xclass.o
-
-
-# We have .pc files for pkg-config users.
-pkgconfigdir = $(libdir)/pkgconfig
-pkgconfig_DATA = libpcre.pc $(am__append_7)
-dist_man_MANS = \
- doc/pcre.3 \
- doc/pcre-config.1 \
- doc/pcre_compile.3 \
- doc/pcre_compile2.3 \
- doc/pcre_config.3 \
- doc/pcre_copy_named_substring.3 \
- doc/pcre_copy_substring.3 \
- doc/pcre_dfa_exec.3 \
- doc/pcre_exec.3 \
- doc/pcre_free_substring.3 \
- doc/pcre_free_substring_list.3 \
- doc/pcre_fullinfo.3 \
- doc/pcre_get_named_substring.3 \
- doc/pcre_get_stringnumber.3 \
- doc/pcre_get_stringtable_entries.3 \
- doc/pcre_get_substring.3 \
- doc/pcre_get_substring_list.3 \
- doc/pcre_info.3 \
- doc/pcre_maketables.3 \
- doc/pcre_refcount.3 \
- doc/pcre_study.3 \
- doc/pcre_version.3 \
- doc/pcreapi.3 \
- doc/pcrebuild.3 \
- doc/pcrecallout.3 \
- doc/pcrecompat.3 \
- doc/pcregrep.1 \
- doc/pcrematching.3 \
- doc/pcrepartial.3 \
- doc/pcrepattern.3 \
- doc/pcreperform.3 \
- doc/pcreposix.3 \
- doc/pcreprecompile.3 \
- doc/pcresample.3 \
- doc/pcrestack.3 \
- doc/pcresyntax.3 \
- doc/pcretest.1
-
-pcrecpp_man = doc/pcrecpp.3
-@WITH_PCRE_CPP_TRUE@man_MANS = $(pcrecpp_man)
-all: config.h
- $(MAKE) $(AM_MAKEFLAGS) all-am
-
-.SUFFIXES:
-.SUFFIXES: .c .cc .lo .o .obj
-am--refresh:
- @:
-$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
- @for dep in $?; do \
- case '$(am__configure_deps)' in \
- *$$dep*) \
- echo ' cd $(srcdir) && $(AUTOMAKE) --gnu '; \
- cd $(srcdir) && $(AUTOMAKE) --gnu \
- && exit 0; \
- exit 1;; \
- esac; \
- done; \
- echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \
- cd $(top_srcdir) && \
- $(AUTOMAKE) --gnu Makefile
-.PRECIOUS: Makefile
-Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
- @case '$?' in \
- *config.status*) \
- echo ' $(SHELL) ./config.status'; \
- $(SHELL) ./config.status;; \
- *) \
- echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \
- cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \
- esac;
-
-$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
- $(SHELL) ./config.status --recheck
-
-$(top_srcdir)/configure: $(am__configure_deps)
- cd $(srcdir) && $(AUTOCONF)
-$(ACLOCAL_M4): $(am__aclocal_m4_deps)
- cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
-
-config.h: stamp-h1
- @if test ! -f $@; then \
- rm -f stamp-h1; \
- $(MAKE) $(AM_MAKEFLAGS) stamp-h1; \
- else :; fi
-
-stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status
- @rm -f stamp-h1
- cd $(top_builddir) && $(SHELL) ./config.status config.h
-$(srcdir)/config.h.in: $(am__configure_deps)
- cd $(top_srcdir) && $(AUTOHEADER)
- rm -f stamp-h1
- touch $@
-
-distclean-hdr:
- -rm -f config.h stamp-h1
-libpcre.pc: $(top_builddir)/config.status $(srcdir)/libpcre.pc.in
- cd $(top_builddir) && $(SHELL) ./config.status $@
-libpcrecpp.pc: $(top_builddir)/config.status $(srcdir)/libpcrecpp.pc.in
- cd $(top_builddir) && $(SHELL) ./config.status $@
-pcre-config: $(top_builddir)/config.status $(srcdir)/pcre-config.in
- cd $(top_builddir) && $(SHELL) ./config.status $@
-pcre.h: $(top_builddir)/config.status $(srcdir)/pcre.h.in
- cd $(top_builddir) && $(SHELL) ./config.status $@
-pcre_stringpiece.h: $(top_builddir)/config.status $(srcdir)/pcre_stringpiece.h.in
- cd $(top_builddir) && $(SHELL) ./config.status $@
-pcrecpparg.h: $(top_builddir)/config.status $(srcdir)/pcrecpparg.h.in
- cd $(top_builddir) && $(SHELL) ./config.status $@
-install-libLTLIBRARIES: $(lib_LTLIBRARIES)
- @$(NORMAL_INSTALL)
- test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)"
- @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
- if test -f $$p; then \
- f=$(am__strip_dir) \
- echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \
- $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(libdir)/$$f"; \
- else :; fi; \
- done
-
-uninstall-libLTLIBRARIES:
- @$(NORMAL_UNINSTALL)
- @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
- p=$(am__strip_dir) \
- echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$p'"; \
- $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$p"; \
- done
-
-clean-libLTLIBRARIES:
- -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
- @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
- dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
- test "$$dir" != "$$p" || dir=.; \
- echo "rm -f \"$${dir}/so_locations\""; \
- rm -f "$${dir}/so_locations"; \
- done
-libpcre.la: $(libpcre_la_OBJECTS) $(libpcre_la_DEPENDENCIES)
- $(libpcre_la_LINK) -rpath $(libdir) $(libpcre_la_OBJECTS) $(libpcre_la_LIBADD) $(LIBS)
-libpcrecpp.la: $(libpcrecpp_la_OBJECTS) $(libpcrecpp_la_DEPENDENCIES)
- $(libpcrecpp_la_LINK) $(am_libpcrecpp_la_rpath) $(libpcrecpp_la_OBJECTS) $(libpcrecpp_la_LIBADD) $(LIBS)
-libpcreposix.la: $(libpcreposix_la_OBJECTS) $(libpcreposix_la_DEPENDENCIES)
- $(libpcreposix_la_LINK) -rpath $(libdir) $(libpcreposix_la_OBJECTS) $(libpcreposix_la_LIBADD) $(LIBS)
-install-binPROGRAMS: $(bin_PROGRAMS)
- @$(NORMAL_INSTALL)
- test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)"
- @list='$(bin_PROGRAMS)'; for p in $$list; do \
- p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
- if test -f $$p \
- || test -f $$p1 \
- ; then \
- f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
- echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(binPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(bindir)/$$f'"; \
- $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(binPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(bindir)/$$f" || exit 1; \
- else :; fi; \
- done
-
-uninstall-binPROGRAMS:
- @$(NORMAL_UNINSTALL)
- @list='$(bin_PROGRAMS)'; for p in $$list; do \
- f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
- echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \
- rm -f "$(DESTDIR)$(bindir)/$$f"; \
- done
-
-clean-binPROGRAMS:
- @list='$(bin_PROGRAMS)'; for p in $$list; do \
- f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
- echo " rm -f $$p $$f"; \
- rm -f $$p $$f ; \
- done
-
-clean-noinstPROGRAMS:
- @list='$(noinst_PROGRAMS)'; for p in $$list; do \
- f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
- echo " rm -f $$p $$f"; \
- rm -f $$p $$f ; \
- done
-dftables$(EXEEXT): $(dftables_OBJECTS) $(dftables_DEPENDENCIES)
- @rm -f dftables$(EXEEXT)
- $(LINK) $(dftables_OBJECTS) $(dftables_LDADD) $(LIBS)
-pcre_scanner_unittest$(EXEEXT): $(pcre_scanner_unittest_OBJECTS) $(pcre_scanner_unittest_DEPENDENCIES)
- @rm -f pcre_scanner_unittest$(EXEEXT)
- $(CXXLINK) $(pcre_scanner_unittest_OBJECTS) $(pcre_scanner_unittest_LDADD) $(LIBS)
-pcre_stringpiece_unittest$(EXEEXT): $(pcre_stringpiece_unittest_OBJECTS) $(pcre_stringpiece_unittest_DEPENDENCIES)
- @rm -f pcre_stringpiece_unittest$(EXEEXT)
- $(CXXLINK) $(pcre_stringpiece_unittest_OBJECTS) $(pcre_stringpiece_unittest_LDADD) $(LIBS)
-pcrecpp_unittest$(EXEEXT): $(pcrecpp_unittest_OBJECTS) $(pcrecpp_unittest_DEPENDENCIES)
- @rm -f pcrecpp_unittest$(EXEEXT)
- $(CXXLINK) $(pcrecpp_unittest_OBJECTS) $(pcrecpp_unittest_LDADD) $(LIBS)
-pcregrep$(EXEEXT): $(pcregrep_OBJECTS) $(pcregrep_DEPENDENCIES)
- @rm -f pcregrep$(EXEEXT)
- $(LINK) $(pcregrep_OBJECTS) $(pcregrep_LDADD) $(LIBS)
-pcretest$(EXEEXT): $(pcretest_OBJECTS) $(pcretest_DEPENDENCIES)
- @rm -f pcretest$(EXEEXT)
- $(LINK) $(pcretest_OBJECTS) $(pcretest_LDADD) $(LIBS)
-install-binSCRIPTS: $(bin_SCRIPTS)
- @$(NORMAL_INSTALL)
- test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)"
- @list='$(bin_SCRIPTS)'; for p in $$list; do \
- if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
- if test -f $$d$$p; then \
- f=`echo "$$p" | sed 's|^.*/||;$(transform)'`; \
- echo " $(binSCRIPT_INSTALL) '$$d$$p' '$(DESTDIR)$(bindir)/$$f'"; \
- $(binSCRIPT_INSTALL) "$$d$$p" "$(DESTDIR)$(bindir)/$$f"; \
- else :; fi; \
- done
-
-uninstall-binSCRIPTS:
- @$(NORMAL_UNINSTALL)
- @list='$(bin_SCRIPTS)'; for p in $$list; do \
- f=`echo "$$p" | sed 's|^.*/||;$(transform)'`; \
- echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \
- rm -f "$(DESTDIR)$(bindir)/$$f"; \
- done
-
-mostlyclean-compile:
- -rm -f *.$(OBJEXT)
-
-distclean-compile:
- -rm -f *.tab.c
-
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dftables.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre_chartables.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre_compile.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre_config.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre_dfa_exec.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre_exec.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre_fullinfo.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre_get.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre_globals.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre_info.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre_maketables.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre_newline.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre_ord2utf8.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre_refcount.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre_scanner.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre_scanner_unittest.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre_stringpiece.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre_stringpiece_unittest.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre_study.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre_tables.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre_try_flipped.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre_ucp_searchfuncs.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre_valid_utf8.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre_version.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre_xclass.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcrecpp.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcrecpp_unittest.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcregrep.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcreposix.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcretest.Po@am__quote@
-
-.c.o:
-@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(COMPILE) -c $<
-
-.c.obj:
-@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
-
-.c.lo:
-@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
-
-.cc.o:
-@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
-@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $<
-
-.cc.obj:
-@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
-@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
-
-.cc.lo:
-@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
-@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $<
-
-mostlyclean-libtool:
- -rm -f *.lo
-
-clean-libtool:
- -rm -rf .libs _libs
-
-distclean-libtool:
- -rm -f libtool
-install-man1: $(man1_MANS) $(man_MANS)
- @$(NORMAL_INSTALL)
- test -z "$(man1dir)" || $(MKDIR_P) "$(DESTDIR)$(man1dir)"
- @list='$(man1_MANS) $(dist_man1_MANS) $(nodist_man1_MANS)'; \
- l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
- for i in $$l2; do \
- case "$$i" in \
- *.1*) list="$$list $$i" ;; \
- esac; \
- done; \
- for i in $$list; do \
- if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
- else file=$$i; fi; \
- ext=`echo $$i | sed -e 's/^.*\\.//'`; \
- case "$$ext" in \
- 1*) ;; \
- *) ext='1' ;; \
- esac; \
- inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
- inst=`echo $$inst | sed -e 's/^.*\///'`; \
- inst=`echo $$inst | sed '$(transform)'`.$$ext; \
- echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \
- $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst"; \
- done
-uninstall-man1:
- @$(NORMAL_UNINSTALL)
- @list='$(man1_MANS) $(dist_man1_MANS) $(nodist_man1_MANS)'; \
- l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
- for i in $$l2; do \
- case "$$i" in \
- *.1*) list="$$list $$i" ;; \
- esac; \
- done; \
- for i in $$list; do \
- ext=`echo $$i | sed -e 's/^.*\\.//'`; \
- case "$$ext" in \
- 1*) ;; \
- *) ext='1' ;; \
- esac; \
- inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
- inst=`echo $$inst | sed -e 's/^.*\///'`; \
- inst=`echo $$inst | sed '$(transform)'`.$$ext; \
- echo " rm -f '$(DESTDIR)$(man1dir)/$$inst'"; \
- rm -f "$(DESTDIR)$(man1dir)/$$inst"; \
- done
-install-man3: $(man3_MANS) $(man_MANS)
- @$(NORMAL_INSTALL)
- test -z "$(man3dir)" || $(MKDIR_P) "$(DESTDIR)$(man3dir)"
- @list='$(man3_MANS) $(dist_man3_MANS) $(nodist_man3_MANS)'; \
- l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
- for i in $$l2; do \
- case "$$i" in \
- *.3*) list="$$list $$i" ;; \
- esac; \
- done; \
- for i in $$list; do \
- if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
- else file=$$i; fi; \
- ext=`echo $$i | sed -e 's/^.*\\.//'`; \
- case "$$ext" in \
- 3*) ;; \
- *) ext='3' ;; \
- esac; \
- inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
- inst=`echo $$inst | sed -e 's/^.*\///'`; \
- inst=`echo $$inst | sed '$(transform)'`.$$ext; \
- echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man3dir)/$$inst'"; \
- $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man3dir)/$$inst"; \
- done
-uninstall-man3:
- @$(NORMAL_UNINSTALL)
- @list='$(man3_MANS) $(dist_man3_MANS) $(nodist_man3_MANS)'; \
- l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
- for i in $$l2; do \
- case "$$i" in \
- *.3*) list="$$list $$i" ;; \
- esac; \
- done; \
- for i in $$list; do \
- ext=`echo $$i | sed -e 's/^.*\\.//'`; \
- case "$$ext" in \
- 3*) ;; \
- *) ext='3' ;; \
- esac; \
- inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
- inst=`echo $$inst | sed -e 's/^.*\///'`; \
- inst=`echo $$inst | sed '$(transform)'`.$$ext; \
- echo " rm -f '$(DESTDIR)$(man3dir)/$$inst'"; \
- rm -f "$(DESTDIR)$(man3dir)/$$inst"; \
- done
-install-dist_docDATA: $(dist_doc_DATA)
- @$(NORMAL_INSTALL)
- test -z "$(docdir)" || $(MKDIR_P) "$(DESTDIR)$(docdir)"
- @list='$(dist_doc_DATA)'; for p in $$list; do \
- if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
- f=$(am__strip_dir) \
- echo " $(dist_docDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(docdir)/$$f'"; \
- $(dist_docDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(docdir)/$$f"; \
- done
-
-uninstall-dist_docDATA:
- @$(NORMAL_UNINSTALL)
- @list='$(dist_doc_DATA)'; for p in $$list; do \
- f=$(am__strip_dir) \
- echo " rm -f '$(DESTDIR)$(docdir)/$$f'"; \
- rm -f "$(DESTDIR)$(docdir)/$$f"; \
- done
-install-dist_htmlDATA: $(dist_html_DATA)
- @$(NORMAL_INSTALL)
- test -z "$(htmldir)" || $(MKDIR_P) "$(DESTDIR)$(htmldir)"
- @list='$(dist_html_DATA)'; for p in $$list; do \
- if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
- f=$(am__strip_dir) \
- echo " $(dist_htmlDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(htmldir)/$$f'"; \
- $(dist_htmlDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(htmldir)/$$f"; \
- done
-
-uninstall-dist_htmlDATA:
- @$(NORMAL_UNINSTALL)
- @list='$(dist_html_DATA)'; for p in $$list; do \
- f=$(am__strip_dir) \
- echo " rm -f '$(DESTDIR)$(htmldir)/$$f'"; \
- rm -f "$(DESTDIR)$(htmldir)/$$f"; \
- done
-install-htmlDATA: $(html_DATA)
- @$(NORMAL_INSTALL)
- test -z "$(htmldir)" || $(MKDIR_P) "$(DESTDIR)$(htmldir)"
- @list='$(html_DATA)'; for p in $$list; do \
- if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
- f=$(am__strip_dir) \
- echo " $(htmlDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(htmldir)/$$f'"; \
- $(htmlDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(htmldir)/$$f"; \
- done
-
-uninstall-htmlDATA:
- @$(NORMAL_UNINSTALL)
- @list='$(html_DATA)'; for p in $$list; do \
- f=$(am__strip_dir) \
- echo " rm -f '$(DESTDIR)$(htmldir)/$$f'"; \
- rm -f "$(DESTDIR)$(htmldir)/$$f"; \
- done
-install-pkgconfigDATA: $(pkgconfig_DATA)
- @$(NORMAL_INSTALL)
- test -z "$(pkgconfigdir)" || $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)"
- @list='$(pkgconfig_DATA)'; for p in $$list; do \
- if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
- f=$(am__strip_dir) \
- echo " $(pkgconfigDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(pkgconfigdir)/$$f'"; \
- $(pkgconfigDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(pkgconfigdir)/$$f"; \
- done
-
-uninstall-pkgconfigDATA:
- @$(NORMAL_UNINSTALL)
- @list='$(pkgconfig_DATA)'; for p in $$list; do \
- f=$(am__strip_dir) \
- echo " rm -f '$(DESTDIR)$(pkgconfigdir)/$$f'"; \
- rm -f "$(DESTDIR)$(pkgconfigdir)/$$f"; \
- done
-install-includeHEADERS: $(include_HEADERS)
- @$(NORMAL_INSTALL)
- test -z "$(includedir)" || $(MKDIR_P) "$(DESTDIR)$(includedir)"
- @list='$(include_HEADERS)'; for p in $$list; do \
- if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
- f=$(am__strip_dir) \
- echo " $(includeHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(includedir)/$$f'"; \
- $(includeHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(includedir)/$$f"; \
- done
-
-uninstall-includeHEADERS:
- @$(NORMAL_UNINSTALL)
- @list='$(include_HEADERS)'; for p in $$list; do \
- f=$(am__strip_dir) \
- echo " rm -f '$(DESTDIR)$(includedir)/$$f'"; \
- rm -f "$(DESTDIR)$(includedir)/$$f"; \
- done
-install-nodist_includeHEADERS: $(nodist_include_HEADERS)
- @$(NORMAL_INSTALL)
- test -z "$(includedir)" || $(MKDIR_P) "$(DESTDIR)$(includedir)"
- @list='$(nodist_include_HEADERS)'; for p in $$list; do \
- if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
- f=$(am__strip_dir) \
- echo " $(nodist_includeHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(includedir)/$$f'"; \
- $(nodist_includeHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(includedir)/$$f"; \
- done
-
-uninstall-nodist_includeHEADERS:
- @$(NORMAL_UNINSTALL)
- @list='$(nodist_include_HEADERS)'; for p in $$list; do \
- f=$(am__strip_dir) \
- echo " rm -f '$(DESTDIR)$(includedir)/$$f'"; \
- rm -f "$(DESTDIR)$(includedir)/$$f"; \
- done
-
-ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
- list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
- unique=`for i in $$list; do \
- if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
- done | \
- $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
- END { if (nonempty) { for (i in files) print i; }; }'`; \
- mkid -fID $$unique
-tags: TAGS
-
-TAGS: $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
- $(TAGS_FILES) $(LISP)
- tags=; \
- here=`pwd`; \
- list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
- unique=`for i in $$list; do \
- if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
- done | \
- $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
- END { if (nonempty) { for (i in files) print i; }; }'`; \
- if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
- test -n "$$unique" || unique=$$empty_fix; \
- $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
- $$tags $$unique; \
- fi
-ctags: CTAGS
-CTAGS: $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
- $(TAGS_FILES) $(LISP)
- tags=; \
- list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
- unique=`for i in $$list; do \
- if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
- done | \
- $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
- END { if (nonempty) { for (i in files) print i; }; }'`; \
- test -z "$(CTAGS_ARGS)$$tags$$unique" \
- || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
- $$tags $$unique
-
-GTAGS:
- here=`$(am__cd) $(top_builddir) && pwd` \
- && cd $(top_srcdir) \
- && gtags -i $(GTAGS_ARGS) $$here
-
-distclean-tags:
- -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
-
-check-TESTS: $(TESTS)
- @failed=0; all=0; xfail=0; xpass=0; skip=0; ws='[ ]'; \
- srcdir=$(srcdir); export srcdir; \
- list=' $(TESTS) '; \
- if test -n "$$list"; then \
- for tst in $$list; do \
- if test -f ./$$tst; then dir=./; \
- elif test -f $$tst; then dir=; \
- else dir="$(srcdir)/"; fi; \
- if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \
- all=`expr $$all + 1`; \
- case " $(XFAIL_TESTS) " in \
- *$$ws$$tst$$ws*) \
- xpass=`expr $$xpass + 1`; \
- failed=`expr $$failed + 1`; \
- echo "XPASS: $$tst"; \
- ;; \
- *) \
- echo "PASS: $$tst"; \
- ;; \
- esac; \
- elif test $$? -ne 77; then \
- all=`expr $$all + 1`; \
- case " $(XFAIL_TESTS) " in \
- *$$ws$$tst$$ws*) \
- xfail=`expr $$xfail + 1`; \
- echo "XFAIL: $$tst"; \
- ;; \
- *) \
- failed=`expr $$failed + 1`; \
- echo "FAIL: $$tst"; \
- ;; \
- esac; \
- else \
- skip=`expr $$skip + 1`; \
- echo "SKIP: $$tst"; \
- fi; \
- done; \
- if test "$$failed" -eq 0; then \
- if test "$$xfail" -eq 0; then \
- banner="All $$all tests passed"; \
- else \
- banner="All $$all tests behaved as expected ($$xfail expected failures)"; \
- fi; \
- else \
- if test "$$xpass" -eq 0; then \
- banner="$$failed of $$all tests failed"; \
- else \
- banner="$$failed of $$all tests did not behave as expected ($$xpass unexpected passes)"; \
- fi; \
- fi; \
- dashes="$$banner"; \
- skipped=""; \
- if test "$$skip" -ne 0; then \
- skipped="($$skip tests were not run)"; \
- test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \
- dashes="$$skipped"; \
- fi; \
- report=""; \
- if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \
- report="Please report to $(PACKAGE_BUGREPORT)"; \
- test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \
- dashes="$$report"; \
- fi; \
- dashes=`echo "$$dashes" | sed s/./=/g`; \
- echo "$$dashes"; \
- echo "$$banner"; \
- test -z "$$skipped" || echo "$$skipped"; \
- test -z "$$report" || echo "$$report"; \
- echo "$$dashes"; \
- test "$$failed" -eq 0; \
- else :; fi
-
-distdir: $(DISTFILES)
- $(am__remove_distdir)
- test -d $(distdir) || mkdir $(distdir)
- @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
- topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
- list='$(DISTFILES)'; \
- dist_files=`for file in $$list; do echo $$file; done | \
- sed -e "s|^$$srcdirstrip/||;t" \
- -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
- case $$dist_files in \
- */*) $(MKDIR_P) `echo "$$dist_files" | \
- sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
- sort -u` ;; \
- esac; \
- for file in $$dist_files; do \
- if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
- if test -d $$d/$$file; then \
- dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
- if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
- cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
- fi; \
- cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
- else \
- test -f $(distdir)/$$file \
- || cp -p $$d/$$file $(distdir)/$$file \
- || exit 1; \
- fi; \
- done
- -find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -o \
- ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
- ! -type d ! -perm -400 -exec chmod a+r {} \; -o \
- ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \
- || chmod -R a+r $(distdir)
-dist-gzip: distdir
- tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
- $(am__remove_distdir)
-dist-bzip2: distdir
- tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2
- $(am__remove_distdir)
-
-dist-lzma: distdir
- tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma
- $(am__remove_distdir)
-
-dist-tarZ: distdir
- tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
- $(am__remove_distdir)
-
-dist-shar: distdir
- shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
- $(am__remove_distdir)
-dist-zip: distdir
- -rm -f $(distdir).zip
- zip -rq $(distdir).zip $(distdir)
- $(am__remove_distdir)
-
-dist dist-all: distdir
- tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
- tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2
- -rm -f $(distdir).zip
- zip -rq $(distdir).zip $(distdir)
- $(am__remove_distdir)
-
-# This target untars the dist file and tries a VPATH configuration. Then
-# it guarantees that the distribution is self-contained by making another
-# tarfile.
-distcheck: dist
- case '$(DIST_ARCHIVES)' in \
- *.tar.gz*) \
- GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(am__untar) ;;\
- *.tar.bz2*) \
- bunzip2 -c $(distdir).tar.bz2 | $(am__untar) ;;\
- *.tar.lzma*) \
- unlzma -c $(distdir).tar.lzma | $(am__untar) ;;\
- *.tar.Z*) \
- uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
- *.shar.gz*) \
- GZIP=$(GZIP_ENV) gunzip -c $(distdir).shar.gz | unshar ;;\
- *.zip*) \
- unzip $(distdir).zip ;;\
- esac
- chmod -R a-w $(distdir); chmod a+w $(distdir)
- mkdir $(distdir)/_build
- mkdir $(distdir)/_inst
- chmod a-w $(distdir)
- dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
- && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
- && cd $(distdir)/_build \
- && ../configure --srcdir=.. --prefix="$$dc_install_base" \
- $(DISTCHECK_CONFIGURE_FLAGS) \
- && $(MAKE) $(AM_MAKEFLAGS) \
- && $(MAKE) $(AM_MAKEFLAGS) dvi \
- && $(MAKE) $(AM_MAKEFLAGS) check \
- && $(MAKE) $(AM_MAKEFLAGS) install \
- && $(MAKE) $(AM_MAKEFLAGS) installcheck \
- && $(MAKE) $(AM_MAKEFLAGS) uninstall \
- && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \
- distuninstallcheck \
- && chmod -R a-w "$$dc_install_base" \
- && ({ \
- (cd ../.. && umask 077 && mkdir "$$dc_destdir") \
- && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \
- && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \
- && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \
- distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \
- } || { rm -rf "$$dc_destdir"; exit 1; }) \
- && rm -rf "$$dc_destdir" \
- && $(MAKE) $(AM_MAKEFLAGS) dist \
- && rm -rf $(DIST_ARCHIVES) \
- && $(MAKE) $(AM_MAKEFLAGS) distcleancheck
- $(am__remove_distdir)
- @(echo "$(distdir) archives ready for distribution: "; \
- list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
- sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x'
-distuninstallcheck:
- @cd $(distuninstallcheck_dir) \
- && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \
- || { echo "ERROR: files left after uninstall:" ; \
- if test -n "$(DESTDIR)"; then \
- echo " (check DESTDIR support)"; \
- fi ; \
- $(distuninstallcheck_listfiles) ; \
- exit 1; } >&2
-distcleancheck: distclean
- @if test '$(srcdir)' = . ; then \
- echo "ERROR: distcleancheck can only run from a VPATH build" ; \
- exit 1 ; \
- fi
- @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \
- || { echo "ERROR: files left in build directory after distclean:" ; \
- $(distcleancheck_listfiles) ; \
- exit 1; } >&2
-check-am: all-am
- $(MAKE) $(AM_MAKEFLAGS) $(check_SCRIPTS)
- $(MAKE) $(AM_MAKEFLAGS) check-TESTS
-check: check-am
-all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(SCRIPTS) $(MANS) $(DATA) \
- $(HEADERS) config.h
-install-binPROGRAMS: install-libLTLIBRARIES
-
-installdirs:
- for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man3dir)" "$(DESTDIR)$(docdir)" "$(DESTDIR)$(htmldir)" "$(DESTDIR)$(htmldir)" "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(includedir)" "$(DESTDIR)$(includedir)"; do \
- test -z "$$dir" || $(MKDIR_P) "$$dir"; \
- done
-install: install-am
-install-exec: install-exec-am
-install-data: install-data-am
-uninstall: uninstall-am
-
-install-am: all-am
- @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
-
-installcheck: installcheck-am
-install-strip:
- $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
- install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
- `test -z '$(STRIP)' || \
- echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
-mostlyclean-generic:
-
-clean-generic:
- -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
-
-distclean-generic:
- -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-
-maintainer-clean-generic:
- @echo "This command is intended for maintainers to use"
- @echo "it deletes files that may require special tools to rebuild."
- -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
-clean: clean-am
-
-clean-am: clean-binPROGRAMS clean-generic clean-libLTLIBRARIES \
- clean-libtool clean-noinstPROGRAMS mostlyclean-am
-
-distclean: distclean-am
- -rm -f $(am__CONFIG_DISTCLEAN_FILES)
- -rm -rf ./$(DEPDIR)
- -rm -f Makefile
-distclean-am: clean-am distclean-compile distclean-generic \
- distclean-hdr distclean-libtool distclean-tags
-
-dvi: dvi-am
-
-dvi-am:
-
-html: html-am
-
-info: info-am
-
-info-am:
-
-install-data-am: install-dist_docDATA install-dist_htmlDATA \
- install-htmlDATA install-includeHEADERS install-man \
- install-nodist_includeHEADERS install-pkgconfigDATA
-
-install-dvi: install-dvi-am
-
-install-exec-am: install-binPROGRAMS install-binSCRIPTS \
- install-libLTLIBRARIES
-
-install-html: install-html-am
-
-install-info: install-info-am
-
-install-man: install-man1 install-man3
-
-install-pdf: install-pdf-am
-
-install-ps: install-ps-am
-
-installcheck-am:
-
-maintainer-clean: maintainer-clean-am
- -rm -f $(am__CONFIG_DISTCLEAN_FILES)
- -rm -rf $(top_srcdir)/autom4te.cache
- -rm -rf ./$(DEPDIR)
- -rm -f Makefile
-maintainer-clean-am: distclean-am maintainer-clean-generic
-
-mostlyclean: mostlyclean-am
-
-mostlyclean-am: mostlyclean-compile mostlyclean-generic \
- mostlyclean-libtool
-
-pdf: pdf-am
-
-pdf-am:
-
-ps: ps-am
-
-ps-am:
-
-uninstall-am: uninstall-binPROGRAMS uninstall-binSCRIPTS \
- uninstall-dist_docDATA uninstall-dist_htmlDATA \
- uninstall-htmlDATA uninstall-includeHEADERS \
- uninstall-libLTLIBRARIES uninstall-man \
- uninstall-nodist_includeHEADERS uninstall-pkgconfigDATA
-
-uninstall-man: uninstall-man1 uninstall-man3
-
-.MAKE: install-am install-strip
-
-.PHONY: CTAGS GTAGS all all-am am--refresh check check-TESTS check-am \
- clean clean-binPROGRAMS clean-generic clean-libLTLIBRARIES \
- clean-libtool clean-noinstPROGRAMS ctags dist dist-all \
- dist-bzip2 dist-gzip dist-lzma dist-shar dist-tarZ dist-zip \
- distcheck distclean distclean-compile distclean-generic \
- distclean-hdr distclean-libtool distclean-tags distcleancheck \
- distdir distuninstallcheck dvi dvi-am html html-am info \
- info-am install install-am install-binPROGRAMS \
- install-binSCRIPTS install-data install-data-am \
- install-dist_docDATA install-dist_htmlDATA install-dvi \
- install-dvi-am install-exec install-exec-am install-html \
- install-html-am install-htmlDATA install-includeHEADERS \
- install-info install-info-am install-libLTLIBRARIES \
- install-man install-man1 install-man3 \
- install-nodist_includeHEADERS install-pdf install-pdf-am \
- install-pkgconfigDATA install-ps install-ps-am install-strip \
- installcheck installcheck-am installdirs maintainer-clean \
- maintainer-clean-generic mostlyclean mostlyclean-compile \
- mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
- tags uninstall uninstall-am uninstall-binPROGRAMS \
- uninstall-binSCRIPTS uninstall-dist_docDATA \
- uninstall-dist_htmlDATA uninstall-htmlDATA \
- uninstall-includeHEADERS uninstall-libLTLIBRARIES \
- uninstall-man uninstall-man1 uninstall-man3 \
- uninstall-nodist_includeHEADERS uninstall-pkgconfigDATA
-
-
-pcre.h.generic: configure.ac
- rm -f $@
- cp -p pcre.h $@
-
-@WITH_REBUILD_CHARTABLES_TRUE@pcre_chartables.c: dftables$(EXEEXT)
-@WITH_REBUILD_CHARTABLES_TRUE@ ./dftables$(EXEEXT) $@
-
-@WITH_REBUILD_CHARTABLES_FALSE@pcre_chartables.c: $(srcdir)/pcre_chartables.c.dist
-@WITH_REBUILD_CHARTABLES_FALSE@ rm -f $@
-@WITH_REBUILD_CHARTABLES_FALSE@ $(LN_S) $(srcdir)/pcre_chartables.c.dist $@
-
-# A compatibility line, the old build system worked with 'make test'
-test: check ;
-
-# A PCRE user submitted the following addition, saying that it "will allow
-# anyone using the 'mingw32' compiler to simply type 'make pcre.dll' and get a
-# nice DLL for Windows use".
-pcre.dll: $(DLL_OBJS)
- $(CC) -shared -o pcre.dll -Wl,"--strip-all" -Wl,"--export-all-symbols" $(DLL_OBJS)
-# Tell versions [3.59,3.63) of GNU make to not export all variables.
-# Otherwise a system limit (for SysV at least) may be exceeded.
-.NOEXPORT:
diff --git a/crawl-ref/source/util/pcre/NEWS b/crawl-ref/source/util/pcre/NEWS
deleted file mode 100644
index affe6ea99f..0000000000
--- a/crawl-ref/source/util/pcre/NEWS
+++ /dev/null
@@ -1,416 +0,0 @@
-News about PCRE releases
-------------------------
-
-
-Release 7.7 07-May-08
----------------------
-
-This is once again mainly a bug-fix release, but there are a couple of new
-features.
-
-
-Release 7.6 28-Jan-08
----------------------
-
-The main reason for having this release so soon after 7.5 is because it fixes a
-potential buffer overflow problem in pcre_compile() when run in UTF-8 mode. In
-addition, the CMake configuration files have been brought up to date.
-
-
-Release 7.5 10-Jan-08
----------------------
-
-This is mainly a bug-fix release. However the ability to link pcregrep with
-libz or libbz2 and the ability to link pcretest with libreadline have been
-added. Also the --line-offsets and --file-offsets options were added to
-pcregrep.
-
-
-Release 7.4 21-Sep-07
----------------------
-
-The only change of specification is the addition of options to control whether
-\R matches any Unicode line ending (the default) or just CR, LF, and CRLF.
-Otherwise, the changes are bug fixes and a refactoring to reduce the number of
-relocations needed in a shared library. There have also been some documentation
-updates, in particular, some more information about using CMake to build PCRE
-has been added to the NON-UNIX-USE file.
-
-
-Release 7.3 28-Aug-07
----------------------
-
-Most changes are bug fixes. Some that are not:
-
-1. There is some support for Perl 5.10's experimental "backtracking control
- verbs" such as (*PRUNE).
-
-2. UTF-8 checking is now as per RFC 3629 instead of RFC 2279; this is more
- restrictive in the strings it accepts.
-
-3. Checking for potential integer overflow has been made more dynamic, and as a
- consequence there is no longer a hard limit on the size of a subpattern that
- has a limited repeat count.
-
-4. When CRLF is a valid line-ending sequence, pcre_exec() and pcre_dfa_exec()
- no longer advance by two characters instead of one when an unanchored match
- fails at CRLF if there are explicit CR or LF matches within the pattern.
- This gets rid of some anomalous effects that previously occurred.
-
-5. Some PCRE-specific settings for varying the newline options at the start of
- a pattern have been added.
-
-
-Release 7.2 19-Jun-07
----------------------
-
-WARNING: saved patterns that were compiled by earlier versions of PCRE must be
-recompiled for use with 7.2 (necessitated by the addition of \K, \h, \H, \v,
-and \V).
-
-Correction to the notes for 7.1: the note about shared libraries for Windows is
-wrong. Previously, three libraries were built, but each could function
-independently. For example, the pcreposix library also included all the
-functions from the basic pcre library. The change is that the three libraries
-are no longer independent. They are like the Unix libraries. To use the
-pcreposix functions, for example, you need to link with both the pcreposix and
-the basic pcre library.
-
-Some more features from Perl 5.10 have been added:
-
- (?-n) and (?+n) relative references for recursion and subroutines.
-
- (?(-n) and (?(+n) relative references as conditions.
-
- \k{name} and \g{name} are synonyms for \k<name>.
-
- \K to reset the start of the matched string; for example, (foo)\Kbar
- matches bar preceded by foo, but only sets bar as the matched string.
-
- (?| introduces a group where the capturing parentheses in each alternative
- start from the same number; for example, (?|(abc)|(xyz)) sets capturing
- parentheses number 1 in both cases.
-
- \h, \H, \v, \V match horizontal and vertical whitespace, respectively.
-
-
-Release 7.1 24-Apr-07
----------------------
-
-There is only one new feature in this release: a linebreak setting of
-PCRE_NEWLINE_ANYCRLF. It is a cut-down version of PCRE_NEWLINE_ANY, which
-recognizes only CRLF, CR, and LF as linebreaks.
-
-A few bugs are fixed (see ChangeLog for details), but the major change is a
-complete re-implementation of the build system. This now has full Autotools
-support and so is now "standard" in some sense. It should help with compiling
-PCRE in a wide variety of environments.
-
-NOTE: when building shared libraries for Windows, three dlls are now built,
-called libpcre, libpcreposix, and libpcrecpp. Previously, everything was
-included in a single dll.
-
-Another important change is that the dftables auxiliary program is no longer
-compiled and run at "make" time by default. Instead, a default set of character
-tables (assuming ASCII coding) is used. If you want to use dftables to generate
-the character tables as previously, add --enable-rebuild-chartables to the
-"configure" command. You must do this if you are compiling PCRE to run on a
-system that uses EBCDIC code.
-
-There is a discussion about character tables in the README file. The default is
-not to use dftables so that that there is no problem when cross-compiling.
-
-
-Release 7.0 19-Dec-06
----------------------
-
-This release has a new major number because there have been some internal
-upheavals to facilitate the addition of new optimizations and other facilities,
-and to make subsequent maintenance and extension easier. Compilation is likely
-to be a bit slower, but there should be no major effect on runtime performance.
-Previously compiled patterns are NOT upwards compatible with this release. If
-you have saved compiled patterns from a previous release, you will have to
-re-compile them. Important changes that are visible to users are:
-
-1. The Unicode property tables have been updated to Unicode 5.0.0, which adds
- some more scripts.
-
-2. The option PCRE_NEWLINE_ANY causes PCRE to recognize any Unicode newline
- sequence as a newline.
-
-3. The \R escape matches a single Unicode newline sequence as a single unit.
-
-4. New features that will appear in Perl 5.10 are now in PCRE. These include
- alternative Perl syntax for named parentheses, and Perl syntax for
- recursion.
-
-5. The C++ wrapper interface has been extended by the addition of a
- QuoteMeta function and the ability to allow copy construction and
- assignment.
-
-For a complete list of changes, see the ChangeLog file.
-
-
-Release 6.7 04-Jul-06
----------------------
-
-The main additions to this release are the ability to use the same name for
-multiple sets of parentheses, and support for CRLF line endings in both the
-library and pcregrep (and in pcretest for testing).
-
-Thanks to Ian Taylor, the stack usage for many kinds of pattern has been
-significantly reduced for certain subject strings.
-
-
-Release 6.5 01-Feb-06
----------------------
-
-Important changes in this release:
-
-1. A number of new features have been added to pcregrep.
-
-2. The Unicode property tables have been updated to Unicode 4.1.0, and the
- supported properties have been extended with script names such as "Arabic",
- and the derived properties "Any" and "L&". This has necessitated a change to
- the interal format of compiled patterns. Any saved compiled patterns that
- use \p or \P must be recompiled.
-
-3. The specification of recursion in patterns has been changed so that all
- recursive subpatterns are automatically treated as atomic groups. Thus, for
- example, (?R) is treated as if it were (?>(?R)). This is necessary because
- otherwise there are situations where recursion does not work.
-
-See the ChangeLog for a complete list of changes, which include a number of bug
-fixes and tidies.
-
-
-Release 6.0 07-Jun-05
----------------------
-
-The release number has been increased to 6.0 because of the addition of several
-major new pieces of functionality.
-
-A new function, pcre_dfa_exec(), which implements pattern matching using a DFA
-algorithm, has been added. This has a number of advantages for certain cases,
-though it does run more slowly, and lacks the ability to capture substrings. On
-the other hand, it does find all matches, not just the first, and it works
-better for partial matching. The pcrematching man page discusses the
-differences.
-
-The pcretest program has been enhanced so that it can make use of the new
-pcre_dfa_exec() matching function and the extra features it provides.
-
-The distribution now includes a C++ wrapper library. This is built
-automatically if a C++ compiler is found. The pcrecpp man page discusses this
-interface.
-
-The code itself has been re-organized into many more files, one for each
-function, so it no longer requires everything to be linked in when static
-linkage is used. As a consequence, some internal functions have had to have
-their names exposed. These functions all have names starting with _pcre_. They
-are undocumented, and are not intended for use by outside callers.
-
-The pcregrep program has been enhanced with new functionality such as
-multiline-matching and options for output more matching context. See the
-ChangeLog for a complete list of changes to the library and the utility
-programs.
-
-
-Release 5.0 13-Sep-04
----------------------
-
-The licence under which PCRE is released has been changed to the more
-conventional "BSD" licence.
-
-In the code, some bugs have been fixed, and there are also some major changes
-in this release (which is why I've increased the number to 5.0). Some changes
-are internal rearrangements, and some provide a number of new facilities. The
-new features are:
-
-1. There's an "automatic callout" feature that inserts callouts before every
- item in the regex, and there's a new callout field that gives the position
- in the pattern - useful for debugging and tracing.
-
-2. The extra_data structure can now be used to pass in a set of character
- tables at exec time. This is useful if compiled regex are saved and re-used
- at a later time when the tables may not be at the same address. If the
- default internal tables are used, the pointer saved with the compiled
- pattern is now set to NULL, which means that you don't need to do anything
- special unless you are using custom tables.
-
-3. It is possible, with some restrictions on the content of the regex, to
- request "partial" matching. A special return code is given if all of the
- subject string matched part of the regex. This could be useful for testing
- an input field as it is being typed.
-
-4. There is now some optional support for Unicode character properties, which
- means that the patterns items such as \p{Lu} and \X can now be used. Only
- the general category properties are supported. If PCRE is compiled with this
- support, an additional 90K data structure is include, which increases the
- size of the library dramatically.
-
-5. There is support for saving compiled patterns and re-using them later.
-
-6. There is support for running regular expressions that were compiled on a
- different host with the opposite endianness.
-
-7. The pcretest program has been extended to accommodate the new features.
-
-The main internal rearrangement is that sequences of literal characters are no
-longer handled as strings. Instead, each character is handled on its own. This
-makes some UTF-8 handling easier, and makes the support of partial matching
-possible. Compiled patterns containing long literal strings will be larger as a
-result of this change; I hope that performance will not be much affected.
-
-
-Release 4.5 01-Dec-03
----------------------
-
-Again mainly a bug-fix and tidying release, with only a couple of new features:
-
-1. It's possible now to compile PCRE so that it does not use recursive
-function calls when matching. Instead it gets memory from the heap. This slows
-things down, but may be necessary on systems with limited stacks.
-
-2. UTF-8 string checking has been tightened to reject overlong sequences and to
-check that a starting offset points to the start of a character. Failure of the
-latter returns a new error code: PCRE_ERROR_BADUTF8_OFFSET.
-
-3. PCRE can now be compiled for systems that use EBCDIC code.
-
-
-Release 4.4 21-Aug-03
----------------------
-
-This is mainly a bug-fix and tidying release. The only new feature is that PCRE
-checks UTF-8 strings for validity by default. There is an option to suppress
-this, just in case anybody wants that teeny extra bit of performance.
-
-
-Releases 4.1 - 4.3
-------------------
-
-Sorry, I forgot about updating the NEWS file for these releases. Please take a
-look at ChangeLog.
-
-
-Release 4.0 17-Feb-03
----------------------
-
-There have been a lot of changes for the 4.0 release, adding additional
-functionality and mending bugs. Below is a list of the highlights of the new
-functionality. For full details of these features, please consult the
-documentation. For a complete list of changes, see the ChangeLog file.
-
-1. Support for Perl's \Q...\E escapes.
-
-2. "Possessive quantifiers" ?+, *+, ++, and {,}+ which come from Sun's Java
-package. They provide some syntactic sugar for simple cases of "atomic
-grouping".
-
-3. Support for the \G assertion. It is true when the current matching position
-is at the start point of the match.
-
-4. A new feature that provides some of the functionality that Perl provides
-with (?{...}). The facility is termed a "callout". The way it is done in PCRE
-is for the caller to provide an optional function, by setting pcre_callout to
-its entry point. To get the function called, the regex must include (?C) at
-appropriate points.
-
-5. Support for recursive calls to individual subpatterns. This makes it really
-easy to get totally confused.
-
-6. Support for named subpatterns. The Python syntax (?P<name>...) is used to
-name a group.
-
-7. Several extensions to UTF-8 support; it is now fairly complete. There is an
-option for pcregrep to make it operate in UTF-8 mode.
-
-8. The single man page has been split into a number of separate man pages.
-These also give rise to individual HTML pages which are put in a separate
-directory. There is an index.html page that lists them all. Some hyperlinking
-between the pages has been installed.
-
-
-Release 3.5 15-Aug-01
----------------------
-
-1. The configuring system has been upgraded to use later versions of autoconf
-and libtool. By default it builds both a shared and a static library if the OS
-supports it. You can use --disable-shared or --disable-static on the configure
-command if you want only one of them.
-
-2. The pcretest utility is now installed along with pcregrep because it is
-useful for users (to test regexs) and by doing this, it automatically gets
-relinked by libtool. The documentation has been turned into a man page, so
-there are now .1, .txt, and .html versions in /doc.
-
-3. Upgrades to pcregrep:
- (i) Added long-form option names like gnu grep.
- (ii) Added --help to list all options with an explanatory phrase.
- (iii) Added -r, --recursive to recurse into sub-directories.
- (iv) Added -f, --file to read patterns from a file.
-
-4. Added --enable-newline-is-cr and --enable-newline-is-lf to the configure
-script, to force use of CR or LF instead of \n in the source. On non-Unix
-systems, the value can be set in config.h.
-
-5. The limit of 200 on non-capturing parentheses is a _nesting_ limit, not an
-absolute limit. Changed the text of the error message to make this clear, and
-likewise updated the man page.
-
-6. The limit of 99 on the number of capturing subpatterns has been removed.
-The new limit is 65535, which I hope will not be a "real" limit.
-
-
-Release 3.3 01-Aug-00
----------------------
-
-There is some support for UTF-8 character strings. This is incomplete and
-experimental. The documentation describes what is and what is not implemented.
-Otherwise, this is just a bug-fixing release.
-
-
-Release 3.0 01-Feb-00
----------------------
-
-1. A "configure" script is now used to configure PCRE for Unix systems. It
-builds a Makefile, a config.h file, and the pcre-config script.
-
-2. PCRE is built as a shared library by default.
-
-3. There is support for POSIX classes such as [:alpha:].
-
-5. There is an experimental recursion feature.
-
-----------------------------------------------------------------------------
- IMPORTANT FOR THOSE UPGRADING FROM VERSIONS BEFORE 2.00
-
-Please note that there has been a change in the API such that a larger
-ovector is required at matching time, to provide some additional workspace.
-The new man page has details. This change was necessary in order to support
-some of the new functionality in Perl 5.005.
-
- IMPORTANT FOR THOSE UPGRADING FROM VERSION 2.00
-
-Another (I hope this is the last!) change has been made to the API for the
-pcre_compile() function. An additional argument has been added to make it
-possible to pass over a pointer to character tables built in the current
-locale by pcre_maketables(). To use the default tables, this new arguement
-should be passed as NULL.
-
- IMPORTANT FOR THOSE UPGRADING FROM VERSION 2.05
-
-Yet another (and again I hope this really is the last) change has been made
-to the API for the pcre_exec() function. An additional argument has been
-added to make it possible to start the match other than at the start of the
-subject string. This is important if there are lookbehinds. The new man
-page has the details, but you just want to convert existing programs, all
-you need to do is to stick in a new fifth argument to pcre_exec(), with a
-value of zero. For example, change
-
- pcre_exec(pattern, extra, subject, length, options, ovec, ovecsize)
-to
- pcre_exec(pattern, extra, subject, length, 0, options, ovec, ovecsize)
-
-****
diff --git a/crawl-ref/source/util/pcre/NON-UNIX-USE b/crawl-ref/source/util/pcre/NON-UNIX-USE
deleted file mode 100644
index e6726faaad..0000000000
--- a/crawl-ref/source/util/pcre/NON-UNIX-USE
+++ /dev/null
@@ -1,432 +0,0 @@
-Compiling PCRE on non-Unix systems
-----------------------------------
-
-This document contains the following sections:
-
- General
- Generic instructions for the PCRE C library
- The C++ wrapper functions
- Building for virtual Pascal
- Stack size in Windows environments
- Linking programs in Windows environments
- Comments about Win32 builds
- Building PCRE on Windows with CMake
- Use of relative paths with CMake on Windows
- Testing with runtest.bat
- Building under Windows with BCC5.5
- Building PCRE on OpenVMS
-
-
-GENERAL
-
-I (Philip Hazel) have no experience of Windows or VMS sytems and how their
-libraries work. The items in the PCRE distribution and Makefile that relate to
-anything other than Unix-like systems are untested by me.
-
-There are some other comments and files in the Contrib directory on the ftp
-site that you may find useful. See
-
- ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/Contrib
-
-If you want to compile PCRE for a non-Unix system (especially for a system that
-does not support "configure" and "make" files), note that the basic PCRE
-library consists entirely of code written in Standard C, and so should compile
-successfully on any system that has a Standard C compiler and library. The C++
-wrapper functions are a separate issue (see below).
-
-The PCRE distribution includes a "configure" file for use by the Configure/Make
-build system, as found in many Unix-like environments. There is also support
-support for CMake, which some users prefer, in particular in Windows
-environments. There are some instructions for CMake under Windows in the
-section entitled "Building PCRE with CMake" below. CMake can also be used to
-build PCRE in Unix-like systems.
-
-
-GENERIC INSTRUCTIONS FOR THE PCRE C LIBRARY
-
-The following are generic comments about building the PCRE C library "by hand".
-
- (1) Copy or rename the file config.h.generic as config.h, and edit the macro
- settings that it contains to whatever is appropriate for your environment.
- In particular, if you want to force a specific value for newline, you can
- define the NEWLINE macro. When you compile any of the PCRE modules, you
- must specify -DHAVE_CONFIG_H to your compiler so that config.h is included
- in the sources.
-
- An alternative approach is not to edit config.h, but to use -D on the
- compiler command line to make any changes that you need to the
- configuration options. In this case -DHAVE_CONFIG_H must not be set.
-
- NOTE: There have been occasions when the way in which certain parameters
- in config.h are used has changed between releases. (In the configure/make
- world, this is handled automatically.) When upgrading to a new release,
- you are strongly advised to review config.h.generic before re-using what
- you had previously.
-
- (2) Copy or rename the file pcre.h.generic as pcre.h.
-
- (3) EITHER:
- Copy or rename file pcre_chartables.c.dist as pcre_chartables.c.
-
- OR:
- Compile dftables.c as a stand-alone program (using -DHAVE_CONFIG_H if
- you have set up config.h), and then run it with the single argument
- "pcre_chartables.c". This generates a set of standard character tables
- and writes them to that file. The tables are generated using the default
- C locale for your system. If you want to use a locale that is specified
- by LC_xxx environment variables, add the -L option to the dftables
- command. You must use this method if you are building on a system that
- uses EBCDIC code.
-
- The tables in pcre_chartables.c are defaults. The caller of PCRE can
- specify alternative tables at run time.
-
- (4) Ensure that you have the following header files:
-
- pcre_internal.h
- ucp.h
- ucpinternal.h
- ucptable.h
-
- (5) Also ensure that you have the following file, which is #included as source
- when building a debugging version of PCRE, and is also used by pcretest.
-
- pcre_printint.src
-
- (6) Compile the following source files, setting -DHAVE_CONFIG_H as a compiler
- option if you have set up config.h with your configuration, or else use
- other -D settings to change the configuration as required.
-
- pcre_chartables.c
- pcre_compile.c
- pcre_config.c
- pcre_dfa_exec.c
- pcre_exec.c
- pcre_fullinfo.c
- pcre_get.c
- pcre_globals.c
- pcre_info.c
- pcre_maketables.c
- pcre_newline.c
- pcre_ord2utf8.c
- pcre_refcount.c
- pcre_study.c
- pcre_tables.c
- pcre_try_flipped.c
- pcre_ucp_searchfuncs.c
- pcre_valid_utf8.c
- pcre_version.c
- pcre_xclass.c
-
- Make sure that you include -I. in the compiler command (or equivalent for
- an unusual compiler) so that all included PCRE header files are first
- sought in the current directory. Otherwise you run the risk of picking up
- a previously-installed file from somewhere else.
-
- (7) Now link all the compiled code into an object library in whichever form
- your system keeps such libraries. This is the basic PCRE C library. If
- your system has static and shared libraries, you may have to do this once
- for each type.
-
- (8) Similarly, compile pcreposix.c (remembering -DHAVE_CONFIG_H if necessary)
- and link the result (on its own) as the pcreposix library.
-
- (9) Compile the test program pcretest.c (again, don't forget -DHAVE_CONFIG_H).
- This needs the functions in the pcre and pcreposix libraries when linking.
- It also needs the pcre_printint.src source file, which it #includes.
-
-(10) Run pcretest on the testinput files in the testdata directory, and check
- that the output matches the corresponding testoutput files. Note that the
- supplied files are in Unix format, with just LF characters as line
- terminators. You may need to edit them to change this if your system uses
- a different convention. If you are using Windows, you probably should use
- the wintestinput3 file instead of testinput3 (and the corresponding output
- file). This is a locale test; wintestinput3 sets the locale to "french"
- rather than "fr_FR", and there some minor output differences.
-
-(11) If you want to use the pcregrep command, compile and link pcregrep.c; it
- uses only the basic PCRE library (it does not need the pcreposix library).
-
-
-THE C++ WRAPPER FUNCTIONS
-
-The PCRE distribution also contains some C++ wrapper functions and tests,
-contributed by Google Inc. On a system that can use "configure" and "make",
-the functions are automatically built into a library called pcrecpp. It should
-be straightforward to compile the .cc files manually on other systems. The
-files called xxx_unittest.cc are test programs for each of the corresponding
-xxx.cc files.
-
-
-BUILDING FOR VIRTUAL PASCAL
-
-A script for building PCRE using Borland's C++ compiler for use with VPASCAL
-was contributed by Alexander Tokarev. Stefan Weber updated the script and added
-additional files. The following files in the distribution are for building PCRE
-for use with VP/Borland: makevp_c.txt, makevp_l.txt, makevp.bat, pcregexp.pas.
-
-
-STACK SIZE IN WINDOWS ENVIRONMENTS
-
-The default processor stack size of 1Mb in some Windows environments is too
-small for matching patterns that need much recursion. In particular, test 2 may
-fail because of this. Normally, running out of stack causes a crash, but there
-have been cases where the test program has just died silently. See your linker
-documentation for how to increase stack size if you experience problems. The
-Linux default of 8Mb is a reasonable choice for the stack, though even that can
-be too small for some pattern/subject combinations.
-
-PCRE has a compile configuration option to disable the use of stack for
-recursion so that heap is used instead. However, pattern matching is
-significantly slower when this is done. There is more about stack usage in the
-"pcrestack" documentation.
-
-
-LINKING PROGRAMS IN WINDOWS ENVIRONMENTS
-
-If you want to statically link a program against a PCRE library in the form of
-a non-dll .a file, you must define PCRE_STATIC before including pcre.h,
-otherwise the pcre_malloc() and pcre_free() exported functions will be declared
-__declspec(dllimport), with unwanted results.
-
-
-COMMENTS ABOUT WIN32 BUILDS (see also "BUILDING PCRE WITH CMAKE" below)
-
-There are two ways of building PCRE using the "configure, make, make install"
-paradigm on Windows systems: using MinGW or using Cygwin. These are not at all
-the same thing; they are completely different from each other. There is also
-support for building using CMake, which some users find a more straightforward
-way of building PCRE under Windows. However, the tests are not run
-automatically when CMake is used.
-
-The MinGW home page (http://www.mingw.org/) says this:
-
- MinGW: A collection of freely available and freely distributable Windows
- specific header files and import libraries combined with GNU toolsets that
- allow one to produce native Windows programs that do not rely on any
- 3rd-party C runtime DLLs.
-
-The Cygwin home page (http://www.cygwin.com/) says this:
-
- Cygwin is a Linux-like environment for Windows. It consists of two parts:
-
- . A DLL (cygwin1.dll) which acts as a Linux API emulation layer providing
- substantial Linux API functionality
-
- . A collection of tools which provide Linux look and feel.
-
- The Cygwin DLL currently works with all recent, commercially released x86 32
- bit and 64 bit versions of Windows, with the exception of Windows CE.
-
-On both MinGW and Cygwin, PCRE should build correctly using:
-
- ./configure && make && make install
-
-This should create two libraries called libpcre and libpcreposix, and, if you
-have enabled building the C++ wrapper, a third one called libpcrecpp. These are
-independent libraries: when you like with libpcreposix or libpcrecpp you must
-also link with libpcre, which contains the basic functions. (Some earlier
-releases of PCRE included the basic libpcre functions in libpcreposix. This no
-longer happens.)
-
-A user submitted a special-purpose patch that makes it easy to create
-"pcre.dll" under mingw32 using the "msys" environment. It provides "pcre.dll"
-as a special target. If you use this target, no other files are built, and in
-particular, the pcretest and pcregrep programs are not built. An example of how
-this might be used is:
-
- ./configure --enable-utf --disable-cpp CFLAGS="-03 -s"; make pcre.dll
-
-Using Cygwin's compiler generates libraries and executables that depend on
-cygwin1.dll. If a library that is generated this way is distributed,
-cygwin1.dll has to be distributed as well. Since cygwin1.dll is under the GPL
-licence, this forces not only PCRE to be under the GPL, but also the entire
-application. A distributor who wants to keep their own code proprietary must
-purchase an appropriate Cygwin licence.
-
-MinGW has no such restrictions. The MinGW compiler generates a library or
-executable that can run standalone on Windows without any third party dll or
-licensing issues.
-
-But there is more complication:
-
-If a Cygwin user uses the -mno-cygwin Cygwin gcc flag, what that really does is
-to tell Cygwin's gcc to use the MinGW gcc. Cygwin's gcc is only acting as a
-front end to MinGW's gcc (if you install Cygwin's gcc, you get both Cygwin's
-gcc and MinGW's gcc). So, a user can:
-
-. Build native binaries by using MinGW or by getting Cygwin and using
- -mno-cygwin.
-
-. Build binaries that depend on cygwin1.dll by using Cygwin with the normal
- compiler flags.
-
-The test files that are supplied with PCRE are in Unix format, with LF
-characters as line terminators. It may be necessary to change the line
-terminators in order to get some of the tests to work. We hope to improve
-things in this area in future.
-
-
-BUILDING PCRE ON WINDOWS WITH CMAKE
-
-CMake is an alternative build facility that can be used instead of the
-traditional Unix "configure". CMake version 2.4.7 supports Borland makefiles,
-MinGW makefiles, MSYS makefiles, NMake makefiles, UNIX makefiles, Visual Studio
-6, Visual Studio 7, Visual Studio 8, and Watcom W8. The following instructions
-were contributed by a PCRE user.
-
-1. Download CMake 2.4.7 or above from http://www.cmake.org/, install and ensure
- that cmake\bin is on your path.
-
-2. Unzip (retaining folder structure) the PCRE source tree into a source
- directory such as C:\pcre.
-
-3. Create a new, empty build directory: C:\pcre\build\
-
-4. Run CMakeSetup from the Shell envirornment of your build tool, e.g., Msys
- for Msys/MinGW or Visual Studio Command Prompt for VC/VC++
-
-5. Enter C:\pcre\pcre-xx and C:\pcre\build for the source and build
- directories, respectively
-
-6. Hit the "Configure" button.
-
-7. Select the particular IDE / build tool that you are using (Visual Studio,
- MSYS makefiles, MinGW makefiles, etc.)
-
-8. The GUI will then list several configuration options. This is where you can
- enable UTF-8 support, etc.
-
-9. Hit "Configure" again. The adjacent "OK" button should now be active.
-
-10. Hit "OK".
-
-11. The build directory should now contain a usable build system, be it a
- solution file for Visual Studio, makefiles for MinGW, etc.
-
-
-USE OF RELATIVE PATHS WITH CMAKE ON WINDOWS
-
-A PCRE user comments as follows:
-
-I thought that others may want to know the current state of
-CMAKE_USE_RELATIVE_PATHS support on Windows.
-
-Here it is:
--- AdditionalIncludeDirectories is only partially modified (only the
-first path - see below)
--- Only some of the contained file paths are modified - shown below for
-pcre.vcproj
--- It properly modifies
-
-I am sure CMake people can fix that if they want to. Until then one will
-need to replace existing absolute paths in project files with relative
-paths manually (e.g. from VS) - relative to project file location. I did
-just that before being told to try CMAKE_USE_RELATIVE_PATHS. Not a big
-deal.
-
-AdditionalIncludeDirectories="E:\builds\pcre\build;E:\builds\pcre\pcre-7.5;"
-AdditionalIncludeDirectories=".;E:\builds\pcre\pcre-7.5;"
-
-RelativePath="pcre.h">
-RelativePath="pcre_chartables.c">
-RelativePath="pcre_chartables.c.rule">
-
-
-TESTING WITH RUNTEST.BAT
-
-1. Copy RunTest.bat into the directory where pcretest.exe has been created.
-
-2. Edit RunTest.bat and insert a line that indentifies the relative location of
- the pcre source, e.g.:
-
- set srcdir=..\pcre-7.4-RC3
-
-3. Run RunTest.bat from a command shell environment. Test outputs will
- automatically be compared to expected results, and discrepancies will
- identified in the console output.
-
-4. To test pcrecpp, run pcrecpp_unittest.exe, pcre_stringpiece_unittest.exe and
- pcre_scanner_unittest.exe.
-
-
-BUILDING UNDER WINDOWS WITH BCC5.5
-
-Michael Roy sent these comments about building PCRE under Windows with BCC5.5:
-
- Some of the core BCC libraries have a version of PCRE from 1998 built in,
- which can lead to pcre_exec() giving an erroneous PCRE_ERROR_NULL from a
- version mismatch. I'm including an easy workaround below, if you'd like to
- include it in the non-unix instructions:
-
- When linking a project with BCC5.5, pcre.lib must be included before any of
- the libraries cw32.lib, cw32i.lib, cw32mt.lib, and cw32mti.lib on the command
- line.
-
-
-BUILDING PCRE ON OPENVMS
-
-Dan Mooney sent the following comments about building PCRE on OpenVMS. They
-relate to an older version of PCRE that used fewer source files, so the exact
-commands will need changing. See the current list of source files above.
-
-"It was quite easy to compile and link the library. I don't have a formal
-make file but the attached file [reproduced below] contains the OpenVMS DCL
-commands I used to build the library. I had to add #define
-POSIX_MALLOC_THRESHOLD 10 to pcre.h since it was not defined anywhere.
-
-The library was built on:
-O/S: HP OpenVMS v7.3-1
-Compiler: Compaq C v6.5-001-48BCD
-Linker: vA13-01
-
-The test results did not match 100% due to the issues you mention in your
-documentation regarding isprint(), iscntrl(), isgraph() and ispunct(). I
-modified some of the character tables temporarily and was able to get the
-results to match. Tests using the fr locale did not match since I don't have
-that locale loaded. The study size was always reported to be 3 less than the
-value in the standard test output files."
-
-=========================
-$! This DCL procedure builds PCRE on OpenVMS
-$!
-$! I followed the instructions in the non-unix-use file in the distribution.
-$!
-$ COMPILE == "CC/LIST/NOMEMBER_ALIGNMENT/PREFIX_LIBRARY_ENTRIES=ALL_ENTRIES
-$ COMPILE DFTABLES.C
-$ LINK/EXE=DFTABLES.EXE DFTABLES.OBJ
-$ RUN DFTABLES.EXE/OUTPUT=CHARTABLES.C
-$ COMPILE MAKETABLES.C
-$ COMPILE GET.C
-$ COMPILE STUDY.C
-$! I had to set POSIX_MALLOC_THRESHOLD to 10 in PCRE.H since the symbol
-$! did not seem to be defined anywhere.
-$! I edited pcre.h and added #DEFINE SUPPORT_UTF8 to enable UTF8 support.
-$ COMPILE PCRE.C
-$ LIB/CREATE PCRE MAKETABLES.OBJ, GET.OBJ, STUDY.OBJ, PCRE.OBJ
-$! I had to set POSIX_MALLOC_THRESHOLD to 10 in PCRE.H since the symbol
-$! did not seem to be defined anywhere.
-$ COMPILE PCREPOSIX.C
-$ LIB/CREATE PCREPOSIX PCREPOSIX.OBJ
-$ COMPILE PCRETEST.C
-$ LINK/EXE=PCRETEST.EXE PCRETEST.OBJ, PCRE/LIB, PCREPOSIX/LIB
-$! C programs that want access to command line arguments must be
-$! defined as a symbol
-$ PCRETEST :== "$ SYS$ROADSUSERS:[DMOONEY.REGEXP]PCRETEST.EXE"
-$! Arguments must be enclosed in quotes.
-$ PCRETEST "-C"
-$! Test results:
-$!
-$! The test results did not match 100%. The functions isprint(), iscntrl(),
-$! isgraph() and ispunct() on OpenVMS must not produce the same results
-$! as the system that built the test output files provided with the
-$! distribution.
-$!
-$! The study size did not match and was always 3 less on OpenVMS.
-$!
-$! Locale could not be set to fr
-$!
-=========================
-
-Last Updated: 25 January 2008
-****
diff --git a/crawl-ref/source/util/pcre/PrepareRelease b/crawl-ref/source/util/pcre/PrepareRelease
deleted file mode 100644
index 79b139fe9a..0000000000
--- a/crawl-ref/source/util/pcre/PrepareRelease
+++ /dev/null
@@ -1,214 +0,0 @@
-#/bin/sh
-
-# Script to prepare the files for building a PCRE release. It does some
-# processing of the documentation, detrails files, and creates pcre.h.generic
-# and config.h.generic (for use by builders who can't run ./configure).
-
-# You must run this script before runnning "make dist". It makes use of the
-# following files:
-
-# 132html A Perl script that converts a .1 or .3 man page into HTML. It
-# is called from MakeRelease. It "knows" the relevant troff
-# constructs that are used in the PCRE man pages.
-
-# CleanTxt A Perl script that cleans up the output of "nroff -man" by
-# removing backspaces and other redundant text so as to produce
-# a readable .txt file.
-
-# Detrail A Perl script that removes trailing spaces from files.
-
-# doc/index.html.src
-# A file that is copied as index.html into the doc/html directory
-# when the HTML documentation is built. It works like this so that
-# doc/html can be deleted and re-created from scratch.
-
-
-# First, sort out the documentation
-
-cd doc
-echo Processing documentation
-
-# Make Text form of the documentation. It needs some mangling to make it
-# tidy for online reading. Concatenate all the .3 stuff, but omit the
-# individual function pages.
-
-cat <<End >pcre.txt
------------------------------------------------------------------------------
-This file contains a concatenation of the PCRE man pages, converted to plain
-text format for ease of searching with a text editor, or for use on systems
-that do not have a man page processor. The small individual files that give
-synopses of each function in the library have not been included. There are
-separate text files for the pcregrep and pcretest commands.
------------------------------------------------------------------------------
-
-
-End
-
-echo "Making pcre.txt"
-for file in pcre pcrebuild pcrematching pcreapi pcrecallout pcrecompat \
- pcrepattern pcresyntax pcrepartial pcreprecompile \
- pcreperform pcreposix pcrecpp pcresample pcrestack ; do
- echo " Processing $file.3"
- nroff -c -man $file.3 >$file.rawtxt
- ../CleanTxt <$file.rawtxt >>pcre.txt
- /bin/rm $file.rawtxt
- echo "------------------------------------------------------------------------------" >>pcre.txt
- if [ "$file" != "pcresample" ] ; then
- echo " " >>pcre.txt
- echo " " >>pcre.txt
- fi
-done
-
-# The three commands
-for file in pcretest pcregrep pcre-config ; do
- echo Making $file.txt
- nroff -c -man $file.1 >$file.rawtxt
- ../CleanTxt <$file.rawtxt >$file.txt
- /bin/rm $file.rawtxt
-done
-
-
-# Make HTML form of the documentation.
-
-echo "Making HTML documentation"
-/bin/rm html/*
-cp index.html.src html/index.html
-
-for file in *.1 ; do
- base=`basename $file .1`
- echo " Making $base.html"
- ../132html -toc $base <$file >html/$base.html
-done
-
-# Exclude table of contents for function summaries. It seems that expr
-# forces an anchored regex. Also exclude them for small pages that have
-# only one section.
-for file in *.3 ; do
- base=`basename $file .3`
- toc=-toc
- if [ `expr $base : '.*_'` -ne 0 ] ; then toc="" ; fi
- if [ "$base" = "pcresample" ] || \
- [ "$base" = "pcrestack" ] || \
- [ "$base" = "pcrecompat" ] || \
- [ "$base" = "pcreperform" ] ; then
- toc=""
- fi
- echo " Making $base.html"
- ../132html $toc $base <$file >html/$base.html
- if [ $? != 0 ] ; then exit 1; fi
-done
-
-# End of documentation processing
-
-cd ..
-echo Documentation done
-
-# These files are detrailed; do not detrail the test data because there may be
-# significant trailing spaces. The configure files are also omitted from the
-# detrailing.
-
-files="\
- Makefile.am \
- Makefile.in \
- configure.ac \
- README \
- LICENCE \
- COPYING \
- AUTHORS \
- NEWS \
- NON-UNIX-USE \
- INSTALL \
- 132html \
- CleanTxt \
- Detrail \
- ChangeLog \
- CMakeLists.txt \
- RunGrepTest \
- RunTest \
- RunTest.bat \
- pcre-config.in \
- libpcre.pc.in \
- libpcrecpp.pc.in \
- config.h.in \
- pcre_printint.src \
- pcre_chartables.c.dist \
- pcredemo.c \
- pcregrep.c \
- pcretest.c \
- dftables.c \
- pcreposix.c \
- pcreposix.h \
- pcre.h.in \
- pcre_internal.h
- pcre_compile.c \
- pcre_config.c \
- pcre_dfa_exec.c \
- pcre_exec.c \
- pcre_fullinfo.c \
- pcre_get.c \
- pcre_globals.c \
- pcre_info.c \
- pcre_maketables.c \
- pcre_newline.c \
- pcre_ord2utf8.c \
- pcre_refcount.c \
- pcre_study.c \
- pcre_tables.c \
- pcre_try_flipped.c \
- pcre_ucp_searchfuncs.c \
- pcre_valid_utf8.c \
- pcre_version.c \
- pcre_xclass.c \
- pcre_scanner.cc \
- pcre_scanner.h \
- pcre_scanner_unittest.cc \
- pcrecpp.cc \
- pcrecpp.h \
- pcrecpparg.h.in \
- pcrecpp_unittest.cc \
- pcre_stringpiece.cc \
- pcre_stringpiece.h.in \
- pcre_stringpiece_unittest.cc \
- perltest.pl \
- ucp.h \
- ucpinternal.h \
- ucptable.h \
- makevp.bat \
- pcre.def \
- libpcre.def \
- libpcreposix.def"
-
-echo Detrailing
-./Detrail $files doc/p* doc/html/*
-
-echo Doing basic configure to get default pcre.h and config.h
-# This is in case the caller has set aliases (as I do - PH)
-unset cp ls mv rm
-./configure >/dev/null
-
-echo Converting pcre.h and config.h to generic forms
-cp -f pcre.h pcre.h.generic
-
-perl <<'END'
- open(IN, "<config.h") || die "Can't open config.h: $!\n";
- open(OUT, ">config.h.generic") || die "Can't open config.h.generic: $!\n";
- while (<IN>)
- {
- if (/^#define\s(?!PACKAGE)(\w+)/)
- {
- print OUT "#ifndef $1\n";
- print OUT;
- print OUT "#endif\n";
- }
- else
- {
- print OUT;
- }
- }
- close IN;
- close OUT;
-END
-
-echo Done
-
-#End
diff --git a/crawl-ref/source/util/pcre/README b/crawl-ref/source/util/pcre/README
deleted file mode 100644
index 8b48940ace..0000000000
--- a/crawl-ref/source/util/pcre/README
+++ /dev/null
@@ -1,752 +0,0 @@
-README file for PCRE (Perl-compatible regular expression library)
------------------------------------------------------------------
-
-The latest release of PCRE is always available from
-
- ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-xxx.tar.gz
-
-There is a mailing list for discussion about the development of PCRE at
-
- pcre-dev@exim.org
-
-Please read the NEWS file if you are upgrading from a previous release.
-The contents of this README file are:
-
- The PCRE APIs
- Documentation for PCRE
- Contributions by users of PCRE
- Building PCRE on non-Unix systems
- Building PCRE on Unix-like systems
- Retrieving configuration information on Unix-like systems
- Shared libraries on Unix-like systems
- Cross-compiling on Unix-like systems
- Using HP's ANSI C++ compiler (aCC)
- Making new tarballs
- Testing PCRE
- Character tables
- File manifest
-
-
-The PCRE APIs
--------------
-
-PCRE is written in C, and it has its own API. The distribution also includes a
-set of C++ wrapper functions (see the pcrecpp man page for details), courtesy
-of Google Inc.
-
-In addition, there is a set of C wrapper functions that are based on the POSIX
-regular expression API (see the pcreposix man page). These end up in the
-library called libpcreposix. Note that this just provides a POSIX calling
-interface to PCRE; the regular expressions themselves still follow Perl syntax
-and semantics. The POSIX API is restricted, and does not give full access to
-all of PCRE's facilities.
-
-The header file for the POSIX-style functions is called pcreposix.h. The
-official POSIX name is regex.h, but I did not want to risk possible problems
-with existing files of that name by distributing it that way. To use PCRE with
-an existing program that uses the POSIX API, pcreposix.h will have to be
-renamed or pointed at by a link.
-
-If you are using the POSIX interface to PCRE and there is already a POSIX regex
-library installed on your system, as well as worrying about the regex.h header
-file (as mentioned above), you must also take care when linking programs to
-ensure that they link with PCRE's libpcreposix library. Otherwise they may pick
-up the POSIX functions of the same name from the other library.
-
-One way of avoiding this confusion is to compile PCRE with the addition of
--Dregcomp=PCREregcomp (and similarly for the other POSIX functions) to the
-compiler flags (CFLAGS if you are using "configure" -- see below). This has the
-effect of renaming the functions so that the names no longer clash. Of course,
-you have to do the same thing for your applications, or write them using the
-new names.
-
-
-Documentation for PCRE
-----------------------
-
-If you install PCRE in the normal way on a Unix-like system, you will end up
-with a set of man pages whose names all start with "pcre". The one that is just
-called "pcre" lists all the others. In addition to these man pages, the PCRE
-documentation is supplied in two other forms:
-
- 1. There are files called doc/pcre.txt, doc/pcregrep.txt, and
- doc/pcretest.txt in the source distribution. The first of these is a
- concatenation of the text forms of all the section 3 man pages except
- those that summarize individual functions. The other two are the text
- forms of the section 1 man pages for the pcregrep and pcretest commands.
- These text forms are provided for ease of scanning with text editors or
- similar tools. They are installed in <prefix>/share/doc/pcre, where
- <prefix> is the installation prefix (defaulting to /usr/local).
-
- 2. A set of files containing all the documentation in HTML form, hyperlinked
- in various ways, and rooted in a file called index.html, is distributed in
- doc/html and installed in <prefix>/share/doc/pcre/html.
-
-
-Contributions by users of PCRE
-------------------------------
-
-You can find contributions from PCRE users in the directory
-
- ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/Contrib
-
-There is a README file giving brief descriptions of what they are. Some are
-complete in themselves; others are pointers to URLs containing relevant files.
-Some of this material is likely to be well out-of-date. Several of the earlier
-contributions provided support for compiling PCRE on various flavours of
-Windows (I myself do not use Windows). Nowadays there is more Windows support
-in the standard distribution, so these contibutions have been archived.
-
-
-Building PCRE on non-Unix systems
----------------------------------
-
-For a non-Unix system, please read the comments in the file NON-UNIX-USE,
-though if your system supports the use of "configure" and "make" you may be
-able to build PCRE in the same way as for Unix-like systems. PCRE can also be
-configured in many platform environments using the GUI facility of CMake's
-CMakeSetup. It creates Makefiles, solution files, etc.
-
-PCRE has been compiled on many different operating systems. It should be
-straightforward to build PCRE on any system that has a Standard C compiler and
-library, because it uses only Standard C functions.
-
-
-Building PCRE on Unix-like systems
-----------------------------------
-
-If you are using HP's ANSI C++ compiler (aCC), please see the special note
-in the section entitled "Using HP's ANSI C++ compiler (aCC)" below.
-
-The following instructions assume the use of the widely used "configure, make,
-make install" process. There is also support for CMake in the PCRE
-distribution; there are some comments about using CMake in the NON-UNIX-USE
-file, though it can also be used in Unix-like systems.
-
-To build PCRE on a Unix-like system, first run the "configure" command from the
-PCRE distribution directory, with your current directory set to the directory
-where you want the files to be created. This command is a standard GNU
-"autoconf" configuration script, for which generic instructions are supplied in
-the file INSTALL.
-
-Most commonly, people build PCRE within its own distribution directory, and in
-this case, on many systems, just running "./configure" is sufficient. However,
-the usual methods of changing standard defaults are available. For example:
-
-CFLAGS='-O2 -Wall' ./configure --prefix=/opt/local
-
-specifies that the C compiler should be run with the flags '-O2 -Wall' instead
-of the default, and that "make install" should install PCRE under /opt/local
-instead of the default /usr/local.
-
-If you want to build in a different directory, just run "configure" with that
-directory as current. For example, suppose you have unpacked the PCRE source
-into /source/pcre/pcre-xxx, but you want to build it in /build/pcre/pcre-xxx:
-
-cd /build/pcre/pcre-xxx
-/source/pcre/pcre-xxx/configure
-
-PCRE is written in C and is normally compiled as a C library. However, it is
-possible to build it as a C++ library, though the provided building apparatus
-does not have any features to support this.
-
-There are some optional features that can be included or omitted from the PCRE
-library. You can read more about them in the pcrebuild man page.
-
-. If you want to suppress the building of the C++ wrapper library, you can add
- --disable-cpp to the "configure" command. Otherwise, when "configure" is run,
- it will try to find a C++ compiler and C++ header files, and if it succeeds,
- it will try to build the C++ wrapper.
-
-. If you want to make use of the support for UTF-8 character strings in PCRE,
- you must add --enable-utf8 to the "configure" command. Without it, the code
- for handling UTF-8 is not included in the library. (Even when included, it
- still has to be enabled by an option at run time.)
-
-. If, in addition to support for UTF-8 character strings, you want to include
- support for the \P, \p, and \X sequences that recognize Unicode character
- properties, you must add --enable-unicode-properties to the "configure"
- command. This adds about 30K to the size of the library (in the form of a
- property table); only the basic two-letter properties such as Lu are
- supported.
-
-. You can build PCRE to recognize either CR or LF or the sequence CRLF or any
- of the preceding, or any of the Unicode newline sequences as indicating the
- end of a line. Whatever you specify at build time is the default; the caller
- of PCRE can change the selection at run time. The default newline indicator
- is a single LF character (the Unix standard). You can specify the default
- newline indicator by adding --enable-newline-is-cr or --enable-newline-is-lf
- or --enable-newline-is-crlf or --enable-newline-is-anycrlf or
- --enable-newline-is-any to the "configure" command, respectively.
-
- If you specify --enable-newline-is-cr or --enable-newline-is-crlf, some of
- the standard tests will fail, because the lines in the test files end with
- LF. Even if the files are edited to change the line endings, there are likely
- to be some failures. With --enable-newline-is-anycrlf or
- --enable-newline-is-any, many tests should succeed, but there may be some
- failures.
-
-. By default, the sequence \R in a pattern matches any Unicode line ending
- sequence. This is independent of the option specifying what PCRE considers to
- be the end of a line (see above). However, the caller of PCRE can restrict \R
- to match only CR, LF, or CRLF. You can make this the default by adding
- --enable-bsr-anycrlf to the "configure" command (bsr = "backslash R").
-
-. When called via the POSIX interface, PCRE uses malloc() to get additional
- storage for processing capturing parentheses if there are more than 10 of
- them in a pattern. You can increase this threshold by setting, for example,
-
- --with-posix-malloc-threshold=20
-
- on the "configure" command.
-
-. PCRE has a counter that can be set to limit the amount of resources it uses.
- If the limit is exceeded during a match, the match fails. The default is ten
- million. You can change the default by setting, for example,
-
- --with-match-limit=500000
-
- on the "configure" command. This is just the default; individual calls to
- pcre_exec() can supply their own value. There is more discussion on the
- pcreapi man page.
-
-. There is a separate counter that limits the depth of recursive function calls
- during a matching process. This also has a default of ten million, which is
- essentially "unlimited". You can change the default by setting, for example,
-
- --with-match-limit-recursion=500000
-
- Recursive function calls use up the runtime stack; running out of stack can
- cause programs to crash in strange ways. There is a discussion about stack
- sizes in the pcrestack man page.
-
-. The default maximum compiled pattern size is around 64K. You can increase
- this by adding --with-link-size=3 to the "configure" command. You can
- increase it even more by setting --with-link-size=4, but this is unlikely
- ever to be necessary. Increasing the internal link size will reduce
- performance.
-
-. You can build PCRE so that its internal match() function that is called from
- pcre_exec() does not call itself recursively. Instead, it uses memory blocks
- obtained from the heap via the special functions pcre_stack_malloc() and
- pcre_stack_free() to save data that would otherwise be saved on the stack. To
- build PCRE like this, use
-
- --disable-stack-for-recursion
-
- on the "configure" command. PCRE runs more slowly in this mode, but it may be
- necessary in environments with limited stack sizes. This applies only to the
- pcre_exec() function; it does not apply to pcre_dfa_exec(), which does not
- use deeply nested recursion. There is a discussion about stack sizes in the
- pcrestack man page.
-
-. For speed, PCRE uses four tables for manipulating and identifying characters
- whose code point values are less than 256. By default, it uses a set of
- tables for ASCII encoding that is part of the distribution. If you specify
-
- --enable-rebuild-chartables
-
- a program called dftables is compiled and run in the default C locale when
- you obey "make". It builds a source file called pcre_chartables.c. If you do
- not specify this option, pcre_chartables.c is created as a copy of
- pcre_chartables.c.dist. See "Character tables" below for further information.
-
-. It is possible to compile PCRE for use on systems that use EBCDIC as their
- default character code (as opposed to ASCII) by specifying
-
- --enable-ebcdic
-
- This automatically implies --enable-rebuild-chartables (see above).
-
-. It is possible to compile pcregrep to use libz and/or libbz2, in order to
- read .gz and .bz2 files (respectively), by specifying one or both of
-
- --enable-pcregrep-libz
- --enable-pcregrep-libbz2
-
- Of course, the relevant libraries must be installed on your system.
-
-. It is possible to compile pcretest so that it links with the libreadline
- library, by specifying
-
- --enable-pcretest-libreadline
-
- If this is done, when pcretest's input is from a terminal, it reads it using
- the readline() function. This provides line-editing and history facilities.
- Note that libreadline is GPL-licenced, so if you distribute a binary of
- pcretest linked in this way, there may be licensing issues.
-
- Setting this option causes the -lreadline option to be added to the pcretest
- build. In many operating environments with a sytem-installed readline
- library this is sufficient. However, in some environments (e.g. if an
- unmodified distribution version of readline is in use), it may be necessary
- to specify something like LIBS="-lncurses" as well. This is because, to quote
- the readline INSTALL, "Readline uses the termcap functions, but does not link
- with the termcap or curses library itself, allowing applications which link
- with readline the to choose an appropriate library."
-
-The "configure" script builds the following files for the basic C library:
-
-. Makefile is the makefile that builds the library
-. config.h contains build-time configuration options for the library
-. pcre.h is the public PCRE header file
-. pcre-config is a script that shows the settings of "configure" options
-. libpcre.pc is data for the pkg-config command
-. libtool is a script that builds shared and/or static libraries
-. RunTest is a script for running tests on the basic C library
-. RunGrepTest is a script for running tests on the pcregrep command
-
-Versions of config.h and pcre.h are distributed in the PCRE tarballs under
-the names config.h.generic and pcre.h.generic. These are provided for the
-benefit of those who have to built PCRE without the benefit of "configure". If
-you use "configure", the .generic versions are not used.
-
-If a C++ compiler is found, the following files are also built:
-
-. libpcrecpp.pc is data for the pkg-config command
-. pcrecpparg.h is a header file for programs that call PCRE via the C++ wrapper
-. pcre_stringpiece.h is the header for the C++ "stringpiece" functions
-
-The "configure" script also creates config.status, which is an executable
-script that can be run to recreate the configuration, and config.log, which
-contains compiler output from tests that "configure" runs.
-
-Once "configure" has run, you can run "make". It builds two libraries, called
-libpcre and libpcreposix, a test program called pcretest, and the pcregrep
-command. If a C++ compiler was found on your system, "make" also builds the C++
-wrapper library, which is called libpcrecpp, and some test programs called
-pcrecpp_unittest, pcre_scanner_unittest, and pcre_stringpiece_unittest.
-Building the C++ wrapper can be disabled by adding --disable-cpp to the
-"configure" command.
-
-The command "make check" runs all the appropriate tests. Details of the PCRE
-tests are given below in a separate section of this document.
-
-You can use "make install" to install PCRE into live directories on your
-system. The following are installed (file names are all relative to the
-<prefix> that is set when "configure" is run):
-
- Commands (bin):
- pcretest
- pcregrep
- pcre-config
-
- Libraries (lib):
- libpcre
- libpcreposix
- libpcrecpp (if C++ support is enabled)
-
- Configuration information (lib/pkgconfig):
- libpcre.pc
- libpcrecpp.pc (if C++ support is enabled)
-
- Header files (include):
- pcre.h
- pcreposix.h
- pcre_scanner.h )
- pcre_stringpiece.h ) if C++ support is enabled
- pcrecpp.h )
- pcrecpparg.h )
-
- Man pages (share/man/man{1,3}):
- pcregrep.1
- pcretest.1
- pcre.3
- pcre*.3 (lots more pages, all starting "pcre")
-
- HTML documentation (share/doc/pcre/html):
- index.html
- *.html (lots more pages, hyperlinked from index.html)
-
- Text file documentation (share/doc/pcre):
- AUTHORS
- COPYING
- ChangeLog
- LICENCE
- NEWS
- README
- pcre.txt (a concatenation of the man(3) pages)
- pcretest.txt the pcretest man page
- pcregrep.txt the pcregrep man page
-
-If you want to remove PCRE from your system, you can run "make uninstall".
-This removes all the files that "make install" installed. However, it does not
-remove any directories, because these are often shared with other programs.
-
-
-Retrieving configuration information on Unix-like systems
----------------------------------------------------------
-
-Running "make install" installs the command pcre-config, which can be used to
-recall information about the PCRE configuration and installation. For example:
-
- pcre-config --version
-
-prints the version number, and
-
- pcre-config --libs
-
-outputs information about where the library is installed. This command can be
-included in makefiles for programs that use PCRE, saving the programmer from
-having to remember too many details.
-
-The pkg-config command is another system for saving and retrieving information
-about installed libraries. Instead of separate commands for each library, a
-single command is used. For example:
-
- pkg-config --cflags pcre
-
-The data is held in *.pc files that are installed in a directory called
-<prefix>/lib/pkgconfig.
-
-
-Shared libraries on Unix-like systems
--------------------------------------
-
-The default distribution builds PCRE as shared libraries and static libraries,
-as long as the operating system supports shared libraries. Shared library
-support relies on the "libtool" script which is built as part of the
-"configure" process.
-
-The libtool script is used to compile and link both shared and static
-libraries. They are placed in a subdirectory called .libs when they are newly
-built. The programs pcretest and pcregrep are built to use these uninstalled
-libraries (by means of wrapper scripts in the case of shared libraries). When
-you use "make install" to install shared libraries, pcregrep and pcretest are
-automatically re-built to use the newly installed shared libraries before being
-installed themselves. However, the versions left in the build directory still
-use the uninstalled libraries.
-
-To build PCRE using static libraries only you must use --disable-shared when
-configuring it. For example:
-
-./configure --prefix=/usr/gnu --disable-shared
-
-Then run "make" in the usual way. Similarly, you can use --disable-static to
-build only shared libraries.
-
-
-Cross-compiling on Unix-like systems
-------------------------------------
-
-You can specify CC and CFLAGS in the normal way to the "configure" command, in
-order to cross-compile PCRE for some other host. However, you should NOT
-specify --enable-rebuild-chartables, because if you do, the dftables.c source
-file is compiled and run on the local host, in order to generate the inbuilt
-character tables (the pcre_chartables.c file). This will probably not work,
-because dftables.c needs to be compiled with the local compiler, not the cross
-compiler.
-
-When --enable-rebuild-chartables is not specified, pcre_chartables.c is created
-by making a copy of pcre_chartables.c.dist, which is a default set of tables
-that assumes ASCII code. Cross-compiling with the default tables should not be
-a problem.
-
-If you need to modify the character tables when cross-compiling, you should
-move pcre_chartables.c.dist out of the way, then compile dftables.c by hand and
-run it on the local host to make a new version of pcre_chartables.c.dist.
-Then when you cross-compile PCRE this new version of the tables will be used.
-
-
-Using HP's ANSI C++ compiler (aCC)
-----------------------------------
-
-Unless C++ support is disabled by specifying the "--disable-cpp" option of the
-"configure" script, you must include the "-AA" option in the CXXFLAGS
-environment variable in order for the C++ components to compile correctly.
-
-Also, note that the aCC compiler on PA-RISC platforms may have a defect whereby
-needed libraries fail to get included when specifying the "-AA" compiler
-option. If you experience unresolved symbols when linking the C++ programs,
-use the workaround of specifying the following environment variable prior to
-running the "configure" script:
-
- CXXLDFLAGS="-lstd_v2 -lCsup_v2"
-
-
-Making new tarballs
--------------------
-
-The command "make dist" creates three PCRE tarballs, in tar.gz, tar.bz2, and
-zip formats. The command "make distcheck" does the same, but then does a trial
-build of the new distribution to ensure that it works.
-
-If you have modified any of the man page sources in the doc directory, you
-should first run the PrepareRelease script before making a distribution. This
-script creates the .txt and HTML forms of the documentation from the man pages.
-
-
-Testing PCRE
-------------
-
-To test the basic PCRE library on a Unix system, run the RunTest script that is
-created by the configuring process. There is also a script called RunGrepTest
-that tests the options of the pcregrep command. If the C++ wrapper library is
-built, three test programs called pcrecpp_unittest, pcre_scanner_unittest, and
-pcre_stringpiece_unittest are also built.
-
-Both the scripts and all the program tests are run if you obey "make check" or
-"make test". For other systems, see the instructions in NON-UNIX-USE.
-
-The RunTest script runs the pcretest test program (which is documented in its
-own man page) on each of the testinput files in the testdata directory in
-turn, and compares the output with the contents of the corresponding testoutput
-files. A file called testtry is used to hold the main output from pcretest
-(testsavedregex is also used as a working file). To run pcretest on just one of
-the test files, give its number as an argument to RunTest, for example:
-
- RunTest 2
-
-The first test file can also be fed directly into the perltest.pl script to
-check that Perl gives the same results. The only difference you should see is
-in the first few lines, where the Perl version is given instead of the PCRE
-version.
-
-The second set of tests check pcre_fullinfo(), pcre_info(), pcre_study(),
-pcre_copy_substring(), pcre_get_substring(), pcre_get_substring_list(), error
-detection, and run-time flags that are specific to PCRE, as well as the POSIX
-wrapper API. It also uses the debugging flags to check some of the internals of
-pcre_compile().
-
-If you build PCRE with a locale setting that is not the standard C locale, the
-character tables may be different (see next paragraph). In some cases, this may
-cause failures in the second set of tests. For example, in a locale where the
-isprint() function yields TRUE for characters in the range 128-255, the use of
-[:isascii:] inside a character class defines a different set of characters, and
-this shows up in this test as a difference in the compiled code, which is being
-listed for checking. Where the comparison test output contains [\x00-\x7f] the
-test will contain [\x00-\xff], and similarly in some other cases. This is not a
-bug in PCRE.
-
-The third set of tests checks pcre_maketables(), the facility for building a
-set of character tables for a specific locale and using them instead of the
-default tables. The tests make use of the "fr_FR" (French) locale. Before
-running the test, the script checks for the presence of this locale by running
-the "locale" command. If that command fails, or if it doesn't include "fr_FR"
-in the list of available locales, the third test cannot be run, and a comment
-is output to say why. If running this test produces instances of the error
-
- ** Failed to set locale "fr_FR"
-
-in the comparison output, it means that locale is not available on your system,
-despite being listed by "locale". This does not mean that PCRE is broken.
-
-[If you are trying to run this test on Windows, you may be able to get it to
-work by changing "fr_FR" to "french" everywhere it occurs. Alternatively, use
-RunTest.bat. The version of RunTest.bat included with PCRE 7.4 and above uses
-Windows versions of test 2. More info on using RunTest.bat is included in the
-document entitled NON-UNIX-USE.]
-
-The fourth test checks the UTF-8 support. It is not run automatically unless
-PCRE is built with UTF-8 support. To do this you must set --enable-utf8 when
-running "configure". This file can be also fed directly to the perltest script,
-provided you are running Perl 5.8 or higher. (For Perl 5.6, a small patch,
-commented in the script, can be be used.)
-
-The fifth test checks error handling with UTF-8 encoding, and internal UTF-8
-features of PCRE that are not relevant to Perl.
-
-The sixth test checks the support for Unicode character properties. It it not
-run automatically unless PCRE is built with Unicode property support. To to
-this you must set --enable-unicode-properties when running "configure".
-
-The seventh, eighth, and ninth tests check the pcre_dfa_exec() alternative
-matching function, in non-UTF-8 mode, UTF-8 mode, and UTF-8 mode with Unicode
-property support, respectively. The eighth and ninth tests are not run
-automatically unless PCRE is build with the relevant support.
-
-
-Character tables
-----------------
-
-For speed, PCRE uses four tables for manipulating and identifying characters
-whose code point values are less than 256. The final argument of the
-pcre_compile() function is a pointer to a block of memory containing the
-concatenated tables. A call to pcre_maketables() can be used to generate a set
-of tables in the current locale. If the final argument for pcre_compile() is
-passed as NULL, a set of default tables that is built into the binary is used.
-
-The source file called pcre_chartables.c contains the default set of tables. By
-default, this is created as a copy of pcre_chartables.c.dist, which contains
-tables for ASCII coding. However, if --enable-rebuild-chartables is specified
-for ./configure, a different version of pcre_chartables.c is built by the
-program dftables (compiled from dftables.c), which uses the ANSI C character
-handling functions such as isalnum(), isalpha(), isupper(), islower(), etc. to
-build the table sources. This means that the default C locale which is set for
-your system will control the contents of these default tables. You can change
-the default tables by editing pcre_chartables.c and then re-building PCRE. If
-you do this, you should take care to ensure that the file does not get
-automatically re-generated. The best way to do this is to move
-pcre_chartables.c.dist out of the way and replace it with your customized
-tables.
-
-When the dftables program is run as a result of --enable-rebuild-chartables,
-it uses the default C locale that is set on your system. It does not pay
-attention to the LC_xxx environment variables. In other words, it uses the
-system's default locale rather than whatever the compiling user happens to have
-set. If you really do want to build a source set of character tables in a
-locale that is specified by the LC_xxx variables, you can run the dftables
-program by hand with the -L option. For example:
-
- ./dftables -L pcre_chartables.c.special
-
-The first two 256-byte tables provide lower casing and case flipping functions,
-respectively. The next table consists of three 32-byte bit maps which identify
-digits, "word" characters, and white space, respectively. These are used when
-building 32-byte bit maps that represent character classes for code points less
-than 256.
-
-The final 256-byte table has bits indicating various character types, as
-follows:
-
- 1 white space character
- 2 letter
- 4 decimal digit
- 8 hexadecimal digit
- 16 alphanumeric or '_'
- 128 regular expression metacharacter or binary zero
-
-You should not alter the set of characters that contain the 128 bit, as that
-will cause PCRE to malfunction.
-
-
-File manifest
--------------
-
-The distribution should contain the following files:
-
-(A) Source files of the PCRE library functions and their headers:
-
- dftables.c auxiliary program for building pcre_chartables.c
- when --enable-rebuild-chartables is specified
-
- pcre_chartables.c.dist a default set of character tables that assume ASCII
- coding; used, unless --enable-rebuild-chartables is
- specified, by copying to pcre_chartables.c
-
- pcreposix.c )
- pcre_compile.c )
- pcre_config.c )
- pcre_dfa_exec.c )
- pcre_exec.c )
- pcre_fullinfo.c )
- pcre_get.c ) sources for the functions in the library,
- pcre_globals.c ) and some internal functions that they use
- pcre_info.c )
- pcre_maketables.c )
- pcre_newline.c )
- pcre_ord2utf8.c )
- pcre_refcount.c )
- pcre_study.c )
- pcre_tables.c )
- pcre_try_flipped.c )
- pcre_ucp_searchfuncs.c )
- pcre_valid_utf8.c )
- pcre_version.c )
- pcre_xclass.c )
- pcre_printint.src ) debugging function that is #included in pcretest,
- ) and can also be #included in pcre_compile()
- pcre.h.in template for pcre.h when built by "configure"
- pcreposix.h header for the external POSIX wrapper API
- pcre_internal.h header for internal use
- ucp.h ) headers concerned with
- ucpinternal.h ) Unicode property handling
- ucptable.h ) (this one is the data table)
-
- config.h.in template for config.h, which is built by "configure"
-
- pcrecpp.h public header file for the C++ wrapper
- pcrecpparg.h.in template for another C++ header file
- pcre_scanner.h public header file for C++ scanner functions
- pcrecpp.cc )
- pcre_scanner.cc ) source for the C++ wrapper library
-
- pcre_stringpiece.h.in template for pcre_stringpiece.h, the header for the
- C++ stringpiece functions
- pcre_stringpiece.cc source for the C++ stringpiece functions
-
-(B) Source files for programs that use PCRE:
-
- pcredemo.c simple demonstration of coding calls to PCRE
- pcregrep.c source of a grep utility that uses PCRE
- pcretest.c comprehensive test program
-
-(C) Auxiliary files:
-
- 132html script to turn "man" pages into HTML
- AUTHORS information about the author of PCRE
- ChangeLog log of changes to the code
- CleanTxt script to clean nroff output for txt man pages
- Detrail script to remove trailing spaces
- HACKING some notes about the internals of PCRE
- INSTALL generic installation instructions
- LICENCE conditions for the use of PCRE
- COPYING the same, using GNU's standard name
- Makefile.in ) template for Unix Makefile, which is built by
- ) "configure"
- Makefile.am ) the automake input that was used to create
- ) Makefile.in
- NEWS important changes in this release
- NON-UNIX-USE notes on building PCRE on non-Unix systems
- PrepareRelease script to make preparations for "make dist"
- README this file
- RunTest a Unix shell script for running tests
- RunGrepTest a Unix shell script for pcregrep tests
- aclocal.m4 m4 macros (generated by "aclocal")
- config.guess ) files used by libtool,
- config.sub ) used only when building a shared library
- configure a configuring shell script (built by autoconf)
- configure.ac ) the autoconf input that was used to build
- ) "configure" and config.h
- depcomp ) script to find program dependencies, generated by
- ) automake
- doc/*.3 man page sources for the PCRE functions
- doc/*.1 man page sources for pcregrep and pcretest
- doc/index.html.src the base HTML page
- doc/html/* HTML documentation
- doc/pcre.txt plain text version of the man pages
- doc/pcretest.txt plain text documentation of test program
- doc/perltest.txt plain text documentation of Perl test program
- install-sh a shell script for installing files
- libpcre.pc.in template for libpcre.pc for pkg-config
- libpcrecpp.pc.in template for libpcrecpp.pc for pkg-config
- ltmain.sh file used to build a libtool script
- missing ) common stub for a few missing GNU programs while
- ) installing, generated by automake
- mkinstalldirs script for making install directories
- perltest.pl Perl test program
- pcre-config.in source of script which retains PCRE information
- pcrecpp_unittest.cc )
- pcre_scanner_unittest.cc ) test programs for the C++ wrapper
- pcre_stringpiece_unittest.cc )
- testdata/testinput* test data for main library tests
- testdata/testoutput* expected test results
- testdata/grep* input and output for pcregrep tests
-
-(D) Auxiliary files for cmake support
-
- CMakeLists.txt
- config-cmake.h.in
-
-(E) Auxiliary files for VPASCAL
-
- makevp.bat
- makevp_c.txt
- makevp_l.txt
- pcregexp.pas
-
-(F) Auxiliary files for building PCRE "by hand"
-
- pcre.h.generic ) a version of the public PCRE header file
- ) for use in non-"configure" environments
- config.h.generic ) a version of config.h for use in non-"configure"
- ) environments
-
-(F) Miscellaneous
-
- RunTest.bat a script for running tests under Windows
-
-Philip Hazel
-Email local part: ph10
-Email domain: cam.ac.uk
-Last updated: 13 April 2008
diff --git a/crawl-ref/source/util/pcre/RunGrepTest b/crawl-ref/source/util/pcre/RunGrepTest
deleted file mode 100644
index 2d87541c79..0000000000
--- a/crawl-ref/source/util/pcre/RunGrepTest
+++ /dev/null
@@ -1,277 +0,0 @@
-#! /bin/sh
-
-# Run pcregrep tests. The assumption is that the PCRE tests check the library
-# itself. What we are checking here is the file handling and options that are
-# supported by pcregrep.
-
-# Set the C locale, so that sort(1) behaves predictably.
-LC_ALL=C
-export LC_ALL
-
-pcregrep=`pwd`/pcregrep
-
-echo " "
-echo "Testing pcregrep"
-$pcregrep -V
-
-cf="diff -ub"
-valgrind=
-
-while [ $# -gt 0 ] ; do
- case $1 in
- valgrind) valgrind="valgrind -q --leak-check=no";;
- *) echo "Unknown argument $1"; exit 1;;
- esac
- shift
-done
-
-# If PCRE has been built in a directory other than the source directory, and
-# this test is being run from "make check" as usual, then $(srcdir) will be
-# set. If not, set it to the current directory. We then arrange to run the
-# pcregrep command in the source directory so that the file names that appear
-# in the output are always the same.
-
-if [ -z "$srcdir" -o ! -d "$srcdir/testdata" ] ; then
- srcdir=.
-fi
-
-# Check for the availability of UTF-8 support
-
-./pcretest -C | ./pcregrep "No UTF-8 support" >/dev/null
-utf8=$?
-
-echo "---------------------------- Test 1 ------------------------------" >testtry
-(cd $srcdir; $valgrind $pcregrep PATTERN ./testdata/grepinput) >>testtry
-
-echo "---------------------------- Test 2 ------------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep '^PATTERN' ./testdata/grepinput) >>testtry
-
-echo "---------------------------- Test 3 ------------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -in PATTERN ./testdata/grepinput) >>testtry
-
-echo "---------------------------- Test 4 ------------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -ic PATTERN ./testdata/grepinput) >>testtry
-
-echo "---------------------------- Test 5 ------------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -in PATTERN ./testdata/grepinput ./testdata/grepinputx) >>testtry
-
-echo "---------------------------- Test 6 ------------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -inh PATTERN ./testdata/grepinput ./testdata/grepinputx) >>testtry
-
-echo "---------------------------- Test 7 ------------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -il PATTERN ./testdata/grepinput ./testdata/grepinputx) >>testtry
-
-echo "---------------------------- Test 8 ------------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -l PATTERN ./testdata/grepinput ./testdata/grepinputx) >>testtry
-
-echo "---------------------------- Test 9 ------------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -q PATTERN ./testdata/grepinput ./testdata/grepinputx) >>testtry
-echo "RC=$?" >>testtry
-
-echo "---------------------------- Test 10 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -q NEVER-PATTERN ./testdata/grepinput ./testdata/grepinputx) >>testtry
-echo "RC=$?" >>testtry
-
-echo "---------------------------- Test 11 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -vn pattern ./testdata/grepinputx) >>testtry
-
-echo "---------------------------- Test 12 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -ix pattern ./testdata/grepinputx) >>testtry
-
-echo "---------------------------- Test 13 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -f./testdata/greplist ./testdata/grepinputx) >>testtry
-
-echo "---------------------------- Test 14 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -w pat ./testdata/grepinput ./testdata/grepinputx) >>testtry
-
-echo "---------------------------- Test 15 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep 'abc^*' ./testdata/grepinput) 2>>testtry >>testtry
-
-echo "---------------------------- Test 16 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep abc ./testdata/grepinput ./testdata/nonexistfile) 2>>testtry >>testtry
-
-echo "---------------------------- Test 17 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -M 'the\noutput' ./testdata/grepinput) >>testtry
-
-echo "---------------------------- Test 18 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -Mn '(the\noutput|dog\.\n--)' ./testdata/grepinput) >>testtry
-
-echo "---------------------------- Test 19 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -Mix 'Pattern' ./testdata/grepinputx) >>testtry
-
-echo "---------------------------- Test 20 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -Mixn 'complete pair\nof lines' ./testdata/grepinputx) >>testtry
-
-echo "---------------------------- Test 21 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -nA3 'four' ./testdata/grepinputx) >>testtry
-
-echo "---------------------------- Test 22 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -nB3 'four' ./testdata/grepinputx) >>testtry
-
-echo "---------------------------- Test 23 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -C3 'four' ./testdata/grepinputx) >>testtry
-
-echo "---------------------------- Test 24 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -A9 'four' ./testdata/grepinputx) >>testtry
-
-echo "---------------------------- Test 25 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -nB9 'four' ./testdata/grepinputx) >>testtry
-
-echo "---------------------------- Test 26 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -A9 -B9 'four' ./testdata/grepinputx) >>testtry
-
-echo "---------------------------- Test 27 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -A10 'four' ./testdata/grepinputx) >>testtry
-
-echo "---------------------------- Test 28 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -nB10 'four' ./testdata/grepinputx) >>testtry
-
-echo "---------------------------- Test 29 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -C12 -B10 'four' ./testdata/grepinputx) >>testtry
-
-echo "---------------------------- Test 30 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -inB3 'pattern' ./testdata/grepinput ./testdata/grepinputx) >>testtry
-
-echo "---------------------------- Test 31 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -inA3 'pattern' ./testdata/grepinput ./testdata/grepinputx) >>testtry
-
-echo "---------------------------- Test 32 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -L 'fox' ./testdata/grepinput ./testdata/grepinputx) >>testtry
-
-echo "---------------------------- Test 33 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep 'fox' ./testdata/grepnonexist) >>testtry 2>&1
-echo "RC=$?" >>testtry
-
-echo "---------------------------- Test 34 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -s 'fox' ./testdata/grepnonexist) >>testtry 2>&1
-echo "RC=$?" >>testtry
-
-echo "---------------------------- Test 35 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -L -r --include=grepinputx --exclude_dir='^\.' 'fox' ./testdata) >>testtry
-echo "RC=$?" >>testtry
-
-echo "---------------------------- Test 36 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -L -r --include=grepinput --exclude 'grepinput$' --exclude_dir='^\.' 'fox' ./testdata | sort) >>testtry
-echo "RC=$?" >>testtry
-
-echo "---------------------------- Test 37 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep '^(a+)*\d' ./testdata/grepinput) >>testtry 2>teststderr
-echo "RC=$?" >>testtry
-echo "======== STDERR ========" >>testtry
-cat teststderr >>testtry
-
-echo "---------------------------- Test 38 ------------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep '>\x00<' ./testdata/grepinput) >>testtry
-
-echo "---------------------------- Test 39 ------------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -A1 'before the binary zero' ./testdata/grepinput) >>testtry
-
-echo "---------------------------- Test 40 ------------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -B1 'after the binary zero' ./testdata/grepinput) >>testtry
-
-echo "---------------------------- Test 41 ------------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -B1 -o '\w+ the binary zero' ./testdata/grepinput) >>testtry
-
-echo "---------------------------- Test 41 ------------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -B1 -onH '\w+ the binary zero' ./testdata/grepinput) >>testtry
-
-echo "---------------------------- Test 42 ------------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -on 'before|zero|after' ./testdata/grepinput) >>testtry
-
-echo "---------------------------- Test 43 ------------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -on -e before -e zero -e after ./testdata/grepinput) >>testtry
-
-echo "---------------------------- Test 44 ------------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -on -f ./testdata/greplist -e binary ./testdata/grepinput) >>testtry
-
-echo "---------------------------- Test 45 ------------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -e abc -e '(unclosed' ./testdata/grepinput) 2>>testtry >>testtry
-
-echo "---------------------------- Test 46 ------------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -Fx "AB.VE
-elephant" ./testdata/grepinput) >>testtry
-
-echo "---------------------------- Test 47 ------------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -F "AB.VE
-elephant" ./testdata/grepinput) >>testtry
-
-echo "---------------------------- Test 48 ------------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -F -e DATA -e "AB.VE
-elephant" ./testdata/grepinput) >>testtry
-
-echo "---------------------------- Test 49 ------------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep "^(abc|def|ghi|jkl)" ./testdata/grepinputx) >>testtry
-
-echo "---------------------------- Test 50 ------------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -Mv "brown\sfox" ./testdata/grepinputv) >>testtry
-
-echo "---------------------------- Test 51 ------------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep --colour=always jumps ./testdata/grepinputv) >>testtry
-
-echo "---------------------------- Test 52 ------------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep --file-offsets 'before|zero|after' ./testdata/grepinput) >>testtry
-
-echo "---------------------------- Test 53 ------------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep --line-offsets 'before|zero|after' ./testdata/grepinput) >>testtry
-
-# Now compare the results.
-
-$cf $srcdir/testdata/grepoutput testtry
-if [ $? != 0 ] ; then exit 1; fi
-
-
-# These tests require UTF-8 support
-
-if [ $utf8 -ne 0 ] ; then
- echo "Testing pcregrep UTF-8 features"
-
- echo "---------------------------- Test U1 ------------------------------" >testtry
- (cd $srcdir; $valgrind $pcregrep -n -u --newline=any "^X" ./testdata/grepinput8) >>testtry
-
- echo "---------------------------- Test U2 ------------------------------" >>testtry
- (cd $srcdir; $valgrind $pcregrep -n -u -C 3 --newline=any "Match" ./testdata/grepinput8) >>testtry
-
- $cf $srcdir/testdata/grepoutput8 testtry
- if [ $? != 0 ] ; then exit 1; fi
-
-else
- echo "Skipping pcregrep UTF-8 tests: no UTF-8 support in PCRE library"
-fi
-
-
-# We go to some contortions to try to ensure that the tests for the various
-# newline settings will work in environments where the normal newline sequence
-# is not \n. Do not use exported files, whose line endings might be changed.
-# Instead, create an input file using printf so that its contents are exactly
-# what we want. Note the messy fudge to get printf to write a string that
-# starts with a hyphen.
-
-echo "Testing pcregrep newline settings"
-printf "abc\rdef\r\nghi\njkl" >testNinput
-
-printf "%c--------------------------- Test N1 ------------------------------\r\n" - >testtry
-$valgrind $pcregrep -n -N CR "^(abc|def|ghi|jkl)" testNinput >>testtry
-
-printf "%c--------------------------- Test N2 ------------------------------\r\n" - >>testtry
-$valgrind $pcregrep -n --newline=crlf "^(abc|def|ghi|jkl)" testNinput >>testtry
-
-printf "%c--------------------------- Test N3 ------------------------------\r\n" - >>testtry
-pattern=`printf 'def\rjkl'`
-$valgrind $pcregrep -n --newline=cr -F "$pattern" testNinput >>testtry
-
-printf "%c--------------------------- Test N4 ------------------------------\r\n" - >>testtry
-pattern=`printf 'xxx\r\njkl'`
-$valgrind $pcregrep -n --newline=crlf -F "$pattern" testNinput >>testtry
-
-printf "%c--------------------------- Test N5 ------------------------------\r\n" - >>testtry
-$valgrind $pcregrep -n --newline=any "^(abc|def|ghi|jkl)" testNinput >>testtry
-
-printf "%c--------------------------- Test N6 ------------------------------\r\n" - >>testtry
-$valgrind $pcregrep -n --newline=anycrlf "^(abc|def|ghi|jkl)" testNinput >>testtry
-
-$cf $srcdir/testdata/grepoutputN testtry
-if [ $? != 0 ] ; then exit 1; fi
-
-exit 0
-
-# End
diff --git a/crawl-ref/source/util/pcre/RunTest b/crawl-ref/source/util/pcre/RunTest
deleted file mode 100644
index 5ae334a05e..0000000000
--- a/crawl-ref/source/util/pcre/RunTest
+++ /dev/null
@@ -1,285 +0,0 @@
-#! /bin/sh
-
-# Run PCRE tests.
-
-valgrind=
-
-# Set up a suitable "diff" command for comparison. Some systems
-# have a diff that lacks a -u option. Try to deal with this.
-
-if diff -u /dev/null /dev/null; then cf="diff -u"; else cf="diff"; fi
-
-# Find the test data
-
-testdata=testdata
-if [ -n "$srcdir" -a -d "$srcdir" ] ; then
- testdata="$srcdir/testdata"
-fi
-
-# Find which optional facilities are available
-
-case `./pcretest -C | ./pcregrep 'Internal link size'` in
- *2) link_size=2;;
- *3) link_size=3;;
- *4) link_size=4;;
- *) echo "Failed to find internal link size"; exit 1;;
-esac
-
-./pcretest -C | ./pcregrep 'No UTF-8 support' >/dev/null
-utf8=$?
-
-./pcretest -C | ./pcregrep 'No Unicode properties support' >/dev/null
-ucp=$?
-
-# Select which tests to run; for those that are explicitly requested, check
-# that the necessary optional facilities are available.
-
-do1=no
-do2=no
-do3=no
-do4=no
-do5=no
-do6=no
-do7=no
-do8=no
-do9=no
-do10=no
-
-while [ $# -gt 0 ] ; do
- case $1 in
- 1) do1=yes;;
- 2) do2=yes;;
- 3) do3=yes;;
- 4) do4=yes;;
- 5) do5=yes;;
- 6) do6=yes;;
- 7) do7=yes;;
- 8) do8=yes;;
- 9) do9=yes;;
- 10) do10=yes;;
- valgrind) valgrind="valgrind -q";;
- *) echo "Unknown test number $1"; exit 1;;
- esac
- shift
-done
-
-if [ $utf8 -eq 0 ] ; then
- if [ $do4 = yes ] ; then
- echo "Can't run test 4 because UTF-8 support is not configured"
- exit 1
- fi
- if [ $do5 = yes ] ; then
- echo "Can't run test 5 because UTF-8 support is not configured"
- exit 1
- fi
- if [ $do8 = yes ] ; then
- echo "Can't run test 8 because UTF-8 support is not configured"
- exit 1
- fi
-fi
-
-if [ $ucp -eq 0 ] ; then
- if [ $do6 = yes ] ; then
- echo "Can't run test 6 because Unicode property support is not configured"
- exit 1
- fi
- if [ $do9 = yes ] ; then
- echo "Can't run test 9 because Unicode property support is not configured"
- exit 1
- fi
- if [ $do10 = yes ] ; then
- echo "Can't run test 10 because Unicode property support is not configured"
- exit 1
- fi
-fi
-
-if [ $link_size -ne 2 ] ; then
- if [ $do10 = yes ] ; then
- echo "Can't run test 10 because the link size ($link_size) is not 2"
- exit 1
- fi
-fi
-
-# If no specific tests were requested, select all that are relevant.
-
-if [ $do1 = no -a $do2 = no -a $do3 = no -a $do4 = no -a \
- $do5 = no -a $do6 = no -a $do7 = no -a $do8 = no -a \
- $do9 = no -a $do10 = no ] ; then
- do1=yes
- do2=yes
- do3=yes
- if [ $utf8 -ne 0 ] ; then do4=yes; fi
- if [ $utf8 -ne 0 ] ; then do5=yes; fi
- if [ $utf8 -ne 0 -a $ucp -ne 0 ] ; then do6=yes; fi
- do7=yes
- if [ $utf8 -ne 0 ] ; then do8=yes; fi
- if [ $utf8 -ne 0 -a $ucp -ne 0 ] ; then do9=yes; fi
- if [ $link_size -eq 2 -a $ucp -ne 0 ] ; then do10=yes; fi
-fi
-
-# Show which release
-
-echo ""
-echo PCRE C library tests
-./pcretest /dev/null
-
-# Primary test, Perl-compatible
-
-if [ $do1 = yes ] ; then
- echo "Test 1: main functionality (Perl compatible)"
- $valgrind ./pcretest -q $testdata/testinput1 testtry
- if [ $? = 0 ] ; then
- $cf $testdata/testoutput1 testtry
- if [ $? != 0 ] ; then exit 1; fi
- else exit 1
- fi
- echo "OK"
-fi
-
-# PCRE tests that are not Perl-compatible - API & error tests, mostly
-
-if [ $do2 = yes ] ; then
- echo "Test 2: API and error handling (not Perl compatible)"
- $valgrind ./pcretest -q $testdata/testinput2 testtry
- if [ $? = 0 ] ; then
- $cf $testdata/testoutput2 testtry
- if [ $? != 0 ] ; then exit 1; fi
- else exit 1
- fi
- echo "OK"
-fi
-
-# Locale-specific tests, provided that either the "fr_FR" or the "french"
-# locale is available. The former is the Unix-like standard; the latter is
-# for Windows.
-
-if [ $do3 = yes ] ; then
- locale -a | grep '^fr_FR$' >/dev/null
- if [ $? -eq 0 ] ; then
- locale=fr_FR
- infile=$testdata/testinput3
- outfile=$testdata/testoutput3
- else
- locale -a | grep '^french$' >/dev/null
- if [ $? -eq 0 ] ; then
- locale=french
- sed 's/fr_FR/french/' $testdata/testinput3 >test3input
- sed 's/fr_FR/french/' $testdata/testoutput3 >test3output
- infile=test3input
- outfile=test3output
- else
- locale=
- fi
- fi
-
- if [ "$locale" != "" ] ; then
- echo "Test 3: locale-specific features (using '$locale' locale)"
- $valgrind ./pcretest -q $infile testtry
- if [ $? = 0 ] ; then
- $cf $outfile testtry
- if [ $? != 0 ] ; then
- echo " "
- echo "Locale test did not run entirely successfully."
- echo "This usually means that there is a problem with the locale"
- echo "settings rather than a bug in PCRE."
- else
- echo "OK"
- fi
- else exit 1
- fi
- else
- echo "Cannot test locale-specific features - neither the 'fr_FR' nor the"
- echo "'french' locale exists, or the \"locale\" command is not available"
- echo "to check for them."
- echo " "
- fi
-fi
-
-# Additional tests for UTF8 support
-
-if [ $do4 = yes ] ; then
- echo "Test 4: UTF-8 support (Perl compatible)"
- $valgrind ./pcretest -q $testdata/testinput4 testtry
- if [ $? = 0 ] ; then
- $cf $testdata/testoutput4 testtry
- if [ $? != 0 ] ; then exit 1; fi
- else exit 1
- fi
- echo "OK"
-fi
-
-if [ $do5 = yes ] ; then
- echo "Test 5: API and internals for UTF-8 support (not Perl compatible)"
- $valgrind ./pcretest -q $testdata/testinput5 testtry
- if [ $? = 0 ] ; then
- $cf $testdata/testoutput5 testtry
- if [ $? != 0 ] ; then exit 1; fi
- else exit 1
- fi
- echo "OK"
-fi
-
-if [ $do6 = yes ] ; then
- echo "Test 6: Unicode property support"
- $valgrind ./pcretest -q $testdata/testinput6 testtry
- if [ $? = 0 ] ; then
- $cf $testdata/testoutput6 testtry
- if [ $? != 0 ] ; then exit 1; fi
- else exit 1
- fi
- echo "OK"
-fi
-
-# Tests for DFA matching support
-
-if [ $do7 = yes ] ; then
- echo "Test 7: DFA matching"
- $valgrind ./pcretest -q -dfa $testdata/testinput7 testtry
- if [ $? = 0 ] ; then
- $cf $testdata/testoutput7 testtry
- if [ $? != 0 ] ; then exit 1; fi
- else exit 1
- fi
- echo "OK"
-fi
-
-if [ $do8 = yes ] ; then
- echo "Test 8: DFA matching with UTF-8"
- $valgrind ./pcretest -q -dfa $testdata/testinput8 testtry
- if [ $? = 0 ] ; then
- $cf $testdata/testoutput8 testtry
- if [ $? != 0 ] ; then exit 1; fi
- else exit 1
- fi
- echo "OK"
-fi
-
-if [ $do9 = yes ] ; then
- echo "Test 9: DFA matching with Unicode properties"
- $valgrind ./pcretest -q -dfa $testdata/testinput9 testtry
- if [ $? = 0 ] ; then
- $cf $testdata/testoutput9 testtry
- if [ $? != 0 ] ; then exit 1; fi
- else exit 1
- fi
- echo "OK"
-fi
-
-# Test of internal offsets and code sizes. This test is run only when there
-# is Unicode property support and the link size is 2. The actual tests are
-# mostly the same as in some of the above, but in this test we inspect some
-# offsets and sizes that require a known link size. This is a doublecheck for
-# the maintainer, just in case something changes unexpectely.
-
-if [ $do10 = yes ] ; then
- echo "Test 10: Internal offsets and code size tests"
- $valgrind ./pcretest -q $testdata/testinput10 testtry
- if [ $? = 0 ] ; then
- $cf $testdata/testoutput10 testtry
- if [ $? != 0 ] ; then exit 1; fi
- else exit 1
- fi
- echo "OK"
-fi
-
-# End
diff --git a/crawl-ref/source/util/pcre/RunTest.bat b/crawl-ref/source/util/pcre/RunTest.bat
deleted file mode 100644
index 70517d09ee..0000000000
--- a/crawl-ref/source/util/pcre/RunTest.bat
+++ /dev/null
@@ -1,39 +0,0 @@
-@rem This file was contributed by Ralf Junker, and touched up by
-@rem Daniel Richard G. Test 10 added by Philip H.
-@rem Philip H also changed test 3 to use "wintest" files.
-@rem
-@rem MS Windows batch file to run pcretest on testfiles with the correct
-@rem options.
-@rem
-@rem Output is written to a newly created subfolder named "testdata".
-
-setlocal
-
-if [%srcdir%]==[] set srcdir=.
-if [%pcretest%]==[] set pcretest=pcretest
-
-if not exist testout md testout
-
-%pcretest% -q %srcdir%\testdata\testinput1 > testout\testoutput1
-%pcretest% -q %srcdir%\testdata\testinput2 > testout\testoutput2
-@rem %pcretest% -q %srcdir%\testdata\testinput3 > testout\testoutput3
-%pcretest% -q %srcdir%\testdata\wintestinput3 > testout\wintestoutput3
-%pcretest% -q %srcdir%\testdata\testinput4 > testout\testoutput4
-%pcretest% -q %srcdir%\testdata\testinput5 > testout\testoutput5
-%pcretest% -q %srcdir%\testdata\testinput6 > testout\testoutput6
-%pcretest% -q -dfa %srcdir%\testdata\testinput7 > testout\testoutput7
-%pcretest% -q -dfa %srcdir%\testdata\testinput8 > testout\testoutput8
-%pcretest% -q -dfa %srcdir%\testdata\testinput9 > testout\testoutput9
-%pcretest% -q %srcdir%\testdata\testinput10 > testout\testoutput10
-
-fc /n %srcdir%\testdata\testoutput1 testout\testoutput1
-fc /n %srcdir%\testdata\testoutput2 testout\testoutput2
-rem fc /n %srcdir%\testdata\testoutput3 testout\testoutput3
-fc /n %srcdir%\testdata\wintestoutput3 testout\wintestoutput3
-fc /n %srcdir%\testdata\testoutput4 testout\testoutput4
-fc /n %srcdir%\testdata\testoutput5 testout\testoutput5
-fc /n %srcdir%\testdata\testoutput6 testout\testoutput6
-fc /n %srcdir%\testdata\testoutput7 testout\testoutput7
-fc /n %srcdir%\testdata\testoutput8 testout\testoutput8
-fc /n %srcdir%\testdata\testoutput9 testout\testoutput9
-fc /n %srcdir%\testdata\testoutput10 testout\testoutput10
diff --git a/crawl-ref/source/util/pcre/aclocal.m4 b/crawl-ref/source/util/pcre/aclocal.m4
deleted file mode 100644
index 91a2ef0c48..0000000000
--- a/crawl-ref/source/util/pcre/aclocal.m4
+++ /dev/null
@@ -1,7560 +0,0 @@
-# generated automatically by aclocal 1.10.1 -*- Autoconf -*-
-
-# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-# 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
-# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-# PARTICULAR PURPOSE.
-
-m4_ifndef([AC_AUTOCONF_VERSION],
- [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
-m4_if(AC_AUTOCONF_VERSION, [2.61],,
-[m4_warning([this file was generated for autoconf 2.61.
-You have another version of autoconf. It may work, but is not guaranteed to.
-If you have problems, you may need to regenerate the build system entirely.
-To do so, use the procedure documented by the package, typically `autoreconf'.])])
-
-# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*-
-
-# serial 52 AC_PROG_LIBTOOL
-
-
-# AC_PROVIDE_IFELSE(MACRO-NAME, IF-PROVIDED, IF-NOT-PROVIDED)
-# -----------------------------------------------------------
-# If this macro is not defined by Autoconf, define it here.
-m4_ifdef([AC_PROVIDE_IFELSE],
- [],
- [m4_define([AC_PROVIDE_IFELSE],
- [m4_ifdef([AC_PROVIDE_$1],
- [$2], [$3])])])
-
-
-# AC_PROG_LIBTOOL
-# ---------------
-AC_DEFUN([AC_PROG_LIBTOOL],
-[AC_REQUIRE([_AC_PROG_LIBTOOL])dnl
-dnl If AC_PROG_CXX has already been expanded, run AC_LIBTOOL_CXX
-dnl immediately, otherwise, hook it in at the end of AC_PROG_CXX.
- AC_PROVIDE_IFELSE([AC_PROG_CXX],
- [AC_LIBTOOL_CXX],
- [define([AC_PROG_CXX], defn([AC_PROG_CXX])[AC_LIBTOOL_CXX
- ])])
-dnl And a similar setup for Fortran 77 support
- AC_PROVIDE_IFELSE([AC_PROG_F77],
- [AC_LIBTOOL_F77],
- [define([AC_PROG_F77], defn([AC_PROG_F77])[AC_LIBTOOL_F77
-])])
-
-dnl Quote A][M_PROG_GCJ so that aclocal doesn't bring it in needlessly.
-dnl If either AC_PROG_GCJ or A][M_PROG_GCJ have already been expanded, run
-dnl AC_LIBTOOL_GCJ immediately, otherwise, hook it in at the end of both.
- AC_PROVIDE_IFELSE([AC_PROG_GCJ],
- [AC_LIBTOOL_GCJ],
- [AC_PROVIDE_IFELSE([A][M_PROG_GCJ],
- [AC_LIBTOOL_GCJ],
- [AC_PROVIDE_IFELSE([LT_AC_PROG_GCJ],
- [AC_LIBTOOL_GCJ],
- [ifdef([AC_PROG_GCJ],
- [define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[AC_LIBTOOL_GCJ])])
- ifdef([A][M_PROG_GCJ],
- [define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[AC_LIBTOOL_GCJ])])
- ifdef([LT_AC_PROG_GCJ],
- [define([LT_AC_PROG_GCJ],
- defn([LT_AC_PROG_GCJ])[AC_LIBTOOL_GCJ])])])])
-])])# AC_PROG_LIBTOOL
-
-
-# _AC_PROG_LIBTOOL
-# ----------------
-AC_DEFUN([_AC_PROG_LIBTOOL],
-[AC_REQUIRE([AC_LIBTOOL_SETUP])dnl
-AC_BEFORE([$0],[AC_LIBTOOL_CXX])dnl
-AC_BEFORE([$0],[AC_LIBTOOL_F77])dnl
-AC_BEFORE([$0],[AC_LIBTOOL_GCJ])dnl
-
-# This can be used to rebuild libtool when needed
-LIBTOOL_DEPS="$ac_aux_dir/ltmain.sh"
-
-# Always use our own libtool.
-LIBTOOL='$(SHELL) $(top_builddir)/libtool'
-AC_SUBST(LIBTOOL)dnl
-
-# Prevent multiple expansion
-define([AC_PROG_LIBTOOL], [])
-])# _AC_PROG_LIBTOOL
-
-
-# AC_LIBTOOL_SETUP
-# ----------------
-AC_DEFUN([AC_LIBTOOL_SETUP],
-[AC_PREREQ(2.50)dnl
-AC_REQUIRE([AC_ENABLE_SHARED])dnl
-AC_REQUIRE([AC_ENABLE_STATIC])dnl
-AC_REQUIRE([AC_ENABLE_FAST_INSTALL])dnl
-AC_REQUIRE([AC_CANONICAL_HOST])dnl
-AC_REQUIRE([AC_CANONICAL_BUILD])dnl
-AC_REQUIRE([AC_PROG_CC])dnl
-AC_REQUIRE([AC_PROG_LD])dnl
-AC_REQUIRE([AC_PROG_LD_RELOAD_FLAG])dnl
-AC_REQUIRE([AC_PROG_NM])dnl
-
-AC_REQUIRE([AC_PROG_LN_S])dnl
-AC_REQUIRE([AC_DEPLIBS_CHECK_METHOD])dnl
-# Autoconf 2.13's AC_OBJEXT and AC_EXEEXT macros only works for C compilers!
-AC_REQUIRE([AC_OBJEXT])dnl
-AC_REQUIRE([AC_EXEEXT])dnl
-dnl
-AC_LIBTOOL_SYS_MAX_CMD_LEN
-AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE
-AC_LIBTOOL_OBJDIR
-
-AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl
-_LT_AC_PROG_ECHO_BACKSLASH
-
-case $host_os in
-aix3*)
- # AIX sometimes has problems with the GCC collect2 program. For some
- # reason, if we set the COLLECT_NAMES environment variable, the problems
- # vanish in a puff of smoke.
- if test "X${COLLECT_NAMES+set}" != Xset; then
- COLLECT_NAMES=
- export COLLECT_NAMES
- fi
- ;;
-esac
-
-# Sed substitution that helps us do robust quoting. It backslashifies
-# metacharacters that are still active within double-quoted strings.
-Xsed='sed -e 1s/^X//'
-[sed_quote_subst='s/\([\\"\\`$\\\\]\)/\\\1/g']
-
-# Same as above, but do not quote variable references.
-[double_quote_subst='s/\([\\"\\`\\\\]\)/\\\1/g']
-
-# Sed substitution to delay expansion of an escaped shell variable in a
-# double_quote_subst'ed string.
-delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
-
-# Sed substitution to avoid accidental globbing in evaled expressions
-no_glob_subst='s/\*/\\\*/g'
-
-# Constants:
-rm="rm -f"
-
-# Global variables:
-default_ofile=libtool
-can_build_shared=yes
-
-# All known linkers require a `.a' archive for static linking (except MSVC,
-# which needs '.lib').
-libext=a
-ltmain="$ac_aux_dir/ltmain.sh"
-ofile="$default_ofile"
-with_gnu_ld="$lt_cv_prog_gnu_ld"
-
-AC_CHECK_TOOL(AR, ar, false)
-AC_CHECK_TOOL(RANLIB, ranlib, :)
-AC_CHECK_TOOL(STRIP, strip, :)
-
-old_CC="$CC"
-old_CFLAGS="$CFLAGS"
-
-# Set sane defaults for various variables
-test -z "$AR" && AR=ar
-test -z "$AR_FLAGS" && AR_FLAGS=cru
-test -z "$AS" && AS=as
-test -z "$CC" && CC=cc
-test -z "$LTCC" && LTCC=$CC
-test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS
-test -z "$DLLTOOL" && DLLTOOL=dlltool
-test -z "$LD" && LD=ld
-test -z "$LN_S" && LN_S="ln -s"
-test -z "$MAGIC_CMD" && MAGIC_CMD=file
-test -z "$NM" && NM=nm
-test -z "$SED" && SED=sed
-test -z "$OBJDUMP" && OBJDUMP=objdump
-test -z "$RANLIB" && RANLIB=:
-test -z "$STRIP" && STRIP=:
-test -z "$ac_objext" && ac_objext=o
-
-# Determine commands to create old-style static archives.
-old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs'
-old_postinstall_cmds='chmod 644 $oldlib'
-old_postuninstall_cmds=
-
-if test -n "$RANLIB"; then
- case $host_os in
- openbsd*)
- old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib"
- ;;
- *)
- old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib"
- ;;
- esac
- old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib"
-fi
-
-_LT_CC_BASENAME([$compiler])
-
-# Only perform the check for file, if the check method requires it
-case $deplibs_check_method in
-file_magic*)
- if test "$file_magic_cmd" = '$MAGIC_CMD'; then
- AC_PATH_MAGIC
- fi
- ;;
-esac
-
-_LT_REQUIRED_DARWIN_CHECKS
-
-AC_PROVIDE_IFELSE([AC_LIBTOOL_DLOPEN], enable_dlopen=yes, enable_dlopen=no)
-AC_PROVIDE_IFELSE([AC_LIBTOOL_WIN32_DLL],
-enable_win32_dll=yes, enable_win32_dll=no)
-
-AC_ARG_ENABLE([libtool-lock],
- [AC_HELP_STRING([--disable-libtool-lock],
- [avoid locking (might break parallel builds)])])
-test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
-
-AC_ARG_WITH([pic],
- [AC_HELP_STRING([--with-pic],
- [try to use only PIC/non-PIC objects @<:@default=use both@:>@])],
- [pic_mode="$withval"],
- [pic_mode=default])
-test -z "$pic_mode" && pic_mode=default
-
-# Check if we have a version mismatch between libtool.m4 and ltmain.sh.
-#
-# Note: This should be in AC_LIBTOOL_SETUP, _after_ $ltmain have been defined.
-# We also should do it _before_ AC_LIBTOOL_LANG_C_CONFIG that actually
-# calls AC_LIBTOOL_CONFIG and creates libtool.
-#
-_LT_VERSION_CHECK
-
-# Use C for the default configuration in the libtool script
-tagname=
-AC_LIBTOOL_LANG_C_CONFIG
-_LT_AC_TAGCONFIG
-])# AC_LIBTOOL_SETUP
-
-
-# _LT_VERSION_CHECK
-# -----------------
-AC_DEFUN([_LT_VERSION_CHECK],
-[AC_MSG_CHECKING([for correct ltmain.sh version])
-if test "x$ltmain" = "x" ; then
- AC_MSG_RESULT(no)
- AC_MSG_ERROR([
-
-*** @<:@Gentoo@:>@ sanity check failed! ***
-*** \$ltmain is not defined, please check the patch for consistency! ***
-])
-fi
-gentoo_lt_version="1.5.26"
-gentoo_ltmain_version=`sed -n '/^[[ ]]*VERSION=/{s/^[[ ]]*VERSION=//;p;q;}' "$ltmain"`
-if test "x$gentoo_lt_version" != "x$gentoo_ltmain_version" ; then
- AC_MSG_RESULT(no)
- AC_MSG_ERROR([
-
-*** @<:@Gentoo@:>@ sanity check failed! ***
-*** libtool.m4 and ltmain.sh have a version mismatch! ***
-*** (libtool.m4 = $gentoo_lt_version, ltmain.sh = $gentoo_ltmain_version) ***
-
-Please run:
-
- libtoolize --copy --force
-
-if appropriate, please contact the maintainer of this
-package (or your distribution) for help.
-])
-else
- AC_MSG_RESULT(yes)
-fi
-])# _LT_VERSION_CHECK
-
-
-# _LT_AC_SYS_COMPILER
-# -------------------
-AC_DEFUN([_LT_AC_SYS_COMPILER],
-[AC_REQUIRE([AC_PROG_CC])dnl
-
-# If no C compiler was specified, use CC.
-LTCC=${LTCC-"$CC"}
-
-# If no C compiler flags were specified, use CFLAGS.
-LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
-
-# Allow CC to be a program name with arguments.
-compiler=$CC
-])# _LT_AC_SYS_COMPILER
-
-
-# _LT_CC_BASENAME(CC)
-# -------------------
-# Calculate cc_basename. Skip known compiler wrappers and cross-prefix.
-AC_DEFUN([_LT_CC_BASENAME],
-[for cc_temp in $1""; do
- case $cc_temp in
- compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;;
- distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;;
- \-*) ;;
- *) break;;
- esac
-done
-cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"`
-])
-
-
-# _LT_COMPILER_BOILERPLATE
-# ------------------------
-# Check for compiler boilerplate output or warnings with
-# the simple compiler test code.
-AC_DEFUN([_LT_COMPILER_BOILERPLATE],
-[AC_REQUIRE([LT_AC_PROG_SED])dnl
-ac_outfile=conftest.$ac_objext
-echo "$lt_simple_compile_test_code" >conftest.$ac_ext
-eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
-_lt_compiler_boilerplate=`cat conftest.err`
-$rm conftest*
-])# _LT_COMPILER_BOILERPLATE
-
-
-# _LT_LINKER_BOILERPLATE
-# ----------------------
-# Check for linker boilerplate output or warnings with
-# the simple link test code.
-AC_DEFUN([_LT_LINKER_BOILERPLATE],
-[AC_REQUIRE([LT_AC_PROG_SED])dnl
-ac_outfile=conftest.$ac_objext
-echo "$lt_simple_link_test_code" >conftest.$ac_ext
-eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
-_lt_linker_boilerplate=`cat conftest.err`
-$rm -r conftest*
-])# _LT_LINKER_BOILERPLATE
-
-# _LT_REQUIRED_DARWIN_CHECKS
-# --------------------------
-# Check for some things on darwin
-AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS],[
- case $host_os in
- rhapsody* | darwin*)
- AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:])
- AC_CHECK_TOOL([NMEDIT], [nmedit], [:])
-
- AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod],
- [lt_cv_apple_cc_single_mod=no
- if test -z "${LT_MULTI_MODULE}"; then
- # By default we will add the -single_module flag. You can override
- # by either setting the environment variable LT_MULTI_MODULE
- # non-empty at configure time, or by adding -multi_module to the
- # link flags.
- echo "int foo(void){return 1;}" > conftest.c
- $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
- -dynamiclib ${wl}-single_module conftest.c
- if test -f libconftest.dylib; then
- lt_cv_apple_cc_single_mod=yes
- rm -rf libconftest.dylib*
- fi
- rm conftest.c
- fi])
- AC_CACHE_CHECK([for -exported_symbols_list linker flag],
- [lt_cv_ld_exported_symbols_list],
- [lt_cv_ld_exported_symbols_list=no
- save_LDFLAGS=$LDFLAGS
- echo "_main" > conftest.sym
- LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym"
- AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])],
- [lt_cv_ld_exported_symbols_list=yes],
- [lt_cv_ld_exported_symbols_list=no])
- LDFLAGS="$save_LDFLAGS"
- ])
- case $host_os in
- rhapsody* | darwin1.[[0123]])
- _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;;
- darwin1.*)
- _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
- darwin*)
- # if running on 10.5 or later, the deployment target defaults
- # to the OS version, if on x86, and 10.4, the deployment
- # target defaults to 10.4. Don't you love it?
- case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
- 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*)
- _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
- 10.[[012]]*)
- _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
- 10.*)
- _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
- esac
- ;;
- esac
- if test "$lt_cv_apple_cc_single_mod" = "yes"; then
- _lt_dar_single_mod='$single_module'
- fi
- if test "$lt_cv_ld_exported_symbols_list" = "yes"; then
- _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym'
- else
- _lt_dar_export_syms="~$NMEDIT -s \$output_objdir/\${libname}-symbols.expsym \${lib}"
- fi
- if test "$DSYMUTIL" != ":"; then
- _lt_dsymutil="~$DSYMUTIL \$lib || :"
- else
- _lt_dsymutil=
- fi
- ;;
- esac
-])
-
-# _LT_AC_SYS_LIBPATH_AIX
-# ----------------------
-# Links a minimal program and checks the executable
-# for the system default hardcoded library path. In most cases,
-# this is /usr/lib:/lib, but when the MPI compilers are used
-# the location of the communication and MPI libs are included too.
-# If we don't find anything, use the default library path according
-# to the aix ld manual.
-AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX],
-[AC_REQUIRE([LT_AC_PROG_SED])dnl
-AC_LINK_IFELSE(AC_LANG_PROGRAM,[
-lt_aix_libpath_sed='
- /Import File Strings/,/^$/ {
- /^0/ {
- s/^0 *\(.*\)$/\1/
- p
- }
- }'
-aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
-# Check for a 64-bit object if we didn't find anything.
-if test -z "$aix_libpath"; then
- aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
-fi],[])
-if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
-])# _LT_AC_SYS_LIBPATH_AIX
-
-
-# _LT_AC_SHELL_INIT(ARG)
-# ----------------------
-AC_DEFUN([_LT_AC_SHELL_INIT],
-[ifdef([AC_DIVERSION_NOTICE],
- [AC_DIVERT_PUSH(AC_DIVERSION_NOTICE)],
- [AC_DIVERT_PUSH(NOTICE)])
-$1
-AC_DIVERT_POP
-])# _LT_AC_SHELL_INIT
-
-
-# _LT_AC_PROG_ECHO_BACKSLASH
-# --------------------------
-# Add some code to the start of the generated configure script which
-# will find an echo command which doesn't interpret backslashes.
-AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH],
-[_LT_AC_SHELL_INIT([
-# Check that we are running under the correct shell.
-SHELL=${CONFIG_SHELL-/bin/sh}
-
-case X$ECHO in
-X*--fallback-echo)
- # Remove one level of quotation (which was required for Make).
- ECHO=`echo "$ECHO" | sed 's,\\\\\[$]\\[$]0,'[$]0','`
- ;;
-esac
-
-echo=${ECHO-echo}
-if test "X[$]1" = X--no-reexec; then
- # Discard the --no-reexec flag, and continue.
- shift
-elif test "X[$]1" = X--fallback-echo; then
- # Avoid inline document here, it may be left over
- :
-elif test "X`($echo '\t') 2>/dev/null`" = 'X\t' ; then
- # Yippee, $echo works!
- :
-else
- # Restart under the correct shell.
- exec $SHELL "[$]0" --no-reexec ${1+"[$]@"}
-fi
-
-if test "X[$]1" = X--fallback-echo; then
- # used as fallback echo
- shift
- cat <<EOF
-[$]*
-EOF
- exit 0
-fi
-
-# The HP-UX ksh and POSIX shell print the target directory to stdout
-# if CDPATH is set.
-(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
-
-if test -z "$ECHO"; then
-if test "X${echo_test_string+set}" != Xset; then
-# find a string as large as possible, as long as the shell can cope with it
- for cmd in 'sed 50q "[$]0"' 'sed 20q "[$]0"' 'sed 10q "[$]0"' 'sed 2q "[$]0"' 'echo test'; do
- # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ...
- if (echo_test_string=`eval $cmd`) 2>/dev/null &&
- echo_test_string=`eval $cmd` &&
- (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null
- then
- break
- fi
- done
-fi
-
-if test "X`($echo '\t') 2>/dev/null`" = 'X\t' &&
- echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` &&
- test "X$echo_testing_string" = "X$echo_test_string"; then
- :
-else
- # The Solaris, AIX, and Digital Unix default echo programs unquote
- # backslashes. This makes it impossible to quote backslashes using
- # echo "$something" | sed 's/\\/\\\\/g'
- #
- # So, first we look for a working echo in the user's PATH.
-
- lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
- for dir in $PATH /usr/ucb; do
- IFS="$lt_save_ifs"
- if (test -f $dir/echo || test -f $dir/echo$ac_exeext) &&
- test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' &&
- echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` &&
- test "X$echo_testing_string" = "X$echo_test_string"; then
- echo="$dir/echo"
- break
- fi
- done
- IFS="$lt_save_ifs"
-
- if test "X$echo" = Xecho; then
- # We didn't find a better echo, so look for alternatives.
- if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' &&
- echo_testing_string=`(print -r "$echo_test_string") 2>/dev/null` &&
- test "X$echo_testing_string" = "X$echo_test_string"; then
- # This shell has a builtin print -r that does the trick.
- echo='print -r'
- elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) &&
- test "X$CONFIG_SHELL" != X/bin/ksh; then
- # If we have ksh, try running configure again with it.
- ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
- export ORIGINAL_CONFIG_SHELL
- CONFIG_SHELL=/bin/ksh
- export CONFIG_SHELL
- exec $CONFIG_SHELL "[$]0" --no-reexec ${1+"[$]@"}
- else
- # Try using printf.
- echo='printf %s\n'
- if test "X`($echo '\t') 2>/dev/null`" = 'X\t' &&
- echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` &&
- test "X$echo_testing_string" = "X$echo_test_string"; then
- # Cool, printf works
- :
- elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` &&
- test "X$echo_testing_string" = 'X\t' &&
- echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
- test "X$echo_testing_string" = "X$echo_test_string"; then
- CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL
- export CONFIG_SHELL
- SHELL="$CONFIG_SHELL"
- export SHELL
- echo="$CONFIG_SHELL [$]0 --fallback-echo"
- elif echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` &&
- test "X$echo_testing_string" = 'X\t' &&
- echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
- test "X$echo_testing_string" = "X$echo_test_string"; then
- echo="$CONFIG_SHELL [$]0 --fallback-echo"
- else
- # maybe with a smaller string...
- prev=:
-
- for cmd in 'echo test' 'sed 2q "[$]0"' 'sed 10q "[$]0"' 'sed 20q "[$]0"' 'sed 50q "[$]0"'; do
- if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null
- then
- break
- fi
- prev="$cmd"
- done
-
- if test "$prev" != 'sed 50q "[$]0"'; then
- echo_test_string=`eval $prev`
- export echo_test_string
- exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "[$]0" ${1+"[$]@"}
- else
- # Oops. We lost completely, so just stick with echo.
- echo=echo
- fi
- fi
- fi
- fi
-fi
-fi
-
-# Copy echo and quote the copy suitably for passing to libtool from
-# the Makefile, instead of quoting the original, which is used later.
-ECHO=$echo
-if test "X$ECHO" = "X$CONFIG_SHELL [$]0 --fallback-echo"; then
- ECHO="$CONFIG_SHELL \\\$\[$]0 --fallback-echo"
-fi
-
-AC_SUBST(ECHO)
-])])# _LT_AC_PROG_ECHO_BACKSLASH
-
-
-# _LT_AC_LOCK
-# -----------
-AC_DEFUN([_LT_AC_LOCK],
-[AC_ARG_ENABLE([libtool-lock],
- [AC_HELP_STRING([--disable-libtool-lock],
- [avoid locking (might break parallel builds)])])
-test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
-
-# Some flags need to be propagated to the compiler or linker for good
-# libtool support.
-case $host in
-ia64-*-hpux*)
- # Find out which ABI we are using.
- echo 'int i;' > conftest.$ac_ext
- if AC_TRY_EVAL(ac_compile); then
- case `/usr/bin/file conftest.$ac_objext` in
- *ELF-32*)
- HPUX_IA64_MODE="32"
- ;;
- *ELF-64*)
- HPUX_IA64_MODE="64"
- ;;
- esac
- fi
- rm -rf conftest*
- ;;
-*-*-irix6*)
- # Find out which ABI we are using.
- echo '[#]line __oline__ "configure"' > conftest.$ac_ext
- if AC_TRY_EVAL(ac_compile); then
- if test "$lt_cv_prog_gnu_ld" = yes; then
- case `/usr/bin/file conftest.$ac_objext` in
- *32-bit*)
- LD="${LD-ld} -melf32bsmip"
- ;;
- *N32*)
- LD="${LD-ld} -melf32bmipn32"
- ;;
- *64-bit*)
- LD="${LD-ld} -melf64bmip"
- ;;
- esac
- else
- case `/usr/bin/file conftest.$ac_objext` in
- *32-bit*)
- LD="${LD-ld} -32"
- ;;
- *N32*)
- LD="${LD-ld} -n32"
- ;;
- *64-bit*)
- LD="${LD-ld} -64"
- ;;
- esac
- fi
- fi
- rm -rf conftest*
- ;;
-
-x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \
-s390*-*linux*|sparc*-*linux*)
- # Find out which ABI we are using.
- echo 'int i;' > conftest.$ac_ext
- if AC_TRY_EVAL(ac_compile); then
- case `/usr/bin/file conftest.o` in
- *32-bit*)
- case $host in
- x86_64-*kfreebsd*-gnu)
- LD="${LD-ld} -m elf_i386_fbsd"
- ;;
- x86_64-*linux*)
- LD="${LD-ld} -m elf_i386"
- ;;
- ppc64-*linux*|powerpc64-*linux*)
- LD="${LD-ld} -m elf32ppclinux"
- ;;
- s390x-*linux*)
- LD="${LD-ld} -m elf_s390"
- ;;
- sparc64-*linux*)
- LD="${LD-ld} -m elf32_sparc"
- ;;
- esac
- ;;
- *64-bit*)
- case $host in
- x86_64-*kfreebsd*-gnu)
- LD="${LD-ld} -m elf_x86_64_fbsd"
- ;;
- x86_64-*linux*)
- LD="${LD-ld} -m elf_x86_64"
- ;;
- ppc*-*linux*|powerpc*-*linux*)
- LD="${LD-ld} -m elf64ppc"
- ;;
- s390*-*linux*)
- LD="${LD-ld} -m elf64_s390"
- ;;
- sparc*-*linux*)
- LD="${LD-ld} -m elf64_sparc"
- ;;
- esac
- ;;
- esac
- fi
- rm -rf conftest*
- ;;
-
-*-*-sco3.2v5*)
- # On SCO OpenServer 5, we need -belf to get full-featured binaries.
- SAVE_CFLAGS="$CFLAGS"
- CFLAGS="$CFLAGS -belf"
- AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf,
- [AC_LANG_PUSH(C)
- AC_TRY_LINK([],[],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no])
- AC_LANG_POP])
- 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
- CFLAGS="$SAVE_CFLAGS"
- fi
- ;;
-sparc*-*solaris*)
- # Find out which ABI we are using.
- echo 'int i;' > conftest.$ac_ext
- if AC_TRY_EVAL(ac_compile); then
- case `/usr/bin/file conftest.o` in
- *64-bit*)
- case $lt_cv_prog_gnu_ld in
- yes*) LD="${LD-ld} -m elf64_sparc" ;;
- *)
- if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then
- LD="${LD-ld} -64"
- fi
- ;;
- esac
- ;;
- esac
- fi
- rm -rf conftest*
- ;;
-
-AC_PROVIDE_IFELSE([AC_LIBTOOL_WIN32_DLL],
-[*-*-cygwin* | *-*-mingw* | *-*-pw32*)
- AC_CHECK_TOOL(DLLTOOL, dlltool, false)
- AC_CHECK_TOOL(AS, as, false)
- AC_CHECK_TOOL(OBJDUMP, objdump, false)
- ;;
- ])
-esac
-
-need_locks="$enable_libtool_lock"
-
-])# _LT_AC_LOCK
-
-
-# AC_LIBTOOL_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS,
-# [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE])
-# ----------------------------------------------------------------
-# Check whether the given compiler option works
-AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION],
-[AC_REQUIRE([LT_AC_PROG_SED])
-AC_CACHE_CHECK([$1], [$2],
- [$2=no
- ifelse([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4])
- echo "$lt_simple_compile_test_code" > conftest.$ac_ext
- lt_compiler_flag="$3"
- # Insert the option either (1) after the last *FLAGS variable, or
- # (2) before a word containing "conftest.", or (3) at the end.
- # Note that $ac_compile itself does not contain backslashes and begins
- # with a dollar sign (not a hyphen), so the echo should work correctly.
- # The option is referenced via a variable to avoid confusing sed.
- lt_compile=`echo "$ac_compile" | $SED \
- -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:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
- (eval "$lt_compile" 2>conftest.err)
- ac_status=$?
- cat conftest.err >&AS_MESSAGE_LOG_FD
- echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
- 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.
- $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp
- $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
- if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
- $2=yes
- fi
- fi
- $rm conftest*
-])
-
-if test x"[$]$2" = xyes; then
- ifelse([$5], , :, [$5])
-else
- ifelse([$6], , :, [$6])
-fi
-])# AC_LIBTOOL_COMPILER_OPTION
-
-
-# AC_LIBTOOL_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS,
-# [ACTION-SUCCESS], [ACTION-FAILURE])
-# ------------------------------------------------------------
-# Check whether the given compiler option works
-AC_DEFUN([AC_LIBTOOL_LINKER_OPTION],
-[AC_REQUIRE([LT_AC_PROG_SED])dnl
-AC_CACHE_CHECK([$1], [$2],
- [$2=no
- save_LDFLAGS="$LDFLAGS"
- LDFLAGS="$LDFLAGS $3"
- echo "$lt_simple_link_test_code" > conftest.$ac_ext
- if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
- # The linker can only warn and ignore the option if not recognized
- # So say no if there are warnings
- if test -s conftest.err; then
- # Append any errors to the config.log.
- cat conftest.err 1>&AS_MESSAGE_LOG_FD
- $echo "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp
- $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
- if diff conftest.exp conftest.er2 >/dev/null; then
- $2=yes
- fi
- else
- $2=yes
- fi
- fi
- $rm -r conftest*
- LDFLAGS="$save_LDFLAGS"
-])
-
-if test x"[$]$2" = xyes; then
- ifelse([$4], , :, [$4])
-else
- ifelse([$5], , :, [$5])
-fi
-])# AC_LIBTOOL_LINKER_OPTION
-
-
-# AC_LIBTOOL_SYS_MAX_CMD_LEN
-# --------------------------
-AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN],
-[# find the maximum length of command line arguments
-AC_MSG_CHECKING([the maximum length of command line arguments])
-AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
- i=0
- teststring="ABCD"
-
- case $build_os in
- msdosdjgpp*)
- # On DJGPP, this test can blow up pretty badly due to problems in libc
- # (any single argument exceeding 2000 bytes causes a buffer overrun
- # during glob expansion). Even if it were fixed, the result of this
- # check would be larger than it should be.
- lt_cv_sys_max_cmd_len=12288; # 12K is about right
- ;;
-
- gnu*)
- # Under GNU Hurd, this test is not required because there is
- # no limit to the length of command line arguments.
- # Libtool will interpret -1 as no limit whatsoever
- lt_cv_sys_max_cmd_len=-1;
- ;;
-
- cygwin* | mingw*)
- # On Win9x/ME, this test blows up -- it succeeds, but takes
- # about 5 minutes as the teststring grows exponentially.
- # Worse, since 9x/ME are not pre-emptively multitasking,
- # you end up with a "frozen" computer, even though with patience
- # the test eventually succeeds (with a max line length of 256k).
- # Instead, let's just punt: use the minimum linelength reported by
- # all of the supported platforms: 8192 (on NT/2K/XP).
- lt_cv_sys_max_cmd_len=8192;
- ;;
-
- amigaos*)
- # On AmigaOS with pdksh, this test takes hours, literally.
- # So we just punt and use a minimum line length of 8192.
- lt_cv_sys_max_cmd_len=8192;
- ;;
-
- netbsd* | freebsd* | openbsd* | darwin* | dragonfly*)
- # This has been around since 386BSD, at least. Likely further.
- if test -x /sbin/sysctl; then
- lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
- elif test -x /usr/sbin/sysctl; then
- lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax`
- else
- lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs
- fi
- # And add a safety zone
- lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
- lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
- ;;
-
- interix*)
- # We know the value 262144 and hardcode it with a safety zone (like BSD)
- lt_cv_sys_max_cmd_len=196608
- ;;
-
- osf*)
- # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure
- # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not
- # nice to cause kernel panics so lets avoid the loop below.
- # First set a reasonable default.
- lt_cv_sys_max_cmd_len=16384
- #
- if test -x /sbin/sysconfig; then
- case `/sbin/sysconfig -q proc exec_disable_arg_limit` in
- *1*) lt_cv_sys_max_cmd_len=-1 ;;
- esac
- fi
- ;;
- sco3.2v5*)
- lt_cv_sys_max_cmd_len=102400
- ;;
- sysv5* | sco5v6* | sysv4.2uw2*)
- kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null`
- if test -n "$kargmax"; then
- lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'`
- else
- lt_cv_sys_max_cmd_len=32768
- fi
- ;;
- *)
- lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null`
- if test -n "$lt_cv_sys_max_cmd_len"; then
- lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
- lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
- else
- SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
- while (test "X"`$SHELL [$]0 --fallback-echo "X$teststring" 2>/dev/null` \
- = "XX$teststring") >/dev/null 2>&1 &&
- new_result=`expr "X$teststring" : ".*" 2>&1` &&
- lt_cv_sys_max_cmd_len=$new_result &&
- test $i != 17 # 1/2 MB should be enough
- do
- i=`expr $i + 1`
- teststring=$teststring$teststring
- done
- teststring=
- # Add a significant safety factor because C++ compilers can tack on massive
- # amounts of additional arguments before passing them to the linker.
- # It appears as though 1/2 is a usable value.
- lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2`
- fi
- ;;
- esac
-])
-if test -n $lt_cv_sys_max_cmd_len ; then
- AC_MSG_RESULT($lt_cv_sys_max_cmd_len)
-else
- AC_MSG_RESULT(none)
-fi
-])# AC_LIBTOOL_SYS_MAX_CMD_LEN
-
-
-# _LT_AC_CHECK_DLFCN
-# ------------------
-AC_DEFUN([_LT_AC_CHECK_DLFCN],
-[AC_CHECK_HEADERS(dlfcn.h)dnl
-])# _LT_AC_CHECK_DLFCN
-
-
-# _LT_AC_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE,
-# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING)
-# ---------------------------------------------------------------------
-AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF],
-[AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl
-if test "$cross_compiling" = yes; then :
- [$4]
-else
- lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
- lt_status=$lt_dlunknown
- cat > conftest.$ac_ext <<EOF
-[#line __oline__ "configure"
-#include "confdefs.h"
-
-#if HAVE_DLFCN_H
-#include <dlfcn.h>
-#endif
-
-#include <stdio.h>
-
-#ifdef RTLD_GLOBAL
-# define LT_DLGLOBAL RTLD_GLOBAL
-#else
-# ifdef DL_GLOBAL
-# define LT_DLGLOBAL DL_GLOBAL
-# else
-# define LT_DLGLOBAL 0
-# endif
-#endif
-
-/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
- find out it does not work in some platform. */
-#ifndef LT_DLLAZY_OR_NOW
-# ifdef RTLD_LAZY
-# define LT_DLLAZY_OR_NOW RTLD_LAZY
-# else
-# ifdef DL_LAZY
-# define LT_DLLAZY_OR_NOW DL_LAZY
-# else
-# ifdef RTLD_NOW
-# define LT_DLLAZY_OR_NOW RTLD_NOW
-# else
-# ifdef DL_NOW
-# define LT_DLLAZY_OR_NOW DL_NOW
-# else
-# define LT_DLLAZY_OR_NOW 0
-# endif
-# endif
-# endif
-# endif
-#endif
-
-#ifdef __cplusplus
-extern "C" void exit (int);
-#endif
-
-void fnord() { int i=42;}
-int main ()
-{
- void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
- int status = $lt_dlunknown;
-
- if (self)
- {
- if (dlsym (self,"fnord")) status = $lt_dlno_uscore;
- else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
- /* dlclose (self); */
- }
- else
- puts (dlerror ());
-
- exit (status);
-}]
-EOF
- if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then
- (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null
- lt_status=$?
- case x$lt_status in
- x$lt_dlno_uscore) $1 ;;
- x$lt_dlneed_uscore) $2 ;;
- x$lt_dlunknown|x*) $3 ;;
- esac
- else :
- # compilation failed
- $3
- fi
-fi
-rm -fr conftest*
-])# _LT_AC_TRY_DLOPEN_SELF
-
-
-# AC_LIBTOOL_DLOPEN_SELF
-# ----------------------
-AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF],
-[AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl
-if test "x$enable_dlopen" != xyes; then
- enable_dlopen=unknown
- enable_dlopen_self=unknown
- enable_dlopen_self_static=unknown
-else
- lt_cv_dlopen=no
- lt_cv_dlopen_libs=
-
- case $host_os in
- beos*)
- lt_cv_dlopen="load_add_on"
- lt_cv_dlopen_libs=
- lt_cv_dlopen_self=yes
- ;;
-
- mingw* | pw32*)
- lt_cv_dlopen="LoadLibrary"
- lt_cv_dlopen_libs=
- ;;
-
- cygwin*)
- lt_cv_dlopen="dlopen"
- lt_cv_dlopen_libs=
- ;;
-
- darwin*)
- # if libdl is installed we need to link against it
- AC_CHECK_LIB([dl], [dlopen],
- [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[
- lt_cv_dlopen="dyld"
- lt_cv_dlopen_libs=
- lt_cv_dlopen_self=yes
- ])
- ;;
-
- *)
- AC_CHECK_FUNC([shl_load],
- [lt_cv_dlopen="shl_load"],
- [AC_CHECK_LIB([dld], [shl_load],
- [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"],
- [AC_CHECK_FUNC([dlopen],
- [lt_cv_dlopen="dlopen"],
- [AC_CHECK_LIB([dl], [dlopen],
- [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],
- [AC_CHECK_LIB([svld], [dlopen],
- [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"],
- [AC_CHECK_LIB([dld], [dld_link],
- [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"])
- ])
- ])
- ])
- ])
- ])
- ;;
- esac
-
- if test "x$lt_cv_dlopen" != xno; then
- enable_dlopen=yes
- else
- enable_dlopen=no
- fi
-
- case $lt_cv_dlopen in
- dlopen)
- save_CPPFLAGS="$CPPFLAGS"
- test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
-
- save_LDFLAGS="$LDFLAGS"
- wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
-
- save_LIBS="$LIBS"
- LIBS="$lt_cv_dlopen_libs $LIBS"
-
- AC_CACHE_CHECK([whether a program can dlopen itself],
- lt_cv_dlopen_self, [dnl
- _LT_AC_TRY_DLOPEN_SELF(
- lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes,
- lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross)
- ])
-
- if test "x$lt_cv_dlopen_self" = xyes; then
- wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
- AC_CACHE_CHECK([whether a statically linked program can dlopen itself],
- lt_cv_dlopen_self_static, [dnl
- _LT_AC_TRY_DLOPEN_SELF(
- lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes,
- lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross)
- ])
- fi
-
- CPPFLAGS="$save_CPPFLAGS"
- LDFLAGS="$save_LDFLAGS"
- LIBS="$save_LIBS"
- ;;
- esac
-
- case $lt_cv_dlopen_self in
- yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
- *) enable_dlopen_self=unknown ;;
- esac
-
- case $lt_cv_dlopen_self_static in
- yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
- *) enable_dlopen_self_static=unknown ;;
- esac
-fi
-])# AC_LIBTOOL_DLOPEN_SELF
-
-
-# AC_LIBTOOL_PROG_CC_C_O([TAGNAME])
-# ---------------------------------
-# Check to see if options -c and -o are simultaneously supported by compiler
-AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O],
-[AC_REQUIRE([LT_AC_PROG_SED])dnl
-AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl
-AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext],
- [_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)],
- [_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no
- $rm -r conftest 2>/dev/null
- mkdir conftest
- cd conftest
- mkdir out
- echo "$lt_simple_compile_test_code" > conftest.$ac_ext
-
- lt_compiler_flag="-o out/conftest2.$ac_objext"
- # Insert the option either (1) after the last *FLAGS variable, or
- # (2) before a word containing "conftest.", or (3) at the end.
- # Note that $ac_compile itself does not contain backslashes and begins
- # with a dollar sign (not a hyphen), so the echo should work correctly.
- lt_compile=`echo "$ac_compile" | $SED \
- -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:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
- (eval "$lt_compile" 2>out/conftest.err)
- ac_status=$?
- cat out/conftest.err >&AS_MESSAGE_LOG_FD
- echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
- if (exit $ac_status) && test -s out/conftest2.$ac_objext
- then
- # The compiler can only warn and ignore the option if not recognized
- # So say no if there are warnings
- $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp
- $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
- if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
- _LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes
- fi
- fi
- chmod u+w . 2>&AS_MESSAGE_LOG_FD
- $rm conftest*
- # SGI C++ compiler will create directory out/ii_files/ for
- # template instantiation
- test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files
- $rm out/* && rmdir out
- cd ..
- rmdir conftest
- $rm conftest*
-])
-])# AC_LIBTOOL_PROG_CC_C_O
-
-
-# AC_LIBTOOL_SYS_HARD_LINK_LOCKS([TAGNAME])
-# -----------------------------------------
-# Check to see if we can do hard links to lock some files if needed
-AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS],
-[AC_REQUIRE([_LT_AC_LOCK])dnl
-
-hard_links="nottested"
-if test "$_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then
- # do not overwrite the value of need_locks provided by the user
- AC_MSG_CHECKING([if we can lock with hard links])
- hard_links=yes
- $rm conftest*
- ln conftest.a conftest.b 2>/dev/null && hard_links=no
- touch conftest.a
- ln conftest.a conftest.b 2>&5 || hard_links=no
- ln conftest.a conftest.b 2>/dev/null && hard_links=no
- AC_MSG_RESULT([$hard_links])
- if test "$hard_links" = no; then
- AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe])
- need_locks=warn
- fi
-else
- need_locks=no
-fi
-])# AC_LIBTOOL_SYS_HARD_LINK_LOCKS
-
-
-# AC_LIBTOOL_OBJDIR
-# -----------------
-AC_DEFUN([AC_LIBTOOL_OBJDIR],
-[AC_CACHE_CHECK([for objdir], [lt_cv_objdir],
-[rm -f .libs 2>/dev/null
-mkdir .libs 2>/dev/null
-if test -d .libs; then
- lt_cv_objdir=.libs
-else
- # MS-DOS does not allow filenames that begin with a dot.
- lt_cv_objdir=_libs
-fi
-rmdir .libs 2>/dev/null])
-objdir=$lt_cv_objdir
-])# AC_LIBTOOL_OBJDIR
-
-
-# AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH([TAGNAME])
-# ----------------------------------------------
-# Check hardcoding attributes.
-AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH],
-[AC_MSG_CHECKING([how to hardcode library paths into programs])
-_LT_AC_TAGVAR(hardcode_action, $1)=
-if test -n "$_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)" || \
- test -n "$_LT_AC_TAGVAR(runpath_var, $1)" || \
- test "X$_LT_AC_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then
-
- # We can hardcode non-existant directories.
- if test "$_LT_AC_TAGVAR(hardcode_direct, $1)" != no &&
- # If the only mechanism to avoid hardcoding is shlibpath_var, we
- # have to relink, otherwise we might link with an installed library
- # when we should be linking with a yet-to-be-installed one
- ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, $1)" != no &&
- test "$_LT_AC_TAGVAR(hardcode_minus_L, $1)" != no; then
- # Linking always hardcodes the temporary library directory.
- _LT_AC_TAGVAR(hardcode_action, $1)=relink
- else
- # We can link without hardcoding, and we can hardcode nonexisting dirs.
- _LT_AC_TAGVAR(hardcode_action, $1)=immediate
- fi
-else
- # We cannot hardcode anything, or else we can only hardcode existing
- # directories.
- _LT_AC_TAGVAR(hardcode_action, $1)=unsupported
-fi
-AC_MSG_RESULT([$_LT_AC_TAGVAR(hardcode_action, $1)])
-
-if test "$_LT_AC_TAGVAR(hardcode_action, $1)" = relink; then
- # Fast installation is not supported
- enable_fast_install=no
-elif test "$shlibpath_overrides_runpath" = yes ||
- test "$enable_shared" = no; then
- # Fast installation is not necessary
- enable_fast_install=needless
-fi
-])# AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH
-
-
-# AC_LIBTOOL_SYS_LIB_STRIP
-# ------------------------
-AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP],
-[striplib=
-old_striplib=
-AC_MSG_CHECKING([whether stripping libraries is possible])
-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"
- AC_MSG_RESULT([yes])
-else
-# FIXME - insert some real tests, host_os isn't really good enough
- case $host_os in
- darwin*)
- if test -n "$STRIP" ; then
- striplib="$STRIP -x"
- old_striplib="$STRIP -S"
- AC_MSG_RESULT([yes])
- else
- AC_MSG_RESULT([no])
-fi
- ;;
- *)
- AC_MSG_RESULT([no])
- ;;
- esac
-fi
-])# AC_LIBTOOL_SYS_LIB_STRIP
-
-
-# AC_LIBTOOL_SYS_DYNAMIC_LINKER
-# -----------------------------
-# PORTME Fill in your ld.so characteristics
-AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER],
-[AC_REQUIRE([LT_AC_PROG_SED])dnl
-AC_MSG_CHECKING([dynamic linker characteristics])
-library_names_spec=
-libname_spec='lib$name'
-soname_spec=
-shrext_cmds=".so"
-postinstall_cmds=
-postuninstall_cmds=
-finish_cmds=
-finish_eval=
-shlibpath_var=
-shlibpath_overrides_runpath=unknown
-version_type=none
-dynamic_linker="$host_os ld.so"
-sys_lib_dlsearch_path_spec="/lib /usr/lib"
-m4_if($1,[],[
-if test "$GCC" = yes; then
- case $host_os in
- darwin*) lt_awk_arg="/^libraries:/,/LR/" ;;
- *) lt_awk_arg="/^libraries:/" ;;
- esac
- lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e "s,=/,/,g"`
- if echo "$lt_search_path_spec" | grep ';' >/dev/null ; then
- # if the path contains ";" then we assume it to be the separator
- # otherwise default to the standard path separator (i.e. ":") - it is
- # assumed that no part of a normal pathname contains ";" but that should
- # okay in the real world where ";" in dirpaths is itself problematic.
- lt_search_path_spec=`echo "$lt_search_path_spec" | $SED -e 's/;/ /g'`
- else
- lt_search_path_spec=`echo "$lt_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
- fi
- # Ok, now we have the path, separated by spaces, we can step through it
- # and add multilib dir if necessary.
- lt_tmp_lt_search_path_spec=
- lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
- for lt_sys_path in $lt_search_path_spec; do
- if test -d "$lt_sys_path/$lt_multi_os_dir"; then
- lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir"
- else
- test -d "$lt_sys_path" && \
- lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path"
- fi
- done
- lt_search_path_spec=`echo $lt_tmp_lt_search_path_spec | awk '
-BEGIN {RS=" "; FS="/|\n";} {
- lt_foo="";
- lt_count=0;
- for (lt_i = NF; lt_i > 0; lt_i--) {
- if ($lt_i != "" && $lt_i != ".") {
- if ($lt_i == "..") {
- lt_count++;
- } else {
- if (lt_count == 0) {
- lt_foo="/" $lt_i lt_foo;
- } else {
- lt_count--;
- }
- }
- }
- }
- if (lt_foo != "") { lt_freq[[lt_foo]]++; }
- if (lt_freq[[lt_foo]] == 1) { print lt_foo; }
-}'`
- sys_lib_search_path_spec=`echo $lt_search_path_spec`
-else
- sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
-fi])
-need_lib_prefix=unknown
-hardcode_into_libs=no
-
-# when you set need_version to no, make sure it does not cause -set_version
-# flags to be left without arguments
-need_version=unknown
-
-case $host_os in
-aix3*)
- version_type=linux
- library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
- shlibpath_var=LIBPATH
-
- # AIX 3 has no versioning support, so we append a major version to the name.
- soname_spec='${libname}${release}${shared_ext}$major'
- ;;
-
-aix[[4-9]]*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- hardcode_into_libs=yes
- if test "$host_cpu" = ia64; then
- # AIX 5 supports IA64
- library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
- shlibpath_var=LD_LIBRARY_PATH
- else
- # With GCC up to 2.95.x, collect2 would create an import file
- # for dependence libraries. The import file would start with
- # the line `#! .'. This would cause the generated library to
- # depend on `.', always an invalid library. This was fixed in
- # development snapshots of GCC prior to 3.0.
- case $host_os in
- aix4 | aix4.[[01]] | aix4.[[01]].*)
- if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
- echo ' yes '
- echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then
- :
- else
- can_build_shared=no
- fi
- ;;
- esac
- # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
- # soname into executable. Probably we can add versioning support to
- # collect2, so additional links can be useful in future.
- if test "$aix_use_runtimelinking" = yes; then
- # If using run time linking (on AIX 4.2 or later) use lib<name>.so
- # instead of lib<name>.a to let people know that these are not
- # typical AIX shared libraries.
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- else
- # We preserve .a as extension for shared libraries through AIX4.2
- # and later when we are not doing run time linking.
- library_names_spec='${libname}${release}.a $libname.a'
- soname_spec='${libname}${release}${shared_ext}$major'
- fi
- shlibpath_var=LIBPATH
- fi
- ;;
-
-amigaos*)
- library_names_spec='$libname.ixlibrary $libname.a'
- # Create ${libname}_ixlibrary.a entries in /sys/libs.
- finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
- ;;
-
-beos*)
- library_names_spec='${libname}${shared_ext}'
- dynamic_linker="$host_os ld.so"
- shlibpath_var=LIBRARY_PATH
- ;;
-
-bsdi[[45]]*)
- version_type=linux
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
- shlibpath_var=LD_LIBRARY_PATH
- sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
- sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
- # the default ld.so.conf also contains /usr/contrib/lib and
- # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
- # libtool to hard-code these into programs
- ;;
-
-cygwin* | mingw* | pw32*)
- version_type=windows
- shrext_cmds=".dll"
- need_version=no
- need_lib_prefix=no
-
- case $GCC,$host_os in
- yes,cygwin* | yes,mingw* | yes,pw32*)
- library_names_spec='$libname.dll.a'
- # DLL is installed to $(libdir)/../bin by postinstall_cmds
- postinstall_cmds='base_file=`basename \${file}`~
- dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~
- dldir=$destdir/`dirname \$dlpath`~
- test -d \$dldir || mkdir -p \$dldir~
- $install_prog $dir/$dlname \$dldir/$dlname~
- chmod a+x \$dldir/$dlname'
- postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
- dlpath=$dir/\$dldll~
- $rm \$dlpath'
- shlibpath_overrides_runpath=yes
-
- case $host_os in
- cygwin*)
- # Cygwin DLLs use 'cyg' prefix rather than 'lib'
- soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
- sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib"
- ;;
- mingw*)
- # MinGW DLLs use traditional 'lib' prefix
- soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
- sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
- if echo "$sys_lib_search_path_spec" | [grep ';[c-zC-Z]:/' >/dev/null]; then
- # It is most probably a Windows format PATH printed by
- # mingw gcc, but we are running on Cygwin. Gcc prints its search
- # path with ; separators, and with drive letters. We can handle the
- # drive letters (cygwin fileutils understands them), so leave them,
- # especially as we might pass files found there to a mingw objdump,
- # which wouldn't understand a cygwinified path. Ahh.
- sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
- else
- sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
- fi
- ;;
- pw32*)
- # pw32 DLLs use 'pw' prefix rather than 'lib'
- library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
- ;;
- esac
- ;;
-
- *)
- library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib'
- ;;
- esac
- dynamic_linker='Win32 ld.exe'
- # FIXME: first we should search . and the directory the executable is in
- shlibpath_var=PATH
- ;;
-
-darwin* | rhapsody*)
- dynamic_linker="$host_os dyld"
- version_type=darwin
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext'
- soname_spec='${libname}${release}${major}$shared_ext'
- shlibpath_overrides_runpath=yes
- shlibpath_var=DYLD_LIBRARY_PATH
- shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
- m4_if([$1], [],[
- sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"])
- sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
- ;;
-
-dgux*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- ;;
-
-freebsd1*)
- dynamic_linker=no
- ;;
-
-freebsd* | dragonfly*)
- # DragonFly does not have aout. When/if they implement a new
- # versioning mechanism, adjust this.
- if test -x /usr/bin/objformat; then
- objformat=`/usr/bin/objformat`
- else
- case $host_os in
- freebsd[[123]]*) objformat=aout ;;
- *) objformat=elf ;;
- esac
- fi
- # Handle Gentoo/FreeBSD as it was Linux
- case $host_vendor in
- gentoo)
- version_type=linux ;;
- *)
- version_type=freebsd-$objformat ;;
- esac
-
- case $version_type in
- freebsd-elf*)
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
- need_version=no
- need_lib_prefix=no
- ;;
- freebsd-*)
- library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
- need_version=yes
- ;;
- linux)
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- need_lib_prefix=no
- need_version=no
- ;;
- esac
- shlibpath_var=LD_LIBRARY_PATH
- case $host_os in
- freebsd2*)
- shlibpath_overrides_runpath=yes
- ;;
- freebsd3.[[01]]* | freebsdelf3.[[01]]*)
- shlibpath_overrides_runpath=yes
- hardcode_into_libs=yes
- ;;
- freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \
- freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1)
- shlibpath_overrides_runpath=no
- hardcode_into_libs=yes
- ;;
- *) # from 4.6 on, and DragonFly
- shlibpath_overrides_runpath=yes
- hardcode_into_libs=yes
- ;;
- esac
- ;;
-
-gnu*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- hardcode_into_libs=yes
- ;;
-
-hpux9* | hpux10* | hpux11*)
- # Give a soname corresponding to the major version so that dld.sl refuses to
- # link against other versions.
- version_type=sunos
- need_lib_prefix=no
- need_version=no
- case $host_cpu in
- ia64*)
- shrext_cmds='.so'
- hardcode_into_libs=yes
- dynamic_linker="$host_os dld.so"
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- if test "X$HPUX_IA64_MODE" = X32; then
- sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
- else
- sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
- fi
- sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
- ;;
- hppa*64*)
- shrext_cmds='.sl'
- hardcode_into_libs=yes
- dynamic_linker="$host_os dld.sl"
- shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
- shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
- sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
- ;;
- *)
- shrext_cmds='.sl'
- dynamic_linker="$host_os dld.sl"
- shlibpath_var=SHLIB_PATH
- shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- ;;
- esac
- # HP-UX runs *really* slowly unless shared libraries are mode 555.
- postinstall_cmds='chmod 555 $lib'
- ;;
-
-interix[[3-9]]*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=no
- hardcode_into_libs=yes
- ;;
-
-irix5* | irix6* | nonstopux*)
- case $host_os in
- nonstopux*) version_type=nonstopux ;;
- *)
- if test "$lt_cv_prog_gnu_ld" = yes; then
- version_type=linux
- else
- version_type=irix
- fi ;;
- esac
- need_lib_prefix=no
- need_version=no
- soname_spec='${libname}${release}${shared_ext}$major'
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
- case $host_os in
- irix5* | nonstopux*)
- libsuff= shlibsuff=
- ;;
- *)
- case $LD in # libtool.m4 will add one of these switches to LD
- *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
- libsuff= shlibsuff= libmagic=32-bit;;
- *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
- libsuff=32 shlibsuff=N32 libmagic=N32;;
- *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
- libsuff=64 shlibsuff=64 libmagic=64-bit;;
- *) libsuff= shlibsuff= libmagic=never-match;;
- esac
- ;;
- esac
- shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
- shlibpath_overrides_runpath=no
- sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
- sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
- hardcode_into_libs=yes
- ;;
-
-# No shared lib support for Linux oldld, aout, or coff.
-linux*oldld* | linux*aout* | linux*coff*)
- dynamic_linker=no
- ;;
-
-# This must be Linux ELF.
-linux* | k*bsd*-gnu)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=no
- # This implies no fast_install, which is unacceptable.
- # Some rework will be needed to allow for fast_install
- # before this can be enabled.
- hardcode_into_libs=yes
-
- # Append ld.so.conf contents to the search path
- if test -f /etc/ld.so.conf; then
- lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '`
- sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
- fi
-
- # We used to test for /lib/ld.so.1 and disable shared libraries on
- # powerpc, because MkLinux only supported shared libraries with the
- # GNU dynamic linker. Since this was broken with cross compilers,
- # most powerpc-linux boxes support dynamic linking these days and
- # people can always --disable-shared, the test was removed, and we
- # assume the GNU/Linux dynamic linker is in use.
- dynamic_linker='GNU/Linux ld.so'
- ;;
-
-netbsd*)
- version_type=sunos
- need_lib_prefix=no
- need_version=no
- if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
- finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
- dynamic_linker='NetBSD (a.out) ld.so'
- else
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- dynamic_linker='NetBSD ld.elf_so'
- fi
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes
- hardcode_into_libs=yes
- ;;
-
-newsos6)
- version_type=linux
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes
- ;;
-
-nto-qnx*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes
- ;;
-
-openbsd*)
- version_type=sunos
- sys_lib_dlsearch_path_spec="/usr/lib"
- need_lib_prefix=no
- # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
- case $host_os in
- openbsd3.3 | openbsd3.3.*) need_version=yes ;;
- *) need_version=no ;;
- esac
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
- finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
- shlibpath_var=LD_LIBRARY_PATH
- if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
- case $host_os in
- openbsd2.[[89]] | openbsd2.[[89]].*)
- shlibpath_overrides_runpath=no
- ;;
- *)
- shlibpath_overrides_runpath=yes
- ;;
- esac
- else
- shlibpath_overrides_runpath=yes
- fi
- ;;
-
-os2*)
- libname_spec='$name'
- shrext_cmds=".dll"
- need_lib_prefix=no
- library_names_spec='$libname${shared_ext} $libname.a'
- dynamic_linker='OS/2 ld.exe'
- shlibpath_var=LIBPATH
- ;;
-
-osf3* | osf4* | osf5*)
- version_type=osf
- need_lib_prefix=no
- need_version=no
- soname_spec='${libname}${release}${shared_ext}$major'
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- shlibpath_var=LD_LIBRARY_PATH
- sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
- sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
- ;;
-
-rdos*)
- dynamic_linker=no
- ;;
-
-solaris*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes
- hardcode_into_libs=yes
- # ldd complains unless libraries are executable
- postinstall_cmds='chmod +x $lib'
- ;;
-
-sunos4*)
- version_type=sunos
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
- finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes
- if test "$with_gnu_ld" = yes; then
- need_lib_prefix=no
- fi
- need_version=yes
- ;;
-
-sysv4 | sysv4.3*)
- version_type=linux
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- case $host_vendor in
- sni)
- shlibpath_overrides_runpath=no
- need_lib_prefix=no
- export_dynamic_flag_spec='${wl}-Blargedynsym'
- runpath_var=LD_RUN_PATH
- ;;
- siemens)
- need_lib_prefix=no
- ;;
- motorola)
- need_lib_prefix=no
- need_version=no
- shlibpath_overrides_runpath=no
- sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
- ;;
- esac
- ;;
-
-sysv4*MP*)
- if test -d /usr/nec ;then
- version_type=linux
- library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
- soname_spec='$libname${shared_ext}.$major'
- shlibpath_var=LD_LIBRARY_PATH
- fi
- ;;
-
-sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
- version_type=freebsd-elf
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- hardcode_into_libs=yes
- if test "$with_gnu_ld" = yes; then
- sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
- shlibpath_overrides_runpath=no
- else
- sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
- shlibpath_overrides_runpath=yes
- case $host_os in
- sco3.2v5*)
- sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
- ;;
- esac
- fi
- sys_lib_dlsearch_path_spec='/usr/lib'
- ;;
-
-uts4*)
- version_type=linux
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- ;;
-
-*)
- dynamic_linker=no
- ;;
-esac
-AC_MSG_RESULT([$dynamic_linker])
-test "$dynamic_linker" = no && can_build_shared=no
-
-AC_CACHE_VAL([lt_cv_sys_lib_search_path_spec],
-[lt_cv_sys_lib_search_path_spec="$sys_lib_search_path_spec"])
-sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec"
-AC_CACHE_VAL([lt_cv_sys_lib_dlsearch_path_spec],
-[lt_cv_sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec"])
-sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec"
-
-variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
-if test "$GCC" = yes; then
- variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
-fi
-])# AC_LIBTOOL_SYS_DYNAMIC_LINKER
-
-
-# _LT_AC_TAGCONFIG
-# ----------------
-AC_DEFUN([_LT_AC_TAGCONFIG],
-[AC_REQUIRE([LT_AC_PROG_SED])dnl
-AC_ARG_WITH([tags],
- [AC_HELP_STRING([--with-tags@<:@=TAGS@:>@],
- [include additional configurations @<:@automatic@:>@])],
- [tagnames="$withval"])
-
-if test -f "$ltmain" && test -n "$tagnames"; then
- if test ! -f "${ofile}"; then
- AC_MSG_WARN([output file `$ofile' does not exist])
- fi
-
- if test -z "$LTCC"; then
- eval "`$SHELL ${ofile} --config | grep '^LTCC='`"
- if test -z "$LTCC"; then
- AC_MSG_WARN([output file `$ofile' does not look like a libtool script])
- else
- AC_MSG_WARN([using `LTCC=$LTCC', extracted from `$ofile'])
- fi
- fi
- if test -z "$LTCFLAGS"; then
- eval "`$SHELL ${ofile} --config | grep '^LTCFLAGS='`"
- fi
-
- # Extract list of available tagged configurations in $ofile.
- # Note that this assumes the entire list is on one line.
- available_tags=`grep "^available_tags=" "${ofile}" | $SED -e 's/available_tags=\(.*$\)/\1/' -e 's/\"//g'`
-
- lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
- for tagname in $tagnames; do
- IFS="$lt_save_ifs"
- # Check whether tagname contains only valid characters
- case `$echo "X$tagname" | $Xsed -e 's:[[-_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890,/]]::g'` in
- "") ;;
- *) AC_MSG_ERROR([invalid tag name: $tagname])
- ;;
- esac
-
- if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$" < "${ofile}" > /dev/null
- then
- AC_MSG_ERROR([tag name \"$tagname\" already exists])
- fi
-
- # Update the list of available tags.
- if test -n "$tagname"; then
- echo appending configuration tag \"$tagname\" to $ofile
-
- case $tagname in
- CXX)
- if test -n "$CXX" && ( test "X$CXX" != "Xno" &&
- ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) ||
- (test "X$CXX" != "Xg++"))) ; then
- AC_LIBTOOL_LANG_CXX_CONFIG
- else
- tagname=""
- fi
- ;;
-
- F77)
- if test -n "$F77" && test "X$F77" != "Xno"; then
- AC_LIBTOOL_LANG_F77_CONFIG
- else
- tagname=""
- fi
- ;;
-
- GCJ)
- if test -n "$GCJ" && test "X$GCJ" != "Xno"; then
- AC_LIBTOOL_LANG_GCJ_CONFIG
- else
- tagname=""
- fi
- ;;
-
- RC)
- AC_LIBTOOL_LANG_RC_CONFIG
- ;;
-
- *)
- AC_MSG_ERROR([Unsupported tag name: $tagname])
- ;;
- esac
-
- # Append the new tag name to the list of available tags.
- if test -n "$tagname" ; then
- available_tags="$available_tags $tagname"
- fi
- fi
- done
- IFS="$lt_save_ifs"
-
- # Now substitute the updated list of available tags.
- if eval "sed -e 's/^available_tags=.*\$/available_tags=\"$available_tags\"/' \"$ofile\" > \"${ofile}T\""; then
- mv "${ofile}T" "$ofile"
- chmod +x "$ofile"
- else
- rm -f "${ofile}T"
- AC_MSG_ERROR([unable to update list of available tagged configurations.])
- fi
-fi
-])# _LT_AC_TAGCONFIG
-
-
-# AC_LIBTOOL_DLOPEN
-# -----------------
-# enable checks for dlopen support
-AC_DEFUN([AC_LIBTOOL_DLOPEN],
- [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])
-])# AC_LIBTOOL_DLOPEN
-
-
-# AC_LIBTOOL_WIN32_DLL
-# --------------------
-# declare package support for building win32 DLLs
-AC_DEFUN([AC_LIBTOOL_WIN32_DLL],
-[AC_BEFORE([$0], [AC_LIBTOOL_SETUP])
-])# AC_LIBTOOL_WIN32_DLL
-
-
-# AC_ENABLE_SHARED([DEFAULT])
-# ---------------------------
-# implement the --enable-shared flag
-# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'.
-AC_DEFUN([AC_ENABLE_SHARED],
-[define([AC_ENABLE_SHARED_DEFAULT], ifelse($1, no, no, yes))dnl
-AC_ARG_ENABLE([shared],
- [AC_HELP_STRING([--enable-shared@<:@=PKGS@:>@],
- [build shared libraries @<:@default=]AC_ENABLE_SHARED_DEFAULT[@:>@])],
- [p=${PACKAGE-default}
- case $enableval in
- yes) enable_shared=yes ;;
- no) enable_shared=no ;;
- *)
- enable_shared=no
- # Look at the argument we got. We use all the common list separators.
- lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
- for pkg in $enableval; do
- IFS="$lt_save_ifs"
- if test "X$pkg" = "X$p"; then
- enable_shared=yes
- fi
- done
- IFS="$lt_save_ifs"
- ;;
- esac],
- [enable_shared=]AC_ENABLE_SHARED_DEFAULT)
-])# AC_ENABLE_SHARED
-
-
-# AC_DISABLE_SHARED
-# -----------------
-# set the default shared flag to --disable-shared
-AC_DEFUN([AC_DISABLE_SHARED],
-[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
-AC_ENABLE_SHARED(no)
-])# AC_DISABLE_SHARED
-
-
-# AC_ENABLE_STATIC([DEFAULT])
-# ---------------------------
-# implement the --enable-static flag
-# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'.
-AC_DEFUN([AC_ENABLE_STATIC],
-[define([AC_ENABLE_STATIC_DEFAULT], ifelse($1, no, no, yes))dnl
-AC_ARG_ENABLE([static],
- [AC_HELP_STRING([--enable-static@<:@=PKGS@:>@],
- [build static libraries @<:@default=]AC_ENABLE_STATIC_DEFAULT[@:>@])],
- [p=${PACKAGE-default}
- case $enableval in
- yes) enable_static=yes ;;
- no) enable_static=no ;;
- *)
- enable_static=no
- # Look at the argument we got. We use all the common list separators.
- lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
- for pkg in $enableval; do
- IFS="$lt_save_ifs"
- if test "X$pkg" = "X$p"; then
- enable_static=yes
- fi
- done
- IFS="$lt_save_ifs"
- ;;
- esac],
- [enable_static=]AC_ENABLE_STATIC_DEFAULT)
-])# AC_ENABLE_STATIC
-
-
-# AC_DISABLE_STATIC
-# -----------------
-# set the default static flag to --disable-static
-AC_DEFUN([AC_DISABLE_STATIC],
-[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
-AC_ENABLE_STATIC(no)
-])# AC_DISABLE_STATIC
-
-
-# AC_ENABLE_FAST_INSTALL([DEFAULT])
-# ---------------------------------
-# implement the --enable-fast-install flag
-# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'.
-AC_DEFUN([AC_ENABLE_FAST_INSTALL],
-[define([AC_ENABLE_FAST_INSTALL_DEFAULT], ifelse($1, no, no, yes))dnl
-AC_ARG_ENABLE([fast-install],
- [AC_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@],
- [optimize for fast installation @<:@default=]AC_ENABLE_FAST_INSTALL_DEFAULT[@:>@])],
- [p=${PACKAGE-default}
- case $enableval in
- yes) enable_fast_install=yes ;;
- no) enable_fast_install=no ;;
- *)
- enable_fast_install=no
- # Look at the argument we got. We use all the common list separators.
- lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
- for pkg in $enableval; do
- IFS="$lt_save_ifs"
- if test "X$pkg" = "X$p"; then
- enable_fast_install=yes
- fi
- done
- IFS="$lt_save_ifs"
- ;;
- esac],
- [enable_fast_install=]AC_ENABLE_FAST_INSTALL_DEFAULT)
-])# AC_ENABLE_FAST_INSTALL
-
-
-# AC_DISABLE_FAST_INSTALL
-# -----------------------
-# set the default to --disable-fast-install
-AC_DEFUN([AC_DISABLE_FAST_INSTALL],
-[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
-AC_ENABLE_FAST_INSTALL(no)
-])# AC_DISABLE_FAST_INSTALL
-
-
-# AC_LIBTOOL_PICMODE([MODE])
-# --------------------------
-# implement the --with-pic flag
-# MODE is either `yes' or `no'. If omitted, it defaults to `both'.
-AC_DEFUN([AC_LIBTOOL_PICMODE],
-[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
-pic_mode=ifelse($#,1,$1,default)
-])# AC_LIBTOOL_PICMODE
-
-
-# AC_PROG_EGREP
-# -------------
-# This is predefined starting with Autoconf 2.54, so this conditional
-# definition can be removed once we require Autoconf 2.54 or later.
-m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP],
-[AC_CACHE_CHECK([for egrep], [ac_cv_prog_egrep],
- [if echo a | (grep -E '(a|b)') >/dev/null 2>&1
- then ac_cv_prog_egrep='grep -E'
- else ac_cv_prog_egrep='egrep'
- fi])
- EGREP=$ac_cv_prog_egrep
- AC_SUBST([EGREP])
-])])
-
-
-# AC_PATH_TOOL_PREFIX
-# -------------------
-# find a file program which can recognize shared library
-AC_DEFUN([AC_PATH_TOOL_PREFIX],
-[AC_REQUIRE([AC_PROG_EGREP])dnl
-AC_MSG_CHECKING([for $1])
-AC_CACHE_VAL(lt_cv_path_MAGIC_CMD,
-[case $MAGIC_CMD in
-[[\\/*] | ?:[\\/]*])
- lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
- ;;
-*)
- lt_save_MAGIC_CMD="$MAGIC_CMD"
- lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
-dnl $ac_dummy forces splitting on constant user-supplied paths.
-dnl POSIX.2 word splitting is done only on the output of word expansions,
-dnl not every word. This closes a longstanding sh security hole.
- ac_dummy="ifelse([$2], , $PATH, [$2])"
- for ac_dir in $ac_dummy; do
- IFS="$lt_save_ifs"
- test -z "$ac_dir" && ac_dir=.
- if test -f $ac_dir/$1; then
- lt_cv_path_MAGIC_CMD="$ac_dir/$1"
- if test -n "$file_magic_test_file"; then
- case $deplibs_check_method in
- "file_magic "*)
- file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
- MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
- if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
- $EGREP "$file_magic_regex" > /dev/null; then
- :
- else
- cat <<EOF 1>&2
-
-*** Warning: the command libtool uses to detect shared libraries,
-*** $file_magic_cmd, produces output that libtool cannot recognize.
-*** The result is that libtool may fail to recognize shared libraries
-*** as such. This will affect the creation of libtool libraries that
-*** depend on shared libraries, but programs linked with such libtool
-*** libraries will work regardless of this problem. Nevertheless, you
-*** may want to report the problem to your system manager and/or to
-*** bug-libtool@gnu.org
-
-EOF
- fi ;;
- esac
- fi
- break
- fi
- done
- IFS="$lt_save_ifs"
- MAGIC_CMD="$lt_save_MAGIC_CMD"
- ;;
-esac])
-MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
-if test -n "$MAGIC_CMD"; then
- AC_MSG_RESULT($MAGIC_CMD)
-else
- AC_MSG_RESULT(no)
-fi
-])# AC_PATH_TOOL_PREFIX
-
-
-# AC_PATH_MAGIC
-# -------------
-# find a file program which can recognize a shared library
-AC_DEFUN([AC_PATH_MAGIC],
-[AC_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH)
-if test -z "$lt_cv_path_MAGIC_CMD"; then
- if test -n "$ac_tool_prefix"; then
- AC_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH)
- else
- MAGIC_CMD=:
- fi
-fi
-])# AC_PATH_MAGIC
-
-
-# AC_PROG_LD
-# ----------
-# find the pathname to the GNU or non-GNU linker
-AC_DEFUN([AC_PROG_LD],
-[AC_ARG_WITH([gnu-ld],
- [AC_HELP_STRING([--with-gnu-ld],
- [assume the C compiler uses GNU ld @<:@default=no@:>@])],
- [test "$withval" = no || with_gnu_ld=yes],
- [with_gnu_ld=no])
-AC_REQUIRE([LT_AC_PROG_SED])dnl
-AC_REQUIRE([AC_PROG_CC])dnl
-AC_REQUIRE([AC_CANONICAL_HOST])dnl
-AC_REQUIRE([AC_CANONICAL_BUILD])dnl
-ac_prog=ld
-if test "$GCC" = yes; then
- # Check if gcc -print-prog-name=ld gives a path.
- AC_MSG_CHECKING([for ld used by $CC])
- case $host in
- *-*-mingw*)
- # gcc leaves a trailing carriage return which upsets mingw
- ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
- *)
- ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
- esac
- case $ac_prog in
- # Accept absolute paths.
- [[\\/]]* | ?:[[\\/]]*)
- re_direlt='/[[^/]][[^/]]*/\.\./'
- # Canonicalize the pathname of ld
- ac_prog=`echo $ac_prog| $SED 's%\\\\%/%g'`
- while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
- ac_prog=`echo $ac_prog| $SED "s%$re_direlt%/%"`
- done
- test -z "$LD" && LD="$ac_prog"
- ;;
- "")
- # If it fails, then pretend we aren't using GCC.
- ac_prog=ld
- ;;
- *)
- # If it is relative, then search for the first ld in PATH.
- with_gnu_ld=unknown
- ;;
- esac
-elif test "$with_gnu_ld" = yes; then
- AC_MSG_CHECKING([for GNU ld])
-else
- AC_MSG_CHECKING([for non-GNU ld])
-fi
-AC_CACHE_VAL(lt_cv_path_LD,
-[if test -z "$LD"; then
- lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
- for ac_dir in $PATH; do
- IFS="$lt_save_ifs"
- test -z "$ac_dir" && ac_dir=.
- if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
- lt_cv_path_LD="$ac_dir/$ac_prog"
- # Check to see if the program is GNU ld. I'd rather use --version,
- # but apparently some variants of GNU ld only accept -v.
- # Break only if it was the GNU/non-GNU ld that we prefer.
- case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
- *GNU* | *'with BFD'*)
- test "$with_gnu_ld" != no && break
- ;;
- *)
- test "$with_gnu_ld" != yes && break
- ;;
- esac
- fi
- done
- IFS="$lt_save_ifs"
-else
- lt_cv_path_LD="$LD" # Let the user override the test with a path.
-fi])
-LD="$lt_cv_path_LD"
-if test -n "$LD"; then
- AC_MSG_RESULT($LD)
-else
- AC_MSG_RESULT(no)
-fi
-test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
-AC_PROG_LD_GNU
-])# AC_PROG_LD
-
-
-# AC_PROG_LD_GNU
-# --------------
-AC_DEFUN([AC_PROG_LD_GNU],
-[AC_REQUIRE([AC_PROG_EGREP])dnl
-AC_CACHE_CHECK([if the linker ($LD) is GNU ld], lt_cv_prog_gnu_ld,
-[# I'd rather use --version here, but apparently some GNU lds only accept -v.
-case `$LD -v 2>&1 </dev/null` in
-*GNU* | *'with BFD'*)
- lt_cv_prog_gnu_ld=yes
- ;;
-*)
- lt_cv_prog_gnu_ld=no
- ;;
-esac])
-with_gnu_ld=$lt_cv_prog_gnu_ld
-])# AC_PROG_LD_GNU
-
-
-# AC_PROG_LD_RELOAD_FLAG
-# ----------------------
-# find reload flag for linker
-# -- PORTME Some linkers may need a different reload flag.
-AC_DEFUN([AC_PROG_LD_RELOAD_FLAG],
-[AC_CACHE_CHECK([for $LD option to reload object files],
- lt_cv_ld_reload_flag,
- [lt_cv_ld_reload_flag='-r'])
-reload_flag=$lt_cv_ld_reload_flag
-case $reload_flag in
-"" | " "*) ;;
-*) reload_flag=" $reload_flag" ;;
-esac
-reload_cmds='$LD$reload_flag -o $output$reload_objs'
-case $host_os in
- darwin*)
- if test "$GCC" = yes; then
- reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs'
- else
- reload_cmds='$LD$reload_flag -o $output$reload_objs'
- fi
- ;;
-esac
-])# AC_PROG_LD_RELOAD_FLAG
-
-
-# AC_DEPLIBS_CHECK_METHOD
-# -----------------------
-# how to check for library dependencies
-# -- PORTME fill in with the dynamic library characteristics
-AC_DEFUN([AC_DEPLIBS_CHECK_METHOD],
-[AC_CACHE_CHECK([how to recognize dependent libraries],
-lt_cv_deplibs_check_method,
-[lt_cv_file_magic_cmd='$MAGIC_CMD'
-lt_cv_file_magic_test_file=
-lt_cv_deplibs_check_method='unknown'
-# Need to set the preceding variable on all platforms that support
-# interlibrary dependencies.
-# 'none' -- dependencies not supported.
-# `unknown' -- same as none, but documents that we really don't know.
-# 'pass_all' -- all dependencies passed with no checks.
-# 'test_compile' -- check by making test program.
-# 'file_magic [[regex]]' -- check by looking for files in library path
-# which responds to the $file_magic_cmd with a given extended regex.
-# If you have `file' or equivalent on your system and you're not sure
-# whether `pass_all' will *always* work, you probably want this one.
-
-case $host_os in
-aix[[4-9]]*)
- lt_cv_deplibs_check_method=pass_all
- ;;
-
-beos*)
- lt_cv_deplibs_check_method=pass_all
- ;;
-
-bsdi[[45]]*)
- lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)'
- lt_cv_file_magic_cmd='/usr/bin/file -L'
- lt_cv_file_magic_test_file=/shlib/libc.so
- ;;
-
-cygwin*)
- # func_win32_libid is a shell function defined in ltmain.sh
- lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
- lt_cv_file_magic_cmd='func_win32_libid'
- ;;
-
-mingw* | pw32*)
- # Base MSYS/MinGW do not provide the 'file' command needed by
- # func_win32_libid shell function, so use a weaker test based on 'objdump',
- # unless we find 'file', for example because we are cross-compiling.
- if ( file / ) >/dev/null 2>&1; then
- lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
- lt_cv_file_magic_cmd='func_win32_libid'
- else
- lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'
- lt_cv_file_magic_cmd='$OBJDUMP -f'
- fi
- ;;
-
-darwin* | rhapsody*)
- lt_cv_deplibs_check_method=pass_all
- ;;
-
-freebsd* | dragonfly*)
- if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then
- case $host_cpu in
- i*86 )
- # Not sure whether the presence of OpenBSD here was a mistake.
- # Let's accept both of them until this is cleared up.
- lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library'
- lt_cv_file_magic_cmd=/usr/bin/file
- lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
- ;;
- esac
- else
- lt_cv_deplibs_check_method=pass_all
- fi
- ;;
-
-gnu*)
- lt_cv_deplibs_check_method=pass_all
- ;;
-
-hpux10.20* | hpux11*)
- lt_cv_file_magic_cmd=/usr/bin/file
- case $host_cpu in
- ia64*)
- lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64'
- lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
- ;;
- hppa*64*)
- [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]']
- lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl
- ;;
- *)
- lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]].[[0-9]]) shared library'
- lt_cv_file_magic_test_file=/usr/lib/libc.sl
- ;;
- esac
- ;;
-
-interix[[3-9]]*)
- # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here
- lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$'
- ;;
-
-irix5* | irix6* | nonstopux*)
- case $LD in
- *-32|*"-32 ") libmagic=32-bit;;
- *-n32|*"-n32 ") libmagic=N32;;
- *-64|*"-64 ") libmagic=64-bit;;
- *) libmagic=never-match;;
- esac
- lt_cv_deplibs_check_method=pass_all
- ;;
-
-# This must be Linux ELF.
-linux* | k*bsd*-gnu)
- lt_cv_deplibs_check_method=pass_all
- ;;
-
-netbsd*)
- if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then
- lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
- else
- lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$'
- fi
- ;;
-
-newos6*)
- lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)'
- lt_cv_file_magic_cmd=/usr/bin/file
- lt_cv_file_magic_test_file=/usr/lib/libnls.so
- ;;
-
-nto-qnx*)
- lt_cv_deplibs_check_method=unknown
- ;;
-
-openbsd*)
- if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
- lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$'
- else
- lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
- fi
- ;;
-
-osf3* | osf4* | osf5*)
- lt_cv_deplibs_check_method=pass_all
- ;;
-
-rdos*)
- lt_cv_deplibs_check_method=pass_all
- ;;
-
-solaris*)
- lt_cv_deplibs_check_method=pass_all
- ;;
-
-sysv4 | sysv4.3*)
- case $host_vendor in
- motorola)
- lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]'
- lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
- ;;
- ncr)
- lt_cv_deplibs_check_method=pass_all
- ;;
- sequent)
- lt_cv_file_magic_cmd='/bin/file'
- lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )'
- ;;
- sni)
- lt_cv_file_magic_cmd='/bin/file'
- lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib"
- lt_cv_file_magic_test_file=/lib/libc.so
- ;;
- siemens)
- lt_cv_deplibs_check_method=pass_all
- ;;
- pc)
- lt_cv_deplibs_check_method=pass_all
- ;;
- esac
- ;;
-
-sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
- lt_cv_deplibs_check_method=pass_all
- ;;
-esac
-])
-file_magic_cmd=$lt_cv_file_magic_cmd
-deplibs_check_method=$lt_cv_deplibs_check_method
-test -z "$deplibs_check_method" && deplibs_check_method=unknown
-])# AC_DEPLIBS_CHECK_METHOD
-
-
-# AC_PROG_NM
-# ----------
-# find the pathname to a BSD-compatible name lister
-AC_DEFUN([AC_PROG_NM],
-[AC_CACHE_CHECK([for BSD-compatible nm], lt_cv_path_NM,
-[if test -n "$NM"; then
- # Let the user override the test.
- lt_cv_path_NM="$NM"
-else
- lt_nm_to_check="${ac_tool_prefix}nm"
- if test -n "$ac_tool_prefix" && test "$build" = "$host"; then
- lt_nm_to_check="$lt_nm_to_check nm"
- fi
- for lt_tmp_nm in $lt_nm_to_check; do
- lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
- for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do
- IFS="$lt_save_ifs"
- test -z "$ac_dir" && ac_dir=.
- tmp_nm="$ac_dir/$lt_tmp_nm"
- if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then
- # Check to see if the nm accepts a BSD-compat flag.
- # Adding the `sed 1q' prevents false positives on HP-UX, which says:
- # nm: unknown option "B" ignored
- # Tru64's nm complains that /dev/null is an invalid object file
- case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in
- */dev/null* | *'Invalid file or object type'*)
- lt_cv_path_NM="$tmp_nm -B"
- break
- ;;
- *)
- case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
- */dev/null*)
- lt_cv_path_NM="$tmp_nm -p"
- break
- ;;
- *)
- lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
- continue # so that we can try to find one that supports BSD flags
- ;;
- esac
- ;;
- esac
- fi
- done
- IFS="$lt_save_ifs"
- done
- test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm
-fi])
-NM="$lt_cv_path_NM"
-])# AC_PROG_NM
-
-
-# AC_CHECK_LIBM
-# -------------
-# check for math library
-AC_DEFUN([AC_CHECK_LIBM],
-[AC_REQUIRE([AC_CANONICAL_HOST])dnl
-LIBM=
-case $host in
-*-*-beos* | *-*-cygwin* | *-*-pw32* | *-*-darwin*)
- # These system don't have libm, or don't need it
- ;;
-*-ncr-sysv4.3*)
- AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw")
- AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm")
- ;;
-*)
- AC_CHECK_LIB(m, cos, LIBM="-lm")
- ;;
-esac
-])# AC_CHECK_LIBM
-
-
-# AC_LIBLTDL_CONVENIENCE([DIRECTORY])
-# -----------------------------------
-# sets LIBLTDL to the link flags for the libltdl convenience library and
-# LTDLINCL to the include flags for the libltdl header and adds
-# --enable-ltdl-convenience to the configure arguments. Note that
-# AC_CONFIG_SUBDIRS is not called here. If DIRECTORY is not provided,
-# it is assumed to be `libltdl'. LIBLTDL will be prefixed with
-# '${top_builddir}/' and LTDLINCL will be prefixed with '${top_srcdir}/'
-# (note the single quotes!). If your package is not flat and you're not
-# using automake, define top_builddir and top_srcdir appropriately in
-# the Makefiles.
-AC_DEFUN([AC_LIBLTDL_CONVENIENCE],
-[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
- case $enable_ltdl_convenience in
- no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;;
- "") enable_ltdl_convenience=yes
- ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;;
- esac
- LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdlc.la
- LTDLINCL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl'])
- # For backwards non-gettext consistent compatibility...
- INCLTDL="$LTDLINCL"
-])# AC_LIBLTDL_CONVENIENCE
-
-
-# AC_LIBLTDL_INSTALLABLE([DIRECTORY])
-# -----------------------------------
-# sets LIBLTDL to the link flags for the libltdl installable library and
-# LTDLINCL to the include flags for the libltdl header and adds
-# --enable-ltdl-install to the configure arguments. Note that
-# AC_CONFIG_SUBDIRS is not called here. If DIRECTORY is not provided,
-# and an installed libltdl is not found, it is assumed to be `libltdl'.
-# LIBLTDL will be prefixed with '${top_builddir}/'# and LTDLINCL with
-# '${top_srcdir}/' (note the single quotes!). If your package is not
-# flat and you're not using automake, define top_builddir and top_srcdir
-# appropriately in the Makefiles.
-# In the future, this macro may have to be called after AC_PROG_LIBTOOL.
-AC_DEFUN([AC_LIBLTDL_INSTALLABLE],
-[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
- AC_CHECK_LIB(ltdl, lt_dlinit,
- [test x"$enable_ltdl_install" != xyes && enable_ltdl_install=no],
- [if test x"$enable_ltdl_install" = xno; then
- AC_MSG_WARN([libltdl not installed, but installation disabled])
- else
- enable_ltdl_install=yes
- fi
- ])
- if test x"$enable_ltdl_install" = x"yes"; then
- ac_configure_args="$ac_configure_args --enable-ltdl-install"
- LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdl.la
- LTDLINCL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl'])
- else
- ac_configure_args="$ac_configure_args --enable-ltdl-install=no"
- LIBLTDL="-lltdl"
- LTDLINCL=
- fi
- # For backwards non-gettext consistent compatibility...
- INCLTDL="$LTDLINCL"
-])# AC_LIBLTDL_INSTALLABLE
-
-
-# AC_LIBTOOL_CXX
-# --------------
-# enable support for C++ libraries
-AC_DEFUN([AC_LIBTOOL_CXX],
-[AC_REQUIRE([_LT_AC_LANG_CXX])
-])# AC_LIBTOOL_CXX
-
-
-# _LT_AC_LANG_CXX
-# ---------------
-AC_DEFUN([_LT_AC_LANG_CXX],
-[AC_REQUIRE([AC_PROG_CXX])
-AC_REQUIRE([_LT_AC_PROG_CXXCPP])
-_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}CXX])
-])# _LT_AC_LANG_CXX
-
-# _LT_AC_PROG_CXXCPP
-# ------------------
-AC_DEFUN([_LT_AC_PROG_CXXCPP],
-[
-AC_REQUIRE([AC_PROG_CXX])
-if test -n "$CXX" && ( test "X$CXX" != "Xno" &&
- ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) ||
- (test "X$CXX" != "Xg++"))) ; then
- AC_PROG_CXXCPP
-fi
-])# _LT_AC_PROG_CXXCPP
-
-# AC_LIBTOOL_F77
-# --------------
-# enable support for Fortran 77 libraries
-AC_DEFUN([AC_LIBTOOL_F77],
-[AC_REQUIRE([_LT_AC_LANG_F77])
-])# AC_LIBTOOL_F77
-
-
-# _LT_AC_LANG_F77
-# ---------------
-AC_DEFUN([_LT_AC_LANG_F77],
-[AC_REQUIRE([AC_PROG_F77])
-_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}F77])
-])# _LT_AC_LANG_F77
-
-
-# AC_LIBTOOL_GCJ
-# --------------
-# enable support for GCJ libraries
-AC_DEFUN([AC_LIBTOOL_GCJ],
-[AC_REQUIRE([_LT_AC_LANG_GCJ])
-])# AC_LIBTOOL_GCJ
-
-
-# _LT_AC_LANG_GCJ
-# ---------------
-AC_DEFUN([_LT_AC_LANG_GCJ],
-[AC_PROVIDE_IFELSE([AC_PROG_GCJ],[],
- [AC_PROVIDE_IFELSE([A][M_PROG_GCJ],[],
- [AC_PROVIDE_IFELSE([LT_AC_PROG_GCJ],[],
- [ifdef([AC_PROG_GCJ],[AC_REQUIRE([AC_PROG_GCJ])],
- [ifdef([A][M_PROG_GCJ],[AC_REQUIRE([A][M_PROG_GCJ])],
- [AC_REQUIRE([A][C_PROG_GCJ_OR_A][M_PROG_GCJ])])])])])])
-_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}GCJ])
-])# _LT_AC_LANG_GCJ
-
-
-# AC_LIBTOOL_RC
-# -------------
-# enable support for Windows resource files
-AC_DEFUN([AC_LIBTOOL_RC],
-[AC_REQUIRE([LT_AC_PROG_RC])
-_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}RC])
-])# AC_LIBTOOL_RC
-
-
-# AC_LIBTOOL_LANG_C_CONFIG
-# ------------------------
-# Ensure that the configuration vars for the C compiler are
-# suitably defined. Those variables are subsequently used by
-# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'.
-AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG], [_LT_AC_LANG_C_CONFIG])
-AC_DEFUN([_LT_AC_LANG_C_CONFIG],
-[lt_save_CC="$CC"
-AC_LANG_PUSH(C)
-
-# Source file extension for C test sources.
-ac_ext=c
-
-# Object file extension for compiled C test sources.
-objext=o
-_LT_AC_TAGVAR(objext, $1)=$objext
-
-# Code to be used in simple compile tests
-lt_simple_compile_test_code="int some_variable = 0;"
-
-# Code to be used in simple link tests
-lt_simple_link_test_code='int main(){return(0);}'
-
-_LT_AC_SYS_COMPILER
-
-# save warnings/boilerplate of simple test code
-_LT_COMPILER_BOILERPLATE
-_LT_LINKER_BOILERPLATE
-
-AC_LIBTOOL_PROG_COMPILER_NO_RTTI($1)
-AC_LIBTOOL_PROG_COMPILER_PIC($1)
-AC_LIBTOOL_PROG_CC_C_O($1)
-AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1)
-AC_LIBTOOL_PROG_LD_SHLIBS($1)
-AC_LIBTOOL_SYS_DYNAMIC_LINKER($1)
-AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1)
-AC_LIBTOOL_SYS_LIB_STRIP
-AC_LIBTOOL_DLOPEN_SELF
-
-# Report which library types will actually be built
-AC_MSG_CHECKING([if libtool supports shared libraries])
-AC_MSG_RESULT([$can_build_shared])
-
-AC_MSG_CHECKING([whether to build shared libraries])
-test "$can_build_shared" = "no" && enable_shared=no
-
-# On AIX, shared libraries and static libraries use the same namespace, and
-# are all built from PIC.
-case $host_os in
-aix3*)
- test "$enable_shared" = yes && enable_static=no
- if test -n "$RANLIB"; then
- archive_cmds="$archive_cmds~\$RANLIB \$lib"
- postinstall_cmds='$RANLIB $lib'
- fi
- ;;
-
-aix[[4-9]]*)
- if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
- test "$enable_shared" = yes && enable_static=no
- fi
- ;;
-esac
-AC_MSG_RESULT([$enable_shared])
-
-AC_MSG_CHECKING([whether to build static libraries])
-# Make sure either enable_shared or enable_static is yes.
-test "$enable_shared" = yes || enable_static=yes
-AC_MSG_RESULT([$enable_static])
-
-AC_LIBTOOL_CONFIG($1)
-
-AC_LANG_POP
-CC="$lt_save_CC"
-])# AC_LIBTOOL_LANG_C_CONFIG
-
-
-# AC_LIBTOOL_LANG_CXX_CONFIG
-# --------------------------
-# Ensure that the configuration vars for the C compiler are
-# suitably defined. Those variables are subsequently used by
-# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'.
-AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG], [_LT_AC_LANG_CXX_CONFIG(CXX)])
-AC_DEFUN([_LT_AC_LANG_CXX_CONFIG],
-[AC_LANG_PUSH(C++)
-AC_REQUIRE([AC_PROG_CXX])
-AC_REQUIRE([_LT_AC_PROG_CXXCPP])
-
-_LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
-_LT_AC_TAGVAR(allow_undefined_flag, $1)=
-_LT_AC_TAGVAR(always_export_symbols, $1)=no
-_LT_AC_TAGVAR(archive_expsym_cmds, $1)=
-_LT_AC_TAGVAR(export_dynamic_flag_spec, $1)=
-_LT_AC_TAGVAR(hardcode_direct, $1)=no
-_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)=
-_LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=
-_LT_AC_TAGVAR(hardcode_libdir_separator, $1)=
-_LT_AC_TAGVAR(hardcode_minus_L, $1)=no
-_LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
-_LT_AC_TAGVAR(hardcode_automatic, $1)=no
-_LT_AC_TAGVAR(module_cmds, $1)=
-_LT_AC_TAGVAR(module_expsym_cmds, $1)=
-_LT_AC_TAGVAR(link_all_deplibs, $1)=unknown
-_LT_AC_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
-_LT_AC_TAGVAR(no_undefined_flag, $1)=
-_LT_AC_TAGVAR(whole_archive_flag_spec, $1)=
-_LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=no
-
-# Dependencies to place before and after the object being linked:
-_LT_AC_TAGVAR(predep_objects, $1)=
-_LT_AC_TAGVAR(postdep_objects, $1)=
-_LT_AC_TAGVAR(predeps, $1)=
-_LT_AC_TAGVAR(postdeps, $1)=
-_LT_AC_TAGVAR(compiler_lib_search_path, $1)=
-_LT_AC_TAGVAR(compiler_lib_search_dirs, $1)=
-
-# Source file extension for C++ test sources.
-ac_ext=cpp
-
-# Object file extension for compiled C++ test sources.
-objext=o
-_LT_AC_TAGVAR(objext, $1)=$objext
-
-# Code to be used in simple compile tests
-lt_simple_compile_test_code="int some_variable = 0;"
-
-# Code to be used in simple link tests
-lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }'
-
-# ltmain only uses $CC for tagged configurations so make sure $CC is set.
-_LT_AC_SYS_COMPILER
-
-# save warnings/boilerplate of simple test code
-_LT_COMPILER_BOILERPLATE
-_LT_LINKER_BOILERPLATE
-
-# Allow CC to be a program name with arguments.
-lt_save_CC=$CC
-lt_save_LD=$LD
-lt_save_GCC=$GCC
-GCC=$GXX
-lt_save_with_gnu_ld=$with_gnu_ld
-lt_save_path_LD=$lt_cv_path_LD
-if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then
- lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx
-else
- $as_unset lt_cv_prog_gnu_ld
-fi
-if test -n "${lt_cv_path_LDCXX+set}"; then
- lt_cv_path_LD=$lt_cv_path_LDCXX
-else
- $as_unset lt_cv_path_LD
-fi
-test -z "${LDCXX+set}" || LD=$LDCXX
-CC=${CXX-"c++"}
-compiler=$CC
-_LT_AC_TAGVAR(compiler, $1)=$CC
-_LT_CC_BASENAME([$compiler])
-
-# We don't want -fno-exception wen compiling C++ code, so set the
-# no_builtin_flag separately
-if test "$GXX" = yes; then
- _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin'
-else
- _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
-fi
-
-if test "$GXX" = yes; then
- # Set up default GNU C++ configuration
-
- AC_PROG_LD
-
- # Check if GNU C++ uses GNU ld as the underlying linker, since the
- # archiving commands below assume that GNU ld is being used.
- if test "$with_gnu_ld" = yes; then
- _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
- _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
-
- _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir'
- _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
-
- # If archive_cmds runs LD, not CC, wlarc should be empty
- # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to
- # investigate it a little bit more. (MM)
- wlarc='${wl}'
-
- # ancient GNU ld didn't support --whole-archive et. al.
- if eval "`$CC -print-prog-name=ld` --help 2>&1" | \
- grep 'no-whole-archive' > /dev/null; then
- _LT_AC_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
- else
- _LT_AC_TAGVAR(whole_archive_flag_spec, $1)=
- fi
- else
- with_gnu_ld=no
- wlarc=
-
- # A generic and very simple default shared library creation
- # command for GNU C++ for the case where it uses the native
- # linker, instead of GNU ld. If possible, this setting should
- # overridden to take advantage of the native linker features on
- # the platform it is being used on.
- _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
- fi
-
- # Commands to make compiler produce verbose output that lists
- # what "hidden" libraries, object files and flags are used when
- # linking a shared library.
- output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"'
-
-else
- GXX=no
- with_gnu_ld=no
- wlarc=
-fi
-
-# PORTME: fill in a description of your system's C++ link characteristics
-AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries])
-_LT_AC_TAGVAR(ld_shlibs, $1)=yes
-case $host_os in
- aix3*)
- # FIXME: insert proper C++ library support
- _LT_AC_TAGVAR(ld_shlibs, $1)=no
- ;;
- aix[[4-9]]*)
- if test "$host_cpu" = ia64; then
- # On IA64, the linker does run time linking by default, so we don't
- # have to do anything special.
- aix_use_runtimelinking=no
- exp_sym_flag='-Bexport'
- no_entry_flag=""
- else
- aix_use_runtimelinking=no
-
- # Test if we are trying to use run time linking or normal
- # AIX style linking. If -brtl is somewhere in LDFLAGS, we
- # need to do runtime linking.
- case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*)
- for ld_flag in $LDFLAGS; do
- case $ld_flag in
- *-brtl*)
- aix_use_runtimelinking=yes
- break
- ;;
- esac
- done
- ;;
- esac
-
- exp_sym_flag='-bexport'
- no_entry_flag='-bnoentry'
- fi
-
- # When large executables or shared objects are built, AIX ld can
- # have problems creating the table of contents. If linking a library
- # or program results in "error TOC overflow" add -mminimal-toc to
- # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not
- # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
-
- _LT_AC_TAGVAR(archive_cmds, $1)=''
- _LT_AC_TAGVAR(hardcode_direct, $1)=yes
- _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':'
- _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
-
- if test "$GXX" = yes; then
- case $host_os in aix4.[[012]]|aix4.[[012]].*)
- # We only want to do this on AIX 4.2 and lower, the check
- # below for broken collect2 doesn't work under 4.3+
- collect2name=`${CC} -print-prog-name=collect2`
- if test -f "$collect2name" && \
- strings "$collect2name" | grep resolve_lib_name >/dev/null
- then
- # We have reworked collect2
- :
- else
- # We have old collect2
- _LT_AC_TAGVAR(hardcode_direct, $1)=unsupported
- # It fails to find uninstalled libraries when the uninstalled
- # path is not listed in the libpath. Setting hardcode_minus_L
- # to unsupported forces relinking
- _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
- _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
- _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=
- fi
- ;;
- esac
- shared_flag='-shared'
- if test "$aix_use_runtimelinking" = yes; then
- shared_flag="$shared_flag "'${wl}-G'
- fi
- else
- # not using gcc
- if test "$host_cpu" = ia64; then
- # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
- # chokes on -Wl,-G. The following line is correct:
- shared_flag='-G'
- else
- if test "$aix_use_runtimelinking" = yes; then
- shared_flag='${wl}-G'
- else
- shared_flag='${wl}-bM:SRE'
- fi
- fi
- fi
-
- # It seems that -bexpall does not export symbols beginning with
- # underscore (_), so it is better to generate a list of symbols to export.
- _LT_AC_TAGVAR(always_export_symbols, $1)=yes
- if test "$aix_use_runtimelinking" = yes; then
- # Warning - without using the other runtime loading flags (-brtl),
- # -berok will link without error, but may produce a broken library.
- _LT_AC_TAGVAR(allow_undefined_flag, $1)='-berok'
- # Determine the default libpath from the value encoded in an empty executable.
- _LT_AC_SYS_LIBPATH_AIX
- _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
-
- _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
- else
- if test "$host_cpu" = ia64; then
- _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib'
- _LT_AC_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
- _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
- else
- # Determine the default libpath from the value encoded in an empty executable.
- _LT_AC_SYS_LIBPATH_AIX
- _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
- # Warning - without using the other run time loading flags,
- # -berok will link without error, but may produce a broken library.
- _LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok'
- _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok'
- # Exported symbols can be pulled into shared objects from archives
- _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
- _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes
- # This is similar to how AIX traditionally builds its shared libraries.
- _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
- fi
- fi
- ;;
-
- beos*)
- if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
- _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported
- # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
- # support --undefined. This deserves some investigation. FIXME
- _LT_AC_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- else
- _LT_AC_TAGVAR(ld_shlibs, $1)=no
- fi
- ;;
-
- chorus*)
- case $cc_basename in
- *)
- # FIXME: insert proper C++ library support
- _LT_AC_TAGVAR(ld_shlibs, $1)=no
- ;;
- esac
- ;;
-
- cygwin* | mingw* | pw32*)
- # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
- # as there is no search path for DLLs.
- _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
- _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported
- _LT_AC_TAGVAR(always_export_symbols, $1)=no
- _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
-
- if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then
- _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
- # If the export-symbols file already is a .def file (1st line
- # is EXPORTS), use it as is; otherwise, prepend...
- _LT_AC_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
- cp $export_symbols $output_objdir/$soname.def;
- else
- echo EXPORTS > $output_objdir/$soname.def;
- cat $export_symbols >> $output_objdir/$soname.def;
- fi~
- $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
- else
- _LT_AC_TAGVAR(ld_shlibs, $1)=no
- fi
- ;;
- darwin* | rhapsody*)
- _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
- _LT_AC_TAGVAR(hardcode_direct, $1)=no
- _LT_AC_TAGVAR(hardcode_automatic, $1)=yes
- _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
- _LT_AC_TAGVAR(whole_archive_flag_spec, $1)=''
- _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
- _LT_AC_TAGVAR(allow_undefined_flag, $1)="$_lt_dar_allow_undefined"
- if test "$GXX" = yes ; then
- output_verbose_link_cmd='echo'
- _LT_AC_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
- _LT_AC_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
- _LT_AC_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
- _LT_AC_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}"
- if test "$lt_cv_apple_cc_single_mod" != "yes"; then
- _LT_AC_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}"
- _LT_AC_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}"
- fi
- else
- case $cc_basename in
- xlc*)
- output_verbose_link_cmd='echo'
- _LT_AC_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $xlcverstring'
- _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
- # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds
- _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $xlcverstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
- _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
- ;;
- *)
- _LT_AC_TAGVAR(ld_shlibs, $1)=no
- ;;
- esac
- fi
- ;;
-
- dgux*)
- case $cc_basename in
- ec++*)
- # FIXME: insert proper C++ library support
- _LT_AC_TAGVAR(ld_shlibs, $1)=no
- ;;
- ghcx*)
- # Green Hills C++ Compiler
- # FIXME: insert proper C++ library support
- _LT_AC_TAGVAR(ld_shlibs, $1)=no
- ;;
- *)
- # FIXME: insert proper C++ library support
- _LT_AC_TAGVAR(ld_shlibs, $1)=no
- ;;
- esac
- ;;
- freebsd[[12]]*)
- # C++ shared libraries reported to be fairly broken before switch to ELF
- _LT_AC_TAGVAR(ld_shlibs, $1)=no
- ;;
- freebsd-elf*)
- _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
- ;;
- freebsd* | dragonfly*)
- # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF
- # conventions
- _LT_AC_TAGVAR(ld_shlibs, $1)=yes
- ;;
- gnu*)
- ;;
- hpux9*)
- _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
- _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
- _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
- _LT_AC_TAGVAR(hardcode_direct, $1)=yes
- _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
- # but as the default
- # location of the library.
-
- case $cc_basename in
- CC*)
- # FIXME: insert proper C++ library support
- _LT_AC_TAGVAR(ld_shlibs, $1)=no
- ;;
- aCC*)
- _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
- # Commands to make compiler produce verbose output that lists
- # what "hidden" libraries, object files and flags are used when
- # linking a shared library.
- #
- # There doesn't appear to be a way to prevent this compiler from
- # explicitly linking system object files so we need to strip them
- # from the output so that they don't get included in the library
- # dependencies.
- output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "[[-]]L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
- ;;
- *)
- if test "$GXX" = yes; then
- _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
- else
- # FIXME: insert proper C++ library support
- _LT_AC_TAGVAR(ld_shlibs, $1)=no
- fi
- ;;
- esac
- ;;
- hpux10*|hpux11*)
- if test $with_gnu_ld = no; then
- _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
- _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
-
- case $host_cpu in
- hppa*64*|ia64*) ;;
- *)
- _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
- ;;
- esac
- fi
- case $host_cpu in
- hppa*64*|ia64*)
- _LT_AC_TAGVAR(hardcode_direct, $1)=no
- _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
- ;;
- *)
- _LT_AC_TAGVAR(hardcode_direct, $1)=yes
- _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
- # but as the default
- # location of the library.
- ;;
- esac
-
- case $cc_basename in
- CC*)
- # FIXME: insert proper C++ library support
- _LT_AC_TAGVAR(ld_shlibs, $1)=no
- ;;
- aCC*)
- case $host_cpu in
- hppa*64*)
- _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
- ;;
- ia64*)
- _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
- ;;
- *)
- _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
- ;;
- esac
- # Commands to make compiler produce verbose output that lists
- # what "hidden" libraries, object files and flags are used when
- # linking a shared library.
- #
- # There doesn't appear to be a way to prevent this compiler from
- # explicitly linking system object files so we need to strip them
- # from the output so that they don't get included in the library
- # dependencies.
- output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
- ;;
- *)
- if test "$GXX" = yes; then
- if test $with_gnu_ld = no; then
- case $host_cpu in
- hppa*64*)
- _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
- ;;
- ia64*)
- _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
- ;;
- *)
- _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
- ;;
- esac
- fi
- else
- # FIXME: insert proper C++ library support
- _LT_AC_TAGVAR(ld_shlibs, $1)=no
- fi
- ;;
- esac
- ;;
- interix[[3-9]]*)
- _LT_AC_TAGVAR(hardcode_direct, $1)=no
- _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
- _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
- _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
- # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
- # Instead, shared libraries are loaded at an image base (0x10000000 by
- # default) and relocated if they conflict, which is a slow very memory
- # consuming and fragmenting process. To avoid this, we pick a random,
- # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
- # time. Moving up from 0x10000000 also allows more sbrk(2) space.
- _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
- _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
- ;;
- irix5* | irix6*)
- case $cc_basename in
- CC*)
- # SGI C++
- _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
-
- # Archives containing C++ object files must be created using
- # "CC -ar", where "CC" is the IRIX C++ compiler. This is
- # necessary to make sure instantiated templates are included
- # in the archive.
- _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs'
- ;;
- *)
- if test "$GXX" = yes; then
- if test "$with_gnu_ld" = no; then
- _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
- else
- _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` -o $lib'
- fi
- fi
- _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
- ;;
- esac
- _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
- _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
- ;;
- linux* | k*bsd*-gnu)
- case $cc_basename in
- KCC*)
- # Kuck and Associates, Inc. (KAI) C++ Compiler
-
- # KCC will only create a shared library if the output file
- # ends with ".so" (or ".sl" for HP-UX), so rename the library
- # to its proper name (with version) after linking.
- _LT_AC_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
- _LT_AC_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib'
- # Commands to make compiler produce verbose output that lists
- # what "hidden" libraries, object files and flags are used when
- # linking a shared library.
- #
- # There doesn't appear to be a way to prevent this compiler from
- # explicitly linking system object files so we need to strip them
- # from the output so that they don't get included in the library
- # dependencies.
- output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | grep "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
-
- _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath,$libdir'
- _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
-
- # Archives containing C++ object files must be created using
- # "CC -Bstatic", where "CC" is the KAI C++ compiler.
- _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs'
- ;;
- icpc*)
- # Intel C++
- with_gnu_ld=yes
- # version 8.0 and above of icpc choke on multiply defined symbols
- # if we add $predep_objects and $postdep_objects, however 7.1 and
- # earlier do not add the objects themselves.
- case `$CC -V 2>&1` in
- *"Version 7."*)
- _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
- _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
- ;;
- *) # Version 8.0 or newer
- tmp_idyn=
- case $host_cpu in
- ia64*) tmp_idyn=' -i_dynamic';;
- esac
- _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
- ;;
- esac
- _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
- _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
- _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
- _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
- ;;
- pgCC* | pgcpp*)
- # Portland Group C++ compiler
- _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
- _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
-
- _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir'
- _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
- _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
- ;;
- cxx*)
- # Compaq C++
- _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
- _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols'
-
- runpath_var=LD_RUN_PATH
- _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
- _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
-
- # Commands to make compiler produce verbose output that lists
- # what "hidden" libraries, object files and flags are used when
- # linking a shared library.
- #
- # There doesn't appear to be a way to prevent this compiler from
- # explicitly linking system object files so we need to strip them
- # from the output so that they don't get included in the library
- # dependencies.
- output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
- ;;
- *)
- case `$CC -V 2>&1 | sed 5q` in
- *Sun\ C*)
- # Sun C++ 5.9
- _LT_AC_TAGVAR(no_undefined_flag, $1)=' -zdefs'
- _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
- _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols'
- _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
- _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
-
- # Not sure whether something based on
- # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1
- # would be better.
- output_verbose_link_cmd='echo'
-
- # Archives containing C++ object files must be created using
- # "CC -xar", where "CC" is the Sun C++ compiler. This is
- # necessary to make sure instantiated templates are included
- # in the archive.
- _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs'
- ;;
- esac
- ;;
- esac
- ;;
- lynxos*)
- # FIXME: insert proper C++ library support
- _LT_AC_TAGVAR(ld_shlibs, $1)=no
- ;;
- m88k*)
- # FIXME: insert proper C++ library support
- _LT_AC_TAGVAR(ld_shlibs, $1)=no
- ;;
- mvs*)
- case $cc_basename in
- cxx*)
- # FIXME: insert proper C++ library support
- _LT_AC_TAGVAR(ld_shlibs, $1)=no
- ;;
- *)
- # FIXME: insert proper C++ library support
- _LT_AC_TAGVAR(ld_shlibs, $1)=no
- ;;
- esac
- ;;
- netbsd*)
- if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
- _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags'
- wlarc=
- _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
- _LT_AC_TAGVAR(hardcode_direct, $1)=yes
- _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
- fi
- # Workaround some broken pre-1.5 toolchains
- output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"'
- ;;
- openbsd2*)
- # C++ shared libraries are fairly broken
- _LT_AC_TAGVAR(ld_shlibs, $1)=no
- ;;
- openbsd*)
- if test -f /usr/libexec/ld.so; then
- _LT_AC_TAGVAR(hardcode_direct, $1)=yes
- _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
- _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
- _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
- if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
- _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib'
- _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
- _LT_AC_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
- fi
- output_verbose_link_cmd='echo'
- else
- _LT_AC_TAGVAR(ld_shlibs, $1)=no
- fi
- ;;
- osf3*)
- case $cc_basename in
- KCC*)
- # Kuck and Associates, Inc. (KAI) C++ Compiler
-
- # KCC will only create a shared library if the output file
- # ends with ".so" (or ".sl" for HP-UX), so rename the library
- # to its proper name (with version) after linking.
- _LT_AC_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
-
- _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
- _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
-
- # Archives containing C++ object files must be created using
- # "CC -Bstatic", where "CC" is the KAI C++ compiler.
- _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs'
-
- ;;
- RCC*)
- # Rational C++ 2.4.1
- # FIXME: insert proper C++ library support
- _LT_AC_TAGVAR(ld_shlibs, $1)=no
- ;;
- cxx*)
- _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
- _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && echo ${wl}-set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
-
- _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
- _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
-
- # Commands to make compiler produce verbose output that lists
- # what "hidden" libraries, object files and flags are used when
- # linking a shared library.
- #
- # There doesn't appear to be a way to prevent this compiler from
- # explicitly linking system object files so we need to strip them
- # from the output so that they don't get included in the library
- # dependencies.
- output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
- ;;
- *)
- if test "$GXX" = yes && test "$with_gnu_ld" = no; then
- _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
- _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
-
- _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
- _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
-
- # Commands to make compiler produce verbose output that lists
- # what "hidden" libraries, object files and flags are used when
- # linking a shared library.
- output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"'
-
- else
- # FIXME: insert proper C++ library support
- _LT_AC_TAGVAR(ld_shlibs, $1)=no
- fi
- ;;
- esac
- ;;
- osf4* | osf5*)
- case $cc_basename in
- KCC*)
- # Kuck and Associates, Inc. (KAI) C++ Compiler
-
- # KCC will only create a shared library if the output file
- # ends with ".so" (or ".sl" for HP-UX), so rename the library
- # to its proper name (with version) after linking.
- _LT_AC_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
-
- _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
- _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
-
- # Archives containing C++ object files must be created using
- # the KAI C++ compiler.
- _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs'
- ;;
- RCC*)
- # Rational C++ 2.4.1
- # FIXME: insert proper C++ library support
- _LT_AC_TAGVAR(ld_shlibs, $1)=no
- ;;
- cxx*)
- _LT_AC_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
- _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
- _LT_AC_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~
- echo "-hidden">> $lib.exp~
- $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname -Wl,-input -Wl,$lib.exp `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~
- $rm $lib.exp'
-
- _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
- _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
-
- # Commands to make compiler produce verbose output that lists
- # what "hidden" libraries, object files and flags are used when
- # linking a shared library.
- #
- # There doesn't appear to be a way to prevent this compiler from
- # explicitly linking system object files so we need to strip them
- # from the output so that they don't get included in the library
- # dependencies.
- output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
- ;;
- *)
- if test "$GXX" = yes && test "$with_gnu_ld" = no; then
- _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
- _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
-
- _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
- _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
-
- # Commands to make compiler produce verbose output that lists
- # what "hidden" libraries, object files and flags are used when
- # linking a shared library.
- output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"'
-
- else
- # FIXME: insert proper C++ library support
- _LT_AC_TAGVAR(ld_shlibs, $1)=no
- fi
- ;;
- esac
- ;;
- psos*)
- # FIXME: insert proper C++ library support
- _LT_AC_TAGVAR(ld_shlibs, $1)=no
- ;;
- sunos4*)
- case $cc_basename in
- CC*)
- # Sun C++ 4.x
- # FIXME: insert proper C++ library support
- _LT_AC_TAGVAR(ld_shlibs, $1)=no
- ;;
- lcc*)
- # Lucid
- # FIXME: insert proper C++ library support
- _LT_AC_TAGVAR(ld_shlibs, $1)=no
- ;;
- *)
- # FIXME: insert proper C++ library support
- _LT_AC_TAGVAR(ld_shlibs, $1)=no
- ;;
- esac
- ;;
- solaris*)
- case $cc_basename in
- CC*)
- # Sun C++ 4.2, 5.x and Centerline C++
- _LT_AC_TAGVAR(archive_cmds_need_lc,$1)=yes
- _LT_AC_TAGVAR(no_undefined_flag, $1)=' -zdefs'
- _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
- _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
- $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp'
-
- _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
- _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
- case $host_os in
- solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
- *)
- # The compiler driver will combine and reorder linker options,
- # but understands `-z linker_flag'.
- # Supported since Solaris 2.6 (maybe 2.5.1?)
- _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract'
- ;;
- esac
- _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
-
- output_verbose_link_cmd='echo'
-
- # Archives containing C++ object files must be created using
- # "CC -xar", where "CC" is the Sun C++ compiler. This is
- # necessary to make sure instantiated templates are included
- # in the archive.
- _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs'
- ;;
- gcx*)
- # Green Hills C++ Compiler
- _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
-
- # The C++ compiler must be used to create the archive.
- _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs'
- ;;
- *)
- # GNU C++ compiler with Solaris linker
- if test "$GXX" = yes && test "$with_gnu_ld" = no; then
- _LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs'
- if $CC --version | grep -v '^2\.7' > /dev/null; then
- _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
- _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
- $CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp'
-
- # Commands to make compiler produce verbose output that lists
- # what "hidden" libraries, object files and flags are used when
- # linking a shared library.
- output_verbose_link_cmd="$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep \"\-L\""
- else
- # g++ 2.7 appears to require `-G' NOT `-shared' on this
- # platform.
- _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
- _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
- $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp'
-
- # Commands to make compiler produce verbose output that lists
- # what "hidden" libraries, object files and flags are used when
- # linking a shared library.
- output_verbose_link_cmd="$CC -G $CFLAGS -v conftest.$objext 2>&1 | grep \"\-L\""
- fi
-
- _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir'
- case $host_os in
- solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
- *)
- _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
- ;;
- esac
- fi
- ;;
- esac
- ;;
- sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*)
- _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
- _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
- _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
- runpath_var='LD_RUN_PATH'
-
- case $cc_basename in
- CC*)
- _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- *)
- _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- esac
- ;;
- sysv5* | sco3.2v5* | sco5v6*)
- # Note: We can NOT use -z defs as we might desire, because we do not
- # link with -lc, and that would cause any symbols used from libc to
- # always be unresolved, which means just about no library would
- # ever link correctly. If we're not using GNU ld we use -z text
- # though, which does catch some bad symbols but isn't as heavy-handed
- # as -z defs.
- # For security reasons, it is highly recommended that you always
- # use absolute paths for naming shared libraries, and exclude the
- # DT_RUNPATH tag from executables and libraries. But doing so
- # requires that you compile everything twice, which is a pain.
- # So that behaviour is only enabled if SCOABSPATH is set to a
- # non-empty value in the environment. Most likely only useful for
- # creating official distributions of packages.
- # This is a hack until libtool officially supports absolute path
- # names for shared libraries.
- _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
- _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs'
- _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
- _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
- _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`'
- _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':'
- _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
- _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport'
- runpath_var='LD_RUN_PATH'
-
- case $cc_basename in
- CC*)
- _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
- _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- *)
- _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
- _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- esac
- ;;
- tandem*)
- case $cc_basename in
- NCC*)
- # NonStop-UX NCC 3.20
- # FIXME: insert proper C++ library support
- _LT_AC_TAGVAR(ld_shlibs, $1)=no
- ;;
- *)
- # FIXME: insert proper C++ library support
- _LT_AC_TAGVAR(ld_shlibs, $1)=no
- ;;
- esac
- ;;
- vxworks*)
- # FIXME: insert proper C++ library support
- _LT_AC_TAGVAR(ld_shlibs, $1)=no
- ;;
- *)
- # FIXME: insert proper C++ library support
- _LT_AC_TAGVAR(ld_shlibs, $1)=no
- ;;
-esac
-AC_MSG_RESULT([$_LT_AC_TAGVAR(ld_shlibs, $1)])
-test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no
-
-_LT_AC_TAGVAR(GCC, $1)="$GXX"
-_LT_AC_TAGVAR(LD, $1)="$LD"
-
-AC_LIBTOOL_POSTDEP_PREDEP($1)
-AC_LIBTOOL_PROG_COMPILER_PIC($1)
-AC_LIBTOOL_PROG_CC_C_O($1)
-AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1)
-AC_LIBTOOL_PROG_LD_SHLIBS($1)
-AC_LIBTOOL_SYS_DYNAMIC_LINKER($1)
-AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1)
-
-AC_LIBTOOL_CONFIG($1)
-
-AC_LANG_POP
-CC=$lt_save_CC
-LDCXX=$LD
-LD=$lt_save_LD
-GCC=$lt_save_GCC
-with_gnu_ldcxx=$with_gnu_ld
-with_gnu_ld=$lt_save_with_gnu_ld
-lt_cv_path_LDCXX=$lt_cv_path_LD
-lt_cv_path_LD=$lt_save_path_LD
-lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld
-lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld
-])# AC_LIBTOOL_LANG_CXX_CONFIG
-
-# AC_LIBTOOL_POSTDEP_PREDEP([TAGNAME])
-# ------------------------------------
-# Figure out "hidden" library dependencies from verbose
-# compiler output when linking a shared library.
-# Parse the compiler output and extract the necessary
-# objects, libraries and library flags.
-AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP],
-[AC_REQUIRE([LT_AC_PROG_SED])dnl
-dnl we can't use the lt_simple_compile_test_code here,
-dnl because it contains code intended for an executable,
-dnl not a library. It's possible we should let each
-dnl tag define a new lt_????_link_test_code variable,
-dnl but it's only used here...
-ifelse([$1],[],[cat > conftest.$ac_ext <<EOF
-int a;
-void foo (void) { a = 0; }
-EOF
-],[$1],[CXX],[cat > conftest.$ac_ext <<EOF
-class Foo
-{
-public:
- Foo (void) { a = 0; }
-private:
- int a;
-};
-EOF
-],[$1],[F77],[cat > conftest.$ac_ext <<EOF
- subroutine foo
- implicit none
- integer*4 a
- a=0
- return
- end
-EOF
-],[$1],[GCJ],[cat > conftest.$ac_ext <<EOF
-public class foo {
- private int a;
- public void bar (void) {
- a = 0;
- }
-};
-EOF
-])
-dnl Parse the compiler output and extract the necessary
-dnl objects, libraries and library flags.
-if AC_TRY_EVAL(ac_compile); then
- # Parse the compiler output and extract the necessary
- # objects, libraries and library flags.
-
- # Sentinel used to keep track of whether or not we are before
- # the conftest object file.
- pre_test_object_deps_done=no
-
- # The `*' in the case matches for architectures that use `case' in
- # $output_verbose_cmd can trigger glob expansion during the loop
- # eval without this substitution.
- output_verbose_link_cmd=`$echo "X$output_verbose_link_cmd" | $Xsed -e "$no_glob_subst"`
-
- for p in `eval $output_verbose_link_cmd`; do
- case $p in
-
- -L* | -R* | -l*)
- # Some compilers place space between "-{L,R}" and the path.
- # Remove the space.
- if test $p = "-L" \
- || test $p = "-R"; then
- prev=$p
- continue
- else
- prev=
- fi
-
- if test "$pre_test_object_deps_done" = no; then
- case $p in
- -L* | -R*)
- # Internal compiler library paths should come after those
- # provided the user. The postdeps already come after the
- # user supplied libs so there is no need to process them.
- if test -z "$_LT_AC_TAGVAR(compiler_lib_search_path, $1)"; then
- _LT_AC_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}"
- else
- _LT_AC_TAGVAR(compiler_lib_search_path, $1)="${_LT_AC_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}"
- fi
- ;;
- # The "-l" case would never come before the object being
- # linked, so don't bother handling this case.
- esac
- else
- if test -z "$_LT_AC_TAGVAR(postdeps, $1)"; then
- _LT_AC_TAGVAR(postdeps, $1)="${prev}${p}"
- else
- _LT_AC_TAGVAR(postdeps, $1)="${_LT_AC_TAGVAR(postdeps, $1)} ${prev}${p}"
- fi
- fi
- ;;
-
- *.$objext)
- # This assumes that the test object file only shows up
- # once in the compiler output.
- if test "$p" = "conftest.$objext"; then
- pre_test_object_deps_done=yes
- continue
- fi
-
- if test "$pre_test_object_deps_done" = no; then
- if test -z "$_LT_AC_TAGVAR(predep_objects, $1)"; then
- _LT_AC_TAGVAR(predep_objects, $1)="$p"
- else
- _LT_AC_TAGVAR(predep_objects, $1)="$_LT_AC_TAGVAR(predep_objects, $1) $p"
- fi
- else
- if test -z "$_LT_AC_TAGVAR(postdep_objects, $1)"; then
- _LT_AC_TAGVAR(postdep_objects, $1)="$p"
- else
- _LT_AC_TAGVAR(postdep_objects, $1)="$_LT_AC_TAGVAR(postdep_objects, $1) $p"
- fi
- fi
- ;;
-
- *) ;; # Ignore the rest.
-
- esac
- done
-
- # Clean up.
- rm -f a.out a.exe
-else
- echo "libtool.m4: error: problem compiling $1 test program"
-fi
-
-$rm -f confest.$objext
-
-_LT_AC_TAGVAR(compiler_lib_search_dirs, $1)=
-if test -n "$_LT_AC_TAGVAR(compiler_lib_search_path, $1)"; then
- _LT_AC_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_AC_TAGVAR(compiler_lib_search_path, $1)}" | ${SED} -e 's! -L! !g' -e 's!^ !!'`
-fi
-
-# PORTME: override above test on systems where it is broken
-ifelse([$1],[CXX],
-[case $host_os in
-interix[[3-9]]*)
- # Interix 3.5 installs completely hosed .la files for C++, so rather than
- # hack all around it, let's just trust "g++" to DTRT.
- _LT_AC_TAGVAR(predep_objects,$1)=
- _LT_AC_TAGVAR(postdep_objects,$1)=
- _LT_AC_TAGVAR(postdeps,$1)=
- ;;
-
-linux*)
- case `$CC -V 2>&1 | sed 5q` in
- *Sun\ C*)
- # Sun C++ 5.9
- #
- # The more standards-conforming stlport4 library is
- # incompatible with the Cstd library. Avoid specifying
- # it if it's in CXXFLAGS. Ignore libCrun as
- # -library=stlport4 depends on it.
- case " $CXX $CXXFLAGS " in
- *" -library=stlport4 "*)
- solaris_use_stlport4=yes
- ;;
- esac
- if test "$solaris_use_stlport4" != yes; then
- _LT_AC_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun'
- fi
- ;;
- esac
- ;;
-
-solaris*)
- case $cc_basename in
- CC*)
- # The more standards-conforming stlport4 library is
- # incompatible with the Cstd library. Avoid specifying
- # it if it's in CXXFLAGS. Ignore libCrun as
- # -library=stlport4 depends on it.
- case " $CXX $CXXFLAGS " in
- *" -library=stlport4 "*)
- solaris_use_stlport4=yes
- ;;
- esac
-
- # Adding this requires a known-good setup of shared libraries for
- # Sun compiler versions before 5.6, else PIC objects from an old
- # archive will be linked into the output, leading to subtle bugs.
- if test "$solaris_use_stlport4" != yes; then
- _LT_AC_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun'
- fi
- ;;
- esac
- ;;
-esac
-])
-case " $_LT_AC_TAGVAR(postdeps, $1) " in
-*" -lc "*) _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no ;;
-esac
-])# AC_LIBTOOL_POSTDEP_PREDEP
-
-# AC_LIBTOOL_LANG_F77_CONFIG
-# --------------------------
-# Ensure that the configuration vars for the C compiler are
-# suitably defined. Those variables are subsequently used by
-# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'.
-AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG], [_LT_AC_LANG_F77_CONFIG(F77)])
-AC_DEFUN([_LT_AC_LANG_F77_CONFIG],
-[AC_REQUIRE([AC_PROG_F77])
-AC_LANG_PUSH(Fortran 77)
-
-_LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
-_LT_AC_TAGVAR(allow_undefined_flag, $1)=
-_LT_AC_TAGVAR(always_export_symbols, $1)=no
-_LT_AC_TAGVAR(archive_expsym_cmds, $1)=
-_LT_AC_TAGVAR(export_dynamic_flag_spec, $1)=
-_LT_AC_TAGVAR(hardcode_direct, $1)=no
-_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)=
-_LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=
-_LT_AC_TAGVAR(hardcode_libdir_separator, $1)=
-_LT_AC_TAGVAR(hardcode_minus_L, $1)=no
-_LT_AC_TAGVAR(hardcode_automatic, $1)=no
-_LT_AC_TAGVAR(module_cmds, $1)=
-_LT_AC_TAGVAR(module_expsym_cmds, $1)=
-_LT_AC_TAGVAR(link_all_deplibs, $1)=unknown
-_LT_AC_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
-_LT_AC_TAGVAR(no_undefined_flag, $1)=
-_LT_AC_TAGVAR(whole_archive_flag_spec, $1)=
-_LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=no
-
-# Source file extension for f77 test sources.
-ac_ext=f
-
-# Object file extension for compiled f77 test sources.
-objext=o
-_LT_AC_TAGVAR(objext, $1)=$objext
-
-# Code to be used in simple compile tests
-lt_simple_compile_test_code="\
- subroutine t
- return
- end
-"
-
-# Code to be used in simple link tests
-lt_simple_link_test_code="\
- program t
- end
-"
-
-# ltmain only uses $CC for tagged configurations so make sure $CC is set.
-_LT_AC_SYS_COMPILER
-
-# save warnings/boilerplate of simple test code
-_LT_COMPILER_BOILERPLATE
-_LT_LINKER_BOILERPLATE
-
-# Allow CC to be a program name with arguments.
-lt_save_CC="$CC"
-CC=${F77-"f77"}
-compiler=$CC
-_LT_AC_TAGVAR(compiler, $1)=$CC
-_LT_CC_BASENAME([$compiler])
-
-AC_MSG_CHECKING([if libtool supports shared libraries])
-AC_MSG_RESULT([$can_build_shared])
-
-AC_MSG_CHECKING([whether to build shared libraries])
-test "$can_build_shared" = "no" && enable_shared=no
-
-# On AIX, shared libraries and static libraries use the same namespace, and
-# are all built from PIC.
-case $host_os in
-aix3*)
- test "$enable_shared" = yes && enable_static=no
- if test -n "$RANLIB"; then
- archive_cmds="$archive_cmds~\$RANLIB \$lib"
- postinstall_cmds='$RANLIB $lib'
- fi
- ;;
-aix[[4-9]]*)
- if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
- test "$enable_shared" = yes && enable_static=no
- fi
- ;;
-esac
-AC_MSG_RESULT([$enable_shared])
-
-AC_MSG_CHECKING([whether to build static libraries])
-# Make sure either enable_shared or enable_static is yes.
-test "$enable_shared" = yes || enable_static=yes
-AC_MSG_RESULT([$enable_static])
-
-_LT_AC_TAGVAR(GCC, $1)="$G77"
-_LT_AC_TAGVAR(LD, $1)="$LD"
-
-AC_LIBTOOL_PROG_COMPILER_PIC($1)
-AC_LIBTOOL_PROG_CC_C_O($1)
-AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1)
-AC_LIBTOOL_PROG_LD_SHLIBS($1)
-AC_LIBTOOL_SYS_DYNAMIC_LINKER($1)
-AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1)
-
-AC_LIBTOOL_CONFIG($1)
-
-AC_LANG_POP
-CC="$lt_save_CC"
-])# AC_LIBTOOL_LANG_F77_CONFIG
-
-
-# AC_LIBTOOL_LANG_GCJ_CONFIG
-# --------------------------
-# Ensure that the configuration vars for the C compiler are
-# suitably defined. Those variables are subsequently used by
-# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'.
-AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG], [_LT_AC_LANG_GCJ_CONFIG(GCJ)])
-AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG],
-[AC_LANG_SAVE
-
-# Source file extension for Java test sources.
-ac_ext=java
-
-# Object file extension for compiled Java test sources.
-objext=o
-_LT_AC_TAGVAR(objext, $1)=$objext
-
-# Code to be used in simple compile tests
-lt_simple_compile_test_code="class foo {}"
-
-# Code to be used in simple link tests
-lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }'
-
-# ltmain only uses $CC for tagged configurations so make sure $CC is set.
-_LT_AC_SYS_COMPILER
-
-# save warnings/boilerplate of simple test code
-_LT_COMPILER_BOILERPLATE
-_LT_LINKER_BOILERPLATE
-
-# Allow CC to be a program name with arguments.
-lt_save_CC="$CC"
-CC=${GCJ-"gcj"}
-compiler=$CC
-_LT_AC_TAGVAR(compiler, $1)=$CC
-_LT_CC_BASENAME([$compiler])
-
-# GCJ did not exist at the time GCC didn't implicitly link libc in.
-_LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
-
-_LT_AC_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
-
-AC_LIBTOOL_PROG_COMPILER_NO_RTTI($1)
-AC_LIBTOOL_PROG_COMPILER_PIC($1)
-AC_LIBTOOL_PROG_CC_C_O($1)
-AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1)
-AC_LIBTOOL_PROG_LD_SHLIBS($1)
-AC_LIBTOOL_SYS_DYNAMIC_LINKER($1)
-AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1)
-
-AC_LIBTOOL_CONFIG($1)
-
-AC_LANG_RESTORE
-CC="$lt_save_CC"
-])# AC_LIBTOOL_LANG_GCJ_CONFIG
-
-
-# AC_LIBTOOL_LANG_RC_CONFIG
-# -------------------------
-# Ensure that the configuration vars for the Windows resource compiler are
-# suitably defined. Those variables are subsequently used by
-# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'.
-AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG], [_LT_AC_LANG_RC_CONFIG(RC)])
-AC_DEFUN([_LT_AC_LANG_RC_CONFIG],
-[AC_LANG_SAVE
-
-# Source file extension for RC test sources.
-ac_ext=rc
-
-# Object file extension for compiled RC test sources.
-objext=o
-_LT_AC_TAGVAR(objext, $1)=$objext
-
-# Code to be used in simple compile tests
-lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }'
-
-# Code to be used in simple link tests
-lt_simple_link_test_code="$lt_simple_compile_test_code"
-
-# ltmain only uses $CC for tagged configurations so make sure $CC is set.
-_LT_AC_SYS_COMPILER
-
-# save warnings/boilerplate of simple test code
-_LT_COMPILER_BOILERPLATE
-_LT_LINKER_BOILERPLATE
-
-# Allow CC to be a program name with arguments.
-lt_save_CC="$CC"
-CC=${RC-"windres"}
-compiler=$CC
-_LT_AC_TAGVAR(compiler, $1)=$CC
-_LT_CC_BASENAME([$compiler])
-_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes
-
-AC_LIBTOOL_CONFIG($1)
-
-AC_LANG_RESTORE
-CC="$lt_save_CC"
-])# AC_LIBTOOL_LANG_RC_CONFIG
-
-
-# AC_LIBTOOL_CONFIG([TAGNAME])
-# ----------------------------
-# If TAGNAME is not passed, then create an initial libtool script
-# with a default configuration from the untagged config vars. Otherwise
-# add code to config.status for appending the configuration named by
-# TAGNAME from the matching tagged config vars.
-AC_DEFUN([AC_LIBTOOL_CONFIG],
-[# The else clause should only fire when bootstrapping the
-# libtool distribution, otherwise you forgot to ship ltmain.sh
-# with your package, and you will get complaints that there are
-# no rules to generate ltmain.sh.
-if test -f "$ltmain"; then
- # See if we are running on zsh, and set the options which allow our commands through
- # without removal of \ escapes.
- if test -n "${ZSH_VERSION+set}" ; then
- setopt NO_GLOB_SUBST
- fi
- # Now quote all the things that may contain metacharacters while being
- # careful not to overquote the AC_SUBSTed values. We take copies of the
- # variables and quote the copies for generation of the libtool script.
- for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \
- SED SHELL STRIP \
- libname_spec library_names_spec soname_spec extract_expsyms_cmds \
- old_striplib striplib file_magic_cmd finish_cmds finish_eval \
- deplibs_check_method reload_flag reload_cmds need_locks \
- lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \
- lt_cv_sys_global_symbol_to_c_name_address \
- sys_lib_search_path_spec sys_lib_dlsearch_path_spec \
- old_postinstall_cmds old_postuninstall_cmds \
- _LT_AC_TAGVAR(compiler, $1) \
- _LT_AC_TAGVAR(CC, $1) \
- _LT_AC_TAGVAR(LD, $1) \
- _LT_AC_TAGVAR(lt_prog_compiler_wl, $1) \
- _LT_AC_TAGVAR(lt_prog_compiler_pic, $1) \
- _LT_AC_TAGVAR(lt_prog_compiler_static, $1) \
- _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) \
- _LT_AC_TAGVAR(export_dynamic_flag_spec, $1) \
- _LT_AC_TAGVAR(thread_safe_flag_spec, $1) \
- _LT_AC_TAGVAR(whole_archive_flag_spec, $1) \
- _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1) \
- _LT_AC_TAGVAR(old_archive_cmds, $1) \
- _LT_AC_TAGVAR(old_archive_from_new_cmds, $1) \
- _LT_AC_TAGVAR(predep_objects, $1) \
- _LT_AC_TAGVAR(postdep_objects, $1) \
- _LT_AC_TAGVAR(predeps, $1) \
- _LT_AC_TAGVAR(postdeps, $1) \
- _LT_AC_TAGVAR(compiler_lib_search_path, $1) \
- _LT_AC_TAGVAR(compiler_lib_search_dirs, $1) \
- _LT_AC_TAGVAR(archive_cmds, $1) \
- _LT_AC_TAGVAR(archive_expsym_cmds, $1) \
- _LT_AC_TAGVAR(postinstall_cmds, $1) \
- _LT_AC_TAGVAR(postuninstall_cmds, $1) \
- _LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1) \
- _LT_AC_TAGVAR(allow_undefined_flag, $1) \
- _LT_AC_TAGVAR(no_undefined_flag, $1) \
- _LT_AC_TAGVAR(export_symbols_cmds, $1) \
- _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) \
- _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1) \
- _LT_AC_TAGVAR(hardcode_libdir_separator, $1) \
- _LT_AC_TAGVAR(hardcode_automatic, $1) \
- _LT_AC_TAGVAR(module_cmds, $1) \
- _LT_AC_TAGVAR(module_expsym_cmds, $1) \
- _LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1) \
- _LT_AC_TAGVAR(fix_srcfile_path, $1) \
- _LT_AC_TAGVAR(exclude_expsyms, $1) \
- _LT_AC_TAGVAR(include_expsyms, $1); do
-
- case $var in
- _LT_AC_TAGVAR(old_archive_cmds, $1) | \
- _LT_AC_TAGVAR(old_archive_from_new_cmds, $1) | \
- _LT_AC_TAGVAR(archive_cmds, $1) | \
- _LT_AC_TAGVAR(archive_expsym_cmds, $1) | \
- _LT_AC_TAGVAR(module_cmds, $1) | \
- _LT_AC_TAGVAR(module_expsym_cmds, $1) | \
- _LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1) | \
- _LT_AC_TAGVAR(export_symbols_cmds, $1) | \
- extract_expsyms_cmds | reload_cmds | finish_cmds | \
- postinstall_cmds | postuninstall_cmds | \
- old_postinstall_cmds | old_postuninstall_cmds | \
- sys_lib_search_path_spec | sys_lib_dlsearch_path_spec)
- # Double-quote double-evaled strings.
- eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\""
- ;;
- *)
- eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\""
- ;;
- esac
- done
-
- case $lt_echo in
- *'\[$]0 --fallback-echo"')
- lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\[$]0 --fallback-echo"[$]/[$]0 --fallback-echo"/'`
- ;;
- esac
-
-ifelse([$1], [],
- [cfgfile="${ofile}T"
- trap "$rm \"$cfgfile\"; exit 1" 1 2 15
- $rm -f "$cfgfile"
- AC_MSG_NOTICE([creating $ofile])],
- [cfgfile="$ofile"])
-
- cat <<__EOF__ >> "$cfgfile"
-ifelse([$1], [],
-[#! $SHELL
-
-# `$echo "$cfgfile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
-# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP)
-# NOTE: Changes made to this file will be lost: look at ltmain.sh.
-#
-# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
-# Free Software Foundation, Inc.
-#
-# This file is part of GNU Libtool:
-# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# As a special exception to the GNU General Public License, if you
-# distribute this file as part of a program that contains a
-# configuration script generated by Autoconf, you may include it under
-# the same distribution terms that you use for the rest of that program.
-
-# A sed program that does not truncate output.
-SED=$lt_SED
-
-# Sed that helps us avoid accidentally triggering echo(1) options like -n.
-Xsed="$SED -e 1s/^X//"
-
-# The HP-UX ksh and POSIX shell print the target directory to stdout
-# if CDPATH is set.
-(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
-
-# The names of the tagged configurations supported by this script.
-available_tags=
-
-# ### BEGIN LIBTOOL CONFIG],
-[# ### BEGIN LIBTOOL TAG CONFIG: $tagname])
-
-# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
-
-# Shell to use when invoking shell scripts.
-SHELL=$lt_SHELL
-
-# Whether or not to build shared libraries.
-build_libtool_libs=$enable_shared
-
-# Whether or not to build static libraries.
-build_old_libs=$enable_static
-
-# Whether or not to add -lc for building shared libraries.
-build_libtool_need_lc=$_LT_AC_TAGVAR(archive_cmds_need_lc, $1)
-
-# Whether or not to disallow shared libs when runtime libs are static
-allow_libtool_libs_with_static_runtimes=$_LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)
-
-# Whether or not to optimize for fast installation.
-fast_install=$enable_fast_install
-
-# The host system.
-host_alias=$host_alias
-host=$host
-host_os=$host_os
-
-# The build system.
-build_alias=$build_alias
-build=$build
-build_os=$build_os
-
-# An echo program that does not interpret backslashes.
-echo=$lt_echo
-
-# The archiver.
-AR=$lt_AR
-AR_FLAGS=$lt_AR_FLAGS
-
-# A C compiler.
-LTCC=$lt_LTCC
-
-# LTCC compiler flags.
-LTCFLAGS=$lt_LTCFLAGS
-
-# A language-specific compiler.
-CC=$lt_[]_LT_AC_TAGVAR(compiler, $1)
-
-# Is the compiler the GNU C compiler?
-with_gcc=$_LT_AC_TAGVAR(GCC, $1)
-
-# An ERE matcher.
-EGREP=$lt_EGREP
-
-# The linker used to build libraries.
-LD=$lt_[]_LT_AC_TAGVAR(LD, $1)
-
-# Whether we need hard or soft links.
-LN_S=$lt_LN_S
-
-# A BSD-compatible nm program.
-NM=$lt_NM
-
-# A symbol stripping program
-STRIP=$lt_STRIP
-
-# Used to examine libraries when file_magic_cmd begins "file"
-MAGIC_CMD=$MAGIC_CMD
-
-# Used on cygwin: DLL creation program.
-DLLTOOL="$DLLTOOL"
-
-# Used on cygwin: object dumper.
-OBJDUMP="$OBJDUMP"
-
-# Used on cygwin: assembler.
-AS="$AS"
-
-# The name of the directory that contains temporary libtool files.
-objdir=$objdir
-
-# How to create reloadable object files.
-reload_flag=$lt_reload_flag
-reload_cmds=$lt_reload_cmds
-
-# How to pass a linker flag through the compiler.
-wl=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_wl, $1)
-
-# Object file suffix (normally "o").
-objext="$ac_objext"
-
-# Old archive suffix (normally "a").
-libext="$libext"
-
-# Shared library suffix (normally ".so").
-shrext_cmds='$shrext_cmds'
-
-# Executable file suffix (normally "").
-exeext="$exeext"
-
-# Additional compiler flags for building library objects.
-pic_flag=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)
-pic_mode=$pic_mode
-
-# What is the maximum length of a command?
-max_cmd_len=$lt_cv_sys_max_cmd_len
-
-# Does compiler simultaneously support -c and -o options?
-compiler_c_o=$lt_[]_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)
-
-# Must we lock files when doing compilation?
-need_locks=$lt_need_locks
-
-# Do we need the lib prefix for modules?
-need_lib_prefix=$need_lib_prefix
-
-# Do we need a version for libraries?
-need_version=$need_version
-
-# Whether dlopen is supported.
-dlopen_support=$enable_dlopen
-
-# Whether dlopen of programs is supported.
-dlopen_self=$enable_dlopen_self
-
-# Whether dlopen of statically linked programs is supported.
-dlopen_self_static=$enable_dlopen_self_static
-
-# Compiler flag to prevent dynamic linking.
-link_static_flag=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_static, $1)
-
-# Compiler flag to turn off builtin functions.
-no_builtin_flag=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)
-
-# Compiler flag to allow reflexive dlopens.
-export_dynamic_flag_spec=$lt_[]_LT_AC_TAGVAR(export_dynamic_flag_spec, $1)
-
-# Compiler flag to generate shared objects directly from archives.
-whole_archive_flag_spec=$lt_[]_LT_AC_TAGVAR(whole_archive_flag_spec, $1)
-
-# Compiler flag to generate thread-safe objects.
-thread_safe_flag_spec=$lt_[]_LT_AC_TAGVAR(thread_safe_flag_spec, $1)
-
-# Library versioning type.
-version_type=$version_type
-
-# Format of library name prefix.
-libname_spec=$lt_libname_spec
-
-# List of archive names. First name is the real one, the rest are links.
-# The last name is the one that the linker finds with -lNAME.
-library_names_spec=$lt_library_names_spec
-
-# The coded name of the library, if different from the real name.
-soname_spec=$lt_soname_spec
-
-# Commands used to build and install an old-style archive.
-RANLIB=$lt_RANLIB
-old_archive_cmds=$lt_[]_LT_AC_TAGVAR(old_archive_cmds, $1)
-old_postinstall_cmds=$lt_old_postinstall_cmds
-old_postuninstall_cmds=$lt_old_postuninstall_cmds
-
-# Create an old-style archive from a shared archive.
-old_archive_from_new_cmds=$lt_[]_LT_AC_TAGVAR(old_archive_from_new_cmds, $1)
-
-# Create a temporary old-style archive to link instead of a shared archive.
-old_archive_from_expsyms_cmds=$lt_[]_LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1)
-
-# Commands used to build and install a shared archive.
-archive_cmds=$lt_[]_LT_AC_TAGVAR(archive_cmds, $1)
-archive_expsym_cmds=$lt_[]_LT_AC_TAGVAR(archive_expsym_cmds, $1)
-postinstall_cmds=$lt_postinstall_cmds
-postuninstall_cmds=$lt_postuninstall_cmds
-
-# Commands used to build a loadable module (assumed same as above if empty)
-module_cmds=$lt_[]_LT_AC_TAGVAR(module_cmds, $1)
-module_expsym_cmds=$lt_[]_LT_AC_TAGVAR(module_expsym_cmds, $1)
-
-# Commands to strip libraries.
-old_striplib=$lt_old_striplib
-striplib=$lt_striplib
-
-# Dependencies to place before the objects being linked to create a
-# shared library.
-predep_objects=$lt_[]_LT_AC_TAGVAR(predep_objects, $1)
-
-# Dependencies to place after the objects being linked to create a
-# shared library.
-postdep_objects=$lt_[]_LT_AC_TAGVAR(postdep_objects, $1)
-
-# Dependencies to place before the objects being linked to create a
-# shared library.
-predeps=$lt_[]_LT_AC_TAGVAR(predeps, $1)
-
-# Dependencies to place after the objects being linked to create a
-# shared library.
-postdeps=$lt_[]_LT_AC_TAGVAR(postdeps, $1)
-
-# The directories searched by this compiler when creating a shared
-# library
-compiler_lib_search_dirs=$lt_[]_LT_AC_TAGVAR(compiler_lib_search_dirs, $1)
-
-# The library search path used internally by the compiler when linking
-# a shared library.
-compiler_lib_search_path=$lt_[]_LT_AC_TAGVAR(compiler_lib_search_path, $1)
-
-# Method to check whether dependent libraries are shared objects.
-deplibs_check_method=$lt_deplibs_check_method
-
-# Command to use when deplibs_check_method == file_magic.
-file_magic_cmd=$lt_file_magic_cmd
-
-# Flag that allows shared libraries with undefined symbols to be built.
-allow_undefined_flag=$lt_[]_LT_AC_TAGVAR(allow_undefined_flag, $1)
-
-# Flag that forces no undefined symbols.
-no_undefined_flag=$lt_[]_LT_AC_TAGVAR(no_undefined_flag, $1)
-
-# Commands used to finish a libtool library installation in a directory.
-finish_cmds=$lt_finish_cmds
-
-# Same as above, but a single script fragment to be evaled but not shown.
-finish_eval=$lt_finish_eval
-
-# Take the output of nm and produce a listing of raw symbols and C names.
-global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe
-
-# Transform the output of nm in a proper C declaration
-global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl
-
-# Transform the output of nm in a C name address pair
-global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address
-
-# This is the shared library runtime path variable.
-runpath_var=$runpath_var
-
-# This is the shared library path variable.
-shlibpath_var=$shlibpath_var
-
-# Is shlibpath searched before the hard-coded library search path?
-shlibpath_overrides_runpath=$shlibpath_overrides_runpath
-
-# How to hardcode a shared library path into an executable.
-hardcode_action=$_LT_AC_TAGVAR(hardcode_action, $1)
-
-# Whether we should hardcode library paths into libraries.
-hardcode_into_libs=$hardcode_into_libs
-
-# Flag to hardcode \$libdir into a binary during linking.
-# This must work even if \$libdir does not exist.
-hardcode_libdir_flag_spec=$lt_[]_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)
-
-# If ld is used when linking, flag to hardcode \$libdir into
-# a binary during linking. This must work even if \$libdir does
-# not exist.
-hardcode_libdir_flag_spec_ld=$lt_[]_LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)
-
-# Whether we need a single -rpath flag with a separated argument.
-hardcode_libdir_separator=$lt_[]_LT_AC_TAGVAR(hardcode_libdir_separator, $1)
-
-# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the
-# resulting binary.
-hardcode_direct=$_LT_AC_TAGVAR(hardcode_direct, $1)
-
-# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
-# resulting binary.
-hardcode_minus_L=$_LT_AC_TAGVAR(hardcode_minus_L, $1)
-
-# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into
-# the resulting binary.
-hardcode_shlibpath_var=$_LT_AC_TAGVAR(hardcode_shlibpath_var, $1)
-
-# Set to yes if building a shared library automatically hardcodes DIR into the library
-# and all subsequent libraries and executables linked against it.
-hardcode_automatic=$_LT_AC_TAGVAR(hardcode_automatic, $1)
-
-# Variables whose values should be saved in libtool wrapper scripts and
-# restored at relink time.
-variables_saved_for_relink="$variables_saved_for_relink"
-
-# Whether libtool must link a program against all its dependency libraries.
-link_all_deplibs=$_LT_AC_TAGVAR(link_all_deplibs, $1)
-
-# Compile-time system search path for libraries
-sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
-
-# Run-time system search path for libraries
-sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
-
-# Fix the shell variable \$srcfile for the compiler.
-fix_srcfile_path=$lt_fix_srcfile_path
-
-# Set to yes if exported symbols are required.
-always_export_symbols=$_LT_AC_TAGVAR(always_export_symbols, $1)
-
-# The commands to list exported symbols.
-export_symbols_cmds=$lt_[]_LT_AC_TAGVAR(export_symbols_cmds, $1)
-
-# The commands to extract the exported symbol list from a shared archive.
-extract_expsyms_cmds=$lt_extract_expsyms_cmds
-
-# Symbols that should not be listed in the preloaded symbols.
-exclude_expsyms=$lt_[]_LT_AC_TAGVAR(exclude_expsyms, $1)
-
-# Symbols that must always be exported.
-include_expsyms=$lt_[]_LT_AC_TAGVAR(include_expsyms, $1)
-
-ifelse([$1],[],
-[# ### END LIBTOOL CONFIG],
-[# ### END LIBTOOL TAG CONFIG: $tagname])
-
-__EOF__
-
-ifelse([$1],[], [
- case $host_os in
- aix3*)
- cat <<\EOF >> "$cfgfile"
-
-# AIX sometimes has problems with the GCC collect2 program. For some
-# reason, if we set the COLLECT_NAMES environment variable, the problems
-# vanish in a puff of smoke.
-if test "X${COLLECT_NAMES+set}" != Xset; then
- COLLECT_NAMES=
- export COLLECT_NAMES
-fi
-EOF
- ;;
- esac
-
- # We use sed instead of cat because bash on DJGPP gets confused if
- # if finds mixed CR/LF and LF-only lines. Since sed operates in
- # text mode, it properly converts lines to CR/LF. This bash problem
- # is reportedly fixed, but why not run on old versions too?
- sed '$q' "$ltmain" >> "$cfgfile" || (rm -f "$cfgfile"; exit 1)
-
- mv -f "$cfgfile" "$ofile" || \
- (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
- chmod +x "$ofile"
-])
-else
- # If there is no Makefile yet, we rely on a make rule to execute
- # `config.status --recheck' to rerun these tests and create the
- # libtool script then.
- ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'`
- if test -f "$ltmain_in"; then
- test -f Makefile && make "$ltmain"
- fi
-fi
-])# AC_LIBTOOL_CONFIG
-
-
-# AC_LIBTOOL_PROG_COMPILER_NO_RTTI([TAGNAME])
-# -------------------------------------------
-AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI],
-[AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl
-
-_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
-
-if test "$GCC" = yes; then
- _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin'
-
- AC_LIBTOOL_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions],
- lt_cv_prog_compiler_rtti_exceptions,
- [-fno-rtti -fno-exceptions], [],
- [_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"])
-fi
-])# AC_LIBTOOL_PROG_COMPILER_NO_RTTI
-
-
-# AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE
-# ---------------------------------
-AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE],
-[AC_REQUIRE([AC_CANONICAL_HOST])
-AC_REQUIRE([LT_AC_PROG_SED])
-AC_REQUIRE([AC_PROG_NM])
-AC_REQUIRE([AC_OBJEXT])
-# Check for command to grab the raw symbol name followed by C symbol from nm.
-AC_MSG_CHECKING([command to parse $NM output from $compiler object])
-AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe],
-[
-# These are sane defaults that work on at least a few old systems.
-# [They come from Ultrix. What could be older than Ultrix?!! ;)]
-
-# Character class describing NM global symbol codes.
-symcode='[[BCDEGRST]]'
-
-# Regexp to match symbols that can be accessed directly from C.
-sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)'
-
-# Transform an extracted symbol line into a proper C declaration
-lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern int \1;/p'"
-
-# Transform an extracted symbol line into symbol name and symbol address
-lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'"
-
-# Define system-specific variables.
-case $host_os in
-aix*)
- symcode='[[BCDT]]'
- ;;
-cygwin* | mingw* | pw32*)
- symcode='[[ABCDGISTW]]'
- ;;
-hpux*) # Its linker distinguishes data from code symbols
- if test "$host_cpu" = ia64; then
- symcode='[[ABCDEGRST]]'
- fi
- lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
- lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'"
- ;;
-linux* | k*bsd*-gnu)
- if test "$host_cpu" = ia64; then
- symcode='[[ABCDGIRSTW]]'
- lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
- lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'"
- fi
- ;;
-irix* | nonstopux*)
- symcode='[[BCDEGRST]]'
- ;;
-osf*)
- symcode='[[BCDEGQRST]]'
- ;;
-solaris*)
- symcode='[[BDRT]]'
- ;;
-sco3.2v5*)
- symcode='[[DT]]'
- ;;
-sysv4.2uw2*)
- symcode='[[DT]]'
- ;;
-sysv5* | sco5v6* | unixware* | OpenUNIX*)
- symcode='[[ABDT]]'
- ;;
-sysv4)
- symcode='[[DFNSTU]]'
- ;;
-esac
-
-# Handle CRLF in mingw tool chain
-opt_cr=
-case $build_os in
-mingw*)
- opt_cr=`echo 'x\{0,1\}' | tr x '\015'` # option cr in regexp
- ;;
-esac
-
-# If we're using GNU nm, then use its standard symbol codes.
-case `$NM -V 2>&1` in
-*GNU* | *'with BFD'*)
- symcode='[[ABCDGIRSTW]]' ;;
-esac
-
-# Try without a prefix undercore, then with it.
-for ac_symprfx in "" "_"; do
-
- # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol.
- symxfrm="\\1 $ac_symprfx\\2 \\2"
-
- # Write the raw and C identifiers.
- lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
-
- # Check to see that the pipe works correctly.
- pipe_works=no
-
- rm -f conftest*
- cat > conftest.$ac_ext <<EOF
-#ifdef __cplusplus
-extern "C" {
-#endif
-char nm_test_var;
-void nm_test_func(){}
-#ifdef __cplusplus
-}
-#endif
-int main(){nm_test_var='a';nm_test_func();return(0);}
-EOF
-
- if AC_TRY_EVAL(ac_compile); then
- # Now try to grab the symbols.
- nlist=conftest.nm
- if AC_TRY_EVAL(NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) && test -s "$nlist"; then
- # Try sorting and uniquifying the output.
- if sort "$nlist" | uniq > "$nlist"T; then
- mv -f "$nlist"T "$nlist"
- else
- rm -f "$nlist"T
- fi
-
- # Make sure that we snagged all the symbols we need.
- if grep ' nm_test_var$' "$nlist" >/dev/null; then
- if grep ' nm_test_func$' "$nlist" >/dev/null; then
- cat <<EOF > conftest.$ac_ext
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-EOF
- # Now generate the symbol file.
- eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | grep -v main >> conftest.$ac_ext'
-
- cat <<EOF >> conftest.$ac_ext
-#if defined (__STDC__) && __STDC__
-# define lt_ptr_t void *
-#else
-# define lt_ptr_t char *
-# define const
-#endif
-
-/* The mapping between symbol names and symbols. */
-const struct {
- const char *name;
- lt_ptr_t address;
-}
-lt_preloaded_symbols[[]] =
-{
-EOF
- $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (lt_ptr_t) \&\2},/" < "$nlist" | grep -v main >> conftest.$ac_ext
- cat <<\EOF >> conftest.$ac_ext
- {0, (lt_ptr_t) 0}
-};
-
-#ifdef __cplusplus
-}
-#endif
-EOF
- # Now try linking the two files.
- mv conftest.$ac_objext conftstm.$ac_objext
- lt_save_LIBS="$LIBS"
- lt_save_CFLAGS="$CFLAGS"
- LIBS="conftstm.$ac_objext"
- CFLAGS="$CFLAGS$_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)"
- if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then
- pipe_works=yes
- fi
- LIBS="$lt_save_LIBS"
- CFLAGS="$lt_save_CFLAGS"
- else
- echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD
- fi
- else
- echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD
- fi
- else
- echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD
- fi
- else
- echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD
- cat conftest.$ac_ext >&5
- fi
- rm -rf conftest* conftst*
-
- # Do not use the global_symbol_pipe unless it works.
- if test "$pipe_works" = yes; then
- break
- else
- lt_cv_sys_global_symbol_pipe=
- fi
-done
-])
-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
- AC_MSG_RESULT(failed)
-else
- AC_MSG_RESULT(ok)
-fi
-]) # AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE
-
-
-# AC_LIBTOOL_PROG_COMPILER_PIC([TAGNAME])
-# ---------------------------------------
-AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC],
-[_LT_AC_TAGVAR(lt_prog_compiler_wl, $1)=
-_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=
-_LT_AC_TAGVAR(lt_prog_compiler_static, $1)=
-
-AC_MSG_CHECKING([for $compiler option to produce PIC])
- ifelse([$1],[CXX],[
- # C++ specific cases for pic, static, wl, etc.
- if test "$GXX" = yes; then
- _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
- _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static'
-
- case $host_os in
- aix*)
- # All AIX code is PIC.
- if test "$host_cpu" = ia64; then
- # AIX 5 now supports IA64 processor
- _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
- fi
- ;;
- amigaos*)
- # FIXME: we need at least 68020 code to build shared libraries, but
- # adding the `-m68020' flag to GCC prevents building anything better,
- # like `-m68040'.
- _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
- ;;
- beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
- # PIC is the default for these OSes.
- ;;
- mingw* | cygwin* | os2* | pw32*)
- # This hack is so that the source file can tell whether it is being
- # built for inclusion in a dll (and should export symbols for example).
- # Although the cygwin gcc ignores -fPIC, still need this for old-style
- # (--disable-auto-import) libraries
- m4_if([$1], [GCJ], [],
- [_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
- ;;
- darwin* | rhapsody*)
- # PIC is the default on this platform
- # Common symbols not allowed in MH_DYLIB files
- _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
- ;;
- *djgpp*)
- # DJGPP does not support shared libraries at all
- _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=
- ;;
- interix[[3-9]]*)
- # Interix 3.x gcc -fpic/-fPIC options generate broken code.
- # Instead, we relocate shared libraries at runtime.
- ;;
- sysv4*MP*)
- if test -d /usr/nec; then
- _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic
- fi
- ;;
- hpux*)
- # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
- # not for PA HP-UX.
- case $host_cpu in
- hppa*64*|ia64*)
- ;;
- *)
- _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
- ;;
- esac
- ;;
- *)
- _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
- ;;
- esac
- else
- case $host_os in
- aix[[4-9]]*)
- # All AIX code is PIC.
- if test "$host_cpu" = ia64; then
- # AIX 5 now supports IA64 processor
- _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
- else
- _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp'
- fi
- ;;
- chorus*)
- case $cc_basename in
- cxch68*)
- # Green Hills C++ Compiler
- # _LT_AC_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a"
- ;;
- esac
- ;;
- darwin*)
- # PIC is the default on this platform
- # Common symbols not allowed in MH_DYLIB files
- case $cc_basename in
- xlc*)
- _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-qnocommon'
- _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
- ;;
- esac
- ;;
- dgux*)
- case $cc_basename in
- ec++*)
- _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
- ;;
- ghcx*)
- # Green Hills C++ Compiler
- _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
- ;;
- *)
- ;;
- esac
- ;;
- freebsd* | dragonfly*)
- # FreeBSD uses GNU C++
- ;;
- hpux9* | hpux10* | hpux11*)
- case $cc_basename in
- CC*)
- _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
- _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
- if test "$host_cpu" != ia64; then
- _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
- fi
- ;;
- aCC*)
- _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
- _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
- case $host_cpu in
- hppa*64*|ia64*)
- # +Z the default
- ;;
- *)
- _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
- ;;
- esac
- ;;
- *)
- ;;
- esac
- ;;
- interix*)
- # This is c89, which is MS Visual C++ (no shared libs)
- # Anyone wants to do a port?
- ;;
- irix5* | irix6* | nonstopux*)
- case $cc_basename in
- CC*)
- _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
- _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
- # CC pic flag -KPIC is the default.
- ;;
- *)
- ;;
- esac
- ;;
- linux* | k*bsd*-gnu)
- case $cc_basename in
- KCC*)
- # KAI C++ Compiler
- _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,'
- _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
- ;;
- icpc* | ecpc*)
- # Intel C++
- _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
- _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
- _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static'
- ;;
- pgCC* | pgcpp*)
- # Portland Group C++ compiler.
- _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
- _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
- _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
- ;;
- cxx*)
- # Compaq C++
- # Make sure the PIC flag is empty. It appears that all Alpha
- # Linux and Compaq Tru64 Unix objects are PIC.
- _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=
- _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
- ;;
- *)
- case `$CC -V 2>&1 | sed 5q` in
- *Sun\ C*)
- # Sun C++ 5.9
- _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
- _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
- _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
- ;;
- esac
- ;;
- esac
- ;;
- lynxos*)
- ;;
- m88k*)
- ;;
- mvs*)
- case $cc_basename in
- cxx*)
- _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall'
- ;;
- *)
- ;;
- esac
- ;;
- netbsd*)
- ;;
- osf3* | osf4* | osf5*)
- case $cc_basename in
- KCC*)
- _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,'
- ;;
- RCC*)
- # Rational C++ 2.4.1
- _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
- ;;
- cxx*)
- # Digital/Compaq C++
- _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
- # Make sure the PIC flag is empty. It appears that all Alpha
- # Linux and Compaq Tru64 Unix objects are PIC.
- _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=
- _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
- ;;
- *)
- ;;
- esac
- ;;
- psos*)
- ;;
- solaris*)
- case $cc_basename in
- CC*)
- # Sun C++ 4.2, 5.x and Centerline C++
- _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
- _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
- _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
- ;;
- gcx*)
- # Green Hills C++ Compiler
- _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
- ;;
- *)
- ;;
- esac
- ;;
- sunos4*)
- case $cc_basename in
- CC*)
- # Sun C++ 4.x
- _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
- _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
- ;;
- lcc*)
- # Lucid
- _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
- ;;
- *)
- ;;
- esac
- ;;
- tandem*)
- case $cc_basename in
- NCC*)
- # NonStop-UX NCC 3.20
- _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
- ;;
- *)
- ;;
- esac
- ;;
- sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
- case $cc_basename in
- CC*)
- _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
- _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
- _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
- ;;
- esac
- ;;
- vxworks*)
- ;;
- *)
- _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
- ;;
- esac
- fi
-],
-[
- if test "$GCC" = yes; then
- _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
- _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static'
-
- case $host_os in
- aix*)
- # All AIX code is PIC.
- if test "$host_cpu" = ia64; then
- # AIX 5 now supports IA64 processor
- _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
- fi
- ;;
-
- amigaos*)
- # FIXME: we need at least 68020 code to build shared libraries, but
- # adding the `-m68020' flag to GCC prevents building anything better,
- # like `-m68040'.
- _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
- ;;
-
- beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
- # PIC is the default for these OSes.
- ;;
-
- mingw* | cygwin* | pw32* | os2*)
- # This hack is so that the source file can tell whether it is being
- # built for inclusion in a dll (and should export symbols for example).
- # Although the cygwin gcc ignores -fPIC, still need this for old-style
- # (--disable-auto-import) libraries
- m4_if([$1], [GCJ], [],
- [_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
- ;;
-
- darwin* | rhapsody*)
- # PIC is the default on this platform
- # Common symbols not allowed in MH_DYLIB files
- _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
- ;;
-
- interix[[3-9]]*)
- # Interix 3.x gcc -fpic/-fPIC options generate broken code.
- # Instead, we relocate shared libraries at runtime.
- ;;
-
- msdosdjgpp*)
- # Just because we use GCC doesn't mean we suddenly get shared libraries
- # on systems that don't support them.
- _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
- enable_shared=no
- ;;
-
- sysv4*MP*)
- if test -d /usr/nec; then
- _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic
- fi
- ;;
-
- hpux*)
- # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
- # not for PA HP-UX.
- case $host_cpu in
- hppa*64*|ia64*)
- # +Z the default
- ;;
- *)
- _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
- ;;
- esac
- ;;
-
- *)
- _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
- ;;
- esac
- else
- # PORTME Check for flag to pass linker flags through the system compiler.
- case $host_os in
- aix*)
- _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
- if test "$host_cpu" = ia64; then
- # AIX 5 now supports IA64 processor
- _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
- else
- _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp'
- fi
- ;;
- darwin*)
- # PIC is the default on this platform
- # Common symbols not allowed in MH_DYLIB files
- case $cc_basename in
- xlc*)
- _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-qnocommon'
- _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
- ;;
- esac
- ;;
-
- mingw* | cygwin* | pw32* | os2*)
- # This hack is so that the source file can tell whether it is being
- # built for inclusion in a dll (and should export symbols for example).
- m4_if([$1], [GCJ], [],
- [_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
- ;;
-
- hpux9* | hpux10* | hpux11*)
- _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
- # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
- # not for PA HP-UX.
- case $host_cpu in
- hppa*64*|ia64*)
- # +Z the default
- ;;
- *)
- _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
- ;;
- esac
- # Is there a better lt_prog_compiler_static that works with the bundled CC?
- _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
- ;;
-
- irix5* | irix6* | nonstopux*)
- _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
- # PIC (with -KPIC) is the default.
- _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
- ;;
-
- newsos6)
- _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
- _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
- ;;
-
- linux* | k*bsd*-gnu)
- case $cc_basename in
- icc* | ecc*)
- _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
- _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
- _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static'
- ;;
- pgcc* | pgf77* | pgf90* | pgf95*)
- # Portland Group compilers (*not* the Pentium gcc compiler,
- # which looks to be a dead project)
- _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
- _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
- _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
- ;;
- ccc*)
- _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
- # All Alpha code is PIC.
- _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
- ;;
- *)
- case `$CC -V 2>&1 | sed 5q` in
- *Sun\ C*)
- # Sun C 5.9
- _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
- _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
- _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
- ;;
- *Sun\ F*)
- # Sun Fortran 8.3 passes all unrecognized flags to the linker
- _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
- _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
- _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)=''
- ;;
- esac
- ;;
- esac
- ;;
-
- osf3* | osf4* | osf5*)
- _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
- # All OSF/1 code is PIC.
- _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
- ;;
-
- rdos*)
- _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
- ;;
-
- solaris*)
- _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
- _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
- case $cc_basename in
- f77* | f90* | f95*)
- _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';;
- *)
- _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';;
- esac
- ;;
-
- sunos4*)
- _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
- _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
- _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
- ;;
-
- sysv4 | sysv4.2uw2* | sysv4.3*)
- _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
- _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
- _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
- ;;
-
- sysv4*MP*)
- if test -d /usr/nec ;then
- _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic'
- _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
- fi
- ;;
-
- sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
- _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
- _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
- _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
- ;;
-
- unicos*)
- _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
- _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
- ;;
-
- uts4*)
- _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
- _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
- ;;
-
- *)
- _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
- ;;
- esac
- fi
-])
-AC_MSG_RESULT([$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)])
-
-#
-# Check to make sure the PIC flag actually works.
-#
-if test -n "$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)"; then
- AC_LIBTOOL_COMPILER_OPTION([if $compiler PIC flag $_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) works],
- _LT_AC_TAGVAR(lt_cv_prog_compiler_pic_works, $1),
- [$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)ifelse([$1],[],[ -DPIC],[ifelse([$1],[CXX],[ -DPIC],[])])], [],
- [case $_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) in
- "" | " "*) ;;
- *) _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)" ;;
- esac],
- [_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=
- _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no])
-fi
-case $host_os in
- # For platforms which do not support PIC, -DPIC is meaningless:
- *djgpp*)
- _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=
- ;;
- *)
- _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)ifelse([$1],[],[ -DPIC],[ifelse([$1],[CXX],[ -DPIC],[])])"
- ;;
-esac
-
-#
-# Check to make sure the static flag actually works.
-#
-wl=$_LT_AC_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_AC_TAGVAR(lt_prog_compiler_static, $1)\"
-AC_LIBTOOL_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works],
- _LT_AC_TAGVAR(lt_cv_prog_compiler_static_works, $1),
- $lt_tmp_static_flag,
- [],
- [_LT_AC_TAGVAR(lt_prog_compiler_static, $1)=])
-])
-
-
-# AC_LIBTOOL_PROG_LD_SHLIBS([TAGNAME])
-# ------------------------------------
-# See if the linker supports building shared libraries.
-AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS],
-[AC_REQUIRE([LT_AC_PROG_SED])dnl
-AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries])
-ifelse([$1],[CXX],[
- _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
- case $host_os in
- aix[[4-9]]*)
- # If we're using GNU nm, then we don't want the "-C" option.
- # -C means demangle to AIX nm, but means don't demangle with GNU nm
- if $NM -V 2>&1 | grep 'GNU' > /dev/null; then
- _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols'
- else
- _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols'
- fi
- ;;
- pw32*)
- _LT_AC_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds"
- ;;
- cygwin* | mingw*)
- _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;/^.*[[ ]]__nm__/s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols'
- ;;
- *)
- _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
- ;;
- esac
- _LT_AC_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*']
-],[
- runpath_var=
- _LT_AC_TAGVAR(allow_undefined_flag, $1)=
- _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=no
- _LT_AC_TAGVAR(archive_cmds, $1)=
- _LT_AC_TAGVAR(archive_expsym_cmds, $1)=
- _LT_AC_TAGVAR(old_archive_From_new_cmds, $1)=
- _LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1)=
- _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)=
- _LT_AC_TAGVAR(whole_archive_flag_spec, $1)=
- _LT_AC_TAGVAR(thread_safe_flag_spec, $1)=
- _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)=
- _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=
- _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=
- _LT_AC_TAGVAR(hardcode_direct, $1)=no
- _LT_AC_TAGVAR(hardcode_minus_L, $1)=no
- _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
- _LT_AC_TAGVAR(link_all_deplibs, $1)=unknown
- _LT_AC_TAGVAR(hardcode_automatic, $1)=no
- _LT_AC_TAGVAR(module_cmds, $1)=
- _LT_AC_TAGVAR(module_expsym_cmds, $1)=
- _LT_AC_TAGVAR(always_export_symbols, $1)=no
- _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
- # include_expsyms should be a list of space-separated symbols to be *always*
- # included in the symbol list
- _LT_AC_TAGVAR(include_expsyms, $1)=
- # exclude_expsyms can be an extended regexp of symbols to exclude
- # it will be wrapped by ` (' and `)$', so one must not match beginning or
- # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
- # as well as any symbol that contains `d'.
- _LT_AC_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*']
- # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
- # platforms (ab)use it in PIC code, but their linkers get confused if
- # the symbol is explicitly referenced. Since portable code cannot
- # rely on this symbol name, it's probably fine to never include it in
- # preloaded symbol tables.
- # Exclude shared library initialization/finalization symbols.
-dnl Note also adjust exclude_expsyms for C++ above.
- extract_expsyms_cmds=
- # Just being paranoid about ensuring that cc_basename is set.
- _LT_CC_BASENAME([$compiler])
- case $host_os in
- cygwin* | mingw* | pw32*)
- # FIXME: the MSVC++ port hasn't been tested in a loooong time
- # When not using gcc, we currently assume that we are using
- # Microsoft Visual C++.
- if test "$GCC" != yes; then
- with_gnu_ld=no
- fi
- ;;
- interix*)
- # we just hope/assume this is gcc and not c89 (= MSVC++)
- with_gnu_ld=yes
- ;;
- openbsd*)
- with_gnu_ld=no
- ;;
- esac
-
- _LT_AC_TAGVAR(ld_shlibs, $1)=yes
- if test "$with_gnu_ld" = yes; then
- # If archive_cmds runs LD, not CC, wlarc should be empty
- wlarc='${wl}'
-
- # Set some defaults for GNU ld with shared library support. These
- # are reset later if shared libraries are not supported. Putting them
- # here allows them to be overridden if necessary.
- runpath_var=LD_RUN_PATH
- _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir'
- _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
- # ancient GNU ld didn't support --whole-archive et. al.
- if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then
- _LT_AC_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
- else
- _LT_AC_TAGVAR(whole_archive_flag_spec, $1)=
- fi
- supports_anon_versioning=no
- case `$LD -v 2>/dev/null` in
- *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11
- *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
- *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
- *\ 2.11.*) ;; # other 2.11 versions
- *) supports_anon_versioning=yes ;;
- esac
-
- # See if GNU ld supports shared libraries.
- case $host_os in
- aix[[3-9]]*)
- # On AIX/PPC, the GNU linker is very broken
- if test "$host_cpu" != ia64; then
- _LT_AC_TAGVAR(ld_shlibs, $1)=no
- cat <<EOF 1>&2
-
-*** Warning: the GNU linker, at least up to release 2.9.1, is reported
-*** to be unable to reliably create shared libraries on AIX.
-*** Therefore, libtool is disabling shared libraries support. If you
-*** really care for shared libraries, you may want to modify your PATH
-*** so that a non-GNU linker is found, and then restart.
-
-EOF
- fi
- ;;
-
- amigaos*)
- _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
- _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
- _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
-
- # Samuel A. Falvo II <kc5tja@dolphin.openprojects.net> reports
- # that the semantics of dynamic libraries on AmigaOS, at least up
- # to version 4, is to share data among multiple programs linked
- # with the same dynamic library. Since this doesn't match the
- # behavior of shared libraries on other platforms, we can't use
- # them.
- _LT_AC_TAGVAR(ld_shlibs, $1)=no
- ;;
-
- beos*)
- if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
- _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported
- # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
- # support --undefined. This deserves some investigation. FIXME
- _LT_AC_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- else
- _LT_AC_TAGVAR(ld_shlibs, $1)=no
- fi
- ;;
-
- cygwin* | mingw* | pw32*)
- # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
- # as there is no search path for DLLs.
- _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
- _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported
- _LT_AC_TAGVAR(always_export_symbols, $1)=no
- _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
- _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/'\'' -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols'
-
- if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then
- _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
- # If the export-symbols file already is a .def file (1st line
- # is EXPORTS), use it as is; otherwise, prepend...
- _LT_AC_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
- cp $export_symbols $output_objdir/$soname.def;
- else
- echo EXPORTS > $output_objdir/$soname.def;
- cat $export_symbols >> $output_objdir/$soname.def;
- fi~
- $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
- else
- _LT_AC_TAGVAR(ld_shlibs, $1)=no
- fi
- ;;
-
- interix[[3-9]]*)
- _LT_AC_TAGVAR(hardcode_direct, $1)=no
- _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
- _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
- _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
- # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
- # Instead, shared libraries are loaded at an image base (0x10000000 by
- # default) and relocated if they conflict, which is a slow very memory
- # consuming and fragmenting process. To avoid this, we pick a random,
- # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
- # time. Moving up from 0x10000000 also allows more sbrk(2) space.
- _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
- _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
- ;;
-
- gnu* | linux* | k*bsd*-gnu)
- if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
- tmp_addflag=
- case $cc_basename,$host_cpu in
- pgcc*) # Portland Group C compiler
- _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
- tmp_addflag=' $pic_flag'
- ;;
- pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers
- _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
- tmp_addflag=' $pic_flag -Mnomain' ;;
- ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64
- tmp_addflag=' -i_dynamic' ;;
- efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64
- tmp_addflag=' -i_dynamic -nofor_main' ;;
- ifc* | ifort*) # Intel Fortran compiler
- tmp_addflag=' -nofor_main' ;;
- esac
- case `$CC -V 2>&1 | sed 5q` in
- *Sun\ C*) # Sun C 5.9
- _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
- tmp_sharedflag='-G' ;;
- *Sun\ F*) # Sun Fortran 8.3
- tmp_sharedflag='-G' ;;
- *)
- tmp_sharedflag='-shared' ;;
- esac
- _LT_AC_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
-
- if test $supports_anon_versioning = yes; then
- _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $output_objdir/$libname.ver~
- cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
- $echo "local: *; };" >> $output_objdir/$libname.ver~
- $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
- fi
- else
- _LT_AC_TAGVAR(ld_shlibs, $1)=no
- fi
- ;;
-
- netbsd*)
- if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
- _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
- wlarc=
- else
- _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
- fi
- ;;
-
- solaris*)
- if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then
- _LT_AC_TAGVAR(ld_shlibs, $1)=no
- cat <<EOF 1>&2
-
-*** Warning: The releases 2.8.* of the GNU linker cannot reliably
-*** create shared libraries on Solaris systems. Therefore, libtool
-*** is disabling shared libraries support. We urge you to upgrade GNU
-*** binutils to release 2.9.1 or newer. Another option is to modify
-*** your PATH or compiler configuration so that the native linker is
-*** used, and then restart.
-
-EOF
- elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
- _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
- else
- _LT_AC_TAGVAR(ld_shlibs, $1)=no
- fi
- ;;
-
- sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
- case `$LD -v 2>&1` in
- *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*)
- _LT_AC_TAGVAR(ld_shlibs, $1)=no
- cat <<_LT_EOF 1>&2
-
-*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not
-*** reliably create shared libraries on SCO systems. Therefore, libtool
-*** is disabling shared libraries support. We urge you to upgrade GNU
-*** binutils to release 2.16.91.0.3 or newer. Another option is to modify
-*** your PATH or compiler configuration so that the native linker is
-*** used, and then restart.
-
-_LT_EOF
- ;;
- *)
- if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
- _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`'
- _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib'
- _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname,-retain-symbols-file,$export_symbols -o $lib'
- else
- _LT_AC_TAGVAR(ld_shlibs, $1)=no
- fi
- ;;
- esac
- ;;
-
- sunos4*)
- _LT_AC_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
- wlarc=
- _LT_AC_TAGVAR(hardcode_direct, $1)=yes
- _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
- ;;
-
- *)
- if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
- _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
- else
- _LT_AC_TAGVAR(ld_shlibs, $1)=no
- fi
- ;;
- esac
-
- if test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no; then
- runpath_var=
- _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)=
- _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)=
- _LT_AC_TAGVAR(whole_archive_flag_spec, $1)=
- fi
- else
- # PORTME fill in a description of your system's linker (not GNU ld)
- case $host_os in
- aix3*)
- _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported
- _LT_AC_TAGVAR(always_export_symbols, $1)=yes
- _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
- # Note: this linker hardcodes the directories in LIBPATH if there
- # are no directories specified by -L.
- _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
- if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then
- # Neither direct hardcoding nor static linking is supported with a
- # broken collect2.
- _LT_AC_TAGVAR(hardcode_direct, $1)=unsupported
- fi
- ;;
-
- aix[[4-9]]*)
- if test "$host_cpu" = ia64; then
- # On IA64, the linker does run time linking by default, so we don't
- # have to do anything special.
- aix_use_runtimelinking=no
- exp_sym_flag='-Bexport'
- no_entry_flag=""
- else
- # If we're using GNU nm, then we don't want the "-C" option.
- # -C means demangle to AIX nm, but means don't demangle with GNU nm
- if $NM -V 2>&1 | grep 'GNU' > /dev/null; then
- _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols'
- else
- _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols'
- fi
- aix_use_runtimelinking=no
-
- # Test if we are trying to use run time linking or normal
- # AIX style linking. If -brtl is somewhere in LDFLAGS, we
- # need to do runtime linking.
- case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*)
- for ld_flag in $LDFLAGS; do
- if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
- aix_use_runtimelinking=yes
- break
- fi
- done
- ;;
- esac
-
- exp_sym_flag='-bexport'
- no_entry_flag='-bnoentry'
- fi
-
- # When large executables or shared objects are built, AIX ld can
- # have problems creating the table of contents. If linking a library
- # or program results in "error TOC overflow" add -mminimal-toc to
- # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not
- # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
-
- _LT_AC_TAGVAR(archive_cmds, $1)=''
- _LT_AC_TAGVAR(hardcode_direct, $1)=yes
- _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':'
- _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
-
- if test "$GCC" = yes; then
- case $host_os in aix4.[[012]]|aix4.[[012]].*)
- # We only want to do this on AIX 4.2 and lower, the check
- # below for broken collect2 doesn't work under 4.3+
- collect2name=`${CC} -print-prog-name=collect2`
- if test -f "$collect2name" && \
- strings "$collect2name" | grep resolve_lib_name >/dev/null
- then
- # We have reworked collect2
- :
- else
- # We have old collect2
- _LT_AC_TAGVAR(hardcode_direct, $1)=unsupported
- # It fails to find uninstalled libraries when the uninstalled
- # path is not listed in the libpath. Setting hardcode_minus_L
- # to unsupported forces relinking
- _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
- _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
- _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=
- fi
- ;;
- esac
- shared_flag='-shared'
- if test "$aix_use_runtimelinking" = yes; then
- shared_flag="$shared_flag "'${wl}-G'
- fi
- else
- # not using gcc
- if test "$host_cpu" = ia64; then
- # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
- # chokes on -Wl,-G. The following line is correct:
- shared_flag='-G'
- else
- if test "$aix_use_runtimelinking" = yes; then
- shared_flag='${wl}-G'
- else
- shared_flag='${wl}-bM:SRE'
- fi
- fi
- fi
-
- # It seems that -bexpall does not export symbols beginning with
- # underscore (_), so it is better to generate a list of symbols to export.
- _LT_AC_TAGVAR(always_export_symbols, $1)=yes
- if test "$aix_use_runtimelinking" = yes; then
- # Warning - without using the other runtime loading flags (-brtl),
- # -berok will link without error, but may produce a broken library.
- _LT_AC_TAGVAR(allow_undefined_flag, $1)='-berok'
- # Determine the default libpath from the value encoded in an empty executable.
- _LT_AC_SYS_LIBPATH_AIX
- _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
- _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
- else
- if test "$host_cpu" = ia64; then
- _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib'
- _LT_AC_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
- _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
- else
- # Determine the default libpath from the value encoded in an empty executable.
- _LT_AC_SYS_LIBPATH_AIX
- _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
- # Warning - without using the other run time loading flags,
- # -berok will link without error, but may produce a broken library.
- _LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok'
- _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok'
- # Exported symbols can be pulled into shared objects from archives
- _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
- _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes
- # This is similar to how AIX traditionally builds its shared libraries.
- _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
- fi
- fi
- ;;
-
- amigaos*)
- _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
- _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
- _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
- # see comment about different semantics on the GNU ld section
- _LT_AC_TAGVAR(ld_shlibs, $1)=no
- ;;
-
- bsdi[[45]]*)
- _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic
- ;;
-
- cygwin* | mingw* | pw32*)
- # When not using gcc, we currently assume that we are using
- # Microsoft Visual C++.
- # hardcode_libdir_flag_spec is actually meaningless, as there is
- # no search path for DLLs.
- _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
- _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported
- # Tell ltmain to make .lib files, not .a files.
- libext=lib
- # Tell ltmain to make .dll files, not .so files.
- shrext_cmds=".dll"
- # FIXME: Setting linknames here is a bad hack.
- _LT_AC_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | $SED -e '\''s/ -lc$//'\''` -link -dll~linknames='
- # The linker will automatically build a .lib file if we build a DLL.
- _LT_AC_TAGVAR(old_archive_From_new_cmds, $1)='true'
- # FIXME: Should let the user specify the lib program.
- _LT_AC_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs'
- _LT_AC_TAGVAR(fix_srcfile_path, $1)='`cygpath -w "$srcfile"`'
- _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
- ;;
-
- darwin* | rhapsody*)
- case $host_os in
- rhapsody* | darwin1.[[012]])
- _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}suppress'
- ;;
- *) # Darwin 1.3 on
- if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then
- _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-flat_namespace ${wl}-undefined ${wl}suppress'
- else
- case ${MACOSX_DEPLOYMENT_TARGET} in
- 10.[[012]])
- _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-flat_namespace ${wl}-undefined ${wl}suppress'
- ;;
- 10.*)
- _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}dynamic_lookup'
- ;;
- esac
- fi
- ;;
- esac
- _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
- _LT_AC_TAGVAR(hardcode_direct, $1)=no
- _LT_AC_TAGVAR(hardcode_automatic, $1)=yes
- _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
- _LT_AC_TAGVAR(whole_archive_flag_spec, $1)=''
- _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
- if test "$GCC" = yes ; then
- output_verbose_link_cmd='echo'
- _LT_AC_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
- _LT_AC_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
- _LT_AC_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
- _LT_AC_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}"
- else
- case $cc_basename in
- xlc*)
- output_verbose_link_cmd='echo'
- _LT_AC_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $xlcverstring'
- _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
- # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds
- _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $xlcverstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
- _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
- ;;
- *)
- _LT_AC_TAGVAR(ld_shlibs, $1)=no
- ;;
- esac
- fi
- ;;
-
- dgux*)
- _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
- _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
- ;;
-
- freebsd1*)
- _LT_AC_TAGVAR(ld_shlibs, $1)=no
- ;;
-
- # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
- # support. Future versions do this automatically, but an explicit c++rt0.o
- # does not break anything, and helps significantly (at the cost of a little
- # extra space).
- freebsd2.2*)
- _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
- _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
- _LT_AC_TAGVAR(hardcode_direct, $1)=yes
- _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
- ;;
-
- # Unfortunately, older versions of FreeBSD 2 do not have this feature.
- freebsd2*)
- _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
- _LT_AC_TAGVAR(hardcode_direct, $1)=yes
- _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
- _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
- ;;
-
- # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
- freebsd* | dragonfly*)
- _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
- _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
- _LT_AC_TAGVAR(hardcode_direct, $1)=yes
- _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
- ;;
-
- hpux9*)
- if test "$GCC" = yes; then
- _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
- else
- _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
- fi
- _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
- _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
- _LT_AC_TAGVAR(hardcode_direct, $1)=yes
-
- # hardcode_minus_L: Not really in the search PATH,
- # but as the default location of the library.
- _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
- _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
- ;;
-
- hpux10*)
- if test "$GCC" = yes -a "$with_gnu_ld" = no; then
- _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
- else
- _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
- fi
- if test "$with_gnu_ld" = no; then
- _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
- _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
-
- _LT_AC_TAGVAR(hardcode_direct, $1)=yes
- _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
-
- # hardcode_minus_L: Not really in the search PATH,
- # but as the default location of the library.
- _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
- fi
- ;;
-
- hpux11*)
- if test "$GCC" = yes -a "$with_gnu_ld" = no; then
- case $host_cpu in
- hppa*64*)
- _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- ia64*)
- _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- *)
- _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- esac
- else
- case $host_cpu in
- hppa*64*)
- _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- ia64*)
- _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- *)
- _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- esac
- fi
- if test "$with_gnu_ld" = no; then
- _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
- _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
-
- case $host_cpu in
- hppa*64*|ia64*)
- _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir'
- _LT_AC_TAGVAR(hardcode_direct, $1)=no
- _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
- ;;
- *)
- _LT_AC_TAGVAR(hardcode_direct, $1)=yes
- _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
-
- # hardcode_minus_L: Not really in the search PATH,
- # but as the default location of the library.
- _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
- ;;
- esac
- fi
- ;;
-
- irix5* | irix6* | nonstopux*)
- if test "$GCC" = yes; then
- _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
- else
- _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
- _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='-rpath $libdir'
- fi
- _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
- _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
- _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
- ;;
-
- netbsd*)
- if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
- _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out
- else
- _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF
- fi
- _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
- _LT_AC_TAGVAR(hardcode_direct, $1)=yes
- _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
- ;;
-
- newsos6)
- _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- _LT_AC_TAGVAR(hardcode_direct, $1)=yes
- _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
- _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
- _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
- ;;
-
- openbsd*)
- if test -f /usr/libexec/ld.so; then
- _LT_AC_TAGVAR(hardcode_direct, $1)=yes
- _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
- if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
- _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
- _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'
- _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
- _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
- else
- case $host_os in
- openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*)
- _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
- _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
- ;;
- *)
- _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
- _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
- ;;
- esac
- fi
- else
- _LT_AC_TAGVAR(ld_shlibs, $1)=no
- fi
- ;;
-
- os2*)
- _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
- _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
- _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported
- _LT_AC_TAGVAR(archive_cmds, $1)='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
- _LT_AC_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
- ;;
-
- osf3*)
- if test "$GCC" = yes; then
- _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
- _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
- else
- _LT_AC_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
- _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
- fi
- _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
- _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
- ;;
-
- osf4* | osf5*) # as osf3* with the addition of -msym flag
- if test "$GCC" = yes; then
- _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
- _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
- _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
- else
- _LT_AC_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
- _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
- _LT_AC_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~
- $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~$rm $lib.exp'
-
- # Both c and cxx compiler support -rpath directly
- _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
- fi
- _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
- ;;
-
- solaris*)
- _LT_AC_TAGVAR(no_undefined_flag, $1)=' -z text'
- if test "$GCC" = yes; then
- wlarc='${wl}'
- _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
- _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
- $CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp'
- else
- wlarc=''
- _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
- _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
- $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp'
- fi
- _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
- _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
- case $host_os in
- solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
- *)
- # The compiler driver will combine and reorder linker options,
- # but understands `-z linker_flag'. GCC discards it without `$wl',
- # but is careful enough not to reorder.
- # Supported since Solaris 2.6 (maybe 2.5.1?)
- if test "$GCC" = yes; then
- _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
- else
- _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract'
- fi
- ;;
- esac
- _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
- ;;
-
- sunos4*)
- if test "x$host_vendor" = xsequent; then
- # Use $CC to link under sequent, because it throws in some extra .o
- # files that make .init and .fini sections work.
- _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
- else
- _LT_AC_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
- fi
- _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
- _LT_AC_TAGVAR(hardcode_direct, $1)=yes
- _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
- _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
- ;;
-
- sysv4)
- case $host_vendor in
- sni)
- _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- _LT_AC_TAGVAR(hardcode_direct, $1)=yes # is this really true???
- ;;
- siemens)
- ## LD is ld it makes a PLAMLIB
- ## CC just makes a GrossModule.
- _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags'
- _LT_AC_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs'
- _LT_AC_TAGVAR(hardcode_direct, $1)=no
- ;;
- motorola)
- _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- _LT_AC_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie
- ;;
- esac
- runpath_var='LD_RUN_PATH'
- _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
- ;;
-
- sysv4.3*)
- _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
- _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport'
- ;;
-
- sysv4*MP*)
- if test -d /usr/nec; then
- _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
- runpath_var=LD_RUN_PATH
- hardcode_runpath_var=yes
- _LT_AC_TAGVAR(ld_shlibs, $1)=yes
- fi
- ;;
-
- sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*)
- _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
- _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
- _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
- runpath_var='LD_RUN_PATH'
-
- if test "$GCC" = yes; then
- _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- else
- _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- fi
- ;;
-
- sysv5* | sco3.2v5* | sco5v6*)
- # Note: We can NOT use -z defs as we might desire, because we do not
- # link with -lc, and that would cause any symbols used from libc to
- # always be unresolved, which means just about no library would
- # ever link correctly. If we're not using GNU ld we use -z text
- # though, which does catch some bad symbols but isn't as heavy-handed
- # as -z defs.
- _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
- _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs'
- _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
- _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
- _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`'
- _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':'
- _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
- _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport'
- runpath_var='LD_RUN_PATH'
-
- if test "$GCC" = yes; then
- _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
- _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
- else
- _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
- _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
- fi
- ;;
-
- uts4*)
- _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
- _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
- ;;
-
- *)
- _LT_AC_TAGVAR(ld_shlibs, $1)=no
- ;;
- esac
- fi
-])
-AC_MSG_RESULT([$_LT_AC_TAGVAR(ld_shlibs, $1)])
-test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no
-
-#
-# Do we need to explicitly link libc?
-#
-case "x$_LT_AC_TAGVAR(archive_cmds_need_lc, $1)" in
-x|xyes)
- # Assume -lc should be added
- _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes
-
- if test "$enable_shared" = yes && test "$GCC" = yes; then
- case $_LT_AC_TAGVAR(archive_cmds, $1) in
- *'~'*)
- # FIXME: we may have to deal with multi-command sequences.
- ;;
- '$CC '*)
- # 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.
- AC_MSG_CHECKING([whether -lc should be explicitly linked in])
- $rm conftest*
- echo "$lt_simple_compile_test_code" > conftest.$ac_ext
-
- if AC_TRY_EVAL(ac_compile) 2>conftest.err; then
- soname=conftest
- lib=conftest
- libobjs=conftest.$ac_objext
- deplibs=
- wl=$_LT_AC_TAGVAR(lt_prog_compiler_wl, $1)
- pic_flag=$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)
- compiler_flags=-v
- linker_flags=-v
- verstring=
- output_objdir=.
- libname=conftest
- lt_save_allow_undefined_flag=$_LT_AC_TAGVAR(allow_undefined_flag, $1)
- _LT_AC_TAGVAR(allow_undefined_flag, $1)=
- if AC_TRY_EVAL(_LT_AC_TAGVAR(archive_cmds, $1) 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1)
- then
- _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
- else
- _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes
- fi
- _LT_AC_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag
- else
- cat conftest.err 1>&5
- fi
- $rm conftest*
- AC_MSG_RESULT([$_LT_AC_TAGVAR(archive_cmds_need_lc, $1)])
- ;;
- esac
- fi
- ;;
-esac
-])# AC_LIBTOOL_PROG_LD_SHLIBS
-
-
-# _LT_AC_FILE_LTDLL_C
-# -------------------
-# Be careful that the start marker always follows a newline.
-AC_DEFUN([_LT_AC_FILE_LTDLL_C], [
-# /* ltdll.c starts here */
-# #define WIN32_LEAN_AND_MEAN
-# #include <windows.h>
-# #undef WIN32_LEAN_AND_MEAN
-# #include <stdio.h>
-#
-# #ifndef __CYGWIN__
-# # ifdef __CYGWIN32__
-# # define __CYGWIN__ __CYGWIN32__
-# # endif
-# #endif
-#
-# #ifdef __cplusplus
-# extern "C" {
-# #endif
-# BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved);
-# #ifdef __cplusplus
-# }
-# #endif
-#
-# #ifdef __CYGWIN__
-# #include <cygwin/cygwin_dll.h>
-# DECLARE_CYGWIN_DLL( DllMain );
-# #endif
-# HINSTANCE __hDllInstance_base;
-#
-# BOOL APIENTRY
-# DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved)
-# {
-# __hDllInstance_base = hInst;
-# return TRUE;
-# }
-# /* ltdll.c ends here */
-])# _LT_AC_FILE_LTDLL_C
-
-
-# _LT_AC_TAGVAR(VARNAME, [TAGNAME])
-# ---------------------------------
-AC_DEFUN([_LT_AC_TAGVAR], [ifelse([$2], [], [$1], [$1_$2])])
-
-
-# old names
-AC_DEFUN([AM_PROG_LIBTOOL], [AC_PROG_LIBTOOL])
-AC_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)])
-AC_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)])
-AC_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)])
-AC_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)])
-AC_DEFUN([AM_PROG_LD], [AC_PROG_LD])
-AC_DEFUN([AM_PROG_NM], [AC_PROG_NM])
-
-# This is just to silence aclocal about the macro not being used
-ifelse([AC_DISABLE_FAST_INSTALL])
-
-AC_DEFUN([LT_AC_PROG_GCJ],
-[AC_CHECK_TOOL(GCJ, gcj, no)
- test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2"
- AC_SUBST(GCJFLAGS)
-])
-
-AC_DEFUN([LT_AC_PROG_RC],
-[AC_CHECK_TOOL(RC, windres, no)
-])
-
-
-# Cheap backport of AS_EXECUTABLE_P and required macros
-# from Autoconf 2.59; we should not use $as_executable_p directly.
-
-# _AS_TEST_PREPARE
-# ----------------
-m4_ifndef([_AS_TEST_PREPARE],
-[m4_defun([_AS_TEST_PREPARE],
-[if test -x / >/dev/null 2>&1; then
- as_executable_p='test -x'
-else
- as_executable_p='test -f'
-fi
-])])# _AS_TEST_PREPARE
-
-# AS_EXECUTABLE_P
-# ---------------
-# Check whether a file is executable.
-m4_ifndef([AS_EXECUTABLE_P],
-[m4_defun([AS_EXECUTABLE_P],
-[AS_REQUIRE([_AS_TEST_PREPARE])dnl
-$as_executable_p $1[]dnl
-])])# AS_EXECUTABLE_P
-
-# NOTE: This macro has been submitted for inclusion into #
-# GNU Autoconf as AC_PROG_SED. When it is available in #
-# a released version of Autoconf we should remove this #
-# macro and use it instead. #
-# LT_AC_PROG_SED
-# --------------
-# Check for a fully-functional sed program, that truncates
-# as few characters as possible. Prefer GNU sed if found.
-AC_DEFUN([LT_AC_PROG_SED],
-[AC_MSG_CHECKING([for a sed that does not truncate output])
-AC_CACHE_VAL(lt_cv_path_SED,
-[# Loop through the user's path and test for sed and gsed.
-# Then use that list of sed's as ones to test for truncation.
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for lt_ac_prog in sed gsed; do
- for ac_exec_ext in '' $ac_executable_extensions; do
- if AS_EXECUTABLE_P(["$as_dir/$lt_ac_prog$ac_exec_ext"]); then
- lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext"
- fi
- done
- done
-done
-IFS=$as_save_IFS
-lt_ac_max=0
-lt_ac_count=0
-# Add /usr/xpg4/bin/sed as it is typically found on Solaris
-# along with /bin/sed that truncates output.
-for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do
- test ! -f $lt_ac_sed && continue
- cat /dev/null > conftest.in
- lt_ac_count=0
- echo $ECHO_N "0123456789$ECHO_C" >conftest.in
- # Check for GNU sed and select it if it is found.
- if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then
- lt_cv_path_SED=$lt_ac_sed
- break
- fi
- while true; do
- cat conftest.in conftest.in >conftest.tmp
- mv conftest.tmp conftest.in
- cp conftest.in conftest.nl
- echo >>conftest.nl
- $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break
- cmp -s conftest.out conftest.nl || break
- # 10000 chars as input seems more than enough
- test $lt_ac_count -gt 10 && break
- lt_ac_count=`expr $lt_ac_count + 1`
- if test $lt_ac_count -gt $lt_ac_max; then
- lt_ac_max=$lt_ac_count
- lt_cv_path_SED=$lt_ac_sed
- fi
- done
-done
-])
-SED=$lt_cv_path_SED
-AC_SUBST([SED])
-AC_MSG_RESULT([$SED])
-])
-
-# Copyright (C) 2002, 2003, 2005, 2006, 2007 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# AM_AUTOMAKE_VERSION(VERSION)
-# ----------------------------
-# Automake X.Y traces this macro to ensure aclocal.m4 has been
-# generated from the m4 files accompanying Automake X.Y.
-# (This private macro should not be called outside this file.)
-AC_DEFUN([AM_AUTOMAKE_VERSION],
-[am__api_version='1.10'
-dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
-dnl require some minimum version. Point them to the right macro.
-m4_if([$1], [1.10.1], [],
- [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
-])
-
-# _AM_AUTOCONF_VERSION(VERSION)
-# -----------------------------
-# aclocal traces this macro to find the Autoconf version.
-# This is a private macro too. Using m4_define simplifies
-# the logic in aclocal, which can simply ignore this definition.
-m4_define([_AM_AUTOCONF_VERSION], [])
-
-# AM_SET_CURRENT_AUTOMAKE_VERSION
-# -------------------------------
-# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
-# This function is AC_REQUIREd by AC_INIT_AUTOMAKE.
-AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
-[AM_AUTOMAKE_VERSION([1.10.1])dnl
-m4_ifndef([AC_AUTOCONF_VERSION],
- [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
-_AM_AUTOCONF_VERSION(AC_AUTOCONF_VERSION)])
-
-# AM_AUX_DIR_EXPAND -*- Autoconf -*-
-
-# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
-# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to
-# `$srcdir', `$srcdir/..', or `$srcdir/../..'.
-#
-# Of course, Automake must honor this variable whenever it calls a
-# tool from the auxiliary directory. The problem is that $srcdir (and
-# therefore $ac_aux_dir as well) can be either absolute or relative,
-# depending on how configure is run. This is pretty annoying, since
-# it makes $ac_aux_dir quite unusable in subdirectories: in the top
-# source directory, any form will work fine, but in subdirectories a
-# relative path needs to be adjusted first.
-#
-# $ac_aux_dir/missing
-# fails when called from a subdirectory if $ac_aux_dir is relative
-# $top_srcdir/$ac_aux_dir/missing
-# fails if $ac_aux_dir is absolute,
-# fails when called from a subdirectory in a VPATH build with
-# a relative $ac_aux_dir
-#
-# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
-# are both prefixed by $srcdir. In an in-source build this is usually
-# harmless because $srcdir is `.', but things will broke when you
-# start a VPATH build or use an absolute $srcdir.
-#
-# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
-# iff we strip the leading $srcdir from $ac_aux_dir. That would be:
-# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"`
-# and then we would define $MISSING as
-# MISSING="\${SHELL} $am_aux_dir/missing"
-# This will work as long as MISSING is not called from configure, because
-# unfortunately $(top_srcdir) has no meaning in configure.
-# However there are other variables, like CC, which are often used in
-# configure, and could therefore not use this "fixed" $ac_aux_dir.
-#
-# Another solution, used here, is to always expand $ac_aux_dir to an
-# absolute PATH. The drawback is that using absolute paths prevent a
-# configured tree to be moved without reconfiguration.
-
-AC_DEFUN([AM_AUX_DIR_EXPAND],
-[dnl Rely on autoconf to set up CDPATH properly.
-AC_PREREQ([2.50])dnl
-# expand $ac_aux_dir to an absolute path
-am_aux_dir=`cd $ac_aux_dir && pwd`
-])
-
-# AM_CONDITIONAL -*- Autoconf -*-
-
-# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006
-# Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# serial 8
-
-# AM_CONDITIONAL(NAME, SHELL-CONDITION)
-# -------------------------------------
-# Define a conditional.
-AC_DEFUN([AM_CONDITIONAL],
-[AC_PREREQ(2.52)dnl
- ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])],
- [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
-AC_SUBST([$1_TRUE])dnl
-AC_SUBST([$1_FALSE])dnl
-_AM_SUBST_NOTMAKE([$1_TRUE])dnl
-_AM_SUBST_NOTMAKE([$1_FALSE])dnl
-if $2; then
- $1_TRUE=
- $1_FALSE='#'
-else
- $1_TRUE='#'
- $1_FALSE=
-fi
-AC_CONFIG_COMMANDS_PRE(
-[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
- AC_MSG_ERROR([[conditional "$1" was never defined.
-Usually this means the macro was only invoked conditionally.]])
-fi])])
-
-# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
-# Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# serial 9
-
-# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be
-# written in clear, in which case automake, when reading aclocal.m4,
-# will think it sees a *use*, and therefore will trigger all it's
-# C support machinery. Also note that it means that autoscan, seeing
-# CC etc. in the Makefile, will ask for an AC_PROG_CC use...
-
-
-# _AM_DEPENDENCIES(NAME)
-# ----------------------
-# See how the compiler implements dependency checking.
-# NAME is "CC", "CXX", "GCJ", or "OBJC".
-# We try a few techniques and use that to set a single cache variable.
-#
-# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was
-# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular
-# dependency, and given that the user is not expected to run this macro,
-# just rely on AC_PROG_CC.
-AC_DEFUN([_AM_DEPENDENCIES],
-[AC_REQUIRE([AM_SET_DEPDIR])dnl
-AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl
-AC_REQUIRE([AM_MAKE_INCLUDE])dnl
-AC_REQUIRE([AM_DEP_TRACK])dnl
-
-ifelse([$1], CC, [depcc="$CC" am_compiler_list=],
- [$1], CXX, [depcc="$CXX" am_compiler_list=],
- [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
- [$1], UPC, [depcc="$UPC" am_compiler_list=],
- [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'],
- [depcc="$$1" am_compiler_list=])
-
-AC_CACHE_CHECK([dependency style of $depcc],
- [am_cv_$1_dependencies_compiler_type],
-[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
- # We make a subdir and do the tests there. Otherwise we can end up
- # making bogus files that we don't know about and never remove. For
- # instance it was reported that on HP-UX the gcc test will end up
- # making a dummy file named `D' -- because `-MD' means `put the output
- # in D'.
- mkdir conftest.dir
- # Copy depcomp to subdir because otherwise we won't find it if we're
- # using a relative directory.
- cp "$am_depcomp" conftest.dir
- cd conftest.dir
- # We will build objects and dependencies in a subdirectory because
- # it helps to detect inapplicable dependency modes. For instance
- # both Tru64's cc and ICC support -MD to output dependencies as a
- # side effect of compilation, but ICC will put the dependencies in
- # the current directory while Tru64 will put them in the object
- # directory.
- mkdir sub
-
- am_cv_$1_dependencies_compiler_type=none
- if test "$am_compiler_list" = ""; then
- am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp`
- fi
- for depmode in $am_compiler_list; do
- # Setup a source with many dependencies, because some compilers
- # like to wrap large dependency lists on column 80 (with \), and
- # we should not choose a depcomp mode which is confused by this.
- #
- # We need to recreate these files for each test, as the compiler may
- # overwrite some of them when testing with obscure command lines.
- # This happens at least with the AIX C compiler.
- : > sub/conftest.c
- for i in 1 2 3 4 5 6; do
- echo '#include "conftst'$i'.h"' >> sub/conftest.c
- # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
- # Solaris 8's {/usr,}/bin/sh.
- touch sub/conftst$i.h
- done
- echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
-
- case $depmode in
- nosideeffect)
- # after this tag, mechanisms are not by side-effect, so they'll
- # only be used when explicitly requested
- if test "x$enable_dependency_tracking" = xyes; then
- continue
- else
- break
- fi
- ;;
- none) break ;;
- esac
- # We check with `-c' and `-o' for the sake of the "dashmstdout"
- # mode. It turns out that the SunPro C++ compiler does not properly
- # handle `-M -o', and we need to detect this.
- if depmode=$depmode \
- source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \
- depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
- $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \
- >/dev/null 2>conftest.err &&
- grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
- grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
- grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 &&
- ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
- # icc doesn't choke on unknown options, it will just issue warnings
- # or remarks (even with -Werror). So we grep stderr for any message
- # that says an option was ignored or not supported.
- # When given -MP, icc 7.0 and 7.1 complain thusly:
- # icc: Command line warning: ignoring option '-M'; no argument required
- # The diagnosis changed in icc 8.0:
- # icc: Command line remark: option '-MP' not supported
- if (grep 'ignoring option' conftest.err ||
- grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
- am_cv_$1_dependencies_compiler_type=$depmode
- break
- fi
- fi
- done
-
- cd ..
- rm -rf conftest.dir
-else
- am_cv_$1_dependencies_compiler_type=none
-fi
-])
-AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type])
-AM_CONDITIONAL([am__fastdep$1], [
- test "x$enable_dependency_tracking" != xno \
- && test "$am_cv_$1_dependencies_compiler_type" = gcc3])
-])
-
-
-# AM_SET_DEPDIR
-# -------------
-# Choose a directory name for dependency files.
-# This macro is AC_REQUIREd in _AM_DEPENDENCIES
-AC_DEFUN([AM_SET_DEPDIR],
-[AC_REQUIRE([AM_SET_LEADING_DOT])dnl
-AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl
-])
-
-
-# AM_DEP_TRACK
-# ------------
-AC_DEFUN([AM_DEP_TRACK],
-[AC_ARG_ENABLE(dependency-tracking,
-[ --disable-dependency-tracking speeds up one-time build
- --enable-dependency-tracking do not reject slow dependency extractors])
-if test "x$enable_dependency_tracking" != xno; then
- am_depcomp="$ac_aux_dir/depcomp"
- AMDEPBACKSLASH='\'
-fi
-AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
-AC_SUBST([AMDEPBACKSLASH])dnl
-_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl
-])
-
-# Generate code to set up dependency tracking. -*- Autoconf -*-
-
-# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
-# Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-#serial 3
-
-# _AM_OUTPUT_DEPENDENCY_COMMANDS
-# ------------------------------
-AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
-[for mf in $CONFIG_FILES; do
- # Strip MF so we end up with the name of the file.
- mf=`echo "$mf" | sed -e 's/:.*$//'`
- # Check whether this is an Automake generated Makefile or not.
- # We used to match only the files named `Makefile.in', but
- # some people rename them; so instead we look at the file content.
- # Grep'ing the first line is not enough: some people post-process
- # each Makefile.in and add a new line on top of each file to say so.
- # Grep'ing the whole file is not good either: AIX grep has a line
- # limit of 2048, but all sed's we know have understand at least 4000.
- if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
- dirpart=`AS_DIRNAME("$mf")`
- else
- continue
- fi
- # Extract the definition of DEPDIR, am__include, and am__quote
- # from the Makefile without running `make'.
- DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
- test -z "$DEPDIR" && continue
- am__include=`sed -n 's/^am__include = //p' < "$mf"`
- test -z "am__include" && continue
- am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
- # When using ansi2knr, U may be empty or an underscore; expand it
- U=`sed -n 's/^U = //p' < "$mf"`
- # Find all dependency output files, they are included files with
- # $(DEPDIR) in their names. We invoke sed twice because it is the
- # simplest approach to changing $(DEPDIR) to its actual value in the
- # expansion.
- for file in `sed -n "
- s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
- sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
- # Make sure the directory exists.
- test -f "$dirpart/$file" && continue
- fdir=`AS_DIRNAME(["$file"])`
- AS_MKDIR_P([$dirpart/$fdir])
- # echo "creating $dirpart/$file"
- echo '# dummy' > "$dirpart/$file"
- done
-done
-])# _AM_OUTPUT_DEPENDENCY_COMMANDS
-
-
-# AM_OUTPUT_DEPENDENCY_COMMANDS
-# -----------------------------
-# This macro should only be invoked once -- use via AC_REQUIRE.
-#
-# This code is only required when automatic dependency tracking
-# is enabled. FIXME. This creates each `.P' file that we will
-# need in order to bootstrap the dependency handling code.
-AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
-[AC_CONFIG_COMMANDS([depfiles],
- [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS],
- [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
-])
-
-# Do all the work for Automake. -*- Autoconf -*-
-
-# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-# 2005, 2006, 2008 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# serial 13
-
-# This macro actually does too much. Some checks are only needed if
-# your package does certain things. But this isn't really a big deal.
-
-# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
-# AM_INIT_AUTOMAKE([OPTIONS])
-# -----------------------------------------------
-# The call with PACKAGE and VERSION arguments is the old style
-# call (pre autoconf-2.50), which is being phased out. PACKAGE
-# and VERSION should now be passed to AC_INIT and removed from
-# the call to AM_INIT_AUTOMAKE.
-# We support both call styles for the transition. After
-# the next Automake release, Autoconf can make the AC_INIT
-# arguments mandatory, and then we can depend on a new Autoconf
-# release and drop the old call support.
-AC_DEFUN([AM_INIT_AUTOMAKE],
-[AC_PREREQ([2.60])dnl
-dnl Autoconf wants to disallow AM_ names. We explicitly allow
-dnl the ones we care about.
-m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
-AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl
-AC_REQUIRE([AC_PROG_INSTALL])dnl
-if test "`cd $srcdir && pwd`" != "`pwd`"; then
- # Use -I$(srcdir) only when $(srcdir) != ., so that make's output
- # is not polluted with repeated "-I."
- AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl
- # test to see if srcdir already configured
- if test -f $srcdir/config.status; then
- AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
- fi
-fi
-
-# test whether we have cygpath
-if test -z "$CYGPATH_W"; then
- if (cygpath --version) >/dev/null 2>/dev/null; then
- CYGPATH_W='cygpath -w'
- else
- CYGPATH_W=echo
- fi
-fi
-AC_SUBST([CYGPATH_W])
-
-# Define the identity of the package.
-dnl Distinguish between old-style and new-style calls.
-m4_ifval([$2],
-[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
- AC_SUBST([PACKAGE], [$1])dnl
- AC_SUBST([VERSION], [$2])],
-[_AM_SET_OPTIONS([$1])dnl
-dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT.
-m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,,
- [m4_fatal([AC_INIT should be called with package and version arguments])])dnl
- AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
- AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl
-
-_AM_IF_OPTION([no-define],,
-[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
- AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl
-
-# Some tools Automake needs.
-AC_REQUIRE([AM_SANITY_CHECK])dnl
-AC_REQUIRE([AC_ARG_PROGRAM])dnl
-AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version})
-AM_MISSING_PROG(AUTOCONF, autoconf)
-AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version})
-AM_MISSING_PROG(AUTOHEADER, autoheader)
-AM_MISSING_PROG(MAKEINFO, makeinfo)
-AM_PROG_INSTALL_SH
-AM_PROG_INSTALL_STRIP
-AC_REQUIRE([AM_PROG_MKDIR_P])dnl
-# We need awk for the "check" target. The system "awk" is bad on
-# some platforms.
-AC_REQUIRE([AC_PROG_AWK])dnl
-AC_REQUIRE([AC_PROG_MAKE_SET])dnl
-AC_REQUIRE([AM_SET_LEADING_DOT])dnl
-_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])],
- [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])],
- [_AM_PROG_TAR([v7])])])
-_AM_IF_OPTION([no-dependencies],,
-[AC_PROVIDE_IFELSE([AC_PROG_CC],
- [_AM_DEPENDENCIES(CC)],
- [define([AC_PROG_CC],
- defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl
-AC_PROVIDE_IFELSE([AC_PROG_CXX],
- [_AM_DEPENDENCIES(CXX)],
- [define([AC_PROG_CXX],
- defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl
-AC_PROVIDE_IFELSE([AC_PROG_OBJC],
- [_AM_DEPENDENCIES(OBJC)],
- [define([AC_PROG_OBJC],
- defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl
-])
-])
-
-
-# When config.status generates a header, we must update the stamp-h file.
-# This file resides in the same directory as the config header
-# that is generated. The stamp files are numbered to have different names.
-
-# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the
-# loop where config.status creates the headers, so we can generate
-# our stamp files there.
-AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
-[# Compute $1's index in $config_headers.
-_am_arg=$1
-_am_stamp_count=1
-for _am_header in $config_headers :; do
- case $_am_header in
- $_am_arg | $_am_arg:* )
- break ;;
- * )
- _am_stamp_count=`expr $_am_stamp_count + 1` ;;
- esac
-done
-echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
-
-# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# AM_PROG_INSTALL_SH
-# ------------------
-# Define $install_sh.
-AC_DEFUN([AM_PROG_INSTALL_SH],
-[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
-install_sh=${install_sh-"\$(SHELL) $am_aux_dir/install-sh"}
-AC_SUBST(install_sh)])
-
-# Copyright (C) 2003, 2005 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# serial 2
-
-# Check whether the underlying file-system supports filenames
-# with a leading dot. For instance MS-DOS doesn't.
-AC_DEFUN([AM_SET_LEADING_DOT],
-[rm -rf .tst 2>/dev/null
-mkdir .tst 2>/dev/null
-if test -d .tst; then
- am__leading_dot=.
-else
- am__leading_dot=_
-fi
-rmdir .tst 2>/dev/null
-AC_SUBST([am__leading_dot])])
-
-# Check to see how 'make' treats includes. -*- Autoconf -*-
-
-# Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# serial 3
-
-# AM_MAKE_INCLUDE()
-# -----------------
-# Check to see how make treats includes.
-AC_DEFUN([AM_MAKE_INCLUDE],
-[am_make=${MAKE-make}
-cat > confinc << 'END'
-am__doit:
- @echo done
-.PHONY: am__doit
-END
-# If we don't find an include directive, just comment out the code.
-AC_MSG_CHECKING([for style of include used by $am_make])
-am__include="#"
-am__quote=
-_am_result=none
-# First try GNU make style include.
-echo "include confinc" > confmf
-# We grep out `Entering directory' and `Leaving directory'
-# messages which can occur if `w' ends up in MAKEFLAGS.
-# In particular we don't look at `^make:' because GNU make might
-# be invoked under some other name (usually "gmake"), in which
-# case it prints its new name instead of `make'.
-if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then
- am__include=include
- am__quote=
- _am_result=GNU
-fi
-# Now try BSD make style include.
-if test "$am__include" = "#"; then
- echo '.include "confinc"' > confmf
- if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then
- am__include=.include
- am__quote="\""
- _am_result=BSD
- fi
-fi
-AC_SUBST([am__include])
-AC_SUBST([am__quote])
-AC_MSG_RESULT([$_am_result])
-rm -f confinc confmf
-])
-
-# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-
-
-# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005
-# Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# serial 5
-
-# AM_MISSING_PROG(NAME, PROGRAM)
-# ------------------------------
-AC_DEFUN([AM_MISSING_PROG],
-[AC_REQUIRE([AM_MISSING_HAS_RUN])
-$1=${$1-"${am_missing_run}$2"}
-AC_SUBST($1)])
-
-
-# AM_MISSING_HAS_RUN
-# ------------------
-# Define MISSING if not defined so far and test if it supports --run.
-# If it does, set am_missing_run to use it, otherwise, to nothing.
-AC_DEFUN([AM_MISSING_HAS_RUN],
-[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
-AC_REQUIRE_AUX_FILE([missing])dnl
-test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing"
-# Use eval to expand $SHELL
-if eval "$MISSING --run true"; then
- am_missing_run="$MISSING --run "
-else
- am_missing_run=
- AC_MSG_WARN([`missing' script is too old or missing])
-fi
-])
-
-# Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# AM_PROG_MKDIR_P
-# ---------------
-# Check for `mkdir -p'.
-AC_DEFUN([AM_PROG_MKDIR_P],
-[AC_PREREQ([2.60])dnl
-AC_REQUIRE([AC_PROG_MKDIR_P])dnl
-dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P,
-dnl while keeping a definition of mkdir_p for backward compatibility.
-dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile.
-dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of
-dnl Makefile.ins that do not define MKDIR_P, so we do our own
-dnl adjustment using top_builddir (which is defined more often than
-dnl MKDIR_P).
-AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl
-case $mkdir_p in
- [[\\/$]]* | ?:[[\\/]]*) ;;
- */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;;
-esac
-])
-
-# Helper functions for option handling. -*- Autoconf -*-
-
-# Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# serial 3
-
-# _AM_MANGLE_OPTION(NAME)
-# -----------------------
-AC_DEFUN([_AM_MANGLE_OPTION],
-[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])
-
-# _AM_SET_OPTION(NAME)
-# ------------------------------
-# Set option NAME. Presently that only means defining a flag for this option.
-AC_DEFUN([_AM_SET_OPTION],
-[m4_define(_AM_MANGLE_OPTION([$1]), 1)])
-
-# _AM_SET_OPTIONS(OPTIONS)
-# ----------------------------------
-# OPTIONS is a space-separated list of Automake options.
-AC_DEFUN([_AM_SET_OPTIONS],
-[AC_FOREACH([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
-
-# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET])
-# -------------------------------------------
-# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
-AC_DEFUN([_AM_IF_OPTION],
-[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
-
-# Check to make sure that the build environment is sane. -*- Autoconf -*-
-
-# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005
-# Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# serial 4
-
-# AM_SANITY_CHECK
-# ---------------
-AC_DEFUN([AM_SANITY_CHECK],
-[AC_MSG_CHECKING([whether build environment is sane])
-# Just in case
-sleep 1
-echo timestamp > conftest.file
-# Do `set' in a subshell so we don't clobber the current shell's
-# arguments. Must try -L first in case configure is actually a
-# symlink; some systems play weird games with the mod time of symlinks
-# (eg FreeBSD returns the mod time of the symlink's containing
-# directory).
-if (
- set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null`
- if test "$[*]" = "X"; then
- # -L didn't work.
- set X `ls -t $srcdir/configure conftest.file`
- fi
- rm -f conftest.file
- if test "$[*]" != "X $srcdir/configure conftest.file" \
- && test "$[*]" != "X conftest.file $srcdir/configure"; then
-
- # If neither matched, then we have a broken ls. This can happen
- # if, for instance, CONFIG_SHELL is bash and it inherits a
- # broken ls alias from the environment. This has actually
- # happened. Such a system could not be considered "sane".
- AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
-alias in your environment])
- fi
-
- test "$[2]" = conftest.file
- )
-then
- # Ok.
- :
-else
- AC_MSG_ERROR([newly created file is older than distributed files!
-Check your system clock])
-fi
-AC_MSG_RESULT(yes)])
-
-# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# AM_PROG_INSTALL_STRIP
-# ---------------------
-# One issue with vendor `install' (even GNU) is that you can't
-# specify the program used to strip binaries. This is especially
-# annoying in cross-compiling environments, where the build's strip
-# is unlikely to handle the host's binaries.
-# Fortunately install-sh will honor a STRIPPROG variable, so we
-# always use install-sh in `make install-strip', and initialize
-# STRIPPROG with the value of the STRIP variable (set by the user).
-AC_DEFUN([AM_PROG_INSTALL_STRIP],
-[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
-# Installed binaries are usually stripped using `strip' when the user
-# run `make install-strip'. However `strip' might not be the right
-# tool to use in cross-compilation environments, therefore Automake
-# will honor the `STRIP' environment variable to overrule this program.
-dnl Don't test for $cross_compiling = yes, because it might be `maybe'.
-if test "$cross_compiling" != no; then
- AC_CHECK_TOOL([STRIP], [strip], :)
-fi
-INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
-AC_SUBST([INSTALL_STRIP_PROGRAM])])
-
-# Copyright (C) 2006 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# _AM_SUBST_NOTMAKE(VARIABLE)
-# ---------------------------
-# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in.
-# This macro is traced by Automake.
-AC_DEFUN([_AM_SUBST_NOTMAKE])
-
-# Check how to create a tarball. -*- Autoconf -*-
-
-# Copyright (C) 2004, 2005 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# serial 2
-
-# _AM_PROG_TAR(FORMAT)
-# --------------------
-# Check how to create a tarball in format FORMAT.
-# FORMAT should be one of `v7', `ustar', or `pax'.
-#
-# Substitute a variable $(am__tar) that is a command
-# writing to stdout a FORMAT-tarball containing the directory
-# $tardir.
-# tardir=directory && $(am__tar) > result.tar
-#
-# Substitute a variable $(am__untar) that extract such
-# a tarball read from stdin.
-# $(am__untar) < result.tar
-AC_DEFUN([_AM_PROG_TAR],
-[# Always define AMTAR for backward compatibility.
-AM_MISSING_PROG([AMTAR], [tar])
-m4_if([$1], [v7],
- [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'],
- [m4_case([$1], [ustar],, [pax],,
- [m4_fatal([Unknown tar format])])
-AC_MSG_CHECKING([how to create a $1 tar archive])
-# Loop over all known methods to create a tar archive until one works.
-_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none'
-_am_tools=${am_cv_prog_tar_$1-$_am_tools}
-# Do not fold the above two line into one, because Tru64 sh and
-# Solaris sh will not grok spaces in the rhs of `-'.
-for _am_tool in $_am_tools
-do
- case $_am_tool in
- gnutar)
- for _am_tar in tar gnutar gtar;
- do
- AM_RUN_LOG([$_am_tar --version]) && break
- done
- am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"'
- am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"'
- am__untar="$_am_tar -xf -"
- ;;
- plaintar)
- # Must skip GNU tar: if it does not support --format= it doesn't create
- # ustar tarball either.
- (tar --version) >/dev/null 2>&1 && continue
- am__tar='tar chf - "$$tardir"'
- am__tar_='tar chf - "$tardir"'
- am__untar='tar xf -'
- ;;
- pax)
- am__tar='pax -L -x $1 -w "$$tardir"'
- am__tar_='pax -L -x $1 -w "$tardir"'
- am__untar='pax -r'
- ;;
- cpio)
- am__tar='find "$$tardir" -print | cpio -o -H $1 -L'
- am__tar_='find "$tardir" -print | cpio -o -H $1 -L'
- am__untar='cpio -i -H $1 -d'
- ;;
- none)
- am__tar=false
- am__tar_=false
- am__untar=false
- ;;
- esac
-
- # If the value was cached, stop now. We just wanted to have am__tar
- # and am__untar set.
- test -n "${am_cv_prog_tar_$1}" && break
-
- # tar/untar a dummy directory, and stop if the command works
- rm -rf conftest.dir
- mkdir conftest.dir
- echo GrepMe > conftest.dir/file
- AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar])
- rm -rf conftest.dir
- if test -s conftest.tar; then
- AM_RUN_LOG([$am__untar <conftest.tar])
- grep GrepMe conftest.dir/file >/dev/null 2>&1 && break
- fi
-done
-rm -rf conftest.dir
-
-AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool])
-AC_MSG_RESULT([$am_cv_prog_tar_$1])])
-AC_SUBST([am__tar])
-AC_SUBST([am__untar])
-]) # _AM_PROG_TAR
-
diff --git a/crawl-ref/source/util/pcre/config-cmake.h.in b/crawl-ref/source/util/pcre/config-cmake.h.in
deleted file mode 100644
index 5951af7441..0000000000
--- a/crawl-ref/source/util/pcre/config-cmake.h.in
+++ /dev/null
@@ -1,44 +0,0 @@
-/* config.h for CMake builds */
-
-#cmakedefine HAVE_DIRENT_H 1
-#cmakedefine HAVE_SYS_STAT_H 1
-#cmakedefine HAVE_SYS_TYPES_H 1
-#cmakedefine HAVE_UNISTD_H 1
-#cmakedefine HAVE_WINDOWS_H 1
-
-#cmakedefine HAVE_TYPE_TRAITS_H 1
-#cmakedefine HAVE_BITS_TYPE_TRAITS_H 1
-
-#cmakedefine HAVE_BCOPY 1
-#cmakedefine HAVE_MEMMOVE 1
-#cmakedefine HAVE_STRERROR 1
-#cmakedefine HAVE_STRTOLL 1
-#cmakedefine HAVE_STRTOQ 1
-#cmakedefine HAVE__STRTOI64 1
-
-#cmakedefine PCRE_STATIC 1
-
-#cmakedefine SUPPORT_UTF8 1
-#cmakedefine SUPPORT_UCP 1
-#cmakedefine EBCDIC 1
-#cmakedefine BSR_ANYCRLF 1
-#cmakedefine NO_RECURSE 1
-
-#cmakedefine HAVE_LONG_LONG 1
-#cmakedefine HAVE_UNSIGNED_LONG_LONG 1
-
-#cmakedefine SUPPORT_LIBBZ2 1
-#cmakedefine SUPPORT_LIBZ 1
-#cmakedefine SUPPORT_LIBREADLINE 1
-
-#define NEWLINE @NEWLINE@
-#define POSIX_MALLOC_THRESHOLD @PCRE_POSIX_MALLOC_THRESHOLD@
-#define LINK_SIZE @PCRE_LINK_SIZE@
-#define MATCH_LIMIT @PCRE_MATCH_LIMIT@
-#define MATCH_LIMIT_RECURSION @PCRE_MATCH_LIMIT_RECURSION@
-
-
-#define MAX_NAME_SIZE 32
-#define MAX_NAME_COUNT 10000
-
-/* end config.h for CMake builds */
diff --git a/crawl-ref/source/util/pcre/config.guess b/crawl-ref/source/util/pcre/config.guess
deleted file mode 100644
index 34093cc6bb..0000000000
--- a/crawl-ref/source/util/pcre/config.guess
+++ /dev/null
@@ -1,1535 +0,0 @@
-#! /bin/sh
-# Attempt to guess a canonical system name.
-# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-# 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation,
-# Inc.
-
-timestamp='2007-07-22'
-
-# This file is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
-# 02110-1301, USA.
-#
-# As a special exception to the GNU General Public License, if you
-# distribute this file as part of a program that contains a
-# configuration script generated by Autoconf, you may include it under
-# the same distribution terms that you use for the rest of that program.
-
-
-# Originally written by Per Bothner <per@bothner.com>.
-# Please send patches to <config-patches@gnu.org>. Submit a context
-# diff and a properly formatted ChangeLog entry.
-#
-# This script attempts to guess a canonical system name similar to
-# config.sub. If it succeeds, it prints the system name on stdout, and
-# exits with 0. Otherwise, it exits with 1.
-#
-# The plan is that this can be called by configure scripts if you
-# don't specify an explicit build system type.
-
-me=`echo "$0" | sed -e 's,.*/,,'`
-
-usage="\
-Usage: $0 [OPTION]
-
-Output the configuration name of the system \`$me' is run on.
-
-Operation modes:
- -h, --help print this help, then exit
- -t, --time-stamp print date of last modification, then exit
- -v, --version print version number, then exit
-
-Report bugs and patches to <config-patches@gnu.org>."
-
-version="\
-GNU config.guess ($timestamp)
-
-Originally written by Per Bothner.
-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
-Free Software Foundation, Inc.
-
-This is free software; see the source for copying conditions. There is NO
-warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
-
-help="
-Try \`$me --help' for more information."
-
-# Parse command line
-while test $# -gt 0 ; do
- case $1 in
- --time-stamp | --time* | -t )
- echo "$timestamp" ; exit ;;
- --version | -v )
- echo "$version" ; exit ;;
- --help | --h* | -h )
- echo "$usage"; exit ;;
- -- ) # Stop option processing
- shift; break ;;
- - ) # Use stdin as input.
- break ;;
- -* )
- echo "$me: invalid option $1$help" >&2
- exit 1 ;;
- * )
- break ;;
- esac
-done
-
-if test $# != 0; then
- echo "$me: too many arguments$help" >&2
- exit 1
-fi
-
-trap 'exit 1' 1 2 15
-
-# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
-# compiler to aid in system detection is discouraged as it requires
-# temporary files to be created and, as you can see below, it is a
-# headache to deal with in a portable fashion.
-
-# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
-# use `HOST_CC' if defined, but it is deprecated.
-
-# Portable tmp directory creation inspired by the Autoconf team.
-
-set_cc_for_build='
-trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
-trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
-: ${TMPDIR=/tmp} ;
- { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
- { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
- { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
- { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
-dummy=$tmp/dummy ;
-tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
-case $CC_FOR_BUILD,$HOST_CC,$CC in
- ,,) echo "int x;" > $dummy.c ;
- for c in cc gcc c89 c99 ; do
- if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
- CC_FOR_BUILD="$c"; break ;
- fi ;
- done ;
- if test x"$CC_FOR_BUILD" = x ; then
- CC_FOR_BUILD=no_compiler_found ;
- fi
- ;;
- ,,*) CC_FOR_BUILD=$CC ;;
- ,*,*) CC_FOR_BUILD=$HOST_CC ;;
-esac ; set_cc_for_build= ;'
-
-# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
-# (ghazi@noc.rutgers.edu 1994-08-24)
-if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
- PATH=$PATH:/.attbin ; export PATH
-fi
-
-UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
-UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
-UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
-UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
-
-if [ "${UNAME_SYSTEM}" = "Linux" ] ; then
- eval $set_cc_for_build
- cat << EOF > $dummy.c
- #include <features.h>
- #ifdef __UCLIBC__
- # ifdef __UCLIBC_CONFIG_VERSION__
- LIBC=uclibc __UCLIBC_CONFIG_VERSION__
- # else
- LIBC=uclibc
- # endif
- #else
- LIBC=gnu
- #endif
-EOF
- eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep LIBC= | sed -e 's: ::g'`
-fi
-
-# Note: order is significant - the case branches are not exclusive.
-
-case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
- *:NetBSD:*:*)
- # NetBSD (nbsd) targets should (where applicable) match one or
- # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
- # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
- # switched to ELF, *-*-netbsd* would select the old
- # object file format. This provides both forward
- # compatibility and a consistent mechanism for selecting the
- # object file format.
- #
- # Note: NetBSD doesn't particularly care about the vendor
- # portion of the name. We always set it to "unknown".
- sysctl="sysctl -n hw.machine_arch"
- UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
- /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
- case "${UNAME_MACHINE_ARCH}" in
- armeb) machine=armeb-unknown ;;
- arm*) machine=arm-unknown ;;
- sh3el) machine=shl-unknown ;;
- sh3eb) machine=sh-unknown ;;
- sh5el) machine=sh5le-unknown ;;
- *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
- esac
- # The Operating System including object format, if it has switched
- # to ELF recently, or will in the future.
- case "${UNAME_MACHINE_ARCH}" in
- arm*|i386|m68k|ns32k|sh3*|sparc|vax)
- eval $set_cc_for_build
- if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
- | grep __ELF__ >/dev/null
- then
- # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
- # Return netbsd for either. FIX?
- os=netbsd
- else
- os=netbsdelf
- fi
- ;;
- *)
- os=netbsd
- ;;
- esac
- # The OS release
- # Debian GNU/NetBSD machines have a different userland, and
- # thus, need a distinct triplet. However, they do not need
- # kernel version information, so it can be replaced with a
- # suitable tag, in the style of linux-gnu.
- case "${UNAME_VERSION}" in
- Debian*)
- release='-gnu'
- ;;
- *)
- release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
- ;;
- esac
- # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
- # contains redundant information, the shorter form:
- # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
- echo "${machine}-${os}${release}"
- exit ;;
- *:OpenBSD:*:*)
- UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
- echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
- exit ;;
- *:ekkoBSD:*:*)
- echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
- exit ;;
- *:SolidBSD:*:*)
- echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}
- exit ;;
- macppc:MirBSD:*:*)
- echo powerpc-unknown-mirbsd${UNAME_RELEASE}
- exit ;;
- *:MirBSD:*:*)
- echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
- exit ;;
- alpha:OSF1:*:*)
- case $UNAME_RELEASE in
- *4.0)
- UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
- ;;
- *5.*)
- UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
- ;;
- esac
- # According to Compaq, /usr/sbin/psrinfo has been available on
- # OSF/1 and Tru64 systems produced since 1995. I hope that
- # covers most systems running today. This code pipes the CPU
- # types through head -n 1, so we only detect the type of CPU 0.
- ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1`
- case "$ALPHA_CPU_TYPE" in
- "EV4 (21064)")
- UNAME_MACHINE="alpha" ;;
- "EV4.5 (21064)")
- UNAME_MACHINE="alpha" ;;
- "LCA4 (21066/21068)")
- UNAME_MACHINE="alpha" ;;
- "EV5 (21164)")
- UNAME_MACHINE="alphaev5" ;;
- "EV5.6 (21164A)")
- UNAME_MACHINE="alphaev56" ;;
- "EV5.6 (21164PC)")
- UNAME_MACHINE="alphapca56" ;;
- "EV5.7 (21164PC)")
- UNAME_MACHINE="alphapca57" ;;
- "EV6 (21264)")
- UNAME_MACHINE="alphaev6" ;;
- "EV6.7 (21264A)")
- UNAME_MACHINE="alphaev67" ;;
- "EV6.8CB (21264C)")
- UNAME_MACHINE="alphaev68" ;;
- "EV6.8AL (21264B)")
- UNAME_MACHINE="alphaev68" ;;
- "EV6.8CX (21264D)")
- UNAME_MACHINE="alphaev68" ;;
- "EV6.9A (21264/EV69A)")
- UNAME_MACHINE="alphaev69" ;;
- "EV7 (21364)")
- UNAME_MACHINE="alphaev7" ;;
- "EV7.9 (21364A)")
- UNAME_MACHINE="alphaev79" ;;
- esac
- # A Pn.n version is a patched version.
- # A Vn.n version is a released version.
- # A Tn.n version is a released field test version.
- # A Xn.n version is an unreleased experimental baselevel.
- # 1.2 uses "1.2" for uname -r.
- echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
- exit ;;
- Alpha\ *:Windows_NT*:*)
- # How do we know it's Interix rather than the generic POSIX subsystem?
- # Should we change UNAME_MACHINE based on the output of uname instead
- # of the specific Alpha model?
- echo alpha-pc-interix
- exit ;;
- 21064:Windows_NT:50:3)
- echo alpha-dec-winnt3.5
- exit ;;
- Amiga*:UNIX_System_V:4.0:*)
- echo m68k-unknown-sysv4
- exit ;;
- *:[Aa]miga[Oo][Ss]:*:*)
- echo ${UNAME_MACHINE}-unknown-amigaos
- exit ;;
- *:[Mm]orph[Oo][Ss]:*:*)
- echo ${UNAME_MACHINE}-unknown-morphos
- exit ;;
- *:OS/390:*:*)
- echo i370-ibm-openedition
- exit ;;
- *:z/VM:*:*)
- echo s390-ibm-zvmoe
- exit ;;
- *:OS400:*:*)
- echo powerpc-ibm-os400
- exit ;;
- arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
- echo arm-acorn-riscix${UNAME_RELEASE}
- exit ;;
- arm:riscos:*:*|arm:RISCOS:*:*)
- echo arm-unknown-riscos
- exit ;;
- SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
- echo hppa1.1-hitachi-hiuxmpp
- exit ;;
- Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
- # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
- if test "`(/bin/universe) 2>/dev/null`" = att ; then
- echo pyramid-pyramid-sysv3
- else
- echo pyramid-pyramid-bsd
- fi
- exit ;;
- NILE*:*:*:dcosx)
- echo pyramid-pyramid-svr4
- exit ;;
- DRS?6000:unix:4.0:6*)
- echo sparc-icl-nx6
- exit ;;
- DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
- case `/usr/bin/uname -p` in
- sparc) echo sparc-icl-nx7; exit ;;
- esac ;;
- sun4H:SunOS:5.*:*)
- echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit ;;
- sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
- echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit ;;
- i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
- echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit ;;
- sun4*:SunOS:6*:*)
- # According to config.sub, this is the proper way to canonicalize
- # SunOS6. Hard to guess exactly what SunOS6 will be like, but
- # it's likely to be more like Solaris than SunOS4.
- echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit ;;
- sun4*:SunOS:*:*)
- case "`/usr/bin/arch -k`" in
- Series*|S4*)
- UNAME_RELEASE=`uname -v`
- ;;
- esac
- # Japanese Language versions have a version number like `4.1.3-JL'.
- echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
- exit ;;
- sun3*:SunOS:*:*)
- echo m68k-sun-sunos${UNAME_RELEASE}
- exit ;;
- sun*:*:4.2BSD:*)
- UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
- test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
- case "`/bin/arch`" in
- sun3)
- echo m68k-sun-sunos${UNAME_RELEASE}
- ;;
- sun4)
- echo sparc-sun-sunos${UNAME_RELEASE}
- ;;
- esac
- exit ;;
- aushp:SunOS:*:*)
- echo sparc-auspex-sunos${UNAME_RELEASE}
- exit ;;
- # The situation for MiNT is a little confusing. The machine name
- # can be virtually everything (everything which is not
- # "atarist" or "atariste" at least should have a processor
- # > m68000). The system name ranges from "MiNT" over "FreeMiNT"
- # to the lowercase version "mint" (or "freemint"). Finally
- # the system name "TOS" denotes a system which is actually not
- # MiNT. But MiNT is downward compatible to TOS, so this should
- # be no problem.
- atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
- echo m68k-atari-mint${UNAME_RELEASE}
- exit ;;
- atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
- echo m68k-atari-mint${UNAME_RELEASE}
- exit ;;
- *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
- echo m68k-atari-mint${UNAME_RELEASE}
- exit ;;
- milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
- echo m68k-milan-mint${UNAME_RELEASE}
- exit ;;
- hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
- echo m68k-hades-mint${UNAME_RELEASE}
- exit ;;
- *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
- echo m68k-unknown-mint${UNAME_RELEASE}
- exit ;;
- m68k:machten:*:*)
- echo m68k-apple-machten${UNAME_RELEASE}
- exit ;;
- powerpc:machten:*:*)
- echo powerpc-apple-machten${UNAME_RELEASE}
- exit ;;
- RISC*:Mach:*:*)
- echo mips-dec-mach_bsd4.3
- exit ;;
- RISC*:ULTRIX:*:*)
- echo mips-dec-ultrix${UNAME_RELEASE}
- exit ;;
- VAX*:ULTRIX*:*:*)
- echo vax-dec-ultrix${UNAME_RELEASE}
- exit ;;
- 2020:CLIX:*:* | 2430:CLIX:*:*)
- echo clipper-intergraph-clix${UNAME_RELEASE}
- exit ;;
- mips:*:*:UMIPS | mips:*:*:RISCos)
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
-#ifdef __cplusplus
-#include <stdio.h> /* for printf() prototype */
- int main (int argc, char *argv[]) {
-#else
- int main (argc, argv) int argc; char *argv[]; {
-#endif
- #if defined (host_mips) && defined (MIPSEB)
- #if defined (SYSTYPE_SYSV)
- printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
- #endif
- #if defined (SYSTYPE_SVR4)
- printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
- #endif
- #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
- printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
- #endif
- #endif
- exit (-1);
- }
-EOF
- $CC_FOR_BUILD -o $dummy $dummy.c &&
- dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` &&
- SYSTEM_NAME=`$dummy $dummyarg` &&
- { echo "$SYSTEM_NAME"; exit; }
- echo mips-mips-riscos${UNAME_RELEASE}
- exit ;;
- Motorola:PowerMAX_OS:*:*)
- echo powerpc-motorola-powermax
- exit ;;
- Motorola:*:4.3:PL8-*)
- echo powerpc-harris-powermax
- exit ;;
- Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
- echo powerpc-harris-powermax
- exit ;;
- Night_Hawk:Power_UNIX:*:*)
- echo powerpc-harris-powerunix
- exit ;;
- m88k:CX/UX:7*:*)
- echo m88k-harris-cxux7
- exit ;;
- m88k:*:4*:R4*)
- echo m88k-motorola-sysv4
- exit ;;
- m88k:*:3*:R3*)
- echo m88k-motorola-sysv3
- exit ;;
- AViiON:dgux:*:*)
- # DG/UX returns AViiON for all architectures
- UNAME_PROCESSOR=`/usr/bin/uname -p`
- if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
- then
- if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
- [ ${TARGET_BINARY_INTERFACE}x = x ]
- then
- echo m88k-dg-dgux${UNAME_RELEASE}
- else
- echo m88k-dg-dguxbcs${UNAME_RELEASE}
- fi
- else
- echo i586-dg-dgux${UNAME_RELEASE}
- fi
- exit ;;
- M88*:DolphinOS:*:*) # DolphinOS (SVR3)
- echo m88k-dolphin-sysv3
- exit ;;
- M88*:*:R3*:*)
- # Delta 88k system running SVR3
- echo m88k-motorola-sysv3
- exit ;;
- XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
- echo m88k-tektronix-sysv3
- exit ;;
- Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
- echo m68k-tektronix-bsd
- exit ;;
- *:IRIX*:*:*)
- echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
- exit ;;
- ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
- echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id
- exit ;; # Note that: echo "'`uname -s`'" gives 'AIX '
- i*86:AIX:*:*)
- echo i386-ibm-aix
- exit ;;
- ia64:AIX:*:*)
- if [ -x /usr/bin/oslevel ] ; then
- IBM_REV=`/usr/bin/oslevel`
- else
- IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
- fi
- echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
- exit ;;
- *:AIX:2:3)
- if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
- #include <sys/systemcfg.h>
-
- main()
- {
- if (!__power_pc())
- exit(1);
- puts("powerpc-ibm-aix3.2.5");
- exit(0);
- }
-EOF
- if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy`
- then
- echo "$SYSTEM_NAME"
- else
- echo rs6000-ibm-aix3.2.5
- fi
- elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
- echo rs6000-ibm-aix3.2.4
- else
- echo rs6000-ibm-aix3.2
- fi
- exit ;;
- *:AIX:*:[45])
- IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
- if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
- IBM_ARCH=rs6000
- else
- IBM_ARCH=powerpc
- fi
- if [ -x /usr/bin/oslevel ] ; then
- IBM_REV=`/usr/bin/oslevel`
- else
- IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
- fi
- echo ${IBM_ARCH}-ibm-aix${IBM_REV}
- exit ;;
- *:AIX:*:*)
- echo rs6000-ibm-aix
- exit ;;
- ibmrt:4.4BSD:*|romp-ibm:BSD:*)
- echo romp-ibm-bsd4.4
- exit ;;
- ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and
- echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to
- exit ;; # report: romp-ibm BSD 4.3
- *:BOSX:*:*)
- echo rs6000-bull-bosx
- exit ;;
- DPX/2?00:B.O.S.:*:*)
- echo m68k-bull-sysv3
- exit ;;
- 9000/[34]??:4.3bsd:1.*:*)
- echo m68k-hp-bsd
- exit ;;
- hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
- echo m68k-hp-bsd4.4
- exit ;;
- 9000/[34678]??:HP-UX:*:*)
- HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
- case "${UNAME_MACHINE}" in
- 9000/31? ) HP_ARCH=m68000 ;;
- 9000/[34]?? ) HP_ARCH=m68k ;;
- 9000/[678][0-9][0-9])
- if [ -x /usr/bin/getconf ]; then
- sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
- sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
- case "${sc_cpu_version}" in
- 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
- 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
- 532) # CPU_PA_RISC2_0
- case "${sc_kernel_bits}" in
- 32) HP_ARCH="hppa2.0n" ;;
- 64) HP_ARCH="hppa2.0w" ;;
- '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20
- esac ;;
- esac
- fi
- if [ "${HP_ARCH}" = "" ]; then
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
-
- #define _HPUX_SOURCE
- #include <stdlib.h>
- #include <unistd.h>
-
- int main ()
- {
- #if defined(_SC_KERNEL_BITS)
- long bits = sysconf(_SC_KERNEL_BITS);
- #endif
- long cpu = sysconf (_SC_CPU_VERSION);
-
- switch (cpu)
- {
- case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
- case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
- case CPU_PA_RISC2_0:
- #if defined(_SC_KERNEL_BITS)
- switch (bits)
- {
- case 64: puts ("hppa2.0w"); break;
- case 32: puts ("hppa2.0n"); break;
- default: puts ("hppa2.0"); break;
- } break;
- #else /* !defined(_SC_KERNEL_BITS) */
- puts ("hppa2.0"); break;
- #endif
- default: puts ("hppa1.0"); break;
- }
- exit (0);
- }
-EOF
- (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
- test -z "$HP_ARCH" && HP_ARCH=hppa
- fi ;;
- esac
- if [ ${HP_ARCH} = "hppa2.0w" ]
- then
- eval $set_cc_for_build
-
- # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
- # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler
- # generating 64-bit code. GNU and HP use different nomenclature:
- #
- # $ CC_FOR_BUILD=cc ./config.guess
- # => hppa2.0w-hp-hpux11.23
- # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
- # => hppa64-hp-hpux11.23
-
- if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
- grep __LP64__ >/dev/null
- then
- HP_ARCH="hppa2.0w"
- else
- HP_ARCH="hppa64"
- fi
- fi
- echo ${HP_ARCH}-hp-hpux${HPUX_REV}
- exit ;;
- ia64:HP-UX:*:*)
- HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
- echo ia64-hp-hpux${HPUX_REV}
- exit ;;
- 3050*:HI-UX:*:*)
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
- #include <unistd.h>
- int
- main ()
- {
- long cpu = sysconf (_SC_CPU_VERSION);
- /* The order matters, because CPU_IS_HP_MC68K erroneously returns
- true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct
- results, however. */
- if (CPU_IS_PA_RISC (cpu))
- {
- switch (cpu)
- {
- case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
- case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
- case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
- default: puts ("hppa-hitachi-hiuxwe2"); break;
- }
- }
- else if (CPU_IS_HP_MC68K (cpu))
- puts ("m68k-hitachi-hiuxwe2");
- else puts ("unknown-hitachi-hiuxwe2");
- exit (0);
- }
-EOF
- $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` &&
- { echo "$SYSTEM_NAME"; exit; }
- echo unknown-hitachi-hiuxwe2
- exit ;;
- 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
- echo hppa1.1-hp-bsd
- exit ;;
- 9000/8??:4.3bsd:*:*)
- echo hppa1.0-hp-bsd
- exit ;;
- *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
- echo hppa1.0-hp-mpeix
- exit ;;
- hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
- echo hppa1.1-hp-osf
- exit ;;
- hp8??:OSF1:*:*)
- echo hppa1.0-hp-osf
- exit ;;
- i*86:OSF1:*:*)
- if [ -x /usr/sbin/sysversion ] ; then
- echo ${UNAME_MACHINE}-unknown-osf1mk
- else
- echo ${UNAME_MACHINE}-unknown-osf1
- fi
- exit ;;
- parisc*:Lites*:*:*)
- echo hppa1.1-hp-lites
- exit ;;
- C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
- echo c1-convex-bsd
- exit ;;
- C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
- if getsysinfo -f scalar_acc
- then echo c32-convex-bsd
- else echo c2-convex-bsd
- fi
- exit ;;
- C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
- echo c34-convex-bsd
- exit ;;
- C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
- echo c38-convex-bsd
- exit ;;
- C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
- echo c4-convex-bsd
- exit ;;
- CRAY*Y-MP:*:*:*)
- echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
- exit ;;
- CRAY*[A-Z]90:*:*:*)
- echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
- | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
- -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
- -e 's/\.[^.]*$/.X/'
- exit ;;
- CRAY*TS:*:*:*)
- echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
- exit ;;
- CRAY*T3E:*:*:*)
- echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
- exit ;;
- CRAY*SV1:*:*:*)
- echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
- exit ;;
- *:UNICOS/mp:*:*)
- echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
- exit ;;
- F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
- FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
- FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
- FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
- echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
- exit ;;
- 5000:UNIX_System_V:4.*:*)
- FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
- FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
- echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
- exit ;;
- i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
- echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
- exit ;;
- sparc*:BSD/OS:*:*)
- echo sparc-unknown-bsdi${UNAME_RELEASE}
- exit ;;
- *:BSD/OS:*:*)
- echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
- exit ;;
- *:FreeBSD:*:*)
- case ${UNAME_MACHINE} in
- pc98)
- echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
- amd64)
- echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
- *)
- echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
- esac
- exit ;;
- i*:CYGWIN*:*)
- echo ${UNAME_MACHINE}-pc-cygwin
- exit ;;
- *:MINGW*:*)
- echo ${UNAME_MACHINE}-pc-mingw32
- exit ;;
- i*:windows32*:*)
- # uname -m includes "-pc" on this system.
- echo ${UNAME_MACHINE}-mingw32
- exit ;;
- i*:PW*:*)
- echo ${UNAME_MACHINE}-pc-pw32
- exit ;;
- *:Interix*:[3456]*)
- case ${UNAME_MACHINE} in
- x86)
- echo i586-pc-interix${UNAME_RELEASE}
- exit ;;
- EM64T | authenticamd)
- echo x86_64-unknown-interix${UNAME_RELEASE}
- exit ;;
- esac ;;
- [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
- echo i${UNAME_MACHINE}-pc-mks
- exit ;;
- i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
- # How do we know it's Interix rather than the generic POSIX subsystem?
- # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
- # UNAME_MACHINE based on the output of uname instead of i386?
- echo i586-pc-interix
- exit ;;
- i*:UWIN*:*)
- echo ${UNAME_MACHINE}-pc-uwin
- exit ;;
- amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
- echo x86_64-unknown-cygwin
- exit ;;
- p*:CYGWIN*:*)
- echo powerpcle-unknown-cygwin
- exit ;;
- prep*:SunOS:5.*:*)
- echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit ;;
- *:GNU:*:*)
- # the GNU system
- echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
- exit ;;
- *:GNU/*:*:*)
- # other systems with GNU libc and userland
- echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
- exit ;;
- i*86:Minix:*:*)
- echo ${UNAME_MACHINE}-pc-minix
- exit ;;
- arm*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
- exit ;;
- avr32*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
- exit ;;
- cris:Linux:*:*)
- echo cris-axis-linux-${LIBC}
- exit ;;
- crisv32:Linux:*:*)
- echo crisv32-axis-linux-${LIBC}
- exit ;;
- frv:Linux:*:*)
- echo frv-unknown-linux-${LIBC}
- exit ;;
- ia64:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
- exit ;;
- m32r*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
- exit ;;
- m68*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
- exit ;;
- mips:Linux:*:*)
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
- #undef CPU
- #undef mips
- #undef mipsel
- #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
- CPU=mipsel
- #else
- #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
- CPU=mips
- #else
- CPU=
- #endif
- #endif
-EOF
- eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
- /^CPU/{
- s: ::g
- p
- }'`"
- test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; }
- ;;
- mips64:Linux:*:*)
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
- #undef CPU
- #undef mips64
- #undef mips64el
- #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
- CPU=mips64el
- #else
- #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
- CPU=mips64
- #else
- CPU=
- #endif
- #endif
-EOF
- eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
- /^CPU/{
- s: ::g
- p
- }'`"
- test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; }
- ;;
- or32:Linux:*:*)
- echo or32-unknown-linux-${LIBC}
- exit ;;
- ppc:Linux:*:*)
- echo powerpc-unknown-linux-${LIBC}
- exit ;;
- ppc64:Linux:*:*)
- echo powerpc64-unknown-linux-${LIBC}
- exit ;;
- alpha:Linux:*:*)
- case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
- EV5) UNAME_MACHINE=alphaev5 ;;
- EV56) UNAME_MACHINE=alphaev56 ;;
- PCA56) UNAME_MACHINE=alphapca56 ;;
- PCA57) UNAME_MACHINE=alphapca56 ;;
- EV6) UNAME_MACHINE=alphaev6 ;;
- EV67) UNAME_MACHINE=alphaev67 ;;
- EV68*) UNAME_MACHINE=alphaev68 ;;
- esac
- objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
- if test "$?" = 0 ; then LIBC="gnulibc1" ; fi
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
- exit ;;
- parisc:Linux:*:* | hppa:Linux:*:*)
- # Look for CPU level
- case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
- PA7*) echo hppa1.1-unknown-linux-${LIBC} ;;
- PA8*) echo hppa2.0-unknown-linux-${LIBC} ;;
- *) echo hppa-unknown-linux-${LIBC} ;;
- esac
- exit ;;
- parisc64:Linux:*:* | hppa64:Linux:*:*)
- echo hppa64-unknown-linux-${LIBC}
- exit ;;
- s390:Linux:*:* | s390x:Linux:*:*)
- echo ${UNAME_MACHINE}-ibm-linux
- exit ;;
- sh64*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
- exit ;;
- sh*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
- exit ;;
- sparc:Linux:*:* | sparc64:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
- exit ;;
- vax:Linux:*:*)
- echo ${UNAME_MACHINE}-dec-linux-${LIBC}
- exit ;;
- x86_64:Linux:*:*)
- echo x86_64-unknown-linux-${LIBC}
- exit ;;
- xtensa:Linux:*:*)
- echo xtensa-unknown-linux-${LIBC}
- exit ;;
- i*86:Linux:*:*)
- # The BFD linker knows what the default object file format is, so
- # first see if it will tell us. cd to the root directory to prevent
- # problems with other programs or directories called `ld' in the path.
- # Set LC_ALL=C to ensure ld outputs messages in English.
- ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \
- | sed -ne '/supported targets:/!d
- s/[ ][ ]*/ /g
- s/.*supported targets: *//
- s/ .*//
- p'`
- case "$ld_supported_targets" in
- elf32-i386)
- TENTATIVE="${UNAME_MACHINE}-pc-linux-${LIBC}"
- ;;
- a.out-i386-linux)
- echo "${UNAME_MACHINE}-pc-linux-${LIBC}aout"
- exit ;;
- coff-i386)
- echo "${UNAME_MACHINE}-pc-linux-${LIBC}coff"
- exit ;;
- "")
- # Either a pre-BFD a.out linker (linux-gnuoldld) or
- # one that does not give us useful --help.
- echo "${UNAME_MACHINE}-pc-linux-${LIBC}oldld"
- exit ;;
- esac
- # This should get integrated into the C code below, but now we hack
- if [ "$LIBC" != "gnu" ] ; then echo "$TENTATIVE" && exit 0 ; fi
- # Determine whether the default compiler is a.out or elf
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
- #include <features.h>
- #ifdef __ELF__
- # ifdef __GLIBC__
- # if __GLIBC__ >= 2
- LIBC=gnu
- # else
- LIBC=gnulibc1
- # endif
- # else
- LIBC=gnulibc1
- # endif
- #else
- #if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC)
- LIBC=gnu
- #else
- LIBC=gnuaout
- #endif
- #endif
- #ifdef __dietlibc__
- LIBC=dietlibc
- #endif
-EOF
- eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
- /^LIBC/{
- s: ::g
- p
- }'`"
- test x"${LIBC}" != x && {
- echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
- exit
- }
- test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; }
- ;;
- i*86:DYNIX/ptx:4*:*)
- # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
- # earlier versions are messed up and put the nodename in both
- # sysname and nodename.
- echo i386-sequent-sysv4
- exit ;;
- i*86:UNIX_SV:4.2MP:2.*)
- # Unixware is an offshoot of SVR4, but it has its own version
- # number series starting with 2...
- # I am not positive that other SVR4 systems won't match this,
- # I just have to hope. -- rms.
- # Use sysv4.2uw... so that sysv4* matches it.
- echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
- exit ;;
- i*86:OS/2:*:*)
- # If we were able to find `uname', then EMX Unix compatibility
- # is probably installed.
- echo ${UNAME_MACHINE}-pc-os2-emx
- exit ;;
- i*86:XTS-300:*:STOP)
- echo ${UNAME_MACHINE}-unknown-stop
- exit ;;
- i*86:atheos:*:*)
- echo ${UNAME_MACHINE}-unknown-atheos
- exit ;;
- i*86:syllable:*:*)
- echo ${UNAME_MACHINE}-pc-syllable
- exit ;;
- i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
- echo i386-unknown-lynxos${UNAME_RELEASE}
- exit ;;
- i*86:*DOS:*:*)
- echo ${UNAME_MACHINE}-pc-msdosdjgpp
- exit ;;
- i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
- UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
- if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
- echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
- else
- echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
- fi
- exit ;;
- i*86:*:5:[678]*)
- # UnixWare 7.x, OpenUNIX and OpenServer 6.
- case `/bin/uname -X | grep "^Machine"` in
- *486*) UNAME_MACHINE=i486 ;;
- *Pentium) UNAME_MACHINE=i586 ;;
- *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
- esac
- echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
- exit ;;
- i*86:*:3.2:*)
- if test -f /usr/options/cb.name; then
- UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
- echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
- elif /bin/uname -X 2>/dev/null >/dev/null ; then
- UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
- (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
- (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
- && UNAME_MACHINE=i586
- (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
- && UNAME_MACHINE=i686
- (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
- && UNAME_MACHINE=i686
- echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
- else
- echo ${UNAME_MACHINE}-pc-sysv32
- fi
- exit ;;
- pc:*:*:*)
- # Left here for compatibility:
- # uname -m prints for DJGPP always 'pc', but it prints nothing about
- # the processor, so we play safe by assuming i386.
- echo i386-pc-msdosdjgpp
- exit ;;
- Intel:Mach:3*:*)
- echo i386-pc-mach3
- exit ;;
- paragon:*:*:*)
- echo i860-intel-osf1
- exit ;;
- i860:*:4.*:*) # i860-SVR4
- if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
- echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
- else # Add other i860-SVR4 vendors below as they are discovered.
- echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4
- fi
- exit ;;
- mini*:CTIX:SYS*5:*)
- # "miniframe"
- echo m68010-convergent-sysv
- exit ;;
- mc68k:UNIX:SYSTEM5:3.51m)
- echo m68k-convergent-sysv
- exit ;;
- M680?0:D-NIX:5.3:*)
- echo m68k-diab-dnix
- exit ;;
- M68*:*:R3V[5678]*:*)
- test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;
- 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
- OS_REL=''
- test -r /etc/.relid \
- && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
- /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
- && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
- /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
- && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
- 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
- /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
- && { echo i486-ncr-sysv4; exit; } ;;
- m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
- echo m68k-unknown-lynxos${UNAME_RELEASE}
- exit ;;
- mc68030:UNIX_System_V:4.*:*)
- echo m68k-atari-sysv4
- exit ;;
- TSUNAMI:LynxOS:2.*:*)
- echo sparc-unknown-lynxos${UNAME_RELEASE}
- exit ;;
- rs6000:LynxOS:2.*:*)
- echo rs6000-unknown-lynxos${UNAME_RELEASE}
- exit ;;
- PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
- echo powerpc-unknown-lynxos${UNAME_RELEASE}
- exit ;;
- SM[BE]S:UNIX_SV:*:*)
- echo mips-dde-sysv${UNAME_RELEASE}
- exit ;;
- RM*:ReliantUNIX-*:*:*)
- echo mips-sni-sysv4
- exit ;;
- RM*:SINIX-*:*:*)
- echo mips-sni-sysv4
- exit ;;
- *:SINIX-*:*:*)
- if uname -p 2>/dev/null >/dev/null ; then
- UNAME_MACHINE=`(uname -p) 2>/dev/null`
- echo ${UNAME_MACHINE}-sni-sysv4
- else
- echo ns32k-sni-sysv
- fi
- exit ;;
- PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
- # says <Richard.M.Bartel@ccMail.Census.GOV>
- echo i586-unisys-sysv4
- exit ;;
- *:UNIX_System_V:4*:FTX*)
- # From Gerald Hewes <hewes@openmarket.com>.
- # How about differentiating between stratus architectures? -djm
- echo hppa1.1-stratus-sysv4
- exit ;;
- *:*:*:FTX*)
- # From seanf@swdc.stratus.com.
- echo i860-stratus-sysv4
- exit ;;
- i*86:VOS:*:*)
- # From Paul.Green@stratus.com.
- echo ${UNAME_MACHINE}-stratus-vos
- exit ;;
- *:VOS:*:*)
- # From Paul.Green@stratus.com.
- echo hppa1.1-stratus-vos
- exit ;;
- mc68*:A/UX:*:*)
- echo m68k-apple-aux${UNAME_RELEASE}
- exit ;;
- news*:NEWS-OS:6*:*)
- echo mips-sony-newsos6
- exit ;;
- R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
- if [ -d /usr/nec ]; then
- echo mips-nec-sysv${UNAME_RELEASE}
- else
- echo mips-unknown-sysv${UNAME_RELEASE}
- fi
- exit ;;
- BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
- echo powerpc-be-beos
- exit ;;
- BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only.
- echo powerpc-apple-beos
- exit ;;
- BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
- echo i586-pc-beos
- exit ;;
- SX-4:SUPER-UX:*:*)
- echo sx4-nec-superux${UNAME_RELEASE}
- exit ;;
- SX-5:SUPER-UX:*:*)
- echo sx5-nec-superux${UNAME_RELEASE}
- exit ;;
- SX-6:SUPER-UX:*:*)
- echo sx6-nec-superux${UNAME_RELEASE}
- exit ;;
- SX-7:SUPER-UX:*:*)
- echo sx7-nec-superux${UNAME_RELEASE}
- exit ;;
- SX-8:SUPER-UX:*:*)
- echo sx8-nec-superux${UNAME_RELEASE}
- exit ;;
- SX-8R:SUPER-UX:*:*)
- echo sx8r-nec-superux${UNAME_RELEASE}
- exit ;;
- Power*:Rhapsody:*:*)
- echo powerpc-apple-rhapsody${UNAME_RELEASE}
- exit ;;
- *:Rhapsody:*:*)
- echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
- exit ;;
- *:Darwin:*:*)
- UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
- case $UNAME_PROCESSOR in
- unknown) UNAME_PROCESSOR=powerpc ;;
- esac
- echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
- exit ;;
- *:procnto*:*:* | *:QNX:[0123456789]*:*)
- UNAME_PROCESSOR=`uname -p`
- if test "$UNAME_PROCESSOR" = "x86"; then
- UNAME_PROCESSOR=i386
- UNAME_MACHINE=pc
- fi
- echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
- exit ;;
- *:QNX:*:4*)
- echo i386-pc-qnx
- exit ;;
- NSE-?:NONSTOP_KERNEL:*:*)
- echo nse-tandem-nsk${UNAME_RELEASE}
- exit ;;
- NSR-?:NONSTOP_KERNEL:*:*)
- echo nsr-tandem-nsk${UNAME_RELEASE}
- exit ;;
- *:NonStop-UX:*:*)
- echo mips-compaq-nonstopux
- exit ;;
- BS2000:POSIX*:*:*)
- echo bs2000-siemens-sysv
- exit ;;
- DS/*:UNIX_System_V:*:*)
- echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
- exit ;;
- *:Plan9:*:*)
- # "uname -m" is not consistent, so use $cputype instead. 386
- # is converted to i386 for consistency with other x86
- # operating systems.
- if test "$cputype" = "386"; then
- UNAME_MACHINE=i386
- else
- UNAME_MACHINE="$cputype"
- fi
- echo ${UNAME_MACHINE}-unknown-plan9
- exit ;;
- *:TOPS-10:*:*)
- echo pdp10-unknown-tops10
- exit ;;
- *:TENEX:*:*)
- echo pdp10-unknown-tenex
- exit ;;
- KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
- echo pdp10-dec-tops20
- exit ;;
- XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
- echo pdp10-xkl-tops20
- exit ;;
- *:TOPS-20:*:*)
- echo pdp10-unknown-tops20
- exit ;;
- *:ITS:*:*)
- echo pdp10-unknown-its
- exit ;;
- SEI:*:*:SEIUX)
- echo mips-sei-seiux${UNAME_RELEASE}
- exit ;;
- *:DragonFly:*:*)
- echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
- exit ;;
- *:*VMS:*:*)
- UNAME_MACHINE=`(uname -p) 2>/dev/null`
- case "${UNAME_MACHINE}" in
- A*) echo alpha-dec-vms ; exit ;;
- I*) echo ia64-dec-vms ; exit ;;
- V*) echo vax-dec-vms ; exit ;;
- esac ;;
- *:XENIX:*:SysV)
- echo i386-pc-xenix
- exit ;;
- i*86:skyos:*:*)
- echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'
- exit ;;
- i*86:rdos:*:*)
- echo ${UNAME_MACHINE}-pc-rdos
- exit ;;
-esac
-
-#echo '(No uname command or uname output not recognized.)' 1>&2
-#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
-
-eval $set_cc_for_build
-cat >$dummy.c <<EOF
-#ifdef _SEQUENT_
-# include <sys/types.h>
-# include <sys/utsname.h>
-#endif
-main ()
-{
-#if defined (sony)
-#if defined (MIPSEB)
- /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed,
- I don't know.... */
- printf ("mips-sony-bsd\n"); exit (0);
-#else
-#include <sys/param.h>
- printf ("m68k-sony-newsos%s\n",
-#ifdef NEWSOS4
- "4"
-#else
- ""
-#endif
- ); exit (0);
-#endif
-#endif
-
-#if defined (__arm) && defined (__acorn) && defined (__unix)
- printf ("arm-acorn-riscix\n"); exit (0);
-#endif
-
-#if defined (hp300) && !defined (hpux)
- printf ("m68k-hp-bsd\n"); exit (0);
-#endif
-
-#if defined (NeXT)
-#if !defined (__ARCHITECTURE__)
-#define __ARCHITECTURE__ "m68k"
-#endif
- int version;
- version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
- if (version < 4)
- printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
- else
- printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
- exit (0);
-#endif
-
-#if defined (MULTIMAX) || defined (n16)
-#if defined (UMAXV)
- printf ("ns32k-encore-sysv\n"); exit (0);
-#else
-#if defined (CMU)
- printf ("ns32k-encore-mach\n"); exit (0);
-#else
- printf ("ns32k-encore-bsd\n"); exit (0);
-#endif
-#endif
-#endif
-
-#if defined (__386BSD__)
- printf ("i386-pc-bsd\n"); exit (0);
-#endif
-
-#if defined (sequent)
-#if defined (i386)
- printf ("i386-sequent-dynix\n"); exit (0);
-#endif
-#if defined (ns32000)
- printf ("ns32k-sequent-dynix\n"); exit (0);
-#endif
-#endif
-
-#if defined (_SEQUENT_)
- struct utsname un;
-
- uname(&un);
-
- if (strncmp(un.version, "V2", 2) == 0) {
- printf ("i386-sequent-ptx2\n"); exit (0);
- }
- if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
- printf ("i386-sequent-ptx1\n"); exit (0);
- }
- printf ("i386-sequent-ptx\n"); exit (0);
-
-#endif
-
-#if defined (vax)
-# if !defined (ultrix)
-# include <sys/param.h>
-# if defined (BSD)
-# if BSD == 43
- printf ("vax-dec-bsd4.3\n"); exit (0);
-# else
-# if BSD == 199006
- printf ("vax-dec-bsd4.3reno\n"); exit (0);
-# else
- printf ("vax-dec-bsd\n"); exit (0);
-# endif
-# endif
-# else
- printf ("vax-dec-bsd\n"); exit (0);
-# endif
-# else
- printf ("vax-dec-ultrix\n"); exit (0);
-# endif
-#endif
-
-#if defined (alliant) && defined (i860)
- printf ("i860-alliant-bsd\n"); exit (0);
-#endif
-
- exit (1);
-}
-EOF
-
-$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` &&
- { echo "$SYSTEM_NAME"; exit; }
-
-# Apollos put the system type in the environment.
-
-test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; }
-
-# Convex versions that predate uname can use getsysinfo(1)
-
-if [ -x /usr/convex/getsysinfo ]
-then
- case `getsysinfo -f cpu_type` in
- c1*)
- echo c1-convex-bsd
- exit ;;
- c2*)
- if getsysinfo -f scalar_acc
- then echo c32-convex-bsd
- else echo c2-convex-bsd
- fi
- exit ;;
- c34*)
- echo c34-convex-bsd
- exit ;;
- c38*)
- echo c38-convex-bsd
- exit ;;
- c4*)
- echo c4-convex-bsd
- exit ;;
- esac
-fi
-
-cat >&2 <<EOF
-$0: unable to guess system type
-
-This script, last modified $timestamp, has failed to recognize
-the operating system you are using. It is advised that you
-download the most up to date version of the config scripts from
-
- http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.guess
-and
- http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.sub
-
-If the version you run ($0) is already up to date, please
-send the following data and any information you think might be
-pertinent to <config-patches@gnu.org> in order to provide the needed
-information to handle your system.
-
-config.guess timestamp = $timestamp
-
-uname -m = `(uname -m) 2>/dev/null || echo unknown`
-uname -r = `(uname -r) 2>/dev/null || echo unknown`
-uname -s = `(uname -s) 2>/dev/null || echo unknown`
-uname -v = `(uname -v) 2>/dev/null || echo unknown`
-
-/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
-/bin/uname -X = `(/bin/uname -X) 2>/dev/null`
-
-hostinfo = `(hostinfo) 2>/dev/null`
-/bin/universe = `(/bin/universe) 2>/dev/null`
-/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null`
-/bin/arch = `(/bin/arch) 2>/dev/null`
-/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null`
-/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
-
-UNAME_MACHINE = ${UNAME_MACHINE}
-UNAME_RELEASE = ${UNAME_RELEASE}
-UNAME_SYSTEM = ${UNAME_SYSTEM}
-UNAME_VERSION = ${UNAME_VERSION}
-EOF
-
-exit 1
-
-# Local variables:
-# eval: (add-hook 'write-file-hooks 'time-stamp)
-# time-stamp-start: "timestamp='"
-# time-stamp-format: "%:y-%02m-%02d"
-# time-stamp-end: "'"
-# End:
diff --git a/crawl-ref/source/util/pcre/config.h b/crawl-ref/source/util/pcre/config.h
deleted file mode 100644
index f66f4dd1a9..0000000000
--- a/crawl-ref/source/util/pcre/config.h
+++ /dev/null
@@ -1,307 +0,0 @@
-/* config.h. Generated from config.h.in by configure. */
-/* config.h.in. Generated from configure.ac by autoheader. */
-
-
-/* On Unix-like systems config.h.in is converted by "configure" into config.h.
-Some other environments also support the use of "configure". PCRE is written in
-Standard C, but there are a few non-standard things it can cope with, allowing
-it to run on SunOS4 and other "close to standard" systems.
-
-If you are going to build PCRE "by hand" on a system without "configure" you
-should copy the distributed config.h.generic to config.h, and then set up the
-macro definitions the way you need them. You must then add -DHAVE_CONFIG_H to
-all of your compile commands, so that config.h is included at the start of
-every source.
-
-Alternatively, you can avoid editing by using -D on the compiler command line
-to set the macro values. In this case, you do not have to set -DHAVE_CONFIG_H.
-
-PCRE uses memmove() if HAVE_MEMMOVE is set to 1; otherwise it uses bcopy() if
-HAVE_BCOPY is set to 1. If your system has neither bcopy() nor memmove(), set
-them both to 0; an emulation function will be used. */
-
-/* By default, the \R escape sequence matches any Unicode line ending
- character or sequence of characters. If BSR_ANYCRLF is defined, this is
- changed so that backslash-R matches only CR, LF, or CRLF. The build- time
- default can be overridden by the user of PCRE at runtime. On systems that
- support it, "configure" can be used to override the default. */
-/* #undef BSR_ANYCRLF */
-
-/* If you are compiling for a system that uses EBCDIC instead of ASCII
- character codes, define this macro as 1. On systems that can use
- "configure", this can be done via --enable-ebcdic. */
-/* #undef EBCDIC */
-
-/* Define to 1 if you have the `bcopy' function. */
-#ifndef HAVE_BCOPY
-#define HAVE_BCOPY 1
-#endif
-
-/* Define to 1 if you have the <bits/type_traits.h> header file. */
-/* #undef HAVE_BITS_TYPE_TRAITS_H */
-
-/* Define to 1 if you have the <bzlib.h> header file. */
-#ifndef HAVE_BZLIB_H
-#define HAVE_BZLIB_H 1
-#endif
-
-/* Define to 1 if you have the <dirent.h> header file. */
-#ifndef HAVE_DIRENT_H
-#define HAVE_DIRENT_H 1
-#endif
-
-/* Define to 1 if you have the <dlfcn.h> header file. */
-#ifndef HAVE_DLFCN_H
-#define HAVE_DLFCN_H 1
-#endif
-
-/* Define to 1 if you have the <inttypes.h> header file. */
-#ifndef HAVE_INTTYPES_H
-#define HAVE_INTTYPES_H 1
-#endif
-
-/* Define to 1 if you have the <limits.h> header file. */
-#ifndef HAVE_LIMITS_H
-#define HAVE_LIMITS_H 1
-#endif
-
-/* Define to 1 if the system has the type `long long'. */
-#ifndef HAVE_LONG_LONG
-#define HAVE_LONG_LONG 1
-#endif
-
-/* Define to 1 if you have the `memmove' function. */
-#ifndef HAVE_MEMMOVE
-#define HAVE_MEMMOVE 1
-#endif
-
-/* Define to 1 if you have the <memory.h> header file. */
-#ifndef HAVE_MEMORY_H
-#define HAVE_MEMORY_H 1
-#endif
-
-/* Define to 1 if you have the <readline/history.h> header file. */
-#ifndef HAVE_READLINE_HISTORY_H
-#define HAVE_READLINE_HISTORY_H 1
-#endif
-
-/* Define to 1 if you have the <readline/readline.h> header file. */
-#ifndef HAVE_READLINE_READLINE_H
-#define HAVE_READLINE_READLINE_H 1
-#endif
-
-/* Define to 1 if you have the <stdint.h> header file. */
-#ifndef HAVE_STDINT_H
-#define HAVE_STDINT_H 1
-#endif
-
-/* Define to 1 if you have the <stdlib.h> header file. */
-#ifndef HAVE_STDLIB_H
-#define HAVE_STDLIB_H 1
-#endif
-
-/* Define to 1 if you have the `strerror' function. */
-#ifndef HAVE_STRERROR
-#define HAVE_STRERROR 1
-#endif
-
-/* Define to 1 if you have the <string> header file. */
-#ifndef HAVE_STRING
-#define HAVE_STRING 1
-#endif
-
-/* Define to 1 if you have the <strings.h> header file. */
-#ifndef HAVE_STRINGS_H
-#define HAVE_STRINGS_H 1
-#endif
-
-/* Define to 1 if you have the <string.h> header file. */
-#ifndef HAVE_STRING_H
-#define HAVE_STRING_H 1
-#endif
-
-/* Define to 1 if you have the `strtoll' function. */
-/* #undef HAVE_STRTOLL */
-
-/* Define to 1 if you have the `strtoq' function. */
-#ifndef HAVE_STRTOQ
-#define HAVE_STRTOQ 1
-#endif
-
-/* Define to 1 if you have the <sys/stat.h> header file. */
-#ifndef HAVE_SYS_STAT_H
-#define HAVE_SYS_STAT_H 1
-#endif
-
-/* Define to 1 if you have the <sys/types.h> header file. */
-#ifndef HAVE_SYS_TYPES_H
-#define HAVE_SYS_TYPES_H 1
-#endif
-
-/* Define to 1 if you have the <type_traits.h> header file. */
-/* #undef HAVE_TYPE_TRAITS_H */
-
-/* Define to 1 if you have the <unistd.h> header file. */
-#ifndef HAVE_UNISTD_H
-#define HAVE_UNISTD_H 1
-#endif
-
-/* Define to 1 if the system has the type `unsigned long long'. */
-#ifndef HAVE_UNSIGNED_LONG_LONG
-#define HAVE_UNSIGNED_LONG_LONG 1
-#endif
-
-/* Define to 1 if you have the <windows.h> header file. */
-/* #undef HAVE_WINDOWS_H */
-
-/* Define to 1 if you have the <zlib.h> header file. */
-#ifndef HAVE_ZLIB_H
-#define HAVE_ZLIB_H 1
-#endif
-
-/* Define to 1 if you have the `_strtoi64' function. */
-/* #undef HAVE__STRTOI64 */
-
-/* The value of LINK_SIZE determines the number of bytes used to store links
- as offsets within the compiled regex. The default is 2, which allows for
- compiled patterns up to 64K long. This covers the vast majority of cases.
- However, PCRE can also be compiled to use 3 or 4 bytes instead. This allows
- for longer patterns in extreme cases. On systems that support it,
- "configure" can be used to override this default. */
-#ifndef LINK_SIZE
-#define LINK_SIZE 2
-#endif
-
-/* The value of MATCH_LIMIT determines the default number of times the
- internal match() function can be called during a single execution of
- pcre_exec(). There is a runtime interface for setting a different limit.
- The limit exists in order to catch runaway regular expressions that take
- for ever to determine that they do not match. The default is set very large
- so that it does not accidentally catch legitimate cases. On systems that
- support it, "configure" can be used to override this default default. */
-#ifndef MATCH_LIMIT
-#define MATCH_LIMIT 10000000
-#endif
-
-/* The above limit applies to all calls of match(), whether or not they
- increase the recursion depth. In some environments it is desirable to limit
- the depth of recursive calls of match() more strictly, in order to restrict
- the maximum amount of stack (or heap, if NO_RECURSE is defined) that is
- used. The value of MATCH_LIMIT_RECURSION applies only to recursive calls of
- match(). To have any useful effect, it must be less than the value of
- MATCH_LIMIT. The default is to use the same value as MATCH_LIMIT. There is
- a runtime method for setting a different limit. On systems that support it,
- "configure" can be used to override the default. */
-#ifndef MATCH_LIMIT_RECURSION
-#define MATCH_LIMIT_RECURSION MATCH_LIMIT
-#endif
-
-/* This limit is parameterized just in case anybody ever wants to change it.
- Care must be taken if it is increased, because it guards against integer
- overflow caused by enormously large patterns. */
-#ifndef MAX_NAME_COUNT
-#define MAX_NAME_COUNT 10000
-#endif
-
-/* This limit is parameterized just in case anybody ever wants to change it.
- Care must be taken if it is increased, because it guards against integer
- overflow caused by enormously large patterns. */
-#ifndef MAX_NAME_SIZE
-#define MAX_NAME_SIZE 32
-#endif
-
-/* The value of NEWLINE determines the newline character sequence. On systems
- that support it, "configure" can be used to override the default, which is
- 10. The possible values are 10 (LF), 13 (CR), 3338 (CRLF), -1 (ANY), or -2
- (ANYCRLF). */
-#ifndef NEWLINE
-#define NEWLINE 10
-#endif
-
-/* PCRE uses recursive function calls to handle backtracking while matching.
- This can sometimes be a problem on systems that have stacks of limited
- size. Define NO_RECURSE to get a version that doesn't use recursion in the
- match() function; instead it creates its own stack by steam using
- pcre_recurse_malloc() to obtain memory from the heap. For more detail, see
- the comments and other stuff just above the match() function. On systems
- that support it, "configure" can be used to set this in the Makefile (use
- --disable-stack-for-recursion). */
-/* #undef NO_RECURSE */
-
-/* Name of package */
-#define PACKAGE "pcre"
-
-/* Define to the address where bug reports for this package should be sent. */
-#define PACKAGE_BUGREPORT ""
-
-/* Define to the full name of this package. */
-#define PACKAGE_NAME "PCRE"
-
-/* Define to the full name and version of this package. */
-#define PACKAGE_STRING "PCRE 7.7"
-
-/* Define to the one symbol short name of this package. */
-#define PACKAGE_TARNAME "pcre"
-
-/* Define to the version of this package. */
-#define PACKAGE_VERSION "7.7"
-
-
-/* If you are compiling for a system other than a Unix-like system or
- Win32, and it needs some magic to be inserted before the definition
- of a function that is exported by the library, define this macro to
- contain the relevant magic. If you do not define this macro, it
- defaults to "extern" for a C compiler and "extern C" for a C++
- compiler on non-Win32 systems. This macro apears at the start of
- every exported function that is part of the external API. It does
- not appear on functions that are "external" in the C sense, but
- which are internal to the library. */
-/* #undef PCRE_EXP_DEFN */
-
-/* Define if linking statically (TODO: make nice with Libtool) */
-/* #undef PCRE_STATIC */
-
-/* When calling PCRE via the POSIX interface, additional working storage is
- required for holding the pointers to capturing substrings because PCRE
- requires three integers per substring, whereas the POSIX interface provides
- only two. If the number of expected substrings is small, the wrapper
- function uses space on the stack, because this is faster than using
- malloc() for each call. The threshold above which the stack is no longer
- used is defined by POSIX_MALLOC_THRESHOLD. On systems that support it,
- "configure" can be used to override this default. */
-#ifndef POSIX_MALLOC_THRESHOLD
-#define POSIX_MALLOC_THRESHOLD 10
-#endif
-
-/* Define to 1 if you have the ANSI C header files. */
-#ifndef STDC_HEADERS
-#define STDC_HEADERS 1
-#endif
-
-/* Define to allow pcregrep to be linked with libbz2, so that it is able to
- handle .bz2 files. */
-/* #undef SUPPORT_LIBBZ2 */
-
-/* Define to allow pcretest to be linked with libreadline. */
-/* #undef SUPPORT_LIBREADLINE */
-
-/* Define to allow pcregrep to be linked with libz, so that it is able to
- handle .gz files. */
-/* #undef SUPPORT_LIBZ */
-
-/* Define to enable support for Unicode properties */
-/* #undef SUPPORT_UCP */
-
-/* Define to enable support for the UTF-8 Unicode encoding. */
-/* #undef SUPPORT_UTF8 */
-
-/* Version number of package */
-#ifndef VERSION
-#define VERSION "7.7"
-#endif
-
-/* Define to empty if `const' does not conform to ANSI C. */
-/* #undef const */
-
-/* Define to `unsigned int' if <sys/types.h> does not define. */
-/* #undef size_t */
diff --git a/crawl-ref/source/util/pcre/config.h.in b/crawl-ref/source/util/pcre/config.h.in
deleted file mode 100644
index fb7a37a970..0000000000
--- a/crawl-ref/source/util/pcre/config.h.in
+++ /dev/null
@@ -1,242 +0,0 @@
-/* config.h.in. Generated from configure.ac by autoheader. */
-
-
-/* On Unix-like systems config.h.in is converted by "configure" into config.h.
-Some other environments also support the use of "configure". PCRE is written in
-Standard C, but there are a few non-standard things it can cope with, allowing
-it to run on SunOS4 and other "close to standard" systems.
-
-If you are going to build PCRE "by hand" on a system without "configure" you
-should copy the distributed config.h.generic to config.h, and then set up the
-macro definitions the way you need them. You must then add -DHAVE_CONFIG_H to
-all of your compile commands, so that config.h is included at the start of
-every source.
-
-Alternatively, you can avoid editing by using -D on the compiler command line
-to set the macro values. In this case, you do not have to set -DHAVE_CONFIG_H.
-
-PCRE uses memmove() if HAVE_MEMMOVE is set to 1; otherwise it uses bcopy() if
-HAVE_BCOPY is set to 1. If your system has neither bcopy() nor memmove(), set
-them both to 0; an emulation function will be used. */
-
-/* By default, the \R escape sequence matches any Unicode line ending
- character or sequence of characters. If BSR_ANYCRLF is defined, this is
- changed so that backslash-R matches only CR, LF, or CRLF. The build- time
- default can be overridden by the user of PCRE at runtime. On systems that
- support it, "configure" can be used to override the default. */
-#undef BSR_ANYCRLF
-
-/* If you are compiling for a system that uses EBCDIC instead of ASCII
- character codes, define this macro as 1. On systems that can use
- "configure", this can be done via --enable-ebcdic. */
-#undef EBCDIC
-
-/* Define to 1 if you have the `bcopy' function. */
-#undef HAVE_BCOPY
-
-/* Define to 1 if you have the <bits/type_traits.h> header file. */
-#undef HAVE_BITS_TYPE_TRAITS_H
-
-/* Define to 1 if you have the <bzlib.h> header file. */
-#undef HAVE_BZLIB_H
-
-/* Define to 1 if you have the <dirent.h> header file. */
-#undef HAVE_DIRENT_H
-
-/* Define to 1 if you have the <dlfcn.h> header file. */
-#undef HAVE_DLFCN_H
-
-/* Define to 1 if you have the <inttypes.h> header file. */
-#undef HAVE_INTTYPES_H
-
-/* Define to 1 if you have the <limits.h> header file. */
-#undef HAVE_LIMITS_H
-
-/* Define to 1 if the system has the type `long long'. */
-#undef HAVE_LONG_LONG
-
-/* Define to 1 if you have the `memmove' function. */
-#undef HAVE_MEMMOVE
-
-/* Define to 1 if you have the <memory.h> header file. */
-#undef HAVE_MEMORY_H
-
-/* Define to 1 if you have the <readline/history.h> header file. */
-#undef HAVE_READLINE_HISTORY_H
-
-/* Define to 1 if you have the <readline/readline.h> header file. */
-#undef HAVE_READLINE_READLINE_H
-
-/* Define to 1 if you have the <stdint.h> header file. */
-#undef HAVE_STDINT_H
-
-/* Define to 1 if you have the <stdlib.h> header file. */
-#undef HAVE_STDLIB_H
-
-/* Define to 1 if you have the `strerror' function. */
-#undef HAVE_STRERROR
-
-/* Define to 1 if you have the <string> header file. */
-#undef HAVE_STRING
-
-/* Define to 1 if you have the <strings.h> header file. */
-#undef HAVE_STRINGS_H
-
-/* Define to 1 if you have the <string.h> header file. */
-#undef HAVE_STRING_H
-
-/* Define to 1 if you have the `strtoll' function. */
-#undef HAVE_STRTOLL
-
-/* Define to 1 if you have the `strtoq' function. */
-#undef HAVE_STRTOQ
-
-/* Define to 1 if you have the <sys/stat.h> header file. */
-#undef HAVE_SYS_STAT_H
-
-/* Define to 1 if you have the <sys/types.h> header file. */
-#undef HAVE_SYS_TYPES_H
-
-/* Define to 1 if you have the <type_traits.h> header file. */
-#undef HAVE_TYPE_TRAITS_H
-
-/* Define to 1 if you have the <unistd.h> header file. */
-#undef HAVE_UNISTD_H
-
-/* Define to 1 if the system has the type `unsigned long long'. */
-#undef HAVE_UNSIGNED_LONG_LONG
-
-/* Define to 1 if you have the <windows.h> header file. */
-#undef HAVE_WINDOWS_H
-
-/* Define to 1 if you have the <zlib.h> header file. */
-#undef HAVE_ZLIB_H
-
-/* Define to 1 if you have the `_strtoi64' function. */
-#undef HAVE__STRTOI64
-
-/* The value of LINK_SIZE determines the number of bytes used to store links
- as offsets within the compiled regex. The default is 2, which allows for
- compiled patterns up to 64K long. This covers the vast majority of cases.
- However, PCRE can also be compiled to use 3 or 4 bytes instead. This allows
- for longer patterns in extreme cases. On systems that support it,
- "configure" can be used to override this default. */
-#undef LINK_SIZE
-
-/* The value of MATCH_LIMIT determines the default number of times the
- internal match() function can be called during a single execution of
- pcre_exec(). There is a runtime interface for setting a different limit.
- The limit exists in order to catch runaway regular expressions that take
- for ever to determine that they do not match. The default is set very large
- so that it does not accidentally catch legitimate cases. On systems that
- support it, "configure" can be used to override this default default. */
-#undef MATCH_LIMIT
-
-/* The above limit applies to all calls of match(), whether or not they
- increase the recursion depth. In some environments it is desirable to limit
- the depth of recursive calls of match() more strictly, in order to restrict
- the maximum amount of stack (or heap, if NO_RECURSE is defined) that is
- used. The value of MATCH_LIMIT_RECURSION applies only to recursive calls of
- match(). To have any useful effect, it must be less than the value of
- MATCH_LIMIT. The default is to use the same value as MATCH_LIMIT. There is
- a runtime method for setting a different limit. On systems that support it,
- "configure" can be used to override the default. */
-#undef MATCH_LIMIT_RECURSION
-
-/* This limit is parameterized just in case anybody ever wants to change it.
- Care must be taken if it is increased, because it guards against integer
- overflow caused by enormously large patterns. */
-#undef MAX_NAME_COUNT
-
-/* This limit is parameterized just in case anybody ever wants to change it.
- Care must be taken if it is increased, because it guards against integer
- overflow caused by enormously large patterns. */
-#undef MAX_NAME_SIZE
-
-/* The value of NEWLINE determines the newline character sequence. On systems
- that support it, "configure" can be used to override the default, which is
- 10. The possible values are 10 (LF), 13 (CR), 3338 (CRLF), -1 (ANY), or -2
- (ANYCRLF). */
-#undef NEWLINE
-
-/* PCRE uses recursive function calls to handle backtracking while matching.
- This can sometimes be a problem on systems that have stacks of limited
- size. Define NO_RECURSE to get a version that doesn't use recursion in the
- match() function; instead it creates its own stack by steam using
- pcre_recurse_malloc() to obtain memory from the heap. For more detail, see
- the comments and other stuff just above the match() function. On systems
- that support it, "configure" can be used to set this in the Makefile (use
- --disable-stack-for-recursion). */
-#undef NO_RECURSE
-
-/* Name of package */
-#undef PACKAGE
-
-/* Define to the address where bug reports for this package should be sent. */
-#undef PACKAGE_BUGREPORT
-
-/* Define to the full name of this package. */
-#undef PACKAGE_NAME
-
-/* Define to the full name and version of this package. */
-#undef PACKAGE_STRING
-
-/* Define to the one symbol short name of this package. */
-#undef PACKAGE_TARNAME
-
-/* Define to the version of this package. */
-#undef PACKAGE_VERSION
-
-
-/* If you are compiling for a system other than a Unix-like system or
- Win32, and it needs some magic to be inserted before the definition
- of a function that is exported by the library, define this macro to
- contain the relevant magic. If you do not define this macro, it
- defaults to "extern" for a C compiler and "extern C" for a C++
- compiler on non-Win32 systems. This macro apears at the start of
- every exported function that is part of the external API. It does
- not appear on functions that are "external" in the C sense, but
- which are internal to the library. */
-#undef PCRE_EXP_DEFN
-
-/* Define if linking statically (TODO: make nice with Libtool) */
-#undef PCRE_STATIC
-
-/* When calling PCRE via the POSIX interface, additional working storage is
- required for holding the pointers to capturing substrings because PCRE
- requires three integers per substring, whereas the POSIX interface provides
- only two. If the number of expected substrings is small, the wrapper
- function uses space on the stack, because this is faster than using
- malloc() for each call. The threshold above which the stack is no longer
- used is defined by POSIX_MALLOC_THRESHOLD. On systems that support it,
- "configure" can be used to override this default. */
-#undef POSIX_MALLOC_THRESHOLD
-
-/* Define to 1 if you have the ANSI C header files. */
-#undef STDC_HEADERS
-
-/* Define to allow pcregrep to be linked with libbz2, so that it is able to
- handle .bz2 files. */
-#undef SUPPORT_LIBBZ2
-
-/* Define to allow pcretest to be linked with libreadline. */
-#undef SUPPORT_LIBREADLINE
-
-/* Define to allow pcregrep to be linked with libz, so that it is able to
- handle .gz files. */
-#undef SUPPORT_LIBZ
-
-/* Define to enable support for Unicode properties */
-#undef SUPPORT_UCP
-
-/* Define to enable support for the UTF-8 Unicode encoding. */
-#undef SUPPORT_UTF8
-
-/* Version number of package */
-#undef VERSION
-
-/* Define to empty if `const' does not conform to ANSI C. */
-#undef const
-
-/* Define to `unsigned int' if <sys/types.h> does not define. */
-#undef size_t
diff --git a/crawl-ref/source/util/pcre/config.sub b/crawl-ref/source/util/pcre/config.sub
deleted file mode 100644
index 63cdd0a35d..0000000000
--- a/crawl-ref/source/util/pcre/config.sub
+++ /dev/null
@@ -1,1644 +0,0 @@
-#! /bin/sh
-# Configuration validation subroutine script.
-# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-# 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation,
-# Inc.
-
-timestamp='2007-06-28'
-
-# This file is (in principle) common to ALL GNU software.
-# The presence of a machine in this file suggests that SOME GNU software
-# can handle that machine. It does not imply ALL GNU software can.
-#
-# This file is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
-# 02110-1301, USA.
-#
-# As a special exception to the GNU General Public License, if you
-# distribute this file as part of a program that contains a
-# configuration script generated by Autoconf, you may include it under
-# the same distribution terms that you use for the rest of that program.
-
-
-# Please send patches to <config-patches@gnu.org>. Submit a context
-# diff and a properly formatted ChangeLog entry.
-#
-# Configuration subroutine to validate and canonicalize a configuration type.
-# Supply the specified configuration type as an argument.
-# If it is invalid, we print an error message on stderr and exit with code 1.
-# Otherwise, we print the canonical config type on stdout and succeed.
-
-# This file is supposed to be the same for all GNU packages
-# and recognize all the CPU types, system types and aliases
-# that are meaningful with *any* GNU software.
-# Each package is responsible for reporting which valid configurations
-# it does not support. The user should be able to distinguish
-# a failure to support a valid configuration from a meaningless
-# configuration.
-
-# The goal of this file is to map all the various variations of a given
-# machine specification into a single specification in the form:
-# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
-# or in some cases, the newer four-part form:
-# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
-# It is wrong to echo any other type of specification.
-
-me=`echo "$0" | sed -e 's,.*/,,'`
-
-usage="\
-Usage: $0 [OPTION] CPU-MFR-OPSYS
- $0 [OPTION] ALIAS
-
-Canonicalize a configuration name.
-
-Operation modes:
- -h, --help print this help, then exit
- -t, --time-stamp print date of last modification, then exit
- -v, --version print version number, then exit
-
-Report bugs and patches to <config-patches@gnu.org>."
-
-version="\
-GNU config.sub ($timestamp)
-
-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
-Free Software Foundation, Inc.
-
-This is free software; see the source for copying conditions. There is NO
-warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
-
-help="
-Try \`$me --help' for more information."
-
-# Parse command line
-while test $# -gt 0 ; do
- case $1 in
- --time-stamp | --time* | -t )
- echo "$timestamp" ; exit ;;
- --version | -v )
- echo "$version" ; exit ;;
- --help | --h* | -h )
- echo "$usage"; exit ;;
- -- ) # Stop option processing
- shift; break ;;
- - ) # Use stdin as input.
- break ;;
- -* )
- echo "$me: invalid option $1$help"
- exit 1 ;;
-
- *local*)
- # First pass through any local machine types.
- echo $1
- exit ;;
-
- * )
- break ;;
- esac
-done
-
-case $# in
- 0) echo "$me: missing argument$help" >&2
- exit 1;;
- 1) ;;
- *) echo "$me: too many arguments$help" >&2
- exit 1;;
-esac
-
-# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
-# Here we must recognize all the valid KERNEL-OS combinations.
-maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
-case $maybe_os in
- nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \
- uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \
- storm-chaos* | os2-emx* | rtmk-nova*)
- os=-$maybe_os
- basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
- ;;
- *)
- basic_machine=`echo $1 | sed 's/-[^-]*$//'`
- if [ $basic_machine != $1 ]
- then os=`echo $1 | sed 's/.*-/-/'`
- else os=; fi
- ;;
-esac
-
-### Let's recognize common machines as not being operating systems so
-### that things like config.sub decstation-3100 work. We also
-### recognize some manufacturers as not being operating systems, so we
-### can provide default operating systems below.
-case $os in
- -sun*os*)
- # Prevent following clause from handling this invalid input.
- ;;
- -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
- -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
- -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
- -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
- -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
- -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
- -apple | -axis | -knuth | -cray)
- os=
- basic_machine=$1
- ;;
- -sim | -cisco | -oki | -wec | -winbond)
- os=
- basic_machine=$1
- ;;
- -scout)
- ;;
- -wrs)
- os=-vxworks
- basic_machine=$1
- ;;
- -chorusos*)
- os=-chorusos
- basic_machine=$1
- ;;
- -chorusrdb)
- os=-chorusrdb
- basic_machine=$1
- ;;
- -hiux*)
- os=-hiuxwe2
- ;;
- -sco6)
- os=-sco5v6
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco5)
- os=-sco3.2v5
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco4)
- os=-sco3.2v4
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco3.2.[4-9]*)
- os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco3.2v[4-9]*)
- # Don't forget version if it is 3.2v4 or newer.
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco5v6*)
- # Don't forget version if it is 3.2v4 or newer.
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco*)
- os=-sco3.2v2
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -udk*)
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -isc)
- os=-isc2.2
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -clix*)
- basic_machine=clipper-intergraph
- ;;
- -isc*)
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -lynx*)
- os=-lynxos
- ;;
- -ptx*)
- basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
- ;;
- -windowsnt*)
- os=`echo $os | sed -e 's/windowsnt/winnt/'`
- ;;
- -psos*)
- os=-psos
- ;;
- -mint | -mint[0-9]*)
- basic_machine=m68k-atari
- os=-mint
- ;;
-esac
-
-# Decode aliases for certain CPU-COMPANY combinations.
-case $basic_machine in
- # Recognize the basic CPU types without company name.
- # Some are omitted here because they have special meanings below.
- 1750a | 580 \
- | a29k \
- | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
- | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
- | am33_2.0 \
- | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
- | bfin \
- | c4x | clipper \
- | d10v | d30v | dlx | dsp16xx | dvp \
- | fido | fr30 | frv \
- | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
- | i370 | i860 | i960 | ia64 \
- | ip2k | iq2000 \
- | m32c | m32r | m32rle | m68000 | m68k | m88k \
- | maxq | mb | microblaze | mcore | mep \
- | mips | mipsbe | mipseb | mipsel | mipsle \
- | mips16 \
- | mips64 | mips64el \
- | mips64vr | mips64vrel \
- | mips64orion | mips64orionel \
- | mips64vr4100 | mips64vr4100el \
- | mips64vr4300 | mips64vr4300el \
- | mips64vr5000 | mips64vr5000el \
- | mips64vr5900 | mips64vr5900el \
- | mipsisa32 | mipsisa32el \
- | mipsisa32r2 | mipsisa32r2el \
- | mipsisa64 | mipsisa64el \
- | mipsisa64r2 | mipsisa64r2el \
- | mipsisa64sb1 | mipsisa64sb1el \
- | mipsisa64sr71k | mipsisa64sr71kel \
- | mipstx39 | mipstx39el \
- | mn10200 | mn10300 \
- | mt \
- | msp430 \
- | nios | nios2 \
- | ns16k | ns32k \
- | or32 \
- | pdp10 | pdp11 | pj | pjl \
- | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
- | pyramid \
- | score \
- | sh | sh[1234] | sh[24]a | sh[24]a*eb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
- | sh64 | sh64le \
- | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
- | sparcv8 | sparcv9 | sparcv9b | sparcv9v \
- | spu | strongarm \
- | tahoe | thumb | tic4x | tic80 | tron \
- | v850 | v850e \
- | we32k \
- | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \
- | z8k)
- basic_machine=$basic_machine-unknown
- ;;
- m6811 | m68hc11 | m6812 | m68hc12)
- # Motorola 68HC11/12.
- basic_machine=$basic_machine-unknown
- os=-none
- ;;
- m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
- ;;
- ms1)
- basic_machine=mt-unknown
- ;;
-
- # We use `pc' rather than `unknown'
- # because (1) that's what they normally are, and
- # (2) the word "unknown" tends to confuse beginning users.
- i*86 | x86_64)
- basic_machine=$basic_machine-pc
- ;;
- # Object if more than one company name word.
- *-*-*)
- echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
- exit 1
- ;;
- # Recognize the basic CPU types with company name.
- 580-* \
- | a29k-* \
- | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
- | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
- | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
- | arm-* | armbe-* | armle-* | armeb-* | armv*-* \
- | avr-* | avr32-* \
- | bfin-* | bs2000-* \
- | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
- | clipper-* | craynv-* | cydra-* \
- | d10v-* | d30v-* | dlx-* \
- | elxsi-* \
- | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
- | h8300-* | h8500-* \
- | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
- | i*86-* | i860-* | i960-* | ia64-* \
- | ip2k-* | iq2000-* \
- | m32c-* | m32r-* | m32rle-* \
- | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
- | m88110-* | m88k-* | maxq-* | mcore-* \
- | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
- | mips16-* \
- | mips64-* | mips64el-* \
- | mips64vr-* | mips64vrel-* \
- | mips64orion-* | mips64orionel-* \
- | mips64vr4100-* | mips64vr4100el-* \
- | mips64vr4300-* | mips64vr4300el-* \
- | mips64vr5000-* | mips64vr5000el-* \
- | mips64vr5900-* | mips64vr5900el-* \
- | mipsisa32-* | mipsisa32el-* \
- | mipsisa32r2-* | mipsisa32r2el-* \
- | mipsisa64-* | mipsisa64el-* \
- | mipsisa64r2-* | mipsisa64r2el-* \
- | mipsisa64sb1-* | mipsisa64sb1el-* \
- | mipsisa64sr71k-* | mipsisa64sr71kel-* \
- | mipstx39-* | mipstx39el-* \
- | mmix-* \
- | mt-* \
- | msp430-* \
- | nios-* | nios2-* \
- | none-* | np1-* | ns16k-* | ns32k-* \
- | orion-* \
- | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
- | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
- | pyramid-* \
- | romp-* | rs6000-* \
- | sh-* | sh[1234]-* | sh[24]a-* | sh[24]a*eb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
- | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
- | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
- | sparclite-* \
- | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \
- | tahoe-* | thumb-* \
- | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
- | tron-* \
- | v850-* | v850e-* | vax-* \
- | we32k-* \
- | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \
- | xstormy16-* | xtensa-* \
- | ymp-* \
- | z8k-*)
- ;;
- # Recognize the various machine names and aliases which stand
- # for a CPU type and a company and sometimes even an OS.
- 386bsd)
- basic_machine=i386-unknown
- os=-bsd
- ;;
- 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
- basic_machine=m68000-att
- ;;
- 3b*)
- basic_machine=we32k-att
- ;;
- a29khif)
- basic_machine=a29k-amd
- os=-udi
- ;;
- abacus)
- basic_machine=abacus-unknown
- ;;
- adobe68k)
- basic_machine=m68010-adobe
- os=-scout
- ;;
- alliant | fx80)
- basic_machine=fx80-alliant
- ;;
- altos | altos3068)
- basic_machine=m68k-altos
- ;;
- am29k)
- basic_machine=a29k-none
- os=-bsd
- ;;
- amd64)
- basic_machine=x86_64-pc
- ;;
- amd64-*)
- basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- amdahl)
- basic_machine=580-amdahl
- os=-sysv
- ;;
- amiga | amiga-*)
- basic_machine=m68k-unknown
- ;;
- amigaos | amigados)
- basic_machine=m68k-unknown
- os=-amigaos
- ;;
- amigaunix | amix)
- basic_machine=m68k-unknown
- os=-sysv4
- ;;
- apollo68)
- basic_machine=m68k-apollo
- os=-sysv
- ;;
- apollo68bsd)
- basic_machine=m68k-apollo
- os=-bsd
- ;;
- aux)
- basic_machine=m68k-apple
- os=-aux
- ;;
- balance)
- basic_machine=ns32k-sequent
- os=-dynix
- ;;
- c90)
- basic_machine=c90-cray
- os=-unicos
- ;;
- convex-c1)
- basic_machine=c1-convex
- os=-bsd
- ;;
- convex-c2)
- basic_machine=c2-convex
- os=-bsd
- ;;
- convex-c32)
- basic_machine=c32-convex
- os=-bsd
- ;;
- convex-c34)
- basic_machine=c34-convex
- os=-bsd
- ;;
- convex-c38)
- basic_machine=c38-convex
- os=-bsd
- ;;
- cray | j90)
- basic_machine=j90-cray
- os=-unicos
- ;;
- craynv)
- basic_machine=craynv-cray
- os=-unicosmp
- ;;
- cr16)
- basic_machine=cr16-unknown
- os=-elf
- ;;
- crds | unos)
- basic_machine=m68k-crds
- ;;
- crisv32 | crisv32-* | etraxfs*)
- basic_machine=crisv32-axis
- ;;
- cris | cris-* | etrax*)
- basic_machine=cris-axis
- ;;
- crx)
- basic_machine=crx-unknown
- os=-elf
- ;;
- da30 | da30-*)
- basic_machine=m68k-da30
- ;;
- decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
- basic_machine=mips-dec
- ;;
- decsystem10* | dec10*)
- basic_machine=pdp10-dec
- os=-tops10
- ;;
- decsystem20* | dec20*)
- basic_machine=pdp10-dec
- os=-tops20
- ;;
- delta | 3300 | motorola-3300 | motorola-delta \
- | 3300-motorola | delta-motorola)
- basic_machine=m68k-motorola
- ;;
- delta88)
- basic_machine=m88k-motorola
- os=-sysv3
- ;;
- djgpp)
- basic_machine=i586-pc
- os=-msdosdjgpp
- ;;
- dpx20 | dpx20-*)
- basic_machine=rs6000-bull
- os=-bosx
- ;;
- dpx2* | dpx2*-bull)
- basic_machine=m68k-bull
- os=-sysv3
- ;;
- ebmon29k)
- basic_machine=a29k-amd
- os=-ebmon
- ;;
- elxsi)
- basic_machine=elxsi-elxsi
- os=-bsd
- ;;
- encore | umax | mmax)
- basic_machine=ns32k-encore
- ;;
- es1800 | OSE68k | ose68k | ose | OSE)
- basic_machine=m68k-ericsson
- os=-ose
- ;;
- fx2800)
- basic_machine=i860-alliant
- ;;
- genix)
- basic_machine=ns32k-ns
- ;;
- gmicro)
- basic_machine=tron-gmicro
- os=-sysv
- ;;
- go32)
- basic_machine=i386-pc
- os=-go32
- ;;
- h3050r* | hiux*)
- basic_machine=hppa1.1-hitachi
- os=-hiuxwe2
- ;;
- h8300hms)
- basic_machine=h8300-hitachi
- os=-hms
- ;;
- h8300xray)
- basic_machine=h8300-hitachi
- os=-xray
- ;;
- h8500hms)
- basic_machine=h8500-hitachi
- os=-hms
- ;;
- harris)
- basic_machine=m88k-harris
- os=-sysv3
- ;;
- hp300-*)
- basic_machine=m68k-hp
- ;;
- hp300bsd)
- basic_machine=m68k-hp
- os=-bsd
- ;;
- hp300hpux)
- basic_machine=m68k-hp
- os=-hpux
- ;;
- hp3k9[0-9][0-9] | hp9[0-9][0-9])
- basic_machine=hppa1.0-hp
- ;;
- hp9k2[0-9][0-9] | hp9k31[0-9])
- basic_machine=m68000-hp
- ;;
- hp9k3[2-9][0-9])
- basic_machine=m68k-hp
- ;;
- hp9k6[0-9][0-9] | hp6[0-9][0-9])
- basic_machine=hppa1.0-hp
- ;;
- hp9k7[0-79][0-9] | hp7[0-79][0-9])
- basic_machine=hppa1.1-hp
- ;;
- hp9k78[0-9] | hp78[0-9])
- # FIXME: really hppa2.0-hp
- basic_machine=hppa1.1-hp
- ;;
- hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
- # FIXME: really hppa2.0-hp
- basic_machine=hppa1.1-hp
- ;;
- hp9k8[0-9][13679] | hp8[0-9][13679])
- basic_machine=hppa1.1-hp
- ;;
- hp9k8[0-9][0-9] | hp8[0-9][0-9])
- basic_machine=hppa1.0-hp
- ;;
- hppa-next)
- os=-nextstep3
- ;;
- hppaosf)
- basic_machine=hppa1.1-hp
- os=-osf
- ;;
- hppro)
- basic_machine=hppa1.1-hp
- os=-proelf
- ;;
- i370-ibm* | ibm*)
- basic_machine=i370-ibm
- ;;
-# I'm not sure what "Sysv32" means. Should this be sysv3.2?
- i*86v32)
- basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
- os=-sysv32
- ;;
- i*86v4*)
- basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
- os=-sysv4
- ;;
- i*86v)
- basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
- os=-sysv
- ;;
- i*86sol2)
- basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
- os=-solaris2
- ;;
- i386mach)
- basic_machine=i386-mach
- os=-mach
- ;;
- i386-vsta | vsta)
- basic_machine=i386-unknown
- os=-vsta
- ;;
- iris | iris4d)
- basic_machine=mips-sgi
- case $os in
- -irix*)
- ;;
- *)
- os=-irix4
- ;;
- esac
- ;;
- isi68 | isi)
- basic_machine=m68k-isi
- os=-sysv
- ;;
- m88k-omron*)
- basic_machine=m88k-omron
- ;;
- magnum | m3230)
- basic_machine=mips-mips
- os=-sysv
- ;;
- merlin)
- basic_machine=ns32k-utek
- os=-sysv
- ;;
- mingw32)
- basic_machine=i386-pc
- os=-mingw32
- ;;
- mingw32ce)
- basic_machine=arm-unknown
- os=-mingw32ce
- ;;
- miniframe)
- basic_machine=m68000-convergent
- ;;
- *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
- basic_machine=m68k-atari
- os=-mint
- ;;
- mipsEE* | ee | ps2)
- basic_machine=mips64r5900el-scei
- case $os in
- -linux*)
- ;;
- *)
- os=-elf
- ;;
- esac
- ;;
- iop)
- basic_machine=mipsel-scei
- os=-irx
- ;;
- dvp)
- basic_machine=dvp-scei
- os=-elf
- ;;
- mips3*-*)
- basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
- ;;
- mips3*)
- basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
- ;;
- monitor)
- basic_machine=m68k-rom68k
- os=-coff
- ;;
- morphos)
- basic_machine=powerpc-unknown
- os=-morphos
- ;;
- msdos)
- basic_machine=i386-pc
- os=-msdos
- ;;
- ms1-*)
- basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
- ;;
- mvs)
- basic_machine=i370-ibm
- os=-mvs
- ;;
- ncr3000)
- basic_machine=i486-ncr
- os=-sysv4
- ;;
- netbsd386)
- basic_machine=i386-unknown
- os=-netbsd
- ;;
- netwinder)
- basic_machine=armv4l-rebel
- os=-linux
- ;;
- news | news700 | news800 | news900)
- basic_machine=m68k-sony
- os=-newsos
- ;;
- news1000)
- basic_machine=m68030-sony
- os=-newsos
- ;;
- news-3600 | risc-news)
- basic_machine=mips-sony
- os=-newsos
- ;;
- necv70)
- basic_machine=v70-nec
- os=-sysv
- ;;
- next | m*-next )
- basic_machine=m68k-next
- case $os in
- -nextstep* )
- ;;
- -ns2*)
- os=-nextstep2
- ;;
- *)
- os=-nextstep3
- ;;
- esac
- ;;
- nh3000)
- basic_machine=m68k-harris
- os=-cxux
- ;;
- nh[45]000)
- basic_machine=m88k-harris
- os=-cxux
- ;;
- nindy960)
- basic_machine=i960-intel
- os=-nindy
- ;;
- mon960)
- basic_machine=i960-intel
- os=-mon960
- ;;
- nonstopux)
- basic_machine=mips-compaq
- os=-nonstopux
- ;;
- np1)
- basic_machine=np1-gould
- ;;
- nsr-tandem)
- basic_machine=nsr-tandem
- ;;
- op50n-* | op60c-*)
- basic_machine=hppa1.1-oki
- os=-proelf
- ;;
- openrisc | openrisc-*)
- basic_machine=or32-unknown
- ;;
- os400)
- basic_machine=powerpc-ibm
- os=-os400
- ;;
- OSE68000 | ose68000)
- basic_machine=m68000-ericsson
- os=-ose
- ;;
- os68k)
- basic_machine=m68k-none
- os=-os68k
- ;;
- pa-hitachi)
- basic_machine=hppa1.1-hitachi
- os=-hiuxwe2
- ;;
- paragon)
- basic_machine=i860-intel
- os=-osf
- ;;
- pbd)
- basic_machine=sparc-tti
- ;;
- pbb)
- basic_machine=m68k-tti
- ;;
- pc532 | pc532-*)
- basic_machine=ns32k-pc532
- ;;
- pc98)
- basic_machine=i386-pc
- ;;
- pc98-*)
- basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- pentium | p5 | k5 | k6 | nexgen | viac3)
- basic_machine=i586-pc
- ;;
- pentiumpro | p6 | 6x86 | athlon | athlon_*)
- basic_machine=i686-pc
- ;;
- pentiumii | pentium2 | pentiumiii | pentium3)
- basic_machine=i686-pc
- ;;
- pentium4)
- basic_machine=i786-pc
- ;;
- pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
- basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- pentiumpro-* | p6-* | 6x86-* | athlon-*)
- basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
- basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- pentium4-*)
- basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- pn)
- basic_machine=pn-gould
- ;;
- power) basic_machine=power-ibm
- ;;
- ppc) basic_machine=powerpc-unknown
- ;;
- ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- ppcle | powerpclittle | ppc-le | powerpc-little)
- basic_machine=powerpcle-unknown
- ;;
- ppcle-* | powerpclittle-*)
- basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- ppc64) basic_machine=powerpc64-unknown
- ;;
- ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- ppc64le | powerpc64little | ppc64-le | powerpc64-little)
- basic_machine=powerpc64le-unknown
- ;;
- ppc64le-* | powerpc64little-*)
- basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- ps2)
- basic_machine=i386-ibm
- ;;
- pw32)
- basic_machine=i586-unknown
- os=-pw32
- ;;
- rdos)
- basic_machine=i386-pc
- os=-rdos
- ;;
- rom68k)
- basic_machine=m68k-rom68k
- os=-coff
- ;;
- rm[46]00)
- basic_machine=mips-siemens
- ;;
- rtpc | rtpc-*)
- basic_machine=romp-ibm
- ;;
- s390 | s390-*)
- basic_machine=s390-ibm
- ;;
- s390x | s390x-*)
- basic_machine=s390x-ibm
- ;;
- sa29200)
- basic_machine=a29k-amd
- os=-udi
- ;;
- sb1)
- basic_machine=mipsisa64sb1-unknown
- ;;
- sb1el)
- basic_machine=mipsisa64sb1el-unknown
- ;;
- sde)
- basic_machine=mipsisa32-sde
- os=-elf
- ;;
- sei)
- basic_machine=mips-sei
- os=-seiux
- ;;
- sequent)
- basic_machine=i386-sequent
- ;;
- sh)
- basic_machine=sh-hitachi
- os=-hms
- ;;
- sh5el)
- basic_machine=sh5le-unknown
- ;;
- sh64)
- basic_machine=sh64-unknown
- ;;
- sparclite-wrs | simso-wrs)
- basic_machine=sparclite-wrs
- os=-vxworks
- ;;
- sps7)
- basic_machine=m68k-bull
- os=-sysv2
- ;;
- spur)
- basic_machine=spur-unknown
- ;;
- st2000)
- basic_machine=m68k-tandem
- ;;
- stratus)
- basic_machine=i860-stratus
- os=-sysv4
- ;;
- sun2)
- basic_machine=m68000-sun
- ;;
- sun2os3)
- basic_machine=m68000-sun
- os=-sunos3
- ;;
- sun2os4)
- basic_machine=m68000-sun
- os=-sunos4
- ;;
- sun3os3)
- basic_machine=m68k-sun
- os=-sunos3
- ;;
- sun3os4)
- basic_machine=m68k-sun
- os=-sunos4
- ;;
- sun4os3)
- basic_machine=sparc-sun
- os=-sunos3
- ;;
- sun4os4)
- basic_machine=sparc-sun
- os=-sunos4
- ;;
- sun4sol2)
- basic_machine=sparc-sun
- os=-solaris2
- ;;
- sun3 | sun3-*)
- basic_machine=m68k-sun
- ;;
- sun4)
- basic_machine=sparc-sun
- ;;
- sun386 | sun386i | roadrunner)
- basic_machine=i386-sun
- ;;
- sv1)
- basic_machine=sv1-cray
- os=-unicos
- ;;
- symmetry)
- basic_machine=i386-sequent
- os=-dynix
- ;;
- t3e)
- basic_machine=alphaev5-cray
- os=-unicos
- ;;
- t90)
- basic_machine=t90-cray
- os=-unicos
- ;;
- tic54x | c54x*)
- basic_machine=tic54x-unknown
- os=-coff
- ;;
- tic55x | c55x*)
- basic_machine=tic55x-unknown
- os=-coff
- ;;
- tic6x | c6x*)
- basic_machine=tic6x-unknown
- os=-coff
- ;;
- tx39)
- basic_machine=mipstx39-unknown
- ;;
- tx39el)
- basic_machine=mipstx39el-unknown
- ;;
- toad1)
- basic_machine=pdp10-xkl
- os=-tops20
- ;;
- tower | tower-32)
- basic_machine=m68k-ncr
- ;;
- tpf)
- basic_machine=s390x-ibm
- os=-tpf
- ;;
- udi29k)
- basic_machine=a29k-amd
- os=-udi
- ;;
- ultra3)
- basic_machine=a29k-nyu
- os=-sym1
- ;;
- v810 | necv810)
- basic_machine=v810-nec
- os=-none
- ;;
- vaxv)
- basic_machine=vax-dec
- os=-sysv
- ;;
- vms)
- basic_machine=vax-dec
- os=-vms
- ;;
- vpp*|vx|vx-*)
- basic_machine=f301-fujitsu
- ;;
- vxworks960)
- basic_machine=i960-wrs
- os=-vxworks
- ;;
- vxworks68)
- basic_machine=m68k-wrs
- os=-vxworks
- ;;
- vxworks29k)
- basic_machine=a29k-wrs
- os=-vxworks
- ;;
- w65*)
- basic_machine=w65-wdc
- os=-none
- ;;
- w89k-*)
- basic_machine=hppa1.1-winbond
- os=-proelf
- ;;
- xbox)
- basic_machine=i686-pc
- os=-mingw32
- ;;
- xps | xps100)
- basic_machine=xps100-honeywell
- ;;
- ymp)
- basic_machine=ymp-cray
- os=-unicos
- ;;
- z8k-*-coff)
- basic_machine=z8k-unknown
- os=-sim
- ;;
- none)
- basic_machine=none-none
- os=-none
- ;;
-
-# Here we handle the default manufacturer of certain CPU types. It is in
-# some cases the only manufacturer, in others, it is the most popular.
- w89k)
- basic_machine=hppa1.1-winbond
- ;;
- op50n)
- basic_machine=hppa1.1-oki
- ;;
- op60c)
- basic_machine=hppa1.1-oki
- ;;
- romp)
- basic_machine=romp-ibm
- ;;
- mmix)
- basic_machine=mmix-knuth
- ;;
- rs6000)
- basic_machine=rs6000-ibm
- ;;
- vax)
- basic_machine=vax-dec
- ;;
- pdp10)
- # there are many clones, so DEC is not a safe bet
- basic_machine=pdp10-unknown
- ;;
- pdp11)
- basic_machine=pdp11-dec
- ;;
- we32k)
- basic_machine=we32k-att
- ;;
- sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele)
- basic_machine=sh-unknown
- ;;
- sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
- basic_machine=sparc-sun
- ;;
- cydra)
- basic_machine=cydra-cydrome
- ;;
- orion)
- basic_machine=orion-highlevel
- ;;
- orion105)
- basic_machine=clipper-highlevel
- ;;
- mac | mpw | mac-mpw)
- basic_machine=m68k-apple
- ;;
- pmac | pmac-mpw)
- basic_machine=powerpc-apple
- ;;
- *-unknown)
- # Make sure to match an already-canonicalized machine name.
- ;;
- *)
- echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
- exit 1
- ;;
-esac
-
-# Here we canonicalize certain aliases for manufacturers.
-case $basic_machine in
- *-digital*)
- basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
- ;;
- *-commodore*)
- basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
- ;;
- *)
- ;;
-esac
-
-# Decode manufacturer-specific aliases for certain operating systems.
-
-if [ x"$os" != x"" ]
-then
-case $os in
- # First match some system type aliases
- # that might get confused with valid system types.
- # -solaris* is a basic system type, with this one exception.
- -solaris1 | -solaris1.*)
- os=`echo $os | sed -e 's|solaris1|sunos4|'`
- ;;
- -solaris)
- os=-solaris2
- ;;
- -svr4*)
- os=-sysv4
- ;;
- -unixware*)
- os=-sysv4.2uw
- ;;
- -gnu/linux*)
- os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
- ;;
- # First accept the basic system types.
- # The portable systems comes first.
- # Each alternative MUST END IN A *, to match a version number.
- # -sysv* is not here because it comes later, after sysvr4.
- -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
- | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
- | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
- | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
- | -aos* \
- | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
- | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
- | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
- | -openbsd* | -solidbsd* \
- | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
- | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
- | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
- | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
- | -chorusos* | -chorusrdb* \
- | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
- | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \
- | -uxpv* | -beos* | -mpeix* | -udk* \
- | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
- | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
- | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
- | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
- | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
- | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
- | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -irx*)
- # Remember, each alternative MUST END IN *, to match a version number.
- ;;
- -qnx*)
- case $basic_machine in
- x86-* | i*86-*)
- ;;
- *)
- os=-nto$os
- ;;
- esac
- ;;
- -nto-qnx*)
- ;;
- -nto*)
- os=`echo $os | sed -e 's|nto|nto-qnx|'`
- ;;
- -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
- | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
- | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
- ;;
- -mac*)
- os=`echo $os | sed -e 's|mac|macos|'`
- ;;
- -linux-dietlibc)
- os=-linux-dietlibc
- ;;
- -linux*)
- os=`echo $os | sed -e 's|linux|linux-gnu|'`
- ;;
- -sunos5*)
- os=`echo $os | sed -e 's|sunos5|solaris2|'`
- ;;
- -sunos6*)
- os=`echo $os | sed -e 's|sunos6|solaris3|'`
- ;;
- -opened*)
- os=-openedition
- ;;
- -os400*)
- os=-os400
- ;;
- -wince*)
- os=-wince
- ;;
- -osfrose*)
- os=-osfrose
- ;;
- -osf*)
- os=-osf
- ;;
- -utek*)
- os=-bsd
- ;;
- -dynix*)
- os=-bsd
- ;;
- -acis*)
- os=-aos
- ;;
- -atheos*)
- os=-atheos
- ;;
- -syllable*)
- os=-syllable
- ;;
- -386bsd)
- os=-bsd
- ;;
- -ctix* | -uts*)
- os=-sysv
- ;;
- -nova*)
- os=-rtmk-nova
- ;;
- -ns2 )
- os=-nextstep2
- ;;
- -nsk*)
- os=-nsk
- ;;
- # Preserve the version number of sinix5.
- -sinix5.*)
- os=`echo $os | sed -e 's|sinix|sysv|'`
- ;;
- -sinix*)
- os=-sysv4
- ;;
- -tpf*)
- os=-tpf
- ;;
- -triton*)
- os=-sysv3
- ;;
- -oss*)
- os=-sysv3
- ;;
- -svr4)
- os=-sysv4
- ;;
- -svr3)
- os=-sysv3
- ;;
- -sysvr4)
- os=-sysv4
- ;;
- # This must come after -sysvr4.
- -sysv*)
- ;;
- -ose*)
- os=-ose
- ;;
- -es1800*)
- os=-ose
- ;;
- -xenix)
- os=-xenix
- ;;
- -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
- os=-mint
- ;;
- -aros*)
- os=-aros
- ;;
- -kaos*)
- os=-kaos
- ;;
- -zvmoe)
- os=-zvmoe
- ;;
- -none)
- ;;
- *)
- # Get rid of the `-' at the beginning of $os.
- os=`echo $os | sed 's/[^-]*-//'`
- echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
- exit 1
- ;;
-esac
-else
-
-# Here we handle the default operating systems that come with various machines.
-# The value should be what the vendor currently ships out the door with their
-# machine or put another way, the most popular os provided with the machine.
-
-# Note that if you're going to try to match "-MANUFACTURER" here (say,
-# "-sun"), then you have to tell the case statement up towards the top
-# that MANUFACTURER isn't an operating system. Otherwise, code above
-# will signal an error saying that MANUFACTURER isn't an operating
-# system, and we'll never get to this point.
-
-case $basic_machine in
- score-*)
- os=-elf
- ;;
- spu-*)
- os=-elf
- ;;
- *-acorn)
- os=-riscix1.2
- ;;
- arm*-rebel)
- os=-linux
- ;;
- arm*-semi)
- os=-aout
- ;;
- c4x-* | tic4x-*)
- os=-coff
- ;;
- # This must come before the *-dec entry.
- pdp10-*)
- os=-tops20
- ;;
- pdp11-*)
- os=-none
- ;;
- *-dec | vax-*)
- os=-ultrix4.2
- ;;
- m68*-apollo)
- os=-domain
- ;;
- i386-sun)
- os=-sunos4.0.2
- ;;
- m68000-sun)
- os=-sunos3
- # This also exists in the configure program, but was not the
- # default.
- # os=-sunos4
- ;;
- m68*-cisco)
- os=-aout
- ;;
- mep-*)
- os=-elf
- ;;
- mips*-cisco)
- os=-elf
- ;;
- mips*-*)
- os=-elf
- ;;
- or32-*)
- os=-coff
- ;;
- *-tti) # must be before sparc entry or we get the wrong os.
- os=-sysv3
- ;;
- sparc-* | *-sun)
- os=-sunos4.1.1
- ;;
- *-be)
- os=-beos
- ;;
- *-haiku)
- os=-haiku
- ;;
- *-ibm)
- os=-aix
- ;;
- *-knuth)
- os=-mmixware
- ;;
- *-wec)
- os=-proelf
- ;;
- *-winbond)
- os=-proelf
- ;;
- *-oki)
- os=-proelf
- ;;
- *-hp)
- os=-hpux
- ;;
- *-hitachi)
- os=-hiux
- ;;
- i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
- os=-sysv
- ;;
- *-cbm)
- os=-amigaos
- ;;
- *-dg)
- os=-dgux
- ;;
- *-dolphin)
- os=-sysv3
- ;;
- m68k-ccur)
- os=-rtu
- ;;
- m88k-omron*)
- os=-luna
- ;;
- *-next )
- os=-nextstep
- ;;
- *-sequent)
- os=-ptx
- ;;
- *-crds)
- os=-unos
- ;;
- *-ns)
- os=-genix
- ;;
- i370-*)
- os=-mvs
- ;;
- *-next)
- os=-nextstep3
- ;;
- *-gould)
- os=-sysv
- ;;
- *-highlevel)
- os=-bsd
- ;;
- *-encore)
- os=-bsd
- ;;
- *-sgi)
- os=-irix
- ;;
- *-siemens)
- os=-sysv4
- ;;
- *-masscomp)
- os=-rtu
- ;;
- f30[01]-fujitsu | f700-fujitsu)
- os=-uxpv
- ;;
- *-rom68k)
- os=-coff
- ;;
- *-*bug)
- os=-coff
- ;;
- *-apple)
- os=-macos
- ;;
- *-atari*)
- os=-mint
- ;;
- *)
- os=-none
- ;;
-esac
-fi
-
-# Here we handle the case where we know the os, and the CPU type, but not the
-# manufacturer. We pick the logical manufacturer.
-vendor=unknown
-case $basic_machine in
- *-unknown)
- case $os in
- -riscix*)
- vendor=acorn
- ;;
- -sunos*)
- vendor=sun
- ;;
- -aix*)
- vendor=ibm
- ;;
- -beos*)
- vendor=be
- ;;
- -hpux*)
- vendor=hp
- ;;
- -mpeix*)
- vendor=hp
- ;;
- -hiux*)
- vendor=hitachi
- ;;
- -unos*)
- vendor=crds
- ;;
- -dgux*)
- vendor=dg
- ;;
- -luna*)
- vendor=omron
- ;;
- -genix*)
- vendor=ns
- ;;
- -mvs* | -opened*)
- vendor=ibm
- ;;
- -os400*)
- vendor=ibm
- ;;
- -ptx*)
- vendor=sequent
- ;;
- -tpf*)
- vendor=ibm
- ;;
- -vxsim* | -vxworks* | -windiss*)
- vendor=wrs
- ;;
- -aux*)
- vendor=apple
- ;;
- -hms*)
- vendor=hitachi
- ;;
- -mpw* | -macos*)
- vendor=apple
- ;;
- -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
- vendor=atari
- ;;
- -vos*)
- vendor=stratus
- ;;
- esac
- basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
- ;;
-esac
-
-echo $basic_machine$os
-exit
-
-# Local variables:
-# eval: (add-hook 'write-file-hooks 'time-stamp)
-# time-stamp-start: "timestamp='"
-# time-stamp-format: "%:y-%02m-%02d"
-# time-stamp-end: "'"
-# End:
diff --git a/crawl-ref/source/util/pcre/configure b/crawl-ref/source/util/pcre/configure
deleted file mode 100644
index 1d0325f3c8..0000000000
--- a/crawl-ref/source/util/pcre/configure
+++ /dev/null
@@ -1,24388 +0,0 @@
-#! /bin/sh
-# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.61 for PCRE 7.7.
-#
-# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
-# 2002, 2003, 2004, 2005, 2006 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. ##
-## --------------------- ##
-
-# Be more Bourne compatible
-DUALCASE=1; export DUALCASE # for MKS sh
-if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
- emulate sh
- NULLCMD=:
- # Zsh 3.x and 4.x performs 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
-
-
-
-
-# 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
-
-# The user is always right.
-if test "${PATH_SEPARATOR+set}" != set; then
- echo "#! /bin/sh" >conf$$.sh
- echo "exit 0" >>conf$$.sh
- chmod +x conf$$.sh
- if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
- PATH_SEPARATOR=';'
- else
- PATH_SEPARATOR=:
- fi
- rm -f conf$$.sh
-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
-# there to prevent editors from complaining about space-tab.
-# (If _AS_PATH_WALK were called with IFS unset, it would disable word
-# splitting by setting IFS to empty value.)
-as_nl='
-'
-IFS=" "" $as_nl"
-
-# Find who we are. Look in the path if we contain no directory separator.
-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
-IFS=$as_save_IFS
-
- ;;
-esac
-# We did not find ourselves, most probably we were run as `sh COMMAND'
-# in which case we are not to be found in the path.
-if test "x$as_myself" = x; then
- as_myself=$0
-fi
-if test ! -f "$as_myself"; then
- echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
- { (exit 1); exit 1; }
-fi
-
-# 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='> '
-PS4='+ '
-
-# NLS nuisances.
-for as_var in \
- LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
- LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
- LC_TELEPHONE LC_TIME
-do
- if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
- eval $as_var=C; export $as_var
- else
- ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
- fi
-done
-
-# Required to use basename.
-if expr a : '\(a\)' >/dev/null 2>&1 &&
- test "X`expr 00001 : '.*\(...\)'`" = X001; then
- as_expr=expr
-else
- as_expr=false
-fi
-
-if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
- as_basename=basename
-else
- as_basename=false
-fi
-
-
-# Name of the executable.
-as_me=`$as_basename -- "$0" ||
-$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
- X"$0" : 'X\(//\)$' \| \
- X"$0" : 'X\(/\)' \| . 2>/dev/null ||
-echo X/"$0" |
- sed '/^.*\/\([^/][^/]*\)\/*$/{
- s//\1/
- q
- }
- /^X\/\(\/\/\)$/{
- s//\1/
- q
- }
- /^X\/\(\/\).*/{
- s//\1/
- q
- }
- s/.*/./; q'`
-
-# CDPATH.
-$as_unset CDPATH
-
-
-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=:
- # Zsh 3.x and 4.x performs 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=:
- # Zsh 3.x and 4.x performs 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 autoconf@gnu.org about your system,
- echo including any error possibly output before this
- echo message
-}
-
-
-
- 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" ||
- { 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
--n*)
- case `echo 'x\c'` in
- *c*) ECHO_T=' ';; # ECHO_T is single tab character.
- *) 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
- rm -f conf$$.dir/conf$$.file
-else
- rm -f conf$$.dir
- mkdir conf$$.dir
-fi
-echo >conf$$.file
-if ln -s conf$$.file conf$$ 2>/dev/null; then
- as_ln_s='ln -s'
- # ... but there are two gotchas:
- # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
- # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
- # In both cases, we have to default to `cp -p'.
- ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
- as_ln_s='cp -p'
-elif ln conf$$.file conf$$ 2>/dev/null; then
- as_ln_s=ln
-else
- as_ln_s='cp -p'
-fi
-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=:
-else
- test -d ./-p && rmdir ./-p
- as_mkdir_p=false
-fi
-
-if test -x / >/dev/null 2>&1; then
- as_test_x='test -x'
-else
- if ls -dL / >/dev/null 2>&1; then
- as_ls_L_option=L
- else
- as_ls_L_option=
- fi
- as_test_x='
- eval sh -c '\''
- if test -d "$1"; then
- test -d "$1/.";
- else
- case $1 in
- -*)set "./$1";;
- esac;
- case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in
- ???[sx]*):;;*)false;;esac;fi
- '\'' sh
- '
-fi
-as_executable_p=$as_test_x
-
-# Sed expression to map a string onto a valid CPP name.
-as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
-
-# Sed expression to map a string onto a valid variable name.
-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}
-
-case X$ECHO in
-X*--fallback-echo)
- # Remove one level of quotation (which was required for Make).
- ECHO=`echo "$ECHO" | sed 's,\\\\\$\\$0,'$0','`
- ;;
-esac
-
-echo=${ECHO-echo}
-if test "X$1" = X--no-reexec; then
- # Discard the --no-reexec flag, and continue.
- shift
-elif test "X$1" = X--fallback-echo; then
- # Avoid inline document here, it may be left over
- :
-elif test "X`($echo '\t') 2>/dev/null`" = 'X\t' ; then
- # Yippee, $echo works!
- :
-else
- # Restart under the correct shell.
- exec $SHELL "$0" --no-reexec ${1+"$@"}
-fi
-
-if test "X$1" = X--fallback-echo; then
- # used as fallback echo
- shift
- cat <<EOF
-$*
-EOF
- exit 0
-fi
-
-# The HP-UX ksh and POSIX shell print the target directory to stdout
-# if CDPATH is set.
-(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
-
-if test -z "$ECHO"; then
-if test "X${echo_test_string+set}" != Xset; then
-# find a string as large as possible, as long as the shell can cope with it
- for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do
- # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ...
- if (echo_test_string=`eval $cmd`) 2>/dev/null &&
- echo_test_string=`eval $cmd` &&
- (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null
- then
- break
- fi
- done
-fi
-
-if test "X`($echo '\t') 2>/dev/null`" = 'X\t' &&
- echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` &&
- test "X$echo_testing_string" = "X$echo_test_string"; then
- :
-else
- # The Solaris, AIX, and Digital Unix default echo programs unquote
- # backslashes. This makes it impossible to quote backslashes using
- # echo "$something" | sed 's/\\/\\\\/g'
- #
- # So, first we look for a working echo in the user's PATH.
-
- lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
- for dir in $PATH /usr/ucb; do
- IFS="$lt_save_ifs"
- if (test -f $dir/echo || test -f $dir/echo$ac_exeext) &&
- test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' &&
- echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` &&
- test "X$echo_testing_string" = "X$echo_test_string"; then
- echo="$dir/echo"
- break
- fi
- done
- IFS="$lt_save_ifs"
-
- if test "X$echo" = Xecho; then
- # We didn't find a better echo, so look for alternatives.
- if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' &&
- echo_testing_string=`(print -r "$echo_test_string") 2>/dev/null` &&
- test "X$echo_testing_string" = "X$echo_test_string"; then
- # This shell has a builtin print -r that does the trick.
- echo='print -r'
- elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) &&
- test "X$CONFIG_SHELL" != X/bin/ksh; then
- # If we have ksh, try running configure again with it.
- ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
- export ORIGINAL_CONFIG_SHELL
- CONFIG_SHELL=/bin/ksh
- export CONFIG_SHELL
- exec $CONFIG_SHELL "$0" --no-reexec ${1+"$@"}
- else
- # Try using printf.
- echo='printf %s\n'
- if test "X`($echo '\t') 2>/dev/null`" = 'X\t' &&
- echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` &&
- test "X$echo_testing_string" = "X$echo_test_string"; then
- # Cool, printf works
- :
- elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` &&
- test "X$echo_testing_string" = 'X\t' &&
- echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
- test "X$echo_testing_string" = "X$echo_test_string"; then
- CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL
- export CONFIG_SHELL
- SHELL="$CONFIG_SHELL"
- export SHELL
- echo="$CONFIG_SHELL $0 --fallback-echo"
- elif echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` &&
- test "X$echo_testing_string" = 'X\t' &&
- echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
- test "X$echo_testing_string" = "X$echo_test_string"; then
- echo="$CONFIG_SHELL $0 --fallback-echo"
- else
- # maybe with a smaller string...
- prev=:
-
- for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do
- if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null
- then
- break
- fi
- prev="$cmd"
- done
-
- if test "$prev" != 'sed 50q "$0"'; then
- echo_test_string=`eval $prev`
- export echo_test_string
- exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "$0" ${1+"$@"}
- else
- # Oops. We lost completely, so just stick with echo.
- echo=echo
- fi
- fi
- fi
- fi
-fi
-fi
-
-# Copy echo and quote the copy suitably for passing to libtool from
-# the Makefile, instead of quoting the original, which is used later.
-ECHO=$echo
-if test "X$ECHO" = "X$CONFIG_SHELL $0 --fallback-echo"; then
- ECHO="$CONFIG_SHELL \\\$\$0 --fallback-echo"
-fi
-
-
-
-
-tagnames=${tagnames+${tagnames},}CXX
-
-tagnames=${tagnames+${tagnames},}F77
-
-exec 7<&0 </dev/null 6>&1
-
-# Name of the host.
-# 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`
-
-#
-# Initializations.
-#
-ac_default_prefix=/usr/local
-ac_clean_files=
-ac_config_libobj_dir=.
-LIBOBJS=
-cross_compiling=no
-subdirs=
-MFLAGS=
-MAKEFLAGS=
-SHELL=${CONFIG_SHELL-/bin/sh}
-
-# Identity of this package.
-PACKAGE_NAME='PCRE'
-PACKAGE_TARNAME='pcre'
-PACKAGE_VERSION='7.7'
-PACKAGE_STRING='PCRE 7.7'
-PACKAGE_BUGREPORT=''
-
-ac_unique_file="pcre.h.in"
-# Factoring default headers for most tests.
-ac_includes_default="\
-#include <stdio.h>
-#ifdef HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-#ifdef HAVE_SYS_STAT_H
-# include <sys/stat.h>
-#endif
-#ifdef STDC_HEADERS
-# include <stdlib.h>
-# include <stddef.h>
-#else
-# ifdef HAVE_STDLIB_H
-# include <stdlib.h>
-# endif
-#endif
-#ifdef HAVE_STRING_H
-# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
-# include <memory.h>
-# endif
-# include <string.h>
-#endif
-#ifdef HAVE_STRINGS_H
-# include <strings.h>
-#endif
-#ifdef HAVE_INTTYPES_H
-# include <inttypes.h>
-#endif
-#ifdef HAVE_STDINT_H
-# include <stdint.h>
-#endif
-#ifdef HAVE_UNISTD_H
-# include <unistd.h>
-#endif"
-
-ac_subst_vars='SHELL
-PATH_SEPARATOR
-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
-INSTALL_PROGRAM
-INSTALL_SCRIPT
-INSTALL_DATA
-am__isrc
-CYGPATH_W
-PACKAGE
-VERSION
-ACLOCAL
-AUTOCONF
-AUTOMAKE
-AUTOHEADER
-MAKEINFO
-install_sh
-STRIP
-INSTALL_STRIP_PROGRAM
-mkdir_p
-AWK
-SET_MAKE
-am__leading_dot
-AMTAR
-am__tar
-am__untar
-CC
-CFLAGS
-LDFLAGS
-CPPFLAGS
-ac_ct_CC
-EXEEXT
-OBJEXT
-DEPDIR
-am__include
-am__quote
-AMDEP_TRUE
-AMDEP_FALSE
-AMDEPBACKSLASH
-CCDEPMODE
-am__fastdepCC_TRUE
-am__fastdepCC_FALSE
-CXX
-CXXFLAGS
-ac_ct_CXX
-CXXDEPMODE
-am__fastdepCXX_TRUE
-am__fastdepCXX_FALSE
-build
-build_cpu
-build_vendor
-build_os
-host
-host_cpu
-host_vendor
-host_os
-SED
-GREP
-EGREP
-LN_S
-ECHO
-AR
-RANLIB
-DSYMUTIL
-NMEDIT
-DLLTOOL
-AS
-OBJDUMP
-CPP
-CXXCPP
-F77
-FFLAGS
-ac_ct_F77
-LIBTOOL
-PCRE_MAJOR
-PCRE_MINOR
-PCRE_PRERELEASE
-PCRE_DATE
-pcre_have_type_traits
-pcre_have_bits_type_traits
-WITH_PCRE_CPP_TRUE
-WITH_PCRE_CPP_FALSE
-WITH_REBUILD_CHARTABLES_TRUE
-WITH_REBUILD_CHARTABLES_FALSE
-pcre_have_long_long
-pcre_have_ulong_long
-EXTRA_LIBPCRE_LDFLAGS
-EXTRA_LIBPCREPOSIX_LDFLAGS
-EXTRA_LIBPCRECPP_LDFLAGS
-DISTCHECK_CONFIGURE_FLAGS
-LIBOBJS
-LTLIBOBJS'
-ac_subst_files=''
- ac_precious_vars='build_alias
-host_alias
-target_alias
-CC
-CFLAGS
-LDFLAGS
-LIBS
-CPPFLAGS
-CXX
-CXXFLAGS
-CCC
-CPP
-CXXCPP
-F77
-FFLAGS'
-
-
-# Initialize some variables set by options.
-ac_init_help=
-ac_init_version=false
-# The variables have the same names as the options, with
-# dashes changed to underlines.
-cache_file=/dev/null
-exec_prefix=NONE
-no_create=
-no_recursion=
-prefix=NONE
-program_prefix=NONE
-program_suffix=NONE
-program_transform_name=s,x,x,
-silent=
-site=
-srcdir=
-verbose=
-x_includes=NONE
-x_libraries=NONE
-
-# Installation directory options.
-# These are left unexpanded so users can "make install exec_prefix=/foo"
-# and all the variables that are supposed to be based on exec_prefix
-# by default will actually change.
-# Use braces instead of parens because sh, perl, etc. also accept them.
-# (The list follows the same order as the GNU Coding Standards.)
-bindir='${exec_prefix}/bin'
-sbindir='${exec_prefix}/sbin'
-libexecdir='${exec_prefix}/libexec'
-datarootdir='${prefix}/share'
-datadir='${datarootdir}'
-sysconfdir='${prefix}/etc'
-sharedstatedir='${prefix}/com'
-localstatedir='${prefix}/var'
-includedir='${prefix}/include'
-oldincludedir='/usr/include'
-docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
-infodir='${datarootdir}/info'
-htmldir='${docdir}'
-dvidir='${docdir}'
-pdfdir='${docdir}'
-psdir='${docdir}'
-libdir='${exec_prefix}/lib'
-localedir='${datarootdir}/locale'
-mandir='${datarootdir}/man'
-
-ac_prev=
-ac_dashdash=
-for ac_option
-do
- # If the previous option needs an argument, assign it.
- if test -n "$ac_prev"; then
- eval $ac_prev=\$ac_option
- ac_prev=
- continue
- fi
-
- case $ac_option in
- *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
- *) ac_optarg=yes ;;
- esac
-
- # Accept the important Cygnus configure options, so we can diagnose typos.
-
- case $ac_dashdash$ac_option in
- --)
- ac_dashdash=yes ;;
-
- -bindir | --bindir | --bindi | --bind | --bin | --bi)
- ac_prev=bindir ;;
- -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
- bindir=$ac_optarg ;;
-
- -build | --build | --buil | --bui | --bu)
- ac_prev=build_alias ;;
- -build=* | --build=* | --buil=* | --bui=* | --bu=*)
- build_alias=$ac_optarg ;;
-
- -cache-file | --cache-file | --cache-fil | --cache-fi \
- | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
- ac_prev=cache_file ;;
- -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
- | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
- cache_file=$ac_optarg ;;
-
- --config-cache | -C)
- cache_file=config.cache ;;
-
- -datadir | --datadir | --datadi | --datad)
- ac_prev=datadir ;;
- -datadir=* | --datadir=* | --datadi=* | --datad=*)
- datadir=$ac_optarg ;;
-
- -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
- | --dataroo | --dataro | --datar)
- ac_prev=datarootdir ;;
- -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
- | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
- datarootdir=$ac_optarg ;;
-
- -disable-* | --disable-*)
- ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
- # Reject names that are not valid shell variable names.
- expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null &&
- { echo "$as_me: error: invalid feature name: $ac_feature" >&2
- { (exit 1); exit 1; }; }
- ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'`
- eval enable_$ac_feature=no ;;
-
- -docdir | --docdir | --docdi | --doc | --do)
- ac_prev=docdir ;;
- -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
- docdir=$ac_optarg ;;
-
- -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
- ac_prev=dvidir ;;
- -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
- dvidir=$ac_optarg ;;
-
- -enable-* | --enable-*)
- ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
- # Reject names that are not valid shell variable names.
- expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null &&
- { echo "$as_me: error: invalid feature name: $ac_feature" >&2
- { (exit 1); exit 1; }; }
- ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'`
- eval enable_$ac_feature=\$ac_optarg ;;
-
- -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
- | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
- | --exec | --exe | --ex)
- ac_prev=exec_prefix ;;
- -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
- | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
- | --exec=* | --exe=* | --ex=*)
- exec_prefix=$ac_optarg ;;
-
- -gas | --gas | --ga | --g)
- # Obsolete; use --with-gas.
- with_gas=yes ;;
-
- -help | --help | --hel | --he | -h)
- ac_init_help=long ;;
- -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
- ac_init_help=recursive ;;
- -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
- ac_init_help=short ;;
-
- -host | --host | --hos | --ho)
- ac_prev=host_alias ;;
- -host=* | --host=* | --hos=* | --ho=*)
- host_alias=$ac_optarg ;;
-
- -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
- ac_prev=htmldir ;;
- -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
- | --ht=*)
- htmldir=$ac_optarg ;;
-
- -includedir | --includedir | --includedi | --included | --include \
- | --includ | --inclu | --incl | --inc)
- ac_prev=includedir ;;
- -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
- | --includ=* | --inclu=* | --incl=* | --inc=*)
- includedir=$ac_optarg ;;
-
- -infodir | --infodir | --infodi | --infod | --info | --inf)
- ac_prev=infodir ;;
- -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
- infodir=$ac_optarg ;;
-
- -libdir | --libdir | --libdi | --libd)
- ac_prev=libdir ;;
- -libdir=* | --libdir=* | --libdi=* | --libd=*)
- libdir=$ac_optarg ;;
-
- -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
- | --libexe | --libex | --libe)
- ac_prev=libexecdir ;;
- -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
- | --libexe=* | --libex=* | --libe=*)
- libexecdir=$ac_optarg ;;
-
- -localedir | --localedir | --localedi | --localed | --locale)
- ac_prev=localedir ;;
- -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
- localedir=$ac_optarg ;;
-
- -localstatedir | --localstatedir | --localstatedi | --localstated \
- | --localstate | --localstat | --localsta | --localst | --locals)
- ac_prev=localstatedir ;;
- -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
- | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)
- localstatedir=$ac_optarg ;;
-
- -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
- ac_prev=mandir ;;
- -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
- mandir=$ac_optarg ;;
-
- -nfp | --nfp | --nf)
- # Obsolete; use --without-fp.
- with_fp=no ;;
-
- -no-create | --no-create | --no-creat | --no-crea | --no-cre \
- | --no-cr | --no-c | -n)
- no_create=yes ;;
-
- -no-recursion | --no-recursion | --no-recursio | --no-recursi \
- | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
- no_recursion=yes ;;
-
- -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
- | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
- | --oldin | --oldi | --old | --ol | --o)
- ac_prev=oldincludedir ;;
- -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
- | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
- | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
- oldincludedir=$ac_optarg ;;
-
- -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
- ac_prev=prefix ;;
- -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
- prefix=$ac_optarg ;;
-
- -program-prefix | --program-prefix | --program-prefi | --program-pref \
- | --program-pre | --program-pr | --program-p)
- ac_prev=program_prefix ;;
- -program-prefix=* | --program-prefix=* | --program-prefi=* \
- | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
- program_prefix=$ac_optarg ;;
-
- -program-suffix | --program-suffix | --program-suffi | --program-suff \
- | --program-suf | --program-su | --program-s)
- ac_prev=program_suffix ;;
- -program-suffix=* | --program-suffix=* | --program-suffi=* \
- | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
- program_suffix=$ac_optarg ;;
-
- -program-transform-name | --program-transform-name \
- | --program-transform-nam | --program-transform-na \
- | --program-transform-n | --program-transform- \
- | --program-transform | --program-transfor \
- | --program-transfo | --program-transf \
- | --program-trans | --program-tran \
- | --progr-tra | --program-tr | --program-t)
- ac_prev=program_transform_name ;;
- -program-transform-name=* | --program-transform-name=* \
- | --program-transform-nam=* | --program-transform-na=* \
- | --program-transform-n=* | --program-transform-=* \
- | --program-transform=* | --program-transfor=* \
- | --program-transfo=* | --program-transf=* \
- | --program-trans=* | --program-tran=* \
- | --progr-tra=* | --program-tr=* | --program-t=*)
- program_transform_name=$ac_optarg ;;
-
- -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
- ac_prev=pdfdir ;;
- -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
- pdfdir=$ac_optarg ;;
-
- -psdir | --psdir | --psdi | --psd | --ps)
- ac_prev=psdir ;;
- -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
- psdir=$ac_optarg ;;
-
- -q | -quiet | --quiet | --quie | --qui | --qu | --q \
- | -silent | --silent | --silen | --sile | --sil)
- silent=yes ;;
-
- -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
- ac_prev=sbindir ;;
- -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
- | --sbi=* | --sb=*)
- sbindir=$ac_optarg ;;
-
- -sharedstatedir | --sharedstatedir | --sharedstatedi \
- | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
- | --sharedst | --shareds | --shared | --share | --shar \
- | --sha | --sh)
- ac_prev=sharedstatedir ;;
- -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
- | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
- | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
- | --sha=* | --sh=*)
- sharedstatedir=$ac_optarg ;;
-
- -site | --site | --sit)
- ac_prev=site ;;
- -site=* | --site=* | --sit=*)
- site=$ac_optarg ;;
-
- -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
- ac_prev=srcdir ;;
- -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
- srcdir=$ac_optarg ;;
-
- -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
- | --syscon | --sysco | --sysc | --sys | --sy)
- ac_prev=sysconfdir ;;
- -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
- | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
- sysconfdir=$ac_optarg ;;
-
- -target | --target | --targe | --targ | --tar | --ta | --t)
- ac_prev=target_alias ;;
- -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
- target_alias=$ac_optarg ;;
-
- -v | -verbose | --verbose | --verbos | --verbo | --verb)
- verbose=yes ;;
-
- -version | --version | --versio | --versi | --vers | -V)
- ac_init_version=: ;;
-
- -with-* | --with-*)
- ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
- # Reject names that are not valid shell variable names.
- expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null &&
- { echo "$as_me: error: invalid package name: $ac_package" >&2
- { (exit 1); exit 1; }; }
- ac_package=`echo $ac_package | sed 's/[-.]/_/g'`
- eval with_$ac_package=\$ac_optarg ;;
-
- -without-* | --without-*)
- ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'`
- # Reject names that are not valid shell variable names.
- expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null &&
- { echo "$as_me: error: invalid package name: $ac_package" >&2
- { (exit 1); exit 1; }; }
- ac_package=`echo $ac_package | sed 's/[-.]/_/g'`
- eval with_$ac_package=no ;;
-
- --x)
- # Obsolete; use --with-x.
- with_x=yes ;;
-
- -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
- | --x-incl | --x-inc | --x-in | --x-i)
- ac_prev=x_includes ;;
- -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
- | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
- x_includes=$ac_optarg ;;
-
- -x-libraries | --x-libraries | --x-librarie | --x-librari \
- | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
- ac_prev=x_libraries ;;
- -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
- | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
- x_libraries=$ac_optarg ;;
-
- -*) { 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.
- expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null &&
- { echo "$as_me: error: invalid variable name: $ac_envvar" >&2
- { (exit 1); exit 1; }; }
- eval $ac_envvar=\$ac_optarg
- export $ac_envvar ;;
-
- *)
- # FIXME: should be removed in autoconf 3.0.
- echo "$as_me: WARNING: you should use --build, --host, --target" >&2
- expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
- echo "$as_me: WARNING: invalid host type: $ac_option" >&2
- : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
- ;;
-
- esac
-done
-
-if test -n "$ac_prev"; then
- ac_option=--`echo $ac_prev | sed 's/_/-/g'`
- { echo "$as_me: error: missing argument to $ac_option" >&2
- { (exit 1); exit 1; }; }
-fi
-
-# Be sure to have absolute directory names.
-for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
- datadir sysconfdir sharedstatedir localstatedir includedir \
- oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
- libdir localedir mandir
-do
- eval ac_val=\$$ac_var
- case $ac_val in
- [\\/$]* | ?:[\\/]* ) continue;;
- NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
- esac
- { 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'
-# used to hold the argument of --host etc.
-# FIXME: To remove some day.
-build=$build_alias
-host=$host_alias
-target=$target_alias
-
-# FIXME: To remove some day.
-if test "x$host_alias" != x; then
- if test "x$build_alias" = x; then
- cross_compiling=maybe
- 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
-fi
-
-ac_tool_prefix=
-test -n "$host_alias" && ac_tool_prefix=$host_alias-
-
-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 .` ||
- { echo "$as_me: error: Working directory cannot be determined" >&2
- { (exit 1); exit 1; }; }
-test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
- { 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.
-if test -z "$srcdir"; then
- ac_srcdir_defaulted=yes
- # Try the directory containing this script, then the parent directory.
- ac_confdir=`$as_dirname -- "$0" ||
-$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
- X"$0" : 'X\(//\)[^/]' \| \
- X"$0" : 'X\(//\)$' \| \
- X"$0" : 'X\(/\)' \| . 2>/dev/null ||
-echo X"$0" |
- sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
- s//\1/
- q
- }
- /^X\(\/\/\)[^/].*/{
- s//\1/
- q
- }
- /^X\(\/\/\)$/{
- s//\1/
- q
- }
- /^X\(\/\).*/{
- s//\1/
- q
- }
- s/.*/./; q'`
- srcdir=$ac_confdir
- if test ! -r "$srcdir/$ac_unique_file"; then
- srcdir=..
- fi
-else
- ac_srcdir_defaulted=no
-fi
-if test ! -r "$srcdir/$ac_unique_file"; then
- test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
- { 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" || { 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
- srcdir=.
-fi
-# Remove unnecessary trailing slashes from srcdir.
-# Double slashes in file names in object file debugging info
-# mess up M-x gdb in Emacs.
-case $srcdir in
-*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;
-esac
-for ac_var in $ac_precious_vars; do
- eval ac_env_${ac_var}_set=\${${ac_var}+set}
- eval ac_env_${ac_var}_value=\$${ac_var}
- eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
- eval ac_cv_env_${ac_var}_value=\$${ac_var}
-done
-
-#
-# Report the --help message.
-#
-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 PCRE 7.7 to adapt to many kinds of systems.
-
-Usage: $0 [OPTION]... [VAR=VALUE]...
-
-To assign environment variables (e.g., CC, CFLAGS...), specify them as
-VAR=VALUE. See below for descriptions of some of the useful variables.
-
-Defaults for the options are specified in brackets.
-
-Configuration:
- -h, --help display this help and exit
- --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
- --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
- --srcdir=DIR find the sources in DIR [configure dir or \`..']
-
-Installation directories:
- --prefix=PREFIX install architecture-independent files in PREFIX
- [$ac_default_prefix]
- --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
- [PREFIX]
-
-By default, \`make install' will install all the files in
-\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify
-an installation prefix other than \`$ac_default_prefix' using \`--prefix',
-for instance \`--prefix=\$HOME'.
-
-For better control, use the options below.
-
-Fine tuning of the installation directories:
- --bindir=DIR user executables [EPREFIX/bin]
- --sbindir=DIR system admin executables [EPREFIX/sbin]
- --libexecdir=DIR program executables [EPREFIX/libexec]
- --sysconfdir=DIR read-only single-machine data [PREFIX/etc]
- --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
- --localstatedir=DIR modifiable single-machine data [PREFIX/var]
- --libdir=DIR object code libraries [EPREFIX/lib]
- --includedir=DIR C header files [PREFIX/include]
- --oldincludedir=DIR C header files for non-gcc [/usr/include]
- --datarootdir=DIR read-only arch.-independent data root [PREFIX/share]
- --datadir=DIR read-only architecture-independent data [DATAROOTDIR]
- --infodir=DIR info documentation [DATAROOTDIR/info]
- --localedir=DIR locale-dependent data [DATAROOTDIR/locale]
- --mandir=DIR man documentation [DATAROOTDIR/man]
- --docdir=DIR documentation root [DATAROOTDIR/doc/pcre]
- --htmldir=DIR html documentation [DOCDIR]
- --dvidir=DIR dvi documentation [DOCDIR]
- --pdfdir=DIR pdf documentation [DOCDIR]
- --psdir=DIR ps documentation [DOCDIR]
-_ACEOF
-
- cat <<\_ACEOF
-
-Program names:
- --program-prefix=PREFIX prepend PREFIX to installed program names
- --program-suffix=SUFFIX append SUFFIX to installed program names
- --program-transform-name=PROGRAM run sed PROGRAM on installed program names
-
-System types:
- --build=BUILD configure for building on BUILD [guessed]
- --host=HOST cross-compile to build programs to run on HOST [BUILD]
-_ACEOF
-fi
-
-if test -n "$ac_init_help"; then
- case $ac_init_help in
- short | recursive ) echo "Configuration of PCRE 7.7:";;
- esac
- cat <<\_ACEOF
-
-Optional Features:
- --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
- --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
- --disable-dependency-tracking speeds up one-time build
- --enable-dependency-tracking do not reject slow dependency extractors
- --enable-shared[=PKGS] build shared libraries [default=yes]
- --enable-static[=PKGS] build static libraries [default=yes]
- --enable-fast-install[=PKGS]
- optimize for fast installation [default=yes]
- --disable-libtool-lock avoid locking (might break parallel builds)
- --disable-cpp disable C++ support
- --enable-rebuild-chartables
- rebuild character tables in current locale
- --enable-utf8 enable UTF-8 support
- --enable-unicode-properties
- enable Unicode properties support (implies
- --enable-utf8)
- --enable-newline-is-cr use CR as newline character
- --enable-newline-is-lf use LF as newline character (default)
- --enable-newline-is-crlf
- use CRLF as newline sequence
- --enable-newline-is-anycrlf
- use CR, LF, or CRLF as newline sequence
- --enable-newline-is-any use any valid Unicode newline sequence
- --enable-bsr-anycrlf \R matches only CR, LF, CRLF by default
- --enable-ebcdic assume EBCDIC coding rather than ASCII; use this
- only in (uncommon) EBCDIC environments; it implies
- --enable-rebuild-chartables
- --disable-stack-for-recursion
- don't use stack recursion when matching
- --enable-pcregrep-libz link pcregrep with libz to handle .gz files
- --enable-pcregrep-libbz2
- link pcregrep with libbz2 to handle .bz2 files
- --enable-pcretest-libreadline
- link pcretest with libreadline
-
-Optional Packages:
- --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
- --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
- --with-gnu-ld assume the C compiler uses GNU ld [default=no]
- --with-pic try to use only PIC/non-PIC objects [default=use
- both]
- --with-tags[=TAGS] include additional configurations [automatic]
- --with-posix-malloc-threshold=NBYTES
- threshold for POSIX malloc usage (default=10)
- --with-link-size=N internal link size (2, 3, or 4 allowed; default=2)
- --with-match-limit=N default limit on internal looping (default=10000000)
- --with-match-limit-recursion=N
- default limit on internal recursion
- (default=MATCH_LIMIT)
-
-Some influential environment variables:
- CC C compiler command
- CFLAGS C compiler flags
- LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a
- nonstandard directory <lib dir>
- LIBS libraries to pass to the linker, e.g. -l<library>
- CPPFLAGS C/C++/Objective C preprocessor flags, e.g. -I<include dir> if
- you have headers in a nonstandard directory <include dir>
- CXX C++ compiler command
- CXXFLAGS C++ compiler flags
- CPP C preprocessor
- CXXCPP C++ preprocessor
- F77 Fortran 77 compiler command
- FFLAGS Fortran 77 compiler flags
-
-Use these variables to override the choices made by `configure' or to help
-it to find libraries and programs with nonstandard names/locations.
-
-_ACEOF
-ac_status=$?
-fi
-
-if test "$ac_init_help" = "recursive"; then
- # If there are subdirs, report their specific --help.
- for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
- test -d "$ac_dir" || continue
- ac_builddir=.
-
-case "$ac_dir" in
-.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
-*)
- ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
- # A ".." for each directory in $ac_dir_suffix.
- ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'`
- case $ac_top_builddir_sub in
- "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
- *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
- esac ;;
-esac
-ac_abs_top_builddir=$ac_pwd
-ac_abs_builddir=$ac_pwd$ac_dir_suffix
-# for backward compatibility:
-ac_top_builddir=$ac_top_build_prefix
-
-case $srcdir in
- .) # We are building in place.
- ac_srcdir=.
- ac_top_srcdir=$ac_top_builddir_sub
- ac_abs_top_srcdir=$ac_pwd ;;
- [\\/]* | ?:[\\/]* ) # Absolute name.
- ac_srcdir=$srcdir$ac_dir_suffix;
- ac_top_srcdir=$srcdir
- ac_abs_top_srcdir=$srcdir ;;
- *) # Relative name.
- ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
- ac_top_srcdir=$ac_top_build_prefix$srcdir
- ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
-esac
-ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
-
- cd "$ac_dir" || { ac_status=$?; continue; }
- # Check for guested configure.
- if test -f "$ac_srcdir/configure.gnu"; then
- echo &&
- $SHELL "$ac_srcdir/configure.gnu" --help=recursive
- elif test -f "$ac_srcdir/configure"; then
- echo &&
- $SHELL "$ac_srcdir/configure" --help=recursive
- else
- echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
- fi || ac_status=$?
- cd "$ac_pwd" || { ac_status=$?; break; }
- done
-fi
-
-test -n "$ac_init_help" && exit $ac_status
-if $ac_init_version; then
- cat <<\_ACEOF
-PCRE configure 7.7
-generated by GNU Autoconf 2.61
-
-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
-2002, 2003, 2004, 2005, 2006 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
-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 PCRE $as_me 7.7, which was
-generated by GNU Autoconf 2.61. Invocation command line was
-
- $ $0 $@
-
-_ACEOF
-exec 5>>config.log
-{
-cat <<_ASUNAME
-## --------- ##
-## Platform. ##
-## --------- ##
-
-hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
-uname -m = `(uname -m) 2>/dev/null || echo unknown`
-uname -r = `(uname -r) 2>/dev/null || echo unknown`
-uname -s = `(uname -s) 2>/dev/null || echo unknown`
-uname -v = `(uname -v) 2>/dev/null || echo unknown`
-
-/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
-/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown`
-
-/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown`
-/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown`
-/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
-/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown`
-/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown`
-/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown`
-/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown`
-
-_ASUNAME
-
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- echo "PATH: $as_dir"
-done
-IFS=$as_save_IFS
-
-} >&5
-
-cat >&5 <<_ACEOF
-
-
-## ----------- ##
-## Core tests. ##
-## ----------- ##
-
-_ACEOF
-
-
-# Keep a trace of the command line.
-# Strip out --no-create and --no-recursion so they do not pile up.
-# Strip out --silent because we don't want to record it for future runs.
-# Also quote any args containing shell meta-characters.
-# Make two passes to allow for proper duplicate-argument suppression.
-ac_configure_args=
-ac_configure_args0=
-ac_configure_args1=
-ac_must_keep_next=false
-for ac_pass in 1 2
-do
- for ac_arg
- do
- case $ac_arg in
- -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
- -q | -quiet | --quiet | --quie | --qui | --qu | --q \
- | -silent | --silent | --silen | --sile | --sil)
- continue ;;
- *\'*)
- ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
- esac
- case $ac_pass in
- 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;;
- 2)
- 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
- case $ac_arg in
- *=* | --config-cache | -C | -disable-* | --disable-* \
- | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
- | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
- | -with-* | --with-* | -without-* | --without-* | --x)
- case "$ac_configure_args0 " in
- "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
- esac
- ;;
- -* ) ac_must_keep_next=true ;;
- esac
- fi
- ac_configure_args="$ac_configure_args '$ac_arg'"
- ;;
- esac
- done
-done
-$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
-# would cause problems or look ugly.
-# WARNING: Use '\'' to represent an apostrophe within the trap.
-# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
-trap 'exit_status=$?
- # Save into config.log some information that might help in debugging.
- {
- echo
-
- cat <<\_ASBOX
-## ---------------- ##
-## Cache variables. ##
-## ---------------- ##
-_ASBOX
- echo
- # The following way of writing the cache mishandles newlines in values,
-(
- for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
- eval ac_val=\$$ac_var
- case $ac_val in #(
- *${as_nl}*)
- case $ac_var in #(
- *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5
-echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;;
- esac
- case $ac_var in #(
- _ | IFS | as_nl) ;; #(
- *) $as_unset $ac_var ;;
- esac ;;
- esac
- done
- (set) 2>&1 |
- case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
- *${as_nl}ac_space=\ *)
- sed -n \
- "s/'\''/'\''\\\\'\'''\''/g;
- s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
- ;; #(
- *)
- sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
- ;;
- esac |
- sort
-)
- echo
-
- cat <<\_ASBOX
-## ----------------- ##
-## Output variables. ##
-## ----------------- ##
-_ASBOX
- echo
- for ac_var in $ac_subst_vars
- do
- eval ac_val=\$$ac_var
- case $ac_val in
- *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
- esac
- echo "$ac_var='\''$ac_val'\''"
- done | sort
- echo
-
- if test -n "$ac_subst_files"; then
- cat <<\_ASBOX
-## ------------------- ##
-## File substitutions. ##
-## ------------------- ##
-_ASBOX
- echo
- for ac_var in $ac_subst_files
- do
- eval ac_val=\$$ac_var
- case $ac_val in
- *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
- esac
- echo "$ac_var='\''$ac_val'\''"
- done | sort
- echo
- fi
-
- if test -s confdefs.h; then
- cat <<\_ASBOX
-## ----------- ##
-## confdefs.h. ##
-## ----------- ##
-_ASBOX
- echo
- cat confdefs.h
- echo
- fi
- test "$ac_signal" != 0 &&
- echo "$as_me: caught signal $ac_signal"
- echo "$as_me: exit $exit_status"
- } >&5
- rm -f core *.core core.conftest.* &&
- rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
- exit $exit_status
-' 0
-for ac_signal in 1 2 13 15; do
- 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
-
-# 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
-
-
-# Let the site file select an alternate cache file if it wants to.
-# Prefer explicitly selected file to automatically selected ones.
-if test -n "$CONFIG_SITE"; then
- set x "$CONFIG_SITE"
-elif test "x$prefix" != xNONE; then
- set x "$prefix/share/config.site" "$prefix/etc/config.site"
-else
- set x "$ac_default_prefix/share/config.site" \
- "$ac_default_prefix/etc/config.site"
-fi
-shift
-for ac_site_file
-do
- if test -r "$ac_site_file"; then
- { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5
-echo "$as_me: loading site script $ac_site_file" >&6;}
- sed 's/^/| /' "$ac_site_file" >&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.
- if test -f "$cache_file"; then
- { echo "$as_me:$LINENO: loading cache $cache_file" >&5
-echo "$as_me: loading cache $cache_file" >&6;}
- case $cache_file in
- [\\/]* | ?:[\\/]* ) . "$cache_file";;
- *) . "./$cache_file";;
- esac
- fi
-else
- { echo "$as_me:$LINENO: creating cache $cache_file" >&5
-echo "$as_me: creating cache $cache_file" >&6;}
- >$cache_file
-fi
-
-# Check that the precious variables saved in the cache have kept the same
-# value.
-ac_cache_corrupted=false
-for ac_var in $ac_precious_vars; do
- eval ac_old_set=\$ac_cv_env_${ac_var}_set
- eval ac_new_set=\$ac_env_${ac_var}_set
- eval ac_old_val=\$ac_cv_env_${ac_var}_value
- eval ac_new_val=\$ac_env_${ac_var}_value
- case $ac_old_set,$ac_new_set in
- set,)
- { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
-echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
- ac_cache_corrupted=: ;;
- ,set)
- { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5
-echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
- ac_cache_corrupted=: ;;
- ,);;
- *)
- if test "x$ac_old_val" != "x$ac_new_val"; then
- { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5
-echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
- { echo "$as_me:$LINENO: former value: $ac_old_val" >&5
-echo "$as_me: former value: $ac_old_val" >&2;}
- { echo "$as_me:$LINENO: current value: $ac_new_val" >&5
-echo "$as_me: current value: $ac_new_val" >&2;}
- ac_cache_corrupted=:
- fi;;
- esac
- # Pass precious variables to config.status.
- if test "$ac_new_set" = set; then
- case $ac_new_val in
- *\'*) ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
- *) ac_arg=$ac_var=$ac_new_val ;;
- esac
- case " $ac_configure_args " in
- *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy.
- *) ac_configure_args="$ac_configure_args '$ac_arg'" ;;
- esac
- fi
-done
-if $ac_cache_corrupted; then
- { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5
-echo "$as_me: error: changes in the environment can compromise the build" >&2;}
- { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5
-echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;}
- { (exit 1); exit 1; }; }
-fi
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-ac_ext=c
-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
-
-
-
-am__api_version='1.10'
-
-ac_aux_dir=
-for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do
- if test -f "$ac_dir/install-sh"; then
- ac_aux_dir=$ac_dir
- ac_install_sh="$ac_aux_dir/install-sh -c"
- break
- elif test -f "$ac_dir/install.sh"; then
- ac_aux_dir=$ac_dir
- ac_install_sh="$ac_aux_dir/install.sh -c"
- break
- elif test -f "$ac_dir/shtool"; then
- ac_aux_dir=$ac_dir
- ac_install_sh="$ac_aux_dir/shtool install -c"
- break
- fi
-done
-if test -z "$ac_aux_dir"; then
- { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&5
-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,
-# and are intended to be withdrawn in a future Autoconf release.
-# They can cause serious problems if a builder's source tree is in a directory
-# whose full name contains unusual characters.
-ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var.
-ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var.
-ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var.
-
-
-# Find a good install program. We prefer a C program (faster),
-# so one script is as good as another. But avoid the broken or
-# incompatible versions:
-# SysV /etc/install, /usr/sbin/install
-# SunOS /usr/etc/install
-# IRIX /sbin/install
-# AIX /bin/install
-# AmigaOS /C/install, which installs bootblocks on floppy discs
-# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
-# AFS /usr/afsws/bin/install, which mishandles nonexistent args
-# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
-# OS/2's system install, which has a completely different semantic
-# ./install, which can be erroneously created by make from ./install.sh.
-{ echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5
-echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6; }
-if test -z "$INSTALL"; then
-if test "${ac_cv_path_install+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-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/* | \
- /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
- ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \
- /usr/ucb/* ) ;;
- *)
- # OSF1 and SCO ODT 3.0 have their own names for install.
- # Don't use installbsd from OSF since it installs stuff as root
- # by default.
- for ac_prog in ginstall scoinst install; do
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then
- if test $ac_prog = install &&
- grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
- # AIX install. It has an incompatible calling convention.
- :
- elif test $ac_prog = install &&
- grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
- # program-specific install script used by HP pwplus--don't use.
- :
- else
- ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
- break 3
- fi
- fi
- done
- done
- ;;
-esac
-done
-IFS=$as_save_IFS
-
-
-fi
- if test "${ac_cv_path_install+set}" = set; then
- INSTALL=$ac_cv_path_install
- else
- # As a last resort, use the slow shell script. Don't cache a
- # value for INSTALL within a source directory, because that will
- # break other packages using the cache if that directory is
- # removed, or if the value is a relative name.
- INSTALL=$ac_install_sh
- fi
-fi
-{ echo "$as_me:$LINENO: result: $INSTALL" >&5
-echo "${ECHO_T}$INSTALL" >&6; }
-
-# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
-# It thinks the first close brace ends the variable substitution.
-test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
-
-test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
-
-test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
-
-{ echo "$as_me:$LINENO: checking whether build environment is sane" >&5
-echo $ECHO_N "checking whether build environment is sane... $ECHO_C" >&6; }
-# Just in case
-sleep 1
-echo timestamp > conftest.file
-# Do `set' in a subshell so we don't clobber the current shell's
-# arguments. Must try -L first in case configure is actually a
-# symlink; some systems play weird games with the mod time of symlinks
-# (eg FreeBSD returns the mod time of the symlink's containing
-# directory).
-if (
- set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null`
- if test "$*" = "X"; then
- # -L didn't work.
- set X `ls -t $srcdir/configure conftest.file`
- fi
- rm -f conftest.file
- if test "$*" != "X $srcdir/configure conftest.file" \
- && test "$*" != "X conftest.file $srcdir/configure"; then
-
- # If neither matched, then we have a broken ls. This can happen
- # if, for instance, CONFIG_SHELL is bash and it inherits a
- # broken ls alias from the environment. This has actually
- # happened. Such a system could not be considered "sane".
- { { echo "$as_me:$LINENO: error: ls -t appears to fail. Make sure there is not a broken
-alias in your environment" >&5
-echo "$as_me: error: ls -t appears to fail. Make sure there is not a broken
-alias in your environment" >&2;}
- { (exit 1); exit 1; }; }
- fi
-
- test "$2" = conftest.file
- )
-then
- # Ok.
- :
-else
- { { echo "$as_me:$LINENO: error: newly created file is older than distributed files!
-Check your system clock" >&5
-echo "$as_me: error: newly created file is older than distributed files!
-Check your system clock" >&2;}
- { (exit 1); exit 1; }; }
-fi
-{ echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6; }
-test "$program_prefix" != NONE &&
- program_transform_name="s&^&$program_prefix&;$program_transform_name"
-# Use a double $ so make ignores it.
-test "$program_suffix" != NONE &&
- program_transform_name="s&\$&$program_suffix&;$program_transform_name"
-# Double any \ or $. echo might interpret backslashes.
-# By default was `s,x,x', remove it if useless.
-cat <<\_ACEOF >conftest.sed
-s/[\\$]/&&/g;s/;s,x,x,$//
-_ACEOF
-program_transform_name=`echo $program_transform_name | sed -f conftest.sed`
-rm -f conftest.sed
-
-# expand $ac_aux_dir to an absolute path
-am_aux_dir=`cd $ac_aux_dir && pwd`
-
-test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing"
-# Use eval to expand $SHELL
-if eval "$MISSING --run true"; then
- am_missing_run="$MISSING --run "
-else
- am_missing_run=
- { echo "$as_me:$LINENO: WARNING: \`missing' script is too old or missing" >&5
-echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;}
-fi
-
-{ echo "$as_me:$LINENO: checking for a thread-safe mkdir -p" >&5
-echo $ECHO_N "checking for a thread-safe mkdir -p... $ECHO_C" >&6; }
-if test -z "$MKDIR_P"; then
- if test "${ac_cv_path_mkdir+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_prog in mkdir gmkdir; do
- for ac_exec_ext in '' $ac_executable_extensions; do
- { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; } || continue
- case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #(
- 'mkdir (GNU coreutils) '* | \
- 'mkdir (coreutils) '* | \
- 'mkdir (fileutils) '4.1*)
- ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext
- break 3;;
- esac
- done
- done
-done
-IFS=$as_save_IFS
-
-fi
-
- if test "${ac_cv_path_mkdir+set}" = set; then
- MKDIR_P="$ac_cv_path_mkdir -p"
- else
- # As a last resort, use the slow shell script. Don't cache a
- # value for MKDIR_P within a source directory, because that will
- # break other packages using the cache if that directory is
- # removed, or if the value is a relative name.
- test -d ./--version && rmdir ./--version
- MKDIR_P="$ac_install_sh -d"
- fi
-fi
-{ echo "$as_me:$LINENO: result: $MKDIR_P" >&5
-echo "${ECHO_T}$MKDIR_P" >&6; }
-
-mkdir_p="$MKDIR_P"
-case $mkdir_p in
- [\\/$]* | ?:[\\/]*) ;;
- */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;;
-esac
-
-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
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_AWK+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$AWK"; then
- ac_cv_prog_AWK="$AWK" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-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
- 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"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-AWK=$ac_cv_prog_AWK
-if test -n "$AWK"; then
- { echo "$as_me:$LINENO: result: $AWK" >&5
-echo "${ECHO_T}$AWK" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
- test -n "$AWK" && break
-done
-
-{ echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5
-echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6; }
-set x ${MAKE-make}; ac_make=`echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'`
-if { as_var=ac_cv_prog_make_${ac_make}_set; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.make <<\_ACEOF
-SHELL = /bin/sh
-all:
- @echo '@@@%%%=$(MAKE)=@@@%%%'
-_ACEOF
-# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
-case `${MAKE-make} -f conftest.make 2>/dev/null` in
- *@@@%%%=?*=@@@%%%*)
- eval ac_cv_prog_make_${ac_make}_set=yes;;
- *)
- eval ac_cv_prog_make_${ac_make}_set=no;;
-esac
-rm -f conftest.make
-fi
-if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then
- { echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6; }
- SET_MAKE=
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
- SET_MAKE="MAKE=${MAKE-make}"
-fi
-
-rm -rf .tst 2>/dev/null
-mkdir .tst 2>/dev/null
-if test -d .tst; then
- am__leading_dot=.
-else
- am__leading_dot=_
-fi
-rmdir .tst 2>/dev/null
-
-if test "`cd $srcdir && pwd`" != "`pwd`"; then
- # Use -I$(srcdir) only when $(srcdir) != ., so that make's output
- # is not polluted with repeated "-I."
- am__isrc=' -I$(srcdir)'
- # test to see if srcdir already configured
- if test -f $srcdir/config.status; then
- { { echo "$as_me:$LINENO: error: source directory already configured; run \"make distclean\" there first" >&5
-echo "$as_me: error: source directory already configured; run \"make distclean\" there first" >&2;}
- { (exit 1); exit 1; }; }
- fi
-fi
-
-# test whether we have cygpath
-if test -z "$CYGPATH_W"; then
- if (cygpath --version) >/dev/null 2>/dev/null; then
- CYGPATH_W='cygpath -w'
- else
- CYGPATH_W=echo
- fi
-fi
-
-
-# Define the identity of the package.
- PACKAGE='pcre'
- VERSION='7.7'
-
-
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE "$PACKAGE"
-_ACEOF
-
-
-cat >>confdefs.h <<_ACEOF
-#define VERSION "$VERSION"
-_ACEOF
-
-# Some tools Automake needs.
-
-ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"}
-
-
-AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"}
-
-
-AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"}
-
-
-AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"}
-
-
-MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"}
-
-install_sh=${install_sh-"\$(SHELL) $am_aux_dir/install-sh"}
-
-# Installed binaries are usually stripped using `strip' when the user
-# run `make install-strip'. However `strip' might not be the right
-# tool to use in cross-compilation environments, therefore Automake
-# will honor the `STRIP' environment variable to overrule this program.
-if test "$cross_compiling" != no; then
- 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
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_STRIP+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$STRIP"; then
- ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-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
- 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"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-STRIP=$ac_cv_prog_STRIP
-if test -n "$STRIP"; then
- { echo "$as_me:$LINENO: result: $STRIP" >&5
-echo "${ECHO_T}$STRIP" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
-fi
-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
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$ac_ct_STRIP"; then
- ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-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
- 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"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
-if test -n "$ac_ct_STRIP"; then
- { echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5
-echo "${ECHO_T}$ac_ct_STRIP" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
- if test "x$ac_ct_STRIP" = x; then
- STRIP=":"
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ 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
-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
- fi
-else
- STRIP="$ac_cv_prog_STRIP"
-fi
-
-fi
-INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
-
-# We need awk for the "check" target. The system "awk" is bad on
-# some platforms.
-# Always define AMTAR for backward compatibility.
-
-AMTAR=${AMTAR-"${am_missing_run}tar"}
-
-am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'
-
-
-
-
-
-ac_config_headers="$ac_config_headers config.h"
-
-
-# The default CFLAGS and CXXFLAGS in Autoconf are "-g -O2" for gcc and just
-# "-g" for any other compiler. There doesn't seem to be a standard way of
-# getting rid of the -g (which I don't think is needed for a production
-# library). This fudge seems to achieve the necessary. First, we remember the
-# externally set values of CFLAGS and CXXFLAGS. Then call the AC_PROG_CC and
-# AC_PROG_CXX macros to find the compilers - if CFLAGS and CXXFLAGS are not
-# set, they will be set to Autoconf's defaults. Afterwards, if the original
-# values were not set, remove the -g from the Autoconf defaults.
-# (PH 02-May-07)
-
-remember_set_CFLAGS="$CFLAGS"
-remember_set_CXXFLAGS="$CXXFLAGS"
-
-ac_ext=c
-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
-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
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_CC+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$CC"; then
- ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-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
- 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"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
- { echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
-fi
-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
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$ac_ct_CC"; then
- ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-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
- 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"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_CC=$ac_cv_prog_ac_ct_CC
-if test -n "$ac_ct_CC"; then
- { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
-echo "${ECHO_T}$ac_ct_CC" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
- if test "x$ac_ct_CC" = x; then
- CC=""
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ 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
-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
- fi
-else
- CC="$ac_cv_prog_CC"
-fi
-
-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
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_CC+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$CC"; then
- ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-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
- 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"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
- { echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
- fi
-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
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_CC+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$CC"; then
- ac_cv_prog_CC="$CC" # Let the user override the test.
-else
- ac_prog_rejected=no
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-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
- 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"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
-if test $ac_prog_rejected = yes; then
- # We found a bogon in the path, so make sure we never use it.
- set dummy $ac_cv_prog_CC
- shift
- if test $# != 0; then
- # We chose a different compiler from the bogus one.
- # However, it has the same basename, so the bogon will be chosen
- # first if we set CC to just the basename; use the full file name.
- shift
- ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
- fi
-fi
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
- { echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
-fi
-if test -z "$CC"; then
- if test -n "$ac_tool_prefix"; then
- for ac_prog in cl.exe
- 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
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_CC+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$CC"; then
- ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-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
- 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"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
- { echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
- test -n "$CC" && break
- done
-fi
-if test -z "$CC"; then
- ac_ct_CC=$CC
- for ac_prog in cl.exe
-do
- # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$ac_ct_CC"; then
- ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-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
- 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"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_CC=$ac_cv_prog_ac_ct_CC
-if test -n "$ac_ct_CC"; then
- { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
-echo "${ECHO_T}$ac_ct_CC" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
- test -n "$ac_ct_CC" && break
-done
-
- if test "x$ac_ct_CC" = x; then
- CC=""
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ 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
-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
- fi
-fi
-
-fi
-
-
-test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH
-See \`config.log' for more details." >&5
-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.
-echo "$as_me:$LINENO: checking for C compiler version" >&5
-ac_compiler=`set X $ac_compile; echo $2`
-{ (ac_try="$ac_compiler --version >&5"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compiler --version >&5") 2>&5
- ac_status=$?
- 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compiler -v >&5") 2>&5
- ac_status=$?
- 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compiler -V >&5") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }
-
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-ac_clean_files_save=$ac_clean_files
-ac_clean_files="$ac_clean_files a.out 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.
-{ echo "$as_me:$LINENO: checking for C compiler default output file name" >&5
-echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6; }
-ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
-#
-# List of possible output files, starting from the most likely.
-# The algorithm is not robust to junk in `.', hence go to wildcards (a.*)
-# only as a last resort. b.out is created by i960 compilers.
-ac_files='a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out'
-#
-# The IRIX 6 linker writes into existing files which may not be
-# executable, retaining their permissions. Remove them first so a
-# subsequent execution test works.
-ac_rmfiles=
-for ac_file in $ac_files
-do
- case $ac_file in
- *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;;
- * ) ac_rmfiles="$ac_rmfiles $ac_file";;
- esac
-done
-rm -f $ac_rmfiles
-
-if { (ac_try="$ac_link_default"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link_default") 2>&5
- ac_status=$?
- 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,
-# so that the user can short-circuit this test for compilers unknown to
-# Autoconf.
-for ac_file in $ac_files ''
-do
- test -f "$ac_file" || continue
- case $ac_file in
- *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj )
- ;;
- [ab].out )
- # We found the default executable, but exeext='' is most
- # certainly right.
- break;;
- *.* )
- if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
- then :; else
- ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
- fi
- # We set ac_cv_exeext here because the later test for it is not
- # safe: cross compilers may not add the suffix if given an `-o'
- # argument, so we may need to know it at that point already.
- # Even if this section looks crufty: it has the advantage of
- # actually working.
- break;;
- * )
- break;;
- esac
-done
-test "$ac_cv_exeext" = no && ac_cv_exeext=
-
-else
- ac_file=''
-fi
-
-{ echo "$as_me:$LINENO: result: $ac_file" >&5
-echo "${ECHO_T}$ac_file" >&6; }
-if test -z "$ac_file"; then
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-{ { echo "$as_me:$LINENO: error: C compiler cannot create executables
-See \`config.log' for more details." >&5
-echo "$as_me: error: C compiler cannot create executables
-See \`config.log' for more details." >&2;}
- { (exit 77); exit 77; }; }
-fi
-
-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.
-{ echo "$as_me:$LINENO: checking whether the C compiler works" >&5
-echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- 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
- { { 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
-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
-{ echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6; }
-
-rm -f a.out a.exe conftest$ac_cv_exeext b.out
-ac_clean_files=$ac_clean_files_save
-# Check that the compiler produces executables we can run. If not, either
-# the compiler is broken, or we cross compile.
-{ echo "$as_me:$LINENO: checking whether we are cross compiling" >&5
-echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6; }
-{ echo "$as_me:$LINENO: result: $cross_compiling" >&5
-echo "${ECHO_T}$cross_compiling" >&6; }
-
-{ echo "$as_me:$LINENO: checking for suffix of executables" >&5
-echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6; }
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>&5
- ac_status=$?
- 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
-# `rm'.
-for ac_file in conftest.exe conftest conftest.*; do
- test -f "$ac_file" || continue
- case $ac_file in
- *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;;
- *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
- break;;
- * ) break;;
- esac
-done
-else
- { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link
-See \`config.log' for more details." >&5
-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$ac_cv_exeext
-{ echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5
-echo "${ECHO_T}$ac_cv_exeext" >&6; }
-
-rm -f conftest.$ac_ext
-EXEEXT=$ac_cv_exeext
-ac_exeext=$EXEEXT
-{ echo "$as_me:$LINENO: checking for suffix of object files" >&5
-echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6; }
-if test "${ac_cv_objext+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.o conftest.obj
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>&5
- ac_status=$?
- 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
- *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf ) ;;
- *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
- break;;
- esac
-done
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile
-See \`config.log' for more details." >&5
-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
-{ echo "$as_me:$LINENO: result: $ac_cv_objext" >&5
-echo "${ECHO_T}$ac_cv_objext" >&6; }
-OBJEXT=$ac_cv_objext
-ac_objext=$OBJEXT
-{ echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5
-echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6; }
-if test "${ac_cv_c_compiler_gnu+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-int
-main ()
-{
-#ifndef __GNUC__
- choke me
-#endif
-
- ;
- 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 "echo \"\$as_me:$LINENO: $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
- 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
- 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
-{ echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5
-echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6; }
-GCC=`test $ac_compiler_gnu = yes && echo yes`
-ac_test_CFLAGS=${CFLAGS+set}
-ac_save_CFLAGS=$CFLAGS
-{ echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5
-echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6; }
-if test "${ac_cv_prog_cc_g+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&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 >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- 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 "echo \"\$as_me:$LINENO: $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
- 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
- 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
-main ()
-{
-
- ;
- 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 "echo \"\$as_me:$LINENO: $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
- 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
- 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 >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- 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 "echo \"\$as_me:$LINENO: $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
- 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
- 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
-{ echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5
-echo "${ECHO_T}$ac_cv_prog_cc_g" >&6; }
-if test "$ac_test_CFLAGS" = set; then
- CFLAGS=$ac_save_CFLAGS
-elif test $ac_cv_prog_cc_g = yes; then
- if test "$GCC" = yes; then
- CFLAGS="-g -O2"
- else
- CFLAGS="-g"
- fi
-else
- if test "$GCC" = yes; then
- CFLAGS="-O2"
- else
- CFLAGS=
- fi
-fi
-{ echo "$as_me:$LINENO: checking for $CC option to accept ISO C89" >&5
-echo $ECHO_N "checking for $CC option to accept ISO C89... $ECHO_C" >&6; }
-if test "${ac_cv_prog_cc_c89+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_cv_prog_cc_c89=no
-ac_save_CC=$CC
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <stdarg.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
-struct buf { int x; };
-FILE * (*rcsopen) (struct buf *, struct stat *, int);
-static char *e (p, i)
- char **p;
- int i;
-{
- return p[i];
-}
-static char *f (char * (*g) (char **, int), char **p, ...)
-{
- char *s;
- va_list v;
- va_start (v,p);
- s = g (p, va_arg (v,int));
- va_end (v);
- return s;
-}
-
-/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has
- function prototypes and stuff, but not '\xHH' hex character constants.
- These don't provoke an error unfortunately, instead are silently treated
- as 'x'. The following induces an error, until -std is added to get
- proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an
- array size at least. It's necessary to write '\x00'==0 to get something
- that's true only with -std. */
-int osf4_cc_array ['\x00' == 0 ? 1 : -1];
-
-/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
- inside strings and character constants. */
-#define FOO(x) 'x'
-int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
-
-int test (int i, double x);
-struct s1 {int (*f) (int a);};
-struct s2 {int (*f) (double a);};
-int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
-int argc;
-char **argv;
-int
-main ()
-{
-return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
- ;
- return 0;
-}
-_ACEOF
-for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
- -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
-do
- CC="$ac_save_CC $ac_arg"
- 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 "echo \"\$as_me:$LINENO: $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
- 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
- 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
-rm -f conftest.$ac_ext
-CC=$ac_save_CC
-
-fi
-# AC_CACHE_VAL
-case "x$ac_cv_prog_cc_c89" in
- x)
- { echo "$as_me:$LINENO: result: none needed" >&5
-echo "${ECHO_T}none needed" >&6; } ;;
- xno)
- { echo "$as_me:$LINENO: result: unsupported" >&5
-echo "${ECHO_T}unsupported" >&6; } ;;
- *)
- CC="$CC $ac_cv_prog_cc_c89"
- { echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5
-echo "${ECHO_T}$ac_cv_prog_cc_c89" >&6; } ;;
-esac
-
-
-ac_ext=c
-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
-DEPDIR="${am__leading_dot}deps"
-
-ac_config_commands="$ac_config_commands depfiles"
-
-
-am_make=${MAKE-make}
-cat > confinc << 'END'
-am__doit:
- @echo done
-.PHONY: am__doit
-END
-# If we don't find an include directive, just comment out the code.
-{ echo "$as_me:$LINENO: checking for style of include used by $am_make" >&5
-echo $ECHO_N "checking for style of include used by $am_make... $ECHO_C" >&6; }
-am__include="#"
-am__quote=
-_am_result=none
-# First try GNU make style include.
-echo "include confinc" > confmf
-# We grep out `Entering directory' and `Leaving directory'
-# messages which can occur if `w' ends up in MAKEFLAGS.
-# In particular we don't look at `^make:' because GNU make might
-# be invoked under some other name (usually "gmake"), in which
-# case it prints its new name instead of `make'.
-if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then
- am__include=include
- am__quote=
- _am_result=GNU
-fi
-# Now try BSD make style include.
-if test "$am__include" = "#"; then
- echo '.include "confinc"' > confmf
- if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then
- am__include=.include
- am__quote="\""
- _am_result=BSD
- fi
-fi
-
-
-{ echo "$as_me:$LINENO: result: $_am_result" >&5
-echo "${ECHO_T}$_am_result" >&6; }
-rm -f confinc confmf
-
-# Check whether --enable-dependency-tracking was given.
-if test "${enable_dependency_tracking+set}" = set; then
- enableval=$enable_dependency_tracking;
-fi
-
-if test "x$enable_dependency_tracking" != xno; then
- am_depcomp="$ac_aux_dir/depcomp"
- AMDEPBACKSLASH='\'
-fi
- if test "x$enable_dependency_tracking" != xno; then
- AMDEP_TRUE=
- AMDEP_FALSE='#'
-else
- AMDEP_TRUE='#'
- AMDEP_FALSE=
-fi
-
-
-
-depcc="$CC" am_compiler_list=
-
-{ echo "$as_me:$LINENO: checking dependency style of $depcc" >&5
-echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6; }
-if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
- # We make a subdir and do the tests there. Otherwise we can end up
- # making bogus files that we don't know about and never remove. For
- # instance it was reported that on HP-UX the gcc test will end up
- # making a dummy file named `D' -- because `-MD' means `put the output
- # in D'.
- mkdir conftest.dir
- # Copy depcomp to subdir because otherwise we won't find it if we're
- # using a relative directory.
- cp "$am_depcomp" conftest.dir
- cd conftest.dir
- # We will build objects and dependencies in a subdirectory because
- # it helps to detect inapplicable dependency modes. For instance
- # both Tru64's cc and ICC support -MD to output dependencies as a
- # side effect of compilation, but ICC will put the dependencies in
- # the current directory while Tru64 will put them in the object
- # directory.
- mkdir sub
-
- am_cv_CC_dependencies_compiler_type=none
- if test "$am_compiler_list" = ""; then
- am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp`
- fi
- for depmode in $am_compiler_list; do
- # Setup a source with many dependencies, because some compilers
- # like to wrap large dependency lists on column 80 (with \), and
- # we should not choose a depcomp mode which is confused by this.
- #
- # We need to recreate these files for each test, as the compiler may
- # overwrite some of them when testing with obscure command lines.
- # This happens at least with the AIX C compiler.
- : > sub/conftest.c
- for i in 1 2 3 4 5 6; do
- echo '#include "conftst'$i'.h"' >> sub/conftest.c
- # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
- # Solaris 8's {/usr,}/bin/sh.
- touch sub/conftst$i.h
- done
- echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
-
- case $depmode in
- nosideeffect)
- # after this tag, mechanisms are not by side-effect, so they'll
- # only be used when explicitly requested
- if test "x$enable_dependency_tracking" = xyes; then
- continue
- else
- break
- fi
- ;;
- none) break ;;
- esac
- # We check with `-c' and `-o' for the sake of the "dashmstdout"
- # mode. It turns out that the SunPro C++ compiler does not properly
- # handle `-M -o', and we need to detect this.
- if depmode=$depmode \
- source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \
- depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
- $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \
- >/dev/null 2>conftest.err &&
- grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
- grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
- grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 &&
- ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
- # icc doesn't choke on unknown options, it will just issue warnings
- # or remarks (even with -Werror). So we grep stderr for any message
- # that says an option was ignored or not supported.
- # When given -MP, icc 7.0 and 7.1 complain thusly:
- # icc: Command line warning: ignoring option '-M'; no argument required
- # The diagnosis changed in icc 8.0:
- # icc: Command line remark: option '-MP' not supported
- if (grep 'ignoring option' conftest.err ||
- grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
- am_cv_CC_dependencies_compiler_type=$depmode
- break
- fi
- fi
- done
-
- cd ..
- rm -rf conftest.dir
-else
- am_cv_CC_dependencies_compiler_type=none
-fi
-
-fi
-{ echo "$as_me:$LINENO: result: $am_cv_CC_dependencies_compiler_type" >&5
-echo "${ECHO_T}$am_cv_CC_dependencies_compiler_type" >&6; }
-CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type
-
- if
- test "x$enable_dependency_tracking" != xno \
- && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then
- am__fastdepCC_TRUE=
- am__fastdepCC_FALSE='#'
-else
- am__fastdepCC_TRUE='#'
- am__fastdepCC_FALSE=
-fi
-
-
-ac_ext=cpp
-ac_cpp='$CXXCPP $CPPFLAGS'
-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
-if test -z "$CXX"; then
- if test -n "$CCC"; then
- CXX=$CCC
- else
- if test -n "$ac_tool_prefix"; then
- for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
- 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
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_CXX+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$CXX"; then
- ac_cv_prog_CXX="$CXX" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-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
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_CXX="$ac_tool_prefix$ac_prog"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-CXX=$ac_cv_prog_CXX
-if test -n "$CXX"; then
- { echo "$as_me:$LINENO: result: $CXX" >&5
-echo "${ECHO_T}$CXX" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
- test -n "$CXX" && break
- done
-fi
-if test -z "$CXX"; then
- ac_ct_CXX=$CXX
- for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
-do
- # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$ac_ct_CXX"; then
- ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-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
- 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_CXX="$ac_prog"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_CXX=$ac_cv_prog_ac_ct_CXX
-if test -n "$ac_ct_CXX"; then
- { echo "$as_me:$LINENO: result: $ac_ct_CXX" >&5
-echo "${ECHO_T}$ac_ct_CXX" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
- test -n "$ac_ct_CXX" && break
-done
-
- if test "x$ac_ct_CXX" = x; then
- CXX="g++"
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ 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
-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
- CXX=$ac_ct_CXX
- fi
-fi
-
- fi
-fi
-# Provide some information about the compiler.
-echo "$as_me:$LINENO: checking for C++ compiler version" >&5
-ac_compiler=`set X $ac_compile; echo $2`
-{ (ac_try="$ac_compiler --version >&5"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compiler --version >&5") 2>&5
- ac_status=$?
- 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compiler -v >&5") 2>&5
- ac_status=$?
- 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compiler -V >&5") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }
-
-{ echo "$as_me:$LINENO: checking whether we are using the GNU C++ compiler" >&5
-echo $ECHO_N "checking whether we are using the GNU C++ compiler... $ECHO_C" >&6; }
-if test "${ac_cv_cxx_compiler_gnu+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-int
-main ()
-{
-#ifndef __GNUC__
- choke me
-#endif
-
- ;
- 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 "echo \"\$as_me:$LINENO: $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
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_cxx_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_compiler_gnu=yes
-else
- 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_cxx_compiler_gnu=$ac_compiler_gnu
-
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_cxx_compiler_gnu" >&5
-echo "${ECHO_T}$ac_cv_cxx_compiler_gnu" >&6; }
-GXX=`test $ac_compiler_gnu = yes && echo yes`
-ac_test_CXXFLAGS=${CXXFLAGS+set}
-ac_save_CXXFLAGS=$CXXFLAGS
-{ echo "$as_me:$LINENO: checking whether $CXX accepts -g" >&5
-echo $ECHO_N "checking whether $CXX accepts -g... $ECHO_C" >&6; }
-if test "${ac_cv_prog_cxx_g+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_save_cxx_werror_flag=$ac_cxx_werror_flag
- ac_cxx_werror_flag=yes
- ac_cv_prog_cxx_g=no
- CXXFLAGS="-g"
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- 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 "echo \"\$as_me:$LINENO: $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
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_cxx_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_cv_prog_cxx_g=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- CXXFLAGS=""
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- 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 "echo \"\$as_me:$LINENO: $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
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_cxx_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- :
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cxx_werror_flag=$ac_save_cxx_werror_flag
- CXXFLAGS="-g"
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- 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 "echo \"\$as_me:$LINENO: $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
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_cxx_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_cv_prog_cxx_g=yes
-else
- 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_cxx_werror_flag=$ac_save_cxx_werror_flag
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_g" >&5
-echo "${ECHO_T}$ac_cv_prog_cxx_g" >&6; }
-if test "$ac_test_CXXFLAGS" = set; then
- CXXFLAGS=$ac_save_CXXFLAGS
-elif test $ac_cv_prog_cxx_g = yes; then
- if test "$GXX" = yes; then
- CXXFLAGS="-g -O2"
- else
- CXXFLAGS="-g"
- fi
-else
- if test "$GXX" = yes; then
- CXXFLAGS="-O2"
- else
- CXXFLAGS=
- fi
-fi
-ac_ext=c
-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
-
-depcc="$CXX" am_compiler_list=
-
-{ echo "$as_me:$LINENO: checking dependency style of $depcc" >&5
-echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6; }
-if test "${am_cv_CXX_dependencies_compiler_type+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
- # We make a subdir and do the tests there. Otherwise we can end up
- # making bogus files that we don't know about and never remove. For
- # instance it was reported that on HP-UX the gcc test will end up
- # making a dummy file named `D' -- because `-MD' means `put the output
- # in D'.
- mkdir conftest.dir
- # Copy depcomp to subdir because otherwise we won't find it if we're
- # using a relative directory.
- cp "$am_depcomp" conftest.dir
- cd conftest.dir
- # We will build objects and dependencies in a subdirectory because
- # it helps to detect inapplicable dependency modes. For instance
- # both Tru64's cc and ICC support -MD to output dependencies as a
- # side effect of compilation, but ICC will put the dependencies in
- # the current directory while Tru64 will put them in the object
- # directory.
- mkdir sub
-
- am_cv_CXX_dependencies_compiler_type=none
- if test "$am_compiler_list" = ""; then
- am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp`
- fi
- for depmode in $am_compiler_list; do
- # Setup a source with many dependencies, because some compilers
- # like to wrap large dependency lists on column 80 (with \), and
- # we should not choose a depcomp mode which is confused by this.
- #
- # We need to recreate these files for each test, as the compiler may
- # overwrite some of them when testing with obscure command lines.
- # This happens at least with the AIX C compiler.
- : > sub/conftest.c
- for i in 1 2 3 4 5 6; do
- echo '#include "conftst'$i'.h"' >> sub/conftest.c
- # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
- # Solaris 8's {/usr,}/bin/sh.
- touch sub/conftst$i.h
- done
- echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
-
- case $depmode in
- nosideeffect)
- # after this tag, mechanisms are not by side-effect, so they'll
- # only be used when explicitly requested
- if test "x$enable_dependency_tracking" = xyes; then
- continue
- else
- break
- fi
- ;;
- none) break ;;
- esac
- # We check with `-c' and `-o' for the sake of the "dashmstdout"
- # mode. It turns out that the SunPro C++ compiler does not properly
- # handle `-M -o', and we need to detect this.
- if depmode=$depmode \
- source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \
- depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
- $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \
- >/dev/null 2>conftest.err &&
- grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
- grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
- grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 &&
- ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
- # icc doesn't choke on unknown options, it will just issue warnings
- # or remarks (even with -Werror). So we grep stderr for any message
- # that says an option was ignored or not supported.
- # When given -MP, icc 7.0 and 7.1 complain thusly:
- # icc: Command line warning: ignoring option '-M'; no argument required
- # The diagnosis changed in icc 8.0:
- # icc: Command line remark: option '-MP' not supported
- if (grep 'ignoring option' conftest.err ||
- grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
- am_cv_CXX_dependencies_compiler_type=$depmode
- break
- fi
- fi
- done
-
- cd ..
- rm -rf conftest.dir
-else
- am_cv_CXX_dependencies_compiler_type=none
-fi
-
-fi
-{ echo "$as_me:$LINENO: result: $am_cv_CXX_dependencies_compiler_type" >&5
-echo "${ECHO_T}$am_cv_CXX_dependencies_compiler_type" >&6; }
-CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type
-
- if
- test "x$enable_dependency_tracking" != xno \
- && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then
- am__fastdepCXX_TRUE=
- am__fastdepCXX_FALSE='#'
-else
- am__fastdepCXX_TRUE='#'
- am__fastdepCXX_FALSE=
-fi
-
-
-
-if test "x$remember_set_CFLAGS" = "x"
-then
- if test "$CFLAGS" = "-g -O2"
- then
- CFLAGS="-O2"
- elif test "$CFLAGS" = "-g"
- then
- CFLAGS=""
- fi
-fi
-
-if test "x$remember_set_CXXFLAGS" = "x"
-then
- if test "$CXXFLAGS" = "-g -O2"
- then
- CXXFLAGS="-O2"
- elif test "$CXXFLAGS" = "-g"
- then
- CXXFLAGS=""
- fi
-fi
-
-# AC_PROG_CXX will return "g++" even if no c++ compiler is installed.
-# Check for that case, and just disable c++ code if g++ doesn't run.
-ac_ext=cpp
-ac_cpp='$CXXCPP $CPPFLAGS'
-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
-
-
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- 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 "echo \"\$as_me:$LINENO: $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
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_cxx_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- :
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- CXX=""; CXXCP=""; CXXFLAGS=""
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-ac_ext=c
-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
-
-
-# Find a good install program. We prefer a C program (faster),
-# so one script is as good as another. But avoid the broken or
-# incompatible versions:
-# SysV /etc/install, /usr/sbin/install
-# SunOS /usr/etc/install
-# IRIX /sbin/install
-# AIX /bin/install
-# AmigaOS /C/install, which installs bootblocks on floppy discs
-# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
-# AFS /usr/afsws/bin/install, which mishandles nonexistent args
-# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
-# OS/2's system install, which has a completely different semantic
-# ./install, which can be erroneously created by make from ./install.sh.
-{ echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5
-echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6; }
-if test -z "$INSTALL"; then
-if test "${ac_cv_path_install+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-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/* | \
- /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
- ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \
- /usr/ucb/* ) ;;
- *)
- # OSF1 and SCO ODT 3.0 have their own names for install.
- # Don't use installbsd from OSF since it installs stuff as root
- # by default.
- for ac_prog in ginstall scoinst install; do
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then
- if test $ac_prog = install &&
- grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
- # AIX install. It has an incompatible calling convention.
- :
- elif test $ac_prog = install &&
- grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
- # program-specific install script used by HP pwplus--don't use.
- :
- else
- ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
- break 3
- fi
- fi
- done
- done
- ;;
-esac
-done
-IFS=$as_save_IFS
-
-
-fi
- if test "${ac_cv_path_install+set}" = set; then
- INSTALL=$ac_cv_path_install
- else
- # As a last resort, use the slow shell script. Don't cache a
- # value for INSTALL within a source directory, because that will
- # break other packages using the cache if that directory is
- # removed, or if the value is a relative name.
- INSTALL=$ac_install_sh
- fi
-fi
-{ echo "$as_me:$LINENO: result: $INSTALL" >&5
-echo "${ECHO_T}$INSTALL" >&6; }
-
-# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
-# It thinks the first close brace ends the variable substitution.
-test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
-
-test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
-
-test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
-
-
-
-# Check whether --enable-shared was given.
-if test "${enable_shared+set}" = set; then
- enableval=$enable_shared; p=${PACKAGE-default}
- case $enableval in
- yes) enable_shared=yes ;;
- no) enable_shared=no ;;
- *)
- enable_shared=no
- # Look at the argument we got. We use all the common list separators.
- lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
- for pkg in $enableval; do
- IFS="$lt_save_ifs"
- if test "X$pkg" = "X$p"; then
- enable_shared=yes
- fi
- done
- IFS="$lt_save_ifs"
- ;;
- esac
-else
- enable_shared=yes
-fi
-
-
-# Check whether --enable-static was given.
-if test "${enable_static+set}" = set; then
- enableval=$enable_static; p=${PACKAGE-default}
- case $enableval in
- yes) enable_static=yes ;;
- no) enable_static=no ;;
- *)
- enable_static=no
- # Look at the argument we got. We use all the common list separators.
- lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
- for pkg in $enableval; do
- IFS="$lt_save_ifs"
- if test "X$pkg" = "X$p"; then
- enable_static=yes
- fi
- done
- IFS="$lt_save_ifs"
- ;;
- esac
-else
- enable_static=yes
-fi
-
-
-# Check whether --enable-fast-install was given.
-if test "${enable_fast_install+set}" = set; then
- enableval=$enable_fast_install; p=${PACKAGE-default}
- case $enableval in
- yes) enable_fast_install=yes ;;
- no) enable_fast_install=no ;;
- *)
- enable_fast_install=no
- # Look at the argument we got. We use all the common list separators.
- lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
- for pkg in $enableval; do
- IFS="$lt_save_ifs"
- if test "X$pkg" = "X$p"; then
- enable_fast_install=yes
- fi
- done
- IFS="$lt_save_ifs"
- ;;
- esac
-else
- enable_fast_install=yes
-fi
-
-
-# Make sure we can run config.sub.
-$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
- { { echo "$as_me:$LINENO: error: cannot run $SHELL $ac_aux_dir/config.sub" >&5
-echo "$as_me: error: cannot run $SHELL $ac_aux_dir/config.sub" >&2;}
- { (exit 1); exit 1; }; }
-
-{ echo "$as_me:$LINENO: checking build system type" >&5
-echo $ECHO_N "checking build system type... $ECHO_C" >&6; }
-if test "${ac_cv_build+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&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 &&
- { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5
-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` ||
- { { echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&5
-echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&2;}
- { (exit 1); exit 1; }; }
-
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_build" >&5
-echo "${ECHO_T}$ac_cv_build" >&6; }
-case $ac_cv_build in
-*-*-*) ;;
-*) { { echo "$as_me:$LINENO: error: invalid value of canonical build" >&5
-echo "$as_me: error: invalid value of canonical build" >&2;}
- { (exit 1); exit 1; }; };;
-esac
-build=$ac_cv_build
-ac_save_IFS=$IFS; IFS='-'
-set x $ac_cv_build
-shift
-build_cpu=$1
-build_vendor=$2
-shift; shift
-# Remember, the first character of IFS is used to create $*,
-# except with old shells:
-build_os=$*
-IFS=$ac_save_IFS
-case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac
-
-
-{ echo "$as_me:$LINENO: checking host system type" >&5
-echo $ECHO_N "checking host system type... $ECHO_C" >&6; }
-if test "${ac_cv_host+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&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` ||
- { { echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&5
-echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&2;}
- { (exit 1); exit 1; }; }
-fi
-
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_host" >&5
-echo "${ECHO_T}$ac_cv_host" >&6; }
-case $ac_cv_host in
-*-*-*) ;;
-*) { { echo "$as_me:$LINENO: error: invalid value of canonical host" >&5
-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
-
-
-{ echo "$as_me:$LINENO: checking for a sed that does not truncate output" >&5
-echo $ECHO_N "checking for a sed that does not truncate output... $ECHO_C" >&6; }
-if test "${lt_cv_path_SED+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- # Loop through the user's path and test for sed and gsed.
-# Then use that list of sed's as ones to test for truncation.
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for lt_ac_prog in sed gsed; do
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$lt_ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$lt_ac_prog$ac_exec_ext"; }; then
- lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext"
- fi
- done
- done
-done
-IFS=$as_save_IFS
-lt_ac_max=0
-lt_ac_count=0
-# Add /usr/xpg4/bin/sed as it is typically found on Solaris
-# along with /bin/sed that truncates output.
-for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do
- test ! -f $lt_ac_sed && continue
- cat /dev/null > conftest.in
- lt_ac_count=0
- echo $ECHO_N "0123456789$ECHO_C" >conftest.in
- # Check for GNU sed and select it if it is found.
- if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then
- lt_cv_path_SED=$lt_ac_sed
- break
- fi
- while true; do
- cat conftest.in conftest.in >conftest.tmp
- mv conftest.tmp conftest.in
- cp conftest.in conftest.nl
- echo >>conftest.nl
- $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break
- cmp -s conftest.out conftest.nl || break
- # 10000 chars as input seems more than enough
- test $lt_ac_count -gt 10 && break
- lt_ac_count=`expr $lt_ac_count + 1`
- if test $lt_ac_count -gt $lt_ac_max; then
- lt_ac_max=$lt_ac_count
- lt_cv_path_SED=$lt_ac_sed
- fi
- done
-done
-
-fi
-
-SED=$lt_cv_path_SED
-
-{ echo "$as_me:$LINENO: result: $SED" >&5
-echo "${ECHO_T}$SED" >&6; }
-
-{ echo "$as_me:$LINENO: checking for grep that handles long lines and -e" >&5
-echo $ECHO_N "checking for grep that handles long lines and -e... $ECHO_C" >&6; }
-if test "${ac_cv_path_GREP+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- # Extract the first word of "grep ggrep" to use in msg output
-if test -z "$GREP"; then
-set dummy grep ggrep; ac_prog_name=$2
-if test "${ac_cv_path_GREP+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_path_GREP_found=false
-# Loop through the user's path and test for each of PROGNAME-LIST
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-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_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
- # Check for GNU ac_path_GREP and select it if it is found.
- # Check for GNU $ac_path_GREP
-case `"$ac_path_GREP" --version 2>&1` in
-*GNU*)
- ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
-*)
- ac_count=0
- echo $ECHO_N "0123456789$ECHO_C" >"conftest.in"
- while :
- do
- cat "conftest.in" "conftest.in" >"conftest.tmp"
- mv "conftest.tmp" "conftest.in"
- cp "conftest.in" "conftest.nl"
- 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
- 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"
- ac_path_GREP_max=$ac_count
- fi
- # 10*(2^10) chars as input seems more than enough
- test $ac_count -gt 10 && break
- done
- rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
-esac
-
-
- $ac_path_GREP_found && break 3
- done
-done
-
-done
-IFS=$as_save_IFS
-
-
-fi
-
-GREP="$ac_cv_path_GREP"
-if test -z "$GREP"; then
- { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5
-echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;}
- { (exit 1); exit 1; }; }
-fi
-
-else
- ac_cv_path_GREP=$GREP
-fi
-
-
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_path_GREP" >&5
-echo "${ECHO_T}$ac_cv_path_GREP" >&6; }
- GREP="$ac_cv_path_GREP"
-
-
-{ echo "$as_me:$LINENO: checking for egrep" >&5
-echo $ECHO_N "checking for egrep... $ECHO_C" >&6; }
-if test "${ac_cv_path_EGREP+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
- then ac_cv_path_EGREP="$GREP -E"
- else
- # Extract the first word of "egrep" to use in msg output
-if test -z "$EGREP"; then
-set dummy egrep; ac_prog_name=$2
-if test "${ac_cv_path_EGREP+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_path_EGREP_found=false
-# Loop through the user's path and test for each of PROGNAME-LIST
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-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_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
- # Check for GNU ac_path_EGREP and select it if it is found.
- # Check for GNU $ac_path_EGREP
-case `"$ac_path_EGREP" --version 2>&1` in
-*GNU*)
- ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
-*)
- ac_count=0
- echo $ECHO_N "0123456789$ECHO_C" >"conftest.in"
- while :
- do
- cat "conftest.in" "conftest.in" >"conftest.tmp"
- mv "conftest.tmp" "conftest.in"
- cp "conftest.in" "conftest.nl"
- 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
- 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"
- ac_path_EGREP_max=$ac_count
- fi
- # 10*(2^10) chars as input seems more than enough
- test $ac_count -gt 10 && break
- done
- rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
-esac
-
-
- $ac_path_EGREP_found && break 3
- done
-done
-
-done
-IFS=$as_save_IFS
-
-
-fi
-
-EGREP="$ac_cv_path_EGREP"
-if test -z "$EGREP"; then
- { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5
-echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;}
- { (exit 1); exit 1; }; }
-fi
-
-else
- ac_cv_path_EGREP=$EGREP
-fi
-
-
- fi
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_path_EGREP" >&5
-echo "${ECHO_T}$ac_cv_path_EGREP" >&6; }
- EGREP="$ac_cv_path_EGREP"
-
-
-
-# Check whether --with-gnu-ld was given.
-if test "${with_gnu_ld+set}" = set; then
- withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes
-else
- with_gnu_ld=no
-fi
-
-ac_prog=ld
-if test "$GCC" = yes; then
- # Check if gcc -print-prog-name=ld gives a path.
- { echo "$as_me:$LINENO: checking for ld used by $CC" >&5
-echo $ECHO_N "checking for ld used by $CC... $ECHO_C" >&6; }
- case $host in
- *-*-mingw*)
- # gcc leaves a trailing carriage return which upsets mingw
- ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
- *)
- ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
- esac
- case $ac_prog in
- # Accept absolute paths.
- [\\/]* | ?:[\\/]*)
- re_direlt='/[^/][^/]*/\.\./'
- # Canonicalize the pathname of ld
- ac_prog=`echo $ac_prog| $SED 's%\\\\%/%g'`
- while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
- ac_prog=`echo $ac_prog| $SED "s%$re_direlt%/%"`
- done
- test -z "$LD" && LD="$ac_prog"
- ;;
- "")
- # If it fails, then pretend we aren't using GCC.
- ac_prog=ld
- ;;
- *)
- # If it is relative, then search for the first ld in PATH.
- with_gnu_ld=unknown
- ;;
- esac
-elif test "$with_gnu_ld" = yes; then
- { echo "$as_me:$LINENO: checking for GNU ld" >&5
-echo $ECHO_N "checking for GNU ld... $ECHO_C" >&6; }
-else
- { echo "$as_me:$LINENO: checking for non-GNU ld" >&5
-echo $ECHO_N "checking for non-GNU ld... $ECHO_C" >&6; }
-fi
-if test "${lt_cv_path_LD+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -z "$LD"; then
- lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
- for ac_dir in $PATH; do
- IFS="$lt_save_ifs"
- test -z "$ac_dir" && ac_dir=.
- if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
- lt_cv_path_LD="$ac_dir/$ac_prog"
- # Check to see if the program is GNU ld. I'd rather use --version,
- # but apparently some variants of GNU ld only accept -v.
- # Break only if it was the GNU/non-GNU ld that we prefer.
- case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
- *GNU* | *'with BFD'*)
- test "$with_gnu_ld" != no && break
- ;;
- *)
- test "$with_gnu_ld" != yes && break
- ;;
- esac
- fi
- done
- IFS="$lt_save_ifs"
-else
- lt_cv_path_LD="$LD" # Let the user override the test with a path.
-fi
-fi
-
-LD="$lt_cv_path_LD"
-if test -n "$LD"; then
- { echo "$as_me:$LINENO: result: $LD" >&5
-echo "${ECHO_T}$LD" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-test -z "$LD" && { { echo "$as_me:$LINENO: error: no acceptable ld found in \$PATH" >&5
-echo "$as_me: error: no acceptable ld found in \$PATH" >&2;}
- { (exit 1); exit 1; }; }
-{ echo "$as_me:$LINENO: checking if the linker ($LD) is GNU ld" >&5
-echo $ECHO_N "checking if the linker ($LD) is GNU ld... $ECHO_C" >&6; }
-if test "${lt_cv_prog_gnu_ld+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- # I'd rather use --version here, but apparently some GNU lds only accept -v.
-case `$LD -v 2>&1 </dev/null` in
-*GNU* | *'with BFD'*)
- lt_cv_prog_gnu_ld=yes
- ;;
-*)
- lt_cv_prog_gnu_ld=no
- ;;
-esac
-fi
-{ echo "$as_me:$LINENO: result: $lt_cv_prog_gnu_ld" >&5
-echo "${ECHO_T}$lt_cv_prog_gnu_ld" >&6; }
-with_gnu_ld=$lt_cv_prog_gnu_ld
-
-
-{ echo "$as_me:$LINENO: checking for $LD option to reload object files" >&5
-echo $ECHO_N "checking for $LD option to reload object files... $ECHO_C" >&6; }
-if test "${lt_cv_ld_reload_flag+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- lt_cv_ld_reload_flag='-r'
-fi
-{ echo "$as_me:$LINENO: result: $lt_cv_ld_reload_flag" >&5
-echo "${ECHO_T}$lt_cv_ld_reload_flag" >&6; }
-reload_flag=$lt_cv_ld_reload_flag
-case $reload_flag in
-"" | " "*) ;;
-*) reload_flag=" $reload_flag" ;;
-esac
-reload_cmds='$LD$reload_flag -o $output$reload_objs'
-case $host_os in
- darwin*)
- if test "$GCC" = yes; then
- reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs'
- else
- reload_cmds='$LD$reload_flag -o $output$reload_objs'
- fi
- ;;
-esac
-
-{ echo "$as_me:$LINENO: checking for BSD-compatible nm" >&5
-echo $ECHO_N "checking for BSD-compatible nm... $ECHO_C" >&6; }
-if test "${lt_cv_path_NM+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$NM"; then
- # Let the user override the test.
- lt_cv_path_NM="$NM"
-else
- lt_nm_to_check="${ac_tool_prefix}nm"
- if test -n "$ac_tool_prefix" && test "$build" = "$host"; then
- lt_nm_to_check="$lt_nm_to_check nm"
- fi
- for lt_tmp_nm in $lt_nm_to_check; do
- lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
- for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do
- IFS="$lt_save_ifs"
- test -z "$ac_dir" && ac_dir=.
- tmp_nm="$ac_dir/$lt_tmp_nm"
- if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then
- # Check to see if the nm accepts a BSD-compat flag.
- # Adding the `sed 1q' prevents false positives on HP-UX, which says:
- # nm: unknown option "B" ignored
- # Tru64's nm complains that /dev/null is an invalid object file
- case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in
- */dev/null* | *'Invalid file or object type'*)
- lt_cv_path_NM="$tmp_nm -B"
- break
- ;;
- *)
- case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
- */dev/null*)
- lt_cv_path_NM="$tmp_nm -p"
- break
- ;;
- *)
- lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
- continue # so that we can try to find one that supports BSD flags
- ;;
- esac
- ;;
- esac
- fi
- done
- IFS="$lt_save_ifs"
- done
- test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm
-fi
-fi
-{ echo "$as_me:$LINENO: result: $lt_cv_path_NM" >&5
-echo "${ECHO_T}$lt_cv_path_NM" >&6; }
-NM="$lt_cv_path_NM"
-
-{ echo "$as_me:$LINENO: checking whether ln -s works" >&5
-echo $ECHO_N "checking whether ln -s works... $ECHO_C" >&6; }
-LN_S=$as_ln_s
-if test "$LN_S" = "ln -s"; then
- { echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6; }
-else
- { echo "$as_me:$LINENO: result: no, using $LN_S" >&5
-echo "${ECHO_T}no, using $LN_S" >&6; }
-fi
-
-{ echo "$as_me:$LINENO: checking how to recognize dependent libraries" >&5
-echo $ECHO_N "checking how to recognize dependent libraries... $ECHO_C" >&6; }
-if test "${lt_cv_deplibs_check_method+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- lt_cv_file_magic_cmd='$MAGIC_CMD'
-lt_cv_file_magic_test_file=
-lt_cv_deplibs_check_method='unknown'
-# Need to set the preceding variable on all platforms that support
-# interlibrary dependencies.
-# 'none' -- dependencies not supported.
-# `unknown' -- same as none, but documents that we really don't know.
-# 'pass_all' -- all dependencies passed with no checks.
-# 'test_compile' -- check by making test program.
-# 'file_magic [[regex]]' -- check by looking for files in library path
-# which responds to the $file_magic_cmd with a given extended regex.
-# If you have `file' or equivalent on your system and you're not sure
-# whether `pass_all' will *always* work, you probably want this one.
-
-case $host_os in
-aix[4-9]*)
- lt_cv_deplibs_check_method=pass_all
- ;;
-
-beos*)
- lt_cv_deplibs_check_method=pass_all
- ;;
-
-bsdi[45]*)
- lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)'
- lt_cv_file_magic_cmd='/usr/bin/file -L'
- lt_cv_file_magic_test_file=/shlib/libc.so
- ;;
-
-cygwin*)
- # func_win32_libid is a shell function defined in ltmain.sh
- lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
- lt_cv_file_magic_cmd='func_win32_libid'
- ;;
-
-mingw* | pw32*)
- # Base MSYS/MinGW do not provide the 'file' command needed by
- # func_win32_libid shell function, so use a weaker test based on 'objdump',
- # unless we find 'file', for example because we are cross-compiling.
- if ( file / ) >/dev/null 2>&1; then
- lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
- lt_cv_file_magic_cmd='func_win32_libid'
- else
- lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'
- lt_cv_file_magic_cmd='$OBJDUMP -f'
- fi
- ;;
-
-darwin* | rhapsody*)
- lt_cv_deplibs_check_method=pass_all
- ;;
-
-freebsd* | dragonfly*)
- if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then
- case $host_cpu in
- i*86 )
- # Not sure whether the presence of OpenBSD here was a mistake.
- # Let's accept both of them until this is cleared up.
- lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library'
- lt_cv_file_magic_cmd=/usr/bin/file
- lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
- ;;
- esac
- else
- lt_cv_deplibs_check_method=pass_all
- fi
- ;;
-
-gnu*)
- lt_cv_deplibs_check_method=pass_all
- ;;
-
-hpux10.20* | hpux11*)
- lt_cv_file_magic_cmd=/usr/bin/file
- case $host_cpu in
- ia64*)
- lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64'
- lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
- ;;
- hppa*64*)
- lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]'
- lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl
- ;;
- *)
- lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9].[0-9]) shared library'
- lt_cv_file_magic_test_file=/usr/lib/libc.sl
- ;;
- esac
- ;;
-
-interix[3-9]*)
- # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here
- lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$'
- ;;
-
-irix5* | irix6* | nonstopux*)
- case $LD in
- *-32|*"-32 ") libmagic=32-bit;;
- *-n32|*"-n32 ") libmagic=N32;;
- *-64|*"-64 ") libmagic=64-bit;;
- *) libmagic=never-match;;
- esac
- lt_cv_deplibs_check_method=pass_all
- ;;
-
-# This must be Linux ELF.
-linux* | k*bsd*-gnu)
- lt_cv_deplibs_check_method=pass_all
- ;;
-
-netbsd*)
- if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then
- lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
- else
- lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$'
- fi
- ;;
-
-newos6*)
- lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)'
- lt_cv_file_magic_cmd=/usr/bin/file
- lt_cv_file_magic_test_file=/usr/lib/libnls.so
- ;;
-
-nto-qnx*)
- lt_cv_deplibs_check_method=unknown
- ;;
-
-openbsd*)
- if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
- lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$'
- else
- lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
- fi
- ;;
-
-osf3* | osf4* | osf5*)
- lt_cv_deplibs_check_method=pass_all
- ;;
-
-rdos*)
- lt_cv_deplibs_check_method=pass_all
- ;;
-
-solaris*)
- lt_cv_deplibs_check_method=pass_all
- ;;
-
-sysv4 | sysv4.3*)
- case $host_vendor in
- motorola)
- lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]'
- lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
- ;;
- ncr)
- lt_cv_deplibs_check_method=pass_all
- ;;
- sequent)
- lt_cv_file_magic_cmd='/bin/file'
- lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )'
- ;;
- sni)
- lt_cv_file_magic_cmd='/bin/file'
- lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib"
- lt_cv_file_magic_test_file=/lib/libc.so
- ;;
- siemens)
- lt_cv_deplibs_check_method=pass_all
- ;;
- pc)
- lt_cv_deplibs_check_method=pass_all
- ;;
- esac
- ;;
-
-sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
- lt_cv_deplibs_check_method=pass_all
- ;;
-esac
-
-fi
-{ echo "$as_me:$LINENO: result: $lt_cv_deplibs_check_method" >&5
-echo "${ECHO_T}$lt_cv_deplibs_check_method" >&6; }
-file_magic_cmd=$lt_cv_file_magic_cmd
-deplibs_check_method=$lt_cv_deplibs_check_method
-test -z "$deplibs_check_method" && deplibs_check_method=unknown
-
-
-
-
-# If no C compiler was specified, use CC.
-LTCC=${LTCC-"$CC"}
-
-# If no C compiler flags were specified, use CFLAGS.
-LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
-
-# Allow CC to be a program name with arguments.
-compiler=$CC
-
-
-# Check whether --enable-libtool-lock was given.
-if test "${enable_libtool_lock+set}" = set; then
- enableval=$enable_libtool_lock;
-fi
-
-test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
-
-# Some flags need to be propagated to the compiler or linker for good
-# libtool support.
-case $host in
-ia64-*-hpux*)
- # Find out which ABI we are using.
- echo 'int i;' > conftest.$ac_ext
- if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
- ac_status=$?
- 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"
- ;;
- *ELF-64*)
- HPUX_IA64_MODE="64"
- ;;
- esac
- fi
- rm -rf conftest*
- ;;
-*-*-irix6*)
- # Find out which ABI we are using.
- echo '#line 5014 "configure"' > conftest.$ac_ext
- if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
- ac_status=$?
- 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*)
- LD="${LD-ld} -melf32bsmip"
- ;;
- *N32*)
- LD="${LD-ld} -melf32bmipn32"
- ;;
- *64-bit*)
- LD="${LD-ld} -melf64bmip"
- ;;
- esac
- else
- case `/usr/bin/file conftest.$ac_objext` in
- *32-bit*)
- LD="${LD-ld} -32"
- ;;
- *N32*)
- LD="${LD-ld} -n32"
- ;;
- *64-bit*)
- LD="${LD-ld} -64"
- ;;
- esac
- fi
- fi
- rm -rf conftest*
- ;;
-
-x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \
-s390*-*linux*|sparc*-*linux*)
- # Find out which ABI we are using.
- echo 'int i;' > conftest.$ac_ext
- if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; then
- case `/usr/bin/file conftest.o` in
- *32-bit*)
- case $host in
- x86_64-*kfreebsd*-gnu)
- LD="${LD-ld} -m elf_i386_fbsd"
- ;;
- x86_64-*linux*)
- LD="${LD-ld} -m elf_i386"
- ;;
- ppc64-*linux*|powerpc64-*linux*)
- LD="${LD-ld} -m elf32ppclinux"
- ;;
- s390x-*linux*)
- LD="${LD-ld} -m elf_s390"
- ;;
- sparc64-*linux*)
- LD="${LD-ld} -m elf32_sparc"
- ;;
- esac
- ;;
- *64-bit*)
- case $host in
- x86_64-*kfreebsd*-gnu)
- LD="${LD-ld} -m elf_x86_64_fbsd"
- ;;
- x86_64-*linux*)
- LD="${LD-ld} -m elf_x86_64"
- ;;
- ppc*-*linux*|powerpc*-*linux*)
- LD="${LD-ld} -m elf64ppc"
- ;;
- s390*-*linux*)
- LD="${LD-ld} -m elf64_s390"
- ;;
- sparc*-*linux*)
- LD="${LD-ld} -m elf64_sparc"
- ;;
- esac
- ;;
- esac
- fi
- rm -rf conftest*
- ;;
-
-*-*-sco3.2v5*)
- # On SCO OpenServer 5, we need -belf to get full-featured binaries.
- SAVE_CFLAGS="$CFLAGS"
- CFLAGS="$CFLAGS -belf"
- { echo "$as_me:$LINENO: checking whether the C compiler needs -belf" >&5
-echo $ECHO_N "checking whether the C compiler needs -belf... $ECHO_C" >&6; }
-if test "${lt_cv_cc_needs_belf+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_ext=c
-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
-
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- 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 "echo \"\$as_me:$LINENO: $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
- 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 &&
- $as_test_x conftest$ac_exeext; then
- lt_cv_cc_needs_belf=yes
-else
- 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_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'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-fi
-{ echo "$as_me:$LINENO: result: $lt_cv_cc_needs_belf" >&5
-echo "${ECHO_T}$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
- CFLAGS="$SAVE_CFLAGS"
- fi
- ;;
-sparc*-*solaris*)
- # Find out which ABI we are using.
- echo 'int i;' > conftest.$ac_ext
- if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
- ac_status=$?
- 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
- yes*) LD="${LD-ld} -m elf64_sparc" ;;
- *)
- if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then
- LD="${LD-ld} -64"
- fi
- ;;
- esac
- ;;
- esac
- fi
- rm -rf conftest*
- ;;
-
-*-*-cygwin* | *-*-mingw* | *-*-pw32*)
- if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args.
-set dummy ${ac_tool_prefix}dlltool; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_DLLTOOL+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$DLLTOOL"; then
- ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-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
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-DLLTOOL=$ac_cv_prog_DLLTOOL
-if test -n "$DLLTOOL"; then
- { echo "$as_me:$LINENO: result: $DLLTOOL" >&5
-echo "${ECHO_T}$DLLTOOL" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
-fi
-if test -z "$ac_cv_prog_DLLTOOL"; then
- ac_ct_DLLTOOL=$DLLTOOL
- # Extract the first word of "dlltool", so it can be a program name with args.
-set dummy dlltool; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_ac_ct_DLLTOOL+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$ac_ct_DLLTOOL"; then
- ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-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
- 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_DLLTOOL="dlltool"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL
-if test -n "$ac_ct_DLLTOOL"; then
- { echo "$as_me:$LINENO: result: $ac_ct_DLLTOOL" >&5
-echo "${ECHO_T}$ac_ct_DLLTOOL" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
- if test "x$ac_ct_DLLTOOL" = x; then
- DLLTOOL="false"
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ 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
-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
- DLLTOOL=$ac_ct_DLLTOOL
- fi
-else
- DLLTOOL="$ac_cv_prog_DLLTOOL"
-fi
-
- if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}as", so it can be a program name with args.
-set dummy ${ac_tool_prefix}as; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_AS+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$AS"; then
- ac_cv_prog_AS="$AS" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-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
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_AS="${ac_tool_prefix}as"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-AS=$ac_cv_prog_AS
-if test -n "$AS"; then
- { echo "$as_me:$LINENO: result: $AS" >&5
-echo "${ECHO_T}$AS" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
-fi
-if test -z "$ac_cv_prog_AS"; then
- ac_ct_AS=$AS
- # Extract the first word of "as", so it can be a program name with args.
-set dummy as; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_ac_ct_AS+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$ac_ct_AS"; then
- ac_cv_prog_ac_ct_AS="$ac_ct_AS" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-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
- 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_AS="as"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_AS=$ac_cv_prog_ac_ct_AS
-if test -n "$ac_ct_AS"; then
- { echo "$as_me:$LINENO: result: $ac_ct_AS" >&5
-echo "${ECHO_T}$ac_ct_AS" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
- if test "x$ac_ct_AS" = x; then
- AS="false"
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ 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
-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
- AS=$ac_ct_AS
- fi
-else
- AS="$ac_cv_prog_AS"
-fi
-
- 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
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_OBJDUMP+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$OBJDUMP"; then
- ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-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
- 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"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-OBJDUMP=$ac_cv_prog_OBJDUMP
-if test -n "$OBJDUMP"; then
- { echo "$as_me:$LINENO: result: $OBJDUMP" >&5
-echo "${ECHO_T}$OBJDUMP" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
-fi
-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
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_ac_ct_OBJDUMP+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$ac_ct_OBJDUMP"; then
- ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-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
- 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"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP
-if test -n "$ac_ct_OBJDUMP"; then
- { echo "$as_me:$LINENO: result: $ac_ct_OBJDUMP" >&5
-echo "${ECHO_T}$ac_ct_OBJDUMP" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
- if test "x$ac_ct_OBJDUMP" = x; then
- OBJDUMP="false"
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ 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
-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
- fi
-else
- OBJDUMP="$ac_cv_prog_OBJDUMP"
-fi
-
- ;;
-
-esac
-
-need_locks="$enable_libtool_lock"
-
-
-ac_ext=c
-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
-{ echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5
-echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&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
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- # Double quotes because CPP needs to be expanded
- for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
- do
- ac_preproc_ok=false
-for ac_c_preproc_warn_flag in '' yes
-do
- # Use a header file that comes with gcc, so configuring glibc
- # with a fresh cross-compiler works.
- # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- # <limits.h> 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 >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
- Syntax error
-_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 "echo \"\$as_me:$LINENO: $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
- 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
- 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.$ac_ext
-
- # OK, works on sane cases. Now check whether nonexistent headers
- # can be detected and how.
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <ac_nonexistent.h>
-_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 "echo \"\$as_me:$LINENO: $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
- 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
- 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.$ac_ext
-
-done
-# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.err conftest.$ac_ext
-if $ac_preproc_ok; then
- break
-fi
-
- done
- ac_cv_prog_CPP=$CPP
-
-fi
- CPP=$ac_cv_prog_CPP
-else
- ac_cv_prog_CPP=$CPP
-fi
-{ echo "$as_me:$LINENO: result: $CPP" >&5
-echo "${ECHO_T}$CPP" >&6; }
-ac_preproc_ok=false
-for ac_c_preproc_warn_flag in '' yes
-do
- # Use a header file that comes with gcc, so configuring glibc
- # with a fresh cross-compiler works.
- # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- # <limits.h> 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 >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
- Syntax error
-_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 "echo \"\$as_me:$LINENO: $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
- 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
- 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.$ac_ext
-
- # OK, works on sane cases. Now check whether nonexistent headers
- # can be detected and how.
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <ac_nonexistent.h>
-_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 "echo \"\$as_me:$LINENO: $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
- 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
- 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.$ac_ext
-
-done
-# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.err conftest.$ac_ext
-if $ac_preproc_ok; then
- :
-else
- { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check
-See \`config.log' for more details." >&5
-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
-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
-
-
-{ echo "$as_me:$LINENO: checking for ANSI C header files" >&5
-echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6; }
-if test "${ac_cv_header_stdc+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <float.h>
-
-int
-main ()
-{
-
- ;
- 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 "echo \"\$as_me:$LINENO: $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
- 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
- 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 >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <string.h>
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- $EGREP "memchr" >/dev/null 2>&1; then
- :
-else
- ac_cv_header_stdc=no
-fi
-rm -f conftest*
-
-fi
-
-if test $ac_cv_header_stdc = yes; then
- # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <stdlib.h>
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- $EGREP "free" >/dev/null 2>&1; then
- :
-else
- ac_cv_header_stdc=no
-fi
-rm -f conftest*
-
-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
- :
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <ctype.h>
-#include <stdlib.h>
-#if ((' ' & 0x0FF) == 0x020)
-# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
-# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
-#else
-# define ISLOWER(c) \
- (('a' <= (c) && (c) <= 'i') \
- || ('j' <= (c) && (c) <= 'r') \
- || ('s' <= (c) && (c) <= 'z'))
-# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
-#endif
-
-#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
-int
-main ()
-{
- int i;
- for (i = 0; i < 256; i++)
- if (XOR (islower (i), ISLOWER (i))
- || toupper (i) != TOUPPER (i))
- return 2;
- return 0;
-}
-_ACEOF
-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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>&5
- ac_status=$?
- 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- :
-else
- echo "$as_me: program exited with status $ac_status" >&5
-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.$ac_ext
-fi
-
-
-fi
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
-echo "${ECHO_T}$ac_cv_header_stdc" >&6; }
-if test $ac_cv_header_stdc = yes; then
-
-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=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
-{ echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&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 "echo \"\$as_me:$LINENO: $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
- 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
- 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 echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
- cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
-_ACEOF
-
-fi
-
-done
-
-
-
-for ac_header in dlfcn.h
-do
-as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- { echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking $ac_header usability" >&5
-echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&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 "echo \"\$as_me:$LINENO: $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
- 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
- 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
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking $ac_header presence" >&5
-echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&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 "echo \"\$as_me:$LINENO: $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
- 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
- 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
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
-echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
-
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- eval "$as_ac_Header=\$ac_header_preproc"
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
- cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
-_ACEOF
-
-fi
-
-done
-
-
-
-if test -n "$CXX" && ( test "X$CXX" != "Xno" &&
- ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) ||
- (test "X$CXX" != "Xg++"))) ; then
- ac_ext=cpp
-ac_cpp='$CXXCPP $CPPFLAGS'
-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
-{ echo "$as_me:$LINENO: checking how to run the C++ preprocessor" >&5
-echo $ECHO_N "checking how to run the C++ preprocessor... $ECHO_C" >&6; }
-if test -z "$CXXCPP"; then
- if test "${ac_cv_prog_CXXCPP+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- # Double quotes because CXXCPP needs to be expanded
- for CXXCPP in "$CXX -E" "/lib/cpp"
- do
- ac_preproc_ok=false
-for ac_cxx_preproc_warn_flag in '' yes
-do
- # Use a header file that comes with gcc, so configuring glibc
- # with a fresh cross-compiler works.
- # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- # <limits.h> 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 >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
- Syntax error
-_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 "echo \"\$as_me:$LINENO: $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
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" ||
- test ! -s conftest.err
- }; then
- :
-else
- 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.$ac_ext
-
- # OK, works on sane cases. Now check whether nonexistent headers
- # can be detected and how.
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <ac_nonexistent.h>
-_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 "echo \"\$as_me:$LINENO: $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
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" ||
- test ! -s conftest.err
- }; then
- # Broken: success on invalid input.
-continue
-else
- 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.$ac_ext
-
-done
-# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.err conftest.$ac_ext
-if $ac_preproc_ok; then
- break
-fi
-
- done
- ac_cv_prog_CXXCPP=$CXXCPP
-
-fi
- CXXCPP=$ac_cv_prog_CXXCPP
-else
- ac_cv_prog_CXXCPP=$CXXCPP
-fi
-{ echo "$as_me:$LINENO: result: $CXXCPP" >&5
-echo "${ECHO_T}$CXXCPP" >&6; }
-ac_preproc_ok=false
-for ac_cxx_preproc_warn_flag in '' yes
-do
- # Use a header file that comes with gcc, so configuring glibc
- # with a fresh cross-compiler works.
- # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- # <limits.h> 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 >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
- Syntax error
-_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 "echo \"\$as_me:$LINENO: $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
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" ||
- test ! -s conftest.err
- }; then
- :
-else
- 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.$ac_ext
-
- # OK, works on sane cases. Now check whether nonexistent headers
- # can be detected and how.
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <ac_nonexistent.h>
-_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 "echo \"\$as_me:$LINENO: $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
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" ||
- test ! -s conftest.err
- }; then
- # Broken: success on invalid input.
-continue
-else
- 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.$ac_ext
-
-done
-# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.err conftest.$ac_ext
-if $ac_preproc_ok; then
- :
-else
- { { echo "$as_me:$LINENO: error: C++ preprocessor \"$CXXCPP\" fails sanity check
-See \`config.log' for more details." >&5
-echo "$as_me: error: C++ preprocessor \"$CXXCPP\" fails sanity check
-See \`config.log' for more details." >&2;}
- { (exit 1); exit 1; }; }
-fi
-
-ac_ext=cpp
-ac_cpp='$CXXCPP $CPPFLAGS'
-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
-
-fi
-
-ac_ext=f
-ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5'
-ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_f77_compiler_gnu
-if test -n "$ac_tool_prefix"; then
- for ac_prog in g77 xlf f77 frt pgf77 cf77 fort77 fl32 af77 xlf90 f90 pgf90 pghpf epcf90 gfortran g95 xlf95 f95 fort ifort ifc efc pgf95 lf95 ftn
- 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
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_F77+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$F77"; then
- ac_cv_prog_F77="$F77" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-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
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_F77="$ac_tool_prefix$ac_prog"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-F77=$ac_cv_prog_F77
-if test -n "$F77"; then
- { echo "$as_me:$LINENO: result: $F77" >&5
-echo "${ECHO_T}$F77" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
- test -n "$F77" && break
- done
-fi
-if test -z "$F77"; then
- ac_ct_F77=$F77
- for ac_prog in g77 xlf f77 frt pgf77 cf77 fort77 fl32 af77 xlf90 f90 pgf90 pghpf epcf90 gfortran g95 xlf95 f95 fort ifort ifc efc pgf95 lf95 ftn
-do
- # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_ac_ct_F77+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$ac_ct_F77"; then
- ac_cv_prog_ac_ct_F77="$ac_ct_F77" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-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
- 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_F77="$ac_prog"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_F77=$ac_cv_prog_ac_ct_F77
-if test -n "$ac_ct_F77"; then
- { echo "$as_me:$LINENO: result: $ac_ct_F77" >&5
-echo "${ECHO_T}$ac_ct_F77" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
- test -n "$ac_ct_F77" && break
-done
-
- if test "x$ac_ct_F77" = x; then
- F77=""
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ 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
-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
- F77=$ac_ct_F77
- fi
-fi
-
-
-# Provide some information about the compiler.
-echo "$as_me:$LINENO: checking for Fortran 77 compiler version" >&5
-ac_compiler=`set X $ac_compile; echo $2`
-{ (ac_try="$ac_compiler --version >&5"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compiler --version >&5") 2>&5
- ac_status=$?
- 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compiler -v >&5") 2>&5
- ac_status=$?
- 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compiler -V >&5") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }
-rm -f a.out
-
-# If we don't use `.F' as extension, the preprocessor is not run on the
-# input file. (Note that this only needs to work for GNU compilers.)
-ac_save_ext=$ac_ext
-ac_ext=F
-{ echo "$as_me:$LINENO: checking whether we are using the GNU Fortran 77 compiler" >&5
-echo $ECHO_N "checking whether we are using the GNU Fortran 77 compiler... $ECHO_C" >&6; }
-if test "${ac_cv_f77_compiler_gnu+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
- program main
-#ifndef __GNUC__
- choke me
-#endif
-
- end
-_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 "echo \"\$as_me:$LINENO: $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
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_f77_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_compiler_gnu=yes
-else
- 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_f77_compiler_gnu=$ac_compiler_gnu
-
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_f77_compiler_gnu" >&5
-echo "${ECHO_T}$ac_cv_f77_compiler_gnu" >&6; }
-ac_ext=$ac_save_ext
-ac_test_FFLAGS=${FFLAGS+set}
-ac_save_FFLAGS=$FFLAGS
-FFLAGS=
-{ echo "$as_me:$LINENO: checking whether $F77 accepts -g" >&5
-echo $ECHO_N "checking whether $F77 accepts -g... $ECHO_C" >&6; }
-if test "${ac_cv_prog_f77_g+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- FFLAGS=-g
-cat >conftest.$ac_ext <<_ACEOF
- program main
-
- end
-_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 "echo \"\$as_me:$LINENO: $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
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_f77_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_cv_prog_f77_g=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_prog_f77_g=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_prog_f77_g" >&5
-echo "${ECHO_T}$ac_cv_prog_f77_g" >&6; }
-if test "$ac_test_FFLAGS" = set; then
- FFLAGS=$ac_save_FFLAGS
-elif test $ac_cv_prog_f77_g = yes; then
- if test "x$ac_cv_f77_compiler_gnu" = xyes; then
- FFLAGS="-g -O2"
- else
- FFLAGS="-g"
- fi
-else
- if test "x$ac_cv_f77_compiler_gnu" = xyes; then
- FFLAGS="-O2"
- else
- FFLAGS=
- fi
-fi
-
-G77=`test $ac_compiler_gnu = yes && echo yes`
-ac_ext=c
-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
-
-
-
-# Autoconf 2.13's AC_OBJEXT and AC_EXEEXT macros only works for C compilers!
-# find the maximum length of command line arguments
-{ echo "$as_me:$LINENO: checking the maximum length of command line arguments" >&5
-echo $ECHO_N "checking the maximum length of command line arguments... $ECHO_C" >&6; }
-if test "${lt_cv_sys_max_cmd_len+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- i=0
- teststring="ABCD"
-
- case $build_os in
- msdosdjgpp*)
- # On DJGPP, this test can blow up pretty badly due to problems in libc
- # (any single argument exceeding 2000 bytes causes a buffer overrun
- # during glob expansion). Even if it were fixed, the result of this
- # check would be larger than it should be.
- lt_cv_sys_max_cmd_len=12288; # 12K is about right
- ;;
-
- gnu*)
- # Under GNU Hurd, this test is not required because there is
- # no limit to the length of command line arguments.
- # Libtool will interpret -1 as no limit whatsoever
- lt_cv_sys_max_cmd_len=-1;
- ;;
-
- cygwin* | mingw*)
- # On Win9x/ME, this test blows up -- it succeeds, but takes
- # about 5 minutes as the teststring grows exponentially.
- # Worse, since 9x/ME are not pre-emptively multitasking,
- # you end up with a "frozen" computer, even though with patience
- # the test eventually succeeds (with a max line length of 256k).
- # Instead, let's just punt: use the minimum linelength reported by
- # all of the supported platforms: 8192 (on NT/2K/XP).
- lt_cv_sys_max_cmd_len=8192;
- ;;
-
- amigaos*)
- # On AmigaOS with pdksh, this test takes hours, literally.
- # So we just punt and use a minimum line length of 8192.
- lt_cv_sys_max_cmd_len=8192;
- ;;
-
- netbsd* | freebsd* | openbsd* | darwin* | dragonfly*)
- # This has been around since 386BSD, at least. Likely further.
- if test -x /sbin/sysctl; then
- lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
- elif test -x /usr/sbin/sysctl; then
- lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax`
- else
- lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs
- fi
- # And add a safety zone
- lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
- lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
- ;;
-
- interix*)
- # We know the value 262144 and hardcode it with a safety zone (like BSD)
- lt_cv_sys_max_cmd_len=196608
- ;;
-
- osf*)
- # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure
- # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not
- # nice to cause kernel panics so lets avoid the loop below.
- # First set a reasonable default.
- lt_cv_sys_max_cmd_len=16384
- #
- if test -x /sbin/sysconfig; then
- case `/sbin/sysconfig -q proc exec_disable_arg_limit` in
- *1*) lt_cv_sys_max_cmd_len=-1 ;;
- esac
- fi
- ;;
- sco3.2v5*)
- lt_cv_sys_max_cmd_len=102400
- ;;
- sysv5* | sco5v6* | sysv4.2uw2*)
- kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null`
- if test -n "$kargmax"; then
- lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'`
- else
- lt_cv_sys_max_cmd_len=32768
- fi
- ;;
- *)
- lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null`
- if test -n "$lt_cv_sys_max_cmd_len"; then
- lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
- lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
- else
- SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
- while (test "X"`$SHELL $0 --fallback-echo "X$teststring" 2>/dev/null` \
- = "XX$teststring") >/dev/null 2>&1 &&
- new_result=`expr "X$teststring" : ".*" 2>&1` &&
- lt_cv_sys_max_cmd_len=$new_result &&
- test $i != 17 # 1/2 MB should be enough
- do
- i=`expr $i + 1`
- teststring=$teststring$teststring
- done
- teststring=
- # Add a significant safety factor because C++ compilers can tack on massive
- # amounts of additional arguments before passing them to the linker.
- # It appears as though 1/2 is a usable value.
- lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2`
- fi
- ;;
- esac
-
-fi
-
-if test -n $lt_cv_sys_max_cmd_len ; then
- { echo "$as_me:$LINENO: result: $lt_cv_sys_max_cmd_len" >&5
-echo "${ECHO_T}$lt_cv_sys_max_cmd_len" >&6; }
-else
- { echo "$as_me:$LINENO: result: none" >&5
-echo "${ECHO_T}none" >&6; }
-fi
-
-
-
-
-
-# Check for command to grab the raw symbol name followed by C symbol from nm.
-{ echo "$as_me:$LINENO: checking command to parse $NM output from $compiler object" >&5
-echo $ECHO_N "checking command to parse $NM output from $compiler object... $ECHO_C" >&6; }
-if test "${lt_cv_sys_global_symbol_pipe+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-
-# These are sane defaults that work on at least a few old systems.
-# [They come from Ultrix. What could be older than Ultrix?!! ;)]
-
-# Character class describing NM global symbol codes.
-symcode='[BCDEGRST]'
-
-# Regexp to match symbols that can be accessed directly from C.
-sympat='\([_A-Za-z][_A-Za-z0-9]*\)'
-
-# Transform an extracted symbol line into a proper C declaration
-lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern int \1;/p'"
-
-# Transform an extracted symbol line into symbol name and symbol address
-lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode \([^ ]*\) \([^ ]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'"
-
-# Define system-specific variables.
-case $host_os in
-aix*)
- symcode='[BCDT]'
- ;;
-cygwin* | mingw* | pw32*)
- symcode='[ABCDGISTW]'
- ;;
-hpux*) # Its linker distinguishes data from code symbols
- if test "$host_cpu" = ia64; then
- symcode='[ABCDEGRST]'
- fi
- lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
- lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'"
- ;;
-linux* | k*bsd*-gnu)
- if test "$host_cpu" = ia64; then
- symcode='[ABCDGIRSTW]'
- lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
- lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'"
- fi
- ;;
-irix* | nonstopux*)
- symcode='[BCDEGRST]'
- ;;
-osf*)
- symcode='[BCDEGQRST]'
- ;;
-solaris*)
- symcode='[BDRT]'
- ;;
-sco3.2v5*)
- symcode='[DT]'
- ;;
-sysv4.2uw2*)
- symcode='[DT]'
- ;;
-sysv5* | sco5v6* | unixware* | OpenUNIX*)
- symcode='[ABDT]'
- ;;
-sysv4)
- symcode='[DFNSTU]'
- ;;
-esac
-
-# Handle CRLF in mingw tool chain
-opt_cr=
-case $build_os in
-mingw*)
- opt_cr=`echo 'x\{0,1\}' | tr x '\015'` # option cr in regexp
- ;;
-esac
-
-# If we're using GNU nm, then use its standard symbol codes.
-case `$NM -V 2>&1` in
-*GNU* | *'with BFD'*)
- symcode='[ABCDGIRSTW]' ;;
-esac
-
-# Try without a prefix undercore, then with it.
-for ac_symprfx in "" "_"; do
-
- # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol.
- symxfrm="\\1 $ac_symprfx\\2 \\2"
-
- # Write the raw and C identifiers.
- lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
-
- # Check to see that the pipe works correctly.
- pipe_works=no
-
- rm -f conftest*
- cat > conftest.$ac_ext <<EOF
-#ifdef __cplusplus
-extern "C" {
-#endif
-char nm_test_var;
-void nm_test_func(){}
-#ifdef __cplusplus
-}
-#endif
-int main(){nm_test_var='a';nm_test_func();return(0);}
-EOF
-
- if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
- ac_status=$?
- 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:$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=$?
- 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"
- else
- rm -f "$nlist"T
- fi
-
- # Make sure that we snagged all the symbols we need.
- if grep ' nm_test_var$' "$nlist" >/dev/null; then
- if grep ' nm_test_func$' "$nlist" >/dev/null; then
- cat <<EOF > conftest.$ac_ext
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-EOF
- # Now generate the symbol file.
- eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | grep -v main >> conftest.$ac_ext'
-
- cat <<EOF >> conftest.$ac_ext
-#if defined (__STDC__) && __STDC__
-# define lt_ptr_t void *
-#else
-# define lt_ptr_t char *
-# define const
-#endif
-
-/* The mapping between symbol names and symbols. */
-const struct {
- const char *name;
- lt_ptr_t address;
-}
-lt_preloaded_symbols[] =
-{
-EOF
- $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (lt_ptr_t) \&\2},/" < "$nlist" | grep -v main >> conftest.$ac_ext
- cat <<\EOF >> conftest.$ac_ext
- {0, (lt_ptr_t) 0}
-};
-
-#ifdef __cplusplus
-}
-#endif
-EOF
- # Now try linking the two files.
- mv conftest.$ac_objext conftstm.$ac_objext
- lt_save_LIBS="$LIBS"
- lt_save_CFLAGS="$CFLAGS"
- LIBS="conftstm.$ac_objext"
- CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag"
- if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && test -s conftest${ac_exeext}; then
- pipe_works=yes
- fi
- LIBS="$lt_save_LIBS"
- CFLAGS="$lt_save_CFLAGS"
- else
- echo "cannot find nm_test_func in $nlist" >&5
- fi
- else
- echo "cannot find nm_test_var in $nlist" >&5
- fi
- else
- echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5
- fi
- else
- echo "$progname: failed program was:" >&5
- cat conftest.$ac_ext >&5
- fi
- rm -rf conftest* conftst*
-
- # Do not use the global_symbol_pipe unless it works.
- if test "$pipe_works" = yes; then
- break
- else
- lt_cv_sys_global_symbol_pipe=
- fi
-done
-
-fi
-
-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
- { echo "$as_me:$LINENO: result: failed" >&5
-echo "${ECHO_T}failed" >&6; }
-else
- { echo "$as_me:$LINENO: result: ok" >&5
-echo "${ECHO_T}ok" >&6; }
-fi
-
-{ echo "$as_me:$LINENO: checking for objdir" >&5
-echo $ECHO_N "checking for objdir... $ECHO_C" >&6; }
-if test "${lt_cv_objdir+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- rm -f .libs 2>/dev/null
-mkdir .libs 2>/dev/null
-if test -d .libs; then
- lt_cv_objdir=.libs
-else
- # MS-DOS does not allow filenames that begin with a dot.
- lt_cv_objdir=_libs
-fi
-rmdir .libs 2>/dev/null
-fi
-{ echo "$as_me:$LINENO: result: $lt_cv_objdir" >&5
-echo "${ECHO_T}$lt_cv_objdir" >&6; }
-objdir=$lt_cv_objdir
-
-
-
-
-
-case $host_os in
-aix3*)
- # AIX sometimes has problems with the GCC collect2 program. For some
- # reason, if we set the COLLECT_NAMES environment variable, the problems
- # vanish in a puff of smoke.
- if test "X${COLLECT_NAMES+set}" != Xset; then
- COLLECT_NAMES=
- export COLLECT_NAMES
- fi
- ;;
-esac
-
-# Sed substitution that helps us do robust quoting. It backslashifies
-# metacharacters that are still active within double-quoted strings.
-Xsed='sed -e 1s/^X//'
-sed_quote_subst='s/\([\\"\\`$\\\\]\)/\\\1/g'
-
-# Same as above, but do not quote variable references.
-double_quote_subst='s/\([\\"\\`\\\\]\)/\\\1/g'
-
-# Sed substitution to delay expansion of an escaped shell variable in a
-# double_quote_subst'ed string.
-delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
-
-# Sed substitution to avoid accidental globbing in evaled expressions
-no_glob_subst='s/\*/\\\*/g'
-
-# Constants:
-rm="rm -f"
-
-# Global variables:
-default_ofile=libtool
-can_build_shared=yes
-
-# All known linkers require a `.a' archive for static linking (except MSVC,
-# which needs '.lib').
-libext=a
-ltmain="$ac_aux_dir/ltmain.sh"
-ofile="$default_ofile"
-with_gnu_ld="$lt_cv_prog_gnu_ld"
-
-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
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_AR+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$AR"; then
- ac_cv_prog_AR="$AR" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-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
- 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"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-AR=$ac_cv_prog_AR
-if test -n "$AR"; then
- { echo "$as_me:$LINENO: result: $AR" >&5
-echo "${ECHO_T}$AR" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
-fi
-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
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_ac_ct_AR+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$ac_ct_AR"; then
- ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-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
- 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"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_AR=$ac_cv_prog_ac_ct_AR
-if test -n "$ac_ct_AR"; then
- { echo "$as_me:$LINENO: result: $ac_ct_AR" >&5
-echo "${ECHO_T}$ac_ct_AR" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
- if test "x$ac_ct_AR" = x; then
- AR="false"
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ 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
-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
- fi
-else
- AR="$ac_cv_prog_AR"
-fi
-
-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
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_RANLIB+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$RANLIB"; then
- ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-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
- 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"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-RANLIB=$ac_cv_prog_RANLIB
-if test -n "$RANLIB"; then
- { echo "$as_me:$LINENO: result: $RANLIB" >&5
-echo "${ECHO_T}$RANLIB" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
-fi
-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
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$ac_ct_RANLIB"; then
- ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-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
- 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"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
-if test -n "$ac_ct_RANLIB"; then
- { echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5
-echo "${ECHO_T}$ac_ct_RANLIB" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
- if test "x$ac_ct_RANLIB" = x; then
- RANLIB=":"
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ 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
-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
- fi
-else
- RANLIB="$ac_cv_prog_RANLIB"
-fi
-
-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
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_STRIP+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$STRIP"; then
- ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-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
- 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"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-STRIP=$ac_cv_prog_STRIP
-if test -n "$STRIP"; then
- { echo "$as_me:$LINENO: result: $STRIP" >&5
-echo "${ECHO_T}$STRIP" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
-fi
-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
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$ac_ct_STRIP"; then
- ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-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
- 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"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
-if test -n "$ac_ct_STRIP"; then
- { echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5
-echo "${ECHO_T}$ac_ct_STRIP" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
- if test "x$ac_ct_STRIP" = x; then
- STRIP=":"
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ 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
-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
- fi
-else
- STRIP="$ac_cv_prog_STRIP"
-fi
-
-
-old_CC="$CC"
-old_CFLAGS="$CFLAGS"
-
-# Set sane defaults for various variables
-test -z "$AR" && AR=ar
-test -z "$AR_FLAGS" && AR_FLAGS=cru
-test -z "$AS" && AS=as
-test -z "$CC" && CC=cc
-test -z "$LTCC" && LTCC=$CC
-test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS
-test -z "$DLLTOOL" && DLLTOOL=dlltool
-test -z "$LD" && LD=ld
-test -z "$LN_S" && LN_S="ln -s"
-test -z "$MAGIC_CMD" && MAGIC_CMD=file
-test -z "$NM" && NM=nm
-test -z "$SED" && SED=sed
-test -z "$OBJDUMP" && OBJDUMP=objdump
-test -z "$RANLIB" && RANLIB=:
-test -z "$STRIP" && STRIP=:
-test -z "$ac_objext" && ac_objext=o
-
-# Determine commands to create old-style static archives.
-old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs'
-old_postinstall_cmds='chmod 644 $oldlib'
-old_postuninstall_cmds=
-
-if test -n "$RANLIB"; then
- case $host_os in
- openbsd*)
- old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib"
- ;;
- *)
- old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib"
- ;;
- esac
- old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib"
-fi
-
-for cc_temp in $compiler""; do
- case $cc_temp in
- compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
- distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
- \-*) ;;
- *) break;;
- esac
-done
-cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"`
-
-
-# Only perform the check for file, if the check method requires it
-case $deplibs_check_method in
-file_magic*)
- if test "$file_magic_cmd" = '$MAGIC_CMD'; then
- { echo "$as_me:$LINENO: checking for ${ac_tool_prefix}file" >&5
-echo $ECHO_N "checking for ${ac_tool_prefix}file... $ECHO_C" >&6; }
-if test "${lt_cv_path_MAGIC_CMD+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- case $MAGIC_CMD in
-[\\/*] | ?:[\\/]*)
- lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
- ;;
-*)
- lt_save_MAGIC_CMD="$MAGIC_CMD"
- lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
- ac_dummy="/usr/bin$PATH_SEPARATOR$PATH"
- for ac_dir in $ac_dummy; do
- IFS="$lt_save_ifs"
- test -z "$ac_dir" && ac_dir=.
- if test -f $ac_dir/${ac_tool_prefix}file; then
- lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file"
- if test -n "$file_magic_test_file"; then
- case $deplibs_check_method in
- "file_magic "*)
- file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
- MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
- if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
- $EGREP "$file_magic_regex" > /dev/null; then
- :
- else
- cat <<EOF 1>&2
-
-*** Warning: the command libtool uses to detect shared libraries,
-*** $file_magic_cmd, produces output that libtool cannot recognize.
-*** The result is that libtool may fail to recognize shared libraries
-*** as such. This will affect the creation of libtool libraries that
-*** depend on shared libraries, but programs linked with such libtool
-*** libraries will work regardless of this problem. Nevertheless, you
-*** may want to report the problem to your system manager and/or to
-*** bug-libtool@gnu.org
-
-EOF
- fi ;;
- esac
- fi
- break
- fi
- done
- IFS="$lt_save_ifs"
- MAGIC_CMD="$lt_save_MAGIC_CMD"
- ;;
-esac
-fi
-
-MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
-if test -n "$MAGIC_CMD"; then
- { echo "$as_me:$LINENO: result: $MAGIC_CMD" >&5
-echo "${ECHO_T}$MAGIC_CMD" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-if test -z "$lt_cv_path_MAGIC_CMD"; then
- if test -n "$ac_tool_prefix"; then
- { echo "$as_me:$LINENO: checking for file" >&5
-echo $ECHO_N "checking for file... $ECHO_C" >&6; }
-if test "${lt_cv_path_MAGIC_CMD+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- case $MAGIC_CMD in
-[\\/*] | ?:[\\/]*)
- lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
- ;;
-*)
- lt_save_MAGIC_CMD="$MAGIC_CMD"
- lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
- ac_dummy="/usr/bin$PATH_SEPARATOR$PATH"
- for ac_dir in $ac_dummy; do
- IFS="$lt_save_ifs"
- test -z "$ac_dir" && ac_dir=.
- if test -f $ac_dir/file; then
- lt_cv_path_MAGIC_CMD="$ac_dir/file"
- if test -n "$file_magic_test_file"; then
- case $deplibs_check_method in
- "file_magic "*)
- file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
- MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
- if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
- $EGREP "$file_magic_regex" > /dev/null; then
- :
- else
- cat <<EOF 1>&2
-
-*** Warning: the command libtool uses to detect shared libraries,
-*** $file_magic_cmd, produces output that libtool cannot recognize.
-*** The result is that libtool may fail to recognize shared libraries
-*** as such. This will affect the creation of libtool libraries that
-*** depend on shared libraries, but programs linked with such libtool
-*** libraries will work regardless of this problem. Nevertheless, you
-*** may want to report the problem to your system manager and/or to
-*** bug-libtool@gnu.org
-
-EOF
- fi ;;
- esac
- fi
- break
- fi
- done
- IFS="$lt_save_ifs"
- MAGIC_CMD="$lt_save_MAGIC_CMD"
- ;;
-esac
-fi
-
-MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
-if test -n "$MAGIC_CMD"; then
- { echo "$as_me:$LINENO: result: $MAGIC_CMD" >&5
-echo "${ECHO_T}$MAGIC_CMD" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
- else
- MAGIC_CMD=:
- fi
-fi
-
- fi
- ;;
-esac
-
-
- case $host_os in
- rhapsody* | darwin*)
- 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
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_DSYMUTIL+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$DSYMUTIL"; then
- ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-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
- 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"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-DSYMUTIL=$ac_cv_prog_DSYMUTIL
-if test -n "$DSYMUTIL"; then
- { echo "$as_me:$LINENO: result: $DSYMUTIL" >&5
-echo "${ECHO_T}$DSYMUTIL" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
-fi
-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
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_ac_ct_DSYMUTIL+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$ac_ct_DSYMUTIL"; then
- ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-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
- 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"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL
-if test -n "$ac_ct_DSYMUTIL"; then
- { echo "$as_me:$LINENO: result: $ac_ct_DSYMUTIL" >&5
-echo "${ECHO_T}$ac_ct_DSYMUTIL" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
- if test "x$ac_ct_DSYMUTIL" = x; then
- DSYMUTIL=":"
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ 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
-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
- fi
-else
- DSYMUTIL="$ac_cv_prog_DSYMUTIL"
-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
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_NMEDIT+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$NMEDIT"; then
- ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-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
- 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"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-NMEDIT=$ac_cv_prog_NMEDIT
-if test -n "$NMEDIT"; then
- { echo "$as_me:$LINENO: result: $NMEDIT" >&5
-echo "${ECHO_T}$NMEDIT" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
-fi
-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
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_ac_ct_NMEDIT+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$ac_ct_NMEDIT"; then
- ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-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
- 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"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT
-if test -n "$ac_ct_NMEDIT"; then
- { echo "$as_me:$LINENO: result: $ac_ct_NMEDIT" >&5
-echo "${ECHO_T}$ac_ct_NMEDIT" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
- if test "x$ac_ct_NMEDIT" = x; then
- NMEDIT=":"
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ 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
-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
- fi
-else
- NMEDIT="$ac_cv_prog_NMEDIT"
-fi
-
-
- { echo "$as_me:$LINENO: checking for -single_module linker flag" >&5
-echo $ECHO_N "checking for -single_module linker flag... $ECHO_C" >&6; }
-if test "${lt_cv_apple_cc_single_mod+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- lt_cv_apple_cc_single_mod=no
- if test -z "${LT_MULTI_MODULE}"; then
- # By default we will add the -single_module flag. You can override
- # by either setting the environment variable LT_MULTI_MODULE
- # non-empty at configure time, or by adding -multi_module to the
- # link flags.
- echo "int foo(void){return 1;}" > conftest.c
- $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
- -dynamiclib ${wl}-single_module conftest.c
- if test -f libconftest.dylib; then
- lt_cv_apple_cc_single_mod=yes
- rm -rf libconftest.dylib*
- fi
- rm conftest.c
- fi
-fi
-{ echo "$as_me:$LINENO: result: $lt_cv_apple_cc_single_mod" >&5
-echo "${ECHO_T}$lt_cv_apple_cc_single_mod" >&6; }
- { echo "$as_me:$LINENO: checking for -exported_symbols_list linker flag" >&5
-echo $ECHO_N "checking for -exported_symbols_list linker flag... $ECHO_C" >&6; }
-if test "${lt_cv_ld_exported_symbols_list+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&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 >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- 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 "echo \"\$as_me:$LINENO: $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
- 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 &&
- $as_test_x conftest$ac_exeext; then
- lt_cv_ld_exported_symbols_list=yes
-else
- 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_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
- LDFLAGS="$save_LDFLAGS"
-
-fi
-{ echo "$as_me:$LINENO: result: $lt_cv_ld_exported_symbols_list" >&5
-echo "${ECHO_T}$lt_cv_ld_exported_symbols_list" >&6; }
- case $host_os in
- rhapsody* | darwin1.[0123])
- _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;;
- darwin1.*)
- _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
- darwin*)
- # if running on 10.5 or later, the deployment target defaults
- # to the OS version, if on x86, and 10.4, the deployment
- # target defaults to 10.4. Don't you love it?
- case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
- 10.0,*86*-darwin8*|10.0,*-darwin[91]*)
- _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
- 10.[012]*)
- _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
- 10.*)
- _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
- esac
- ;;
- esac
- if test "$lt_cv_apple_cc_single_mod" = "yes"; then
- _lt_dar_single_mod='$single_module'
- fi
- if test "$lt_cv_ld_exported_symbols_list" = "yes"; then
- _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym'
- else
- _lt_dar_export_syms="~$NMEDIT -s \$output_objdir/\${libname}-symbols.expsym \${lib}"
- fi
- if test "$DSYMUTIL" != ":"; then
- _lt_dsymutil="~$DSYMUTIL \$lib || :"
- else
- _lt_dsymutil=
- fi
- ;;
- esac
-
-
-enable_dlopen=no
-enable_win32_dll=yes
-
-# Check whether --enable-libtool-lock was given.
-if test "${enable_libtool_lock+set}" = set; then
- enableval=$enable_libtool_lock;
-fi
-
-test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
-
-
-# Check whether --with-pic was given.
-if test "${with_pic+set}" = set; then
- withval=$with_pic; pic_mode="$withval"
-else
- pic_mode=default
-fi
-
-test -z "$pic_mode" && pic_mode=default
-
-# Check if we have a version mismatch between libtool.m4 and ltmain.sh.
-#
-# Note: This should be in AC_LIBTOOL_SETUP, _after_ $ltmain have been defined.
-# We also should do it _before_ AC_LIBTOOL_LANG_C_CONFIG that actually
-# calls AC_LIBTOOL_CONFIG and creates libtool.
-#
-{ echo "$as_me:$LINENO: checking for correct ltmain.sh version" >&5
-echo $ECHO_N "checking for correct ltmain.sh version... $ECHO_C" >&6; }
-if test "x$ltmain" = "x" ; then
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
- { { echo "$as_me:$LINENO: error:
-
-*** [Gentoo] sanity check failed! ***
-*** \$ltmain is not defined, please check the patch for consistency! ***
-" >&5
-echo "$as_me: error:
-
-*** [Gentoo] sanity check failed! ***
-*** \$ltmain is not defined, please check the patch for consistency! ***
-" >&2;}
- { (exit 1); exit 1; }; }
-fi
-gentoo_lt_version="1.5.26"
-gentoo_ltmain_version=`sed -n '/^[ ]*VERSION=/{s/^[ ]*VERSION=//;p;q;}' "$ltmain"`
-if test "x$gentoo_lt_version" != "x$gentoo_ltmain_version" ; then
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
- { { echo "$as_me:$LINENO: error:
-
-*** [Gentoo] sanity check failed! ***
-*** libtool.m4 and ltmain.sh have a version mismatch! ***
-*** (libtool.m4 = $gentoo_lt_version, ltmain.sh = $gentoo_ltmain_version) ***
-
-Please run:
-
- libtoolize --copy --force
-
-if appropriate, please contact the maintainer of this
-package (or your distribution) for help.
-" >&5
-echo "$as_me: error:
-
-*** [Gentoo] sanity check failed! ***
-*** libtool.m4 and ltmain.sh have a version mismatch! ***
-*** (libtool.m4 = $gentoo_lt_version, ltmain.sh = $gentoo_ltmain_version) ***
-
-Please run:
-
- libtoolize --copy --force
-
-if appropriate, please contact the maintainer of this
-package (or your distribution) for help.
-" >&2;}
- { (exit 1); exit 1; }; }
-else
- { echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6; }
-fi
-
-
-# Use C for the default configuration in the libtool script
-tagname=
-lt_save_CC="$CC"
-ac_ext=c
-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
-
-
-# Source file extension for C test sources.
-ac_ext=c
-
-# Object file extension for compiled C test sources.
-objext=o
-objext=$objext
-
-# Code to be used in simple compile tests
-lt_simple_compile_test_code="int some_variable = 0;"
-
-# Code to be used in simple link tests
-lt_simple_link_test_code='int main(){return(0);}'
-
-
-# If no C compiler was specified, use CC.
-LTCC=${LTCC-"$CC"}
-
-# If no C compiler flags were specified, use CFLAGS.
-LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
-
-# Allow CC to be a program name with arguments.
-compiler=$CC
-
-
-# save warnings/boilerplate of simple test code
-ac_outfile=conftest.$ac_objext
-echo "$lt_simple_compile_test_code" >conftest.$ac_ext
-eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
-_lt_compiler_boilerplate=`cat conftest.err`
-$rm conftest*
-
-ac_outfile=conftest.$ac_objext
-echo "$lt_simple_link_test_code" >conftest.$ac_ext
-eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
-_lt_linker_boilerplate=`cat conftest.err`
-$rm -r conftest*
-
-
-
-lt_prog_compiler_no_builtin_flag=
-
-if test "$GCC" = yes; then
- lt_prog_compiler_no_builtin_flag=' -fno-builtin'
-
-
-{ echo "$as_me:$LINENO: checking if $compiler supports -fno-rtti -fno-exceptions" >&5
-echo $ECHO_N "checking if $compiler supports -fno-rtti -fno-exceptions... $ECHO_C" >&6; }
-if test "${lt_cv_prog_compiler_rtti_exceptions+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- lt_cv_prog_compiler_rtti_exceptions=no
- ac_outfile=conftest.$ac_objext
- echo "$lt_simple_compile_test_code" > conftest.$ac_ext
- lt_compiler_flag="-fno-rtti -fno-exceptions"
- # Insert the option either (1) after the last *FLAGS variable, or
- # (2) before a word containing "conftest.", or (3) at the end.
- # Note that $ac_compile itself does not contain backslashes and begins
- # with a dollar sign (not a hyphen), so the echo should work correctly.
- # The option is referenced via a variable to avoid confusing sed.
- lt_compile=`echo "$ac_compile" | $SED \
- -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:7944: $lt_compile\"" >&5)
- (eval "$lt_compile" 2>conftest.err)
- ac_status=$?
- cat conftest.err >&5
- echo "$as_me:7948: \$? = $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.
- $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp
- $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
- if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
- lt_cv_prog_compiler_rtti_exceptions=yes
- fi
- fi
- $rm conftest*
-
-fi
-{ echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_rtti_exceptions" >&5
-echo "${ECHO_T}$lt_cv_prog_compiler_rtti_exceptions" >&6; }
-
-if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then
- lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions"
-else
- :
-fi
-
-fi
-
-lt_prog_compiler_wl=
-lt_prog_compiler_pic=
-lt_prog_compiler_static=
-
-{ echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5
-echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6; }
-
- if test "$GCC" = yes; then
- lt_prog_compiler_wl='-Wl,'
- lt_prog_compiler_static='-static'
-
- case $host_os in
- aix*)
- # All AIX code is PIC.
- if test "$host_cpu" = ia64; then
- # AIX 5 now supports IA64 processor
- lt_prog_compiler_static='-Bstatic'
- fi
- ;;
-
- amigaos*)
- # FIXME: we need at least 68020 code to build shared libraries, but
- # adding the `-m68020' flag to GCC prevents building anything better,
- # like `-m68040'.
- lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4'
- ;;
-
- beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
- # PIC is the default for these OSes.
- ;;
-
- mingw* | cygwin* | pw32* | os2*)
- # This hack is so that the source file can tell whether it is being
- # built for inclusion in a dll (and should export symbols for example).
- # Although the cygwin gcc ignores -fPIC, still need this for old-style
- # (--disable-auto-import) libraries
- lt_prog_compiler_pic='-DDLL_EXPORT'
- ;;
-
- darwin* | rhapsody*)
- # PIC is the default on this platform
- # Common symbols not allowed in MH_DYLIB files
- lt_prog_compiler_pic='-fno-common'
- ;;
-
- interix[3-9]*)
- # Interix 3.x gcc -fpic/-fPIC options generate broken code.
- # Instead, we relocate shared libraries at runtime.
- ;;
-
- msdosdjgpp*)
- # Just because we use GCC doesn't mean we suddenly get shared libraries
- # on systems that don't support them.
- lt_prog_compiler_can_build_shared=no
- enable_shared=no
- ;;
-
- sysv4*MP*)
- if test -d /usr/nec; then
- lt_prog_compiler_pic=-Kconform_pic
- fi
- ;;
-
- hpux*)
- # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
- # not for PA HP-UX.
- case $host_cpu in
- hppa*64*|ia64*)
- # +Z the default
- ;;
- *)
- lt_prog_compiler_pic='-fPIC'
- ;;
- esac
- ;;
-
- *)
- lt_prog_compiler_pic='-fPIC'
- ;;
- esac
- else
- # PORTME Check for flag to pass linker flags through the system compiler.
- case $host_os in
- aix*)
- lt_prog_compiler_wl='-Wl,'
- if test "$host_cpu" = ia64; then
- # AIX 5 now supports IA64 processor
- lt_prog_compiler_static='-Bstatic'
- else
- lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp'
- fi
- ;;
- darwin*)
- # PIC is the default on this platform
- # Common symbols not allowed in MH_DYLIB files
- case $cc_basename in
- xlc*)
- lt_prog_compiler_pic='-qnocommon'
- lt_prog_compiler_wl='-Wl,'
- ;;
- esac
- ;;
-
- mingw* | cygwin* | pw32* | os2*)
- # This hack is so that the source file can tell whether it is being
- # built for inclusion in a dll (and should export symbols for example).
- lt_prog_compiler_pic='-DDLL_EXPORT'
- ;;
-
- hpux9* | hpux10* | hpux11*)
- lt_prog_compiler_wl='-Wl,'
- # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
- # not for PA HP-UX.
- case $host_cpu in
- hppa*64*|ia64*)
- # +Z the default
- ;;
- *)
- lt_prog_compiler_pic='+Z'
- ;;
- esac
- # Is there a better lt_prog_compiler_static that works with the bundled CC?
- lt_prog_compiler_static='${wl}-a ${wl}archive'
- ;;
-
- irix5* | irix6* | nonstopux*)
- lt_prog_compiler_wl='-Wl,'
- # PIC (with -KPIC) is the default.
- lt_prog_compiler_static='-non_shared'
- ;;
-
- newsos6)
- lt_prog_compiler_pic='-KPIC'
- lt_prog_compiler_static='-Bstatic'
- ;;
-
- linux* | k*bsd*-gnu)
- case $cc_basename in
- icc* | ecc*)
- lt_prog_compiler_wl='-Wl,'
- lt_prog_compiler_pic='-KPIC'
- lt_prog_compiler_static='-static'
- ;;
- pgcc* | pgf77* | pgf90* | pgf95*)
- # Portland Group compilers (*not* the Pentium gcc compiler,
- # which looks to be a dead project)
- lt_prog_compiler_wl='-Wl,'
- lt_prog_compiler_pic='-fpic'
- lt_prog_compiler_static='-Bstatic'
- ;;
- ccc*)
- lt_prog_compiler_wl='-Wl,'
- # All Alpha code is PIC.
- lt_prog_compiler_static='-non_shared'
- ;;
- *)
- case `$CC -V 2>&1 | sed 5q` in
- *Sun\ C*)
- # Sun C 5.9
- lt_prog_compiler_pic='-KPIC'
- lt_prog_compiler_static='-Bstatic'
- lt_prog_compiler_wl='-Wl,'
- ;;
- *Sun\ F*)
- # Sun Fortran 8.3 passes all unrecognized flags to the linker
- lt_prog_compiler_pic='-KPIC'
- lt_prog_compiler_static='-Bstatic'
- lt_prog_compiler_wl=''
- ;;
- esac
- ;;
- esac
- ;;
-
- osf3* | osf4* | osf5*)
- lt_prog_compiler_wl='-Wl,'
- # All OSF/1 code is PIC.
- lt_prog_compiler_static='-non_shared'
- ;;
-
- rdos*)
- lt_prog_compiler_static='-non_shared'
- ;;
-
- solaris*)
- lt_prog_compiler_pic='-KPIC'
- lt_prog_compiler_static='-Bstatic'
- case $cc_basename in
- f77* | f90* | f95*)
- lt_prog_compiler_wl='-Qoption ld ';;
- *)
- lt_prog_compiler_wl='-Wl,';;
- esac
- ;;
-
- sunos4*)
- lt_prog_compiler_wl='-Qoption ld '
- lt_prog_compiler_pic='-PIC'
- lt_prog_compiler_static='-Bstatic'
- ;;
-
- sysv4 | sysv4.2uw2* | sysv4.3*)
- lt_prog_compiler_wl='-Wl,'
- lt_prog_compiler_pic='-KPIC'
- lt_prog_compiler_static='-Bstatic'
- ;;
-
- sysv4*MP*)
- if test -d /usr/nec ;then
- lt_prog_compiler_pic='-Kconform_pic'
- lt_prog_compiler_static='-Bstatic'
- fi
- ;;
-
- sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
- lt_prog_compiler_wl='-Wl,'
- lt_prog_compiler_pic='-KPIC'
- lt_prog_compiler_static='-Bstatic'
- ;;
-
- unicos*)
- lt_prog_compiler_wl='-Wl,'
- lt_prog_compiler_can_build_shared=no
- ;;
-
- uts4*)
- lt_prog_compiler_pic='-pic'
- lt_prog_compiler_static='-Bstatic'
- ;;
-
- *)
- lt_prog_compiler_can_build_shared=no
- ;;
- esac
- fi
-
-{ echo "$as_me:$LINENO: result: $lt_prog_compiler_pic" >&5
-echo "${ECHO_T}$lt_prog_compiler_pic" >&6; }
-
-#
-# Check to make sure the PIC flag actually works.
-#
-if test -n "$lt_prog_compiler_pic"; then
-
-{ echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5
-echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic works... $ECHO_C" >&6; }
-if test "${lt_cv_prog_compiler_pic_works+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- lt_cv_prog_compiler_pic_works=no
- ac_outfile=conftest.$ac_objext
- echo "$lt_simple_compile_test_code" > conftest.$ac_ext
- lt_compiler_flag="$lt_prog_compiler_pic -DPIC"
- # Insert the option either (1) after the last *FLAGS variable, or
- # (2) before a word containing "conftest.", or (3) at the end.
- # Note that $ac_compile itself does not contain backslashes and begins
- # with a dollar sign (not a hyphen), so the echo should work correctly.
- # The option is referenced via a variable to avoid confusing sed.
- lt_compile=`echo "$ac_compile" | $SED \
- -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:8234: $lt_compile\"" >&5)
- (eval "$lt_compile" 2>conftest.err)
- ac_status=$?
- cat conftest.err >&5
- echo "$as_me:8238: \$? = $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.
- $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp
- $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
- if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
- lt_cv_prog_compiler_pic_works=yes
- fi
- fi
- $rm conftest*
-
-fi
-{ echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_pic_works" >&5
-echo "${ECHO_T}$lt_cv_prog_compiler_pic_works" >&6; }
-
-if test x"$lt_cv_prog_compiler_pic_works" = xyes; then
- case $lt_prog_compiler_pic in
- "" | " "*) ;;
- *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;;
- esac
-else
- lt_prog_compiler_pic=
- lt_prog_compiler_can_build_shared=no
-fi
-
-fi
-case $host_os in
- # For platforms which do not support PIC, -DPIC is meaningless:
- *djgpp*)
- lt_prog_compiler_pic=
- ;;
- *)
- lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC"
- ;;
-esac
-
-#
-# Check to make sure the static flag actually works.
-#
-wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\"
-{ echo "$as_me:$LINENO: checking if $compiler static flag $lt_tmp_static_flag works" >&5
-echo $ECHO_N "checking if $compiler static flag $lt_tmp_static_flag works... $ECHO_C" >&6; }
-if test "${lt_cv_prog_compiler_static_works+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- lt_cv_prog_compiler_static_works=no
- save_LDFLAGS="$LDFLAGS"
- LDFLAGS="$LDFLAGS $lt_tmp_static_flag"
- echo "$lt_simple_link_test_code" > conftest.$ac_ext
- if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
- # The linker can only warn and ignore the option if not recognized
- # So say no if there are warnings
- if test -s conftest.err; then
- # Append any errors to the config.log.
- cat conftest.err 1>&5
- $echo "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp
- $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
- if diff conftest.exp conftest.er2 >/dev/null; then
- lt_cv_prog_compiler_static_works=yes
- fi
- else
- lt_cv_prog_compiler_static_works=yes
- fi
- fi
- $rm -r conftest*
- LDFLAGS="$save_LDFLAGS"
-
-fi
-{ echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_static_works" >&5
-echo "${ECHO_T}$lt_cv_prog_compiler_static_works" >&6; }
-
-if test x"$lt_cv_prog_compiler_static_works" = xyes; then
- :
-else
- lt_prog_compiler_static=
-fi
-
-
-{ echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5
-echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6; }
-if test "${lt_cv_prog_compiler_c_o+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- lt_cv_prog_compiler_c_o=no
- $rm -r conftest 2>/dev/null
- mkdir conftest
- cd conftest
- mkdir out
- echo "$lt_simple_compile_test_code" > conftest.$ac_ext
-
- lt_compiler_flag="-o out/conftest2.$ac_objext"
- # Insert the option either (1) after the last *FLAGS variable, or
- # (2) before a word containing "conftest.", or (3) at the end.
- # Note that $ac_compile itself does not contain backslashes and begins
- # with a dollar sign (not a hyphen), so the echo should work correctly.
- lt_compile=`echo "$ac_compile" | $SED \
- -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:8338: $lt_compile\"" >&5)
- (eval "$lt_compile" 2>out/conftest.err)
- ac_status=$?
- cat out/conftest.err >&5
- echo "$as_me:8342: \$? = $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
- # So say no if there are warnings
- $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp
- $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
- if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
- lt_cv_prog_compiler_c_o=yes
- fi
- fi
- chmod u+w . 2>&5
- $rm conftest*
- # SGI C++ compiler will create directory out/ii_files/ for
- # template instantiation
- test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files
- $rm out/* && rmdir out
- cd ..
- rmdir conftest
- $rm conftest*
-
-fi
-{ echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o" >&5
-echo "${ECHO_T}$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
- { echo "$as_me:$LINENO: checking if we can lock with hard links" >&5
-echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6; }
- hard_links=yes
- $rm conftest*
- ln conftest.a conftest.b 2>/dev/null && hard_links=no
- touch conftest.a
- ln conftest.a conftest.b 2>&5 || hard_links=no
- ln conftest.a conftest.b 2>/dev/null && hard_links=no
- { echo "$as_me:$LINENO: result: $hard_links" >&5
-echo "${ECHO_T}$hard_links" >&6; }
- if test "$hard_links" = no; then
- { echo "$as_me:$LINENO: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5
-echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;}
- need_locks=warn
- fi
-else
- need_locks=no
-fi
-
-{ echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5
-echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6; }
-
- runpath_var=
- allow_undefined_flag=
- enable_shared_with_static_runtimes=no
- archive_cmds=
- archive_expsym_cmds=
- old_archive_From_new_cmds=
- old_archive_from_expsyms_cmds=
- export_dynamic_flag_spec=
- whole_archive_flag_spec=
- thread_safe_flag_spec=
- hardcode_libdir_flag_spec=
- hardcode_libdir_flag_spec_ld=
- hardcode_libdir_separator=
- hardcode_direct=no
- hardcode_minus_L=no
- hardcode_shlibpath_var=unsupported
- link_all_deplibs=unknown
- hardcode_automatic=no
- module_cmds=
- module_expsym_cmds=
- always_export_symbols=no
- export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
- # include_expsyms should be a list of space-separated symbols to be *always*
- # included in the symbol list
- include_expsyms=
- # exclude_expsyms can be an extended regexp of symbols to exclude
- # it will be wrapped by ` (' and `)$', so one must not match beginning or
- # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
- # as well as any symbol that contains `d'.
- exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'
- # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
- # platforms (ab)use it in PIC code, but their linkers get confused if
- # the symbol is explicitly referenced. Since portable code cannot
- # rely on this symbol name, it's probably fine to never include it in
- # preloaded symbol tables.
- # Exclude shared library initialization/finalization symbols.
- extract_expsyms_cmds=
- # Just being paranoid about ensuring that cc_basename is set.
- for cc_temp in $compiler""; do
- case $cc_temp in
- compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
- distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
- \-*) ;;
- *) break;;
- esac
-done
-cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"`
-
- case $host_os in
- cygwin* | mingw* | pw32*)
- # FIXME: the MSVC++ port hasn't been tested in a loooong time
- # When not using gcc, we currently assume that we are using
- # Microsoft Visual C++.
- if test "$GCC" != yes; then
- with_gnu_ld=no
- fi
- ;;
- interix*)
- # we just hope/assume this is gcc and not c89 (= MSVC++)
- with_gnu_ld=yes
- ;;
- openbsd*)
- with_gnu_ld=no
- ;;
- esac
-
- ld_shlibs=yes
- if test "$with_gnu_ld" = yes; then
- # If archive_cmds runs LD, not CC, wlarc should be empty
- wlarc='${wl}'
-
- # Set some defaults for GNU ld with shared library support. These
- # are reset later if shared libraries are not supported. Putting them
- # here allows them to be overridden if necessary.
- runpath_var=LD_RUN_PATH
- hardcode_libdir_flag_spec='${wl}--rpath ${wl}$libdir'
- export_dynamic_flag_spec='${wl}--export-dynamic'
- # ancient GNU ld didn't support --whole-archive et. al.
- if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then
- whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
- else
- whole_archive_flag_spec=
- fi
- supports_anon_versioning=no
- case `$LD -v 2>/dev/null` in
- *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11
- *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
- *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
- *\ 2.11.*) ;; # other 2.11 versions
- *) supports_anon_versioning=yes ;;
- esac
-
- # See if GNU ld supports shared libraries.
- case $host_os in
- aix[3-9]*)
- # On AIX/PPC, the GNU linker is very broken
- if test "$host_cpu" != ia64; then
- ld_shlibs=no
- cat <<EOF 1>&2
-
-*** Warning: the GNU linker, at least up to release 2.9.1, is reported
-*** to be unable to reliably create shared libraries on AIX.
-*** Therefore, libtool is disabling shared libraries support. If you
-*** really care for shared libraries, you may want to modify your PATH
-*** so that a non-GNU linker is found, and then restart.
-
-EOF
- fi
- ;;
-
- amigaos*)
- archive_cmds='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
- hardcode_libdir_flag_spec='-L$libdir'
- hardcode_minus_L=yes
-
- # Samuel A. Falvo II <kc5tja@dolphin.openprojects.net> reports
- # that the semantics of dynamic libraries on AmigaOS, at least up
- # to version 4, is to share data among multiple programs linked
- # with the same dynamic library. Since this doesn't match the
- # behavior of shared libraries on other platforms, we can't use
- # them.
- ld_shlibs=no
- ;;
-
- beos*)
- if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
- allow_undefined_flag=unsupported
- # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
- # support --undefined. This deserves some investigation. FIXME
- archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- else
- ld_shlibs=no
- fi
- ;;
-
- cygwin* | mingw* | pw32*)
- # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless,
- # as there is no search path for DLLs.
- hardcode_libdir_flag_spec='-L$libdir'
- allow_undefined_flag=unsupported
- always_export_symbols=no
- enable_shared_with_static_runtimes=yes
- export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/'\'' -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols'
-
- if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then
- archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
- # If the export-symbols file already is a .def file (1st line
- # is EXPORTS), use it as is; otherwise, prepend...
- archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
- cp $export_symbols $output_objdir/$soname.def;
- else
- echo EXPORTS > $output_objdir/$soname.def;
- cat $export_symbols >> $output_objdir/$soname.def;
- fi~
- $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
- else
- ld_shlibs=no
- fi
- ;;
-
- interix[3-9]*)
- hardcode_direct=no
- hardcode_shlibpath_var=no
- hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
- export_dynamic_flag_spec='${wl}-E'
- # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
- # Instead, shared libraries are loaded at an image base (0x10000000 by
- # default) and relocated if they conflict, which is a slow very memory
- # consuming and fragmenting process. To avoid this, we pick a random,
- # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
- # time. Moving up from 0x10000000 also allows more sbrk(2) space.
- archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
- archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
- ;;
-
- gnu* | linux* | k*bsd*-gnu)
- if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
- tmp_addflag=
- case $cc_basename,$host_cpu in
- pgcc*) # Portland Group C compiler
- whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
- tmp_addflag=' $pic_flag'
- ;;
- pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers
- whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
- tmp_addflag=' $pic_flag -Mnomain' ;;
- ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64
- tmp_addflag=' -i_dynamic' ;;
- efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64
- tmp_addflag=' -i_dynamic -nofor_main' ;;
- ifc* | ifort*) # Intel Fortran compiler
- tmp_addflag=' -nofor_main' ;;
- esac
- case `$CC -V 2>&1 | sed 5q` in
- *Sun\ C*) # Sun C 5.9
- whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
- tmp_sharedflag='-G' ;;
- *Sun\ F*) # Sun Fortran 8.3
- tmp_sharedflag='-G' ;;
- *)
- tmp_sharedflag='-shared' ;;
- esac
- archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
-
- if test $supports_anon_versioning = yes; then
- archive_expsym_cmds='$echo "{ global:" > $output_objdir/$libname.ver~
- cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
- $echo "local: *; };" >> $output_objdir/$libname.ver~
- $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
- fi
- else
- ld_shlibs=no
- fi
- ;;
-
- netbsd*)
- if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
- archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
- wlarc=
- else
- archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
- fi
- ;;
-
- solaris*)
- if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then
- ld_shlibs=no
- cat <<EOF 1>&2
-
-*** Warning: The releases 2.8.* of the GNU linker cannot reliably
-*** create shared libraries on Solaris systems. Therefore, libtool
-*** is disabling shared libraries support. We urge you to upgrade GNU
-*** binutils to release 2.9.1 or newer. Another option is to modify
-*** your PATH or compiler configuration so that the native linker is
-*** used, and then restart.
-
-EOF
- elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
- archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
- else
- ld_shlibs=no
- fi
- ;;
-
- sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
- case `$LD -v 2>&1` in
- *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*)
- ld_shlibs=no
- cat <<_LT_EOF 1>&2
-
-*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not
-*** reliably create shared libraries on SCO systems. Therefore, libtool
-*** is disabling shared libraries support. We urge you to upgrade GNU
-*** binutils to release 2.16.91.0.3 or newer. Another option is to modify
-*** your PATH or compiler configuration so that the native linker is
-*** used, and then restart.
-
-_LT_EOF
- ;;
- *)
- if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
- hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`'
- archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib'
- archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname,-retain-symbols-file,$export_symbols -o $lib'
- else
- ld_shlibs=no
- fi
- ;;
- esac
- ;;
-
- sunos4*)
- archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
- wlarc=
- hardcode_direct=yes
- hardcode_shlibpath_var=no
- ;;
-
- *)
- if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
- archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
- else
- ld_shlibs=no
- fi
- ;;
- esac
-
- if test "$ld_shlibs" = no; then
- runpath_var=
- hardcode_libdir_flag_spec=
- export_dynamic_flag_spec=
- whole_archive_flag_spec=
- fi
- else
- # PORTME fill in a description of your system's linker (not GNU ld)
- case $host_os in
- aix3*)
- allow_undefined_flag=unsupported
- always_export_symbols=yes
- archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
- # Note: this linker hardcodes the directories in LIBPATH if there
- # are no directories specified by -L.
- hardcode_minus_L=yes
- if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then
- # Neither direct hardcoding nor static linking is supported with a
- # broken collect2.
- hardcode_direct=unsupported
- fi
- ;;
-
- aix[4-9]*)
- if test "$host_cpu" = ia64; then
- # On IA64, the linker does run time linking by default, so we don't
- # have to do anything special.
- aix_use_runtimelinking=no
- exp_sym_flag='-Bexport'
- no_entry_flag=""
- else
- # If we're using GNU nm, then we don't want the "-C" option.
- # -C means demangle to AIX nm, but means don't demangle with GNU nm
- if $NM -V 2>&1 | grep 'GNU' > /dev/null; then
- export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols'
- else
- export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols'
- fi
- aix_use_runtimelinking=no
-
- # Test if we are trying to use run time linking or normal
- # AIX style linking. If -brtl is somewhere in LDFLAGS, we
- # need to do runtime linking.
- case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*)
- for ld_flag in $LDFLAGS; do
- if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
- aix_use_runtimelinking=yes
- break
- fi
- done
- ;;
- esac
-
- exp_sym_flag='-bexport'
- no_entry_flag='-bnoentry'
- fi
-
- # When large executables or shared objects are built, AIX ld can
- # have problems creating the table of contents. If linking a library
- # or program results in "error TOC overflow" add -mminimal-toc to
- # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not
- # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
-
- archive_cmds=''
- hardcode_direct=yes
- hardcode_libdir_separator=':'
- link_all_deplibs=yes
-
- if test "$GCC" = yes; then
- case $host_os in aix4.[012]|aix4.[012].*)
- # We only want to do this on AIX 4.2 and lower, the check
- # below for broken collect2 doesn't work under 4.3+
- collect2name=`${CC} -print-prog-name=collect2`
- if test -f "$collect2name" && \
- strings "$collect2name" | grep resolve_lib_name >/dev/null
- then
- # We have reworked collect2
- :
- else
- # We have old collect2
- hardcode_direct=unsupported
- # It fails to find uninstalled libraries when the uninstalled
- # path is not listed in the libpath. Setting hardcode_minus_L
- # to unsupported forces relinking
- hardcode_minus_L=yes
- hardcode_libdir_flag_spec='-L$libdir'
- hardcode_libdir_separator=
- fi
- ;;
- esac
- shared_flag='-shared'
- if test "$aix_use_runtimelinking" = yes; then
- shared_flag="$shared_flag "'${wl}-G'
- fi
- else
- # not using gcc
- if test "$host_cpu" = ia64; then
- # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
- # chokes on -Wl,-G. The following line is correct:
- shared_flag='-G'
- else
- if test "$aix_use_runtimelinking" = yes; then
- shared_flag='${wl}-G'
- else
- shared_flag='${wl}-bM:SRE'
- fi
- fi
- fi
-
- # It seems that -bexpall does not export symbols beginning with
- # underscore (_), so it is better to generate a list of symbols to export.
- always_export_symbols=yes
- if test "$aix_use_runtimelinking" = yes; then
- # Warning - without using the other runtime loading flags (-brtl),
- # -berok will link without error, but may produce a broken library.
- allow_undefined_flag='-berok'
- # Determine the default libpath from the value encoded in an empty executable.
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- 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 "echo \"\$as_me:$LINENO: $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
- 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 &&
- $as_test_x conftest$ac_exeext; then
-
-lt_aix_libpath_sed='
- /Import File Strings/,/^$/ {
- /^0/ {
- s/^0 *\(.*\)$/\1/
- p
- }
- }'
-aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
-# Check for a 64-bit object if we didn't find anything.
-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
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-
-fi
-
-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"
- archive_expsym_cmds="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
- else
- if test "$host_cpu" = ia64; then
- hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib'
- allow_undefined_flag="-z nodefs"
- archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
- else
- # Determine the default libpath from the value encoded in an empty executable.
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- 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 "echo \"\$as_me:$LINENO: $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
- 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 &&
- $as_test_x conftest$ac_exeext; then
-
-lt_aix_libpath_sed='
- /Import File Strings/,/^$/ {
- /^0/ {
- s/^0 *\(.*\)$/\1/
- p
- }
- }'
-aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
-# Check for a 64-bit object if we didn't find anything.
-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
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-
-fi
-
-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"
- # Warning - without using the other run time loading flags,
- # -berok will link without error, but may produce a broken library.
- no_undefined_flag=' ${wl}-bernotok'
- allow_undefined_flag=' ${wl}-berok'
- # Exported symbols can be pulled into shared objects from archives
- whole_archive_flag_spec='$convenience'
- archive_cmds_need_lc=yes
- # This is similar to how AIX traditionally builds its shared libraries.
- archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
- fi
- fi
- ;;
-
- amigaos*)
- archive_cmds='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
- hardcode_libdir_flag_spec='-L$libdir'
- hardcode_minus_L=yes
- # see comment about different semantics on the GNU ld section
- ld_shlibs=no
- ;;
-
- bsdi[45]*)
- export_dynamic_flag_spec=-rdynamic
- ;;
-
- cygwin* | mingw* | pw32*)
- # When not using gcc, we currently assume that we are using
- # Microsoft Visual C++.
- # hardcode_libdir_flag_spec is actually meaningless, as there is
- # no search path for DLLs.
- hardcode_libdir_flag_spec=' '
- allow_undefined_flag=unsupported
- # Tell ltmain to make .lib files, not .a files.
- libext=lib
- # Tell ltmain to make .dll files, not .so files.
- shrext_cmds=".dll"
- # FIXME: Setting linknames here is a bad hack.
- archive_cmds='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | $SED -e '\''s/ -lc$//'\''` -link -dll~linknames='
- # The linker will automatically build a .lib file if we build a DLL.
- old_archive_From_new_cmds='true'
- # FIXME: Should let the user specify the lib program.
- old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs'
- fix_srcfile_path='`cygpath -w "$srcfile"`'
- enable_shared_with_static_runtimes=yes
- ;;
-
- darwin* | rhapsody*)
- case $host_os in
- rhapsody* | darwin1.[012])
- allow_undefined_flag='${wl}-undefined ${wl}suppress'
- ;;
- *) # Darwin 1.3 on
- if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then
- allow_undefined_flag='${wl}-flat_namespace ${wl}-undefined ${wl}suppress'
- else
- case ${MACOSX_DEPLOYMENT_TARGET} in
- 10.[012])
- allow_undefined_flag='${wl}-flat_namespace ${wl}-undefined ${wl}suppress'
- ;;
- 10.*)
- allow_undefined_flag='${wl}-undefined ${wl}dynamic_lookup'
- ;;
- esac
- fi
- ;;
- esac
- archive_cmds_need_lc=no
- hardcode_direct=no
- hardcode_automatic=yes
- hardcode_shlibpath_var=unsupported
- whole_archive_flag_spec=''
- link_all_deplibs=yes
- if test "$GCC" = yes ; then
- output_verbose_link_cmd='echo'
- archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
- module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
- archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
- module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}"
- else
- case $cc_basename in
- xlc*)
- output_verbose_link_cmd='echo'
- archive_cmds='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $xlcverstring'
- module_cmds='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
- # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds
- archive_expsym_cmds='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $xlcverstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
- module_expsym_cmds='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
- ;;
- *)
- ld_shlibs=no
- ;;
- esac
- fi
- ;;
-
- dgux*)
- archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- hardcode_libdir_flag_spec='-L$libdir'
- hardcode_shlibpath_var=no
- ;;
-
- freebsd1*)
- ld_shlibs=no
- ;;
-
- # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
- # support. Future versions do this automatically, but an explicit c++rt0.o
- # does not break anything, and helps significantly (at the cost of a little
- # extra space).
- freebsd2.2*)
- archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
- hardcode_libdir_flag_spec='-R$libdir'
- hardcode_direct=yes
- hardcode_shlibpath_var=no
- ;;
-
- # Unfortunately, older versions of FreeBSD 2 do not have this feature.
- freebsd2*)
- archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
- hardcode_direct=yes
- hardcode_minus_L=yes
- hardcode_shlibpath_var=no
- ;;
-
- # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
- freebsd* | dragonfly*)
- archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
- hardcode_libdir_flag_spec='-R$libdir'
- hardcode_direct=yes
- hardcode_shlibpath_var=no
- ;;
-
- hpux9*)
- if test "$GCC" = yes; then
- archive_cmds='$rm $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
- else
- archive_cmds='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
- fi
- hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
- hardcode_libdir_separator=:
- hardcode_direct=yes
-
- # hardcode_minus_L: Not really in the search PATH,
- # but as the default location of the library.
- hardcode_minus_L=yes
- export_dynamic_flag_spec='${wl}-E'
- ;;
-
- hpux10*)
- if test "$GCC" = yes -a "$with_gnu_ld" = no; then
- archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
- else
- archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
- fi
- if test "$with_gnu_ld" = no; then
- hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
- hardcode_libdir_separator=:
-
- hardcode_direct=yes
- export_dynamic_flag_spec='${wl}-E'
-
- # hardcode_minus_L: Not really in the search PATH,
- # but as the default location of the library.
- hardcode_minus_L=yes
- fi
- ;;
-
- hpux11*)
- if test "$GCC" = yes -a "$with_gnu_ld" = no; then
- case $host_cpu in
- hppa*64*)
- archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- ia64*)
- archive_cmds='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- *)
- archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- esac
- else
- case $host_cpu in
- hppa*64*)
- archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- ia64*)
- archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- *)
- archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- esac
- fi
- if test "$with_gnu_ld" = no; then
- hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
- hardcode_libdir_separator=:
-
- case $host_cpu in
- hppa*64*|ia64*)
- hardcode_libdir_flag_spec_ld='+b $libdir'
- hardcode_direct=no
- hardcode_shlibpath_var=no
- ;;
- *)
- hardcode_direct=yes
- export_dynamic_flag_spec='${wl}-E'
-
- # hardcode_minus_L: Not really in the search PATH,
- # but as the default location of the library.
- hardcode_minus_L=yes
- ;;
- esac
- fi
- ;;
-
- irix5* | irix6* | nonstopux*)
- if test "$GCC" = yes; then
- archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
- else
- archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
- hardcode_libdir_flag_spec_ld='-rpath $libdir'
- fi
- hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
- hardcode_libdir_separator=:
- link_all_deplibs=yes
- ;;
-
- netbsd*)
- if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
- archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out
- else
- archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF
- fi
- hardcode_libdir_flag_spec='-R$libdir'
- hardcode_direct=yes
- hardcode_shlibpath_var=no
- ;;
-
- newsos6)
- archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- hardcode_direct=yes
- hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
- hardcode_libdir_separator=:
- hardcode_shlibpath_var=no
- ;;
-
- openbsd*)
- if test -f /usr/libexec/ld.so; then
- hardcode_direct=yes
- hardcode_shlibpath_var=no
- if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
- archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
- archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'
- hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
- export_dynamic_flag_spec='${wl}-E'
- else
- case $host_os in
- openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
- archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
- hardcode_libdir_flag_spec='-R$libdir'
- ;;
- *)
- archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
- hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
- ;;
- esac
- fi
- else
- ld_shlibs=no
- fi
- ;;
-
- os2*)
- hardcode_libdir_flag_spec='-L$libdir'
- hardcode_minus_L=yes
- allow_undefined_flag=unsupported
- archive_cmds='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
- old_archive_From_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
- ;;
-
- osf3*)
- if test "$GCC" = yes; then
- allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
- archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
- else
- allow_undefined_flag=' -expect_unresolved \*'
- archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
- fi
- hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
- hardcode_libdir_separator=:
- ;;
-
- osf4* | osf5*) # as osf3* with the addition of -msym flag
- if test "$GCC" = yes; then
- allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
- archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
- hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
- else
- allow_undefined_flag=' -expect_unresolved \*'
- archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
- archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~
- $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~$rm $lib.exp'
-
- # Both c and cxx compiler support -rpath directly
- hardcode_libdir_flag_spec='-rpath $libdir'
- fi
- hardcode_libdir_separator=:
- ;;
-
- solaris*)
- no_undefined_flag=' -z text'
- if test "$GCC" = yes; then
- wlarc='${wl}'
- archive_cmds='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
- archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
- $CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp'
- else
- wlarc=''
- archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
- archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
- $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp'
- fi
- hardcode_libdir_flag_spec='-R$libdir'
- hardcode_shlibpath_var=no
- case $host_os in
- solaris2.[0-5] | solaris2.[0-5].*) ;;
- *)
- # The compiler driver will combine and reorder linker options,
- # but understands `-z linker_flag'. GCC discards it without `$wl',
- # but is careful enough not to reorder.
- # Supported since Solaris 2.6 (maybe 2.5.1?)
- if test "$GCC" = yes; then
- whole_archive_flag_spec='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
- else
- whole_archive_flag_spec='-z allextract$convenience -z defaultextract'
- fi
- ;;
- esac
- link_all_deplibs=yes
- ;;
-
- sunos4*)
- if test "x$host_vendor" = xsequent; then
- # Use $CC to link under sequent, because it throws in some extra .o
- # files that make .init and .fini sections work.
- archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
- else
- archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
- fi
- hardcode_libdir_flag_spec='-L$libdir'
- hardcode_direct=yes
- hardcode_minus_L=yes
- hardcode_shlibpath_var=no
- ;;
-
- sysv4)
- case $host_vendor in
- sni)
- archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- hardcode_direct=yes # is this really true???
- ;;
- siemens)
- ## LD is ld it makes a PLAMLIB
- ## CC just makes a GrossModule.
- archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags'
- reload_cmds='$CC -r -o $output$reload_objs'
- hardcode_direct=no
- ;;
- motorola)
- archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- hardcode_direct=no #Motorola manual says yes, but my tests say they lie
- ;;
- esac
- runpath_var='LD_RUN_PATH'
- hardcode_shlibpath_var=no
- ;;
-
- sysv4.3*)
- archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- hardcode_shlibpath_var=no
- export_dynamic_flag_spec='-Bexport'
- ;;
-
- sysv4*MP*)
- if test -d /usr/nec; then
- archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- hardcode_shlibpath_var=no
- runpath_var=LD_RUN_PATH
- hardcode_runpath_var=yes
- ld_shlibs=yes
- fi
- ;;
-
- sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
- no_undefined_flag='${wl}-z,text'
- archive_cmds_need_lc=no
- hardcode_shlibpath_var=no
- runpath_var='LD_RUN_PATH'
-
- if test "$GCC" = yes; then
- archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- else
- archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- fi
- ;;
-
- sysv5* | sco3.2v5* | sco5v6*)
- # Note: We can NOT use -z defs as we might desire, because we do not
- # link with -lc, and that would cause any symbols used from libc to
- # always be unresolved, which means just about no library would
- # ever link correctly. If we're not using GNU ld we use -z text
- # though, which does catch some bad symbols but isn't as heavy-handed
- # as -z defs.
- no_undefined_flag='${wl}-z,text'
- allow_undefined_flag='${wl}-z,nodefs'
- archive_cmds_need_lc=no
- hardcode_shlibpath_var=no
- hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`'
- hardcode_libdir_separator=':'
- link_all_deplibs=yes
- export_dynamic_flag_spec='${wl}-Bexport'
- runpath_var='LD_RUN_PATH'
-
- if test "$GCC" = yes; then
- archive_cmds='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
- archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
- else
- archive_cmds='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
- archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
- fi
- ;;
-
- uts4*)
- archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- hardcode_libdir_flag_spec='-L$libdir'
- hardcode_shlibpath_var=no
- ;;
-
- *)
- ld_shlibs=no
- ;;
- esac
- fi
-
-{ echo "$as_me:$LINENO: result: $ld_shlibs" >&5
-echo "${ECHO_T}$ld_shlibs" >&6; }
-test "$ld_shlibs" = no && can_build_shared=no
-
-#
-# Do we need to explicitly link libc?
-#
-case "x$archive_cmds_need_lc" in
-x|xyes)
- # Assume -lc should be added
- archive_cmds_need_lc=yes
-
- if test "$enable_shared" = yes && test "$GCC" = yes; then
- case $archive_cmds in
- *'~'*)
- # FIXME: we may have to deal with multi-command sequences.
- ;;
- '$CC '*)
- # 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.
- { echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5
-echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6; }
- $rm conftest*
- echo "$lt_simple_compile_test_code" > conftest.$ac_ext
-
- if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } 2>conftest.err; then
- soname=conftest
- lib=conftest
- libobjs=conftest.$ac_objext
- deplibs=
- wl=$lt_prog_compiler_wl
- pic_flag=$lt_prog_compiler_pic
- compiler_flags=-v
- linker_flags=-v
- verstring=
- output_objdir=.
- libname=conftest
- lt_save_allow_undefined_flag=$allow_undefined_flag
- allow_undefined_flag=
- 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=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }
- then
- archive_cmds_need_lc=no
- else
- archive_cmds_need_lc=yes
- fi
- allow_undefined_flag=$lt_save_allow_undefined_flag
- else
- cat conftest.err 1>&5
- fi
- $rm conftest*
- { echo "$as_me:$LINENO: result: $archive_cmds_need_lc" >&5
-echo "${ECHO_T}$archive_cmds_need_lc" >&6; }
- ;;
- esac
- fi
- ;;
-esac
-
-{ echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5
-echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6; }
-library_names_spec=
-libname_spec='lib$name'
-soname_spec=
-shrext_cmds=".so"
-postinstall_cmds=
-postuninstall_cmds=
-finish_cmds=
-finish_eval=
-shlibpath_var=
-shlibpath_overrides_runpath=unknown
-version_type=none
-dynamic_linker="$host_os ld.so"
-sys_lib_dlsearch_path_spec="/lib /usr/lib"
-
-if test "$GCC" = yes; then
- case $host_os in
- darwin*) lt_awk_arg="/^libraries:/,/LR/" ;;
- *) lt_awk_arg="/^libraries:/" ;;
- esac
- lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e "s,=/,/,g"`
- if echo "$lt_search_path_spec" | grep ';' >/dev/null ; then
- # if the path contains ";" then we assume it to be the separator
- # otherwise default to the standard path separator (i.e. ":") - it is
- # assumed that no part of a normal pathname contains ";" but that should
- # okay in the real world where ";" in dirpaths is itself problematic.
- lt_search_path_spec=`echo "$lt_search_path_spec" | $SED -e 's/;/ /g'`
- else
- lt_search_path_spec=`echo "$lt_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
- fi
- # Ok, now we have the path, separated by spaces, we can step through it
- # and add multilib dir if necessary.
- lt_tmp_lt_search_path_spec=
- lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
- for lt_sys_path in $lt_search_path_spec; do
- if test -d "$lt_sys_path/$lt_multi_os_dir"; then
- lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir"
- else
- test -d "$lt_sys_path" && \
- lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path"
- fi
- done
- lt_search_path_spec=`echo $lt_tmp_lt_search_path_spec | awk '
-BEGIN {RS=" "; FS="/|\n";} {
- lt_foo="";
- lt_count=0;
- for (lt_i = NF; lt_i > 0; lt_i--) {
- if ($lt_i != "" && $lt_i != ".") {
- if ($lt_i == "..") {
- lt_count++;
- } else {
- if (lt_count == 0) {
- lt_foo="/" $lt_i lt_foo;
- } else {
- lt_count--;
- }
- }
- }
- }
- if (lt_foo != "") { lt_freq[lt_foo]++; }
- if (lt_freq[lt_foo] == 1) { print lt_foo; }
-}'`
- sys_lib_search_path_spec=`echo $lt_search_path_spec`
-else
- sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
-fi
-need_lib_prefix=unknown
-hardcode_into_libs=no
-
-# when you set need_version to no, make sure it does not cause -set_version
-# flags to be left without arguments
-need_version=unknown
-
-case $host_os in
-aix3*)
- version_type=linux
- library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
- shlibpath_var=LIBPATH
-
- # AIX 3 has no versioning support, so we append a major version to the name.
- soname_spec='${libname}${release}${shared_ext}$major'
- ;;
-
-aix[4-9]*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- hardcode_into_libs=yes
- if test "$host_cpu" = ia64; then
- # AIX 5 supports IA64
- library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
- shlibpath_var=LD_LIBRARY_PATH
- else
- # With GCC up to 2.95.x, collect2 would create an import file
- # for dependence libraries. The import file would start with
- # the line `#! .'. This would cause the generated library to
- # depend on `.', always an invalid library. This was fixed in
- # development snapshots of GCC prior to 3.0.
- case $host_os in
- aix4 | aix4.[01] | aix4.[01].*)
- if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
- echo ' yes '
- echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then
- :
- else
- can_build_shared=no
- fi
- ;;
- esac
- # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
- # soname into executable. Probably we can add versioning support to
- # collect2, so additional links can be useful in future.
- if test "$aix_use_runtimelinking" = yes; then
- # If using run time linking (on AIX 4.2 or later) use lib<name>.so
- # instead of lib<name>.a to let people know that these are not
- # typical AIX shared libraries.
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- else
- # We preserve .a as extension for shared libraries through AIX4.2
- # and later when we are not doing run time linking.
- library_names_spec='${libname}${release}.a $libname.a'
- soname_spec='${libname}${release}${shared_ext}$major'
- fi
- shlibpath_var=LIBPATH
- fi
- ;;
-
-amigaos*)
- library_names_spec='$libname.ixlibrary $libname.a'
- # Create ${libname}_ixlibrary.a entries in /sys/libs.
- finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
- ;;
-
-beos*)
- library_names_spec='${libname}${shared_ext}'
- dynamic_linker="$host_os ld.so"
- shlibpath_var=LIBRARY_PATH
- ;;
-
-bsdi[45]*)
- version_type=linux
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
- shlibpath_var=LD_LIBRARY_PATH
- sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
- sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
- # the default ld.so.conf also contains /usr/contrib/lib and
- # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
- # libtool to hard-code these into programs
- ;;
-
-cygwin* | mingw* | pw32*)
- version_type=windows
- shrext_cmds=".dll"
- need_version=no
- need_lib_prefix=no
-
- case $GCC,$host_os in
- yes,cygwin* | yes,mingw* | yes,pw32*)
- library_names_spec='$libname.dll.a'
- # DLL is installed to $(libdir)/../bin by postinstall_cmds
- postinstall_cmds='base_file=`basename \${file}`~
- dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~
- dldir=$destdir/`dirname \$dlpath`~
- test -d \$dldir || mkdir -p \$dldir~
- $install_prog $dir/$dlname \$dldir/$dlname~
- chmod a+x \$dldir/$dlname'
- postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
- dlpath=$dir/\$dldll~
- $rm \$dlpath'
- shlibpath_overrides_runpath=yes
-
- case $host_os in
- cygwin*)
- # Cygwin DLLs use 'cyg' prefix rather than 'lib'
- soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
- sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib"
- ;;
- mingw*)
- # MinGW DLLs use traditional 'lib' prefix
- soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
- sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
- if echo "$sys_lib_search_path_spec" | grep ';[c-zC-Z]:/' >/dev/null; then
- # It is most probably a Windows format PATH printed by
- # mingw gcc, but we are running on Cygwin. Gcc prints its search
- # path with ; separators, and with drive letters. We can handle the
- # drive letters (cygwin fileutils understands them), so leave them,
- # especially as we might pass files found there to a mingw objdump,
- # which wouldn't understand a cygwinified path. Ahh.
- sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
- else
- sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
- fi
- ;;
- pw32*)
- # pw32 DLLs use 'pw' prefix rather than 'lib'
- library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
- ;;
- esac
- ;;
-
- *)
- library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'
- ;;
- esac
- dynamic_linker='Win32 ld.exe'
- # FIXME: first we should search . and the directory the executable is in
- shlibpath_var=PATH
- ;;
-
-darwin* | rhapsody*)
- dynamic_linker="$host_os dyld"
- version_type=darwin
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext'
- soname_spec='${libname}${release}${major}$shared_ext'
- shlibpath_overrides_runpath=yes
- shlibpath_var=DYLD_LIBRARY_PATH
- shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
-
- sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"
- sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
- ;;
-
-dgux*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- ;;
-
-freebsd1*)
- dynamic_linker=no
- ;;
-
-freebsd* | dragonfly*)
- # DragonFly does not have aout. When/if they implement a new
- # versioning mechanism, adjust this.
- if test -x /usr/bin/objformat; then
- objformat=`/usr/bin/objformat`
- else
- case $host_os in
- freebsd[123]*) objformat=aout ;;
- *) objformat=elf ;;
- esac
- fi
- # Handle Gentoo/FreeBSD as it was Linux
- case $host_vendor in
- gentoo)
- version_type=linux ;;
- *)
- version_type=freebsd-$objformat ;;
- esac
-
- case $version_type in
- freebsd-elf*)
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
- need_version=no
- need_lib_prefix=no
- ;;
- freebsd-*)
- library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
- need_version=yes
- ;;
- linux)
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- need_lib_prefix=no
- need_version=no
- ;;
- esac
- shlibpath_var=LD_LIBRARY_PATH
- case $host_os in
- freebsd2*)
- shlibpath_overrides_runpath=yes
- ;;
- freebsd3.[01]* | freebsdelf3.[01]*)
- shlibpath_overrides_runpath=yes
- hardcode_into_libs=yes
- ;;
- freebsd3.[2-9]* | freebsdelf3.[2-9]* | \
- freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1)
- shlibpath_overrides_runpath=no
- hardcode_into_libs=yes
- ;;
- *) # from 4.6 on, and DragonFly
- shlibpath_overrides_runpath=yes
- hardcode_into_libs=yes
- ;;
- esac
- ;;
-
-gnu*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- hardcode_into_libs=yes
- ;;
-
-hpux9* | hpux10* | hpux11*)
- # Give a soname corresponding to the major version so that dld.sl refuses to
- # link against other versions.
- version_type=sunos
- need_lib_prefix=no
- need_version=no
- case $host_cpu in
- ia64*)
- shrext_cmds='.so'
- hardcode_into_libs=yes
- dynamic_linker="$host_os dld.so"
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- if test "X$HPUX_IA64_MODE" = X32; then
- sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
- else
- sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
- fi
- sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
- ;;
- hppa*64*)
- shrext_cmds='.sl'
- hardcode_into_libs=yes
- dynamic_linker="$host_os dld.sl"
- shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
- shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
- sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
- ;;
- *)
- shrext_cmds='.sl'
- dynamic_linker="$host_os dld.sl"
- shlibpath_var=SHLIB_PATH
- shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- ;;
- esac
- # HP-UX runs *really* slowly unless shared libraries are mode 555.
- postinstall_cmds='chmod 555 $lib'
- ;;
-
-interix[3-9]*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=no
- hardcode_into_libs=yes
- ;;
-
-irix5* | irix6* | nonstopux*)
- case $host_os in
- nonstopux*) version_type=nonstopux ;;
- *)
- if test "$lt_cv_prog_gnu_ld" = yes; then
- version_type=linux
- else
- version_type=irix
- fi ;;
- esac
- need_lib_prefix=no
- need_version=no
- soname_spec='${libname}${release}${shared_ext}$major'
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
- case $host_os in
- irix5* | nonstopux*)
- libsuff= shlibsuff=
- ;;
- *)
- case $LD in # libtool.m4 will add one of these switches to LD
- *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
- libsuff= shlibsuff= libmagic=32-bit;;
- *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
- libsuff=32 shlibsuff=N32 libmagic=N32;;
- *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
- libsuff=64 shlibsuff=64 libmagic=64-bit;;
- *) libsuff= shlibsuff= libmagic=never-match;;
- esac
- ;;
- esac
- shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
- shlibpath_overrides_runpath=no
- sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
- sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
- hardcode_into_libs=yes
- ;;
-
-# No shared lib support for Linux oldld, aout, or coff.
-linux*oldld* | linux*aout* | linux*coff*)
- dynamic_linker=no
- ;;
-
-# This must be Linux ELF.
-linux* | k*bsd*-gnu)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=no
- # This implies no fast_install, which is unacceptable.
- # Some rework will be needed to allow for fast_install
- # before this can be enabled.
- hardcode_into_libs=yes
-
- # Append ld.so.conf contents to the search path
- if test -f /etc/ld.so.conf; then
- lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '`
- sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
- fi
-
- # We used to test for /lib/ld.so.1 and disable shared libraries on
- # powerpc, because MkLinux only supported shared libraries with the
- # GNU dynamic linker. Since this was broken with cross compilers,
- # most powerpc-linux boxes support dynamic linking these days and
- # people can always --disable-shared, the test was removed, and we
- # assume the GNU/Linux dynamic linker is in use.
- dynamic_linker='GNU/Linux ld.so'
- ;;
-
-netbsd*)
- version_type=sunos
- need_lib_prefix=no
- need_version=no
- if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
- finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
- dynamic_linker='NetBSD (a.out) ld.so'
- else
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- dynamic_linker='NetBSD ld.elf_so'
- fi
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes
- hardcode_into_libs=yes
- ;;
-
-newsos6)
- version_type=linux
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes
- ;;
-
-nto-qnx*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes
- ;;
-
-openbsd*)
- version_type=sunos
- sys_lib_dlsearch_path_spec="/usr/lib"
- need_lib_prefix=no
- # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
- case $host_os in
- openbsd3.3 | openbsd3.3.*) need_version=yes ;;
- *) need_version=no ;;
- esac
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
- finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
- shlibpath_var=LD_LIBRARY_PATH
- if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
- case $host_os in
- openbsd2.[89] | openbsd2.[89].*)
- shlibpath_overrides_runpath=no
- ;;
- *)
- shlibpath_overrides_runpath=yes
- ;;
- esac
- else
- shlibpath_overrides_runpath=yes
- fi
- ;;
-
-os2*)
- libname_spec='$name'
- shrext_cmds=".dll"
- need_lib_prefix=no
- library_names_spec='$libname${shared_ext} $libname.a'
- dynamic_linker='OS/2 ld.exe'
- shlibpath_var=LIBPATH
- ;;
-
-osf3* | osf4* | osf5*)
- version_type=osf
- need_lib_prefix=no
- need_version=no
- soname_spec='${libname}${release}${shared_ext}$major'
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- shlibpath_var=LD_LIBRARY_PATH
- sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
- sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
- ;;
-
-rdos*)
- dynamic_linker=no
- ;;
-
-solaris*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes
- hardcode_into_libs=yes
- # ldd complains unless libraries are executable
- postinstall_cmds='chmod +x $lib'
- ;;
-
-sunos4*)
- version_type=sunos
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
- finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes
- if test "$with_gnu_ld" = yes; then
- need_lib_prefix=no
- fi
- need_version=yes
- ;;
-
-sysv4 | sysv4.3*)
- version_type=linux
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- case $host_vendor in
- sni)
- shlibpath_overrides_runpath=no
- need_lib_prefix=no
- export_dynamic_flag_spec='${wl}-Blargedynsym'
- runpath_var=LD_RUN_PATH
- ;;
- siemens)
- need_lib_prefix=no
- ;;
- motorola)
- need_lib_prefix=no
- need_version=no
- shlibpath_overrides_runpath=no
- sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
- ;;
- esac
- ;;
-
-sysv4*MP*)
- if test -d /usr/nec ;then
- version_type=linux
- library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
- soname_spec='$libname${shared_ext}.$major'
- shlibpath_var=LD_LIBRARY_PATH
- fi
- ;;
-
-sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
- version_type=freebsd-elf
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- hardcode_into_libs=yes
- if test "$with_gnu_ld" = yes; then
- sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
- shlibpath_overrides_runpath=no
- else
- sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
- shlibpath_overrides_runpath=yes
- case $host_os in
- sco3.2v5*)
- sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
- ;;
- esac
- fi
- sys_lib_dlsearch_path_spec='/usr/lib'
- ;;
-
-uts4*)
- version_type=linux
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- ;;
-
-*)
- dynamic_linker=no
- ;;
-esac
-{ echo "$as_me:$LINENO: result: $dynamic_linker" >&5
-echo "${ECHO_T}$dynamic_linker" >&6; }
-test "$dynamic_linker" = no && can_build_shared=no
-
-if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- lt_cv_sys_lib_search_path_spec="$sys_lib_search_path_spec"
-fi
-
-sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec"
-if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- lt_cv_sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec"
-fi
-
-sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec"
-
-variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
-if test "$GCC" = yes; then
- variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
-fi
-
-{ echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5
-echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6; }
-hardcode_action=
-if test -n "$hardcode_libdir_flag_spec" || \
- test -n "$runpath_var" || \
- test "X$hardcode_automatic" = "Xyes" ; then
-
- # We can hardcode non-existant directories.
- if test "$hardcode_direct" != no &&
- # If the only mechanism to avoid hardcoding is shlibpath_var, we
- # have to relink, otherwise we might link with an installed library
- # when we should be linking with a yet-to-be-installed one
- ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, )" != no &&
- test "$hardcode_minus_L" != no; then
- # Linking always hardcodes the temporary library directory.
- hardcode_action=relink
- else
- # We can link without hardcoding, and we can hardcode nonexisting dirs.
- hardcode_action=immediate
- fi
-else
- # We cannot hardcode anything, or else we can only hardcode existing
- # directories.
- hardcode_action=unsupported
-fi
-{ echo "$as_me:$LINENO: result: $hardcode_action" >&5
-echo "${ECHO_T}$hardcode_action" >&6; }
-
-if test "$hardcode_action" = relink; then
- # Fast installation is not supported
- enable_fast_install=no
-elif test "$shlibpath_overrides_runpath" = yes ||
- test "$enable_shared" = no; then
- # Fast installation is not necessary
- enable_fast_install=needless
-fi
-
-striplib=
-old_striplib=
-{ echo "$as_me:$LINENO: checking whether stripping libraries is possible" >&5
-echo $ECHO_N "checking whether stripping libraries is possible... $ECHO_C" >&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"
- { echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6; }
-else
-# FIXME - insert some real tests, host_os isn't really good enough
- case $host_os in
- darwin*)
- if test -n "$STRIP" ; then
- striplib="$STRIP -x"
- old_striplib="$STRIP -S"
- { echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6; }
- else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
- ;;
- *)
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
- ;;
- esac
-fi
-
-if test "x$enable_dlopen" != xyes; then
- enable_dlopen=unknown
- enable_dlopen_self=unknown
- enable_dlopen_self_static=unknown
-else
- lt_cv_dlopen=no
- lt_cv_dlopen_libs=
-
- case $host_os in
- beos*)
- lt_cv_dlopen="load_add_on"
- lt_cv_dlopen_libs=
- lt_cv_dlopen_self=yes
- ;;
-
- mingw* | pw32*)
- lt_cv_dlopen="LoadLibrary"
- lt_cv_dlopen_libs=
- ;;
-
- cygwin*)
- lt_cv_dlopen="dlopen"
- lt_cv_dlopen_libs=
- ;;
-
- darwin*)
- # if libdl is installed we need to link against it
- { echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5
-echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6; }
-if test "${ac_cv_lib_dl_dlopen+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-ldl $LIBS"
-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.
- 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 ();
-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 "echo \"\$as_me:$LINENO: $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
- 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 &&
- $as_test_x conftest$ac_exeext; then
- ac_cv_lib_dl_dlopen=yes
-else
- 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_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5
-echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6; }
-if test $ac_cv_lib_dl_dlopen = yes; then
- lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
-else
-
- lt_cv_dlopen="dyld"
- lt_cv_dlopen_libs=
- lt_cv_dlopen_self=yes
-
-fi
-
- ;;
-
- *)
- { echo "$as_me:$LINENO: checking for shl_load" >&5
-echo $ECHO_N "checking for shl_load... $ECHO_C" >&6; }
-if test "${ac_cv_func_shl_load+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&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 <limits.h> declares shl_load.
- For example, HP-UX 11i <limits.h> 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 <limits.h> to <assert.h> if __STDC__ is defined, since
- <limits.h> exists even on freestanding compilers. */
-
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#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 "echo \"\$as_me:$LINENO: $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
- 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 &&
- $as_test_x conftest$ac_exeext; then
- ac_cv_func_shl_load=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_func_shl_load=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_func_shl_load" >&5
-echo "${ECHO_T}$ac_cv_func_shl_load" >&6; }
-if test $ac_cv_func_shl_load = yes; then
- lt_cv_dlopen="shl_load"
-else
- { echo "$as_me:$LINENO: checking for shl_load in -ldld" >&5
-echo $ECHO_N "checking for shl_load in -ldld... $ECHO_C" >&6; }
-if test "${ac_cv_lib_dld_shl_load+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-ldld $LIBS"
-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.
- 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 ();
-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 "echo \"\$as_me:$LINENO: $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
- 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 &&
- $as_test_x conftest$ac_exeext; then
- ac_cv_lib_dld_shl_load=yes
-else
- 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_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_dld_shl_load" >&5
-echo "${ECHO_T}$ac_cv_lib_dld_shl_load" >&6; }
-if test $ac_cv_lib_dld_shl_load = yes; then
- lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"
-else
- { echo "$as_me:$LINENO: checking for dlopen" >&5
-echo $ECHO_N "checking for dlopen... $ECHO_C" >&6; }
-if test "${ac_cv_func_dlopen+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&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 <limits.h> declares dlopen.
- For example, HP-UX 11i <limits.h> declares gettimeofday. */
-#define dlopen innocuous_dlopen
-
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char dlopen (); below.
- Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- <limits.h> exists even on freestanding compilers. */
-
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#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 "echo \"\$as_me:$LINENO: $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
- 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 &&
- $as_test_x conftest$ac_exeext; then
- ac_cv_func_dlopen=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_func_dlopen=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_func_dlopen" >&5
-echo "${ECHO_T}$ac_cv_func_dlopen" >&6; }
-if test $ac_cv_func_dlopen = yes; then
- lt_cv_dlopen="dlopen"
-else
- { echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5
-echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6; }
-if test "${ac_cv_lib_dl_dlopen+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-ldl $LIBS"
-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.
- 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 ();
-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 "echo \"\$as_me:$LINENO: $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
- 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 &&
- $as_test_x conftest$ac_exeext; then
- ac_cv_lib_dl_dlopen=yes
-else
- 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_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5
-echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6; }
-if test $ac_cv_lib_dl_dlopen = yes; then
- lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
-else
- { echo "$as_me:$LINENO: checking for dlopen in -lsvld" >&5
-echo $ECHO_N "checking for dlopen in -lsvld... $ECHO_C" >&6; }
-if test "${ac_cv_lib_svld_dlopen+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lsvld $LIBS"
-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.
- 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 ();
-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 "echo \"\$as_me:$LINENO: $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
- 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 &&
- $as_test_x conftest$ac_exeext; then
- ac_cv_lib_svld_dlopen=yes
-else
- 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_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_svld_dlopen" >&5
-echo "${ECHO_T}$ac_cv_lib_svld_dlopen" >&6; }
-if test $ac_cv_lib_svld_dlopen = yes; then
- lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"
-else
- { echo "$as_me:$LINENO: checking for dld_link in -ldld" >&5
-echo $ECHO_N "checking for dld_link in -ldld... $ECHO_C" >&6; }
-if test "${ac_cv_lib_dld_dld_link+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-ldld $LIBS"
-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.
- 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 dld_link ();
-int
-main ()
-{
-return dld_link ();
- ;
- 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 "echo \"\$as_me:$LINENO: $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
- 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 &&
- $as_test_x conftest$ac_exeext; then
- ac_cv_lib_dld_dld_link=yes
-else
- 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_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_dld_dld_link" >&5
-echo "${ECHO_T}$ac_cv_lib_dld_dld_link" >&6; }
-if test $ac_cv_lib_dld_dld_link = yes; then
- lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"
-fi
-
-
-fi
-
-
-fi
-
-
-fi
-
-
-fi
-
-
-fi
-
- ;;
- esac
-
- if test "x$lt_cv_dlopen" != xno; then
- enable_dlopen=yes
- else
- enable_dlopen=no
- fi
-
- case $lt_cv_dlopen in
- dlopen)
- save_CPPFLAGS="$CPPFLAGS"
- test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
-
- save_LDFLAGS="$LDFLAGS"
- wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
-
- save_LIBS="$LIBS"
- LIBS="$lt_cv_dlopen_libs $LIBS"
-
- { echo "$as_me:$LINENO: checking whether a program can dlopen itself" >&5
-echo $ECHO_N "checking whether a program can dlopen itself... $ECHO_C" >&6; }
-if test "${lt_cv_dlopen_self+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test "$cross_compiling" = yes; then :
- lt_cv_dlopen_self=cross
-else
- lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
- lt_status=$lt_dlunknown
- cat > conftest.$ac_ext <<EOF
-#line 10715 "configure"
-#include "confdefs.h"
-
-#if HAVE_DLFCN_H
-#include <dlfcn.h>
-#endif
-
-#include <stdio.h>
-
-#ifdef RTLD_GLOBAL
-# define LT_DLGLOBAL RTLD_GLOBAL
-#else
-# ifdef DL_GLOBAL
-# define LT_DLGLOBAL DL_GLOBAL
-# else
-# define LT_DLGLOBAL 0
-# endif
-#endif
-
-/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
- find out it does not work in some platform. */
-#ifndef LT_DLLAZY_OR_NOW
-# ifdef RTLD_LAZY
-# define LT_DLLAZY_OR_NOW RTLD_LAZY
-# else
-# ifdef DL_LAZY
-# define LT_DLLAZY_OR_NOW DL_LAZY
-# else
-# ifdef RTLD_NOW
-# define LT_DLLAZY_OR_NOW RTLD_NOW
-# else
-# ifdef DL_NOW
-# define LT_DLLAZY_OR_NOW DL_NOW
-# else
-# define LT_DLLAZY_OR_NOW 0
-# endif
-# endif
-# endif
-# endif
-#endif
-
-#ifdef __cplusplus
-extern "C" void exit (int);
-#endif
-
-void fnord() { int i=42;}
-int main ()
-{
- void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
- int status = $lt_dlunknown;
-
- if (self)
- {
- if (dlsym (self,"fnord")) status = $lt_dlno_uscore;
- else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
- /* dlclose (self); */
- }
- else
- puts (dlerror ());
-
- exit (status);
-}
-EOF
- if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>&5
- ac_status=$?
- 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
- x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;;
- x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;;
- x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;;
- esac
- else :
- # compilation failed
- lt_cv_dlopen_self=no
- fi
-fi
-rm -fr conftest*
-
-
-fi
-{ echo "$as_me:$LINENO: result: $lt_cv_dlopen_self" >&5
-echo "${ECHO_T}$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\"
- { echo "$as_me:$LINENO: checking whether a statically linked program can dlopen itself" >&5
-echo $ECHO_N "checking whether a statically linked program can dlopen itself... $ECHO_C" >&6; }
-if test "${lt_cv_dlopen_self_static+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test "$cross_compiling" = yes; then :
- lt_cv_dlopen_self_static=cross
-else
- lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
- lt_status=$lt_dlunknown
- cat > conftest.$ac_ext <<EOF
-#line 10815 "configure"
-#include "confdefs.h"
-
-#if HAVE_DLFCN_H
-#include <dlfcn.h>
-#endif
-
-#include <stdio.h>
-
-#ifdef RTLD_GLOBAL
-# define LT_DLGLOBAL RTLD_GLOBAL
-#else
-# ifdef DL_GLOBAL
-# define LT_DLGLOBAL DL_GLOBAL
-# else
-# define LT_DLGLOBAL 0
-# endif
-#endif
-
-/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
- find out it does not work in some platform. */
-#ifndef LT_DLLAZY_OR_NOW
-# ifdef RTLD_LAZY
-# define LT_DLLAZY_OR_NOW RTLD_LAZY
-# else
-# ifdef DL_LAZY
-# define LT_DLLAZY_OR_NOW DL_LAZY
-# else
-# ifdef RTLD_NOW
-# define LT_DLLAZY_OR_NOW RTLD_NOW
-# else
-# ifdef DL_NOW
-# define LT_DLLAZY_OR_NOW DL_NOW
-# else
-# define LT_DLLAZY_OR_NOW 0
-# endif
-# endif
-# endif
-# endif
-#endif
-
-#ifdef __cplusplus
-extern "C" void exit (int);
-#endif
-
-void fnord() { int i=42;}
-int main ()
-{
- void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
- int status = $lt_dlunknown;
-
- if (self)
- {
- if (dlsym (self,"fnord")) status = $lt_dlno_uscore;
- else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
- /* dlclose (self); */
- }
- else
- puts (dlerror ());
-
- exit (status);
-}
-EOF
- if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>&5
- ac_status=$?
- 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
- x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;;
- x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;;
- x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;;
- esac
- else :
- # compilation failed
- lt_cv_dlopen_self_static=no
- fi
-fi
-rm -fr conftest*
-
-
-fi
-{ echo "$as_me:$LINENO: result: $lt_cv_dlopen_self_static" >&5
-echo "${ECHO_T}$lt_cv_dlopen_self_static" >&6; }
- fi
-
- CPPFLAGS="$save_CPPFLAGS"
- LDFLAGS="$save_LDFLAGS"
- LIBS="$save_LIBS"
- ;;
- esac
-
- case $lt_cv_dlopen_self in
- yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
- *) enable_dlopen_self=unknown ;;
- esac
-
- case $lt_cv_dlopen_self_static in
- yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
- *) enable_dlopen_self_static=unknown ;;
- esac
-fi
-
-
-# Report which library types will actually be built
-{ echo "$as_me:$LINENO: checking if libtool supports shared libraries" >&5
-echo $ECHO_N "checking if libtool supports shared libraries... $ECHO_C" >&6; }
-{ echo "$as_me:$LINENO: result: $can_build_shared" >&5
-echo "${ECHO_T}$can_build_shared" >&6; }
-
-{ echo "$as_me:$LINENO: checking whether to build shared libraries" >&5
-echo $ECHO_N "checking whether to build shared libraries... $ECHO_C" >&6; }
-test "$can_build_shared" = "no" && enable_shared=no
-
-# On AIX, shared libraries and static libraries use the same namespace, and
-# are all built from PIC.
-case $host_os in
-aix3*)
- test "$enable_shared" = yes && enable_static=no
- if test -n "$RANLIB"; then
- archive_cmds="$archive_cmds~\$RANLIB \$lib"
- postinstall_cmds='$RANLIB $lib'
- fi
- ;;
-
-aix[4-9]*)
- if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
- test "$enable_shared" = yes && enable_static=no
- fi
- ;;
-esac
-{ echo "$as_me:$LINENO: result: $enable_shared" >&5
-echo "${ECHO_T}$enable_shared" >&6; }
-
-{ echo "$as_me:$LINENO: checking whether to build static libraries" >&5
-echo $ECHO_N "checking whether to build static libraries... $ECHO_C" >&6; }
-# Make sure either enable_shared or enable_static is yes.
-test "$enable_shared" = yes || enable_static=yes
-{ echo "$as_me:$LINENO: result: $enable_static" >&5
-echo "${ECHO_T}$enable_static" >&6; }
-
-# The else clause should only fire when bootstrapping the
-# libtool distribution, otherwise you forgot to ship ltmain.sh
-# with your package, and you will get complaints that there are
-# no rules to generate ltmain.sh.
-if test -f "$ltmain"; then
- # See if we are running on zsh, and set the options which allow our commands through
- # without removal of \ escapes.
- if test -n "${ZSH_VERSION+set}" ; then
- setopt NO_GLOB_SUBST
- fi
- # Now quote all the things that may contain metacharacters while being
- # careful not to overquote the AC_SUBSTed values. We take copies of the
- # variables and quote the copies for generation of the libtool script.
- for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \
- SED SHELL STRIP \
- libname_spec library_names_spec soname_spec extract_expsyms_cmds \
- old_striplib striplib file_magic_cmd finish_cmds finish_eval \
- deplibs_check_method reload_flag reload_cmds need_locks \
- lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \
- lt_cv_sys_global_symbol_to_c_name_address \
- sys_lib_search_path_spec sys_lib_dlsearch_path_spec \
- old_postinstall_cmds old_postuninstall_cmds \
- compiler \
- CC \
- LD \
- lt_prog_compiler_wl \
- lt_prog_compiler_pic \
- lt_prog_compiler_static \
- lt_prog_compiler_no_builtin_flag \
- export_dynamic_flag_spec \
- thread_safe_flag_spec \
- whole_archive_flag_spec \
- enable_shared_with_static_runtimes \
- old_archive_cmds \
- old_archive_from_new_cmds \
- predep_objects \
- postdep_objects \
- predeps \
- postdeps \
- compiler_lib_search_path \
- compiler_lib_search_dirs \
- archive_cmds \
- archive_expsym_cmds \
- postinstall_cmds \
- postuninstall_cmds \
- old_archive_from_expsyms_cmds \
- allow_undefined_flag \
- no_undefined_flag \
- export_symbols_cmds \
- hardcode_libdir_flag_spec \
- hardcode_libdir_flag_spec_ld \
- hardcode_libdir_separator \
- hardcode_automatic \
- module_cmds \
- module_expsym_cmds \
- lt_cv_prog_compiler_c_o \
- fix_srcfile_path \
- exclude_expsyms \
- include_expsyms; do
-
- case $var in
- old_archive_cmds | \
- old_archive_from_new_cmds | \
- archive_cmds | \
- archive_expsym_cmds | \
- module_cmds | \
- module_expsym_cmds | \
- old_archive_from_expsyms_cmds | \
- export_symbols_cmds | \
- extract_expsyms_cmds | reload_cmds | finish_cmds | \
- postinstall_cmds | postuninstall_cmds | \
- old_postinstall_cmds | old_postuninstall_cmds | \
- sys_lib_search_path_spec | sys_lib_dlsearch_path_spec)
- # Double-quote double-evaled strings.
- eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\""
- ;;
- *)
- eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\""
- ;;
- esac
- done
-
- case $lt_echo in
- *'\$0 --fallback-echo"')
- lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'`
- ;;
- esac
-
-cfgfile="${ofile}T"
- trap "$rm \"$cfgfile\"; exit 1" 1 2 15
- $rm -f "$cfgfile"
- { echo "$as_me:$LINENO: creating $ofile" >&5
-echo "$as_me: creating $ofile" >&6;}
-
- cat <<__EOF__ >> "$cfgfile"
-#! $SHELL
-
-# `$echo "$cfgfile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
-# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP)
-# NOTE: Changes made to this file will be lost: look at ltmain.sh.
-#
-# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
-# Free Software Foundation, Inc.
-#
-# This file is part of GNU Libtool:
-# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# As a special exception to the GNU General Public License, if you
-# distribute this file as part of a program that contains a
-# configuration script generated by Autoconf, you may include it under
-# the same distribution terms that you use for the rest of that program.
-
-# A sed program that does not truncate output.
-SED=$lt_SED
-
-# Sed that helps us avoid accidentally triggering echo(1) options like -n.
-Xsed="$SED -e 1s/^X//"
-
-# The HP-UX ksh and POSIX shell print the target directory to stdout
-# if CDPATH is set.
-(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
-
-# The names of the tagged configurations supported by this script.
-available_tags=
-
-# ### BEGIN LIBTOOL CONFIG
-
-# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
-
-# Shell to use when invoking shell scripts.
-SHELL=$lt_SHELL
-
-# Whether or not to build shared libraries.
-build_libtool_libs=$enable_shared
-
-# Whether or not to build static libraries.
-build_old_libs=$enable_static
-
-# Whether or not to add -lc for building shared libraries.
-build_libtool_need_lc=$archive_cmds_need_lc
-
-# Whether or not to disallow shared libs when runtime libs are static
-allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes
-
-# Whether or not to optimize for fast installation.
-fast_install=$enable_fast_install
-
-# The host system.
-host_alias=$host_alias
-host=$host
-host_os=$host_os
-
-# The build system.
-build_alias=$build_alias
-build=$build
-build_os=$build_os
-
-# An echo program that does not interpret backslashes.
-echo=$lt_echo
-
-# The archiver.
-AR=$lt_AR
-AR_FLAGS=$lt_AR_FLAGS
-
-# A C compiler.
-LTCC=$lt_LTCC
-
-# LTCC compiler flags.
-LTCFLAGS=$lt_LTCFLAGS
-
-# A language-specific compiler.
-CC=$lt_compiler
-
-# Is the compiler the GNU C compiler?
-with_gcc=$GCC
-
-# An ERE matcher.
-EGREP=$lt_EGREP
-
-# The linker used to build libraries.
-LD=$lt_LD
-
-# Whether we need hard or soft links.
-LN_S=$lt_LN_S
-
-# A BSD-compatible nm program.
-NM=$lt_NM
-
-# A symbol stripping program
-STRIP=$lt_STRIP
-
-# Used to examine libraries when file_magic_cmd begins "file"
-MAGIC_CMD=$MAGIC_CMD
-
-# Used on cygwin: DLL creation program.
-DLLTOOL="$DLLTOOL"
-
-# Used on cygwin: object dumper.
-OBJDUMP="$OBJDUMP"
-
-# Used on cygwin: assembler.
-AS="$AS"
-
-# The name of the directory that contains temporary libtool files.
-objdir=$objdir
-
-# How to create reloadable object files.
-reload_flag=$lt_reload_flag
-reload_cmds=$lt_reload_cmds
-
-# How to pass a linker flag through the compiler.
-wl=$lt_lt_prog_compiler_wl
-
-# Object file suffix (normally "o").
-objext="$ac_objext"
-
-# Old archive suffix (normally "a").
-libext="$libext"
-
-# Shared library suffix (normally ".so").
-shrext_cmds='$shrext_cmds'
-
-# Executable file suffix (normally "").
-exeext="$exeext"
-
-# Additional compiler flags for building library objects.
-pic_flag=$lt_lt_prog_compiler_pic
-pic_mode=$pic_mode
-
-# What is the maximum length of a command?
-max_cmd_len=$lt_cv_sys_max_cmd_len
-
-# Does compiler simultaneously support -c and -o options?
-compiler_c_o=$lt_lt_cv_prog_compiler_c_o
-
-# Must we lock files when doing compilation?
-need_locks=$lt_need_locks
-
-# Do we need the lib prefix for modules?
-need_lib_prefix=$need_lib_prefix
-
-# Do we need a version for libraries?
-need_version=$need_version
-
-# Whether dlopen is supported.
-dlopen_support=$enable_dlopen
-
-# Whether dlopen of programs is supported.
-dlopen_self=$enable_dlopen_self
-
-# Whether dlopen of statically linked programs is supported.
-dlopen_self_static=$enable_dlopen_self_static
-
-# Compiler flag to prevent dynamic linking.
-link_static_flag=$lt_lt_prog_compiler_static
-
-# Compiler flag to turn off builtin functions.
-no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag
-
-# Compiler flag to allow reflexive dlopens.
-export_dynamic_flag_spec=$lt_export_dynamic_flag_spec
-
-# Compiler flag to generate shared objects directly from archives.
-whole_archive_flag_spec=$lt_whole_archive_flag_spec
-
-# Compiler flag to generate thread-safe objects.
-thread_safe_flag_spec=$lt_thread_safe_flag_spec
-
-# Library versioning type.
-version_type=$version_type
-
-# Format of library name prefix.
-libname_spec=$lt_libname_spec
-
-# List of archive names. First name is the real one, the rest are links.
-# The last name is the one that the linker finds with -lNAME.
-library_names_spec=$lt_library_names_spec
-
-# The coded name of the library, if different from the real name.
-soname_spec=$lt_soname_spec
-
-# Commands used to build and install an old-style archive.
-RANLIB=$lt_RANLIB
-old_archive_cmds=$lt_old_archive_cmds
-old_postinstall_cmds=$lt_old_postinstall_cmds
-old_postuninstall_cmds=$lt_old_postuninstall_cmds
-
-# Create an old-style archive from a shared archive.
-old_archive_from_new_cmds=$lt_old_archive_from_new_cmds
-
-# Create a temporary old-style archive to link instead of a shared archive.
-old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds
-
-# Commands used to build and install a shared archive.
-archive_cmds=$lt_archive_cmds
-archive_expsym_cmds=$lt_archive_expsym_cmds
-postinstall_cmds=$lt_postinstall_cmds
-postuninstall_cmds=$lt_postuninstall_cmds
-
-# Commands used to build a loadable module (assumed same as above if empty)
-module_cmds=$lt_module_cmds
-module_expsym_cmds=$lt_module_expsym_cmds
-
-# Commands to strip libraries.
-old_striplib=$lt_old_striplib
-striplib=$lt_striplib
-
-# Dependencies to place before the objects being linked to create a
-# shared library.
-predep_objects=$lt_predep_objects
-
-# Dependencies to place after the objects being linked to create a
-# shared library.
-postdep_objects=$lt_postdep_objects
-
-# Dependencies to place before the objects being linked to create a
-# shared library.
-predeps=$lt_predeps
-
-# Dependencies to place after the objects being linked to create a
-# shared library.
-postdeps=$lt_postdeps
-
-# The directories searched by this compiler when creating a shared
-# library
-compiler_lib_search_dirs=$lt_compiler_lib_search_dirs
-
-# The library search path used internally by the compiler when linking
-# a shared library.
-compiler_lib_search_path=$lt_compiler_lib_search_path
-
-# Method to check whether dependent libraries are shared objects.
-deplibs_check_method=$lt_deplibs_check_method
-
-# Command to use when deplibs_check_method == file_magic.
-file_magic_cmd=$lt_file_magic_cmd
-
-# Flag that allows shared libraries with undefined symbols to be built.
-allow_undefined_flag=$lt_allow_undefined_flag
-
-# Flag that forces no undefined symbols.
-no_undefined_flag=$lt_no_undefined_flag
-
-# Commands used to finish a libtool library installation in a directory.
-finish_cmds=$lt_finish_cmds
-
-# Same as above, but a single script fragment to be evaled but not shown.
-finish_eval=$lt_finish_eval
-
-# Take the output of nm and produce a listing of raw symbols and C names.
-global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe
-
-# Transform the output of nm in a proper C declaration
-global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl
-
-# Transform the output of nm in a C name address pair
-global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address
-
-# This is the shared library runtime path variable.
-runpath_var=$runpath_var
-
-# This is the shared library path variable.
-shlibpath_var=$shlibpath_var
-
-# Is shlibpath searched before the hard-coded library search path?
-shlibpath_overrides_runpath=$shlibpath_overrides_runpath
-
-# How to hardcode a shared library path into an executable.
-hardcode_action=$hardcode_action
-
-# Whether we should hardcode library paths into libraries.
-hardcode_into_libs=$hardcode_into_libs
-
-# Flag to hardcode \$libdir into a binary during linking.
-# This must work even if \$libdir does not exist.
-hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec
-
-# If ld is used when linking, flag to hardcode \$libdir into
-# a binary during linking. This must work even if \$libdir does
-# not exist.
-hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld
-
-# Whether we need a single -rpath flag with a separated argument.
-hardcode_libdir_separator=$lt_hardcode_libdir_separator
-
-# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the
-# resulting binary.
-hardcode_direct=$hardcode_direct
-
-# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
-# resulting binary.
-hardcode_minus_L=$hardcode_minus_L
-
-# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into
-# the resulting binary.
-hardcode_shlibpath_var=$hardcode_shlibpath_var
-
-# Set to yes if building a shared library automatically hardcodes DIR into the library
-# and all subsequent libraries and executables linked against it.
-hardcode_automatic=$hardcode_automatic
-
-# Variables whose values should be saved in libtool wrapper scripts and
-# restored at relink time.
-variables_saved_for_relink="$variables_saved_for_relink"
-
-# Whether libtool must link a program against all its dependency libraries.
-link_all_deplibs=$link_all_deplibs
-
-# Compile-time system search path for libraries
-sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
-
-# Run-time system search path for libraries
-sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
-
-# Fix the shell variable \$srcfile for the compiler.
-fix_srcfile_path=$lt_fix_srcfile_path
-
-# Set to yes if exported symbols are required.
-always_export_symbols=$always_export_symbols
-
-# The commands to list exported symbols.
-export_symbols_cmds=$lt_export_symbols_cmds
-
-# The commands to extract the exported symbol list from a shared archive.
-extract_expsyms_cmds=$lt_extract_expsyms_cmds
-
-# Symbols that should not be listed in the preloaded symbols.
-exclude_expsyms=$lt_exclude_expsyms
-
-# Symbols that must always be exported.
-include_expsyms=$lt_include_expsyms
-
-# ### END LIBTOOL CONFIG
-
-__EOF__
-
-
- case $host_os in
- aix3*)
- cat <<\EOF >> "$cfgfile"
-
-# AIX sometimes has problems with the GCC collect2 program. For some
-# reason, if we set the COLLECT_NAMES environment variable, the problems
-# vanish in a puff of smoke.
-if test "X${COLLECT_NAMES+set}" != Xset; then
- COLLECT_NAMES=
- export COLLECT_NAMES
-fi
-EOF
- ;;
- esac
-
- # We use sed instead of cat because bash on DJGPP gets confused if
- # if finds mixed CR/LF and LF-only lines. Since sed operates in
- # text mode, it properly converts lines to CR/LF. This bash problem
- # is reportedly fixed, but why not run on old versions too?
- sed '$q' "$ltmain" >> "$cfgfile" || (rm -f "$cfgfile"; exit 1)
-
- mv -f "$cfgfile" "$ofile" || \
- (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
- chmod +x "$ofile"
-
-else
- # If there is no Makefile yet, we rely on a make rule to execute
- # `config.status --recheck' to rerun these tests and create the
- # libtool script then.
- ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'`
- if test -f "$ltmain_in"; then
- test -f Makefile && make "$ltmain"
- fi
-fi
-
-
-ac_ext=c
-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
-
-CC="$lt_save_CC"
-
-
-# Check whether --with-tags was given.
-if test "${with_tags+set}" = set; then
- withval=$with_tags; tagnames="$withval"
-fi
-
-
-if test -f "$ltmain" && test -n "$tagnames"; then
- if test ! -f "${ofile}"; then
- { echo "$as_me:$LINENO: WARNING: output file \`$ofile' does not exist" >&5
-echo "$as_me: WARNING: output file \`$ofile' does not exist" >&2;}
- fi
-
- if test -z "$LTCC"; then
- eval "`$SHELL ${ofile} --config | grep '^LTCC='`"
- if test -z "$LTCC"; then
- { echo "$as_me:$LINENO: WARNING: output file \`$ofile' does not look like a libtool script" >&5
-echo "$as_me: WARNING: output file \`$ofile' does not look like a libtool script" >&2;}
- else
- { echo "$as_me:$LINENO: WARNING: using \`LTCC=$LTCC', extracted from \`$ofile'" >&5
-echo "$as_me: WARNING: using \`LTCC=$LTCC', extracted from \`$ofile'" >&2;}
- fi
- fi
- if test -z "$LTCFLAGS"; then
- eval "`$SHELL ${ofile} --config | grep '^LTCFLAGS='`"
- fi
-
- # Extract list of available tagged configurations in $ofile.
- # Note that this assumes the entire list is on one line.
- available_tags=`grep "^available_tags=" "${ofile}" | $SED -e 's/available_tags=\(.*$\)/\1/' -e 's/\"//g'`
-
- lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
- for tagname in $tagnames; do
- IFS="$lt_save_ifs"
- # Check whether tagname contains only valid characters
- case `$echo "X$tagname" | $Xsed -e 's:[-_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890,/]::g'` in
- "") ;;
- *) { { echo "$as_me:$LINENO: error: invalid tag name: $tagname" >&5
-echo "$as_me: error: invalid tag name: $tagname" >&2;}
- { (exit 1); exit 1; }; }
- ;;
- esac
-
- if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$" < "${ofile}" > /dev/null
- then
- { { echo "$as_me:$LINENO: error: tag name \"$tagname\" already exists" >&5
-echo "$as_me: error: tag name \"$tagname\" already exists" >&2;}
- { (exit 1); exit 1; }; }
- fi
-
- # Update the list of available tags.
- if test -n "$tagname"; then
- echo appending configuration tag \"$tagname\" to $ofile
-
- case $tagname in
- CXX)
- if test -n "$CXX" && ( test "X$CXX" != "Xno" &&
- ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) ||
- (test "X$CXX" != "Xg++"))) ; then
- ac_ext=cpp
-ac_cpp='$CXXCPP $CPPFLAGS'
-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
-
-
-
-
-archive_cmds_need_lc_CXX=no
-allow_undefined_flag_CXX=
-always_export_symbols_CXX=no
-archive_expsym_cmds_CXX=
-export_dynamic_flag_spec_CXX=
-hardcode_direct_CXX=no
-hardcode_libdir_flag_spec_CXX=
-hardcode_libdir_flag_spec_ld_CXX=
-hardcode_libdir_separator_CXX=
-hardcode_minus_L_CXX=no
-hardcode_shlibpath_var_CXX=unsupported
-hardcode_automatic_CXX=no
-module_cmds_CXX=
-module_expsym_cmds_CXX=
-link_all_deplibs_CXX=unknown
-old_archive_cmds_CXX=$old_archive_cmds
-no_undefined_flag_CXX=
-whole_archive_flag_spec_CXX=
-enable_shared_with_static_runtimes_CXX=no
-
-# Dependencies to place before and after the object being linked:
-predep_objects_CXX=
-postdep_objects_CXX=
-predeps_CXX=
-postdeps_CXX=
-compiler_lib_search_path_CXX=
-compiler_lib_search_dirs_CXX=
-
-# Source file extension for C++ test sources.
-ac_ext=cpp
-
-# Object file extension for compiled C++ test sources.
-objext=o
-objext_CXX=$objext
-
-# Code to be used in simple compile tests
-lt_simple_compile_test_code="int some_variable = 0;"
-
-# Code to be used in simple link tests
-lt_simple_link_test_code='int main(int, char *[]) { return(0); }'
-
-# ltmain only uses $CC for tagged configurations so make sure $CC is set.
-
-# If no C compiler was specified, use CC.
-LTCC=${LTCC-"$CC"}
-
-# If no C compiler flags were specified, use CFLAGS.
-LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
-
-# Allow CC to be a program name with arguments.
-compiler=$CC
-
-
-# save warnings/boilerplate of simple test code
-ac_outfile=conftest.$ac_objext
-echo "$lt_simple_compile_test_code" >conftest.$ac_ext
-eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
-_lt_compiler_boilerplate=`cat conftest.err`
-$rm conftest*
-
-ac_outfile=conftest.$ac_objext
-echo "$lt_simple_link_test_code" >conftest.$ac_ext
-eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
-_lt_linker_boilerplate=`cat conftest.err`
-$rm -r conftest*
-
-
-# Allow CC to be a program name with arguments.
-lt_save_CC=$CC
-lt_save_LD=$LD
-lt_save_GCC=$GCC
-GCC=$GXX
-lt_save_with_gnu_ld=$with_gnu_ld
-lt_save_path_LD=$lt_cv_path_LD
-if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then
- lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx
-else
- $as_unset lt_cv_prog_gnu_ld
-fi
-if test -n "${lt_cv_path_LDCXX+set}"; then
- lt_cv_path_LD=$lt_cv_path_LDCXX
-else
- $as_unset lt_cv_path_LD
-fi
-test -z "${LDCXX+set}" || LD=$LDCXX
-CC=${CXX-"c++"}
-compiler=$CC
-compiler_CXX=$CC
-for cc_temp in $compiler""; do
- case $cc_temp in
- compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
- distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
- \-*) ;;
- *) break;;
- esac
-done
-cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"`
-
-
-# We don't want -fno-exception wen compiling C++ code, so set the
-# no_builtin_flag separately
-if test "$GXX" = yes; then
- lt_prog_compiler_no_builtin_flag_CXX=' -fno-builtin'
-else
- lt_prog_compiler_no_builtin_flag_CXX=
-fi
-
-if test "$GXX" = yes; then
- # Set up default GNU C++ configuration
-
-
-# Check whether --with-gnu-ld was given.
-if test "${with_gnu_ld+set}" = set; then
- withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes
-else
- with_gnu_ld=no
-fi
-
-ac_prog=ld
-if test "$GCC" = yes; then
- # Check if gcc -print-prog-name=ld gives a path.
- { echo "$as_me:$LINENO: checking for ld used by $CC" >&5
-echo $ECHO_N "checking for ld used by $CC... $ECHO_C" >&6; }
- case $host in
- *-*-mingw*)
- # gcc leaves a trailing carriage return which upsets mingw
- ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
- *)
- ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
- esac
- case $ac_prog in
- # Accept absolute paths.
- [\\/]* | ?:[\\/]*)
- re_direlt='/[^/][^/]*/\.\./'
- # Canonicalize the pathname of ld
- ac_prog=`echo $ac_prog| $SED 's%\\\\%/%g'`
- while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
- ac_prog=`echo $ac_prog| $SED "s%$re_direlt%/%"`
- done
- test -z "$LD" && LD="$ac_prog"
- ;;
- "")
- # If it fails, then pretend we aren't using GCC.
- ac_prog=ld
- ;;
- *)
- # If it is relative, then search for the first ld in PATH.
- with_gnu_ld=unknown
- ;;
- esac
-elif test "$with_gnu_ld" = yes; then
- { echo "$as_me:$LINENO: checking for GNU ld" >&5
-echo $ECHO_N "checking for GNU ld... $ECHO_C" >&6; }
-else
- { echo "$as_me:$LINENO: checking for non-GNU ld" >&5
-echo $ECHO_N "checking for non-GNU ld... $ECHO_C" >&6; }
-fi
-if test "${lt_cv_path_LD+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -z "$LD"; then
- lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
- for ac_dir in $PATH; do
- IFS="$lt_save_ifs"
- test -z "$ac_dir" && ac_dir=.
- if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
- lt_cv_path_LD="$ac_dir/$ac_prog"
- # Check to see if the program is GNU ld. I'd rather use --version,
- # but apparently some variants of GNU ld only accept -v.
- # Break only if it was the GNU/non-GNU ld that we prefer.
- case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
- *GNU* | *'with BFD'*)
- test "$with_gnu_ld" != no && break
- ;;
- *)
- test "$with_gnu_ld" != yes && break
- ;;
- esac
- fi
- done
- IFS="$lt_save_ifs"
-else
- lt_cv_path_LD="$LD" # Let the user override the test with a path.
-fi
-fi
-
-LD="$lt_cv_path_LD"
-if test -n "$LD"; then
- { echo "$as_me:$LINENO: result: $LD" >&5
-echo "${ECHO_T}$LD" >&6; }
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-test -z "$LD" && { { echo "$as_me:$LINENO: error: no acceptable ld found in \$PATH" >&5
-echo "$as_me: error: no acceptable ld found in \$PATH" >&2;}
- { (exit 1); exit 1; }; }
-{ echo "$as_me:$LINENO: checking if the linker ($LD) is GNU ld" >&5
-echo $ECHO_N "checking if the linker ($LD) is GNU ld... $ECHO_C" >&6; }
-if test "${lt_cv_prog_gnu_ld+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- # I'd rather use --version here, but apparently some GNU lds only accept -v.
-case `$LD -v 2>&1 </dev/null` in
-*GNU* | *'with BFD'*)
- lt_cv_prog_gnu_ld=yes
- ;;
-*)
- lt_cv_prog_gnu_ld=no
- ;;
-esac
-fi
-{ echo "$as_me:$LINENO: result: $lt_cv_prog_gnu_ld" >&5
-echo "${ECHO_T}$lt_cv_prog_gnu_ld" >&6; }
-with_gnu_ld=$lt_cv_prog_gnu_ld
-
-
-
- # Check if GNU C++ uses GNU ld as the underlying linker, since the
- # archiving commands below assume that GNU ld is being used.
- if test "$with_gnu_ld" = yes; then
- archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
- archive_expsym_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
-
- hardcode_libdir_flag_spec_CXX='${wl}--rpath ${wl}$libdir'
- export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
-
- # If archive_cmds runs LD, not CC, wlarc should be empty
- # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to
- # investigate it a little bit more. (MM)
- wlarc='${wl}'
-
- # ancient GNU ld didn't support --whole-archive et. al.
- if eval "`$CC -print-prog-name=ld` --help 2>&1" | \
- grep 'no-whole-archive' > /dev/null; then
- whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
- else
- whole_archive_flag_spec_CXX=
- fi
- else
- with_gnu_ld=no
- wlarc=
-
- # A generic and very simple default shared library creation
- # command for GNU C++ for the case where it uses the native
- # linker, instead of GNU ld. If possible, this setting should
- # overridden to take advantage of the native linker features on
- # the platform it is being used on.
- archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
- fi
-
- # Commands to make compiler produce verbose output that lists
- # what "hidden" libraries, object files and flags are used when
- # linking a shared library.
- output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"'
-
-else
- GXX=no
- with_gnu_ld=no
- wlarc=
-fi
-
-# PORTME: fill in a description of your system's C++ link characteristics
-{ echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5
-echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6; }
-ld_shlibs_CXX=yes
-case $host_os in
- aix3*)
- # FIXME: insert proper C++ library support
- ld_shlibs_CXX=no
- ;;
- aix[4-9]*)
- if test "$host_cpu" = ia64; then
- # On IA64, the linker does run time linking by default, so we don't
- # have to do anything special.
- aix_use_runtimelinking=no
- exp_sym_flag='-Bexport'
- no_entry_flag=""
- else
- aix_use_runtimelinking=no
-
- # Test if we are trying to use run time linking or normal
- # AIX style linking. If -brtl is somewhere in LDFLAGS, we
- # need to do runtime linking.
- case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*)
- for ld_flag in $LDFLAGS; do
- case $ld_flag in
- *-brtl*)
- aix_use_runtimelinking=yes
- break
- ;;
- esac
- done
- ;;
- esac
-
- exp_sym_flag='-bexport'
- no_entry_flag='-bnoentry'
- fi
-
- # When large executables or shared objects are built, AIX ld can
- # have problems creating the table of contents. If linking a library
- # or program results in "error TOC overflow" add -mminimal-toc to
- # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not
- # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
-
- archive_cmds_CXX=''
- hardcode_direct_CXX=yes
- hardcode_libdir_separator_CXX=':'
- link_all_deplibs_CXX=yes
-
- if test "$GXX" = yes; then
- case $host_os in aix4.[012]|aix4.[012].*)
- # We only want to do this on AIX 4.2 and lower, the check
- # below for broken collect2 doesn't work under 4.3+
- collect2name=`${CC} -print-prog-name=collect2`
- if test -f "$collect2name" && \
- strings "$collect2name" | grep resolve_lib_name >/dev/null
- then
- # We have reworked collect2
- :
- else
- # We have old collect2
- hardcode_direct_CXX=unsupported
- # It fails to find uninstalled libraries when the uninstalled
- # path is not listed in the libpath. Setting hardcode_minus_L
- # to unsupported forces relinking
- hardcode_minus_L_CXX=yes
- hardcode_libdir_flag_spec_CXX='-L$libdir'
- hardcode_libdir_separator_CXX=
- fi
- ;;
- esac
- shared_flag='-shared'
- if test "$aix_use_runtimelinking" = yes; then
- shared_flag="$shared_flag "'${wl}-G'
- fi
- else
- # not using gcc
- if test "$host_cpu" = ia64; then
- # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
- # chokes on -Wl,-G. The following line is correct:
- shared_flag='-G'
- else
- if test "$aix_use_runtimelinking" = yes; then
- shared_flag='${wl}-G'
- else
- shared_flag='${wl}-bM:SRE'
- fi
- fi
- fi
-
- # It seems that -bexpall does not export symbols beginning with
- # underscore (_), so it is better to generate a list of symbols to export.
- always_export_symbols_CXX=yes
- if test "$aix_use_runtimelinking" = yes; then
- # Warning - without using the other runtime loading flags (-brtl),
- # -berok will link without error, but may produce a broken library.
- allow_undefined_flag_CXX='-berok'
- # Determine the default libpath from the value encoded in an empty executable.
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- 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 "echo \"\$as_me:$LINENO: $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
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_cxx_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
-
-lt_aix_libpath_sed='
- /Import File Strings/,/^$/ {
- /^0/ {
- s/^0 *\(.*\)$/\1/
- p
- }
- }'
-aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
-# Check for a 64-bit object if we didn't find anything.
-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
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-
-fi
-
-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_CXX='${wl}-blibpath:$libdir:'"$aix_libpath"
-
- archive_expsym_cmds_CXX="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
- else
- if test "$host_cpu" = ia64; then
- hardcode_libdir_flag_spec_CXX='${wl}-R $libdir:/usr/lib:/lib'
- allow_undefined_flag_CXX="-z nodefs"
- archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
- else
- # Determine the default libpath from the value encoded in an empty executable.
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- 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 "echo \"\$as_me:$LINENO: $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
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_cxx_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
-
-lt_aix_libpath_sed='
- /Import File Strings/,/^$/ {
- /^0/ {
- s/^0 *\(.*\)$/\1/
- p
- }
- }'
-aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
-# Check for a 64-bit object if we didn't find anything.
-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
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-
-fi
-
-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_CXX='${wl}-blibpath:$libdir:'"$aix_libpath"
- # Warning - without using the other run time loading flags,
- # -berok will link without error, but may produce a broken library.
- no_undefined_flag_CXX=' ${wl}-bernotok'
- allow_undefined_flag_CXX=' ${wl}-berok'
- # Exported symbols can be pulled into shared objects from archives
- whole_archive_flag_spec_CXX='$convenience'
- archive_cmds_need_lc_CXX=yes
- # This is similar to how AIX traditionally builds its shared libraries.
- archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
- fi
- fi
- ;;
-
- beos*)
- if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
- allow_undefined_flag_CXX=unsupported
- # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
- # support --undefined. This deserves some investigation. FIXME
- archive_cmds_CXX='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- else
- ld_shlibs_CXX=no
- fi
- ;;
-
- chorus*)
- case $cc_basename in
- *)
- # FIXME: insert proper C++ library support
- ld_shlibs_CXX=no
- ;;
- esac
- ;;
-
- cygwin* | mingw* | pw32*)
- # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless,
- # as there is no search path for DLLs.
- hardcode_libdir_flag_spec_CXX='-L$libdir'
- allow_undefined_flag_CXX=unsupported
- always_export_symbols_CXX=no
- enable_shared_with_static_runtimes_CXX=yes
-
- if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then
- archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
- # If the export-symbols file already is a .def file (1st line
- # is EXPORTS), use it as is; otherwise, prepend...
- archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
- cp $export_symbols $output_objdir/$soname.def;
- else
- echo EXPORTS > $output_objdir/$soname.def;
- cat $export_symbols >> $output_objdir/$soname.def;
- fi~
- $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
- else
- ld_shlibs_CXX=no
- fi
- ;;
- darwin* | rhapsody*)
- archive_cmds_need_lc_CXX=no
- hardcode_direct_CXX=no
- hardcode_automatic_CXX=yes
- hardcode_shlibpath_var_CXX=unsupported
- whole_archive_flag_spec_CXX=''
- link_all_deplibs_CXX=yes
- allow_undefined_flag_CXX="$_lt_dar_allow_undefined"
- if test "$GXX" = yes ; then
- output_verbose_link_cmd='echo'
- archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
- module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
- archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
- module_expsym_cmds_CXX="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}"
- if test "$lt_cv_apple_cc_single_mod" != "yes"; then
- archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}"
- archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}"
- fi
- else
- case $cc_basename in
- xlc*)
- output_verbose_link_cmd='echo'
- archive_cmds_CXX='$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $xlcverstring'
- module_cmds_CXX='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
- # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds
- archive_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $xlcverstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
- module_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
- ;;
- *)
- ld_shlibs_CXX=no
- ;;
- esac
- fi
- ;;
-
- dgux*)
- case $cc_basename in
- ec++*)
- # FIXME: insert proper C++ library support
- ld_shlibs_CXX=no
- ;;
- ghcx*)
- # Green Hills C++ Compiler
- # FIXME: insert proper C++ library support
- ld_shlibs_CXX=no
- ;;
- *)
- # FIXME: insert proper C++ library support
- ld_shlibs_CXX=no
- ;;
- esac
- ;;
- freebsd[12]*)
- # C++ shared libraries reported to be fairly broken before switch to ELF
- ld_shlibs_CXX=no
- ;;
- freebsd-elf*)
- archive_cmds_need_lc_CXX=no
- ;;
- freebsd* | dragonfly*)
- # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF
- # conventions
- ld_shlibs_CXX=yes
- ;;
- gnu*)
- ;;
- hpux9*)
- hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir'
- hardcode_libdir_separator_CXX=:
- export_dynamic_flag_spec_CXX='${wl}-E'
- hardcode_direct_CXX=yes
- hardcode_minus_L_CXX=yes # Not in the search PATH,
- # but as the default
- # location of the library.
-
- case $cc_basename in
- CC*)
- # FIXME: insert proper C++ library support
- ld_shlibs_CXX=no
- ;;
- aCC*)
- archive_cmds_CXX='$rm $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
- # Commands to make compiler produce verbose output that lists
- # what "hidden" libraries, object files and flags are used when
- # linking a shared library.
- #
- # There doesn't appear to be a way to prevent this compiler from
- # explicitly linking system object files so we need to strip them
- # from the output so that they don't get included in the library
- # dependencies.
- output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "[-]L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
- ;;
- *)
- if test "$GXX" = yes; then
- archive_cmds_CXX='$rm $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
- else
- # FIXME: insert proper C++ library support
- ld_shlibs_CXX=no
- fi
- ;;
- esac
- ;;
- hpux10*|hpux11*)
- if test $with_gnu_ld = no; then
- hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir'
- hardcode_libdir_separator_CXX=:
-
- case $host_cpu in
- hppa*64*|ia64*) ;;
- *)
- export_dynamic_flag_spec_CXX='${wl}-E'
- ;;
- esac
- fi
- case $host_cpu in
- hppa*64*|ia64*)
- hardcode_direct_CXX=no
- hardcode_shlibpath_var_CXX=no
- ;;
- *)
- hardcode_direct_CXX=yes
- hardcode_minus_L_CXX=yes # Not in the search PATH,
- # but as the default
- # location of the library.
- ;;
- esac
-
- case $cc_basename in
- CC*)
- # FIXME: insert proper C++ library support
- ld_shlibs_CXX=no
- ;;
- aCC*)
- case $host_cpu in
- hppa*64*)
- archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
- ;;
- ia64*)
- archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
- ;;
- *)
- archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
- ;;
- esac
- # Commands to make compiler produce verbose output that lists
- # what "hidden" libraries, object files and flags are used when
- # linking a shared library.
- #
- # There doesn't appear to be a way to prevent this compiler from
- # explicitly linking system object files so we need to strip them
- # from the output so that they don't get included in the library
- # dependencies.
- output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
- ;;
- *)
- if test "$GXX" = yes; then
- if test $with_gnu_ld = no; then
- case $host_cpu in
- hppa*64*)
- archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
- ;;
- ia64*)
- archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
- ;;
- *)
- archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
- ;;
- esac
- fi
- else
- # FIXME: insert proper C++ library support
- ld_shlibs_CXX=no
- fi
- ;;
- esac
- ;;
- interix[3-9]*)
- hardcode_direct_CXX=no
- hardcode_shlibpath_var_CXX=no
- hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
- export_dynamic_flag_spec_CXX='${wl}-E'
- # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
- # Instead, shared libraries are loaded at an image base (0x10000000 by
- # default) and relocated if they conflict, which is a slow very memory
- # consuming and fragmenting process. To avoid this, we pick a random,
- # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
- # time. Moving up from 0x10000000 also allows more sbrk(2) space.
- archive_cmds_CXX='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
- archive_expsym_cmds_CXX='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
- ;;
- irix5* | irix6*)
- case $cc_basename in
- CC*)
- # SGI C++
- archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
-
- # Archives containing C++ object files must be created using
- # "CC -ar", where "CC" is the IRIX C++ compiler. This is
- # necessary to make sure instantiated templates are included
- # in the archive.
- old_archive_cmds_CXX='$CC -ar -WR,-u -o $oldlib $oldobjs'
- ;;
- *)
- if test "$GXX" = yes; then
- if test "$with_gnu_ld" = no; then
- archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
- else
- archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` -o $lib'
- fi
- fi
- link_all_deplibs_CXX=yes
- ;;
- esac
- hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
- hardcode_libdir_separator_CXX=:
- ;;
- linux* | k*bsd*-gnu)
- case $cc_basename in
- KCC*)
- # Kuck and Associates, Inc. (KAI) C++ Compiler
-
- # KCC will only create a shared library if the output file
- # ends with ".so" (or ".sl" for HP-UX), so rename the library
- # to its proper name (with version) after linking.
- archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
- archive_expsym_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib'
- # Commands to make compiler produce verbose output that lists
- # what "hidden" libraries, object files and flags are used when
- # linking a shared library.
- #
- # There doesn't appear to be a way to prevent this compiler from
- # explicitly linking system object files so we need to strip them
- # from the output so that they don't get included in the library
- # dependencies.
- output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | grep "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
-
- hardcode_libdir_flag_spec_CXX='${wl}--rpath,$libdir'
- export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
-
- # Archives containing C++ object files must be created using
- # "CC -Bstatic", where "CC" is the KAI C++ compiler.
- old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs'
- ;;
- icpc*)
- # Intel C++
- with_gnu_ld=yes
- # version 8.0 and above of icpc choke on multiply defined symbols
- # if we add $predep_objects and $postdep_objects, however 7.1 and
- # earlier do not add the objects themselves.
- case `$CC -V 2>&1` in
- *"Version 7."*)
- archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
- archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
- ;;
- *) # Version 8.0 or newer
- tmp_idyn=
- case $host_cpu in
- ia64*) tmp_idyn=' -i_dynamic';;
- esac
- archive_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- archive_expsym_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
- ;;
- esac
- archive_cmds_need_lc_CXX=no
- hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
- export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
- whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
- ;;
- pgCC* | pgcpp*)
- # Portland Group C++ compiler
- archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
- archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
-
- hardcode_libdir_flag_spec_CXX='${wl}--rpath ${wl}$libdir'
- export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
- whole_archive_flag_spec_CXX='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
- ;;
- cxx*)
- # Compaq C++
- archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
- archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols'
-
- runpath_var=LD_RUN_PATH
- hardcode_libdir_flag_spec_CXX='-rpath $libdir'
- hardcode_libdir_separator_CXX=:
-
- # Commands to make compiler produce verbose output that lists
- # what "hidden" libraries, object files and flags are used when
- # linking a shared library.
- #
- # There doesn't appear to be a way to prevent this compiler from
- # explicitly linking system object files so we need to strip them
- # from the output so that they don't get included in the library
- # dependencies.
- output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
- ;;
- *)
- case `$CC -V 2>&1 | sed 5q` in
- *Sun\ C*)
- # Sun C++ 5.9
- no_undefined_flag_CXX=' -zdefs'
- archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
- archive_expsym_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols'
- hardcode_libdir_flag_spec_CXX='-R$libdir'
- whole_archive_flag_spec_CXX='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
-
- # Not sure whether something based on
- # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1
- # would be better.
- output_verbose_link_cmd='echo'
-
- # Archives containing C++ object files must be created using
- # "CC -xar", where "CC" is the Sun C++ compiler. This is
- # necessary to make sure instantiated templates are included
- # in the archive.
- old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs'
- ;;
- esac
- ;;
- esac
- ;;
- lynxos*)
- # FIXME: insert proper C++ library support
- ld_shlibs_CXX=no
- ;;
- m88k*)
- # FIXME: insert proper C++ library support
- ld_shlibs_CXX=no
- ;;
- mvs*)
- case $cc_basename in
- cxx*)
- # FIXME: insert proper C++ library support
- ld_shlibs_CXX=no
- ;;
- *)
- # FIXME: insert proper C++ library support
- ld_shlibs_CXX=no
- ;;
- esac
- ;;
- netbsd*)
- if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
- archive_cmds_CXX='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags'
- wlarc=
- hardcode_libdir_flag_spec_CXX='-R$libdir'
- hardcode_direct_CXX=yes
- hardcode_shlibpath_var_CXX=no
- fi
- # Workaround some broken pre-1.5 toolchains
- output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"'
- ;;
- openbsd2*)
- # C++ shared libraries are fairly broken
- ld_shlibs_CXX=no
- ;;
- openbsd*)
- if test -f /usr/libexec/ld.so; then
- hardcode_direct_CXX=yes
- hardcode_shlibpath_var_CXX=no
- archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
- hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
- if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
- archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib'
- export_dynamic_flag_spec_CXX='${wl}-E'
- whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
- fi
- output_verbose_link_cmd='echo'
- else
- ld_shlibs_CXX=no
- fi
- ;;
- osf3*)
- case $cc_basename in
- KCC*)
- # Kuck and Associates, Inc. (KAI) C++ Compiler
-
- # KCC will only create a shared library if the output file
- # ends with ".so" (or ".sl" for HP-UX), so rename the library
- # to its proper name (with version) after linking.
- archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
-
- hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
- hardcode_libdir_separator_CXX=:
-
- # Archives containing C++ object files must be created using
- # "CC -Bstatic", where "CC" is the KAI C++ compiler.
- old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs'
-
- ;;
- RCC*)
- # Rational C++ 2.4.1
- # FIXME: insert proper C++ library support
- ld_shlibs_CXX=no
- ;;
- cxx*)
- allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*'
- archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && echo ${wl}-set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
-
- hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
- hardcode_libdir_separator_CXX=:
-
- # Commands to make compiler produce verbose output that lists
- # what "hidden" libraries, object files and flags are used when
- # linking a shared library.
- #
- # There doesn't appear to be a way to prevent this compiler from
- # explicitly linking system object files so we need to strip them
- # from the output so that they don't get included in the library
- # dependencies.
- output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
- ;;
- *)
- if test "$GXX" = yes && test "$with_gnu_ld" = no; then
- allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*'
- archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
-
- hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
- hardcode_libdir_separator_CXX=:
-
- # Commands to make compiler produce verbose output that lists
- # what "hidden" libraries, object files and flags are used when
- # linking a shared library.
- output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"'
-
- else
- # FIXME: insert proper C++ library support
- ld_shlibs_CXX=no
- fi
- ;;
- esac
- ;;
- osf4* | osf5*)
- case $cc_basename in
- KCC*)
- # Kuck and Associates, Inc. (KAI) C++ Compiler
-
- # KCC will only create a shared library if the output file
- # ends with ".so" (or ".sl" for HP-UX), so rename the library
- # to its proper name (with version) after linking.
- archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
-
- hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
- hardcode_libdir_separator_CXX=:
-
- # Archives containing C++ object files must be created using
- # the KAI C++ compiler.
- old_archive_cmds_CXX='$CC -o $oldlib $oldobjs'
- ;;
- RCC*)
- # Rational C++ 2.4.1
- # FIXME: insert proper C++ library support
- ld_shlibs_CXX=no
- ;;
- cxx*)
- allow_undefined_flag_CXX=' -expect_unresolved \*'
- archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
- archive_expsym_cmds_CXX='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~
- echo "-hidden">> $lib.exp~
- $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname -Wl,-input -Wl,$lib.exp `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~
- $rm $lib.exp'
-
- hardcode_libdir_flag_spec_CXX='-rpath $libdir'
- hardcode_libdir_separator_CXX=:
-
- # Commands to make compiler produce verbose output that lists
- # what "hidden" libraries, object files and flags are used when
- # linking a shared library.
- #
- # There doesn't appear to be a way to prevent this compiler from
- # explicitly linking system object files so we need to strip them
- # from the output so that they don't get included in the library
- # dependencies.
- output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
- ;;
- *)
- if test "$GXX" = yes && test "$with_gnu_ld" = no; then
- allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*'
- archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
-
- hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
- hardcode_libdir_separator_CXX=:
-
- # Commands to make compiler produce verbose output that lists
- # what "hidden" libraries, object files and flags are used when
- # linking a shared library.
- output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"'
-
- else
- # FIXME: insert proper C++ library support
- ld_shlibs_CXX=no
- fi
- ;;
- esac
- ;;
- psos*)
- # FIXME: insert proper C++ library support
- ld_shlibs_CXX=no
- ;;
- sunos4*)
- case $cc_basename in
- CC*)
- # Sun C++ 4.x
- # FIXME: insert proper C++ library support
- ld_shlibs_CXX=no
- ;;
- lcc*)
- # Lucid
- # FIXME: insert proper C++ library support
- ld_shlibs_CXX=no
- ;;
- *)
- # FIXME: insert proper C++ library support
- ld_shlibs_CXX=no
- ;;
- esac
- ;;
- solaris*)
- case $cc_basename in
- CC*)
- # Sun C++ 4.2, 5.x and Centerline C++
- archive_cmds_need_lc_CXX=yes
- no_undefined_flag_CXX=' -zdefs'
- archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
- archive_expsym_cmds_CXX='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
- $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp'
-
- hardcode_libdir_flag_spec_CXX='-R$libdir'
- hardcode_shlibpath_var_CXX=no
- case $host_os in
- solaris2.[0-5] | solaris2.[0-5].*) ;;
- *)
- # The compiler driver will combine and reorder linker options,
- # but understands `-z linker_flag'.
- # Supported since Solaris 2.6 (maybe 2.5.1?)
- whole_archive_flag_spec_CXX='-z allextract$convenience -z defaultextract'
- ;;
- esac
- link_all_deplibs_CXX=yes
-
- output_verbose_link_cmd='echo'
-
- # Archives containing C++ object files must be created using
- # "CC -xar", where "CC" is the Sun C++ compiler. This is
- # necessary to make sure instantiated templates are included
- # in the archive.
- old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs'
- ;;
- gcx*)
- # Green Hills C++ Compiler
- archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
-
- # The C++ compiler must be used to create the archive.
- old_archive_cmds_CXX='$CC $LDFLAGS -archive -o $oldlib $oldobjs'
- ;;
- *)
- # GNU C++ compiler with Solaris linker
- if test "$GXX" = yes && test "$with_gnu_ld" = no; then
- no_undefined_flag_CXX=' ${wl}-z ${wl}defs'
- if $CC --version | grep -v '^2\.7' > /dev/null; then
- archive_cmds_CXX='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
- archive_expsym_cmds_CXX='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
- $CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp'
-
- # Commands to make compiler produce verbose output that lists
- # what "hidden" libraries, object files and flags are used when
- # linking a shared library.
- output_verbose_link_cmd="$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep \"\-L\""
- else
- # g++ 2.7 appears to require `-G' NOT `-shared' on this
- # platform.
- archive_cmds_CXX='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
- archive_expsym_cmds_CXX='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
- $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp'
-
- # Commands to make compiler produce verbose output that lists
- # what "hidden" libraries, object files and flags are used when
- # linking a shared library.
- output_verbose_link_cmd="$CC -G $CFLAGS -v conftest.$objext 2>&1 | grep \"\-L\""
- fi
-
- hardcode_libdir_flag_spec_CXX='${wl}-R $wl$libdir'
- case $host_os in
- solaris2.[0-5] | solaris2.[0-5].*) ;;
- *)
- whole_archive_flag_spec_CXX='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
- ;;
- esac
- fi
- ;;
- esac
- ;;
- sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
- no_undefined_flag_CXX='${wl}-z,text'
- archive_cmds_need_lc_CXX=no
- hardcode_shlibpath_var_CXX=no
- runpath_var='LD_RUN_PATH'
-
- case $cc_basename in
- CC*)
- archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- *)
- archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- esac
- ;;
- sysv5* | sco3.2v5* | sco5v6*)
- # Note: We can NOT use -z defs as we might desire, because we do not
- # link with -lc, and that would cause any symbols used from libc to
- # always be unresolved, which means just about no library would
- # ever link correctly. If we're not using GNU ld we use -z text
- # though, which does catch some bad symbols but isn't as heavy-handed
- # as -z defs.
- # For security reasons, it is highly recommended that you always
- # use absolute paths for naming shared libraries, and exclude the
- # DT_RUNPATH tag from executables and libraries. But doing so
- # requires that you compile everything twice, which is a pain.
- # So that behaviour is only enabled if SCOABSPATH is set to a
- # non-empty value in the environment. Most likely only useful for
- # creating official distributions of packages.
- # This is a hack until libtool officially supports absolute path
- # names for shared libraries.
- no_undefined_flag_CXX='${wl}-z,text'
- allow_undefined_flag_CXX='${wl}-z,nodefs'
- archive_cmds_need_lc_CXX=no
- hardcode_shlibpath_var_CXX=no
- hardcode_libdir_flag_spec_CXX='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`'
- hardcode_libdir_separator_CXX=':'
- link_all_deplibs_CXX=yes
- export_dynamic_flag_spec_CXX='${wl}-Bexport'
- runpath_var='LD_RUN_PATH'
-
- case $cc_basename in
- CC*)
- archive_cmds_CXX='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
- archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- *)
- archive_cmds_CXX='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
- archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- esac
- ;;
- tandem*)
- case $cc_basename in
- NCC*)
- # NonStop-UX NCC 3.20
- # FIXME: insert proper C++ library support
- ld_shlibs_CXX=no
- ;;
- *)
- # FIXME: insert proper C++ library support
- ld_shlibs_CXX=no
- ;;
- esac
- ;;
- vxworks*)
- # FIXME: insert proper C++ library support
- ld_shlibs_CXX=no
- ;;
- *)
- # FIXME: insert proper C++ library support
- ld_shlibs_CXX=no
- ;;
-esac
-{ echo "$as_me:$LINENO: result: $ld_shlibs_CXX" >&5
-echo "${ECHO_T}$ld_shlibs_CXX" >&6; }
-test "$ld_shlibs_CXX" = no && can_build_shared=no
-
-GCC_CXX="$GXX"
-LD_CXX="$LD"
-
-cat > conftest.$ac_ext <<EOF
-class Foo
-{
-public:
- Foo (void) { a = 0; }
-private:
- int a;
-};
-EOF
-
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; then
- # Parse the compiler output and extract the necessary
- # objects, libraries and library flags.
-
- # Sentinel used to keep track of whether or not we are before
- # the conftest object file.
- pre_test_object_deps_done=no
-
- # The `*' in the case matches for architectures that use `case' in
- # $output_verbose_cmd can trigger glob expansion during the loop
- # eval without this substitution.
- output_verbose_link_cmd=`$echo "X$output_verbose_link_cmd" | $Xsed -e "$no_glob_subst"`
-
- for p in `eval $output_verbose_link_cmd`; do
- case $p in
-
- -L* | -R* | -l*)
- # Some compilers place space between "-{L,R}" and the path.
- # Remove the space.
- if test $p = "-L" \
- || test $p = "-R"; then
- prev=$p
- continue
- else
- prev=
- fi
-
- if test "$pre_test_object_deps_done" = no; then
- case $p in
- -L* | -R*)
- # Internal compiler library paths should come after those
- # provided the user. The postdeps already come after the
- # user supplied libs so there is no need to process them.
- if test -z "$compiler_lib_search_path_CXX"; then
- compiler_lib_search_path_CXX="${prev}${p}"
- else
- compiler_lib_search_path_CXX="${compiler_lib_search_path_CXX} ${prev}${p}"
- fi
- ;;
- # The "-l" case would never come before the object being
- # linked, so don't bother handling this case.
- esac
- else
- if test -z "$postdeps_CXX"; then
- postdeps_CXX="${prev}${p}"
- else
- postdeps_CXX="${postdeps_CXX} ${prev}${p}"
- fi
- fi
- ;;
-
- *.$objext)
- # This assumes that the test object file only shows up
- # once in the compiler output.
- if test "$p" = "conftest.$objext"; then
- pre_test_object_deps_done=yes
- continue
- fi
-
- if test "$pre_test_object_deps_done" = no; then
- if test -z "$predep_objects_CXX"; then
- predep_objects_CXX="$p"
- else
- predep_objects_CXX="$predep_objects_CXX $p"
- fi
- else
- if test -z "$postdep_objects_CXX"; then
- postdep_objects_CXX="$p"
- else
- postdep_objects_CXX="$postdep_objects_CXX $p"
- fi
- fi
- ;;
-
- *) ;; # Ignore the rest.
-
- esac
- done
-
- # Clean up.
- rm -f a.out a.exe
-else
- echo "libtool.m4: error: problem compiling CXX test program"
-fi
-
-$rm -f confest.$objext
-
-compiler_lib_search_dirs_CXX=
-if test -n "$compiler_lib_search_path_CXX"; then
- compiler_lib_search_dirs_CXX=`echo " ${compiler_lib_search_path_CXX}" | ${SED} -e 's! -L! !g' -e 's!^ !!'`
-fi
-
-# PORTME: override above test on systems where it is broken
-case $host_os in
-interix[3-9]*)
- # Interix 3.5 installs completely hosed .la files for C++, so rather than
- # hack all around it, let's just trust "g++" to DTRT.
- predep_objects_CXX=
- postdep_objects_CXX=
- postdeps_CXX=
- ;;
-
-linux*)
- case `$CC -V 2>&1 | sed 5q` in
- *Sun\ C*)
- # Sun C++ 5.9
- #
- # The more standards-conforming stlport4 library is
- # incompatible with the Cstd library. Avoid specifying
- # it if it's in CXXFLAGS. Ignore libCrun as
- # -library=stlport4 depends on it.
- case " $CXX $CXXFLAGS " in
- *" -library=stlport4 "*)
- solaris_use_stlport4=yes
- ;;
- esac
- if test "$solaris_use_stlport4" != yes; then
- postdeps_CXX='-library=Cstd -library=Crun'
- fi
- ;;
- esac
- ;;
-
-solaris*)
- case $cc_basename in
- CC*)
- # The more standards-conforming stlport4 library is
- # incompatible with the Cstd library. Avoid specifying
- # it if it's in CXXFLAGS. Ignore libCrun as
- # -library=stlport4 depends on it.
- case " $CXX $CXXFLAGS " in
- *" -library=stlport4 "*)
- solaris_use_stlport4=yes
- ;;
- esac
-
- # Adding this requires a known-good setup of shared libraries for
- # Sun compiler versions before 5.6, else PIC objects from an old
- # archive will be linked into the output, leading to subtle bugs.
- if test "$solaris_use_stlport4" != yes; then
- postdeps_CXX='-library=Cstd -library=Crun'
- fi
- ;;
- esac
- ;;
-esac
-
-case " $postdeps_CXX " in
-*" -lc "*) archive_cmds_need_lc_CXX=no ;;
-esac
-
-lt_prog_compiler_wl_CXX=
-lt_prog_compiler_pic_CXX=
-lt_prog_compiler_static_CXX=
-
-{ echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5
-echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6; }
-
- # C++ specific cases for pic, static, wl, etc.
- if test "$GXX" = yes; then
- lt_prog_compiler_wl_CXX='-Wl,'
- lt_prog_compiler_static_CXX='-static'
-
- case $host_os in
- aix*)
- # All AIX code is PIC.
- if test "$host_cpu" = ia64; then
- # AIX 5 now supports IA64 processor
- lt_prog_compiler_static_CXX='-Bstatic'
- fi
- ;;
- amigaos*)
- # FIXME: we need at least 68020 code to build shared libraries, but
- # adding the `-m68020' flag to GCC prevents building anything better,
- # like `-m68040'.
- lt_prog_compiler_pic_CXX='-m68020 -resident32 -malways-restore-a4'
- ;;
- beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
- # PIC is the default for these OSes.
- ;;
- mingw* | cygwin* | os2* | pw32*)
- # This hack is so that the source file can tell whether it is being
- # built for inclusion in a dll (and should export symbols for example).
- # Although the cygwin gcc ignores -fPIC, still need this for old-style
- # (--disable-auto-import) libraries
- lt_prog_compiler_pic_CXX='-DDLL_EXPORT'
- ;;
- darwin* | rhapsody*)
- # PIC is the default on this platform
- # Common symbols not allowed in MH_DYLIB files
- lt_prog_compiler_pic_CXX='-fno-common'
- ;;
- *djgpp*)
- # DJGPP does not support shared libraries at all
- lt_prog_compiler_pic_CXX=
- ;;
- interix[3-9]*)
- # Interix 3.x gcc -fpic/-fPIC options generate broken code.
- # Instead, we relocate shared libraries at runtime.
- ;;
- sysv4*MP*)
- if test -d /usr/nec; then
- lt_prog_compiler_pic_CXX=-Kconform_pic
- fi
- ;;
- hpux*)
- # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
- # not for PA HP-UX.
- case $host_cpu in
- hppa*64*|ia64*)
- ;;
- *)
- lt_prog_compiler_pic_CXX='-fPIC'
- ;;
- esac
- ;;
- *)
- lt_prog_compiler_pic_CXX='-fPIC'
- ;;
- esac
- else
- case $host_os in
- aix[4-9]*)
- # All AIX code is PIC.
- if test "$host_cpu" = ia64; then
- # AIX 5 now supports IA64 processor
- lt_prog_compiler_static_CXX='-Bstatic'
- else
- lt_prog_compiler_static_CXX='-bnso -bI:/lib/syscalls.exp'
- fi
- ;;
- chorus*)
- case $cc_basename in
- cxch68*)
- # Green Hills C++ Compiler
- # _LT_AC_TAGVAR(lt_prog_compiler_static, CXX)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a"
- ;;
- esac
- ;;
- darwin*)
- # PIC is the default on this platform
- # Common symbols not allowed in MH_DYLIB files
- case $cc_basename in
- xlc*)
- lt_prog_compiler_pic_CXX='-qnocommon'
- lt_prog_compiler_wl_CXX='-Wl,'
- ;;
- esac
- ;;
- dgux*)
- case $cc_basename in
- ec++*)
- lt_prog_compiler_pic_CXX='-KPIC'
- ;;
- ghcx*)
- # Green Hills C++ Compiler
- lt_prog_compiler_pic_CXX='-pic'
- ;;
- *)
- ;;
- esac
- ;;
- freebsd* | dragonfly*)
- # FreeBSD uses GNU C++
- ;;
- hpux9* | hpux10* | hpux11*)
- case $cc_basename in
- CC*)
- lt_prog_compiler_wl_CXX='-Wl,'
- lt_prog_compiler_static_CXX='${wl}-a ${wl}archive'
- if test "$host_cpu" != ia64; then
- lt_prog_compiler_pic_CXX='+Z'
- fi
- ;;
- aCC*)
- lt_prog_compiler_wl_CXX='-Wl,'
- lt_prog_compiler_static_CXX='${wl}-a ${wl}archive'
- case $host_cpu in
- hppa*64*|ia64*)
- # +Z the default
- ;;
- *)
- lt_prog_compiler_pic_CXX='+Z'
- ;;
- esac
- ;;
- *)
- ;;
- esac
- ;;
- interix*)
- # This is c89, which is MS Visual C++ (no shared libs)
- # Anyone wants to do a port?
- ;;
- irix5* | irix6* | nonstopux*)
- case $cc_basename in
- CC*)
- lt_prog_compiler_wl_CXX='-Wl,'
- lt_prog_compiler_static_CXX='-non_shared'
- # CC pic flag -KPIC is the default.
- ;;
- *)
- ;;
- esac
- ;;
- linux* | k*bsd*-gnu)
- case $cc_basename in
- KCC*)
- # KAI C++ Compiler
- lt_prog_compiler_wl_CXX='--backend -Wl,'
- lt_prog_compiler_pic_CXX='-fPIC'
- ;;
- icpc* | ecpc*)
- # Intel C++
- lt_prog_compiler_wl_CXX='-Wl,'
- lt_prog_compiler_pic_CXX='-KPIC'
- lt_prog_compiler_static_CXX='-static'
- ;;
- pgCC* | pgcpp*)
- # Portland Group C++ compiler.
- lt_prog_compiler_wl_CXX='-Wl,'
- lt_prog_compiler_pic_CXX='-fpic'
- lt_prog_compiler_static_CXX='-Bstatic'
- ;;
- cxx*)
- # Compaq C++
- # Make sure the PIC flag is empty. It appears that all Alpha
- # Linux and Compaq Tru64 Unix objects are PIC.
- lt_prog_compiler_pic_CXX=
- lt_prog_compiler_static_CXX='-non_shared'
- ;;
- *)
- case `$CC -V 2>&1 | sed 5q` in
- *Sun\ C*)
- # Sun C++ 5.9
- lt_prog_compiler_pic_CXX='-KPIC'
- lt_prog_compiler_static_CXX='-Bstatic'
- lt_prog_compiler_wl_CXX='-Qoption ld '
- ;;
- esac
- ;;
- esac
- ;;
- lynxos*)
- ;;
- m88k*)
- ;;
- mvs*)
- case $cc_basename in
- cxx*)
- lt_prog_compiler_pic_CXX='-W c,exportall'
- ;;
- *)
- ;;
- esac
- ;;
- netbsd*)
- ;;
- osf3* | osf4* | osf5*)
- case $cc_basename in
- KCC*)
- lt_prog_compiler_wl_CXX='--backend -Wl,'
- ;;
- RCC*)
- # Rational C++ 2.4.1
- lt_prog_compiler_pic_CXX='-pic'
- ;;
- cxx*)
- # Digital/Compaq C++
- lt_prog_compiler_wl_CXX='-Wl,'
- # Make sure the PIC flag is empty. It appears that all Alpha
- # Linux and Compaq Tru64 Unix objects are PIC.
- lt_prog_compiler_pic_CXX=
- lt_prog_compiler_static_CXX='-non_shared'
- ;;
- *)
- ;;
- esac
- ;;
- psos*)
- ;;
- solaris*)
- case $cc_basename in
- CC*)
- # Sun C++ 4.2, 5.x and Centerline C++
- lt_prog_compiler_pic_CXX='-KPIC'
- lt_prog_compiler_static_CXX='-Bstatic'
- lt_prog_compiler_wl_CXX='-Qoption ld '
- ;;
- gcx*)
- # Green Hills C++ Compiler
- lt_prog_compiler_pic_CXX='-PIC'
- ;;
- *)
- ;;
- esac
- ;;
- sunos4*)
- case $cc_basename in
- CC*)
- # Sun C++ 4.x
- lt_prog_compiler_pic_CXX='-pic'
- lt_prog_compiler_static_CXX='-Bstatic'
- ;;
- lcc*)
- # Lucid
- lt_prog_compiler_pic_CXX='-pic'
- ;;
- *)
- ;;
- esac
- ;;
- tandem*)
- case $cc_basename in
- NCC*)
- # NonStop-UX NCC 3.20
- lt_prog_compiler_pic_CXX='-KPIC'
- ;;
- *)
- ;;
- esac
- ;;
- sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
- case $cc_basename in
- CC*)
- lt_prog_compiler_wl_CXX='-Wl,'
- lt_prog_compiler_pic_CXX='-KPIC'
- lt_prog_compiler_static_CXX='-Bstatic'
- ;;
- esac
- ;;
- vxworks*)
- ;;
- *)
- lt_prog_compiler_can_build_shared_CXX=no
- ;;
- esac
- fi
-
-{ echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_CXX" >&5
-echo "${ECHO_T}$lt_prog_compiler_pic_CXX" >&6; }
-
-#
-# Check to make sure the PIC flag actually works.
-#
-if test -n "$lt_prog_compiler_pic_CXX"; then
-
-{ echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5
-echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... $ECHO_C" >&6; }
-if test "${lt_cv_prog_compiler_pic_works_CXX+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- lt_cv_prog_compiler_pic_works_CXX=no
- ac_outfile=conftest.$ac_objext
- echo "$lt_simple_compile_test_code" > conftest.$ac_ext
- lt_compiler_flag="$lt_prog_compiler_pic_CXX -DPIC"
- # Insert the option either (1) after the last *FLAGS variable, or
- # (2) before a word containing "conftest.", or (3) at the end.
- # Note that $ac_compile itself does not contain backslashes and begins
- # with a dollar sign (not a hyphen), so the echo should work correctly.
- # The option is referenced via a variable to avoid confusing sed.
- lt_compile=`echo "$ac_compile" | $SED \
- -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:13216: $lt_compile\"" >&5)
- (eval "$lt_compile" 2>conftest.err)
- ac_status=$?
- cat conftest.err >&5
- echo "$as_me:13220: \$? = $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.
- $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp
- $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
- if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
- lt_cv_prog_compiler_pic_works_CXX=yes
- fi
- fi
- $rm conftest*
-
-fi
-{ echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_pic_works_CXX" >&5
-echo "${ECHO_T}$lt_cv_prog_compiler_pic_works_CXX" >&6; }
-
-if test x"$lt_cv_prog_compiler_pic_works_CXX" = xyes; then
- case $lt_prog_compiler_pic_CXX in
- "" | " "*) ;;
- *) lt_prog_compiler_pic_CXX=" $lt_prog_compiler_pic_CXX" ;;
- esac
-else
- lt_prog_compiler_pic_CXX=
- lt_prog_compiler_can_build_shared_CXX=no
-fi
-
-fi
-case $host_os in
- # For platforms which do not support PIC, -DPIC is meaningless:
- *djgpp*)
- lt_prog_compiler_pic_CXX=
- ;;
- *)
- lt_prog_compiler_pic_CXX="$lt_prog_compiler_pic_CXX -DPIC"
- ;;
-esac
-
-#
-# Check to make sure the static flag actually works.
-#
-wl=$lt_prog_compiler_wl_CXX eval lt_tmp_static_flag=\"$lt_prog_compiler_static_CXX\"
-{ echo "$as_me:$LINENO: checking if $compiler static flag $lt_tmp_static_flag works" >&5
-echo $ECHO_N "checking if $compiler static flag $lt_tmp_static_flag works... $ECHO_C" >&6; }
-if test "${lt_cv_prog_compiler_static_works_CXX+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- lt_cv_prog_compiler_static_works_CXX=no
- save_LDFLAGS="$LDFLAGS"
- LDFLAGS="$LDFLAGS $lt_tmp_static_flag"
- echo "$lt_simple_link_test_code" > conftest.$ac_ext
- if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
- # The linker can only warn and ignore the option if not recognized
- # So say no if there are warnings
- if test -s conftest.err; then
- # Append any errors to the config.log.
- cat conftest.err 1>&5
- $echo "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp
- $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
- if diff conftest.exp conftest.er2 >/dev/null; then
- lt_cv_prog_compiler_static_works_CXX=yes
- fi
- else
- lt_cv_prog_compiler_static_works_CXX=yes
- fi
- fi
- $rm -r conftest*
- LDFLAGS="$save_LDFLAGS"
-
-fi
-{ echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_static_works_CXX" >&5
-echo "${ECHO_T}$lt_cv_prog_compiler_static_works_CXX" >&6; }
-
-if test x"$lt_cv_prog_compiler_static_works_CXX" = xyes; then
- :
-else
- lt_prog_compiler_static_CXX=
-fi
-
-
-{ echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5
-echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6; }
-if test "${lt_cv_prog_compiler_c_o_CXX+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- lt_cv_prog_compiler_c_o_CXX=no
- $rm -r conftest 2>/dev/null
- mkdir conftest
- cd conftest
- mkdir out
- echo "$lt_simple_compile_test_code" > conftest.$ac_ext
-
- lt_compiler_flag="-o out/conftest2.$ac_objext"
- # Insert the option either (1) after the last *FLAGS variable, or
- # (2) before a word containing "conftest.", or (3) at the end.
- # Note that $ac_compile itself does not contain backslashes and begins
- # with a dollar sign (not a hyphen), so the echo should work correctly.
- lt_compile=`echo "$ac_compile" | $SED \
- -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:13320: $lt_compile\"" >&5)
- (eval "$lt_compile" 2>out/conftest.err)
- ac_status=$?
- cat out/conftest.err >&5
- echo "$as_me:13324: \$? = $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
- # So say no if there are warnings
- $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp
- $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
- if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
- lt_cv_prog_compiler_c_o_CXX=yes
- fi
- fi
- chmod u+w . 2>&5
- $rm conftest*
- # SGI C++ compiler will create directory out/ii_files/ for
- # template instantiation
- test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files
- $rm out/* && rmdir out
- cd ..
- rmdir conftest
- $rm conftest*
-
-fi
-{ echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o_CXX" >&5
-echo "${ECHO_T}$lt_cv_prog_compiler_c_o_CXX" >&6; }
-
-
-hard_links="nottested"
-if test "$lt_cv_prog_compiler_c_o_CXX" = no && test "$need_locks" != no; then
- # do not overwrite the value of need_locks provided by the user
- { echo "$as_me:$LINENO: checking if we can lock with hard links" >&5
-echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6; }
- hard_links=yes
- $rm conftest*
- ln conftest.a conftest.b 2>/dev/null && hard_links=no
- touch conftest.a
- ln conftest.a conftest.b 2>&5 || hard_links=no
- ln conftest.a conftest.b 2>/dev/null && hard_links=no
- { echo "$as_me:$LINENO: result: $hard_links" >&5
-echo "${ECHO_T}$hard_links" >&6; }
- if test "$hard_links" = no; then
- { echo "$as_me:$LINENO: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5
-echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;}
- need_locks=warn
- fi
-else
- need_locks=no
-fi
-
-{ echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5
-echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6; }
-
- export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
- case $host_os in
- aix[4-9]*)
- # If we're using GNU nm, then we don't want the "-C" option.
- # -C means demangle to AIX nm, but means don't demangle with GNU nm
- if $NM -V 2>&1 | grep 'GNU' > /dev/null; then
- export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols'
- else
- export_symbols_cmds_CXX='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols'
- fi
- ;;
- pw32*)
- export_symbols_cmds_CXX="$ltdll_cmds"
- ;;
- cygwin* | mingw*)
- export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;/^.*[ ]__nm__/s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols'
- ;;
- *)
- export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
- ;;
- esac
- exclude_expsyms_CXX='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'
-
-{ echo "$as_me:$LINENO: result: $ld_shlibs_CXX" >&5
-echo "${ECHO_T}$ld_shlibs_CXX" >&6; }
-test "$ld_shlibs_CXX" = no && can_build_shared=no
-
-#
-# Do we need to explicitly link libc?
-#
-case "x$archive_cmds_need_lc_CXX" in
-x|xyes)
- # Assume -lc should be added
- archive_cmds_need_lc_CXX=yes
-
- if test "$enable_shared" = yes && test "$GCC" = yes; then
- case $archive_cmds_CXX in
- *'~'*)
- # FIXME: we may have to deal with multi-command sequences.
- ;;
- '$CC '*)
- # 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.
- { echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5
-echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6; }
- $rm conftest*
- echo "$lt_simple_compile_test_code" > conftest.$ac_ext
-
- if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } 2>conftest.err; then
- soname=conftest
- lib=conftest
- libobjs=conftest.$ac_objext
- deplibs=
- wl=$lt_prog_compiler_wl_CXX
- pic_flag=$lt_prog_compiler_pic_CXX
- compiler_flags=-v
- linker_flags=-v
- verstring=
- output_objdir=.
- libname=conftest
- lt_save_allow_undefined_flag=$allow_undefined_flag_CXX
- allow_undefined_flag_CXX=
- if { (eval echo "$as_me:$LINENO: \"$archive_cmds_CXX 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1\"") >&5
- (eval $archive_cmds_CXX 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }
- then
- archive_cmds_need_lc_CXX=no
- else
- archive_cmds_need_lc_CXX=yes
- fi
- allow_undefined_flag_CXX=$lt_save_allow_undefined_flag
- else
- cat conftest.err 1>&5
- fi
- $rm conftest*
- { echo "$as_me:$LINENO: result: $archive_cmds_need_lc_CXX" >&5
-echo "${ECHO_T}$archive_cmds_need_lc_CXX" >&6; }
- ;;
- esac
- fi
- ;;
-esac
-
-{ echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5
-echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6; }
-library_names_spec=
-libname_spec='lib$name'
-soname_spec=
-shrext_cmds=".so"
-postinstall_cmds=
-postuninstall_cmds=
-finish_cmds=
-finish_eval=
-shlibpath_var=
-shlibpath_overrides_runpath=unknown
-version_type=none
-dynamic_linker="$host_os ld.so"
-sys_lib_dlsearch_path_spec="/lib /usr/lib"
-
-need_lib_prefix=unknown
-hardcode_into_libs=no
-
-# when you set need_version to no, make sure it does not cause -set_version
-# flags to be left without arguments
-need_version=unknown
-
-case $host_os in
-aix3*)
- version_type=linux
- library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
- shlibpath_var=LIBPATH
-
- # AIX 3 has no versioning support, so we append a major version to the name.
- soname_spec='${libname}${release}${shared_ext}$major'
- ;;
-
-aix[4-9]*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- hardcode_into_libs=yes
- if test "$host_cpu" = ia64; then
- # AIX 5 supports IA64
- library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
- shlibpath_var=LD_LIBRARY_PATH
- else
- # With GCC up to 2.95.x, collect2 would create an import file
- # for dependence libraries. The import file would start with
- # the line `#! .'. This would cause the generated library to
- # depend on `.', always an invalid library. This was fixed in
- # development snapshots of GCC prior to 3.0.
- case $host_os in
- aix4 | aix4.[01] | aix4.[01].*)
- if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
- echo ' yes '
- echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then
- :
- else
- can_build_shared=no
- fi
- ;;
- esac
- # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
- # soname into executable. Probably we can add versioning support to
- # collect2, so additional links can be useful in future.
- if test "$aix_use_runtimelinking" = yes; then
- # If using run time linking (on AIX 4.2 or later) use lib<name>.so
- # instead of lib<name>.a to let people know that these are not
- # typical AIX shared libraries.
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- else
- # We preserve .a as extension for shared libraries through AIX4.2
- # and later when we are not doing run time linking.
- library_names_spec='${libname}${release}.a $libname.a'
- soname_spec='${libname}${release}${shared_ext}$major'
- fi
- shlibpath_var=LIBPATH
- fi
- ;;
-
-amigaos*)
- library_names_spec='$libname.ixlibrary $libname.a'
- # Create ${libname}_ixlibrary.a entries in /sys/libs.
- finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
- ;;
-
-beos*)
- library_names_spec='${libname}${shared_ext}'
- dynamic_linker="$host_os ld.so"
- shlibpath_var=LIBRARY_PATH
- ;;
-
-bsdi[45]*)
- version_type=linux
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
- shlibpath_var=LD_LIBRARY_PATH
- sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
- sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
- # the default ld.so.conf also contains /usr/contrib/lib and
- # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
- # libtool to hard-code these into programs
- ;;
-
-cygwin* | mingw* | pw32*)
- version_type=windows
- shrext_cmds=".dll"
- need_version=no
- need_lib_prefix=no
-
- case $GCC,$host_os in
- yes,cygwin* | yes,mingw* | yes,pw32*)
- library_names_spec='$libname.dll.a'
- # DLL is installed to $(libdir)/../bin by postinstall_cmds
- postinstall_cmds='base_file=`basename \${file}`~
- dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~
- dldir=$destdir/`dirname \$dlpath`~
- test -d \$dldir || mkdir -p \$dldir~
- $install_prog $dir/$dlname \$dldir/$dlname~
- chmod a+x \$dldir/$dlname'
- postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
- dlpath=$dir/\$dldll~
- $rm \$dlpath'
- shlibpath_overrides_runpath=yes
-
- case $host_os in
- cygwin*)
- # Cygwin DLLs use 'cyg' prefix rather than 'lib'
- soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
- sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib"
- ;;
- mingw*)
- # MinGW DLLs use traditional 'lib' prefix
- soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
- sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
- if echo "$sys_lib_search_path_spec" | grep ';[c-zC-Z]:/' >/dev/null; then
- # It is most probably a Windows format PATH printed by
- # mingw gcc, but we are running on Cygwin. Gcc prints its search
- # path with ; separators, and with drive letters. We can handle the
- # drive letters (cygwin fileutils understands them), so leave them,
- # especially as we might pass files found there to a mingw objdump,
- # which wouldn't understand a cygwinified path. Ahh.
- sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
- else
- sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
- fi
- ;;
- pw32*)
- # pw32 DLLs use 'pw' prefix rather than 'lib'
- library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
- ;;
- esac
- ;;
-
- *)
- library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'
- ;;
- esac
- dynamic_linker='Win32 ld.exe'
- # FIXME: first we should search . and the directory the executable is in
- shlibpath_var=PATH
- ;;
-
-darwin* | rhapsody*)
- dynamic_linker="$host_os dyld"
- version_type=darwin
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext'
- soname_spec='${libname}${release}${major}$shared_ext'
- shlibpath_overrides_runpath=yes
- shlibpath_var=DYLD_LIBRARY_PATH
- shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
-
- sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
- ;;
-
-dgux*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- ;;
-
-freebsd1*)
- dynamic_linker=no
- ;;
-
-freebsd* | dragonfly*)
- # DragonFly does not have aout. When/if they implement a new
- # versioning mechanism, adjust this.
- if test -x /usr/bin/objformat; then
- objformat=`/usr/bin/objformat`
- else
- case $host_os in
- freebsd[123]*) objformat=aout ;;
- *) objformat=elf ;;
- esac
- fi
- # Handle Gentoo/FreeBSD as it was Linux
- case $host_vendor in
- gentoo)
- version_type=linux ;;
- *)
- version_type=freebsd-$objformat ;;
- esac
-
- case $version_type in
- freebsd-elf*)
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
- need_version=no
- need_lib_prefix=no
- ;;
- freebsd-*)
- library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
- need_version=yes
- ;;
- linux)
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- need_lib_prefix=no
- need_version=no
- ;;
- esac
- shlibpath_var=LD_LIBRARY_PATH
- case $host_os in
- freebsd2*)
- shlibpath_overrides_runpath=yes
- ;;
- freebsd3.[01]* | freebsdelf3.[01]*)
- shlibpath_overrides_runpath=yes
- hardcode_into_libs=yes
- ;;
- freebsd3.[2-9]* | freebsdelf3.[2-9]* | \
- freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1)
- shlibpath_overrides_runpath=no
- hardcode_into_libs=yes
- ;;
- *) # from 4.6 on, and DragonFly
- shlibpath_overrides_runpath=yes
- hardcode_into_libs=yes
- ;;
- esac
- ;;
-
-gnu*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- hardcode_into_libs=yes
- ;;
-
-hpux9* | hpux10* | hpux11*)
- # Give a soname corresponding to the major version so that dld.sl refuses to
- # link against other versions.
- version_type=sunos
- need_lib_prefix=no
- need_version=no
- case $host_cpu in
- ia64*)
- shrext_cmds='.so'
- hardcode_into_libs=yes
- dynamic_linker="$host_os dld.so"
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- if test "X$HPUX_IA64_MODE" = X32; then
- sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
- else
- sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
- fi
- sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
- ;;
- hppa*64*)
- shrext_cmds='.sl'
- hardcode_into_libs=yes
- dynamic_linker="$host_os dld.sl"
- shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
- shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
- sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
- ;;
- *)
- shrext_cmds='.sl'
- dynamic_linker="$host_os dld.sl"
- shlibpath_var=SHLIB_PATH
- shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- ;;
- esac
- # HP-UX runs *really* slowly unless shared libraries are mode 555.
- postinstall_cmds='chmod 555 $lib'
- ;;
-
-interix[3-9]*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=no
- hardcode_into_libs=yes
- ;;
-
-irix5* | irix6* | nonstopux*)
- case $host_os in
- nonstopux*) version_type=nonstopux ;;
- *)
- if test "$lt_cv_prog_gnu_ld" = yes; then
- version_type=linux
- else
- version_type=irix
- fi ;;
- esac
- need_lib_prefix=no
- need_version=no
- soname_spec='${libname}${release}${shared_ext}$major'
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
- case $host_os in
- irix5* | nonstopux*)
- libsuff= shlibsuff=
- ;;
- *)
- case $LD in # libtool.m4 will add one of these switches to LD
- *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
- libsuff= shlibsuff= libmagic=32-bit;;
- *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
- libsuff=32 shlibsuff=N32 libmagic=N32;;
- *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
- libsuff=64 shlibsuff=64 libmagic=64-bit;;
- *) libsuff= shlibsuff= libmagic=never-match;;
- esac
- ;;
- esac
- shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
- shlibpath_overrides_runpath=no
- sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
- sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
- hardcode_into_libs=yes
- ;;
-
-# No shared lib support for Linux oldld, aout, or coff.
-linux*oldld* | linux*aout* | linux*coff*)
- dynamic_linker=no
- ;;
-
-# This must be Linux ELF.
-linux* | k*bsd*-gnu)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=no
- # This implies no fast_install, which is unacceptable.
- # Some rework will be needed to allow for fast_install
- # before this can be enabled.
- hardcode_into_libs=yes
-
- # Append ld.so.conf contents to the search path
- if test -f /etc/ld.so.conf; then
- lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '`
- sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
- fi
-
- # We used to test for /lib/ld.so.1 and disable shared libraries on
- # powerpc, because MkLinux only supported shared libraries with the
- # GNU dynamic linker. Since this was broken with cross compilers,
- # most powerpc-linux boxes support dynamic linking these days and
- # people can always --disable-shared, the test was removed, and we
- # assume the GNU/Linux dynamic linker is in use.
- dynamic_linker='GNU/Linux ld.so'
- ;;
-
-netbsd*)
- version_type=sunos
- need_lib_prefix=no
- need_version=no
- if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
- finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
- dynamic_linker='NetBSD (a.out) ld.so'
- else
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- dynamic_linker='NetBSD ld.elf_so'
- fi
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes
- hardcode_into_libs=yes
- ;;
-
-newsos6)
- version_type=linux
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes
- ;;
-
-nto-qnx*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes
- ;;
-
-openbsd*)
- version_type=sunos
- sys_lib_dlsearch_path_spec="/usr/lib"
- need_lib_prefix=no
- # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
- case $host_os in
- openbsd3.3 | openbsd3.3.*) need_version=yes ;;
- *) need_version=no ;;
- esac
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
- finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
- shlibpath_var=LD_LIBRARY_PATH
- if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
- case $host_os in
- openbsd2.[89] | openbsd2.[89].*)
- shlibpath_overrides_runpath=no
- ;;
- *)
- shlibpath_overrides_runpath=yes
- ;;
- esac
- else
- shlibpath_overrides_runpath=yes
- fi
- ;;
-
-os2*)
- libname_spec='$name'
- shrext_cmds=".dll"
- need_lib_prefix=no
- library_names_spec='$libname${shared_ext} $libname.a'
- dynamic_linker='OS/2 ld.exe'
- shlibpath_var=LIBPATH
- ;;
-
-osf3* | osf4* | osf5*)
- version_type=osf
- need_lib_prefix=no
- need_version=no
- soname_spec='${libname}${release}${shared_ext}$major'
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- shlibpath_var=LD_LIBRARY_PATH
- sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
- sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
- ;;
-
-rdos*)
- dynamic_linker=no
- ;;
-
-solaris*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes
- hardcode_into_libs=yes
- # ldd complains unless libraries are executable
- postinstall_cmds='chmod +x $lib'
- ;;
-
-sunos4*)
- version_type=sunos
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
- finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes
- if test "$with_gnu_ld" = yes; then
- need_lib_prefix=no
- fi
- need_version=yes
- ;;
-
-sysv4 | sysv4.3*)
- version_type=linux
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- case $host_vendor in
- sni)
- shlibpath_overrides_runpath=no
- need_lib_prefix=no
- export_dynamic_flag_spec='${wl}-Blargedynsym'
- runpath_var=LD_RUN_PATH
- ;;
- siemens)
- need_lib_prefix=no
- ;;
- motorola)
- need_lib_prefix=no
- need_version=no
- shlibpath_overrides_runpath=no
- sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
- ;;
- esac
- ;;
-
-sysv4*MP*)
- if test -d /usr/nec ;then
- version_type=linux
- library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
- soname_spec='$libname${shared_ext}.$major'
- shlibpath_var=LD_LIBRARY_PATH
- fi
- ;;
-
-sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
- version_type=freebsd-elf
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- hardcode_into_libs=yes
- if test "$with_gnu_ld" = yes; then
- sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
- shlibpath_overrides_runpath=no
- else
- sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
- shlibpath_overrides_runpath=yes
- case $host_os in
- sco3.2v5*)
- sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
- ;;
- esac
- fi
- sys_lib_dlsearch_path_spec='/usr/lib'
- ;;
-
-uts4*)
- version_type=linux
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- ;;
-
-*)
- dynamic_linker=no
- ;;
-esac
-{ echo "$as_me:$LINENO: result: $dynamic_linker" >&5
-echo "${ECHO_T}$dynamic_linker" >&6; }
-test "$dynamic_linker" = no && can_build_shared=no
-
-if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- lt_cv_sys_lib_search_path_spec="$sys_lib_search_path_spec"
-fi
-
-sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec"
-if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- lt_cv_sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec"
-fi
-
-sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec"
-
-variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
-if test "$GCC" = yes; then
- variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
-fi
-
-{ echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5
-echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6; }
-hardcode_action_CXX=
-if test -n "$hardcode_libdir_flag_spec_CXX" || \
- test -n "$runpath_var_CXX" || \
- test "X$hardcode_automatic_CXX" = "Xyes" ; then
-
- # We can hardcode non-existant directories.
- if test "$hardcode_direct_CXX" != no &&
- # If the only mechanism to avoid hardcoding is shlibpath_var, we
- # have to relink, otherwise we might link with an installed library
- # when we should be linking with a yet-to-be-installed one
- ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, CXX)" != no &&
- test "$hardcode_minus_L_CXX" != no; then
- # Linking always hardcodes the temporary library directory.
- hardcode_action_CXX=relink
- else
- # We can link without hardcoding, and we can hardcode nonexisting dirs.
- hardcode_action_CXX=immediate
- fi
-else
- # We cannot hardcode anything, or else we can only hardcode existing
- # directories.
- hardcode_action_CXX=unsupported
-fi
-{ echo "$as_me:$LINENO: result: $hardcode_action_CXX" >&5
-echo "${ECHO_T}$hardcode_action_CXX" >&6; }
-
-if test "$hardcode_action_CXX" = relink; then
- # Fast installation is not supported
- enable_fast_install=no
-elif test "$shlibpath_overrides_runpath" = yes ||
- test "$enable_shared" = no; then
- # Fast installation is not necessary
- enable_fast_install=needless
-fi
-
-
-# The else clause should only fire when bootstrapping the
-# libtool distribution, otherwise you forgot to ship ltmain.sh
-# with your package, and you will get complaints that there are
-# no rules to generate ltmain.sh.
-if test -f "$ltmain"; then
- # See if we are running on zsh, and set the options which allow our commands through
- # without removal of \ escapes.
- if test -n "${ZSH_VERSION+set}" ; then
- setopt NO_GLOB_SUBST
- fi
- # Now quote all the things that may contain metacharacters while being
- # careful not to overquote the AC_SUBSTed values. We take copies of the
- # variables and quote the copies for generation of the libtool script.
- for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \
- SED SHELL STRIP \
- libname_spec library_names_spec soname_spec extract_expsyms_cmds \
- old_striplib striplib file_magic_cmd finish_cmds finish_eval \
- deplibs_check_method reload_flag reload_cmds need_locks \
- lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \
- lt_cv_sys_global_symbol_to_c_name_address \
- sys_lib_search_path_spec sys_lib_dlsearch_path_spec \
- old_postinstall_cmds old_postuninstall_cmds \
- compiler_CXX \
- CC_CXX \
- LD_CXX \
- lt_prog_compiler_wl_CXX \
- lt_prog_compiler_pic_CXX \
- lt_prog_compiler_static_CXX \
- lt_prog_compiler_no_builtin_flag_CXX \
- export_dynamic_flag_spec_CXX \
- thread_safe_flag_spec_CXX \
- whole_archive_flag_spec_CXX \
- enable_shared_with_static_runtimes_CXX \
- old_archive_cmds_CXX \
- old_archive_from_new_cmds_CXX \
- predep_objects_CXX \
- postdep_objects_CXX \
- predeps_CXX \
- postdeps_CXX \
- compiler_lib_search_path_CXX \
- compiler_lib_search_dirs_CXX \
- archive_cmds_CXX \
- archive_expsym_cmds_CXX \
- postinstall_cmds_CXX \
- postuninstall_cmds_CXX \
- old_archive_from_expsyms_cmds_CXX \
- allow_undefined_flag_CXX \
- no_undefined_flag_CXX \
- export_symbols_cmds_CXX \
- hardcode_libdir_flag_spec_CXX \
- hardcode_libdir_flag_spec_ld_CXX \
- hardcode_libdir_separator_CXX \
- hardcode_automatic_CXX \
- module_cmds_CXX \
- module_expsym_cmds_CXX \
- lt_cv_prog_compiler_c_o_CXX \
- fix_srcfile_path_CXX \
- exclude_expsyms_CXX \
- include_expsyms_CXX; do
-
- case $var in
- old_archive_cmds_CXX | \
- old_archive_from_new_cmds_CXX | \
- archive_cmds_CXX | \
- archive_expsym_cmds_CXX | \
- module_cmds_CXX | \
- module_expsym_cmds_CXX | \
- old_archive_from_expsyms_cmds_CXX | \
- export_symbols_cmds_CXX | \
- extract_expsyms_cmds | reload_cmds | finish_cmds | \
- postinstall_cmds | postuninstall_cmds | \
- old_postinstall_cmds | old_postuninstall_cmds | \
- sys_lib_search_path_spec | sys_lib_dlsearch_path_spec)
- # Double-quote double-evaled strings.
- eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\""
- ;;
- *)
- eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\""
- ;;
- esac
- done
-
- case $lt_echo in
- *'\$0 --fallback-echo"')
- lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'`
- ;;
- esac
-
-cfgfile="$ofile"
-
- cat <<__EOF__ >> "$cfgfile"
-# ### BEGIN LIBTOOL TAG CONFIG: $tagname
-
-# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
-
-# Shell to use when invoking shell scripts.
-SHELL=$lt_SHELL
-
-# Whether or not to build shared libraries.
-build_libtool_libs=$enable_shared
-
-# Whether or not to build static libraries.
-build_old_libs=$enable_static
-
-# Whether or not to add -lc for building shared libraries.
-build_libtool_need_lc=$archive_cmds_need_lc_CXX
-
-# Whether or not to disallow shared libs when runtime libs are static
-allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_CXX
-
-# Whether or not to optimize for fast installation.
-fast_install=$enable_fast_install
-
-# The host system.
-host_alias=$host_alias
-host=$host
-host_os=$host_os
-
-# The build system.
-build_alias=$build_alias
-build=$build
-build_os=$build_os
-
-# An echo program that does not interpret backslashes.
-echo=$lt_echo
-
-# The archiver.
-AR=$lt_AR
-AR_FLAGS=$lt_AR_FLAGS
-
-# A C compiler.
-LTCC=$lt_LTCC
-
-# LTCC compiler flags.
-LTCFLAGS=$lt_LTCFLAGS
-
-# A language-specific compiler.
-CC=$lt_compiler_CXX
-
-# Is the compiler the GNU C compiler?
-with_gcc=$GCC_CXX
-
-# An ERE matcher.
-EGREP=$lt_EGREP
-
-# The linker used to build libraries.
-LD=$lt_LD_CXX
-
-# Whether we need hard or soft links.
-LN_S=$lt_LN_S
-
-# A BSD-compatible nm program.
-NM=$lt_NM
-
-# A symbol stripping program
-STRIP=$lt_STRIP
-
-# Used to examine libraries when file_magic_cmd begins "file"
-MAGIC_CMD=$MAGIC_CMD
-
-# Used on cygwin: DLL creation program.
-DLLTOOL="$DLLTOOL"
-
-# Used on cygwin: object dumper.
-OBJDUMP="$OBJDUMP"
-
-# Used on cygwin: assembler.
-AS="$AS"
-
-# The name of the directory that contains temporary libtool files.
-objdir=$objdir
-
-# How to create reloadable object files.
-reload_flag=$lt_reload_flag
-reload_cmds=$lt_reload_cmds
-
-# How to pass a linker flag through the compiler.
-wl=$lt_lt_prog_compiler_wl_CXX
-
-# Object file suffix (normally "o").
-objext="$ac_objext"
-
-# Old archive suffix (normally "a").
-libext="$libext"
-
-# Shared library suffix (normally ".so").
-shrext_cmds='$shrext_cmds'
-
-# Executable file suffix (normally "").
-exeext="$exeext"
-
-# Additional compiler flags for building library objects.
-pic_flag=$lt_lt_prog_compiler_pic_CXX
-pic_mode=$pic_mode
-
-# What is the maximum length of a command?
-max_cmd_len=$lt_cv_sys_max_cmd_len
-
-# Does compiler simultaneously support -c and -o options?
-compiler_c_o=$lt_lt_cv_prog_compiler_c_o_CXX
-
-# Must we lock files when doing compilation?
-need_locks=$lt_need_locks
-
-# Do we need the lib prefix for modules?
-need_lib_prefix=$need_lib_prefix
-
-# Do we need a version for libraries?
-need_version=$need_version
-
-# Whether dlopen is supported.
-dlopen_support=$enable_dlopen
-
-# Whether dlopen of programs is supported.
-dlopen_self=$enable_dlopen_self
-
-# Whether dlopen of statically linked programs is supported.
-dlopen_self_static=$enable_dlopen_self_static
-
-# Compiler flag to prevent dynamic linking.
-link_static_flag=$lt_lt_prog_compiler_static_CXX
-
-# Compiler flag to turn off builtin functions.
-no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_CXX
-
-# Compiler flag to allow reflexive dlopens.
-export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_CXX
-
-# Compiler flag to generate shared objects directly from archives.
-whole_archive_flag_spec=$lt_whole_archive_flag_spec_CXX
-
-# Compiler flag to generate thread-safe objects.
-thread_safe_flag_spec=$lt_thread_safe_flag_spec_CXX
-
-# Library versioning type.
-version_type=$version_type
-
-# Format of library name prefix.
-libname_spec=$lt_libname_spec
-
-# List of archive names. First name is the real one, the rest are links.
-# The last name is the one that the linker finds with -lNAME.
-library_names_spec=$lt_library_names_spec
-
-# The coded name of the library, if different from the real name.
-soname_spec=$lt_soname_spec
-
-# Commands used to build and install an old-style archive.
-RANLIB=$lt_RANLIB
-old_archive_cmds=$lt_old_archive_cmds_CXX
-old_postinstall_cmds=$lt_old_postinstall_cmds
-old_postuninstall_cmds=$lt_old_postuninstall_cmds
-
-# Create an old-style archive from a shared archive.
-old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_CXX
-
-# Create a temporary old-style archive to link instead of a shared archive.
-old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_CXX
-
-# Commands used to build and install a shared archive.
-archive_cmds=$lt_archive_cmds_CXX
-archive_expsym_cmds=$lt_archive_expsym_cmds_CXX
-postinstall_cmds=$lt_postinstall_cmds
-postuninstall_cmds=$lt_postuninstall_cmds
-
-# Commands used to build a loadable module (assumed same as above if empty)
-module_cmds=$lt_module_cmds_CXX
-module_expsym_cmds=$lt_module_expsym_cmds_CXX
-
-# Commands to strip libraries.
-old_striplib=$lt_old_striplib
-striplib=$lt_striplib
-
-# Dependencies to place before the objects being linked to create a
-# shared library.
-predep_objects=$lt_predep_objects_CXX
-
-# Dependencies to place after the objects being linked to create a
-# shared library.
-postdep_objects=$lt_postdep_objects_CXX
-
-# Dependencies to place before the objects being linked to create a
-# shared library.
-predeps=$lt_predeps_CXX
-
-# Dependencies to place after the objects being linked to create a
-# shared library.
-postdeps=$lt_postdeps_CXX
-
-# The directories searched by this compiler when creating a shared
-# library
-compiler_lib_search_dirs=$lt_compiler_lib_search_dirs_CXX
-
-# The library search path used internally by the compiler when linking
-# a shared library.
-compiler_lib_search_path=$lt_compiler_lib_search_path_CXX
-
-# Method to check whether dependent libraries are shared objects.
-deplibs_check_method=$lt_deplibs_check_method
-
-# Command to use when deplibs_check_method == file_magic.
-file_magic_cmd=$lt_file_magic_cmd
-
-# Flag that allows shared libraries with undefined symbols to be built.
-allow_undefined_flag=$lt_allow_undefined_flag_CXX
-
-# Flag that forces no undefined symbols.
-no_undefined_flag=$lt_no_undefined_flag_CXX
-
-# Commands used to finish a libtool library installation in a directory.
-finish_cmds=$lt_finish_cmds
-
-# Same as above, but a single script fragment to be evaled but not shown.
-finish_eval=$lt_finish_eval
-
-# Take the output of nm and produce a listing of raw symbols and C names.
-global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe
-
-# Transform the output of nm in a proper C declaration
-global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl
-
-# Transform the output of nm in a C name address pair
-global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address
-
-# This is the shared library runtime path variable.
-runpath_var=$runpath_var
-
-# This is the shared library path variable.
-shlibpath_var=$shlibpath_var
-
-# Is shlibpath searched before the hard-coded library search path?
-shlibpath_overrides_runpath=$shlibpath_overrides_runpath
-
-# How to hardcode a shared library path into an executable.
-hardcode_action=$hardcode_action_CXX
-
-# Whether we should hardcode library paths into libraries.
-hardcode_into_libs=$hardcode_into_libs
-
-# Flag to hardcode \$libdir into a binary during linking.
-# This must work even if \$libdir does not exist.
-hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_CXX
-
-# If ld is used when linking, flag to hardcode \$libdir into
-# a binary during linking. This must work even if \$libdir does
-# not exist.
-hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_CXX
-
-# Whether we need a single -rpath flag with a separated argument.
-hardcode_libdir_separator=$lt_hardcode_libdir_separator_CXX
-
-# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the
-# resulting binary.
-hardcode_direct=$hardcode_direct_CXX
-
-# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
-# resulting binary.
-hardcode_minus_L=$hardcode_minus_L_CXX
-
-# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into
-# the resulting binary.
-hardcode_shlibpath_var=$hardcode_shlibpath_var_CXX
-
-# Set to yes if building a shared library automatically hardcodes DIR into the library
-# and all subsequent libraries and executables linked against it.
-hardcode_automatic=$hardcode_automatic_CXX
-
-# Variables whose values should be saved in libtool wrapper scripts and
-# restored at relink time.
-variables_saved_for_relink="$variables_saved_for_relink"
-
-# Whether libtool must link a program against all its dependency libraries.
-link_all_deplibs=$link_all_deplibs_CXX
-
-# Compile-time system search path for libraries
-sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
-
-# Run-time system search path for libraries
-sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
-
-# Fix the shell variable \$srcfile for the compiler.
-fix_srcfile_path=$lt_fix_srcfile_path
-
-# Set to yes if exported symbols are required.
-always_export_symbols=$always_export_symbols_CXX
-
-# The commands to list exported symbols.
-export_symbols_cmds=$lt_export_symbols_cmds_CXX
-
-# The commands to extract the exported symbol list from a shared archive.
-extract_expsyms_cmds=$lt_extract_expsyms_cmds
-
-# Symbols that should not be listed in the preloaded symbols.
-exclude_expsyms=$lt_exclude_expsyms_CXX
-
-# Symbols that must always be exported.
-include_expsyms=$lt_include_expsyms_CXX
-
-# ### END LIBTOOL TAG CONFIG: $tagname
-
-__EOF__
-
-
-else
- # If there is no Makefile yet, we rely on a make rule to execute
- # `config.status --recheck' to rerun these tests and create the
- # libtool script then.
- ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'`
- if test -f "$ltmain_in"; then
- test -f Makefile && make "$ltmain"
- fi
-fi
-
-
-ac_ext=c
-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
-
-CC=$lt_save_CC
-LDCXX=$LD
-LD=$lt_save_LD
-GCC=$lt_save_GCC
-with_gnu_ldcxx=$with_gnu_ld
-with_gnu_ld=$lt_save_with_gnu_ld
-lt_cv_path_LDCXX=$lt_cv_path_LD
-lt_cv_path_LD=$lt_save_path_LD
-lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld
-lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld
-
- else
- tagname=""
- fi
- ;;
-
- F77)
- if test -n "$F77" && test "X$F77" != "Xno"; then
-
-ac_ext=f
-ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5'
-ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_f77_compiler_gnu
-
-
-archive_cmds_need_lc_F77=no
-allow_undefined_flag_F77=
-always_export_symbols_F77=no
-archive_expsym_cmds_F77=
-export_dynamic_flag_spec_F77=
-hardcode_direct_F77=no
-hardcode_libdir_flag_spec_F77=
-hardcode_libdir_flag_spec_ld_F77=
-hardcode_libdir_separator_F77=
-hardcode_minus_L_F77=no
-hardcode_automatic_F77=no
-module_cmds_F77=
-module_expsym_cmds_F77=
-link_all_deplibs_F77=unknown
-old_archive_cmds_F77=$old_archive_cmds
-no_undefined_flag_F77=
-whole_archive_flag_spec_F77=
-enable_shared_with_static_runtimes_F77=no
-
-# Source file extension for f77 test sources.
-ac_ext=f
-
-# Object file extension for compiled f77 test sources.
-objext=o
-objext_F77=$objext
-
-# Code to be used in simple compile tests
-lt_simple_compile_test_code="\
- subroutine t
- return
- end
-"
-
-# Code to be used in simple link tests
-lt_simple_link_test_code="\
- program t
- end
-"
-
-# ltmain only uses $CC for tagged configurations so make sure $CC is set.
-
-# If no C compiler was specified, use CC.
-LTCC=${LTCC-"$CC"}
-
-# If no C compiler flags were specified, use CFLAGS.
-LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
-
-# Allow CC to be a program name with arguments.
-compiler=$CC
-
-
-# save warnings/boilerplate of simple test code
-ac_outfile=conftest.$ac_objext
-echo "$lt_simple_compile_test_code" >conftest.$ac_ext
-eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
-_lt_compiler_boilerplate=`cat conftest.err`
-$rm conftest*
-
-ac_outfile=conftest.$ac_objext
-echo "$lt_simple_link_test_code" >conftest.$ac_ext
-eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
-_lt_linker_boilerplate=`cat conftest.err`
-$rm -r conftest*
-
-
-# Allow CC to be a program name with arguments.
-lt_save_CC="$CC"
-CC=${F77-"f77"}
-compiler=$CC
-compiler_F77=$CC
-for cc_temp in $compiler""; do
- case $cc_temp in
- compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
- distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
- \-*) ;;
- *) break;;
- esac
-done
-cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"`
-
-
-{ echo "$as_me:$LINENO: checking if libtool supports shared libraries" >&5
-echo $ECHO_N "checking if libtool supports shared libraries... $ECHO_C" >&6; }
-{ echo "$as_me:$LINENO: result: $can_build_shared" >&5
-echo "${ECHO_T}$can_build_shared" >&6; }
-
-{ echo "$as_me:$LINENO: checking whether to build shared libraries" >&5
-echo $ECHO_N "checking whether to build shared libraries... $ECHO_C" >&6; }
-test "$can_build_shared" = "no" && enable_shared=no
-
-# On AIX, shared libraries and static libraries use the same namespace, and
-# are all built from PIC.
-case $host_os in
-aix3*)
- test "$enable_shared" = yes && enable_static=no
- if test -n "$RANLIB"; then
- archive_cmds="$archive_cmds~\$RANLIB \$lib"
- postinstall_cmds='$RANLIB $lib'
- fi
- ;;
-aix[4-9]*)
- if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
- test "$enable_shared" = yes && enable_static=no
- fi
- ;;
-esac
-{ echo "$as_me:$LINENO: result: $enable_shared" >&5
-echo "${ECHO_T}$enable_shared" >&6; }
-
-{ echo "$as_me:$LINENO: checking whether to build static libraries" >&5
-echo $ECHO_N "checking whether to build static libraries... $ECHO_C" >&6; }
-# Make sure either enable_shared or enable_static is yes.
-test "$enable_shared" = yes || enable_static=yes
-{ echo "$as_me:$LINENO: result: $enable_static" >&5
-echo "${ECHO_T}$enable_static" >&6; }
-
-GCC_F77="$G77"
-LD_F77="$LD"
-
-lt_prog_compiler_wl_F77=
-lt_prog_compiler_pic_F77=
-lt_prog_compiler_static_F77=
-
-{ echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5
-echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6; }
-
- if test "$GCC" = yes; then
- lt_prog_compiler_wl_F77='-Wl,'
- lt_prog_compiler_static_F77='-static'
-
- case $host_os in
- aix*)
- # All AIX code is PIC.
- if test "$host_cpu" = ia64; then
- # AIX 5 now supports IA64 processor
- lt_prog_compiler_static_F77='-Bstatic'
- fi
- ;;
-
- amigaos*)
- # FIXME: we need at least 68020 code to build shared libraries, but
- # adding the `-m68020' flag to GCC prevents building anything better,
- # like `-m68040'.
- lt_prog_compiler_pic_F77='-m68020 -resident32 -malways-restore-a4'
- ;;
-
- beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
- # PIC is the default for these OSes.
- ;;
-
- mingw* | cygwin* | pw32* | os2*)
- # This hack is so that the source file can tell whether it is being
- # built for inclusion in a dll (and should export symbols for example).
- # Although the cygwin gcc ignores -fPIC, still need this for old-style
- # (--disable-auto-import) libraries
- lt_prog_compiler_pic_F77='-DDLL_EXPORT'
- ;;
-
- darwin* | rhapsody*)
- # PIC is the default on this platform
- # Common symbols not allowed in MH_DYLIB files
- lt_prog_compiler_pic_F77='-fno-common'
- ;;
-
- interix[3-9]*)
- # Interix 3.x gcc -fpic/-fPIC options generate broken code.
- # Instead, we relocate shared libraries at runtime.
- ;;
-
- msdosdjgpp*)
- # Just because we use GCC doesn't mean we suddenly get shared libraries
- # on systems that don't support them.
- lt_prog_compiler_can_build_shared_F77=no
- enable_shared=no
- ;;
-
- sysv4*MP*)
- if test -d /usr/nec; then
- lt_prog_compiler_pic_F77=-Kconform_pic
- fi
- ;;
-
- hpux*)
- # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
- # not for PA HP-UX.
- case $host_cpu in
- hppa*64*|ia64*)
- # +Z the default
- ;;
- *)
- lt_prog_compiler_pic_F77='-fPIC'
- ;;
- esac
- ;;
-
- *)
- lt_prog_compiler_pic_F77='-fPIC'
- ;;
- esac
- else
- # PORTME Check for flag to pass linker flags through the system compiler.
- case $host_os in
- aix*)
- lt_prog_compiler_wl_F77='-Wl,'
- if test "$host_cpu" = ia64; then
- # AIX 5 now supports IA64 processor
- lt_prog_compiler_static_F77='-Bstatic'
- else
- lt_prog_compiler_static_F77='-bnso -bI:/lib/syscalls.exp'
- fi
- ;;
- darwin*)
- # PIC is the default on this platform
- # Common symbols not allowed in MH_DYLIB files
- case $cc_basename in
- xlc*)
- lt_prog_compiler_pic_F77='-qnocommon'
- lt_prog_compiler_wl_F77='-Wl,'
- ;;
- esac
- ;;
-
- mingw* | cygwin* | pw32* | os2*)
- # This hack is so that the source file can tell whether it is being
- # built for inclusion in a dll (and should export symbols for example).
- lt_prog_compiler_pic_F77='-DDLL_EXPORT'
- ;;
-
- hpux9* | hpux10* | hpux11*)
- lt_prog_compiler_wl_F77='-Wl,'
- # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
- # not for PA HP-UX.
- case $host_cpu in
- hppa*64*|ia64*)
- # +Z the default
- ;;
- *)
- lt_prog_compiler_pic_F77='+Z'
- ;;
- esac
- # Is there a better lt_prog_compiler_static that works with the bundled CC?
- lt_prog_compiler_static_F77='${wl}-a ${wl}archive'
- ;;
-
- irix5* | irix6* | nonstopux*)
- lt_prog_compiler_wl_F77='-Wl,'
- # PIC (with -KPIC) is the default.
- lt_prog_compiler_static_F77='-non_shared'
- ;;
-
- newsos6)
- lt_prog_compiler_pic_F77='-KPIC'
- lt_prog_compiler_static_F77='-Bstatic'
- ;;
-
- linux* | k*bsd*-gnu)
- case $cc_basename in
- icc* | ecc*)
- lt_prog_compiler_wl_F77='-Wl,'
- lt_prog_compiler_pic_F77='-KPIC'
- lt_prog_compiler_static_F77='-static'
- ;;
- pgcc* | pgf77* | pgf90* | pgf95*)
- # Portland Group compilers (*not* the Pentium gcc compiler,
- # which looks to be a dead project)
- lt_prog_compiler_wl_F77='-Wl,'
- lt_prog_compiler_pic_F77='-fpic'
- lt_prog_compiler_static_F77='-Bstatic'
- ;;
- ccc*)
- lt_prog_compiler_wl_F77='-Wl,'
- # All Alpha code is PIC.
- lt_prog_compiler_static_F77='-non_shared'
- ;;
- *)
- case `$CC -V 2>&1 | sed 5q` in
- *Sun\ C*)
- # Sun C 5.9
- lt_prog_compiler_pic_F77='-KPIC'
- lt_prog_compiler_static_F77='-Bstatic'
- lt_prog_compiler_wl_F77='-Wl,'
- ;;
- *Sun\ F*)
- # Sun Fortran 8.3 passes all unrecognized flags to the linker
- lt_prog_compiler_pic_F77='-KPIC'
- lt_prog_compiler_static_F77='-Bstatic'
- lt_prog_compiler_wl_F77=''
- ;;
- esac
- ;;
- esac
- ;;
-
- osf3* | osf4* | osf5*)
- lt_prog_compiler_wl_F77='-Wl,'
- # All OSF/1 code is PIC.
- lt_prog_compiler_static_F77='-non_shared'
- ;;
-
- rdos*)
- lt_prog_compiler_static_F77='-non_shared'
- ;;
-
- solaris*)
- lt_prog_compiler_pic_F77='-KPIC'
- lt_prog_compiler_static_F77='-Bstatic'
- case $cc_basename in
- f77* | f90* | f95*)
- lt_prog_compiler_wl_F77='-Qoption ld ';;
- *)
- lt_prog_compiler_wl_F77='-Wl,';;
- esac
- ;;
-
- sunos4*)
- lt_prog_compiler_wl_F77='-Qoption ld '
- lt_prog_compiler_pic_F77='-PIC'
- lt_prog_compiler_static_F77='-Bstatic'
- ;;
-
- sysv4 | sysv4.2uw2* | sysv4.3*)
- lt_prog_compiler_wl_F77='-Wl,'
- lt_prog_compiler_pic_F77='-KPIC'
- lt_prog_compiler_static_F77='-Bstatic'
- ;;
-
- sysv4*MP*)
- if test -d /usr/nec ;then
- lt_prog_compiler_pic_F77='-Kconform_pic'
- lt_prog_compiler_static_F77='-Bstatic'
- fi
- ;;
-
- sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
- lt_prog_compiler_wl_F77='-Wl,'
- lt_prog_compiler_pic_F77='-KPIC'
- lt_prog_compiler_static_F77='-Bstatic'
- ;;
-
- unicos*)
- lt_prog_compiler_wl_F77='-Wl,'
- lt_prog_compiler_can_build_shared_F77=no
- ;;
-
- uts4*)
- lt_prog_compiler_pic_F77='-pic'
- lt_prog_compiler_static_F77='-Bstatic'
- ;;
-
- *)
- lt_prog_compiler_can_build_shared_F77=no
- ;;
- esac
- fi
-
-{ echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_F77" >&5
-echo "${ECHO_T}$lt_prog_compiler_pic_F77" >&6; }
-
-#
-# Check to make sure the PIC flag actually works.
-#
-if test -n "$lt_prog_compiler_pic_F77"; then
-
-{ echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic_F77 works" >&5
-echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic_F77 works... $ECHO_C" >&6; }
-if test "${lt_cv_prog_compiler_pic_works_F77+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- lt_cv_prog_compiler_pic_works_F77=no
- ac_outfile=conftest.$ac_objext
- echo "$lt_simple_compile_test_code" > conftest.$ac_ext
- lt_compiler_flag="$lt_prog_compiler_pic_F77"
- # Insert the option either (1) after the last *FLAGS variable, or
- # (2) before a word containing "conftest.", or (3) at the end.
- # Note that $ac_compile itself does not contain backslashes and begins
- # with a dollar sign (not a hyphen), so the echo should work correctly.
- # The option is referenced via a variable to avoid confusing sed.
- lt_compile=`echo "$ac_compile" | $SED \
- -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:14916: $lt_compile\"" >&5)
- (eval "$lt_compile" 2>conftest.err)
- ac_status=$?
- cat conftest.err >&5
- echo "$as_me:14920: \$? = $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.
- $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp
- $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
- if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
- lt_cv_prog_compiler_pic_works_F77=yes
- fi
- fi
- $rm conftest*
-
-fi
-{ echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_pic_works_F77" >&5
-echo "${ECHO_T}$lt_cv_prog_compiler_pic_works_F77" >&6; }
-
-if test x"$lt_cv_prog_compiler_pic_works_F77" = xyes; then
- case $lt_prog_compiler_pic_F77 in
- "" | " "*) ;;
- *) lt_prog_compiler_pic_F77=" $lt_prog_compiler_pic_F77" ;;
- esac
-else
- lt_prog_compiler_pic_F77=
- lt_prog_compiler_can_build_shared_F77=no
-fi
-
-fi
-case $host_os in
- # For platforms which do not support PIC, -DPIC is meaningless:
- *djgpp*)
- lt_prog_compiler_pic_F77=
- ;;
- *)
- lt_prog_compiler_pic_F77="$lt_prog_compiler_pic_F77"
- ;;
-esac
-
-#
-# Check to make sure the static flag actually works.
-#
-wl=$lt_prog_compiler_wl_F77 eval lt_tmp_static_flag=\"$lt_prog_compiler_static_F77\"
-{ echo "$as_me:$LINENO: checking if $compiler static flag $lt_tmp_static_flag works" >&5
-echo $ECHO_N "checking if $compiler static flag $lt_tmp_static_flag works... $ECHO_C" >&6; }
-if test "${lt_cv_prog_compiler_static_works_F77+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- lt_cv_prog_compiler_static_works_F77=no
- save_LDFLAGS="$LDFLAGS"
- LDFLAGS="$LDFLAGS $lt_tmp_static_flag"
- echo "$lt_simple_link_test_code" > conftest.$ac_ext
- if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
- # The linker can only warn and ignore the option if not recognized
- # So say no if there are warnings
- if test -s conftest.err; then
- # Append any errors to the config.log.
- cat conftest.err 1>&5
- $echo "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp
- $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
- if diff conftest.exp conftest.er2 >/dev/null; then
- lt_cv_prog_compiler_static_works_F77=yes
- fi
- else
- lt_cv_prog_compiler_static_works_F77=yes
- fi
- fi
- $rm -r conftest*
- LDFLAGS="$save_LDFLAGS"
-
-fi
-{ echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_static_works_F77" >&5
-echo "${ECHO_T}$lt_cv_prog_compiler_static_works_F77" >&6; }
-
-if test x"$lt_cv_prog_compiler_static_works_F77" = xyes; then
- :
-else
- lt_prog_compiler_static_F77=
-fi
-
-
-{ echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5
-echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6; }
-if test "${lt_cv_prog_compiler_c_o_F77+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- lt_cv_prog_compiler_c_o_F77=no
- $rm -r conftest 2>/dev/null
- mkdir conftest
- cd conftest
- mkdir out
- echo "$lt_simple_compile_test_code" > conftest.$ac_ext
-
- lt_compiler_flag="-o out/conftest2.$ac_objext"
- # Insert the option either (1) after the last *FLAGS variable, or
- # (2) before a word containing "conftest.", or (3) at the end.
- # Note that $ac_compile itself does not contain backslashes and begins
- # with a dollar sign (not a hyphen), so the echo should work correctly.
- lt_compile=`echo "$ac_compile" | $SED \
- -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:15020: $lt_compile\"" >&5)
- (eval "$lt_compile" 2>out/conftest.err)
- ac_status=$?
- cat out/conftest.err >&5
- echo "$as_me:15024: \$? = $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
- # So say no if there are warnings
- $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp
- $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
- if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
- lt_cv_prog_compiler_c_o_F77=yes
- fi
- fi
- chmod u+w . 2>&5
- $rm conftest*
- # SGI C++ compiler will create directory out/ii_files/ for
- # template instantiation
- test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files
- $rm out/* && rmdir out
- cd ..
- rmdir conftest
- $rm conftest*
-
-fi
-{ echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o_F77" >&5
-echo "${ECHO_T}$lt_cv_prog_compiler_c_o_F77" >&6; }
-
-
-hard_links="nottested"
-if test "$lt_cv_prog_compiler_c_o_F77" = no && test "$need_locks" != no; then
- # do not overwrite the value of need_locks provided by the user
- { echo "$as_me:$LINENO: checking if we can lock with hard links" >&5
-echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6; }
- hard_links=yes
- $rm conftest*
- ln conftest.a conftest.b 2>/dev/null && hard_links=no
- touch conftest.a
- ln conftest.a conftest.b 2>&5 || hard_links=no
- ln conftest.a conftest.b 2>/dev/null && hard_links=no
- { echo "$as_me:$LINENO: result: $hard_links" >&5
-echo "${ECHO_T}$hard_links" >&6; }
- if test "$hard_links" = no; then
- { echo "$as_me:$LINENO: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5
-echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;}
- need_locks=warn
- fi
-else
- need_locks=no
-fi
-
-{ echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5
-echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6; }
-
- runpath_var=
- allow_undefined_flag_F77=
- enable_shared_with_static_runtimes_F77=no
- archive_cmds_F77=
- archive_expsym_cmds_F77=
- old_archive_From_new_cmds_F77=
- old_archive_from_expsyms_cmds_F77=
- export_dynamic_flag_spec_F77=
- whole_archive_flag_spec_F77=
- thread_safe_flag_spec_F77=
- hardcode_libdir_flag_spec_F77=
- hardcode_libdir_flag_spec_ld_F77=
- hardcode_libdir_separator_F77=
- hardcode_direct_F77=no
- hardcode_minus_L_F77=no
- hardcode_shlibpath_var_F77=unsupported
- link_all_deplibs_F77=unknown
- hardcode_automatic_F77=no
- module_cmds_F77=
- module_expsym_cmds_F77=
- always_export_symbols_F77=no
- export_symbols_cmds_F77='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
- # include_expsyms should be a list of space-separated symbols to be *always*
- # included in the symbol list
- include_expsyms_F77=
- # exclude_expsyms can be an extended regexp of symbols to exclude
- # it will be wrapped by ` (' and `)$', so one must not match beginning or
- # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
- # as well as any symbol that contains `d'.
- exclude_expsyms_F77='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'
- # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
- # platforms (ab)use it in PIC code, but their linkers get confused if
- # the symbol is explicitly referenced. Since portable code cannot
- # rely on this symbol name, it's probably fine to never include it in
- # preloaded symbol tables.
- # Exclude shared library initialization/finalization symbols.
- extract_expsyms_cmds=
- # Just being paranoid about ensuring that cc_basename is set.
- for cc_temp in $compiler""; do
- case $cc_temp in
- compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
- distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
- \-*) ;;
- *) break;;
- esac
-done
-cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"`
-
- case $host_os in
- cygwin* | mingw* | pw32*)
- # FIXME: the MSVC++ port hasn't been tested in a loooong time
- # When not using gcc, we currently assume that we are using
- # Microsoft Visual C++.
- if test "$GCC" != yes; then
- with_gnu_ld=no
- fi
- ;;
- interix*)
- # we just hope/assume this is gcc and not c89 (= MSVC++)
- with_gnu_ld=yes
- ;;
- openbsd*)
- with_gnu_ld=no
- ;;
- esac
-
- ld_shlibs_F77=yes
- if test "$with_gnu_ld" = yes; then
- # If archive_cmds runs LD, not CC, wlarc should be empty
- wlarc='${wl}'
-
- # Set some defaults for GNU ld with shared library support. These
- # are reset later if shared libraries are not supported. Putting them
- # here allows them to be overridden if necessary.
- runpath_var=LD_RUN_PATH
- hardcode_libdir_flag_spec_F77='${wl}--rpath ${wl}$libdir'
- export_dynamic_flag_spec_F77='${wl}--export-dynamic'
- # ancient GNU ld didn't support --whole-archive et. al.
- if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then
- whole_archive_flag_spec_F77="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
- else
- whole_archive_flag_spec_F77=
- fi
- supports_anon_versioning=no
- case `$LD -v 2>/dev/null` in
- *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11
- *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
- *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
- *\ 2.11.*) ;; # other 2.11 versions
- *) supports_anon_versioning=yes ;;
- esac
-
- # See if GNU ld supports shared libraries.
- case $host_os in
- aix[3-9]*)
- # On AIX/PPC, the GNU linker is very broken
- if test "$host_cpu" != ia64; then
- ld_shlibs_F77=no
- cat <<EOF 1>&2
-
-*** Warning: the GNU linker, at least up to release 2.9.1, is reported
-*** to be unable to reliably create shared libraries on AIX.
-*** Therefore, libtool is disabling shared libraries support. If you
-*** really care for shared libraries, you may want to modify your PATH
-*** so that a non-GNU linker is found, and then restart.
-
-EOF
- fi
- ;;
-
- amigaos*)
- archive_cmds_F77='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
- hardcode_libdir_flag_spec_F77='-L$libdir'
- hardcode_minus_L_F77=yes
-
- # Samuel A. Falvo II <kc5tja@dolphin.openprojects.net> reports
- # that the semantics of dynamic libraries on AmigaOS, at least up
- # to version 4, is to share data among multiple programs linked
- # with the same dynamic library. Since this doesn't match the
- # behavior of shared libraries on other platforms, we can't use
- # them.
- ld_shlibs_F77=no
- ;;
-
- beos*)
- if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
- allow_undefined_flag_F77=unsupported
- # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
- # support --undefined. This deserves some investigation. FIXME
- archive_cmds_F77='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- else
- ld_shlibs_F77=no
- fi
- ;;
-
- cygwin* | mingw* | pw32*)
- # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, F77) is actually meaningless,
- # as there is no search path for DLLs.
- hardcode_libdir_flag_spec_F77='-L$libdir'
- allow_undefined_flag_F77=unsupported
- always_export_symbols_F77=no
- enable_shared_with_static_runtimes_F77=yes
- export_symbols_cmds_F77='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/'\'' -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols'
-
- if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then
- archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
- # If the export-symbols file already is a .def file (1st line
- # is EXPORTS), use it as is; otherwise, prepend...
- archive_expsym_cmds_F77='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
- cp $export_symbols $output_objdir/$soname.def;
- else
- echo EXPORTS > $output_objdir/$soname.def;
- cat $export_symbols >> $output_objdir/$soname.def;
- fi~
- $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
- else
- ld_shlibs_F77=no
- fi
- ;;
-
- interix[3-9]*)
- hardcode_direct_F77=no
- hardcode_shlibpath_var_F77=no
- hardcode_libdir_flag_spec_F77='${wl}-rpath,$libdir'
- export_dynamic_flag_spec_F77='${wl}-E'
- # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
- # Instead, shared libraries are loaded at an image base (0x10000000 by
- # default) and relocated if they conflict, which is a slow very memory
- # consuming and fragmenting process. To avoid this, we pick a random,
- # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
- # time. Moving up from 0x10000000 also allows more sbrk(2) space.
- archive_cmds_F77='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
- archive_expsym_cmds_F77='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
- ;;
-
- gnu* | linux* | k*bsd*-gnu)
- if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
- tmp_addflag=
- case $cc_basename,$host_cpu in
- pgcc*) # Portland Group C compiler
- whole_archive_flag_spec_F77='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
- tmp_addflag=' $pic_flag'
- ;;
- pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers
- whole_archive_flag_spec_F77='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
- tmp_addflag=' $pic_flag -Mnomain' ;;
- ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64
- tmp_addflag=' -i_dynamic' ;;
- efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64
- tmp_addflag=' -i_dynamic -nofor_main' ;;
- ifc* | ifort*) # Intel Fortran compiler
- tmp_addflag=' -nofor_main' ;;
- esac
- case `$CC -V 2>&1 | sed 5q` in
- *Sun\ C*) # Sun C 5.9
- whole_archive_flag_spec_F77='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
- tmp_sharedflag='-G' ;;
- *Sun\ F*) # Sun Fortran 8.3
- tmp_sharedflag='-G' ;;
- *)
- tmp_sharedflag='-shared' ;;
- esac
- archive_cmds_F77='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
-
- if test $supports_anon_versioning = yes; then
- archive_expsym_cmds_F77='$echo "{ global:" > $output_objdir/$libname.ver~
- cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
- $echo "local: *; };" >> $output_objdir/$libname.ver~
- $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
- fi
- else
- ld_shlibs_F77=no
- fi
- ;;
-
- netbsd*)
- if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
- archive_cmds_F77='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
- wlarc=
- else
- archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- archive_expsym_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
- fi
- ;;
-
- solaris*)
- if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then
- ld_shlibs_F77=no
- cat <<EOF 1>&2
-
-*** Warning: The releases 2.8.* of the GNU linker cannot reliably
-*** create shared libraries on Solaris systems. Therefore, libtool
-*** is disabling shared libraries support. We urge you to upgrade GNU
-*** binutils to release 2.9.1 or newer. Another option is to modify
-*** your PATH or compiler configuration so that the native linker is
-*** used, and then restart.
-
-EOF
- elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
- archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- archive_expsym_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
- else
- ld_shlibs_F77=no
- fi
- ;;
-
- sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
- case `$LD -v 2>&1` in
- *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*)
- ld_shlibs_F77=no
- cat <<_LT_EOF 1>&2
-
-*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not
-*** reliably create shared libraries on SCO systems. Therefore, libtool
-*** is disabling shared libraries support. We urge you to upgrade GNU
-*** binutils to release 2.16.91.0.3 or newer. Another option is to modify
-*** your PATH or compiler configuration so that the native linker is
-*** used, and then restart.
-
-_LT_EOF
- ;;
- *)
- if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
- hardcode_libdir_flag_spec_F77='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`'
- archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib'
- archive_expsym_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname,-retain-symbols-file,$export_symbols -o $lib'
- else
- ld_shlibs_F77=no
- fi
- ;;
- esac
- ;;
-
- sunos4*)
- archive_cmds_F77='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
- wlarc=
- hardcode_direct_F77=yes
- hardcode_shlibpath_var_F77=no
- ;;
-
- *)
- if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
- archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- archive_expsym_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
- else
- ld_shlibs_F77=no
- fi
- ;;
- esac
-
- if test "$ld_shlibs_F77" = no; then
- runpath_var=
- hardcode_libdir_flag_spec_F77=
- export_dynamic_flag_spec_F77=
- whole_archive_flag_spec_F77=
- fi
- else
- # PORTME fill in a description of your system's linker (not GNU ld)
- case $host_os in
- aix3*)
- allow_undefined_flag_F77=unsupported
- always_export_symbols_F77=yes
- archive_expsym_cmds_F77='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
- # Note: this linker hardcodes the directories in LIBPATH if there
- # are no directories specified by -L.
- hardcode_minus_L_F77=yes
- if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then
- # Neither direct hardcoding nor static linking is supported with a
- # broken collect2.
- hardcode_direct_F77=unsupported
- fi
- ;;
-
- aix[4-9]*)
- if test "$host_cpu" = ia64; then
- # On IA64, the linker does run time linking by default, so we don't
- # have to do anything special.
- aix_use_runtimelinking=no
- exp_sym_flag='-Bexport'
- no_entry_flag=""
- else
- # If we're using GNU nm, then we don't want the "-C" option.
- # -C means demangle to AIX nm, but means don't demangle with GNU nm
- if $NM -V 2>&1 | grep 'GNU' > /dev/null; then
- export_symbols_cmds_F77='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols'
- else
- export_symbols_cmds_F77='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols'
- fi
- aix_use_runtimelinking=no
-
- # Test if we are trying to use run time linking or normal
- # AIX style linking. If -brtl is somewhere in LDFLAGS, we
- # need to do runtime linking.
- case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*)
- for ld_flag in $LDFLAGS; do
- if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
- aix_use_runtimelinking=yes
- break
- fi
- done
- ;;
- esac
-
- exp_sym_flag='-bexport'
- no_entry_flag='-bnoentry'
- fi
-
- # When large executables or shared objects are built, AIX ld can
- # have problems creating the table of contents. If linking a library
- # or program results in "error TOC overflow" add -mminimal-toc to
- # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not
- # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
-
- archive_cmds_F77=''
- hardcode_direct_F77=yes
- hardcode_libdir_separator_F77=':'
- link_all_deplibs_F77=yes
-
- if test "$GCC" = yes; then
- case $host_os in aix4.[012]|aix4.[012].*)
- # We only want to do this on AIX 4.2 and lower, the check
- # below for broken collect2 doesn't work under 4.3+
- collect2name=`${CC} -print-prog-name=collect2`
- if test -f "$collect2name" && \
- strings "$collect2name" | grep resolve_lib_name >/dev/null
- then
- # We have reworked collect2
- :
- else
- # We have old collect2
- hardcode_direct_F77=unsupported
- # It fails to find uninstalled libraries when the uninstalled
- # path is not listed in the libpath. Setting hardcode_minus_L
- # to unsupported forces relinking
- hardcode_minus_L_F77=yes
- hardcode_libdir_flag_spec_F77='-L$libdir'
- hardcode_libdir_separator_F77=
- fi
- ;;
- esac
- shared_flag='-shared'
- if test "$aix_use_runtimelinking" = yes; then
- shared_flag="$shared_flag "'${wl}-G'
- fi
- else
- # not using gcc
- if test "$host_cpu" = ia64; then
- # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
- # chokes on -Wl,-G. The following line is correct:
- shared_flag='-G'
- else
- if test "$aix_use_runtimelinking" = yes; then
- shared_flag='${wl}-G'
- else
- shared_flag='${wl}-bM:SRE'
- fi
- fi
- fi
-
- # It seems that -bexpall does not export symbols beginning with
- # underscore (_), so it is better to generate a list of symbols to export.
- always_export_symbols_F77=yes
- if test "$aix_use_runtimelinking" = yes; then
- # Warning - without using the other runtime loading flags (-brtl),
- # -berok will link without error, but may produce a broken library.
- allow_undefined_flag_F77='-berok'
- # Determine the default libpath from the value encoded in an empty executable.
- cat >conftest.$ac_ext <<_ACEOF
- program main
-
- end
-_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 "echo \"\$as_me:$LINENO: $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
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_f77_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
-
-lt_aix_libpath_sed='
- /Import File Strings/,/^$/ {
- /^0/ {
- s/^0 *\(.*\)$/\1/
- p
- }
- }'
-aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
-# Check for a 64-bit object if we didn't find anything.
-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
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-
-fi
-
-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_F77='${wl}-blibpath:$libdir:'"$aix_libpath"
- archive_expsym_cmds_F77="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
- else
- if test "$host_cpu" = ia64; then
- hardcode_libdir_flag_spec_F77='${wl}-R $libdir:/usr/lib:/lib'
- allow_undefined_flag_F77="-z nodefs"
- archive_expsym_cmds_F77="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
- else
- # Determine the default libpath from the value encoded in an empty executable.
- cat >conftest.$ac_ext <<_ACEOF
- program main
-
- end
-_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 "echo \"\$as_me:$LINENO: $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
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_f77_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
-
-lt_aix_libpath_sed='
- /Import File Strings/,/^$/ {
- /^0/ {
- s/^0 *\(.*\)$/\1/
- p
- }
- }'
-aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
-# Check for a 64-bit object if we didn't find anything.
-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
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-
-fi
-
-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_F77='${wl}-blibpath:$libdir:'"$aix_libpath"
- # Warning - without using the other run time loading flags,
- # -berok will link without error, but may produce a broken library.
- no_undefined_flag_F77=' ${wl}-bernotok'
- allow_undefined_flag_F77=' ${wl}-berok'
- # Exported symbols can be pulled into shared objects from archives
- whole_archive_flag_spec_F77='$convenience'
- archive_cmds_need_lc_F77=yes
- # This is similar to how AIX traditionally builds its shared libraries.
- archive_expsym_cmds_F77="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
- fi
- fi
- ;;
-
- amigaos*)
- archive_cmds_F77='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
- hardcode_libdir_flag_spec_F77='-L$libdir'
- hardcode_minus_L_F77=yes
- # see comment about different semantics on the GNU ld section
- ld_shlibs_F77=no
- ;;
-
- bsdi[45]*)
- export_dynamic_flag_spec_F77=-rdynamic
- ;;
-
- cygwin* | mingw* | pw32*)
- # When not using gcc, we currently assume that we are using
- # Microsoft Visual C++.
- # hardcode_libdir_flag_spec is actually meaningless, as there is
- # no search path for DLLs.
- hardcode_libdir_flag_spec_F77=' '
- allow_undefined_flag_F77=unsupported
- # Tell ltmain to make .lib files, not .a files.
- libext=lib
- # Tell ltmain to make .dll files, not .so files.
- shrext_cmds=".dll"
- # FIXME: Setting linknames here is a bad hack.
- archive_cmds_F77='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | $SED -e '\''s/ -lc$//'\''` -link -dll~linknames='
- # The linker will automatically build a .lib file if we build a DLL.
- old_archive_From_new_cmds_F77='true'
- # FIXME: Should let the user specify the lib program.
- old_archive_cmds_F77='lib -OUT:$oldlib$oldobjs$old_deplibs'
- fix_srcfile_path_F77='`cygpath -w "$srcfile"`'
- enable_shared_with_static_runtimes_F77=yes
- ;;
-
- darwin* | rhapsody*)
- case $host_os in
- rhapsody* | darwin1.[012])
- allow_undefined_flag_F77='${wl}-undefined ${wl}suppress'
- ;;
- *) # Darwin 1.3 on
- if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then
- allow_undefined_flag_F77='${wl}-flat_namespace ${wl}-undefined ${wl}suppress'
- else
- case ${MACOSX_DEPLOYMENT_TARGET} in
- 10.[012])
- allow_undefined_flag_F77='${wl}-flat_namespace ${wl}-undefined ${wl}suppress'
- ;;
- 10.*)
- allow_undefined_flag_F77='${wl}-undefined ${wl}dynamic_lookup'
- ;;
- esac
- fi
- ;;
- esac
- archive_cmds_need_lc_F77=no
- hardcode_direct_F77=no
- hardcode_automatic_F77=yes
- hardcode_shlibpath_var_F77=unsupported
- whole_archive_flag_spec_F77=''
- link_all_deplibs_F77=yes
- if test "$GCC" = yes ; then
- output_verbose_link_cmd='echo'
- archive_cmds_F77="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
- module_cmds_F77="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
- archive_expsym_cmds_F77="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
- module_expsym_cmds_F77="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}"
- else
- case $cc_basename in
- xlc*)
- output_verbose_link_cmd='echo'
- archive_cmds_F77='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $xlcverstring'
- module_cmds_F77='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
- # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds
- archive_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $xlcverstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
- module_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
- ;;
- *)
- ld_shlibs_F77=no
- ;;
- esac
- fi
- ;;
-
- dgux*)
- archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- hardcode_libdir_flag_spec_F77='-L$libdir'
- hardcode_shlibpath_var_F77=no
- ;;
-
- freebsd1*)
- ld_shlibs_F77=no
- ;;
-
- # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
- # support. Future versions do this automatically, but an explicit c++rt0.o
- # does not break anything, and helps significantly (at the cost of a little
- # extra space).
- freebsd2.2*)
- archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
- hardcode_libdir_flag_spec_F77='-R$libdir'
- hardcode_direct_F77=yes
- hardcode_shlibpath_var_F77=no
- ;;
-
- # Unfortunately, older versions of FreeBSD 2 do not have this feature.
- freebsd2*)
- archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
- hardcode_direct_F77=yes
- hardcode_minus_L_F77=yes
- hardcode_shlibpath_var_F77=no
- ;;
-
- # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
- freebsd* | dragonfly*)
- archive_cmds_F77='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
- hardcode_libdir_flag_spec_F77='-R$libdir'
- hardcode_direct_F77=yes
- hardcode_shlibpath_var_F77=no
- ;;
-
- hpux9*)
- if test "$GCC" = yes; then
- archive_cmds_F77='$rm $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
- else
- archive_cmds_F77='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
- fi
- hardcode_libdir_flag_spec_F77='${wl}+b ${wl}$libdir'
- hardcode_libdir_separator_F77=:
- hardcode_direct_F77=yes
-
- # hardcode_minus_L: Not really in the search PATH,
- # but as the default location of the library.
- hardcode_minus_L_F77=yes
- export_dynamic_flag_spec_F77='${wl}-E'
- ;;
-
- hpux10*)
- if test "$GCC" = yes -a "$with_gnu_ld" = no; then
- archive_cmds_F77='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
- else
- archive_cmds_F77='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
- fi
- if test "$with_gnu_ld" = no; then
- hardcode_libdir_flag_spec_F77='${wl}+b ${wl}$libdir'
- hardcode_libdir_separator_F77=:
-
- hardcode_direct_F77=yes
- export_dynamic_flag_spec_F77='${wl}-E'
-
- # hardcode_minus_L: Not really in the search PATH,
- # but as the default location of the library.
- hardcode_minus_L_F77=yes
- fi
- ;;
-
- hpux11*)
- if test "$GCC" = yes -a "$with_gnu_ld" = no; then
- case $host_cpu in
- hppa*64*)
- archive_cmds_F77='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- ia64*)
- archive_cmds_F77='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- *)
- archive_cmds_F77='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- esac
- else
- case $host_cpu in
- hppa*64*)
- archive_cmds_F77='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- ia64*)
- archive_cmds_F77='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- *)
- archive_cmds_F77='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- esac
- fi
- if test "$with_gnu_ld" = no; then
- hardcode_libdir_flag_spec_F77='${wl}+b ${wl}$libdir'
- hardcode_libdir_separator_F77=:
-
- case $host_cpu in
- hppa*64*|ia64*)
- hardcode_libdir_flag_spec_ld_F77='+b $libdir'
- hardcode_direct_F77=no
- hardcode_shlibpath_var_F77=no
- ;;
- *)
- hardcode_direct_F77=yes
- export_dynamic_flag_spec_F77='${wl}-E'
-
- # hardcode_minus_L: Not really in the search PATH,
- # but as the default location of the library.
- hardcode_minus_L_F77=yes
- ;;
- esac
- fi
- ;;
-
- irix5* | irix6* | nonstopux*)
- if test "$GCC" = yes; then
- archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
- else
- archive_cmds_F77='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
- hardcode_libdir_flag_spec_ld_F77='-rpath $libdir'
- fi
- hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir'
- hardcode_libdir_separator_F77=:
- link_all_deplibs_F77=yes
- ;;
-
- netbsd*)
- if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
- archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out
- else
- archive_cmds_F77='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF
- fi
- hardcode_libdir_flag_spec_F77='-R$libdir'
- hardcode_direct_F77=yes
- hardcode_shlibpath_var_F77=no
- ;;
-
- newsos6)
- archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- hardcode_direct_F77=yes
- hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir'
- hardcode_libdir_separator_F77=:
- hardcode_shlibpath_var_F77=no
- ;;
-
- openbsd*)
- if test -f /usr/libexec/ld.so; then
- hardcode_direct_F77=yes
- hardcode_shlibpath_var_F77=no
- if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
- archive_cmds_F77='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
- archive_expsym_cmds_F77='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'
- hardcode_libdir_flag_spec_F77='${wl}-rpath,$libdir'
- export_dynamic_flag_spec_F77='${wl}-E'
- else
- case $host_os in
- openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
- archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
- hardcode_libdir_flag_spec_F77='-R$libdir'
- ;;
- *)
- archive_cmds_F77='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
- hardcode_libdir_flag_spec_F77='${wl}-rpath,$libdir'
- ;;
- esac
- fi
- else
- ld_shlibs_F77=no
- fi
- ;;
-
- os2*)
- hardcode_libdir_flag_spec_F77='-L$libdir'
- hardcode_minus_L_F77=yes
- allow_undefined_flag_F77=unsupported
- archive_cmds_F77='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
- old_archive_From_new_cmds_F77='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
- ;;
-
- osf3*)
- if test "$GCC" = yes; then
- allow_undefined_flag_F77=' ${wl}-expect_unresolved ${wl}\*'
- archive_cmds_F77='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
- else
- allow_undefined_flag_F77=' -expect_unresolved \*'
- archive_cmds_F77='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
- fi
- hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir'
- hardcode_libdir_separator_F77=:
- ;;
-
- osf4* | osf5*) # as osf3* with the addition of -msym flag
- if test "$GCC" = yes; then
- allow_undefined_flag_F77=' ${wl}-expect_unresolved ${wl}\*'
- archive_cmds_F77='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
- hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir'
- else
- allow_undefined_flag_F77=' -expect_unresolved \*'
- archive_cmds_F77='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
- archive_expsym_cmds_F77='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~
- $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~$rm $lib.exp'
-
- # Both c and cxx compiler support -rpath directly
- hardcode_libdir_flag_spec_F77='-rpath $libdir'
- fi
- hardcode_libdir_separator_F77=:
- ;;
-
- solaris*)
- no_undefined_flag_F77=' -z text'
- if test "$GCC" = yes; then
- wlarc='${wl}'
- archive_cmds_F77='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
- archive_expsym_cmds_F77='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
- $CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp'
- else
- wlarc=''
- archive_cmds_F77='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
- archive_expsym_cmds_F77='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
- $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp'
- fi
- hardcode_libdir_flag_spec_F77='-R$libdir'
- hardcode_shlibpath_var_F77=no
- case $host_os in
- solaris2.[0-5] | solaris2.[0-5].*) ;;
- *)
- # The compiler driver will combine and reorder linker options,
- # but understands `-z linker_flag'. GCC discards it without `$wl',
- # but is careful enough not to reorder.
- # Supported since Solaris 2.6 (maybe 2.5.1?)
- if test "$GCC" = yes; then
- whole_archive_flag_spec_F77='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
- else
- whole_archive_flag_spec_F77='-z allextract$convenience -z defaultextract'
- fi
- ;;
- esac
- link_all_deplibs_F77=yes
- ;;
-
- sunos4*)
- if test "x$host_vendor" = xsequent; then
- # Use $CC to link under sequent, because it throws in some extra .o
- # files that make .init and .fini sections work.
- archive_cmds_F77='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
- else
- archive_cmds_F77='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
- fi
- hardcode_libdir_flag_spec_F77='-L$libdir'
- hardcode_direct_F77=yes
- hardcode_minus_L_F77=yes
- hardcode_shlibpath_var_F77=no
- ;;
-
- sysv4)
- case $host_vendor in
- sni)
- archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- hardcode_direct_F77=yes # is this really true???
- ;;
- siemens)
- ## LD is ld it makes a PLAMLIB
- ## CC just makes a GrossModule.
- archive_cmds_F77='$LD -G -o $lib $libobjs $deplibs $linker_flags'
- reload_cmds_F77='$CC -r -o $output$reload_objs'
- hardcode_direct_F77=no
- ;;
- motorola)
- archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- hardcode_direct_F77=no #Motorola manual says yes, but my tests say they lie
- ;;
- esac
- runpath_var='LD_RUN_PATH'
- hardcode_shlibpath_var_F77=no
- ;;
-
- sysv4.3*)
- archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- hardcode_shlibpath_var_F77=no
- export_dynamic_flag_spec_F77='-Bexport'
- ;;
-
- sysv4*MP*)
- if test -d /usr/nec; then
- archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- hardcode_shlibpath_var_F77=no
- runpath_var=LD_RUN_PATH
- hardcode_runpath_var=yes
- ld_shlibs_F77=yes
- fi
- ;;
-
- sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
- no_undefined_flag_F77='${wl}-z,text'
- archive_cmds_need_lc_F77=no
- hardcode_shlibpath_var_F77=no
- runpath_var='LD_RUN_PATH'
-
- if test "$GCC" = yes; then
- archive_cmds_F77='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- archive_expsym_cmds_F77='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- else
- archive_cmds_F77='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- archive_expsym_cmds_F77='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- fi
- ;;
-
- sysv5* | sco3.2v5* | sco5v6*)
- # Note: We can NOT use -z defs as we might desire, because we do not
- # link with -lc, and that would cause any symbols used from libc to
- # always be unresolved, which means just about no library would
- # ever link correctly. If we're not using GNU ld we use -z text
- # though, which does catch some bad symbols but isn't as heavy-handed
- # as -z defs.
- no_undefined_flag_F77='${wl}-z,text'
- allow_undefined_flag_F77='${wl}-z,nodefs'
- archive_cmds_need_lc_F77=no
- hardcode_shlibpath_var_F77=no
- hardcode_libdir_flag_spec_F77='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`'
- hardcode_libdir_separator_F77=':'
- link_all_deplibs_F77=yes
- export_dynamic_flag_spec_F77='${wl}-Bexport'
- runpath_var='LD_RUN_PATH'
-
- if test "$GCC" = yes; then
- archive_cmds_F77='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
- archive_expsym_cmds_F77='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
- else
- archive_cmds_F77='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
- archive_expsym_cmds_F77='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
- fi
- ;;
-
- uts4*)
- archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- hardcode_libdir_flag_spec_F77='-L$libdir'
- hardcode_shlibpath_var_F77=no
- ;;
-
- *)
- ld_shlibs_F77=no
- ;;
- esac
- fi
-
-{ echo "$as_me:$LINENO: result: $ld_shlibs_F77" >&5
-echo "${ECHO_T}$ld_shlibs_F77" >&6; }
-test "$ld_shlibs_F77" = no && can_build_shared=no
-
-#
-# Do we need to explicitly link libc?
-#
-case "x$archive_cmds_need_lc_F77" in
-x|xyes)
- # Assume -lc should be added
- archive_cmds_need_lc_F77=yes
-
- if test "$enable_shared" = yes && test "$GCC" = yes; then
- case $archive_cmds_F77 in
- *'~'*)
- # FIXME: we may have to deal with multi-command sequences.
- ;;
- '$CC '*)
- # 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.
- { echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5
-echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6; }
- $rm conftest*
- echo "$lt_simple_compile_test_code" > conftest.$ac_ext
-
- if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } 2>conftest.err; then
- soname=conftest
- lib=conftest
- libobjs=conftest.$ac_objext
- deplibs=
- wl=$lt_prog_compiler_wl_F77
- pic_flag=$lt_prog_compiler_pic_F77
- compiler_flags=-v
- linker_flags=-v
- verstring=
- output_objdir=.
- libname=conftest
- lt_save_allow_undefined_flag=$allow_undefined_flag_F77
- allow_undefined_flag_F77=
- if { (eval echo "$as_me:$LINENO: \"$archive_cmds_F77 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1\"") >&5
- (eval $archive_cmds_F77 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }
- then
- archive_cmds_need_lc_F77=no
- else
- archive_cmds_need_lc_F77=yes
- fi
- allow_undefined_flag_F77=$lt_save_allow_undefined_flag
- else
- cat conftest.err 1>&5
- fi
- $rm conftest*
- { echo "$as_me:$LINENO: result: $archive_cmds_need_lc_F77" >&5
-echo "${ECHO_T}$archive_cmds_need_lc_F77" >&6; }
- ;;
- esac
- fi
- ;;
-esac
-
-{ echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5
-echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6; }
-library_names_spec=
-libname_spec='lib$name'
-soname_spec=
-shrext_cmds=".so"
-postinstall_cmds=
-postuninstall_cmds=
-finish_cmds=
-finish_eval=
-shlibpath_var=
-shlibpath_overrides_runpath=unknown
-version_type=none
-dynamic_linker="$host_os ld.so"
-sys_lib_dlsearch_path_spec="/lib /usr/lib"
-
-need_lib_prefix=unknown
-hardcode_into_libs=no
-
-# when you set need_version to no, make sure it does not cause -set_version
-# flags to be left without arguments
-need_version=unknown
-
-case $host_os in
-aix3*)
- version_type=linux
- library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
- shlibpath_var=LIBPATH
-
- # AIX 3 has no versioning support, so we append a major version to the name.
- soname_spec='${libname}${release}${shared_ext}$major'
- ;;
-
-aix[4-9]*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- hardcode_into_libs=yes
- if test "$host_cpu" = ia64; then
- # AIX 5 supports IA64
- library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
- shlibpath_var=LD_LIBRARY_PATH
- else
- # With GCC up to 2.95.x, collect2 would create an import file
- # for dependence libraries. The import file would start with
- # the line `#! .'. This would cause the generated library to
- # depend on `.', always an invalid library. This was fixed in
- # development snapshots of GCC prior to 3.0.
- case $host_os in
- aix4 | aix4.[01] | aix4.[01].*)
- if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
- echo ' yes '
- echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then
- :
- else
- can_build_shared=no
- fi
- ;;
- esac
- # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
- # soname into executable. Probably we can add versioning support to
- # collect2, so additional links can be useful in future.
- if test "$aix_use_runtimelinking" = yes; then
- # If using run time linking (on AIX 4.2 or later) use lib<name>.so
- # instead of lib<name>.a to let people know that these are not
- # typical AIX shared libraries.
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- else
- # We preserve .a as extension for shared libraries through AIX4.2
- # and later when we are not doing run time linking.
- library_names_spec='${libname}${release}.a $libname.a'
- soname_spec='${libname}${release}${shared_ext}$major'
- fi
- shlibpath_var=LIBPATH
- fi
- ;;
-
-amigaos*)
- library_names_spec='$libname.ixlibrary $libname.a'
- # Create ${libname}_ixlibrary.a entries in /sys/libs.
- finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
- ;;
-
-beos*)
- library_names_spec='${libname}${shared_ext}'
- dynamic_linker="$host_os ld.so"
- shlibpath_var=LIBRARY_PATH
- ;;
-
-bsdi[45]*)
- version_type=linux
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
- shlibpath_var=LD_LIBRARY_PATH
- sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
- sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
- # the default ld.so.conf also contains /usr/contrib/lib and
- # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
- # libtool to hard-code these into programs
- ;;
-
-cygwin* | mingw* | pw32*)
- version_type=windows
- shrext_cmds=".dll"
- need_version=no
- need_lib_prefix=no
-
- case $GCC,$host_os in
- yes,cygwin* | yes,mingw* | yes,pw32*)
- library_names_spec='$libname.dll.a'
- # DLL is installed to $(libdir)/../bin by postinstall_cmds
- postinstall_cmds='base_file=`basename \${file}`~
- dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~
- dldir=$destdir/`dirname \$dlpath`~
- test -d \$dldir || mkdir -p \$dldir~
- $install_prog $dir/$dlname \$dldir/$dlname~
- chmod a+x \$dldir/$dlname'
- postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
- dlpath=$dir/\$dldll~
- $rm \$dlpath'
- shlibpath_overrides_runpath=yes
-
- case $host_os in
- cygwin*)
- # Cygwin DLLs use 'cyg' prefix rather than 'lib'
- soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
- sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib"
- ;;
- mingw*)
- # MinGW DLLs use traditional 'lib' prefix
- soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
- sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
- if echo "$sys_lib_search_path_spec" | grep ';[c-zC-Z]:/' >/dev/null; then
- # It is most probably a Windows format PATH printed by
- # mingw gcc, but we are running on Cygwin. Gcc prints its search
- # path with ; separators, and with drive letters. We can handle the
- # drive letters (cygwin fileutils understands them), so leave them,
- # especially as we might pass files found there to a mingw objdump,
- # which wouldn't understand a cygwinified path. Ahh.
- sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
- else
- sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
- fi
- ;;
- pw32*)
- # pw32 DLLs use 'pw' prefix rather than 'lib'
- library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
- ;;
- esac
- ;;
-
- *)
- library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'
- ;;
- esac
- dynamic_linker='Win32 ld.exe'
- # FIXME: first we should search . and the directory the executable is in
- shlibpath_var=PATH
- ;;
-
-darwin* | rhapsody*)
- dynamic_linker="$host_os dyld"
- version_type=darwin
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext'
- soname_spec='${libname}${release}${major}$shared_ext'
- shlibpath_overrides_runpath=yes
- shlibpath_var=DYLD_LIBRARY_PATH
- shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
-
- sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
- ;;
-
-dgux*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- ;;
-
-freebsd1*)
- dynamic_linker=no
- ;;
-
-freebsd* | dragonfly*)
- # DragonFly does not have aout. When/if they implement a new
- # versioning mechanism, adjust this.
- if test -x /usr/bin/objformat; then
- objformat=`/usr/bin/objformat`
- else
- case $host_os in
- freebsd[123]*) objformat=aout ;;
- *) objformat=elf ;;
- esac
- fi
- # Handle Gentoo/FreeBSD as it was Linux
- case $host_vendor in
- gentoo)
- version_type=linux ;;
- *)
- version_type=freebsd-$objformat ;;
- esac
-
- case $version_type in
- freebsd-elf*)
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
- need_version=no
- need_lib_prefix=no
- ;;
- freebsd-*)
- library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
- need_version=yes
- ;;
- linux)
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- need_lib_prefix=no
- need_version=no
- ;;
- esac
- shlibpath_var=LD_LIBRARY_PATH
- case $host_os in
- freebsd2*)
- shlibpath_overrides_runpath=yes
- ;;
- freebsd3.[01]* | freebsdelf3.[01]*)
- shlibpath_overrides_runpath=yes
- hardcode_into_libs=yes
- ;;
- freebsd3.[2-9]* | freebsdelf3.[2-9]* | \
- freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1)
- shlibpath_overrides_runpath=no
- hardcode_into_libs=yes
- ;;
- *) # from 4.6 on, and DragonFly
- shlibpath_overrides_runpath=yes
- hardcode_into_libs=yes
- ;;
- esac
- ;;
-
-gnu*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- hardcode_into_libs=yes
- ;;
-
-hpux9* | hpux10* | hpux11*)
- # Give a soname corresponding to the major version so that dld.sl refuses to
- # link against other versions.
- version_type=sunos
- need_lib_prefix=no
- need_version=no
- case $host_cpu in
- ia64*)
- shrext_cmds='.so'
- hardcode_into_libs=yes
- dynamic_linker="$host_os dld.so"
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- if test "X$HPUX_IA64_MODE" = X32; then
- sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
- else
- sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
- fi
- sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
- ;;
- hppa*64*)
- shrext_cmds='.sl'
- hardcode_into_libs=yes
- dynamic_linker="$host_os dld.sl"
- shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
- shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
- sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
- ;;
- *)
- shrext_cmds='.sl'
- dynamic_linker="$host_os dld.sl"
- shlibpath_var=SHLIB_PATH
- shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- ;;
- esac
- # HP-UX runs *really* slowly unless shared libraries are mode 555.
- postinstall_cmds='chmod 555 $lib'
- ;;
-
-interix[3-9]*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=no
- hardcode_into_libs=yes
- ;;
-
-irix5* | irix6* | nonstopux*)
- case $host_os in
- nonstopux*) version_type=nonstopux ;;
- *)
- if test "$lt_cv_prog_gnu_ld" = yes; then
- version_type=linux
- else
- version_type=irix
- fi ;;
- esac
- need_lib_prefix=no
- need_version=no
- soname_spec='${libname}${release}${shared_ext}$major'
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
- case $host_os in
- irix5* | nonstopux*)
- libsuff= shlibsuff=
- ;;
- *)
- case $LD in # libtool.m4 will add one of these switches to LD
- *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
- libsuff= shlibsuff= libmagic=32-bit;;
- *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
- libsuff=32 shlibsuff=N32 libmagic=N32;;
- *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
- libsuff=64 shlibsuff=64 libmagic=64-bit;;
- *) libsuff= shlibsuff= libmagic=never-match;;
- esac
- ;;
- esac
- shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
- shlibpath_overrides_runpath=no
- sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
- sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
- hardcode_into_libs=yes
- ;;
-
-# No shared lib support for Linux oldld, aout, or coff.
-linux*oldld* | linux*aout* | linux*coff*)
- dynamic_linker=no
- ;;
-
-# This must be Linux ELF.
-linux* | k*bsd*-gnu)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=no
- # This implies no fast_install, which is unacceptable.
- # Some rework will be needed to allow for fast_install
- # before this can be enabled.
- hardcode_into_libs=yes
-
- # Append ld.so.conf contents to the search path
- if test -f /etc/ld.so.conf; then
- lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '`
- sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
- fi
-
- # We used to test for /lib/ld.so.1 and disable shared libraries on
- # powerpc, because MkLinux only supported shared libraries with the
- # GNU dynamic linker. Since this was broken with cross compilers,
- # most powerpc-linux boxes support dynamic linking these days and
- # people can always --disable-shared, the test was removed, and we
- # assume the GNU/Linux dynamic linker is in use.
- dynamic_linker='GNU/Linux ld.so'
- ;;
-
-netbsd*)
- version_type=sunos
- need_lib_prefix=no
- need_version=no
- if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
- finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
- dynamic_linker='NetBSD (a.out) ld.so'
- else
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- dynamic_linker='NetBSD ld.elf_so'
- fi
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes
- hardcode_into_libs=yes
- ;;
-
-newsos6)
- version_type=linux
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes
- ;;
-
-nto-qnx*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes
- ;;
-
-openbsd*)
- version_type=sunos
- sys_lib_dlsearch_path_spec="/usr/lib"
- need_lib_prefix=no
- # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
- case $host_os in
- openbsd3.3 | openbsd3.3.*) need_version=yes ;;
- *) need_version=no ;;
- esac
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
- finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
- shlibpath_var=LD_LIBRARY_PATH
- if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
- case $host_os in
- openbsd2.[89] | openbsd2.[89].*)
- shlibpath_overrides_runpath=no
- ;;
- *)
- shlibpath_overrides_runpath=yes
- ;;
- esac
- else
- shlibpath_overrides_runpath=yes
- fi
- ;;
-
-os2*)
- libname_spec='$name'
- shrext_cmds=".dll"
- need_lib_prefix=no
- library_names_spec='$libname${shared_ext} $libname.a'
- dynamic_linker='OS/2 ld.exe'
- shlibpath_var=LIBPATH
- ;;
-
-osf3* | osf4* | osf5*)
- version_type=osf
- need_lib_prefix=no
- need_version=no
- soname_spec='${libname}${release}${shared_ext}$major'
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- shlibpath_var=LD_LIBRARY_PATH
- sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
- sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
- ;;
-
-rdos*)
- dynamic_linker=no
- ;;
-
-solaris*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes
- hardcode_into_libs=yes
- # ldd complains unless libraries are executable
- postinstall_cmds='chmod +x $lib'
- ;;
-
-sunos4*)
- version_type=sunos
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
- finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes
- if test "$with_gnu_ld" = yes; then
- need_lib_prefix=no
- fi
- need_version=yes
- ;;
-
-sysv4 | sysv4.3*)
- version_type=linux
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- case $host_vendor in
- sni)
- shlibpath_overrides_runpath=no
- need_lib_prefix=no
- export_dynamic_flag_spec='${wl}-Blargedynsym'
- runpath_var=LD_RUN_PATH
- ;;
- siemens)
- need_lib_prefix=no
- ;;
- motorola)
- need_lib_prefix=no
- need_version=no
- shlibpath_overrides_runpath=no
- sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
- ;;
- esac
- ;;
-
-sysv4*MP*)
- if test -d /usr/nec ;then
- version_type=linux
- library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
- soname_spec='$libname${shared_ext}.$major'
- shlibpath_var=LD_LIBRARY_PATH
- fi
- ;;
-
-sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
- version_type=freebsd-elf
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- hardcode_into_libs=yes
- if test "$with_gnu_ld" = yes; then
- sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
- shlibpath_overrides_runpath=no
- else
- sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
- shlibpath_overrides_runpath=yes
- case $host_os in
- sco3.2v5*)
- sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
- ;;
- esac
- fi
- sys_lib_dlsearch_path_spec='/usr/lib'
- ;;
-
-uts4*)
- version_type=linux
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- ;;
-
-*)
- dynamic_linker=no
- ;;
-esac
-{ echo "$as_me:$LINENO: result: $dynamic_linker" >&5
-echo "${ECHO_T}$dynamic_linker" >&6; }
-test "$dynamic_linker" = no && can_build_shared=no
-
-if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- lt_cv_sys_lib_search_path_spec="$sys_lib_search_path_spec"
-fi
-
-sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec"
-if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- lt_cv_sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec"
-fi
-
-sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec"
-
-variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
-if test "$GCC" = yes; then
- variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
-fi
-
-{ echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5
-echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6; }
-hardcode_action_F77=
-if test -n "$hardcode_libdir_flag_spec_F77" || \
- test -n "$runpath_var_F77" || \
- test "X$hardcode_automatic_F77" = "Xyes" ; then
-
- # We can hardcode non-existant directories.
- if test "$hardcode_direct_F77" != no &&
- # If the only mechanism to avoid hardcoding is shlibpath_var, we
- # have to relink, otherwise we might link with an installed library
- # when we should be linking with a yet-to-be-installed one
- ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, F77)" != no &&
- test "$hardcode_minus_L_F77" != no; then
- # Linking always hardcodes the temporary library directory.
- hardcode_action_F77=relink
- else
- # We can link without hardcoding, and we can hardcode nonexisting dirs.
- hardcode_action_F77=immediate
- fi
-else
- # We cannot hardcode anything, or else we can only hardcode existing
- # directories.
- hardcode_action_F77=unsupported
-fi
-{ echo "$as_me:$LINENO: result: $hardcode_action_F77" >&5
-echo "${ECHO_T}$hardcode_action_F77" >&6; }
-
-if test "$hardcode_action_F77" = relink; then
- # Fast installation is not supported
- enable_fast_install=no
-elif test "$shlibpath_overrides_runpath" = yes ||
- test "$enable_shared" = no; then
- # Fast installation is not necessary
- enable_fast_install=needless
-fi
-
-
-# The else clause should only fire when bootstrapping the
-# libtool distribution, otherwise you forgot to ship ltmain.sh
-# with your package, and you will get complaints that there are
-# no rules to generate ltmain.sh.
-if test -f "$ltmain"; then
- # See if we are running on zsh, and set the options which allow our commands through
- # without removal of \ escapes.
- if test -n "${ZSH_VERSION+set}" ; then
- setopt NO_GLOB_SUBST
- fi
- # Now quote all the things that may contain metacharacters while being
- # careful not to overquote the AC_SUBSTed values. We take copies of the
- # variables and quote the copies for generation of the libtool script.
- for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \
- SED SHELL STRIP \
- libname_spec library_names_spec soname_spec extract_expsyms_cmds \
- old_striplib striplib file_magic_cmd finish_cmds finish_eval \
- deplibs_check_method reload_flag reload_cmds need_locks \
- lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \
- lt_cv_sys_global_symbol_to_c_name_address \
- sys_lib_search_path_spec sys_lib_dlsearch_path_spec \
- old_postinstall_cmds old_postuninstall_cmds \
- compiler_F77 \
- CC_F77 \
- LD_F77 \
- lt_prog_compiler_wl_F77 \
- lt_prog_compiler_pic_F77 \
- lt_prog_compiler_static_F77 \
- lt_prog_compiler_no_builtin_flag_F77 \
- export_dynamic_flag_spec_F77 \
- thread_safe_flag_spec_F77 \
- whole_archive_flag_spec_F77 \
- enable_shared_with_static_runtimes_F77 \
- old_archive_cmds_F77 \
- old_archive_from_new_cmds_F77 \
- predep_objects_F77 \
- postdep_objects_F77 \
- predeps_F77 \
- postdeps_F77 \
- compiler_lib_search_path_F77 \
- compiler_lib_search_dirs_F77 \
- archive_cmds_F77 \
- archive_expsym_cmds_F77 \
- postinstall_cmds_F77 \
- postuninstall_cmds_F77 \
- old_archive_from_expsyms_cmds_F77 \
- allow_undefined_flag_F77 \
- no_undefined_flag_F77 \
- export_symbols_cmds_F77 \
- hardcode_libdir_flag_spec_F77 \
- hardcode_libdir_flag_spec_ld_F77 \
- hardcode_libdir_separator_F77 \
- hardcode_automatic_F77 \
- module_cmds_F77 \
- module_expsym_cmds_F77 \
- lt_cv_prog_compiler_c_o_F77 \
- fix_srcfile_path_F77 \
- exclude_expsyms_F77 \
- include_expsyms_F77; do
-
- case $var in
- old_archive_cmds_F77 | \
- old_archive_from_new_cmds_F77 | \
- archive_cmds_F77 | \
- archive_expsym_cmds_F77 | \
- module_cmds_F77 | \
- module_expsym_cmds_F77 | \
- old_archive_from_expsyms_cmds_F77 | \
- export_symbols_cmds_F77 | \
- extract_expsyms_cmds | reload_cmds | finish_cmds | \
- postinstall_cmds | postuninstall_cmds | \
- old_postinstall_cmds | old_postuninstall_cmds | \
- sys_lib_search_path_spec | sys_lib_dlsearch_path_spec)
- # Double-quote double-evaled strings.
- eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\""
- ;;
- *)
- eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\""
- ;;
- esac
- done
-
- case $lt_echo in
- *'\$0 --fallback-echo"')
- lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'`
- ;;
- esac
-
-cfgfile="$ofile"
-
- cat <<__EOF__ >> "$cfgfile"
-# ### BEGIN LIBTOOL TAG CONFIG: $tagname
-
-# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
-
-# Shell to use when invoking shell scripts.
-SHELL=$lt_SHELL
-
-# Whether or not to build shared libraries.
-build_libtool_libs=$enable_shared
-
-# Whether or not to build static libraries.
-build_old_libs=$enable_static
-
-# Whether or not to add -lc for building shared libraries.
-build_libtool_need_lc=$archive_cmds_need_lc_F77
-
-# Whether or not to disallow shared libs when runtime libs are static
-allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_F77
-
-# Whether or not to optimize for fast installation.
-fast_install=$enable_fast_install
-
-# The host system.
-host_alias=$host_alias
-host=$host
-host_os=$host_os
-
-# The build system.
-build_alias=$build_alias
-build=$build
-build_os=$build_os
-
-# An echo program that does not interpret backslashes.
-echo=$lt_echo
-
-# The archiver.
-AR=$lt_AR
-AR_FLAGS=$lt_AR_FLAGS
-
-# A C compiler.
-LTCC=$lt_LTCC
-
-# LTCC compiler flags.
-LTCFLAGS=$lt_LTCFLAGS
-
-# A language-specific compiler.
-CC=$lt_compiler_F77
-
-# Is the compiler the GNU C compiler?
-with_gcc=$GCC_F77
-
-# An ERE matcher.
-EGREP=$lt_EGREP
-
-# The linker used to build libraries.
-LD=$lt_LD_F77
-
-# Whether we need hard or soft links.
-LN_S=$lt_LN_S
-
-# A BSD-compatible nm program.
-NM=$lt_NM
-
-# A symbol stripping program
-STRIP=$lt_STRIP
-
-# Used to examine libraries when file_magic_cmd begins "file"
-MAGIC_CMD=$MAGIC_CMD
-
-# Used on cygwin: DLL creation program.
-DLLTOOL="$DLLTOOL"
-
-# Used on cygwin: object dumper.
-OBJDUMP="$OBJDUMP"
-
-# Used on cygwin: assembler.
-AS="$AS"
-
-# The name of the directory that contains temporary libtool files.
-objdir=$objdir
-
-# How to create reloadable object files.
-reload_flag=$lt_reload_flag
-reload_cmds=$lt_reload_cmds
-
-# How to pass a linker flag through the compiler.
-wl=$lt_lt_prog_compiler_wl_F77
-
-# Object file suffix (normally "o").
-objext="$ac_objext"
-
-# Old archive suffix (normally "a").
-libext="$libext"
-
-# Shared library suffix (normally ".so").
-shrext_cmds='$shrext_cmds'
-
-# Executable file suffix (normally "").
-exeext="$exeext"
-
-# Additional compiler flags for building library objects.
-pic_flag=$lt_lt_prog_compiler_pic_F77
-pic_mode=$pic_mode
-
-# What is the maximum length of a command?
-max_cmd_len=$lt_cv_sys_max_cmd_len
-
-# Does compiler simultaneously support -c and -o options?
-compiler_c_o=$lt_lt_cv_prog_compiler_c_o_F77
-
-# Must we lock files when doing compilation?
-need_locks=$lt_need_locks
-
-# Do we need the lib prefix for modules?
-need_lib_prefix=$need_lib_prefix
-
-# Do we need a version for libraries?
-need_version=$need_version
-
-# Whether dlopen is supported.
-dlopen_support=$enable_dlopen
-
-# Whether dlopen of programs is supported.
-dlopen_self=$enable_dlopen_self
-
-# Whether dlopen of statically linked programs is supported.
-dlopen_self_static=$enable_dlopen_self_static
-
-# Compiler flag to prevent dynamic linking.
-link_static_flag=$lt_lt_prog_compiler_static_F77
-
-# Compiler flag to turn off builtin functions.
-no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_F77
-
-# Compiler flag to allow reflexive dlopens.
-export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_F77
-
-# Compiler flag to generate shared objects directly from archives.
-whole_archive_flag_spec=$lt_whole_archive_flag_spec_F77
-
-# Compiler flag to generate thread-safe objects.
-thread_safe_flag_spec=$lt_thread_safe_flag_spec_F77
-
-# Library versioning type.
-version_type=$version_type
-
-# Format of library name prefix.
-libname_spec=$lt_libname_spec
-
-# List of archive names. First name is the real one, the rest are links.
-# The last name is the one that the linker finds with -lNAME.
-library_names_spec=$lt_library_names_spec
-
-# The coded name of the library, if different from the real name.
-soname_spec=$lt_soname_spec
-
-# Commands used to build and install an old-style archive.
-RANLIB=$lt_RANLIB
-old_archive_cmds=$lt_old_archive_cmds_F77
-old_postinstall_cmds=$lt_old_postinstall_cmds
-old_postuninstall_cmds=$lt_old_postuninstall_cmds
-
-# Create an old-style archive from a shared archive.
-old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_F77
-
-# Create a temporary old-style archive to link instead of a shared archive.
-old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_F77
-
-# Commands used to build and install a shared archive.
-archive_cmds=$lt_archive_cmds_F77
-archive_expsym_cmds=$lt_archive_expsym_cmds_F77
-postinstall_cmds=$lt_postinstall_cmds
-postuninstall_cmds=$lt_postuninstall_cmds
-
-# Commands used to build a loadable module (assumed same as above if empty)
-module_cmds=$lt_module_cmds_F77
-module_expsym_cmds=$lt_module_expsym_cmds_F77
-
-# Commands to strip libraries.
-old_striplib=$lt_old_striplib
-striplib=$lt_striplib
-
-# Dependencies to place before the objects being linked to create a
-# shared library.
-predep_objects=$lt_predep_objects_F77
-
-# Dependencies to place after the objects being linked to create a
-# shared library.
-postdep_objects=$lt_postdep_objects_F77
-
-# Dependencies to place before the objects being linked to create a
-# shared library.
-predeps=$lt_predeps_F77
-
-# Dependencies to place after the objects being linked to create a
-# shared library.
-postdeps=$lt_postdeps_F77
-
-# The directories searched by this compiler when creating a shared
-# library
-compiler_lib_search_dirs=$lt_compiler_lib_search_dirs_F77
-
-# The library search path used internally by the compiler when linking
-# a shared library.
-compiler_lib_search_path=$lt_compiler_lib_search_path_F77
-
-# Method to check whether dependent libraries are shared objects.
-deplibs_check_method=$lt_deplibs_check_method
-
-# Command to use when deplibs_check_method == file_magic.
-file_magic_cmd=$lt_file_magic_cmd
-
-# Flag that allows shared libraries with undefined symbols to be built.
-allow_undefined_flag=$lt_allow_undefined_flag_F77
-
-# Flag that forces no undefined symbols.
-no_undefined_flag=$lt_no_undefined_flag_F77
-
-# Commands used to finish a libtool library installation in a directory.
-finish_cmds=$lt_finish_cmds
-
-# Same as above, but a single script fragment to be evaled but not shown.
-finish_eval=$lt_finish_eval
-
-# Take the output of nm and produce a listing of raw symbols and C names.
-global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe
-
-# Transform the output of nm in a proper C declaration
-global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl
-
-# Transform the output of nm in a C name address pair
-global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address
-
-# This is the shared library runtime path variable.
-runpath_var=$runpath_var
-
-# This is the shared library path variable.
-shlibpath_var=$shlibpath_var
-
-# Is shlibpath searched before the hard-coded library search path?
-shlibpath_overrides_runpath=$shlibpath_overrides_runpath
-
-# How to hardcode a shared library path into an executable.
-hardcode_action=$hardcode_action_F77
-
-# Whether we should hardcode library paths into libraries.
-hardcode_into_libs=$hardcode_into_libs
-
-# Flag to hardcode \$libdir into a binary during linking.
-# This must work even if \$libdir does not exist.
-hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_F77
-
-# If ld is used when linking, flag to hardcode \$libdir into
-# a binary during linking. This must work even if \$libdir does
-# not exist.
-hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_F77
-
-# Whether we need a single -rpath flag with a separated argument.
-hardcode_libdir_separator=$lt_hardcode_libdir_separator_F77
-
-# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the
-# resulting binary.
-hardcode_direct=$hardcode_direct_F77
-
-# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
-# resulting binary.
-hardcode_minus_L=$hardcode_minus_L_F77
-
-# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into
-# the resulting binary.
-hardcode_shlibpath_var=$hardcode_shlibpath_var_F77
-
-# Set to yes if building a shared library automatically hardcodes DIR into the library
-# and all subsequent libraries and executables linked against it.
-hardcode_automatic=$hardcode_automatic_F77
-
-# Variables whose values should be saved in libtool wrapper scripts and
-# restored at relink time.
-variables_saved_for_relink="$variables_saved_for_relink"
-
-# Whether libtool must link a program against all its dependency libraries.
-link_all_deplibs=$link_all_deplibs_F77
-
-# Compile-time system search path for libraries
-sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
-
-# Run-time system search path for libraries
-sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
-
-# Fix the shell variable \$srcfile for the compiler.
-fix_srcfile_path=$lt_fix_srcfile_path
-
-# Set to yes if exported symbols are required.
-always_export_symbols=$always_export_symbols_F77
-
-# The commands to list exported symbols.
-export_symbols_cmds=$lt_export_symbols_cmds_F77
-
-# The commands to extract the exported symbol list from a shared archive.
-extract_expsyms_cmds=$lt_extract_expsyms_cmds
-
-# Symbols that should not be listed in the preloaded symbols.
-exclude_expsyms=$lt_exclude_expsyms_F77
-
-# Symbols that must always be exported.
-include_expsyms=$lt_include_expsyms_F77
-
-# ### END LIBTOOL TAG CONFIG: $tagname
-
-__EOF__
-
-
-else
- # If there is no Makefile yet, we rely on a make rule to execute
- # `config.status --recheck' to rerun these tests and create the
- # libtool script then.
- ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'`
- if test -f "$ltmain_in"; then
- test -f Makefile && make "$ltmain"
- fi
-fi
-
-
-ac_ext=c
-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
-
-CC="$lt_save_CC"
-
- else
- tagname=""
- fi
- ;;
-
- GCJ)
- if test -n "$GCJ" && test "X$GCJ" != "Xno"; then
-
-
-# Source file extension for Java test sources.
-ac_ext=java
-
-# Object file extension for compiled Java test sources.
-objext=o
-objext_GCJ=$objext
-
-# Code to be used in simple compile tests
-lt_simple_compile_test_code="class foo {}"
-
-# Code to be used in simple link tests
-lt_simple_link_test_code='public class conftest { public static void main(String[] argv) {}; }'
-
-# ltmain only uses $CC for tagged configurations so make sure $CC is set.
-
-# If no C compiler was specified, use CC.
-LTCC=${LTCC-"$CC"}
-
-# If no C compiler flags were specified, use CFLAGS.
-LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
-
-# Allow CC to be a program name with arguments.
-compiler=$CC
-
-
-# save warnings/boilerplate of simple test code
-ac_outfile=conftest.$ac_objext
-echo "$lt_simple_compile_test_code" >conftest.$ac_ext
-eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
-_lt_compiler_boilerplate=`cat conftest.err`
-$rm conftest*
-
-ac_outfile=conftest.$ac_objext
-echo "$lt_simple_link_test_code" >conftest.$ac_ext
-eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
-_lt_linker_boilerplate=`cat conftest.err`
-$rm -r conftest*
-
-
-# Allow CC to be a program name with arguments.
-lt_save_CC="$CC"
-CC=${GCJ-"gcj"}
-compiler=$CC
-compiler_GCJ=$CC
-for cc_temp in $compiler""; do
- case $cc_temp in
- compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
- distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
- \-*) ;;
- *) break;;
- esac
-done
-cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"`
-
-
-# GCJ did not exist at the time GCC didn't implicitly link libc in.
-archive_cmds_need_lc_GCJ=no
-
-old_archive_cmds_GCJ=$old_archive_cmds
-
-
-lt_prog_compiler_no_builtin_flag_GCJ=
-
-if test "$GCC" = yes; then
- lt_prog_compiler_no_builtin_flag_GCJ=' -fno-builtin'
-
-
-{ echo "$as_me:$LINENO: checking if $compiler supports -fno-rtti -fno-exceptions" >&5
-echo $ECHO_N "checking if $compiler supports -fno-rtti -fno-exceptions... $ECHO_C" >&6; }
-if test "${lt_cv_prog_compiler_rtti_exceptions+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- lt_cv_prog_compiler_rtti_exceptions=no
- ac_outfile=conftest.$ac_objext
- echo "$lt_simple_compile_test_code" > conftest.$ac_ext
- lt_compiler_flag="-fno-rtti -fno-exceptions"
- # Insert the option either (1) after the last *FLAGS variable, or
- # (2) before a word containing "conftest.", or (3) at the end.
- # Note that $ac_compile itself does not contain backslashes and begins
- # with a dollar sign (not a hyphen), so the echo should work correctly.
- # The option is referenced via a variable to avoid confusing sed.
- lt_compile=`echo "$ac_compile" | $SED \
- -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:17240: $lt_compile\"" >&5)
- (eval "$lt_compile" 2>conftest.err)
- ac_status=$?
- cat conftest.err >&5
- echo "$as_me:17244: \$? = $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.
- $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp
- $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
- if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
- lt_cv_prog_compiler_rtti_exceptions=yes
- fi
- fi
- $rm conftest*
-
-fi
-{ echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_rtti_exceptions" >&5
-echo "${ECHO_T}$lt_cv_prog_compiler_rtti_exceptions" >&6; }
-
-if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then
- lt_prog_compiler_no_builtin_flag_GCJ="$lt_prog_compiler_no_builtin_flag_GCJ -fno-rtti -fno-exceptions"
-else
- :
-fi
-
-fi
-
-lt_prog_compiler_wl_GCJ=
-lt_prog_compiler_pic_GCJ=
-lt_prog_compiler_static_GCJ=
-
-{ echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5
-echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6; }
-
- if test "$GCC" = yes; then
- lt_prog_compiler_wl_GCJ='-Wl,'
- lt_prog_compiler_static_GCJ='-static'
-
- case $host_os in
- aix*)
- # All AIX code is PIC.
- if test "$host_cpu" = ia64; then
- # AIX 5 now supports IA64 processor
- lt_prog_compiler_static_GCJ='-Bstatic'
- fi
- ;;
-
- amigaos*)
- # FIXME: we need at least 68020 code to build shared libraries, but
- # adding the `-m68020' flag to GCC prevents building anything better,
- # like `-m68040'.
- lt_prog_compiler_pic_GCJ='-m68020 -resident32 -malways-restore-a4'
- ;;
-
- beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
- # PIC is the default for these OSes.
- ;;
-
- mingw* | cygwin* | pw32* | os2*)
- # This hack is so that the source file can tell whether it is being
- # built for inclusion in a dll (and should export symbols for example).
- # Although the cygwin gcc ignores -fPIC, still need this for old-style
- # (--disable-auto-import) libraries
-
- ;;
-
- darwin* | rhapsody*)
- # PIC is the default on this platform
- # Common symbols not allowed in MH_DYLIB files
- lt_prog_compiler_pic_GCJ='-fno-common'
- ;;
-
- interix[3-9]*)
- # Interix 3.x gcc -fpic/-fPIC options generate broken code.
- # Instead, we relocate shared libraries at runtime.
- ;;
-
- msdosdjgpp*)
- # Just because we use GCC doesn't mean we suddenly get shared libraries
- # on systems that don't support them.
- lt_prog_compiler_can_build_shared_GCJ=no
- enable_shared=no
- ;;
-
- sysv4*MP*)
- if test -d /usr/nec; then
- lt_prog_compiler_pic_GCJ=-Kconform_pic
- fi
- ;;
-
- hpux*)
- # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
- # not for PA HP-UX.
- case $host_cpu in
- hppa*64*|ia64*)
- # +Z the default
- ;;
- *)
- lt_prog_compiler_pic_GCJ='-fPIC'
- ;;
- esac
- ;;
-
- *)
- lt_prog_compiler_pic_GCJ='-fPIC'
- ;;
- esac
- else
- # PORTME Check for flag to pass linker flags through the system compiler.
- case $host_os in
- aix*)
- lt_prog_compiler_wl_GCJ='-Wl,'
- if test "$host_cpu" = ia64; then
- # AIX 5 now supports IA64 processor
- lt_prog_compiler_static_GCJ='-Bstatic'
- else
- lt_prog_compiler_static_GCJ='-bnso -bI:/lib/syscalls.exp'
- fi
- ;;
- darwin*)
- # PIC is the default on this platform
- # Common symbols not allowed in MH_DYLIB files
- case $cc_basename in
- xlc*)
- lt_prog_compiler_pic_GCJ='-qnocommon'
- lt_prog_compiler_wl_GCJ='-Wl,'
- ;;
- esac
- ;;
-
- mingw* | cygwin* | pw32* | os2*)
- # This hack is so that the source file can tell whether it is being
- # built for inclusion in a dll (and should export symbols for example).
-
- ;;
-
- hpux9* | hpux10* | hpux11*)
- lt_prog_compiler_wl_GCJ='-Wl,'
- # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
- # not for PA HP-UX.
- case $host_cpu in
- hppa*64*|ia64*)
- # +Z the default
- ;;
- *)
- lt_prog_compiler_pic_GCJ='+Z'
- ;;
- esac
- # Is there a better lt_prog_compiler_static that works with the bundled CC?
- lt_prog_compiler_static_GCJ='${wl}-a ${wl}archive'
- ;;
-
- irix5* | irix6* | nonstopux*)
- lt_prog_compiler_wl_GCJ='-Wl,'
- # PIC (with -KPIC) is the default.
- lt_prog_compiler_static_GCJ='-non_shared'
- ;;
-
- newsos6)
- lt_prog_compiler_pic_GCJ='-KPIC'
- lt_prog_compiler_static_GCJ='-Bstatic'
- ;;
-
- linux* | k*bsd*-gnu)
- case $cc_basename in
- icc* | ecc*)
- lt_prog_compiler_wl_GCJ='-Wl,'
- lt_prog_compiler_pic_GCJ='-KPIC'
- lt_prog_compiler_static_GCJ='-static'
- ;;
- pgcc* | pgf77* | pgf90* | pgf95*)
- # Portland Group compilers (*not* the Pentium gcc compiler,
- # which looks to be a dead project)
- lt_prog_compiler_wl_GCJ='-Wl,'
- lt_prog_compiler_pic_GCJ='-fpic'
- lt_prog_compiler_static_GCJ='-Bstatic'
- ;;
- ccc*)
- lt_prog_compiler_wl_GCJ='-Wl,'
- # All Alpha code is PIC.
- lt_prog_compiler_static_GCJ='-non_shared'
- ;;
- *)
- case `$CC -V 2>&1 | sed 5q` in
- *Sun\ C*)
- # Sun C 5.9
- lt_prog_compiler_pic_GCJ='-KPIC'
- lt_prog_compiler_static_GCJ='-Bstatic'
- lt_prog_compiler_wl_GCJ='-Wl,'
- ;;
- *Sun\ F*)
- # Sun Fortran 8.3 passes all unrecognized flags to the linker
- lt_prog_compiler_pic_GCJ='-KPIC'
- lt_prog_compiler_static_GCJ='-Bstatic'
- lt_prog_compiler_wl_GCJ=''
- ;;
- esac
- ;;
- esac
- ;;
-
- osf3* | osf4* | osf5*)
- lt_prog_compiler_wl_GCJ='-Wl,'
- # All OSF/1 code is PIC.
- lt_prog_compiler_static_GCJ='-non_shared'
- ;;
-
- rdos*)
- lt_prog_compiler_static_GCJ='-non_shared'
- ;;
-
- solaris*)
- lt_prog_compiler_pic_GCJ='-KPIC'
- lt_prog_compiler_static_GCJ='-Bstatic'
- case $cc_basename in
- f77* | f90* | f95*)
- lt_prog_compiler_wl_GCJ='-Qoption ld ';;
- *)
- lt_prog_compiler_wl_GCJ='-Wl,';;
- esac
- ;;
-
- sunos4*)
- lt_prog_compiler_wl_GCJ='-Qoption ld '
- lt_prog_compiler_pic_GCJ='-PIC'
- lt_prog_compiler_static_GCJ='-Bstatic'
- ;;
-
- sysv4 | sysv4.2uw2* | sysv4.3*)
- lt_prog_compiler_wl_GCJ='-Wl,'
- lt_prog_compiler_pic_GCJ='-KPIC'
- lt_prog_compiler_static_GCJ='-Bstatic'
- ;;
-
- sysv4*MP*)
- if test -d /usr/nec ;then
- lt_prog_compiler_pic_GCJ='-Kconform_pic'
- lt_prog_compiler_static_GCJ='-Bstatic'
- fi
- ;;
-
- sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
- lt_prog_compiler_wl_GCJ='-Wl,'
- lt_prog_compiler_pic_GCJ='-KPIC'
- lt_prog_compiler_static_GCJ='-Bstatic'
- ;;
-
- unicos*)
- lt_prog_compiler_wl_GCJ='-Wl,'
- lt_prog_compiler_can_build_shared_GCJ=no
- ;;
-
- uts4*)
- lt_prog_compiler_pic_GCJ='-pic'
- lt_prog_compiler_static_GCJ='-Bstatic'
- ;;
-
- *)
- lt_prog_compiler_can_build_shared_GCJ=no
- ;;
- esac
- fi
-
-{ echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_GCJ" >&5
-echo "${ECHO_T}$lt_prog_compiler_pic_GCJ" >&6; }
-
-#
-# Check to make sure the PIC flag actually works.
-#
-if test -n "$lt_prog_compiler_pic_GCJ"; then
-
-{ echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic_GCJ works" >&5
-echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic_GCJ works... $ECHO_C" >&6; }
-if test "${lt_cv_prog_compiler_pic_works_GCJ+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- lt_cv_prog_compiler_pic_works_GCJ=no
- ac_outfile=conftest.$ac_objext
- echo "$lt_simple_compile_test_code" > conftest.$ac_ext
- lt_compiler_flag="$lt_prog_compiler_pic_GCJ"
- # Insert the option either (1) after the last *FLAGS variable, or
- # (2) before a word containing "conftest.", or (3) at the end.
- # Note that $ac_compile itself does not contain backslashes and begins
- # with a dollar sign (not a hyphen), so the echo should work correctly.
- # The option is referenced via a variable to avoid confusing sed.
- lt_compile=`echo "$ac_compile" | $SED \
- -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:17530: $lt_compile\"" >&5)
- (eval "$lt_compile" 2>conftest.err)
- ac_status=$?
- cat conftest.err >&5
- echo "$as_me:17534: \$? = $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.
- $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp
- $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
- if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
- lt_cv_prog_compiler_pic_works_GCJ=yes
- fi
- fi
- $rm conftest*
-
-fi
-{ echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_pic_works_GCJ" >&5
-echo "${ECHO_T}$lt_cv_prog_compiler_pic_works_GCJ" >&6; }
-
-if test x"$lt_cv_prog_compiler_pic_works_GCJ" = xyes; then
- case $lt_prog_compiler_pic_GCJ in
- "" | " "*) ;;
- *) lt_prog_compiler_pic_GCJ=" $lt_prog_compiler_pic_GCJ" ;;
- esac
-else
- lt_prog_compiler_pic_GCJ=
- lt_prog_compiler_can_build_shared_GCJ=no
-fi
-
-fi
-case $host_os in
- # For platforms which do not support PIC, -DPIC is meaningless:
- *djgpp*)
- lt_prog_compiler_pic_GCJ=
- ;;
- *)
- lt_prog_compiler_pic_GCJ="$lt_prog_compiler_pic_GCJ"
- ;;
-esac
-
-#
-# Check to make sure the static flag actually works.
-#
-wl=$lt_prog_compiler_wl_GCJ eval lt_tmp_static_flag=\"$lt_prog_compiler_static_GCJ\"
-{ echo "$as_me:$LINENO: checking if $compiler static flag $lt_tmp_static_flag works" >&5
-echo $ECHO_N "checking if $compiler static flag $lt_tmp_static_flag works... $ECHO_C" >&6; }
-if test "${lt_cv_prog_compiler_static_works_GCJ+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- lt_cv_prog_compiler_static_works_GCJ=no
- save_LDFLAGS="$LDFLAGS"
- LDFLAGS="$LDFLAGS $lt_tmp_static_flag"
- echo "$lt_simple_link_test_code" > conftest.$ac_ext
- if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
- # The linker can only warn and ignore the option if not recognized
- # So say no if there are warnings
- if test -s conftest.err; then
- # Append any errors to the config.log.
- cat conftest.err 1>&5
- $echo "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp
- $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
- if diff conftest.exp conftest.er2 >/dev/null; then
- lt_cv_prog_compiler_static_works_GCJ=yes
- fi
- else
- lt_cv_prog_compiler_static_works_GCJ=yes
- fi
- fi
- $rm -r conftest*
- LDFLAGS="$save_LDFLAGS"
-
-fi
-{ echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_static_works_GCJ" >&5
-echo "${ECHO_T}$lt_cv_prog_compiler_static_works_GCJ" >&6; }
-
-if test x"$lt_cv_prog_compiler_static_works_GCJ" = xyes; then
- :
-else
- lt_prog_compiler_static_GCJ=
-fi
-
-
-{ echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5
-echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6; }
-if test "${lt_cv_prog_compiler_c_o_GCJ+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- lt_cv_prog_compiler_c_o_GCJ=no
- $rm -r conftest 2>/dev/null
- mkdir conftest
- cd conftest
- mkdir out
- echo "$lt_simple_compile_test_code" > conftest.$ac_ext
-
- lt_compiler_flag="-o out/conftest2.$ac_objext"
- # Insert the option either (1) after the last *FLAGS variable, or
- # (2) before a word containing "conftest.", or (3) at the end.
- # Note that $ac_compile itself does not contain backslashes and begins
- # with a dollar sign (not a hyphen), so the echo should work correctly.
- lt_compile=`echo "$ac_compile" | $SED \
- -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:17634: $lt_compile\"" >&5)
- (eval "$lt_compile" 2>out/conftest.err)
- ac_status=$?
- cat out/conftest.err >&5
- echo "$as_me:17638: \$? = $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
- # So say no if there are warnings
- $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp
- $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
- if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
- lt_cv_prog_compiler_c_o_GCJ=yes
- fi
- fi
- chmod u+w . 2>&5
- $rm conftest*
- # SGI C++ compiler will create directory out/ii_files/ for
- # template instantiation
- test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files
- $rm out/* && rmdir out
- cd ..
- rmdir conftest
- $rm conftest*
-
-fi
-{ echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o_GCJ" >&5
-echo "${ECHO_T}$lt_cv_prog_compiler_c_o_GCJ" >&6; }
-
-
-hard_links="nottested"
-if test "$lt_cv_prog_compiler_c_o_GCJ" = no && test "$need_locks" != no; then
- # do not overwrite the value of need_locks provided by the user
- { echo "$as_me:$LINENO: checking if we can lock with hard links" >&5
-echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6; }
- hard_links=yes
- $rm conftest*
- ln conftest.a conftest.b 2>/dev/null && hard_links=no
- touch conftest.a
- ln conftest.a conftest.b 2>&5 || hard_links=no
- ln conftest.a conftest.b 2>/dev/null && hard_links=no
- { echo "$as_me:$LINENO: result: $hard_links" >&5
-echo "${ECHO_T}$hard_links" >&6; }
- if test "$hard_links" = no; then
- { echo "$as_me:$LINENO: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5
-echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;}
- need_locks=warn
- fi
-else
- need_locks=no
-fi
-
-{ echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5
-echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6; }
-
- runpath_var=
- allow_undefined_flag_GCJ=
- enable_shared_with_static_runtimes_GCJ=no
- archive_cmds_GCJ=
- archive_expsym_cmds_GCJ=
- old_archive_From_new_cmds_GCJ=
- old_archive_from_expsyms_cmds_GCJ=
- export_dynamic_flag_spec_GCJ=
- whole_archive_flag_spec_GCJ=
- thread_safe_flag_spec_GCJ=
- hardcode_libdir_flag_spec_GCJ=
- hardcode_libdir_flag_spec_ld_GCJ=
- hardcode_libdir_separator_GCJ=
- hardcode_direct_GCJ=no
- hardcode_minus_L_GCJ=no
- hardcode_shlibpath_var_GCJ=unsupported
- link_all_deplibs_GCJ=unknown
- hardcode_automatic_GCJ=no
- module_cmds_GCJ=
- module_expsym_cmds_GCJ=
- always_export_symbols_GCJ=no
- export_symbols_cmds_GCJ='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
- # include_expsyms should be a list of space-separated symbols to be *always*
- # included in the symbol list
- include_expsyms_GCJ=
- # exclude_expsyms can be an extended regexp of symbols to exclude
- # it will be wrapped by ` (' and `)$', so one must not match beginning or
- # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
- # as well as any symbol that contains `d'.
- exclude_expsyms_GCJ='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'
- # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
- # platforms (ab)use it in PIC code, but their linkers get confused if
- # the symbol is explicitly referenced. Since portable code cannot
- # rely on this symbol name, it's probably fine to never include it in
- # preloaded symbol tables.
- # Exclude shared library initialization/finalization symbols.
- extract_expsyms_cmds=
- # Just being paranoid about ensuring that cc_basename is set.
- for cc_temp in $compiler""; do
- case $cc_temp in
- compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
- distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
- \-*) ;;
- *) break;;
- esac
-done
-cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"`
-
- case $host_os in
- cygwin* | mingw* | pw32*)
- # FIXME: the MSVC++ port hasn't been tested in a loooong time
- # When not using gcc, we currently assume that we are using
- # Microsoft Visual C++.
- if test "$GCC" != yes; then
- with_gnu_ld=no
- fi
- ;;
- interix*)
- # we just hope/assume this is gcc and not c89 (= MSVC++)
- with_gnu_ld=yes
- ;;
- openbsd*)
- with_gnu_ld=no
- ;;
- esac
-
- ld_shlibs_GCJ=yes
- if test "$with_gnu_ld" = yes; then
- # If archive_cmds runs LD, not CC, wlarc should be empty
- wlarc='${wl}'
-
- # Set some defaults for GNU ld with shared library support. These
- # are reset later if shared libraries are not supported. Putting them
- # here allows them to be overridden if necessary.
- runpath_var=LD_RUN_PATH
- hardcode_libdir_flag_spec_GCJ='${wl}--rpath ${wl}$libdir'
- export_dynamic_flag_spec_GCJ='${wl}--export-dynamic'
- # ancient GNU ld didn't support --whole-archive et. al.
- if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then
- whole_archive_flag_spec_GCJ="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
- else
- whole_archive_flag_spec_GCJ=
- fi
- supports_anon_versioning=no
- case `$LD -v 2>/dev/null` in
- *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11
- *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
- *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
- *\ 2.11.*) ;; # other 2.11 versions
- *) supports_anon_versioning=yes ;;
- esac
-
- # See if GNU ld supports shared libraries.
- case $host_os in
- aix[3-9]*)
- # On AIX/PPC, the GNU linker is very broken
- if test "$host_cpu" != ia64; then
- ld_shlibs_GCJ=no
- cat <<EOF 1>&2
-
-*** Warning: the GNU linker, at least up to release 2.9.1, is reported
-*** to be unable to reliably create shared libraries on AIX.
-*** Therefore, libtool is disabling shared libraries support. If you
-*** really care for shared libraries, you may want to modify your PATH
-*** so that a non-GNU linker is found, and then restart.
-
-EOF
- fi
- ;;
-
- amigaos*)
- archive_cmds_GCJ='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
- hardcode_libdir_flag_spec_GCJ='-L$libdir'
- hardcode_minus_L_GCJ=yes
-
- # Samuel A. Falvo II <kc5tja@dolphin.openprojects.net> reports
- # that the semantics of dynamic libraries on AmigaOS, at least up
- # to version 4, is to share data among multiple programs linked
- # with the same dynamic library. Since this doesn't match the
- # behavior of shared libraries on other platforms, we can't use
- # them.
- ld_shlibs_GCJ=no
- ;;
-
- beos*)
- if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
- allow_undefined_flag_GCJ=unsupported
- # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
- # support --undefined. This deserves some investigation. FIXME
- archive_cmds_GCJ='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- else
- ld_shlibs_GCJ=no
- fi
- ;;
-
- cygwin* | mingw* | pw32*)
- # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, GCJ) is actually meaningless,
- # as there is no search path for DLLs.
- hardcode_libdir_flag_spec_GCJ='-L$libdir'
- allow_undefined_flag_GCJ=unsupported
- always_export_symbols_GCJ=no
- enable_shared_with_static_runtimes_GCJ=yes
- export_symbols_cmds_GCJ='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/'\'' -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols'
-
- if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then
- archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
- # If the export-symbols file already is a .def file (1st line
- # is EXPORTS), use it as is; otherwise, prepend...
- archive_expsym_cmds_GCJ='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
- cp $export_symbols $output_objdir/$soname.def;
- else
- echo EXPORTS > $output_objdir/$soname.def;
- cat $export_symbols >> $output_objdir/$soname.def;
- fi~
- $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
- else
- ld_shlibs_GCJ=no
- fi
- ;;
-
- interix[3-9]*)
- hardcode_direct_GCJ=no
- hardcode_shlibpath_var_GCJ=no
- hardcode_libdir_flag_spec_GCJ='${wl}-rpath,$libdir'
- export_dynamic_flag_spec_GCJ='${wl}-E'
- # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
- # Instead, shared libraries are loaded at an image base (0x10000000 by
- # default) and relocated if they conflict, which is a slow very memory
- # consuming and fragmenting process. To avoid this, we pick a random,
- # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
- # time. Moving up from 0x10000000 also allows more sbrk(2) space.
- archive_cmds_GCJ='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
- archive_expsym_cmds_GCJ='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
- ;;
-
- gnu* | linux* | k*bsd*-gnu)
- if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
- tmp_addflag=
- case $cc_basename,$host_cpu in
- pgcc*) # Portland Group C compiler
- whole_archive_flag_spec_GCJ='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
- tmp_addflag=' $pic_flag'
- ;;
- pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers
- whole_archive_flag_spec_GCJ='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
- tmp_addflag=' $pic_flag -Mnomain' ;;
- ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64
- tmp_addflag=' -i_dynamic' ;;
- efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64
- tmp_addflag=' -i_dynamic -nofor_main' ;;
- ifc* | ifort*) # Intel Fortran compiler
- tmp_addflag=' -nofor_main' ;;
- esac
- case `$CC -V 2>&1 | sed 5q` in
- *Sun\ C*) # Sun C 5.9
- whole_archive_flag_spec_GCJ='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
- tmp_sharedflag='-G' ;;
- *Sun\ F*) # Sun Fortran 8.3
- tmp_sharedflag='-G' ;;
- *)
- tmp_sharedflag='-shared' ;;
- esac
- archive_cmds_GCJ='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
-
- if test $supports_anon_versioning = yes; then
- archive_expsym_cmds_GCJ='$echo "{ global:" > $output_objdir/$libname.ver~
- cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
- $echo "local: *; };" >> $output_objdir/$libname.ver~
- $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
- fi
- else
- ld_shlibs_GCJ=no
- fi
- ;;
-
- netbsd*)
- if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
- archive_cmds_GCJ='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
- wlarc=
- else
- archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- archive_expsym_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
- fi
- ;;
-
- solaris*)
- if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then
- ld_shlibs_GCJ=no
- cat <<EOF 1>&2
-
-*** Warning: The releases 2.8.* of the GNU linker cannot reliably
-*** create shared libraries on Solaris systems. Therefore, libtool
-*** is disabling shared libraries support. We urge you to upgrade GNU
-*** binutils to release 2.9.1 or newer. Another option is to modify
-*** your PATH or compiler configuration so that the native linker is
-*** used, and then restart.
-
-EOF
- elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
- archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- archive_expsym_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
- else
- ld_shlibs_GCJ=no
- fi
- ;;
-
- sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
- case `$LD -v 2>&1` in
- *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*)
- ld_shlibs_GCJ=no
- cat <<_LT_EOF 1>&2
-
-*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not
-*** reliably create shared libraries on SCO systems. Therefore, libtool
-*** is disabling shared libraries support. We urge you to upgrade GNU
-*** binutils to release 2.16.91.0.3 or newer. Another option is to modify
-*** your PATH or compiler configuration so that the native linker is
-*** used, and then restart.
-
-_LT_EOF
- ;;
- *)
- if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
- hardcode_libdir_flag_spec_GCJ='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`'
- archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib'
- archive_expsym_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname,-retain-symbols-file,$export_symbols -o $lib'
- else
- ld_shlibs_GCJ=no
- fi
- ;;
- esac
- ;;
-
- sunos4*)
- archive_cmds_GCJ='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
- wlarc=
- hardcode_direct_GCJ=yes
- hardcode_shlibpath_var_GCJ=no
- ;;
-
- *)
- if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
- archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- archive_expsym_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
- else
- ld_shlibs_GCJ=no
- fi
- ;;
- esac
-
- if test "$ld_shlibs_GCJ" = no; then
- runpath_var=
- hardcode_libdir_flag_spec_GCJ=
- export_dynamic_flag_spec_GCJ=
- whole_archive_flag_spec_GCJ=
- fi
- else
- # PORTME fill in a description of your system's linker (not GNU ld)
- case $host_os in
- aix3*)
- allow_undefined_flag_GCJ=unsupported
- always_export_symbols_GCJ=yes
- archive_expsym_cmds_GCJ='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
- # Note: this linker hardcodes the directories in LIBPATH if there
- # are no directories specified by -L.
- hardcode_minus_L_GCJ=yes
- if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then
- # Neither direct hardcoding nor static linking is supported with a
- # broken collect2.
- hardcode_direct_GCJ=unsupported
- fi
- ;;
-
- aix[4-9]*)
- if test "$host_cpu" = ia64; then
- # On IA64, the linker does run time linking by default, so we don't
- # have to do anything special.
- aix_use_runtimelinking=no
- exp_sym_flag='-Bexport'
- no_entry_flag=""
- else
- # If we're using GNU nm, then we don't want the "-C" option.
- # -C means demangle to AIX nm, but means don't demangle with GNU nm
- if $NM -V 2>&1 | grep 'GNU' > /dev/null; then
- export_symbols_cmds_GCJ='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols'
- else
- export_symbols_cmds_GCJ='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols'
- fi
- aix_use_runtimelinking=no
-
- # Test if we are trying to use run time linking or normal
- # AIX style linking. If -brtl is somewhere in LDFLAGS, we
- # need to do runtime linking.
- case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*)
- for ld_flag in $LDFLAGS; do
- if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
- aix_use_runtimelinking=yes
- break
- fi
- done
- ;;
- esac
-
- exp_sym_flag='-bexport'
- no_entry_flag='-bnoentry'
- fi
-
- # When large executables or shared objects are built, AIX ld can
- # have problems creating the table of contents. If linking a library
- # or program results in "error TOC overflow" add -mminimal-toc to
- # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not
- # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
-
- archive_cmds_GCJ=''
- hardcode_direct_GCJ=yes
- hardcode_libdir_separator_GCJ=':'
- link_all_deplibs_GCJ=yes
-
- if test "$GCC" = yes; then
- case $host_os in aix4.[012]|aix4.[012].*)
- # We only want to do this on AIX 4.2 and lower, the check
- # below for broken collect2 doesn't work under 4.3+
- collect2name=`${CC} -print-prog-name=collect2`
- if test -f "$collect2name" && \
- strings "$collect2name" | grep resolve_lib_name >/dev/null
- then
- # We have reworked collect2
- :
- else
- # We have old collect2
- hardcode_direct_GCJ=unsupported
- # It fails to find uninstalled libraries when the uninstalled
- # path is not listed in the libpath. Setting hardcode_minus_L
- # to unsupported forces relinking
- hardcode_minus_L_GCJ=yes
- hardcode_libdir_flag_spec_GCJ='-L$libdir'
- hardcode_libdir_separator_GCJ=
- fi
- ;;
- esac
- shared_flag='-shared'
- if test "$aix_use_runtimelinking" = yes; then
- shared_flag="$shared_flag "'${wl}-G'
- fi
- else
- # not using gcc
- if test "$host_cpu" = ia64; then
- # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
- # chokes on -Wl,-G. The following line is correct:
- shared_flag='-G'
- else
- if test "$aix_use_runtimelinking" = yes; then
- shared_flag='${wl}-G'
- else
- shared_flag='${wl}-bM:SRE'
- fi
- fi
- fi
-
- # It seems that -bexpall does not export symbols beginning with
- # underscore (_), so it is better to generate a list of symbols to export.
- always_export_symbols_GCJ=yes
- if test "$aix_use_runtimelinking" = yes; then
- # Warning - without using the other runtime loading flags (-brtl),
- # -berok will link without error, but may produce a broken library.
- allow_undefined_flag_GCJ='-berok'
- # Determine the default libpath from the value encoded in an empty executable.
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- 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 "echo \"\$as_me:$LINENO: $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
- 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 &&
- $as_test_x conftest$ac_exeext; then
-
-lt_aix_libpath_sed='
- /Import File Strings/,/^$/ {
- /^0/ {
- s/^0 *\(.*\)$/\1/
- p
- }
- }'
-aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
-# Check for a 64-bit object if we didn't find anything.
-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
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-
-fi
-
-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_GCJ='${wl}-blibpath:$libdir:'"$aix_libpath"
- archive_expsym_cmds_GCJ="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
- else
- if test "$host_cpu" = ia64; then
- hardcode_libdir_flag_spec_GCJ='${wl}-R $libdir:/usr/lib:/lib'
- allow_undefined_flag_GCJ="-z nodefs"
- archive_expsym_cmds_GCJ="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
- else
- # Determine the default libpath from the value encoded in an empty executable.
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- 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 "echo \"\$as_me:$LINENO: $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
- 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 &&
- $as_test_x conftest$ac_exeext; then
-
-lt_aix_libpath_sed='
- /Import File Strings/,/^$/ {
- /^0/ {
- s/^0 *\(.*\)$/\1/
- p
- }
- }'
-aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
-# Check for a 64-bit object if we didn't find anything.
-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
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-
-fi
-
-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_GCJ='${wl}-blibpath:$libdir:'"$aix_libpath"
- # Warning - without using the other run time loading flags,
- # -berok will link without error, but may produce a broken library.
- no_undefined_flag_GCJ=' ${wl}-bernotok'
- allow_undefined_flag_GCJ=' ${wl}-berok'
- # Exported symbols can be pulled into shared objects from archives
- whole_archive_flag_spec_GCJ='$convenience'
- archive_cmds_need_lc_GCJ=yes
- # This is similar to how AIX traditionally builds its shared libraries.
- archive_expsym_cmds_GCJ="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
- fi
- fi
- ;;
-
- amigaos*)
- archive_cmds_GCJ='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
- hardcode_libdir_flag_spec_GCJ='-L$libdir'
- hardcode_minus_L_GCJ=yes
- # see comment about different semantics on the GNU ld section
- ld_shlibs_GCJ=no
- ;;
-
- bsdi[45]*)
- export_dynamic_flag_spec_GCJ=-rdynamic
- ;;
-
- cygwin* | mingw* | pw32*)
- # When not using gcc, we currently assume that we are using
- # Microsoft Visual C++.
- # hardcode_libdir_flag_spec is actually meaningless, as there is
- # no search path for DLLs.
- hardcode_libdir_flag_spec_GCJ=' '
- allow_undefined_flag_GCJ=unsupported
- # Tell ltmain to make .lib files, not .a files.
- libext=lib
- # Tell ltmain to make .dll files, not .so files.
- shrext_cmds=".dll"
- # FIXME: Setting linknames here is a bad hack.
- archive_cmds_GCJ='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | $SED -e '\''s/ -lc$//'\''` -link -dll~linknames='
- # The linker will automatically build a .lib file if we build a DLL.
- old_archive_From_new_cmds_GCJ='true'
- # FIXME: Should let the user specify the lib program.
- old_archive_cmds_GCJ='lib -OUT:$oldlib$oldobjs$old_deplibs'
- fix_srcfile_path_GCJ='`cygpath -w "$srcfile"`'
- enable_shared_with_static_runtimes_GCJ=yes
- ;;
-
- darwin* | rhapsody*)
- case $host_os in
- rhapsody* | darwin1.[012])
- allow_undefined_flag_GCJ='${wl}-undefined ${wl}suppress'
- ;;
- *) # Darwin 1.3 on
- if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then
- allow_undefined_flag_GCJ='${wl}-flat_namespace ${wl}-undefined ${wl}suppress'
- else
- case ${MACOSX_DEPLOYMENT_TARGET} in
- 10.[012])
- allow_undefined_flag_GCJ='${wl}-flat_namespace ${wl}-undefined ${wl}suppress'
- ;;
- 10.*)
- allow_undefined_flag_GCJ='${wl}-undefined ${wl}dynamic_lookup'
- ;;
- esac
- fi
- ;;
- esac
- archive_cmds_need_lc_GCJ=no
- hardcode_direct_GCJ=no
- hardcode_automatic_GCJ=yes
- hardcode_shlibpath_var_GCJ=unsupported
- whole_archive_flag_spec_GCJ=''
- link_all_deplibs_GCJ=yes
- if test "$GCC" = yes ; then
- output_verbose_link_cmd='echo'
- archive_cmds_GCJ="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
- module_cmds_GCJ="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
- archive_expsym_cmds_GCJ="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
- module_expsym_cmds_GCJ="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}"
- else
- case $cc_basename in
- xlc*)
- output_verbose_link_cmd='echo'
- archive_cmds_GCJ='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $xlcverstring'
- module_cmds_GCJ='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
- # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds
- archive_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $xlcverstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
- module_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
- ;;
- *)
- ld_shlibs_GCJ=no
- ;;
- esac
- fi
- ;;
-
- dgux*)
- archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- hardcode_libdir_flag_spec_GCJ='-L$libdir'
- hardcode_shlibpath_var_GCJ=no
- ;;
-
- freebsd1*)
- ld_shlibs_GCJ=no
- ;;
-
- # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
- # support. Future versions do this automatically, but an explicit c++rt0.o
- # does not break anything, and helps significantly (at the cost of a little
- # extra space).
- freebsd2.2*)
- archive_cmds_GCJ='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
- hardcode_libdir_flag_spec_GCJ='-R$libdir'
- hardcode_direct_GCJ=yes
- hardcode_shlibpath_var_GCJ=no
- ;;
-
- # Unfortunately, older versions of FreeBSD 2 do not have this feature.
- freebsd2*)
- archive_cmds_GCJ='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
- hardcode_direct_GCJ=yes
- hardcode_minus_L_GCJ=yes
- hardcode_shlibpath_var_GCJ=no
- ;;
-
- # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
- freebsd* | dragonfly*)
- archive_cmds_GCJ='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
- hardcode_libdir_flag_spec_GCJ='-R$libdir'
- hardcode_direct_GCJ=yes
- hardcode_shlibpath_var_GCJ=no
- ;;
-
- hpux9*)
- if test "$GCC" = yes; then
- archive_cmds_GCJ='$rm $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
- else
- archive_cmds_GCJ='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
- fi
- hardcode_libdir_flag_spec_GCJ='${wl}+b ${wl}$libdir'
- hardcode_libdir_separator_GCJ=:
- hardcode_direct_GCJ=yes
-
- # hardcode_minus_L: Not really in the search PATH,
- # but as the default location of the library.
- hardcode_minus_L_GCJ=yes
- export_dynamic_flag_spec_GCJ='${wl}-E'
- ;;
-
- hpux10*)
- if test "$GCC" = yes -a "$with_gnu_ld" = no; then
- archive_cmds_GCJ='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
- else
- archive_cmds_GCJ='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
- fi
- if test "$with_gnu_ld" = no; then
- hardcode_libdir_flag_spec_GCJ='${wl}+b ${wl}$libdir'
- hardcode_libdir_separator_GCJ=:
-
- hardcode_direct_GCJ=yes
- export_dynamic_flag_spec_GCJ='${wl}-E'
-
- # hardcode_minus_L: Not really in the search PATH,
- # but as the default location of the library.
- hardcode_minus_L_GCJ=yes
- fi
- ;;
-
- hpux11*)
- if test "$GCC" = yes -a "$with_gnu_ld" = no; then
- case $host_cpu in
- hppa*64*)
- archive_cmds_GCJ='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- ia64*)
- archive_cmds_GCJ='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- *)
- archive_cmds_GCJ='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- esac
- else
- case $host_cpu in
- hppa*64*)
- archive_cmds_GCJ='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- ia64*)
- archive_cmds_GCJ='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- *)
- archive_cmds_GCJ='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- esac
- fi
- if test "$with_gnu_ld" = no; then
- hardcode_libdir_flag_spec_GCJ='${wl}+b ${wl}$libdir'
- hardcode_libdir_separator_GCJ=:
-
- case $host_cpu in
- hppa*64*|ia64*)
- hardcode_libdir_flag_spec_ld_GCJ='+b $libdir'
- hardcode_direct_GCJ=no
- hardcode_shlibpath_var_GCJ=no
- ;;
- *)
- hardcode_direct_GCJ=yes
- export_dynamic_flag_spec_GCJ='${wl}-E'
-
- # hardcode_minus_L: Not really in the search PATH,
- # but as the default location of the library.
- hardcode_minus_L_GCJ=yes
- ;;
- esac
- fi
- ;;
-
- irix5* | irix6* | nonstopux*)
- if test "$GCC" = yes; then
- archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
- else
- archive_cmds_GCJ='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
- hardcode_libdir_flag_spec_ld_GCJ='-rpath $libdir'
- fi
- hardcode_libdir_flag_spec_GCJ='${wl}-rpath ${wl}$libdir'
- hardcode_libdir_separator_GCJ=:
- link_all_deplibs_GCJ=yes
- ;;
-
- netbsd*)
- if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
- archive_cmds_GCJ='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out
- else
- archive_cmds_GCJ='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF
- fi
- hardcode_libdir_flag_spec_GCJ='-R$libdir'
- hardcode_direct_GCJ=yes
- hardcode_shlibpath_var_GCJ=no
- ;;
-
- newsos6)
- archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- hardcode_direct_GCJ=yes
- hardcode_libdir_flag_spec_GCJ='${wl}-rpath ${wl}$libdir'
- hardcode_libdir_separator_GCJ=:
- hardcode_shlibpath_var_GCJ=no
- ;;
-
- openbsd*)
- if test -f /usr/libexec/ld.so; then
- hardcode_direct_GCJ=yes
- hardcode_shlibpath_var_GCJ=no
- if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
- archive_cmds_GCJ='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
- archive_expsym_cmds_GCJ='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'
- hardcode_libdir_flag_spec_GCJ='${wl}-rpath,$libdir'
- export_dynamic_flag_spec_GCJ='${wl}-E'
- else
- case $host_os in
- openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
- archive_cmds_GCJ='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
- hardcode_libdir_flag_spec_GCJ='-R$libdir'
- ;;
- *)
- archive_cmds_GCJ='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
- hardcode_libdir_flag_spec_GCJ='${wl}-rpath,$libdir'
- ;;
- esac
- fi
- else
- ld_shlibs_GCJ=no
- fi
- ;;
-
- os2*)
- hardcode_libdir_flag_spec_GCJ='-L$libdir'
- hardcode_minus_L_GCJ=yes
- allow_undefined_flag_GCJ=unsupported
- archive_cmds_GCJ='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
- old_archive_From_new_cmds_GCJ='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
- ;;
-
- osf3*)
- if test "$GCC" = yes; then
- allow_undefined_flag_GCJ=' ${wl}-expect_unresolved ${wl}\*'
- archive_cmds_GCJ='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
- else
- allow_undefined_flag_GCJ=' -expect_unresolved \*'
- archive_cmds_GCJ='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
- fi
- hardcode_libdir_flag_spec_GCJ='${wl}-rpath ${wl}$libdir'
- hardcode_libdir_separator_GCJ=:
- ;;
-
- osf4* | osf5*) # as osf3* with the addition of -msym flag
- if test "$GCC" = yes; then
- allow_undefined_flag_GCJ=' ${wl}-expect_unresolved ${wl}\*'
- archive_cmds_GCJ='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
- hardcode_libdir_flag_spec_GCJ='${wl}-rpath ${wl}$libdir'
- else
- allow_undefined_flag_GCJ=' -expect_unresolved \*'
- archive_cmds_GCJ='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
- archive_expsym_cmds_GCJ='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~
- $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~$rm $lib.exp'
-
- # Both c and cxx compiler support -rpath directly
- hardcode_libdir_flag_spec_GCJ='-rpath $libdir'
- fi
- hardcode_libdir_separator_GCJ=:
- ;;
-
- solaris*)
- no_undefined_flag_GCJ=' -z text'
- if test "$GCC" = yes; then
- wlarc='${wl}'
- archive_cmds_GCJ='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
- archive_expsym_cmds_GCJ='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
- $CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp'
- else
- wlarc=''
- archive_cmds_GCJ='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
- archive_expsym_cmds_GCJ='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
- $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp'
- fi
- hardcode_libdir_flag_spec_GCJ='-R$libdir'
- hardcode_shlibpath_var_GCJ=no
- case $host_os in
- solaris2.[0-5] | solaris2.[0-5].*) ;;
- *)
- # The compiler driver will combine and reorder linker options,
- # but understands `-z linker_flag'. GCC discards it without `$wl',
- # but is careful enough not to reorder.
- # Supported since Solaris 2.6 (maybe 2.5.1?)
- if test "$GCC" = yes; then
- whole_archive_flag_spec_GCJ='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
- else
- whole_archive_flag_spec_GCJ='-z allextract$convenience -z defaultextract'
- fi
- ;;
- esac
- link_all_deplibs_GCJ=yes
- ;;
-
- sunos4*)
- if test "x$host_vendor" = xsequent; then
- # Use $CC to link under sequent, because it throws in some extra .o
- # files that make .init and .fini sections work.
- archive_cmds_GCJ='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
- else
- archive_cmds_GCJ='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
- fi
- hardcode_libdir_flag_spec_GCJ='-L$libdir'
- hardcode_direct_GCJ=yes
- hardcode_minus_L_GCJ=yes
- hardcode_shlibpath_var_GCJ=no
- ;;
-
- sysv4)
- case $host_vendor in
- sni)
- archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- hardcode_direct_GCJ=yes # is this really true???
- ;;
- siemens)
- ## LD is ld it makes a PLAMLIB
- ## CC just makes a GrossModule.
- archive_cmds_GCJ='$LD -G -o $lib $libobjs $deplibs $linker_flags'
- reload_cmds_GCJ='$CC -r -o $output$reload_objs'
- hardcode_direct_GCJ=no
- ;;
- motorola)
- archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- hardcode_direct_GCJ=no #Motorola manual says yes, but my tests say they lie
- ;;
- esac
- runpath_var='LD_RUN_PATH'
- hardcode_shlibpath_var_GCJ=no
- ;;
-
- sysv4.3*)
- archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- hardcode_shlibpath_var_GCJ=no
- export_dynamic_flag_spec_GCJ='-Bexport'
- ;;
-
- sysv4*MP*)
- if test -d /usr/nec; then
- archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- hardcode_shlibpath_var_GCJ=no
- runpath_var=LD_RUN_PATH
- hardcode_runpath_var=yes
- ld_shlibs_GCJ=yes
- fi
- ;;
-
- sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
- no_undefined_flag_GCJ='${wl}-z,text'
- archive_cmds_need_lc_GCJ=no
- hardcode_shlibpath_var_GCJ=no
- runpath_var='LD_RUN_PATH'
-
- if test "$GCC" = yes; then
- archive_cmds_GCJ='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- archive_expsym_cmds_GCJ='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- else
- archive_cmds_GCJ='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- archive_expsym_cmds_GCJ='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- fi
- ;;
-
- sysv5* | sco3.2v5* | sco5v6*)
- # Note: We can NOT use -z defs as we might desire, because we do not
- # link with -lc, and that would cause any symbols used from libc to
- # always be unresolved, which means just about no library would
- # ever link correctly. If we're not using GNU ld we use -z text
- # though, which does catch some bad symbols but isn't as heavy-handed
- # as -z defs.
- no_undefined_flag_GCJ='${wl}-z,text'
- allow_undefined_flag_GCJ='${wl}-z,nodefs'
- archive_cmds_need_lc_GCJ=no
- hardcode_shlibpath_var_GCJ=no
- hardcode_libdir_flag_spec_GCJ='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`'
- hardcode_libdir_separator_GCJ=':'
- link_all_deplibs_GCJ=yes
- export_dynamic_flag_spec_GCJ='${wl}-Bexport'
- runpath_var='LD_RUN_PATH'
-
- if test "$GCC" = yes; then
- archive_cmds_GCJ='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
- archive_expsym_cmds_GCJ='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
- else
- archive_cmds_GCJ='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
- archive_expsym_cmds_GCJ='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
- fi
- ;;
-
- uts4*)
- archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- hardcode_libdir_flag_spec_GCJ='-L$libdir'
- hardcode_shlibpath_var_GCJ=no
- ;;
-
- *)
- ld_shlibs_GCJ=no
- ;;
- esac
- fi
-
-{ echo "$as_me:$LINENO: result: $ld_shlibs_GCJ" >&5
-echo "${ECHO_T}$ld_shlibs_GCJ" >&6; }
-test "$ld_shlibs_GCJ" = no && can_build_shared=no
-
-#
-# Do we need to explicitly link libc?
-#
-case "x$archive_cmds_need_lc_GCJ" in
-x|xyes)
- # Assume -lc should be added
- archive_cmds_need_lc_GCJ=yes
-
- if test "$enable_shared" = yes && test "$GCC" = yes; then
- case $archive_cmds_GCJ in
- *'~'*)
- # FIXME: we may have to deal with multi-command sequences.
- ;;
- '$CC '*)
- # 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.
- { echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5
-echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6; }
- $rm conftest*
- echo "$lt_simple_compile_test_code" > conftest.$ac_ext
-
- if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } 2>conftest.err; then
- soname=conftest
- lib=conftest
- libobjs=conftest.$ac_objext
- deplibs=
- wl=$lt_prog_compiler_wl_GCJ
- pic_flag=$lt_prog_compiler_pic_GCJ
- compiler_flags=-v
- linker_flags=-v
- verstring=
- output_objdir=.
- libname=conftest
- lt_save_allow_undefined_flag=$allow_undefined_flag_GCJ
- allow_undefined_flag_GCJ=
- if { (eval echo "$as_me:$LINENO: \"$archive_cmds_GCJ 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1\"") >&5
- (eval $archive_cmds_GCJ 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }
- then
- archive_cmds_need_lc_GCJ=no
- else
- archive_cmds_need_lc_GCJ=yes
- fi
- allow_undefined_flag_GCJ=$lt_save_allow_undefined_flag
- else
- cat conftest.err 1>&5
- fi
- $rm conftest*
- { echo "$as_me:$LINENO: result: $archive_cmds_need_lc_GCJ" >&5
-echo "${ECHO_T}$archive_cmds_need_lc_GCJ" >&6; }
- ;;
- esac
- fi
- ;;
-esac
-
-{ echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5
-echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6; }
-library_names_spec=
-libname_spec='lib$name'
-soname_spec=
-shrext_cmds=".so"
-postinstall_cmds=
-postuninstall_cmds=
-finish_cmds=
-finish_eval=
-shlibpath_var=
-shlibpath_overrides_runpath=unknown
-version_type=none
-dynamic_linker="$host_os ld.so"
-sys_lib_dlsearch_path_spec="/lib /usr/lib"
-
-need_lib_prefix=unknown
-hardcode_into_libs=no
-
-# when you set need_version to no, make sure it does not cause -set_version
-# flags to be left without arguments
-need_version=unknown
-
-case $host_os in
-aix3*)
- version_type=linux
- library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
- shlibpath_var=LIBPATH
-
- # AIX 3 has no versioning support, so we append a major version to the name.
- soname_spec='${libname}${release}${shared_ext}$major'
- ;;
-
-aix[4-9]*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- hardcode_into_libs=yes
- if test "$host_cpu" = ia64; then
- # AIX 5 supports IA64
- library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
- shlibpath_var=LD_LIBRARY_PATH
- else
- # With GCC up to 2.95.x, collect2 would create an import file
- # for dependence libraries. The import file would start with
- # the line `#! .'. This would cause the generated library to
- # depend on `.', always an invalid library. This was fixed in
- # development snapshots of GCC prior to 3.0.
- case $host_os in
- aix4 | aix4.[01] | aix4.[01].*)
- if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
- echo ' yes '
- echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then
- :
- else
- can_build_shared=no
- fi
- ;;
- esac
- # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
- # soname into executable. Probably we can add versioning support to
- # collect2, so additional links can be useful in future.
- if test "$aix_use_runtimelinking" = yes; then
- # If using run time linking (on AIX 4.2 or later) use lib<name>.so
- # instead of lib<name>.a to let people know that these are not
- # typical AIX shared libraries.
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- else
- # We preserve .a as extension for shared libraries through AIX4.2
- # and later when we are not doing run time linking.
- library_names_spec='${libname}${release}.a $libname.a'
- soname_spec='${libname}${release}${shared_ext}$major'
- fi
- shlibpath_var=LIBPATH
- fi
- ;;
-
-amigaos*)
- library_names_spec='$libname.ixlibrary $libname.a'
- # Create ${libname}_ixlibrary.a entries in /sys/libs.
- finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
- ;;
-
-beos*)
- library_names_spec='${libname}${shared_ext}'
- dynamic_linker="$host_os ld.so"
- shlibpath_var=LIBRARY_PATH
- ;;
-
-bsdi[45]*)
- version_type=linux
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
- shlibpath_var=LD_LIBRARY_PATH
- sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
- sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
- # the default ld.so.conf also contains /usr/contrib/lib and
- # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
- # libtool to hard-code these into programs
- ;;
-
-cygwin* | mingw* | pw32*)
- version_type=windows
- shrext_cmds=".dll"
- need_version=no
- need_lib_prefix=no
-
- case $GCC,$host_os in
- yes,cygwin* | yes,mingw* | yes,pw32*)
- library_names_spec='$libname.dll.a'
- # DLL is installed to $(libdir)/../bin by postinstall_cmds
- postinstall_cmds='base_file=`basename \${file}`~
- dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~
- dldir=$destdir/`dirname \$dlpath`~
- test -d \$dldir || mkdir -p \$dldir~
- $install_prog $dir/$dlname \$dldir/$dlname~
- chmod a+x \$dldir/$dlname'
- postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
- dlpath=$dir/\$dldll~
- $rm \$dlpath'
- shlibpath_overrides_runpath=yes
-
- case $host_os in
- cygwin*)
- # Cygwin DLLs use 'cyg' prefix rather than 'lib'
- soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
- sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib"
- ;;
- mingw*)
- # MinGW DLLs use traditional 'lib' prefix
- soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
- sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
- if echo "$sys_lib_search_path_spec" | grep ';[c-zC-Z]:/' >/dev/null; then
- # It is most probably a Windows format PATH printed by
- # mingw gcc, but we are running on Cygwin. Gcc prints its search
- # path with ; separators, and with drive letters. We can handle the
- # drive letters (cygwin fileutils understands them), so leave them,
- # especially as we might pass files found there to a mingw objdump,
- # which wouldn't understand a cygwinified path. Ahh.
- sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
- else
- sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
- fi
- ;;
- pw32*)
- # pw32 DLLs use 'pw' prefix rather than 'lib'
- library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
- ;;
- esac
- ;;
-
- *)
- library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'
- ;;
- esac
- dynamic_linker='Win32 ld.exe'
- # FIXME: first we should search . and the directory the executable is in
- shlibpath_var=PATH
- ;;
-
-darwin* | rhapsody*)
- dynamic_linker="$host_os dyld"
- version_type=darwin
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext'
- soname_spec='${libname}${release}${major}$shared_ext'
- shlibpath_overrides_runpath=yes
- shlibpath_var=DYLD_LIBRARY_PATH
- shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
-
- sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
- ;;
-
-dgux*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- ;;
-
-freebsd1*)
- dynamic_linker=no
- ;;
-
-freebsd* | dragonfly*)
- # DragonFly does not have aout. When/if they implement a new
- # versioning mechanism, adjust this.
- if test -x /usr/bin/objformat; then
- objformat=`/usr/bin/objformat`
- else
- case $host_os in
- freebsd[123]*) objformat=aout ;;
- *) objformat=elf ;;
- esac
- fi
- # Handle Gentoo/FreeBSD as it was Linux
- case $host_vendor in
- gentoo)
- version_type=linux ;;
- *)
- version_type=freebsd-$objformat ;;
- esac
-
- case $version_type in
- freebsd-elf*)
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
- need_version=no
- need_lib_prefix=no
- ;;
- freebsd-*)
- library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
- need_version=yes
- ;;
- linux)
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- need_lib_prefix=no
- need_version=no
- ;;
- esac
- shlibpath_var=LD_LIBRARY_PATH
- case $host_os in
- freebsd2*)
- shlibpath_overrides_runpath=yes
- ;;
- freebsd3.[01]* | freebsdelf3.[01]*)
- shlibpath_overrides_runpath=yes
- hardcode_into_libs=yes
- ;;
- freebsd3.[2-9]* | freebsdelf3.[2-9]* | \
- freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1)
- shlibpath_overrides_runpath=no
- hardcode_into_libs=yes
- ;;
- *) # from 4.6 on, and DragonFly
- shlibpath_overrides_runpath=yes
- hardcode_into_libs=yes
- ;;
- esac
- ;;
-
-gnu*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- hardcode_into_libs=yes
- ;;
-
-hpux9* | hpux10* | hpux11*)
- # Give a soname corresponding to the major version so that dld.sl refuses to
- # link against other versions.
- version_type=sunos
- need_lib_prefix=no
- need_version=no
- case $host_cpu in
- ia64*)
- shrext_cmds='.so'
- hardcode_into_libs=yes
- dynamic_linker="$host_os dld.so"
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- if test "X$HPUX_IA64_MODE" = X32; then
- sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
- else
- sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
- fi
- sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
- ;;
- hppa*64*)
- shrext_cmds='.sl'
- hardcode_into_libs=yes
- dynamic_linker="$host_os dld.sl"
- shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
- shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
- sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
- ;;
- *)
- shrext_cmds='.sl'
- dynamic_linker="$host_os dld.sl"
- shlibpath_var=SHLIB_PATH
- shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- ;;
- esac
- # HP-UX runs *really* slowly unless shared libraries are mode 555.
- postinstall_cmds='chmod 555 $lib'
- ;;
-
-interix[3-9]*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=no
- hardcode_into_libs=yes
- ;;
-
-irix5* | irix6* | nonstopux*)
- case $host_os in
- nonstopux*) version_type=nonstopux ;;
- *)
- if test "$lt_cv_prog_gnu_ld" = yes; then
- version_type=linux
- else
- version_type=irix
- fi ;;
- esac
- need_lib_prefix=no
- need_version=no
- soname_spec='${libname}${release}${shared_ext}$major'
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
- case $host_os in
- irix5* | nonstopux*)
- libsuff= shlibsuff=
- ;;
- *)
- case $LD in # libtool.m4 will add one of these switches to LD
- *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
- libsuff= shlibsuff= libmagic=32-bit;;
- *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
- libsuff=32 shlibsuff=N32 libmagic=N32;;
- *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
- libsuff=64 shlibsuff=64 libmagic=64-bit;;
- *) libsuff= shlibsuff= libmagic=never-match;;
- esac
- ;;
- esac
- shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
- shlibpath_overrides_runpath=no
- sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
- sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
- hardcode_into_libs=yes
- ;;
-
-# No shared lib support for Linux oldld, aout, or coff.
-linux*oldld* | linux*aout* | linux*coff*)
- dynamic_linker=no
- ;;
-
-# This must be Linux ELF.
-linux* | k*bsd*-gnu)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=no
- # This implies no fast_install, which is unacceptable.
- # Some rework will be needed to allow for fast_install
- # before this can be enabled.
- hardcode_into_libs=yes
-
- # Append ld.so.conf contents to the search path
- if test -f /etc/ld.so.conf; then
- lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '`
- sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
- fi
-
- # We used to test for /lib/ld.so.1 and disable shared libraries on
- # powerpc, because MkLinux only supported shared libraries with the
- # GNU dynamic linker. Since this was broken with cross compilers,
- # most powerpc-linux boxes support dynamic linking these days and
- # people can always --disable-shared, the test was removed, and we
- # assume the GNU/Linux dynamic linker is in use.
- dynamic_linker='GNU/Linux ld.so'
- ;;
-
-netbsd*)
- version_type=sunos
- need_lib_prefix=no
- need_version=no
- if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
- finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
- dynamic_linker='NetBSD (a.out) ld.so'
- else
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- dynamic_linker='NetBSD ld.elf_so'
- fi
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes
- hardcode_into_libs=yes
- ;;
-
-newsos6)
- version_type=linux
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes
- ;;
-
-nto-qnx*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes
- ;;
-
-openbsd*)
- version_type=sunos
- sys_lib_dlsearch_path_spec="/usr/lib"
- need_lib_prefix=no
- # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
- case $host_os in
- openbsd3.3 | openbsd3.3.*) need_version=yes ;;
- *) need_version=no ;;
- esac
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
- finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
- shlibpath_var=LD_LIBRARY_PATH
- if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
- case $host_os in
- openbsd2.[89] | openbsd2.[89].*)
- shlibpath_overrides_runpath=no
- ;;
- *)
- shlibpath_overrides_runpath=yes
- ;;
- esac
- else
- shlibpath_overrides_runpath=yes
- fi
- ;;
-
-os2*)
- libname_spec='$name'
- shrext_cmds=".dll"
- need_lib_prefix=no
- library_names_spec='$libname${shared_ext} $libname.a'
- dynamic_linker='OS/2 ld.exe'
- shlibpath_var=LIBPATH
- ;;
-
-osf3* | osf4* | osf5*)
- version_type=osf
- need_lib_prefix=no
- need_version=no
- soname_spec='${libname}${release}${shared_ext}$major'
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- shlibpath_var=LD_LIBRARY_PATH
- sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
- sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
- ;;
-
-rdos*)
- dynamic_linker=no
- ;;
-
-solaris*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes
- hardcode_into_libs=yes
- # ldd complains unless libraries are executable
- postinstall_cmds='chmod +x $lib'
- ;;
-
-sunos4*)
- version_type=sunos
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
- finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes
- if test "$with_gnu_ld" = yes; then
- need_lib_prefix=no
- fi
- need_version=yes
- ;;
-
-sysv4 | sysv4.3*)
- version_type=linux
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- case $host_vendor in
- sni)
- shlibpath_overrides_runpath=no
- need_lib_prefix=no
- export_dynamic_flag_spec='${wl}-Blargedynsym'
- runpath_var=LD_RUN_PATH
- ;;
- siemens)
- need_lib_prefix=no
- ;;
- motorola)
- need_lib_prefix=no
- need_version=no
- shlibpath_overrides_runpath=no
- sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
- ;;
- esac
- ;;
-
-sysv4*MP*)
- if test -d /usr/nec ;then
- version_type=linux
- library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
- soname_spec='$libname${shared_ext}.$major'
- shlibpath_var=LD_LIBRARY_PATH
- fi
- ;;
-
-sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
- version_type=freebsd-elf
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- hardcode_into_libs=yes
- if test "$with_gnu_ld" = yes; then
- sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
- shlibpath_overrides_runpath=no
- else
- sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
- shlibpath_overrides_runpath=yes
- case $host_os in
- sco3.2v5*)
- sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
- ;;
- esac
- fi
- sys_lib_dlsearch_path_spec='/usr/lib'
- ;;
-
-uts4*)
- version_type=linux
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- ;;
-
-*)
- dynamic_linker=no
- ;;
-esac
-{ echo "$as_me:$LINENO: result: $dynamic_linker" >&5
-echo "${ECHO_T}$dynamic_linker" >&6; }
-test "$dynamic_linker" = no && can_build_shared=no
-
-if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- lt_cv_sys_lib_search_path_spec="$sys_lib_search_path_spec"
-fi
-
-sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec"
-if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- lt_cv_sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec"
-fi
-
-sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec"
-
-variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
-if test "$GCC" = yes; then
- variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
-fi
-
-{ echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5
-echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6; }
-hardcode_action_GCJ=
-if test -n "$hardcode_libdir_flag_spec_GCJ" || \
- test -n "$runpath_var_GCJ" || \
- test "X$hardcode_automatic_GCJ" = "Xyes" ; then
-
- # We can hardcode non-existant directories.
- if test "$hardcode_direct_GCJ" != no &&
- # If the only mechanism to avoid hardcoding is shlibpath_var, we
- # have to relink, otherwise we might link with an installed library
- # when we should be linking with a yet-to-be-installed one
- ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, GCJ)" != no &&
- test "$hardcode_minus_L_GCJ" != no; then
- # Linking always hardcodes the temporary library directory.
- hardcode_action_GCJ=relink
- else
- # We can link without hardcoding, and we can hardcode nonexisting dirs.
- hardcode_action_GCJ=immediate
- fi
-else
- # We cannot hardcode anything, or else we can only hardcode existing
- # directories.
- hardcode_action_GCJ=unsupported
-fi
-{ echo "$as_me:$LINENO: result: $hardcode_action_GCJ" >&5
-echo "${ECHO_T}$hardcode_action_GCJ" >&6; }
-
-if test "$hardcode_action_GCJ" = relink; then
- # Fast installation is not supported
- enable_fast_install=no
-elif test "$shlibpath_overrides_runpath" = yes ||
- test "$enable_shared" = no; then
- # Fast installation is not necessary
- enable_fast_install=needless
-fi
-
-
-# The else clause should only fire when bootstrapping the
-# libtool distribution, otherwise you forgot to ship ltmain.sh
-# with your package, and you will get complaints that there are
-# no rules to generate ltmain.sh.
-if test -f "$ltmain"; then
- # See if we are running on zsh, and set the options which allow our commands through
- # without removal of \ escapes.
- if test -n "${ZSH_VERSION+set}" ; then
- setopt NO_GLOB_SUBST
- fi
- # Now quote all the things that may contain metacharacters while being
- # careful not to overquote the AC_SUBSTed values. We take copies of the
- # variables and quote the copies for generation of the libtool script.
- for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \
- SED SHELL STRIP \
- libname_spec library_names_spec soname_spec extract_expsyms_cmds \
- old_striplib striplib file_magic_cmd finish_cmds finish_eval \
- deplibs_check_method reload_flag reload_cmds need_locks \
- lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \
- lt_cv_sys_global_symbol_to_c_name_address \
- sys_lib_search_path_spec sys_lib_dlsearch_path_spec \
- old_postinstall_cmds old_postuninstall_cmds \
- compiler_GCJ \
- CC_GCJ \
- LD_GCJ \
- lt_prog_compiler_wl_GCJ \
- lt_prog_compiler_pic_GCJ \
- lt_prog_compiler_static_GCJ \
- lt_prog_compiler_no_builtin_flag_GCJ \
- export_dynamic_flag_spec_GCJ \
- thread_safe_flag_spec_GCJ \
- whole_archive_flag_spec_GCJ \
- enable_shared_with_static_runtimes_GCJ \
- old_archive_cmds_GCJ \
- old_archive_from_new_cmds_GCJ \
- predep_objects_GCJ \
- postdep_objects_GCJ \
- predeps_GCJ \
- postdeps_GCJ \
- compiler_lib_search_path_GCJ \
- compiler_lib_search_dirs_GCJ \
- archive_cmds_GCJ \
- archive_expsym_cmds_GCJ \
- postinstall_cmds_GCJ \
- postuninstall_cmds_GCJ \
- old_archive_from_expsyms_cmds_GCJ \
- allow_undefined_flag_GCJ \
- no_undefined_flag_GCJ \
- export_symbols_cmds_GCJ \
- hardcode_libdir_flag_spec_GCJ \
- hardcode_libdir_flag_spec_ld_GCJ \
- hardcode_libdir_separator_GCJ \
- hardcode_automatic_GCJ \
- module_cmds_GCJ \
- module_expsym_cmds_GCJ \
- lt_cv_prog_compiler_c_o_GCJ \
- fix_srcfile_path_GCJ \
- exclude_expsyms_GCJ \
- include_expsyms_GCJ; do
-
- case $var in
- old_archive_cmds_GCJ | \
- old_archive_from_new_cmds_GCJ | \
- archive_cmds_GCJ | \
- archive_expsym_cmds_GCJ | \
- module_cmds_GCJ | \
- module_expsym_cmds_GCJ | \
- old_archive_from_expsyms_cmds_GCJ | \
- export_symbols_cmds_GCJ | \
- extract_expsyms_cmds | reload_cmds | finish_cmds | \
- postinstall_cmds | postuninstall_cmds | \
- old_postinstall_cmds | old_postuninstall_cmds | \
- sys_lib_search_path_spec | sys_lib_dlsearch_path_spec)
- # Double-quote double-evaled strings.
- eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\""
- ;;
- *)
- eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\""
- ;;
- esac
- done
-
- case $lt_echo in
- *'\$0 --fallback-echo"')
- lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'`
- ;;
- esac
-
-cfgfile="$ofile"
-
- cat <<__EOF__ >> "$cfgfile"
-# ### BEGIN LIBTOOL TAG CONFIG: $tagname
-
-# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
-
-# Shell to use when invoking shell scripts.
-SHELL=$lt_SHELL
-
-# Whether or not to build shared libraries.
-build_libtool_libs=$enable_shared
-
-# Whether or not to build static libraries.
-build_old_libs=$enable_static
-
-# Whether or not to add -lc for building shared libraries.
-build_libtool_need_lc=$archive_cmds_need_lc_GCJ
-
-# Whether or not to disallow shared libs when runtime libs are static
-allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_GCJ
-
-# Whether or not to optimize for fast installation.
-fast_install=$enable_fast_install
-
-# The host system.
-host_alias=$host_alias
-host=$host
-host_os=$host_os
-
-# The build system.
-build_alias=$build_alias
-build=$build
-build_os=$build_os
-
-# An echo program that does not interpret backslashes.
-echo=$lt_echo
-
-# The archiver.
-AR=$lt_AR
-AR_FLAGS=$lt_AR_FLAGS
-
-# A C compiler.
-LTCC=$lt_LTCC
-
-# LTCC compiler flags.
-LTCFLAGS=$lt_LTCFLAGS
-
-# A language-specific compiler.
-CC=$lt_compiler_GCJ
-
-# Is the compiler the GNU C compiler?
-with_gcc=$GCC_GCJ
-
-# An ERE matcher.
-EGREP=$lt_EGREP
-
-# The linker used to build libraries.
-LD=$lt_LD_GCJ
-
-# Whether we need hard or soft links.
-LN_S=$lt_LN_S
-
-# A BSD-compatible nm program.
-NM=$lt_NM
-
-# A symbol stripping program
-STRIP=$lt_STRIP
-
-# Used to examine libraries when file_magic_cmd begins "file"
-MAGIC_CMD=$MAGIC_CMD
-
-# Used on cygwin: DLL creation program.
-DLLTOOL="$DLLTOOL"
-
-# Used on cygwin: object dumper.
-OBJDUMP="$OBJDUMP"
-
-# Used on cygwin: assembler.
-AS="$AS"
-
-# The name of the directory that contains temporary libtool files.
-objdir=$objdir
-
-# How to create reloadable object files.
-reload_flag=$lt_reload_flag
-reload_cmds=$lt_reload_cmds
-
-# How to pass a linker flag through the compiler.
-wl=$lt_lt_prog_compiler_wl_GCJ
-
-# Object file suffix (normally "o").
-objext="$ac_objext"
-
-# Old archive suffix (normally "a").
-libext="$libext"
-
-# Shared library suffix (normally ".so").
-shrext_cmds='$shrext_cmds'
-
-# Executable file suffix (normally "").
-exeext="$exeext"
-
-# Additional compiler flags for building library objects.
-pic_flag=$lt_lt_prog_compiler_pic_GCJ
-pic_mode=$pic_mode
-
-# What is the maximum length of a command?
-max_cmd_len=$lt_cv_sys_max_cmd_len
-
-# Does compiler simultaneously support -c and -o options?
-compiler_c_o=$lt_lt_cv_prog_compiler_c_o_GCJ
-
-# Must we lock files when doing compilation?
-need_locks=$lt_need_locks
-
-# Do we need the lib prefix for modules?
-need_lib_prefix=$need_lib_prefix
-
-# Do we need a version for libraries?
-need_version=$need_version
-
-# Whether dlopen is supported.
-dlopen_support=$enable_dlopen
-
-# Whether dlopen of programs is supported.
-dlopen_self=$enable_dlopen_self
-
-# Whether dlopen of statically linked programs is supported.
-dlopen_self_static=$enable_dlopen_self_static
-
-# Compiler flag to prevent dynamic linking.
-link_static_flag=$lt_lt_prog_compiler_static_GCJ
-
-# Compiler flag to turn off builtin functions.
-no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_GCJ
-
-# Compiler flag to allow reflexive dlopens.
-export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_GCJ
-
-# Compiler flag to generate shared objects directly from archives.
-whole_archive_flag_spec=$lt_whole_archive_flag_spec_GCJ
-
-# Compiler flag to generate thread-safe objects.
-thread_safe_flag_spec=$lt_thread_safe_flag_spec_GCJ
-
-# Library versioning type.
-version_type=$version_type
-
-# Format of library name prefix.
-libname_spec=$lt_libname_spec
-
-# List of archive names. First name is the real one, the rest are links.
-# The last name is the one that the linker finds with -lNAME.
-library_names_spec=$lt_library_names_spec
-
-# The coded name of the library, if different from the real name.
-soname_spec=$lt_soname_spec
-
-# Commands used to build and install an old-style archive.
-RANLIB=$lt_RANLIB
-old_archive_cmds=$lt_old_archive_cmds_GCJ
-old_postinstall_cmds=$lt_old_postinstall_cmds
-old_postuninstall_cmds=$lt_old_postuninstall_cmds
-
-# Create an old-style archive from a shared archive.
-old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_GCJ
-
-# Create a temporary old-style archive to link instead of a shared archive.
-old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_GCJ
-
-# Commands used to build and install a shared archive.
-archive_cmds=$lt_archive_cmds_GCJ
-archive_expsym_cmds=$lt_archive_expsym_cmds_GCJ
-postinstall_cmds=$lt_postinstall_cmds
-postuninstall_cmds=$lt_postuninstall_cmds
-
-# Commands used to build a loadable module (assumed same as above if empty)
-module_cmds=$lt_module_cmds_GCJ
-module_expsym_cmds=$lt_module_expsym_cmds_GCJ
-
-# Commands to strip libraries.
-old_striplib=$lt_old_striplib
-striplib=$lt_striplib
-
-# Dependencies to place before the objects being linked to create a
-# shared library.
-predep_objects=$lt_predep_objects_GCJ
-
-# Dependencies to place after the objects being linked to create a
-# shared library.
-postdep_objects=$lt_postdep_objects_GCJ
-
-# Dependencies to place before the objects being linked to create a
-# shared library.
-predeps=$lt_predeps_GCJ
-
-# Dependencies to place after the objects being linked to create a
-# shared library.
-postdeps=$lt_postdeps_GCJ
-
-# The directories searched by this compiler when creating a shared
-# library
-compiler_lib_search_dirs=$lt_compiler_lib_search_dirs_GCJ
-
-# The library search path used internally by the compiler when linking
-# a shared library.
-compiler_lib_search_path=$lt_compiler_lib_search_path_GCJ
-
-# Method to check whether dependent libraries are shared objects.
-deplibs_check_method=$lt_deplibs_check_method
-
-# Command to use when deplibs_check_method == file_magic.
-file_magic_cmd=$lt_file_magic_cmd
-
-# Flag that allows shared libraries with undefined symbols to be built.
-allow_undefined_flag=$lt_allow_undefined_flag_GCJ
-
-# Flag that forces no undefined symbols.
-no_undefined_flag=$lt_no_undefined_flag_GCJ
-
-# Commands used to finish a libtool library installation in a directory.
-finish_cmds=$lt_finish_cmds
-
-# Same as above, but a single script fragment to be evaled but not shown.
-finish_eval=$lt_finish_eval
-
-# Take the output of nm and produce a listing of raw symbols and C names.
-global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe
-
-# Transform the output of nm in a proper C declaration
-global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl
-
-# Transform the output of nm in a C name address pair
-global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address
-
-# This is the shared library runtime path variable.
-runpath_var=$runpath_var
-
-# This is the shared library path variable.
-shlibpath_var=$shlibpath_var
-
-# Is shlibpath searched before the hard-coded library search path?
-shlibpath_overrides_runpath=$shlibpath_overrides_runpath
-
-# How to hardcode a shared library path into an executable.
-hardcode_action=$hardcode_action_GCJ
-
-# Whether we should hardcode library paths into libraries.
-hardcode_into_libs=$hardcode_into_libs
-
-# Flag to hardcode \$libdir into a binary during linking.
-# This must work even if \$libdir does not exist.
-hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_GCJ
-
-# If ld is used when linking, flag to hardcode \$libdir into
-# a binary during linking. This must work even if \$libdir does
-# not exist.
-hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_GCJ
-
-# Whether we need a single -rpath flag with a separated argument.
-hardcode_libdir_separator=$lt_hardcode_libdir_separator_GCJ
-
-# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the
-# resulting binary.
-hardcode_direct=$hardcode_direct_GCJ
-
-# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
-# resulting binary.
-hardcode_minus_L=$hardcode_minus_L_GCJ
-
-# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into
-# the resulting binary.
-hardcode_shlibpath_var=$hardcode_shlibpath_var_GCJ
-
-# Set to yes if building a shared library automatically hardcodes DIR into the library
-# and all subsequent libraries and executables linked against it.
-hardcode_automatic=$hardcode_automatic_GCJ
-
-# Variables whose values should be saved in libtool wrapper scripts and
-# restored at relink time.
-variables_saved_for_relink="$variables_saved_for_relink"
-
-# Whether libtool must link a program against all its dependency libraries.
-link_all_deplibs=$link_all_deplibs_GCJ
-
-# Compile-time system search path for libraries
-sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
-
-# Run-time system search path for libraries
-sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
-
-# Fix the shell variable \$srcfile for the compiler.
-fix_srcfile_path=$lt_fix_srcfile_path
-
-# Set to yes if exported symbols are required.
-always_export_symbols=$always_export_symbols_GCJ
-
-# The commands to list exported symbols.
-export_symbols_cmds=$lt_export_symbols_cmds_GCJ
-
-# The commands to extract the exported symbol list from a shared archive.
-extract_expsyms_cmds=$lt_extract_expsyms_cmds
-
-# Symbols that should not be listed in the preloaded symbols.
-exclude_expsyms=$lt_exclude_expsyms_GCJ
-
-# Symbols that must always be exported.
-include_expsyms=$lt_include_expsyms_GCJ
-
-# ### END LIBTOOL TAG CONFIG: $tagname
-
-__EOF__
-
-
-else
- # If there is no Makefile yet, we rely on a make rule to execute
- # `config.status --recheck' to rerun these tests and create the
- # libtool script then.
- ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'`
- if test -f "$ltmain_in"; then
- test -f Makefile && make "$ltmain"
- fi
-fi
-
-
-ac_ext=c
-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
-
-CC="$lt_save_CC"
-
- else
- tagname=""
- fi
- ;;
-
- RC)
-
-
-# Source file extension for RC test sources.
-ac_ext=rc
-
-# Object file extension for compiled RC test sources.
-objext=o
-objext_RC=$objext
-
-# Code to be used in simple compile tests
-lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }'
-
-# Code to be used in simple link tests
-lt_simple_link_test_code="$lt_simple_compile_test_code"
-
-# ltmain only uses $CC for tagged configurations so make sure $CC is set.
-
-# If no C compiler was specified, use CC.
-LTCC=${LTCC-"$CC"}
-
-# If no C compiler flags were specified, use CFLAGS.
-LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
-
-# Allow CC to be a program name with arguments.
-compiler=$CC
-
-
-# save warnings/boilerplate of simple test code
-ac_outfile=conftest.$ac_objext
-echo "$lt_simple_compile_test_code" >conftest.$ac_ext
-eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
-_lt_compiler_boilerplate=`cat conftest.err`
-$rm conftest*
-
-ac_outfile=conftest.$ac_objext
-echo "$lt_simple_link_test_code" >conftest.$ac_ext
-eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
-_lt_linker_boilerplate=`cat conftest.err`
-$rm -r conftest*
-
-
-# Allow CC to be a program name with arguments.
-lt_save_CC="$CC"
-CC=${RC-"windres"}
-compiler=$CC
-compiler_RC=$CC
-for cc_temp in $compiler""; do
- case $cc_temp in
- compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
- distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
- \-*) ;;
- *) break;;
- esac
-done
-cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"`
-
-lt_cv_prog_compiler_c_o_RC=yes
-
-# The else clause should only fire when bootstrapping the
-# libtool distribution, otherwise you forgot to ship ltmain.sh
-# with your package, and you will get complaints that there are
-# no rules to generate ltmain.sh.
-if test -f "$ltmain"; then
- # See if we are running on zsh, and set the options which allow our commands through
- # without removal of \ escapes.
- if test -n "${ZSH_VERSION+set}" ; then
- setopt NO_GLOB_SUBST
- fi
- # Now quote all the things that may contain metacharacters while being
- # careful not to overquote the AC_SUBSTed values. We take copies of the
- # variables and quote the copies for generation of the libtool script.
- for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \
- SED SHELL STRIP \
- libname_spec library_names_spec soname_spec extract_expsyms_cmds \
- old_striplib striplib file_magic_cmd finish_cmds finish_eval \
- deplibs_check_method reload_flag reload_cmds need_locks \
- lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \
- lt_cv_sys_global_symbol_to_c_name_address \
- sys_lib_search_path_spec sys_lib_dlsearch_path_spec \
- old_postinstall_cmds old_postuninstall_cmds \
- compiler_RC \
- CC_RC \
- LD_RC \
- lt_prog_compiler_wl_RC \
- lt_prog_compiler_pic_RC \
- lt_prog_compiler_static_RC \
- lt_prog_compiler_no_builtin_flag_RC \
- export_dynamic_flag_spec_RC \
- thread_safe_flag_spec_RC \
- whole_archive_flag_spec_RC \
- enable_shared_with_static_runtimes_RC \
- old_archive_cmds_RC \
- old_archive_from_new_cmds_RC \
- predep_objects_RC \
- postdep_objects_RC \
- predeps_RC \
- postdeps_RC \
- compiler_lib_search_path_RC \
- compiler_lib_search_dirs_RC \
- archive_cmds_RC \
- archive_expsym_cmds_RC \
- postinstall_cmds_RC \
- postuninstall_cmds_RC \
- old_archive_from_expsyms_cmds_RC \
- allow_undefined_flag_RC \
- no_undefined_flag_RC \
- export_symbols_cmds_RC \
- hardcode_libdir_flag_spec_RC \
- hardcode_libdir_flag_spec_ld_RC \
- hardcode_libdir_separator_RC \
- hardcode_automatic_RC \
- module_cmds_RC \
- module_expsym_cmds_RC \
- lt_cv_prog_compiler_c_o_RC \
- fix_srcfile_path_RC \
- exclude_expsyms_RC \
- include_expsyms_RC; do
-
- case $var in
- old_archive_cmds_RC | \
- old_archive_from_new_cmds_RC | \
- archive_cmds_RC | \
- archive_expsym_cmds_RC | \
- module_cmds_RC | \
- module_expsym_cmds_RC | \
- old_archive_from_expsyms_cmds_RC | \
- export_symbols_cmds_RC | \
- extract_expsyms_cmds | reload_cmds | finish_cmds | \
- postinstall_cmds | postuninstall_cmds | \
- old_postinstall_cmds | old_postuninstall_cmds | \
- sys_lib_search_path_spec | sys_lib_dlsearch_path_spec)
- # Double-quote double-evaled strings.
- eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\""
- ;;
- *)
- eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\""
- ;;
- esac
- done
-
- case $lt_echo in
- *'\$0 --fallback-echo"')
- lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'`
- ;;
- esac
-
-cfgfile="$ofile"
-
- cat <<__EOF__ >> "$cfgfile"
-# ### BEGIN LIBTOOL TAG CONFIG: $tagname
-
-# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
-
-# Shell to use when invoking shell scripts.
-SHELL=$lt_SHELL
-
-# Whether or not to build shared libraries.
-build_libtool_libs=$enable_shared
-
-# Whether or not to build static libraries.
-build_old_libs=$enable_static
-
-# Whether or not to add -lc for building shared libraries.
-build_libtool_need_lc=$archive_cmds_need_lc_RC
-
-# Whether or not to disallow shared libs when runtime libs are static
-allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_RC
-
-# Whether or not to optimize for fast installation.
-fast_install=$enable_fast_install
-
-# The host system.
-host_alias=$host_alias
-host=$host
-host_os=$host_os
-
-# The build system.
-build_alias=$build_alias
-build=$build
-build_os=$build_os
-
-# An echo program that does not interpret backslashes.
-echo=$lt_echo
-
-# The archiver.
-AR=$lt_AR
-AR_FLAGS=$lt_AR_FLAGS
-
-# A C compiler.
-LTCC=$lt_LTCC
-
-# LTCC compiler flags.
-LTCFLAGS=$lt_LTCFLAGS
-
-# A language-specific compiler.
-CC=$lt_compiler_RC
-
-# Is the compiler the GNU C compiler?
-with_gcc=$GCC_RC
-
-# An ERE matcher.
-EGREP=$lt_EGREP
-
-# The linker used to build libraries.
-LD=$lt_LD_RC
-
-# Whether we need hard or soft links.
-LN_S=$lt_LN_S
-
-# A BSD-compatible nm program.
-NM=$lt_NM
-
-# A symbol stripping program
-STRIP=$lt_STRIP
-
-# Used to examine libraries when file_magic_cmd begins "file"
-MAGIC_CMD=$MAGIC_CMD
-
-# Used on cygwin: DLL creation program.
-DLLTOOL="$DLLTOOL"
-
-# Used on cygwin: object dumper.
-OBJDUMP="$OBJDUMP"
-
-# Used on cygwin: assembler.
-AS="$AS"
-
-# The name of the directory that contains temporary libtool files.
-objdir=$objdir
-
-# How to create reloadable object files.
-reload_flag=$lt_reload_flag
-reload_cmds=$lt_reload_cmds
-
-# How to pass a linker flag through the compiler.
-wl=$lt_lt_prog_compiler_wl_RC
-
-# Object file suffix (normally "o").
-objext="$ac_objext"
-
-# Old archive suffix (normally "a").
-libext="$libext"
-
-# Shared library suffix (normally ".so").
-shrext_cmds='$shrext_cmds'
-
-# Executable file suffix (normally "").
-exeext="$exeext"
-
-# Additional compiler flags for building library objects.
-pic_flag=$lt_lt_prog_compiler_pic_RC
-pic_mode=$pic_mode
-
-# What is the maximum length of a command?
-max_cmd_len=$lt_cv_sys_max_cmd_len
-
-# Does compiler simultaneously support -c and -o options?
-compiler_c_o=$lt_lt_cv_prog_compiler_c_o_RC
-
-# Must we lock files when doing compilation?
-need_locks=$lt_need_locks
-
-# Do we need the lib prefix for modules?
-need_lib_prefix=$need_lib_prefix
-
-# Do we need a version for libraries?
-need_version=$need_version
-
-# Whether dlopen is supported.
-dlopen_support=$enable_dlopen
-
-# Whether dlopen of programs is supported.
-dlopen_self=$enable_dlopen_self
-
-# Whether dlopen of statically linked programs is supported.
-dlopen_self_static=$enable_dlopen_self_static
-
-# Compiler flag to prevent dynamic linking.
-link_static_flag=$lt_lt_prog_compiler_static_RC
-
-# Compiler flag to turn off builtin functions.
-no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_RC
-
-# Compiler flag to allow reflexive dlopens.
-export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_RC
-
-# Compiler flag to generate shared objects directly from archives.
-whole_archive_flag_spec=$lt_whole_archive_flag_spec_RC
-
-# Compiler flag to generate thread-safe objects.
-thread_safe_flag_spec=$lt_thread_safe_flag_spec_RC
-
-# Library versioning type.
-version_type=$version_type
-
-# Format of library name prefix.
-libname_spec=$lt_libname_spec
-
-# List of archive names. First name is the real one, the rest are links.
-# The last name is the one that the linker finds with -lNAME.
-library_names_spec=$lt_library_names_spec
-
-# The coded name of the library, if different from the real name.
-soname_spec=$lt_soname_spec
-
-# Commands used to build and install an old-style archive.
-RANLIB=$lt_RANLIB
-old_archive_cmds=$lt_old_archive_cmds_RC
-old_postinstall_cmds=$lt_old_postinstall_cmds
-old_postuninstall_cmds=$lt_old_postuninstall_cmds
-
-# Create an old-style archive from a shared archive.
-old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_RC
-
-# Create a temporary old-style archive to link instead of a shared archive.
-old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_RC
-
-# Commands used to build and install a shared archive.
-archive_cmds=$lt_archive_cmds_RC
-archive_expsym_cmds=$lt_archive_expsym_cmds_RC
-postinstall_cmds=$lt_postinstall_cmds
-postuninstall_cmds=$lt_postuninstall_cmds
-
-# Commands used to build a loadable module (assumed same as above if empty)
-module_cmds=$lt_module_cmds_RC
-module_expsym_cmds=$lt_module_expsym_cmds_RC
-
-# Commands to strip libraries.
-old_striplib=$lt_old_striplib
-striplib=$lt_striplib
-
-# Dependencies to place before the objects being linked to create a
-# shared library.
-predep_objects=$lt_predep_objects_RC
-
-# Dependencies to place after the objects being linked to create a
-# shared library.
-postdep_objects=$lt_postdep_objects_RC
-
-# Dependencies to place before the objects being linked to create a
-# shared library.
-predeps=$lt_predeps_RC
-
-# Dependencies to place after the objects being linked to create a
-# shared library.
-postdeps=$lt_postdeps_RC
-
-# The directories searched by this compiler when creating a shared
-# library
-compiler_lib_search_dirs=$lt_compiler_lib_search_dirs_RC
-
-# The library search path used internally by the compiler when linking
-# a shared library.
-compiler_lib_search_path=$lt_compiler_lib_search_path_RC
-
-# Method to check whether dependent libraries are shared objects.
-deplibs_check_method=$lt_deplibs_check_method
-
-# Command to use when deplibs_check_method == file_magic.
-file_magic_cmd=$lt_file_magic_cmd
-
-# Flag that allows shared libraries with undefined symbols to be built.
-allow_undefined_flag=$lt_allow_undefined_flag_RC
-
-# Flag that forces no undefined symbols.
-no_undefined_flag=$lt_no_undefined_flag_RC
-
-# Commands used to finish a libtool library installation in a directory.
-finish_cmds=$lt_finish_cmds
-
-# Same as above, but a single script fragment to be evaled but not shown.
-finish_eval=$lt_finish_eval
-
-# Take the output of nm and produce a listing of raw symbols and C names.
-global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe
-
-# Transform the output of nm in a proper C declaration
-global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl
-
-# Transform the output of nm in a C name address pair
-global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address
-
-# This is the shared library runtime path variable.
-runpath_var=$runpath_var
-
-# This is the shared library path variable.
-shlibpath_var=$shlibpath_var
-
-# Is shlibpath searched before the hard-coded library search path?
-shlibpath_overrides_runpath=$shlibpath_overrides_runpath
-
-# How to hardcode a shared library path into an executable.
-hardcode_action=$hardcode_action_RC
-
-# Whether we should hardcode library paths into libraries.
-hardcode_into_libs=$hardcode_into_libs
-
-# Flag to hardcode \$libdir into a binary during linking.
-# This must work even if \$libdir does not exist.
-hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_RC
-
-# If ld is used when linking, flag to hardcode \$libdir into
-# a binary during linking. This must work even if \$libdir does
-# not exist.
-hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_RC
-
-# Whether we need a single -rpath flag with a separated argument.
-hardcode_libdir_separator=$lt_hardcode_libdir_separator_RC
-
-# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the
-# resulting binary.
-hardcode_direct=$hardcode_direct_RC
-
-# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
-# resulting binary.
-hardcode_minus_L=$hardcode_minus_L_RC
-
-# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into
-# the resulting binary.
-hardcode_shlibpath_var=$hardcode_shlibpath_var_RC
-
-# Set to yes if building a shared library automatically hardcodes DIR into the library
-# and all subsequent libraries and executables linked against it.
-hardcode_automatic=$hardcode_automatic_RC
-
-# Variables whose values should be saved in libtool wrapper scripts and
-# restored at relink time.
-variables_saved_for_relink="$variables_saved_for_relink"
-
-# Whether libtool must link a program against all its dependency libraries.
-link_all_deplibs=$link_all_deplibs_RC
-
-# Compile-time system search path for libraries
-sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
-
-# Run-time system search path for libraries
-sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
-
-# Fix the shell variable \$srcfile for the compiler.
-fix_srcfile_path=$lt_fix_srcfile_path
-
-# Set to yes if exported symbols are required.
-always_export_symbols=$always_export_symbols_RC
-
-# The commands to list exported symbols.
-export_symbols_cmds=$lt_export_symbols_cmds_RC
-
-# The commands to extract the exported symbol list from a shared archive.
-extract_expsyms_cmds=$lt_extract_expsyms_cmds
-
-# Symbols that should not be listed in the preloaded symbols.
-exclude_expsyms=$lt_exclude_expsyms_RC
-
-# Symbols that must always be exported.
-include_expsyms=$lt_include_expsyms_RC
-
-# ### END LIBTOOL TAG CONFIG: $tagname
-
-__EOF__
-
-
-else
- # If there is no Makefile yet, we rely on a make rule to execute
- # `config.status --recheck' to rerun these tests and create the
- # libtool script then.
- ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'`
- if test -f "$ltmain_in"; then
- test -f Makefile && make "$ltmain"
- fi
-fi
-
-
-ac_ext=c
-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
-
-CC="$lt_save_CC"
-
- ;;
-
- *)
- { { echo "$as_me:$LINENO: error: Unsupported tag name: $tagname" >&5
-echo "$as_me: error: Unsupported tag name: $tagname" >&2;}
- { (exit 1); exit 1; }; }
- ;;
- esac
-
- # Append the new tag name to the list of available tags.
- if test -n "$tagname" ; then
- available_tags="$available_tags $tagname"
- fi
- fi
- done
- IFS="$lt_save_ifs"
-
- # Now substitute the updated list of available tags.
- if eval "sed -e 's/^available_tags=.*\$/available_tags=\"$available_tags\"/' \"$ofile\" > \"${ofile}T\""; then
- mv "${ofile}T" "$ofile"
- chmod +x "$ofile"
- else
- rm -f "${ofile}T"
- { { echo "$as_me:$LINENO: error: unable to update list of available tagged configurations." >&5
-echo "$as_me: error: unable to update list of available tagged configurations." >&2;}
- { (exit 1); exit 1; }; }
- fi
-fi
-
-
-
-# This can be used to rebuild libtool when needed
-LIBTOOL_DEPS="$ac_aux_dir/ltmain.sh"
-
-# Always use our own libtool.
-LIBTOOL='$(SHELL) $(top_builddir)/libtool'
-
-# Prevent multiple expansion
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-{ echo "$as_me:$LINENO: checking whether ln -s works" >&5
-echo $ECHO_N "checking whether ln -s works... $ECHO_C" >&6; }
-LN_S=$as_ln_s
-if test "$LN_S" = "ln -s"; then
- { echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6; }
-else
- { echo "$as_me:$LINENO: result: no, using $LN_S" >&5
-echo "${ECHO_T}no, using $LN_S" >&6; }
-fi
-
-
-PCRE_MAJOR="7"
-PCRE_MINOR="7"
-PCRE_PRERELEASE=""
-PCRE_DATE="2008-05-07"
-
-
-
-
-
-
-# Set a more sensible default value for $(htmldir).
-if test "x$htmldir" = 'x${docdir}'
-then
- htmldir='${docdir}/html'
-fi
-
-# Handle --disable-cpp
-# Check whether --enable-cpp was given.
-if test "${enable_cpp+set}" = set; then
- enableval=$enable_cpp;
-else
- enable_cpp=yes
-fi
-
-
-# Handle --enable-rebuild-chartables
-# Check whether --enable-rebuild-chartables was given.
-if test "${enable_rebuild_chartables+set}" = set; then
- enableval=$enable_rebuild_chartables;
-else
- enable_rebuild_chartables=no
-fi
-
-
-# Handle --enable-utf8 (disabled by default)
-# Check whether --enable-utf8 was given.
-if test "${enable_utf8+set}" = set; then
- enableval=$enable_utf8;
-else
- enable_utf8=unset
-fi
-
-
-# Handle --enable-unicode-properties
-# Check whether --enable-unicode-properties was given.
-if test "${enable_unicode_properties+set}" = set; then
- enableval=$enable_unicode_properties;
-else
- enable_unicode_properties=no
-fi
-
-
-# Handle --enable-newline=NL
-
-# Separate newline options
-ac_pcre_newline=lf
-# Check whether --enable-newline-is-cr was given.
-if test "${enable_newline_is_cr+set}" = set; then
- enableval=$enable_newline_is_cr; ac_pcre_newline=cr
-fi
-
-# Check whether --enable-newline-is-lf was given.
-if test "${enable_newline_is_lf+set}" = set; then
- enableval=$enable_newline_is_lf; ac_pcre_newline=lf
-fi
-
-# Check whether --enable-newline-is-crlf was given.
-if test "${enable_newline_is_crlf+set}" = set; then
- enableval=$enable_newline_is_crlf; ac_pcre_newline=crlf
-fi
-
-# Check whether --enable-newline-is-anycrlf was given.
-if test "${enable_newline_is_anycrlf+set}" = set; then
- enableval=$enable_newline_is_anycrlf; ac_pcre_newline=anycrlf
-fi
-
-# Check whether --enable-newline-is-any was given.
-if test "${enable_newline_is_any+set}" = set; then
- enableval=$enable_newline_is_any; ac_pcre_newline=any
-fi
-
-enable_newline="$ac_pcre_newline"
-
-# Handle --enable-bsr-anycrlf
-# Check whether --enable-bsr-anycrlf was given.
-if test "${enable_bsr_anycrlf+set}" = set; then
- enableval=$enable_bsr_anycrlf;
-else
- enable_bsr_anycrlf=no
-fi
-
-
-# Handle --enable-ebcdic
-# Check whether --enable-ebcdic was given.
-if test "${enable_ebcdic+set}" = set; then
- enableval=$enable_ebcdic;
-else
- enable_ebcdic=no
-fi
-
-
-# Handle --disable-stack-for-recursion
-# Check whether --enable-stack-for-recursion was given.
-if test "${enable_stack_for_recursion+set}" = set; then
- enableval=$enable_stack_for_recursion;
-else
- enable_stack_for_recursion=yes
-fi
-
-
-# Handle --enable-pcregrep-libz
-# Check whether --enable-pcregrep-libz was given.
-if test "${enable_pcregrep_libz+set}" = set; then
- enableval=$enable_pcregrep_libz;
-else
- enable_pcregrep_libz=no
-fi
-
-
-# Handle --enable-pcregrep-libbz2
-# Check whether --enable-pcregrep-libbz2 was given.
-if test "${enable_pcregrep_libbz2+set}" = set; then
- enableval=$enable_pcregrep_libbz2;
-else
- enable_pcregrep_libbz2=no
-fi
-
-
-# Handle --enable-pcretest-libreadline
-# Check whether --enable-pcretest-libreadline was given.
-if test "${enable_pcretest_libreadline+set}" = set; then
- enableval=$enable_pcretest_libreadline;
-else
- enable_pcretest_libreadline=no
-fi
-
-
-# Handle --with-posix-malloc-threshold=NBYTES
-
-# Check whether --with-posix-malloc-threshold was given.
-if test "${with_posix_malloc_threshold+set}" = set; then
- withval=$with_posix_malloc_threshold;
-else
- with_posix_malloc_threshold=10
-fi
-
-
-# Handle --with-link-size=N
-
-# Check whether --with-link-size was given.
-if test "${with_link_size+set}" = set; then
- withval=$with_link_size;
-else
- with_link_size=2
-fi
-
-
-# Handle --with-match-limit=N
-
-# Check whether --with-match-limit was given.
-if test "${with_match_limit+set}" = set; then
- withval=$with_match_limit;
-else
- with_match_limit=10000000
-fi
-
-
-# Handle --with-match-limit_recursion=N
-#
-# Note: In config.h, the default is to define MATCH_LIMIT_RECURSION
-# symbolically as MATCH_LIMIT, which in turn is defined to be some numeric
-# value (e.g. 10000000). MATCH_LIMIT_RECURSION can otherwise be set to some
-# different numeric value (or even the same numeric value as MATCH_LIMIT,
-# though no longer defined in terms of the latter).
-#
-
-# Check whether --with-match-limit-recursion was given.
-if test "${with_match_limit_recursion+set}" = set; then
- withval=$with_match_limit_recursion;
-else
- with_match_limit_recursion=MATCH_LIMIT
-fi
-
-
-# Make sure that if enable_unicode_properties was set, that UTF-8 support
-# is enabled.
-#
-if test "x$enable_unicode_properties" = "xyes"
-then
- if test "x$enable_utf8" = "xno"
- then
- { { echo "$as_me:$LINENO: error: support for Unicode properties requires UTF-8 support" >&5
-echo "$as_me: error: support for Unicode properties requires UTF-8 support" >&2;}
- { (exit 1); exit 1; }; }
- fi
- enable_utf8=yes
-fi
-
-if test "x$enable_utf8" = "xunset"
-then
- enable_utf8=no
-fi
-
-# Make sure that if enable_ebcdic is set, rebuild_chartables is also enabled.
-#
-if test "x$enable_ebcdic" = "xyes"
-then
- enable_rebuild_chartables=yes
-fi
-
-# Convert the newline identifier into the appropriate integer value.
-case "$enable_newline" in
- lf) ac_pcre_newline_value=10 ;;
- cr) ac_pcre_newline_value=13 ;;
- crlf) ac_pcre_newline_value=3338 ;;
- anycrlf) ac_pcre_newline_value=-2 ;;
- any) ac_pcre_newline_value=-1 ;;
- *)
- { { echo "$as_me:$LINENO: error: invalid argument \"$enable_newline\" to --enable-newline option" >&5
-echo "$as_me: error: invalid argument \"$enable_newline\" to --enable-newline option" >&2;}
- { (exit 1); exit 1; }; }
- ;;
-esac
-
-# Check argument to --with-link-size
-case "$with_link_size" in
- 2|3|4) ;;
- *)
- { { echo "$as_me:$LINENO: error: invalid argument \"$with_link_size\" to --with-link-size option" >&5
-echo "$as_me: error: invalid argument \"$with_link_size\" to --with-link-size option" >&2;}
- { (exit 1); exit 1; }; }
- ;;
-esac
-
-
-
-
-# Checks for header files.
-{ echo "$as_me:$LINENO: checking for ANSI C header files" >&5
-echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6; }
-if test "${ac_cv_header_stdc+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <float.h>
-
-int
-main ()
-{
-
- ;
- 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 "echo \"\$as_me:$LINENO: $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
- 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
- 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 >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <string.h>
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- $EGREP "memchr" >/dev/null 2>&1; then
- :
-else
- ac_cv_header_stdc=no
-fi
-rm -f conftest*
-
-fi
-
-if test $ac_cv_header_stdc = yes; then
- # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <stdlib.h>
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- $EGREP "free" >/dev/null 2>&1; then
- :
-else
- ac_cv_header_stdc=no
-fi
-rm -f conftest*
-
-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
- :
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <ctype.h>
-#include <stdlib.h>
-#if ((' ' & 0x0FF) == 0x020)
-# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
-# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
-#else
-# define ISLOWER(c) \
- (('a' <= (c) && (c) <= 'i') \
- || ('j' <= (c) && (c) <= 'r') \
- || ('s' <= (c) && (c) <= 'z'))
-# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
-#endif
-
-#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
-int
-main ()
-{
- int i;
- for (i = 0; i < 256; i++)
- if (XOR (islower (i), ISLOWER (i))
- || toupper (i) != TOUPPER (i))
- return 2;
- return 0;
-}
-_ACEOF
-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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>&5
- ac_status=$?
- 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- :
-else
- echo "$as_me: program exited with status $ac_status" >&5
-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.$ac_ext
-fi
-
-
-fi
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
-echo "${ECHO_T}$ac_cv_header_stdc" >&6; }
-if test $ac_cv_header_stdc = yes; then
-
-cat >>confdefs.h <<\_ACEOF
-#define STDC_HEADERS 1
-_ACEOF
-
-fi
-
-
-
-
-
-
-for ac_header in limits.h sys/types.h sys/stat.h dirent.h windows.h
-do
-as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- { echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking $ac_header usability" >&5
-echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&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 "echo \"\$as_me:$LINENO: $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
- 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
- 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
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking $ac_header presence" >&5
-echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&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 "echo \"\$as_me:$LINENO: $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
- 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
- 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
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
-echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
-
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- eval "$as_ac_Header=\$ac_header_preproc"
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
- cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
-_ACEOF
-
-fi
-
-done
-
-
-# The files below are C++ header files.
-pcre_have_type_traits="0"
-pcre_have_bits_type_traits="0"
-if test "x$enable_cpp" = "xyes" -a -n "$CXX"
-then
-ac_ext=cpp
-ac_cpp='$CXXCPP $CPPFLAGS'
-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
-
-
-# Older versions of pcre defined pcrecpp::no_arg, but in new versions
-# it's called pcrecpp::RE::no_arg. For backwards ABI compatibility,
-# we want to make one an alias for the other. Different systems do
-# this in different ways. Some systems, for instance, can do it via
-# a linker flag: -alias (for os x 10.5) or -i (for os x <=10.4).
-OLD_LDFLAGS="$LDFLAGS"
-for flag in "-alias,__ZN7pcrecpp2RE6no_argE,__ZN7pcrecpp6no_argE" \
- "-i__ZN7pcrecpp6no_argE:__ZN7pcrecpp2RE6no_argE"; do
- { echo "$as_me:$LINENO: checking for alias support in the linker" >&5
-echo $ECHO_N "checking for alias support in the linker... $ECHO_C" >&6; }
- LDFLAGS="$OLD_LDFLAGS -Wl,$flag"
- # We try to run the linker with this new ld flag. If the link fails,
- # we give up and remove the new flag from LDFLAGS.
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-namespace pcrecpp {
- class RE { static int no_arg; };
- int RE::no_arg;
- }
-int
-main ()
-{
-
- ;
- 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 "echo \"\$as_me:$LINENO: $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
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_cxx_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- { echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6; };
- EXTRA_LIBPCRECPP_LDFLAGS="$EXTRA_LIBPCRECPP_LDFLAGS -Wl,$flag";
- break;
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
-done
-LDFLAGS="$OLD_LDFLAGS"
-
-# We could be more clever here, given we're doing AC_SUBST with this
-# (eg set a var to be the name of the include file we want). But we're not
-# so it's easy to change back to 'regular' autoconf vars if we needed to.
-
-
-for ac_header in string
-do
-as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- { echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking $ac_header usability" >&5
-echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&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 "echo \"\$as_me:$LINENO: $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
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_cxx_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- 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
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking $ac_header presence" >&5
-echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&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 "echo \"\$as_me:$LINENO: $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
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- 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
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_cxx_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
-echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
-
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- eval "$as_ac_Header=\$ac_header_preproc"
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
- cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
-_ACEOF
- pcre_have_cpp_headers="1"
-else
- pcre_have_cpp_headers="0"
-fi
-
-done
-
-
-for ac_header in bits/type_traits.h
-do
-as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- { echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking $ac_header usability" >&5
-echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&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 "echo \"\$as_me:$LINENO: $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
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_cxx_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- 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
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking $ac_header presence" >&5
-echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&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 "echo \"\$as_me:$LINENO: $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
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- 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
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_cxx_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
-echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
-
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- eval "$as_ac_Header=\$ac_header_preproc"
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
- cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
-_ACEOF
- pcre_have_bits_type_traits="1"
-else
- pcre_have_bits_type_traits="0"
-fi
-
-done
-
-
-for ac_header in type_traits.h
-do
-as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- { echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking $ac_header usability" >&5
-echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&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 "echo \"\$as_me:$LINENO: $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
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_cxx_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_header_compiler=yes
-else
- 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
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking $ac_header presence" >&5
-echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&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 "echo \"\$as_me:$LINENO: $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
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null && {
- test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" ||
- test ! -s conftest.err
- }; then
- ac_header_preproc=yes
-else
- 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
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_cxx_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
-echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
-
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- eval "$as_ac_Header=\$ac_header_preproc"
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
- cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
-_ACEOF
- pcre_have_type_traits="1"
-else
- pcre_have_type_traits="0"
-fi
-
-done
-
-
-ac_ext=c
-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
-
-fi
-# Using AC_SUBST eliminates the need to include config.h in a public .h file
-
-
-
-# Conditional compilation
- if test "x$enable_cpp" = "xyes"; then
- WITH_PCRE_CPP_TRUE=
- WITH_PCRE_CPP_FALSE='#'
-else
- WITH_PCRE_CPP_TRUE='#'
- WITH_PCRE_CPP_FALSE=
-fi
-
- if test "x$enable_rebuild_chartables" = "xyes"; then
- WITH_REBUILD_CHARTABLES_TRUE=
- WITH_REBUILD_CHARTABLES_FALSE='#'
-else
- WITH_REBUILD_CHARTABLES_TRUE='#'
- WITH_REBUILD_CHARTABLES_FALSE=
-fi
-
-
-# Checks for typedefs, structures, and compiler characteristics.
-
-{ echo "$as_me:$LINENO: checking for an ANSI C-conforming const" >&5
-echo $ECHO_N "checking for an ANSI C-conforming const... $ECHO_C" >&6; }
-if test "${ac_cv_c_const+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-int
-main ()
-{
-/* FIXME: Include the comments suggested by Paul. */
-#ifndef __cplusplus
- /* Ultrix mips cc rejects this. */
- typedef int charset[2];
- const charset cs;
- /* SunOS 4.1.1 cc rejects this. */
- char const *const *pcpcc;
- char **ppc;
- /* NEC SVR4.0.2 mips cc rejects this. */
- struct point {int x, y;};
- static struct point const zero = {0,0};
- /* AIX XL C 1.02.0.0 rejects this.
- It does not let you subtract one const X* pointer from another in
- an arm of an if-expression whose if-part is not a constant
- expression */
- const char *g = "string";
- pcpcc = &g + (g ? g-g : 0);
- /* HPUX 7.0 cc rejects these. */
- ++pcpcc;
- ppc = (char**) pcpcc;
- pcpcc = (char const *const *) ppc;
- { /* SCO 3.2v4 cc rejects this. */
- char *t;
- char const *s = 0 ? (char *) 0 : (char const *) 0;
-
- *t++ = 0;
- if (s) return 0;
- }
- { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */
- int x[] = {25, 17};
- const int *foo = &x[0];
- ++foo;
- }
- { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
- typedef const int *iptr;
- iptr p = 0;
- ++p;
- }
- { /* AIX XL C 1.02.0.0 rejects this saying
- "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
- struct s { int j; const int *ap[3]; };
- struct s *b; b->j = 5;
- }
- { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
- const int foo = 10;
- if (!foo) return 0;
- }
- return !cs[0] && !zero.x;
-#endif
-
- ;
- 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 "echo \"\$as_me:$LINENO: $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
- 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_c_const=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_c_const=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_c_const" >&5
-echo "${ECHO_T}$ac_cv_c_const" >&6; }
-if test $ac_cv_c_const = no; then
-
-cat >>confdefs.h <<\_ACEOF
-#define const
-_ACEOF
-
-fi
-
-{ echo "$as_me:$LINENO: checking for size_t" >&5
-echo $ECHO_N "checking for size_t... $ECHO_C" >&6; }
-if test "${ac_cv_type_size_t+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&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
-typedef size_t ac__type_new_;
-int
-main ()
-{
-if ((ac__type_new_ *) 0)
- return 0;
-if (sizeof (ac__type_new_))
- 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 "echo \"\$as_me:$LINENO: $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
- 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_type_size_t=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_type_size_t=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_type_size_t" >&5
-echo "${ECHO_T}$ac_cv_type_size_t" >&6; }
-if test $ac_cv_type_size_t = yes; then
- :
-else
-
-cat >>confdefs.h <<_ACEOF
-#define size_t unsigned int
-_ACEOF
-
-fi
-
-
-pcre_have_strotolonglong=0
-
-
-
-for ac_func in strtoq strtoll _strtoi64
-do
-as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
-{ echo "$as_me:$LINENO: checking for $ac_func" >&5
-echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; }
-if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&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 <limits.h> declares $ac_func.
- For example, HP-UX 11i <limits.h> 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 <limits.h> to <assert.h> if __STDC__ is defined, since
- <limits.h> exists even on freestanding compilers. */
-
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#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 "echo \"\$as_me:$LINENO: $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
- 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 &&
- $as_test_x conftest$ac_exeext; then
- eval "$as_ac_var=yes"
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- eval "$as_ac_var=no"
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
-fi
-ac_res=`eval echo '${'$as_ac_var'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-if test `eval echo '${'$as_ac_var'}'` = yes; then
- cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
-_ACEOF
- pcre_have_strotolonglong="1"; break
-fi
-done
-
-# If we can't convert a string to a long long, pretend we don't even
-# have a long long.
-if test $pcre_have_strotolonglong = "0"; then
- pcre_have_long_long="0"
- pcre_have_ulong_long="0"
-else
- { echo "$as_me:$LINENO: checking for long long" >&5
-echo $ECHO_N "checking for long long... $ECHO_C" >&6; }
-if test "${ac_cv_type_long_long+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&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
-typedef long long ac__type_new_;
-int
-main ()
-{
-if ((ac__type_new_ *) 0)
- return 0;
-if (sizeof (ac__type_new_))
- 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 "echo \"\$as_me:$LINENO: $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
- 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_type_long_long=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_type_long_long=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_type_long_long" >&5
-echo "${ECHO_T}$ac_cv_type_long_long" >&6; }
-if test $ac_cv_type_long_long = yes; then
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_LONG_LONG 1
-_ACEOF
-
-pcre_have_long_long="1"
-else
- pcre_have_long_long="0"
-fi
-
- { echo "$as_me:$LINENO: checking for unsigned long long" >&5
-echo $ECHO_N "checking for unsigned long long... $ECHO_C" >&6; }
-if test "${ac_cv_type_unsigned_long_long+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&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
-typedef unsigned long long ac__type_new_;
-int
-main ()
-{
-if ((ac__type_new_ *) 0)
- return 0;
-if (sizeof (ac__type_new_))
- 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 "echo \"\$as_me:$LINENO: $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
- 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_type_unsigned_long_long=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_type_unsigned_long_long=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_type_unsigned_long_long" >&5
-echo "${ECHO_T}$ac_cv_type_unsigned_long_long" >&6; }
-if test $ac_cv_type_unsigned_long_long = yes; then
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_UNSIGNED_LONG_LONG 1
-_ACEOF
-
-pcre_have_ulong_long="1"
-else
- pcre_have_ulong_long="0"
-fi
-
-fi
-
-
-
-# Checks for library functions.
-
-
-
-
-for ac_func in bcopy memmove strerror
-do
-as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
-{ echo "$as_me:$LINENO: checking for $ac_func" >&5
-echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; }
-if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&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 <limits.h> declares $ac_func.
- For example, HP-UX 11i <limits.h> 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 <limits.h> to <assert.h> if __STDC__ is defined, since
- <limits.h> exists even on freestanding compilers. */
-
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#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 "echo \"\$as_me:$LINENO: $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
- 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 &&
- $as_test_x conftest$ac_exeext; then
- eval "$as_ac_var=yes"
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- eval "$as_ac_var=no"
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
-fi
-ac_res=`eval echo '${'$as_ac_var'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-if test `eval echo '${'$as_ac_var'}'` = yes; then
- cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
-_ACEOF
-
-fi
-done
-
-
-# Check for the availability of libz (aka zlib)
-
-
-for ac_header in zlib.h
-do
-as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- { echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking $ac_header usability" >&5
-echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&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 "echo \"\$as_me:$LINENO: $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
- 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
- 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
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking $ac_header presence" >&5
-echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&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 "echo \"\$as_me:$LINENO: $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
- 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
- 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
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
-echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
-
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- eval "$as_ac_Header=\$ac_header_preproc"
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
- cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
-_ACEOF
- HAVE_ZLIB_H=1
-fi
-
-done
-
-{ echo "$as_me:$LINENO: checking for gzopen in -lz" >&5
-echo $ECHO_N "checking for gzopen in -lz... $ECHO_C" >&6; }
-if test "${ac_cv_lib_z_gzopen+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lz $LIBS"
-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.
- 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 gzopen ();
-int
-main ()
-{
-return gzopen ();
- ;
- 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 "echo \"\$as_me:$LINENO: $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
- 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 &&
- $as_test_x conftest$ac_exeext; then
- ac_cv_lib_z_gzopen=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_lib_z_gzopen=no
-fi
-
-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
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_z_gzopen" >&5
-echo "${ECHO_T}$ac_cv_lib_z_gzopen" >&6; }
-if test $ac_cv_lib_z_gzopen = yes; then
- HAVE_LIBZ=1
-fi
-
-
-# Check for the availability of libbz2
-
-
-for ac_header in bzlib.h
-do
-as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- { echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking $ac_header usability" >&5
-echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&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 "echo \"\$as_me:$LINENO: $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
- 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
- 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
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking $ac_header presence" >&5
-echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&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 "echo \"\$as_me:$LINENO: $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
- 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
- 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
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
-echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
-
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- eval "$as_ac_Header=\$ac_header_preproc"
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
- cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
-_ACEOF
- HAVE_BZLIB_H=1
-fi
-
-done
-
-{ echo "$as_me:$LINENO: checking for BZ2_bzopen in -lbz2" >&5
-echo $ECHO_N "checking for BZ2_bzopen in -lbz2... $ECHO_C" >&6; }
-if test "${ac_cv_lib_bz2_BZ2_bzopen+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lbz2 $LIBS"
-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.
- 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 BZ2_bzopen ();
-int
-main ()
-{
-return BZ2_bzopen ();
- ;
- 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 "echo \"\$as_me:$LINENO: $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
- 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 &&
- $as_test_x conftest$ac_exeext; then
- ac_cv_lib_bz2_BZ2_bzopen=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_lib_bz2_BZ2_bzopen=no
-fi
-
-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
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_bz2_BZ2_bzopen" >&5
-echo "${ECHO_T}$ac_cv_lib_bz2_BZ2_bzopen" >&6; }
-if test $ac_cv_lib_bz2_BZ2_bzopen = yes; then
- HAVE_LIBBZ2=1
-fi
-
-
-# Check for the availabiity of libreadline
-
-
-for ac_header in readline/readline.h
-do
-as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- { echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking $ac_header usability" >&5
-echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&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 "echo \"\$as_me:$LINENO: $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
- 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
- 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
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking $ac_header presence" >&5
-echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&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 "echo \"\$as_me:$LINENO: $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
- 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
- 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
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
-echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
-
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- eval "$as_ac_Header=\$ac_header_preproc"
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
- cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
-_ACEOF
- HAVE_READLINE_H=1
-fi
-
-done
-
-
-for ac_header in readline/history.h
-do
-as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- { echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-else
- # Is the header compilable?
-{ echo "$as_me:$LINENO: checking $ac_header usability" >&5
-echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&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 "echo \"\$as_me:$LINENO: $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
- 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
- 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
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking $ac_header presence" >&5
-echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&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 "echo \"\$as_me:$LINENO: $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
- 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
- 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
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
-echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
-
- ;;
-esac
-{ echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- eval "$as_ac_Header=\$ac_header_preproc"
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
- { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
- cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
-_ACEOF
- HAVE_HISTORY_H=1
-fi
-
-done
-
-{ echo "$as_me:$LINENO: checking for readline in -lreadline" >&5
-echo $ECHO_N "checking for readline in -lreadline... $ECHO_C" >&6; }
-if test "${ac_cv_lib_readline_readline+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lreadline $LIBS"
-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.
- 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 readline ();
-int
-main ()
-{
-return readline ();
- ;
- 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 "echo \"\$as_me:$LINENO: $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
- 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 &&
- $as_test_x conftest$ac_exeext; then
- ac_cv_lib_readline_readline=yes
-else
- 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_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_readline_readline" >&5
-echo "${ECHO_T}$ac_cv_lib_readline_readline" >&6; }
-if test $ac_cv_lib_readline_readline = yes; then
- HAVE_LIB_READLINE=1
-fi
-
-
-# This facilitates -ansi builds under Linux
-
-if test "x$enable_shared" = "xno" ; then
-
-cat >>confdefs.h <<\_ACEOF
-#define PCRE_STATIC 1
-_ACEOF
-
-fi
-
-# Here is where pcre specific defines are handled
-
-if test "$enable_utf8" = "yes"; then
-
-cat >>confdefs.h <<\_ACEOF
-#define SUPPORT_UTF8
-_ACEOF
-
-fi
-
-if test "$enable_unicode_properties" = "yes"; then
-
-cat >>confdefs.h <<\_ACEOF
-#define SUPPORT_UCP
-_ACEOF
-
-fi
-
-if test "$enable_stack_for_recursion" = "no"; then
-
-cat >>confdefs.h <<\_ACEOF
-#define NO_RECURSE
-_ACEOF
-
-fi
-
-if test "$enable_pcregrep_libz" = "yes"; then
-
-cat >>confdefs.h <<\_ACEOF
-#define SUPPORT_LIBZ
-_ACEOF
-
-fi
-
-if test "$enable_pcregrep_libbz2" = "yes"; then
-
-cat >>confdefs.h <<\_ACEOF
-#define SUPPORT_LIBBZ2
-_ACEOF
-
-fi
-
-if test "$enable_pcretest_libreadline" = "yes"; then
-
-cat >>confdefs.h <<\_ACEOF
-#define SUPPORT_LIBREADLINE
-_ACEOF
-
-fi
-
-
-cat >>confdefs.h <<_ACEOF
-#define NEWLINE $ac_pcre_newline_value
-_ACEOF
-
-
-if test "$enable_bsr_anycrlf" = "yes"; then
-
-cat >>confdefs.h <<\_ACEOF
-#define BSR_ANYCRLF
-_ACEOF
-
-fi
-
-
-cat >>confdefs.h <<_ACEOF
-#define LINK_SIZE $with_link_size
-_ACEOF
-
-
-
-cat >>confdefs.h <<_ACEOF
-#define POSIX_MALLOC_THRESHOLD $with_posix_malloc_threshold
-_ACEOF
-
-
-
-cat >>confdefs.h <<_ACEOF
-#define MATCH_LIMIT $with_match_limit
-_ACEOF
-
-
-
-cat >>confdefs.h <<_ACEOF
-#define MATCH_LIMIT_RECURSION $with_match_limit_recursion
-_ACEOF
-
-
-
-cat >>confdefs.h <<\_ACEOF
-#define MAX_NAME_SIZE 32
-_ACEOF
-
-
-
-cat >>confdefs.h <<\_ACEOF
-#define MAX_NAME_COUNT 10000
-_ACEOF
-
-
-
-
-
-if test "$enable_ebcdic" = "yes"; then
-
-cat >>confdefs.h <<_ACEOF
-#define EBCDIC
-_ACEOF
-
-fi
-
-# Platform specific issues
-NO_UNDEFINED=
-EXPORT_ALL_SYMBOLS=
-case $host_os in
- cygwin* | mingw* )
- if test X"$enable_shared" = Xyes; then
- NO_UNDEFINED="-no-undefined"
- EXPORT_ALL_SYMBOLS="-Wl,--export-all-symbols"
- fi
- ;;
-esac
-
-# The extra LDFLAGS for each particular library
-# (Note: The libpcre*_version bits are m4 variables, assigned above)
-
-EXTRA_LIBPCRE_LDFLAGS="$EXTRA_LIBPCRE_LDFLAGS \
- $NO_UNDEFINED -version-info 0:1:0"
-
-EXTRA_LIBPCREPOSIX_LDFLAGS="$EXTRA_LIBPCREPOSIX_LDFLAGS \
- $NO_UNDEFINED -version-info 0:0:0"
-
-EXTRA_LIBPCRECPP_LDFLAGS="$EXTRA_LIBPCRECPP_LDFLAGS \
- $NO_UNDEFINED -version-info 0:0:0 \
- $EXPORT_ALL_SYMBOLS"
-
-
-
-
-
-# When we run 'make distcheck', use these arguments.
-DISTCHECK_CONFIGURE_FLAGS="--enable-cpp --enable-unicode-properties"
-
-
-# Check that, if --enable-pcregrep-libz or --enable-pcregrep-libbz2 is
-# specified, the relevant library is available. If so, add it to LIBS.
-
-if test "$enable_pcregrep_libz" = "yes"; then
- if test "$HAVE_ZLIB_H" != "1"; then
- echo "** Cannot --enable-pcregrep-libz because zlib.h was not found"
- exit 1
- fi
- if test "$HAVE_LIBZ" != "1"; then
- echo "** Cannot --enable-pcregrep-libz because libz was not found"
- exit 1
- fi
- if test "$LIBS" = ""; then LIBS=-lz; else LIBS="$LIBS -lz"; fi
-fi
-
-if test "$enable_pcregrep_libbz2" = "yes"; then
- if test "$HAVE_BZLIB_H" != "1"; then
- echo "** Cannot --enable-pcregrep-libbz2 because bzlib.h was not found"
- exit 1
- fi
- if test "$HAVE_LIBBZ2" != "1"; then
- echo "** Cannot --enable-pcregrep-libbz2 because libbz2 was not found"
- exit 1
- fi
- if test "$LIBS" = ""; then LIBS=-lbz2; else LIBS="$LIBS -lbz2"; fi
-fi
-
-# Similarly for --enable-pcretest-readline
-
-if test "$enable_pcretest_libreadline" = "yes"; then
- if test "$HAVE_READLINE_H" != "1"; then
- echo "** Cannot --enable-pcretest-readline because readline/readline.h was not found."
- exit 1
- fi
- if test "$HAVE_HISTORY_H" != "1"; then
- echo "** Cannot --enable-pcretest-readline because readline/history.h was not found."
- exit 1
- fi
- if test "$LIBS" = ""; then LIBS=-lreadline; else LIBS="$LIBS -lreadline"; fi
-fi
-
-# Produce these files, in addition to config.h.
-ac_config_files="$ac_config_files Makefile libpcre.pc libpcrecpp.pc pcre-config pcre.h pcre_stringpiece.h pcrecpparg.h"
-
-
-# Make the generated script files executable.
-ac_config_commands="$ac_config_commands script-chmod"
-
-
-# Make sure that pcre_chartables.c is removed in case the method for
-# creating it was changed by reconfiguration.
-ac_config_commands="$ac_config_commands delete-old-chartables"
-
-
-cat >confcache <<\_ACEOF
-# This file is a shell script that caches the results of configure
-# tests run on this system so they can be shared between configure
-# scripts and configure runs, see configure's option --config-cache.
-# It is not useful on other systems. If it contains results you don't
-# want to keep, you may remove or edit it.
-#
-# config.status only pays attention to the cache file if you give it
-# the --recheck option to rerun configure.
-#
-# `ac_cv_env_foo' variables (set or unset) will be overridden when
-# loading this file, other *unset* `ac_cv_foo' will be assigned the
-# following values.
-
-_ACEOF
-
-# The following way of writing the cache mishandles newlines in values,
-# but we know of no workaround that is simple, portable, and efficient.
-# So, we kill variables containing newlines.
-# Ultrix sh set writes to stderr and can't be redirected directly,
-# and sets the high bit in the cache file unless we assign to the vars.
-(
- for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
- eval ac_val=\$$ac_var
- case $ac_val in #(
- *${as_nl}*)
- case $ac_var in #(
- *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5
-echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;;
- esac
- case $ac_var in #(
- _ | IFS | as_nl) ;; #(
- *) $as_unset $ac_var ;;
- esac ;;
- esac
- done
-
- (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 \).
- sed -n \
- "s/'/'\\\\''/g;
- s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
- ;; #(
- *)
- # `set' quotes correctly as required by POSIX, so do not add quotes.
- sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
- ;;
- esac |
- sort
-) |
- sed '
- /^ac_cv_env_/b end
- t clear
- :clear
- s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
- t end
- s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
- :end' >>confcache
-if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
- if test -w "$cache_file"; then
- test "x$cache_file" != "x/dev/null" &&
- { echo "$as_me:$LINENO: updating cache $cache_file" >&5
-echo "$as_me: updating cache $cache_file" >&6;}
- cat confcache >$cache_file
- else
- { echo "$as_me:$LINENO: not updating unwritable cache $cache_file" >&5
-echo "$as_me: not updating unwritable cache $cache_file" >&6;}
- fi
-fi
-rm -f confcache
-
-test "x$prefix" = xNONE && prefix=$ac_default_prefix
-# Let make expand exec_prefix.
-test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
-
-DEFS=-DHAVE_CONFIG_H
-
-ac_libobjs=
-ac_ltlibobjs=
-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=`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.
- ac_libobjs="$ac_libobjs \${LIBOBJDIR}$ac_i\$U.$ac_objext"
- ac_ltlibobjs="$ac_ltlibobjs \${LIBOBJDIR}$ac_i"'$U.lo'
-done
-LIBOBJS=$ac_libobjs
-
-LTLIBOBJS=$ac_ltlibobjs
-
-
-if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then
- { { echo "$as_me:$LINENO: error: conditional \"AMDEP\" was never defined.
-Usually this means the macro was only invoked conditionally." >&5
-echo "$as_me: error: conditional \"AMDEP\" was never defined.
-Usually this means the macro was only invoked conditionally." >&2;}
- { (exit 1); exit 1; }; }
-fi
-if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then
- { { echo "$as_me:$LINENO: error: conditional \"am__fastdepCC\" was never defined.
-Usually this means the macro was only invoked conditionally." >&5
-echo "$as_me: error: conditional \"am__fastdepCC\" was never defined.
-Usually this means the macro was only invoked conditionally." >&2;}
- { (exit 1); exit 1; }; }
-fi
-if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then
- { { echo "$as_me:$LINENO: error: conditional \"am__fastdepCXX\" was never defined.
-Usually this means the macro was only invoked conditionally." >&5
-echo "$as_me: error: conditional \"am__fastdepCXX\" was never defined.
-Usually this means the macro was only invoked conditionally." >&2;}
- { (exit 1); exit 1; }; }
-fi
-if test -z "${WITH_PCRE_CPP_TRUE}" && test -z "${WITH_PCRE_CPP_FALSE}"; then
- { { echo "$as_me:$LINENO: error: conditional \"WITH_PCRE_CPP\" was never defined.
-Usually this means the macro was only invoked conditionally." >&5
-echo "$as_me: error: conditional \"WITH_PCRE_CPP\" was never defined.
-Usually this means the macro was only invoked conditionally." >&2;}
- { (exit 1); exit 1; }; }
-fi
-if test -z "${WITH_REBUILD_CHARTABLES_TRUE}" && test -z "${WITH_REBUILD_CHARTABLES_FALSE}"; then
- { { echo "$as_me:$LINENO: error: conditional \"WITH_REBUILD_CHARTABLES\" was never defined.
-Usually this means the macro was only invoked conditionally." >&5
-echo "$as_me: error: conditional \"WITH_REBUILD_CHARTABLES\" was never defined.
-Usually this means the macro was only invoked conditionally." >&2;}
- { (exit 1); exit 1; }; }
-fi
-
-: ${CONFIG_STATUS=./config.status}
-ac_clean_files_save=$ac_clean_files
-ac_clean_files="$ac_clean_files $CONFIG_STATUS"
-{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5
-echo "$as_me: creating $CONFIG_STATUS" >&6;}
-cat >$CONFIG_STATUS <<_ACEOF
-#! $SHELL
-# Generated by $as_me.
-# Run this file to recreate the current configuration.
-# Compiler output produced by configure, useful for debugging
-# configure, is in config.log if it exists.
-
-debug=false
-ac_cs_recheck=false
-ac_cs_silent=false
-SHELL=\${CONFIG_SHELL-$SHELL}
-_ACEOF
-
-cat >>$CONFIG_STATUS <<\_ACEOF
-## --------------------- ##
-## 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
- emulate sh
- NULLCMD=:
- # Zsh 3.x and 4.x performs 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
-
-
-
-
-# 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
-
-# The user is always right.
-if test "${PATH_SEPARATOR+set}" != set; then
- echo "#! /bin/sh" >conf$$.sh
- echo "exit 0" >>conf$$.sh
- chmod +x conf$$.sh
- if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
- PATH_SEPARATOR=';'
- else
- PATH_SEPARATOR=:
- fi
- rm -f conf$$.sh
-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
-# there to prevent editors from complaining about space-tab.
-# (If _AS_PATH_WALK were called with IFS unset, it would disable word
-# splitting by setting IFS to empty value.)
-as_nl='
-'
-IFS=" "" $as_nl"
-
-# Find who we are. Look in the path if we contain no directory separator.
-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
-IFS=$as_save_IFS
-
- ;;
-esac
-# We did not find ourselves, most probably we were run as `sh COMMAND'
-# in which case we are not to be found in the path.
-if test "x$as_myself" = x; then
- as_myself=$0
-fi
-if test ! -f "$as_myself"; then
- echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
- { (exit 1); exit 1; }
-fi
-
-# 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='> '
-PS4='+ '
-
-# NLS nuisances.
-for as_var in \
- LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
- LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
- LC_TELEPHONE LC_TIME
-do
- if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
- eval $as_var=C; export $as_var
- else
- ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
- fi
-done
-
-# Required to use basename.
-if expr a : '\(a\)' >/dev/null 2>&1 &&
- test "X`expr 00001 : '.*\(...\)'`" = X001; then
- as_expr=expr
-else
- as_expr=false
-fi
-
-if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
- as_basename=basename
-else
- as_basename=false
-fi
-
-
-# Name of the executable.
-as_me=`$as_basename -- "$0" ||
-$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
- X"$0" : 'X\(//\)$' \| \
- X"$0" : 'X\(/\)' \| . 2>/dev/null ||
-echo X/"$0" |
- sed '/^.*\/\([^/][^/]*\)\/*$/{
- s//\1/
- q
- }
- /^X\/\(\/\/\)$/{
- s//\1/
- q
- }
- /^X\/\(\/\).*/{
- s//\1/
- q
- }
- s/.*/./; q'`
-
-# 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" ||
- { 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
--n*)
- case `echo 'x\c'` in
- *c*) ECHO_T=' ';; # ECHO_T is single tab character.
- *) 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
- rm -f conf$$.dir/conf$$.file
-else
- rm -f conf$$.dir
- mkdir conf$$.dir
-fi
-echo >conf$$.file
-if ln -s conf$$.file conf$$ 2>/dev/null; then
- as_ln_s='ln -s'
- # ... but there are two gotchas:
- # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
- # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
- # In both cases, we have to default to `cp -p'.
- ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
- as_ln_s='cp -p'
-elif ln conf$$.file conf$$ 2>/dev/null; then
- as_ln_s=ln
-else
- as_ln_s='cp -p'
-fi
-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=:
-else
- test -d ./-p && rmdir ./-p
- as_mkdir_p=false
-fi
-
-if test -x / >/dev/null 2>&1; then
- as_test_x='test -x'
-else
- if ls -dL / >/dev/null 2>&1; then
- as_ls_L_option=L
- else
- as_ls_L_option=
- fi
- as_test_x='
- eval sh -c '\''
- if test -d "$1"; then
- test -d "$1/.";
- else
- case $1 in
- -*)set "./$1";;
- esac;
- case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in
- ???[sx]*):;;*)false;;esac;fi
- '\'' sh
- '
-fi
-as_executable_p=$as_test_x
-
-# Sed expression to map a string onto a valid CPP name.
-as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
-
-# Sed expression to map a string onto a valid variable name.
-as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
-
-
-exec 6>&1
-
-# 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 PCRE $as_me 7.7, which was
-generated by GNU Autoconf 2.61. Invocation command line was
-
- CONFIG_FILES = $CONFIG_FILES
- CONFIG_HEADERS = $CONFIG_HEADERS
- CONFIG_LINKS = $CONFIG_LINKS
- CONFIG_COMMANDS = $CONFIG_COMMANDS
- $ $0 $@
-
-on `(hostname || uname -n) 2>/dev/null | sed 1q`
-"
-
-_ACEOF
-
-cat >>$CONFIG_STATUS <<_ACEOF
-# Files that config.status was made for.
-config_files="$ac_config_files"
-config_headers="$ac_config_headers"
-config_commands="$ac_config_commands"
-
-_ACEOF
-
-cat >>$CONFIG_STATUS <<\_ACEOF
-ac_cs_usage="\
-\`$as_me' instantiates files from templates according to the
-current configuration.
-
-Usage: $0 [OPTIONS] [FILE]...
-
- -h, --help print this help, then exit
- -V, --version print version number and configuration settings, then exit
- -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]
- instantiate the configuration file FILE
- --header=FILE[:TEMPLATE]
- instantiate the configuration header FILE
-
-Configuration files:
-$config_files
-
-Configuration headers:
-$config_headers
-
-Configuration commands:
-$config_commands
-
-Report bugs to <bug-autoconf@gnu.org>."
-
-_ACEOF
-cat >>$CONFIG_STATUS <<_ACEOF
-ac_cs_version="\\
-PCRE config.status 7.7
-configured by $0, generated by GNU Autoconf 2.61,
- with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
-
-Copyright (C) 2006 Free Software Foundation, Inc.
-This config.status script is free software; the Free Software Foundation
-gives unlimited permission to copy, distribute and modify it."
-
-ac_pwd='$ac_pwd'
-srcdir='$srcdir'
-INSTALL='$INSTALL'
-MKDIR_P='$MKDIR_P'
-_ACEOF
-
-cat >>$CONFIG_STATUS <<\_ACEOF
-# If no file are specified by the user, then we need to provide default
-# value. By we need to know if files were specified by the user.
-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=$1
- ac_optarg=$2
- ac_shift=shift
- ;;
- esac
-
- case $ac_option in
- # Handling of the options.
- -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
- ac_cs_recheck=: ;;
- --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
- echo "$ac_cs_version"; exit ;;
- --debug | --debu | --deb | --de | --d | -d )
- debug=: ;;
- --file | --fil | --fi | --f )
- $ac_shift
- CONFIG_FILES="$CONFIG_FILES $ac_optarg"
- ac_need_defaults=false;;
- --header | --heade | --head | --hea )
- $ac_shift
- CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg"
- ac_need_defaults=false;;
- --he | --h)
- # Conflict between --help and --header
- { echo "$as_me: error: ambiguous option: $1
-Try \`$0 --help' for more information." >&2
- { (exit 1); exit 1; }; };;
- --help | --hel | -h )
- echo "$ac_cs_usage"; exit ;;
- -q | -quiet | --quiet | --quie | --qui | --qu | --q \
- | -silent | --silent | --silen | --sile | --sil | --si | --s)
- ac_cs_silent=: ;;
-
- # This is an error.
- -*) { echo "$as_me: error: unrecognized option: $1
-Try \`$0 --help' for more information." >&2
- { (exit 1); exit 1; }; } ;;
-
- *) ac_config_targets="$ac_config_targets $1"
- ac_need_defaults=false ;;
-
- esac
- shift
-done
-
-ac_configure_extra_args=
-
-if $ac_cs_silent; then
- exec 6>/dev/null
- ac_configure_extra_args="$ac_configure_extra_args --silent"
-fi
-
-_ACEOF
-cat >>$CONFIG_STATUS <<_ACEOF
-if \$ac_cs_recheck; then
- echo "running CONFIG_SHELL=$SHELL $SHELL $0 "$ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6
- CONFIG_SHELL=$SHELL
- export CONFIG_SHELL
- exec $SHELL "$0"$ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
-fi
-
-_ACEOF
-cat >>$CONFIG_STATUS <<\_ACEOF
-exec 5>>config.log
-{
- echo
- sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
-## Running $as_me. ##
-_ASBOX
- echo "$ac_log"
-} >&5
-
-_ACEOF
-cat >>$CONFIG_STATUS <<_ACEOF
-#
-# INIT-COMMANDS
-#
-AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"
-
-_ACEOF
-
-cat >>$CONFIG_STATUS <<\_ACEOF
-
-# Handling of arguments.
-for ac_config_target in $ac_config_targets
-do
- case $ac_config_target in
- "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
- "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;;
- "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
- "libpcre.pc") CONFIG_FILES="$CONFIG_FILES libpcre.pc" ;;
- "libpcrecpp.pc") CONFIG_FILES="$CONFIG_FILES libpcrecpp.pc" ;;
- "pcre-config") CONFIG_FILES="$CONFIG_FILES pcre-config" ;;
- "pcre.h") CONFIG_FILES="$CONFIG_FILES pcre.h" ;;
- "pcre_stringpiece.h") CONFIG_FILES="$CONFIG_FILES pcre_stringpiece.h" ;;
- "pcrecpparg.h") CONFIG_FILES="$CONFIG_FILES pcrecpparg.h" ;;
- "script-chmod") CONFIG_COMMANDS="$CONFIG_COMMANDS script-chmod" ;;
- "delete-old-chartables") CONFIG_COMMANDS="$CONFIG_COMMANDS delete-old-chartables" ;;
-
- *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
-echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
- { (exit 1); exit 1; }; };;
- esac
-done
-
-
-# If the user did not use the arguments to specify the items to instantiate,
-# then the envvar interface is used. Set only those that are not.
-# We use the long form for the default assignment because of an extremely
-# bizarre bug on SunOS 4.1.3.
-if $ac_need_defaults; then
- test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
- test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
- test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands
-fi
-
-# Have a temporary directory for convenience. Make it in the build tree
-# simply because there is no reason against having it here, and in addition,
-# creating and moving files from /tmp can sometimes cause problems.
-# Hook for its removal unless debugging.
-# Note that there is a small window in which the directory will not be cleaned:
-# after its creation but before its name has been assigned to `$tmp'.
-$debug ||
-{
- tmp=
- trap 'exit_status=$?
- { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status
-' 0
- trap '{ (exit 1); exit 1; }' 1 2 13 15
-}
-# Create a (secure) tmp directory for tmp files.
-
-{
- tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
- test -n "$tmp" && test -d "$tmp"
-} ||
-{
- tmp=./conf$$-$RANDOM
- (umask 077 && mkdir "$tmp")
-} ||
-{
- echo "$me: cannot create a temporary directory in ." >&2
- { (exit 1); exit 1; }
-}
-
-#
-# Set up the sed scripts for CONFIG_FILES section.
-#
-
-# No need to generate the scripts if there are no CONFIG_FILES.
-# This happens for instance when ./config.status config.h
-if test -n "$CONFIG_FILES"; then
-
-_ACEOF
-
-
-
-ac_delim='%!_!# '
-for ac_last_try in false false false false false :; do
- cat >conf$$subs.sed <<_ACEOF
-SHELL!$SHELL$ac_delim
-PATH_SEPARATOR!$PATH_SEPARATOR$ac_delim
-PACKAGE_NAME!$PACKAGE_NAME$ac_delim
-PACKAGE_TARNAME!$PACKAGE_TARNAME$ac_delim
-PACKAGE_VERSION!$PACKAGE_VERSION$ac_delim
-PACKAGE_STRING!$PACKAGE_STRING$ac_delim
-PACKAGE_BUGREPORT!$PACKAGE_BUGREPORT$ac_delim
-exec_prefix!$exec_prefix$ac_delim
-prefix!$prefix$ac_delim
-program_transform_name!$program_transform_name$ac_delim
-bindir!$bindir$ac_delim
-sbindir!$sbindir$ac_delim
-libexecdir!$libexecdir$ac_delim
-datarootdir!$datarootdir$ac_delim
-datadir!$datadir$ac_delim
-sysconfdir!$sysconfdir$ac_delim
-sharedstatedir!$sharedstatedir$ac_delim
-localstatedir!$localstatedir$ac_delim
-includedir!$includedir$ac_delim
-oldincludedir!$oldincludedir$ac_delim
-docdir!$docdir$ac_delim
-infodir!$infodir$ac_delim
-htmldir!$htmldir$ac_delim
-dvidir!$dvidir$ac_delim
-pdfdir!$pdfdir$ac_delim
-psdir!$psdir$ac_delim
-libdir!$libdir$ac_delim
-localedir!$localedir$ac_delim
-mandir!$mandir$ac_delim
-DEFS!$DEFS$ac_delim
-ECHO_C!$ECHO_C$ac_delim
-ECHO_N!$ECHO_N$ac_delim
-ECHO_T!$ECHO_T$ac_delim
-LIBS!$LIBS$ac_delim
-build_alias!$build_alias$ac_delim
-host_alias!$host_alias$ac_delim
-target_alias!$target_alias$ac_delim
-INSTALL_PROGRAM!$INSTALL_PROGRAM$ac_delim
-INSTALL_SCRIPT!$INSTALL_SCRIPT$ac_delim
-INSTALL_DATA!$INSTALL_DATA$ac_delim
-am__isrc!$am__isrc$ac_delim
-CYGPATH_W!$CYGPATH_W$ac_delim
-PACKAGE!$PACKAGE$ac_delim
-VERSION!$VERSION$ac_delim
-ACLOCAL!$ACLOCAL$ac_delim
-AUTOCONF!$AUTOCONF$ac_delim
-AUTOMAKE!$AUTOMAKE$ac_delim
-AUTOHEADER!$AUTOHEADER$ac_delim
-MAKEINFO!$MAKEINFO$ac_delim
-install_sh!$install_sh$ac_delim
-STRIP!$STRIP$ac_delim
-INSTALL_STRIP_PROGRAM!$INSTALL_STRIP_PROGRAM$ac_delim
-mkdir_p!$mkdir_p$ac_delim
-AWK!$AWK$ac_delim
-SET_MAKE!$SET_MAKE$ac_delim
-am__leading_dot!$am__leading_dot$ac_delim
-AMTAR!$AMTAR$ac_delim
-am__tar!$am__tar$ac_delim
-am__untar!$am__untar$ac_delim
-CC!$CC$ac_delim
-CFLAGS!$CFLAGS$ac_delim
-LDFLAGS!$LDFLAGS$ac_delim
-CPPFLAGS!$CPPFLAGS$ac_delim
-ac_ct_CC!$ac_ct_CC$ac_delim
-EXEEXT!$EXEEXT$ac_delim
-OBJEXT!$OBJEXT$ac_delim
-DEPDIR!$DEPDIR$ac_delim
-am__include!$am__include$ac_delim
-am__quote!$am__quote$ac_delim
-AMDEP_TRUE!$AMDEP_TRUE$ac_delim
-AMDEP_FALSE!$AMDEP_FALSE$ac_delim
-AMDEPBACKSLASH!$AMDEPBACKSLASH$ac_delim
-CCDEPMODE!$CCDEPMODE$ac_delim
-am__fastdepCC_TRUE!$am__fastdepCC_TRUE$ac_delim
-am__fastdepCC_FALSE!$am__fastdepCC_FALSE$ac_delim
-CXX!$CXX$ac_delim
-CXXFLAGS!$CXXFLAGS$ac_delim
-ac_ct_CXX!$ac_ct_CXX$ac_delim
-CXXDEPMODE!$CXXDEPMODE$ac_delim
-am__fastdepCXX_TRUE!$am__fastdepCXX_TRUE$ac_delim
-am__fastdepCXX_FALSE!$am__fastdepCXX_FALSE$ac_delim
-build!$build$ac_delim
-build_cpu!$build_cpu$ac_delim
-build_vendor!$build_vendor$ac_delim
-build_os!$build_os$ac_delim
-host!$host$ac_delim
-host_cpu!$host_cpu$ac_delim
-host_vendor!$host_vendor$ac_delim
-host_os!$host_os$ac_delim
-SED!$SED$ac_delim
-GREP!$GREP$ac_delim
-EGREP!$EGREP$ac_delim
-LN_S!$LN_S$ac_delim
-ECHO!$ECHO$ac_delim
-AR!$AR$ac_delim
-RANLIB!$RANLIB$ac_delim
-DSYMUTIL!$DSYMUTIL$ac_delim
-_ACEOF
-
- if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 97; then
- break
- elif $ac_last_try; then
- { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
-echo "$as_me: error: could not make $CONFIG_STATUS" >&2;}
- { (exit 1); exit 1; }; }
- else
- ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
- fi
-done
-
-ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF/0/p' conf$$subs.sed`
-if test -n "$ac_eof"; then
- ac_eof=`echo "$ac_eof" | sort -nru | sed 1q`
- ac_eof=`expr $ac_eof + 1`
-fi
-
-cat >>$CONFIG_STATUS <<_ACEOF
-cat >"\$tmp/subs-1.sed" <<\CEOF$ac_eof
-/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
-_ACEOF
-sed '
-s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g
-s/^/s,@/; s/!/@,|#_!!_#|/
-:n
-t n
-s/'"$ac_delim"'$/,g/; t
-s/$/\\/; p
-N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n
-' >>$CONFIG_STATUS <conf$$subs.sed
-rm -f conf$$subs.sed
-cat >>$CONFIG_STATUS <<_ACEOF
-CEOF$ac_eof
-_ACEOF
-
-
-ac_delim='%!_!# '
-for ac_last_try in false false false false false :; do
- cat >conf$$subs.sed <<_ACEOF
-NMEDIT!$NMEDIT$ac_delim
-DLLTOOL!$DLLTOOL$ac_delim
-AS!$AS$ac_delim
-OBJDUMP!$OBJDUMP$ac_delim
-CPP!$CPP$ac_delim
-CXXCPP!$CXXCPP$ac_delim
-F77!$F77$ac_delim
-FFLAGS!$FFLAGS$ac_delim
-ac_ct_F77!$ac_ct_F77$ac_delim
-LIBTOOL!$LIBTOOL$ac_delim
-PCRE_MAJOR!$PCRE_MAJOR$ac_delim
-PCRE_MINOR!$PCRE_MINOR$ac_delim
-PCRE_PRERELEASE!$PCRE_PRERELEASE$ac_delim
-PCRE_DATE!$PCRE_DATE$ac_delim
-pcre_have_type_traits!$pcre_have_type_traits$ac_delim
-pcre_have_bits_type_traits!$pcre_have_bits_type_traits$ac_delim
-WITH_PCRE_CPP_TRUE!$WITH_PCRE_CPP_TRUE$ac_delim
-WITH_PCRE_CPP_FALSE!$WITH_PCRE_CPP_FALSE$ac_delim
-WITH_REBUILD_CHARTABLES_TRUE!$WITH_REBUILD_CHARTABLES_TRUE$ac_delim
-WITH_REBUILD_CHARTABLES_FALSE!$WITH_REBUILD_CHARTABLES_FALSE$ac_delim
-pcre_have_long_long!$pcre_have_long_long$ac_delim
-pcre_have_ulong_long!$pcre_have_ulong_long$ac_delim
-EXTRA_LIBPCRE_LDFLAGS!$EXTRA_LIBPCRE_LDFLAGS$ac_delim
-EXTRA_LIBPCREPOSIX_LDFLAGS!$EXTRA_LIBPCREPOSIX_LDFLAGS$ac_delim
-EXTRA_LIBPCRECPP_LDFLAGS!$EXTRA_LIBPCRECPP_LDFLAGS$ac_delim
-DISTCHECK_CONFIGURE_FLAGS!$DISTCHECK_CONFIGURE_FLAGS$ac_delim
-LIBOBJS!$LIBOBJS$ac_delim
-LTLIBOBJS!$LTLIBOBJS$ac_delim
-_ACEOF
-
- if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 28; then
- break
- elif $ac_last_try; then
- { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
-echo "$as_me: error: could not make $CONFIG_STATUS" >&2;}
- { (exit 1); exit 1; }; }
- else
- ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
- fi
-done
-
-ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF/0/p' conf$$subs.sed`
-if test -n "$ac_eof"; then
- ac_eof=`echo "$ac_eof" | sort -nru | sed 1q`
- ac_eof=`expr $ac_eof + 1`
-fi
-
-cat >>$CONFIG_STATUS <<_ACEOF
-cat >"\$tmp/subs-2.sed" <<\CEOF$ac_eof
-/@[a-zA-Z_][a-zA-Z_0-9]*@/!b end
-_ACEOF
-sed '
-s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g
-s/^/s,@/; s/!/@,|#_!!_#|/
-:n
-t n
-s/'"$ac_delim"'$/,g/; t
-s/$/\\/; p
-N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n
-' >>$CONFIG_STATUS <conf$$subs.sed
-rm -f conf$$subs.sed
-cat >>$CONFIG_STATUS <<_ACEOF
-:end
-s/|#_!!_#|//g
-CEOF$ac_eof
-_ACEOF
-
-
-# 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[ ]*=/{
-s/:*\$(srcdir):*/:/
-s/:*\${srcdir}:*/:/
-s/:*@srcdir@:*/:/
-s/^\([^=]*=[ ]*\):*/\1/
-s/:*$//
-s/^[^=]*=[ ]*$//
-}'
-fi
-
-cat >>$CONFIG_STATUS <<\_ACEOF
-fi # test -n "$CONFIG_FILES"
-
-
-for ac_tag in :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS
-do
- case $ac_tag in
- :[FHLC]) ac_mode=$ac_tag; continue;;
- esac
- case $ac_mode$ac_tag in
- :[FHL]*:*);;
- :L* | :C*:*) { { echo "$as_me:$LINENO: error: Invalid tag $ac_tag." >&5
-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
- ac_save_IFS=$IFS
- IFS=:
- set x $ac_tag
- IFS=$ac_save_IFS
- shift
- ac_file=$1
- shift
-
- case $ac_mode in
- :L) ac_source=$1;;
- :[FH])
- ac_file_inputs=
- for ac_f
- do
- case $ac_f in
- -) ac_f="$tmp/stdin";;
- *) # Look for the file first in the build tree, then in the source tree
- # (if the path is not absolute). The absolute path cannot be DOS-style,
- # because $ac_f cannot contain `:'.
- test -f "$ac_f" ||
- case $ac_f in
- [\\/$]*) false;;
- *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
- esac ||
- { { echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5
-echo "$as_me: error: cannot find input file: $ac_f" >&2;}
- { (exit 1); exit 1; }; };;
- esac
- ac_file_inputs="$ac_file_inputs $ac_f"
- done
-
- # Let's still pretend it is `configure' which instantiates (i.e., don't
- # use $as_me), people would be surprised to read:
- # /* config.h. Generated by config.status. */
- configure_input="Generated from "`IFS=:
- echo $* | sed 's|^[^:]*/||;s|:[^:]*/|, |g'`" by configure."
- if test x"$ac_file" != x-; then
- configure_input="$ac_file. $configure_input"
- { echo "$as_me:$LINENO: creating $ac_file" >&5
-echo "$as_me: creating $ac_file" >&6;}
- fi
-
- case $ac_tag in
- *:-:* | *:-) cat >"$tmp/stdin";;
- esac
- ;;
- esac
-
- ac_dir=`$as_dirname -- "$ac_file" ||
-$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
- X"$ac_file" : 'X\(//\)[^/]' \| \
- X"$ac_file" : 'X\(//\)$' \| \
- X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
-echo X"$ac_file" |
- sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
- s//\1/
- q
- }
- /^X\(\/\/\)[^/].*/{
- s//\1/
- q
- }
- /^X\(\/\/\)$/{
- s//\1/
- q
- }
- /^X\(\/\).*/{
- s//\1/
- q
- }
- s/.*/./; q'`
- { 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=`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 ||
-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" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5
-echo "$as_me: error: cannot create directory $as_dir" >&2;}
- { (exit 1); exit 1; }; }; }
- ac_builddir=.
-
-case "$ac_dir" in
-.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
-*)
- ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
- # A ".." for each directory in $ac_dir_suffix.
- ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'`
- case $ac_top_builddir_sub in
- "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
- *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
- esac ;;
-esac
-ac_abs_top_builddir=$ac_pwd
-ac_abs_builddir=$ac_pwd$ac_dir_suffix
-# for backward compatibility:
-ac_top_builddir=$ac_top_build_prefix
-
-case $srcdir in
- .) # We are building in place.
- ac_srcdir=.
- ac_top_srcdir=$ac_top_builddir_sub
- ac_abs_top_srcdir=$ac_pwd ;;
- [\\/]* | ?:[\\/]* ) # Absolute name.
- ac_srcdir=$srcdir$ac_dir_suffix;
- ac_top_srcdir=$srcdir
- ac_abs_top_srcdir=$srcdir ;;
- *) # Relative name.
- ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
- ac_top_srcdir=$ac_top_build_prefix$srcdir
- ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
-esac
-ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
-
-
- case $ac_mode in
- :F)
- #
- # CONFIG_FILE
- #
-
- case $INSTALL in
- [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
- *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;;
- esac
- ac_MKDIR_P=$MKDIR_P
- case $MKDIR_P in
- [\\/$]* | ?:[\\/]* ) ;;
- */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;;
- esac
-_ACEOF
-
-cat >>$CONFIG_STATUS <<\_ACEOF
-# 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=
-
-case `sed -n '/datarootdir/ {
- p
- q
-}
-/@datadir@/p
-/@docdir@/p
-/@infodir@/p
-/@localedir@/p
-/@mandir@/p
-' $ac_file_inputs` in
-*datarootdir*) ac_datarootdir_seen=yes;;
-*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
- { echo "$as_me:$LINENO: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
-echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
-_ACEOF
-cat >>$CONFIG_STATUS <<_ACEOF
- ac_datarootdir_hack='
- s&@datadir@&$datadir&g
- s&@docdir@&$docdir&g
- s&@infodir@&$infodir&g
- s&@localedir@&$localedir&g
- s&@mandir@&$mandir&g
- s&\\\${datarootdir}&$datarootdir&g' ;;
-esac
-_ACEOF
-
-# Neutralize VPATH when `$srcdir' = `.'.
-# Shell code in configure.ac might set extrasub.
-# FIXME: do we really want to maintain this feature?
-cat >>$CONFIG_STATUS <<_ACEOF
- sed "$ac_vpsub
-$extrasub
-_ACEOF
-cat >>$CONFIG_STATUS <<\_ACEOF
-:t
-/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
-s&@configure_input@&$configure_input&;t t
-s&@top_builddir@&$ac_top_builddir_sub&;t t
-s&@srcdir@&$ac_srcdir&;t t
-s&@abs_srcdir@&$ac_abs_srcdir&;t t
-s&@top_srcdir@&$ac_top_srcdir&;t t
-s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t
-s&@builddir@&$ac_builddir&;t t
-s&@abs_builddir@&$ac_abs_builddir&;t t
-s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
-s&@INSTALL@&$ac_INSTALL&;t t
-s&@MKDIR_P@&$ac_MKDIR_P&;t t
-$ac_datarootdir_hack
-" $ac_file_inputs | sed -f "$tmp/subs-1.sed" | sed -f "$tmp/subs-2.sed" >$tmp/out
-
-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"; } &&
- { 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
-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;}
-
- 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
- ;;
- :H)
- #
- # CONFIG_HEADER
- #
-_ACEOF
-
-# Transform confdefs.h into a sed script `conftest.defines', that
-# substitutes the proper values into config.h.in to produce config.h.
-rm -f conftest.defines conftest.tail
-# First, append a space to every undef/define line, to ease matching.
-echo 's/$/ /' >conftest.defines
-# Then, protect against being on the right side of a sed subst, or in
-# an unquoted here document, in config.status. If some macros were
-# called several times there might be several #defines for the same
-# symbol, which is useless. But do not sort them, since the last
-# AC_DEFINE must be honored.
-ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]*
-# These sed commands are passed to sed as "A NAME B PARAMS C VALUE D", where
-# NAME is the cpp macro being defined, VALUE is the value it is being given.
-# PARAMS is the parameter list in the macro definition--in most cases, it's
-# just an empty string.
-ac_dA='s,^\\([ #]*\\)[^ ]*\\([ ]*'
-ac_dB='\\)[ (].*,\\1define\\2'
-ac_dC=' '
-ac_dD=' ,'
-
-uniq confdefs.h |
- sed -n '
- t rset
- :rset
- s/^[ ]*#[ ]*define[ ][ ]*//
- t ok
- d
- :ok
- s/[\\&,]/\\&/g
- s/^\('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/ '"$ac_dA"'\1'"$ac_dB"'\2'"${ac_dC}"'\3'"$ac_dD"'/p
- s/^\('"$ac_word_re"'\)[ ]*\(.*\)/'"$ac_dA"'\1'"$ac_dB$ac_dC"'\2'"$ac_dD"'/p
- ' >>conftest.defines
-
-# Remove the space that was appended to ease matching.
-# Then replace #undef with comments. This is necessary, for
-# example, in the case of _POSIX_SOURCE, which is predefined and required
-# on some systems where configure will not decide to define it.
-# (The regexp can be short, since the line contains either #define or #undef.)
-echo 's/ $//
-s,^[ #]*u.*,/* & */,' >>conftest.defines
-
-# Break up conftest.defines:
-ac_max_sed_lines=50
-
-# First sed command is: sed -f defines.sed $ac_file_inputs >"$tmp/out1"
-# Second one is: sed -f defines.sed "$tmp/out1" >"$tmp/out2"
-# Third one will be: sed -f defines.sed "$tmp/out2" >"$tmp/out1"
-# et cetera.
-ac_in='$ac_file_inputs'
-ac_out='"$tmp/out1"'
-ac_nxt='"$tmp/out2"'
-
-while :
-do
- # Write a here document:
- cat >>$CONFIG_STATUS <<_ACEOF
- # First, check the format of the line:
- cat >"\$tmp/defines.sed" <<\\CEOF
-/^[ ]*#[ ]*undef[ ][ ]*$ac_word_re[ ]*\$/b def
-/^[ ]*#[ ]*define[ ][ ]*$ac_word_re[( ]/b def
-b
-:def
-_ACEOF
- sed ${ac_max_sed_lines}q conftest.defines >>$CONFIG_STATUS
- echo 'CEOF
- sed -f "$tmp/defines.sed"' "$ac_in >$ac_out" >>$CONFIG_STATUS
- ac_in=$ac_out; ac_out=$ac_nxt; ac_nxt=$ac_in
- sed 1,${ac_max_sed_lines}d conftest.defines >conftest.tail
- grep . conftest.tail >/dev/null || break
- rm -f conftest.defines
- mv conftest.tail conftest.defines
-done
-rm -f conftest.defines conftest.tail
-
-echo "ac_result=$ac_in" >>$CONFIG_STATUS
-cat >>$CONFIG_STATUS <<\_ACEOF
- if test x"$ac_file" != x-; then
- echo "/* $configure_input */" >"$tmp/config.h"
- cat "$ac_result" >>"$tmp/config.h"
- if diff $ac_file "$tmp/config.h" >/dev/null 2>&1; then
- { echo "$as_me:$LINENO: $ac_file is unchanged" >&5
-echo "$as_me: $ac_file is unchanged" >&6;}
- else
- rm -f $ac_file
- mv "$tmp/config.h" $ac_file
- fi
- else
- echo "/* $configure_input */"
- cat "$ac_result"
- fi
- rm -f "$tmp/out12"
-# Compute $ac_file's index in $config_headers.
-_am_arg=$ac_file
-_am_stamp_count=1
-for _am_header in $config_headers :; do
- case $_am_header in
- $_am_arg | $_am_arg:* )
- break ;;
- * )
- _am_stamp_count=`expr $_am_stamp_count + 1` ;;
- esac
-done
-echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" ||
-$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
- X"$_am_arg" : 'X\(//\)[^/]' \| \
- X"$_am_arg" : 'X\(//\)$' \| \
- X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null ||
-echo X"$_am_arg" |
- sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
- s//\1/
- q
- }
- /^X\(\/\/\)[^/].*/{
- s//\1/
- q
- }
- /^X\(\/\/\)$/{
- s//\1/
- q
- }
- /^X\(\/\).*/{
- s//\1/
- q
- }
- s/.*/./; q'`/stamp-h$_am_stamp_count
- ;;
-
- :C) { echo "$as_me:$LINENO: executing $ac_file commands" >&5
-echo "$as_me: executing $ac_file commands" >&6;}
- ;;
- esac
-
-
- case $ac_file$ac_mode in
- "depfiles":C) test x"$AMDEP_TRUE" != x"" || for mf in $CONFIG_FILES; do
- # Strip MF so we end up with the name of the file.
- mf=`echo "$mf" | sed -e 's/:.*$//'`
- # Check whether this is an Automake generated Makefile or not.
- # We used to match only the files named `Makefile.in', but
- # some people rename them; so instead we look at the file content.
- # Grep'ing the first line is not enough: some people post-process
- # each Makefile.in and add a new line on top of each file to say so.
- # Grep'ing the whole file is not good either: AIX grep has a line
- # limit of 2048, but all sed's we know have understand at least 4000.
- if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
- dirpart=`$as_dirname -- "$mf" ||
-$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
- X"$mf" : 'X\(//\)[^/]' \| \
- X"$mf" : 'X\(//\)$' \| \
- X"$mf" : 'X\(/\)' \| . 2>/dev/null ||
-echo X"$mf" |
- sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
- s//\1/
- q
- }
- /^X\(\/\/\)[^/].*/{
- s//\1/
- q
- }
- /^X\(\/\/\)$/{
- s//\1/
- q
- }
- /^X\(\/\).*/{
- s//\1/
- q
- }
- s/.*/./; q'`
- else
- continue
- fi
- # Extract the definition of DEPDIR, am__include, and am__quote
- # from the Makefile without running `make'.
- DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
- test -z "$DEPDIR" && continue
- am__include=`sed -n 's/^am__include = //p' < "$mf"`
- test -z "am__include" && continue
- am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
- # When using ansi2knr, U may be empty or an underscore; expand it
- U=`sed -n 's/^U = //p' < "$mf"`
- # Find all dependency output files, they are included files with
- # $(DEPDIR) in their names. We invoke sed twice because it is the
- # simplest approach to changing $(DEPDIR) to its actual value in the
- # expansion.
- for file in `sed -n "
- s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
- sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
- # Make sure the directory exists.
- test -f "$dirpart/$file" && continue
- fdir=`$as_dirname -- "$file" ||
-$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
- X"$file" : 'X\(//\)[^/]' \| \
- X"$file" : 'X\(//\)$' \| \
- X"$file" : 'X\(/\)' \| . 2>/dev/null ||
-echo X"$file" |
- sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
- s//\1/
- q
- }
- /^X\(\/\/\)[^/].*/{
- s//\1/
- q
- }
- /^X\(\/\/\)$/{
- s//\1/
- q
- }
- /^X\(\/\).*/{
- s//\1/
- q
- }
- s/.*/./; q'`
- { as_dir=$dirpart/$fdir
- 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=`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 ||
-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" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5
-echo "$as_me: error: cannot create directory $as_dir" >&2;}
- { (exit 1); exit 1; }; }; }
- # echo "creating $dirpart/$file"
- echo '# dummy' > "$dirpart/$file"
- done
-done
- ;;
- "script-chmod":C) chmod a+x pcre-config ;;
- "delete-old-chartables":C) rm -f pcre_chartables.c ;;
-
- esac
-done # for ac_tag
-
-
-{ (exit 0); exit 0; }
-_ACEOF
-chmod +x $CONFIG_STATUS
-ac_clean_files=$ac_clean_files_save
-
-
-# configure is writing to config.log, and then calls config.status.
-# config.status does its own redirection, appending to config.log.
-# Unfortunately, on DOS this fails, as config.log is still kept open
-# by configure, so config.status won't be able to write to it; its
-# output is simply discarded. So we exec the FD to /dev/null,
-# effectively closing config.log, so it can be properly (re)opened and
-# appended to by config.status. When coming back to configure, we
-# need to make the FD available again.
-if test "$no_create" != yes; then
- ac_cs_success=:
- ac_config_status_args=
- test "$silent" = yes &&
- ac_config_status_args="$ac_config_status_args --quiet"
- exec 5>/dev/null
- $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
- 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 || { (exit 1); exit 1; }
-fi
-
-
-# Print out a nice little message after configure is run displaying your
-# chosen options.
-
-cat <<EOF
-
-$PACKAGE-$VERSION configuration summary:
-
- Install prefix .................. : ${prefix}
- C preprocessor .................. : ${CPP}
- C compiler ...................... : ${CC}
- C++ preprocessor ................ : ${CXXCPP}
- C++ compiler .................... : ${CXX}
- Linker .......................... : ${LD}
- C preprocessor flags ............ : ${CPPFLAGS}
- C compiler flags ................ : ${CFLAGS}
- C++ compiler flags .............. : ${CXXFLAGS}
- Linker flags .................... : ${LDFLAGS}
- Extra libraries ................. : ${LIBS}
-
- Build C++ library ............... : ${enable_cpp}
- Enable UTF-8 support ............ : ${enable_utf8}
- Unicode properties .............. : ${enable_unicode_properties}
- Newline char/sequence ........... : ${enable_newline}
- \R matches only ANYCRLF ......... : ${enable_bsr_anycrlf}
- EBCDIC coding ................... : ${enable_ebcdic}
- Rebuild char tables ............. : ${enable_rebuild_chartables}
- Use stack recursion ............. : ${enable_stack_for_recursion}
- POSIX mem threshold ............. : ${with_posix_malloc_threshold}
- Internal link size .............. : ${with_link_size}
- Match limit ..................... : ${with_match_limit}
- Match limit recursion ........... : ${with_match_limit_recursion}
- Build shared libs ............... : ${enable_shared}
- Build static libs ............... : ${enable_static}
- Link pcregrep with libz ......... : ${enable_pcregrep_libz}
- Link pcregrep with libbz2 ....... : ${enable_pcregrep_libbz2}
- Link pcretest with libreadline .. : ${enable_pcretest_libreadline}
-
-EOF
-
diff --git a/crawl-ref/source/util/pcre/configure.ac b/crawl-ref/source/util/pcre/configure.ac
deleted file mode 100644
index 6865cca6f0..0000000000
--- a/crawl-ref/source/util/pcre/configure.ac
+++ /dev/null
@@ -1,641 +0,0 @@
-dnl Process this file with autoconf to produce a configure script.
-
-dnl NOTE FOR MAINTAINERS: Do not use major or minor version numbers with
-dnl leading zeros, because they may be treated as octal constants. The
-dnl PCRE_PRERELEASE feature is for identifying release candidates. It might
-dnl be defined as -RC2, for example. For real releases, it should be defined
-dnl empty.
-
-m4_define(pcre_major, [7])
-m4_define(pcre_minor, [7])
-m4_define(pcre_prerelease, [])
-m4_define(pcre_date, [2008-05-07])
-
-# Libtool shared library interface versions (current:revision:age)
-m4_define(libpcre_version, [0:1:0])
-m4_define(libpcreposix_version, [0:0:0])
-m4_define(libpcrecpp_version, [0:0:0])
-
-AC_PREREQ(2.57)
-AC_INIT(PCRE, pcre_major.pcre_minor[]pcre_prerelease, , pcre)
-AC_CONFIG_SRCDIR([pcre.h.in])
-AM_INIT_AUTOMAKE([dist-bzip2 dist-zip])
-AC_CONFIG_HEADERS(config.h)
-
-# The default CFLAGS and CXXFLAGS in Autoconf are "-g -O2" for gcc and just
-# "-g" for any other compiler. There doesn't seem to be a standard way of
-# getting rid of the -g (which I don't think is needed for a production
-# library). This fudge seems to achieve the necessary. First, we remember the
-# externally set values of CFLAGS and CXXFLAGS. Then call the AC_PROG_CC and
-# AC_PROG_CXX macros to find the compilers - if CFLAGS and CXXFLAGS are not
-# set, they will be set to Autoconf's defaults. Afterwards, if the original
-# values were not set, remove the -g from the Autoconf defaults.
-# (PH 02-May-07)
-
-remember_set_CFLAGS="$CFLAGS"
-remember_set_CXXFLAGS="$CXXFLAGS"
-
-AC_PROG_CC
-AC_PROG_CXX
-
-if test "x$remember_set_CFLAGS" = "x"
-then
- if test "$CFLAGS" = "-g -O2"
- then
- CFLAGS="-O2"
- elif test "$CFLAGS" = "-g"
- then
- CFLAGS=""
- fi
-fi
-
-if test "x$remember_set_CXXFLAGS" = "x"
-then
- if test "$CXXFLAGS" = "-g -O2"
- then
- CXXFLAGS="-O2"
- elif test "$CXXFLAGS" = "-g"
- then
- CXXFLAGS=""
- fi
-fi
-
-# AC_PROG_CXX will return "g++" even if no c++ compiler is installed.
-# Check for that case, and just disable c++ code if g++ doesn't run.
-AC_LANG_PUSH(C++)
-AC_COMPILE_IFELSE(AC_LANG_PROGRAM([],[]),, CXX=""; CXXCP=""; CXXFLAGS="")
-AC_LANG_POP
-
-AC_PROG_INSTALL
-AC_LIBTOOL_WIN32_DLL
-AC_PROG_LIBTOOL
-AC_PROG_LN_S
-
-PCRE_MAJOR="pcre_major"
-PCRE_MINOR="pcre_minor"
-PCRE_PRERELEASE="pcre_prerelease"
-PCRE_DATE="pcre_date"
-
-AC_SUBST(PCRE_MAJOR)
-AC_SUBST(PCRE_MINOR)
-AC_SUBST(PCRE_PRERELEASE)
-AC_SUBST(PCRE_DATE)
-
-# Set a more sensible default value for $(htmldir).
-if test "x$htmldir" = 'x${docdir}'
-then
- htmldir='${docdir}/html'
-fi
-
-# Handle --disable-cpp
-AC_ARG_ENABLE(cpp,
- AS_HELP_STRING([--disable-cpp],
- [disable C++ support]),
- , enable_cpp=yes)
-
-# Handle --enable-rebuild-chartables
-AC_ARG_ENABLE(rebuild-chartables,
- AS_HELP_STRING([--enable-rebuild-chartables],
- [rebuild character tables in current locale]),
- , enable_rebuild_chartables=no)
-
-# Handle --enable-utf8 (disabled by default)
-AC_ARG_ENABLE(utf8,
- AS_HELP_STRING([--enable-utf8],
- [enable UTF-8 support]),
- , enable_utf8=unset)
-
-# Handle --enable-unicode-properties
-AC_ARG_ENABLE(unicode-properties,
- AS_HELP_STRING([--enable-unicode-properties],
- [enable Unicode properties support (implies --enable-utf8)]),
- , enable_unicode_properties=no)
-
-# Handle --enable-newline=NL
-dnl AC_ARG_ENABLE(newline,
-dnl AS_HELP_STRING([--enable-newline=NL],
-dnl [use NL as newline (lf, cr, crlf, anycrlf, any; default=lf)]),
-dnl , enable_newline=lf)
-
-# Separate newline options
-ac_pcre_newline=lf
-AC_ARG_ENABLE(newline-is-cr,
- AS_HELP_STRING([--enable-newline-is-cr],
- [use CR as newline character]),
- ac_pcre_newline=cr)
-AC_ARG_ENABLE(newline-is-lf,
- AS_HELP_STRING([--enable-newline-is-lf],
- [use LF as newline character (default)]),
- ac_pcre_newline=lf)
-AC_ARG_ENABLE(newline-is-crlf,
- AS_HELP_STRING([--enable-newline-is-crlf],
- [use CRLF as newline sequence]),
- ac_pcre_newline=crlf)
-AC_ARG_ENABLE(newline-is-anycrlf,
- AS_HELP_STRING([--enable-newline-is-anycrlf],
- [use CR, LF, or CRLF as newline sequence]),
- ac_pcre_newline=anycrlf)
-AC_ARG_ENABLE(newline-is-any,
- AS_HELP_STRING([--enable-newline-is-any],
- [use any valid Unicode newline sequence]),
- ac_pcre_newline=any)
-enable_newline="$ac_pcre_newline"
-
-# Handle --enable-bsr-anycrlf
-AC_ARG_ENABLE(bsr-anycrlf,
- AS_HELP_STRING([--enable-bsr-anycrlf],
- [\R matches only CR, LF, CRLF by default]),
- , enable_bsr_anycrlf=no)
-
-# Handle --enable-ebcdic
-AC_ARG_ENABLE(ebcdic,
- AS_HELP_STRING([--enable-ebcdic],
- [assume EBCDIC coding rather than ASCII; use this only in (uncommon) EBCDIC environments; it implies --enable-rebuild-chartables]),
- , enable_ebcdic=no)
-
-# Handle --disable-stack-for-recursion
-AC_ARG_ENABLE(stack-for-recursion,
- AS_HELP_STRING([--disable-stack-for-recursion],
- [don't use stack recursion when matching]),
- , enable_stack_for_recursion=yes)
-
-# Handle --enable-pcregrep-libz
-AC_ARG_ENABLE(pcregrep-libz,
- AS_HELP_STRING([--enable-pcregrep-libz],
- [link pcregrep with libz to handle .gz files]),
- , enable_pcregrep_libz=no)
-
-# Handle --enable-pcregrep-libbz2
-AC_ARG_ENABLE(pcregrep-libbz2,
- AS_HELP_STRING([--enable-pcregrep-libbz2],
- [link pcregrep with libbz2 to handle .bz2 files]),
- , enable_pcregrep_libbz2=no)
-
-# Handle --enable-pcretest-libreadline
-AC_ARG_ENABLE(pcretest-libreadline,
- AS_HELP_STRING([--enable-pcretest-libreadline],
- [link pcretest with libreadline]),
- , enable_pcretest_libreadline=no)
-
-# Handle --with-posix-malloc-threshold=NBYTES
-AC_ARG_WITH(posix-malloc-threshold,
- AS_HELP_STRING([--with-posix-malloc-threshold=NBYTES],
- [threshold for POSIX malloc usage (default=10)]),
- , with_posix_malloc_threshold=10)
-
-# Handle --with-link-size=N
-AC_ARG_WITH(link-size,
- AS_HELP_STRING([--with-link-size=N],
- [internal link size (2, 3, or 4 allowed; default=2)]),
- , with_link_size=2)
-
-# Handle --with-match-limit=N
-AC_ARG_WITH(match-limit,
- AS_HELP_STRING([--with-match-limit=N],
- [default limit on internal looping (default=10000000)]),
- , with_match_limit=10000000)
-
-# Handle --with-match-limit_recursion=N
-#
-# Note: In config.h, the default is to define MATCH_LIMIT_RECURSION
-# symbolically as MATCH_LIMIT, which in turn is defined to be some numeric
-# value (e.g. 10000000). MATCH_LIMIT_RECURSION can otherwise be set to some
-# different numeric value (or even the same numeric value as MATCH_LIMIT,
-# though no longer defined in terms of the latter).
-#
-AC_ARG_WITH(match-limit-recursion,
- AS_HELP_STRING([--with-match-limit-recursion=N],
- [default limit on internal recursion (default=MATCH_LIMIT)]),
- , with_match_limit_recursion=MATCH_LIMIT)
-
-# Make sure that if enable_unicode_properties was set, that UTF-8 support
-# is enabled.
-#
-if test "x$enable_unicode_properties" = "xyes"
-then
- if test "x$enable_utf8" = "xno"
- then
- AC_MSG_ERROR([support for Unicode properties requires UTF-8 support])
- fi
- enable_utf8=yes
-fi
-
-if test "x$enable_utf8" = "xunset"
-then
- enable_utf8=no
-fi
-
-# Make sure that if enable_ebcdic is set, rebuild_chartables is also enabled.
-#
-if test "x$enable_ebcdic" = "xyes"
-then
- enable_rebuild_chartables=yes
-fi
-
-# Convert the newline identifier into the appropriate integer value.
-case "$enable_newline" in
- lf) ac_pcre_newline_value=10 ;;
- cr) ac_pcre_newline_value=13 ;;
- crlf) ac_pcre_newline_value=3338 ;;
- anycrlf) ac_pcre_newline_value=-2 ;;
- any) ac_pcre_newline_value=-1 ;;
- *)
- AC_MSG_ERROR([invalid argument \"$enable_newline\" to --enable-newline option])
- ;;
-esac
-
-# Check argument to --with-link-size
-case "$with_link_size" in
- 2|3|4) ;;
- *)
- AC_MSG_ERROR([invalid argument \"$with_link_size\" to --with-link-size option])
- ;;
-esac
-
-AH_TOP([
-/* On Unix-like systems config.h.in is converted by "configure" into config.h.
-Some other environments also support the use of "configure". PCRE is written in
-Standard C, but there are a few non-standard things it can cope with, allowing
-it to run on SunOS4 and other "close to standard" systems.
-
-If you are going to build PCRE "by hand" on a system without "configure" you
-should copy the distributed config.h.generic to config.h, and then set up the
-macro definitions the way you need them. You must then add -DHAVE_CONFIG_H to
-all of your compile commands, so that config.h is included at the start of
-every source.
-
-Alternatively, you can avoid editing by using -D on the compiler command line
-to set the macro values. In this case, you do not have to set -DHAVE_CONFIG_H.
-
-PCRE uses memmove() if HAVE_MEMMOVE is set to 1; otherwise it uses bcopy() if
-HAVE_BCOPY is set to 1. If your system has neither bcopy() nor memmove(), set
-them both to 0; an emulation function will be used. */])
-
-# Checks for header files.
-AC_HEADER_STDC
-AC_CHECK_HEADERS(limits.h sys/types.h sys/stat.h dirent.h windows.h)
-
-# The files below are C++ header files.
-pcre_have_type_traits="0"
-pcre_have_bits_type_traits="0"
-if test "x$enable_cpp" = "xyes" -a -n "$CXX"
-then
-AC_LANG_PUSH(C++)
-
-# Older versions of pcre defined pcrecpp::no_arg, but in new versions
-# it's called pcrecpp::RE::no_arg. For backwards ABI compatibility,
-# we want to make one an alias for the other. Different systems do
-# this in different ways. Some systems, for instance, can do it via
-# a linker flag: -alias (for os x 10.5) or -i (for os x <=10.4).
-OLD_LDFLAGS="$LDFLAGS"
-for flag in "-alias,__ZN7pcrecpp2RE6no_argE,__ZN7pcrecpp6no_argE" \
- "-i__ZN7pcrecpp6no_argE:__ZN7pcrecpp2RE6no_argE"; do
- AC_MSG_CHECKING([for alias support in the linker])
- LDFLAGS="$OLD_LDFLAGS -Wl,$flag"
- # We try to run the linker with this new ld flag. If the link fails,
- # we give up and remove the new flag from LDFLAGS.
- AC_LINK_IFELSE(AC_LANG_PROGRAM([namespace pcrecpp {
- class RE { static int no_arg; };
- int RE::no_arg;
- }],
- []),
- [AC_MSG_RESULT([yes]);
- EXTRA_LIBPCRECPP_LDFLAGS="$EXTRA_LIBPCRECPP_LDFLAGS -Wl,$flag";
- break;],
- AC_MSG_RESULT([no]))
-done
-LDFLAGS="$OLD_LDFLAGS"
-
-# We could be more clever here, given we're doing AC_SUBST with this
-# (eg set a var to be the name of the include file we want). But we're not
-# so it's easy to change back to 'regular' autoconf vars if we needed to.
-AC_CHECK_HEADERS(string, [pcre_have_cpp_headers="1"],
- [pcre_have_cpp_headers="0"])
-AC_CHECK_HEADERS(bits/type_traits.h, [pcre_have_bits_type_traits="1"],
- [pcre_have_bits_type_traits="0"])
-AC_CHECK_HEADERS(type_traits.h, [pcre_have_type_traits="1"],
- [pcre_have_type_traits="0"])
-
-AC_LANG_POP
-fi
-# Using AC_SUBST eliminates the need to include config.h in a public .h file
-AC_SUBST(pcre_have_type_traits)
-AC_SUBST(pcre_have_bits_type_traits)
-
-# Conditional compilation
-AM_CONDITIONAL(WITH_PCRE_CPP, test "x$enable_cpp" = "xyes")
-AM_CONDITIONAL(WITH_REBUILD_CHARTABLES, test "x$enable_rebuild_chartables" = "xyes")
-
-# Checks for typedefs, structures, and compiler characteristics.
-
-AC_C_CONST
-AC_TYPE_SIZE_T
-
-pcre_have_strotolonglong=0
-AC_CHECK_FUNCS(strtoq strtoll _strtoi64, [pcre_have_strotolonglong="1"; break])
-# If we can't convert a string to a long long, pretend we don't even
-# have a long long.
-if test $pcre_have_strotolonglong = "0"; then
- pcre_have_long_long="0"
- pcre_have_ulong_long="0"
-else
- AC_CHECK_TYPES([long long],
- [pcre_have_long_long="1"],
- [pcre_have_long_long="0"])
- AC_CHECK_TYPES([unsigned long long],
- [pcre_have_ulong_long="1"],
- [pcre_have_ulong_long="0"])
-fi
-AC_SUBST(pcre_have_long_long)
-AC_SUBST(pcre_have_ulong_long)
-
-# Checks for library functions.
-
-AC_CHECK_FUNCS(bcopy memmove strerror)
-
-# Check for the availability of libz (aka zlib)
-
-AC_CHECK_HEADERS([zlib.h], [HAVE_ZLIB_H=1])
-AC_CHECK_LIB([z], [gzopen], [HAVE_LIBZ=1])
-
-# Check for the availability of libbz2
-
-AC_CHECK_HEADERS([bzlib.h], [HAVE_BZLIB_H=1])
-AC_CHECK_LIB([bz2], [BZ2_bzopen], [HAVE_LIBBZ2=1])
-
-# Check for the availabiity of libreadline
-
-AC_CHECK_HEADERS([readline/readline.h], [HAVE_READLINE_H=1])
-AC_CHECK_HEADERS([readline/history.h], [HAVE_HISTORY_H=1])
-AC_CHECK_LIB([readline], [readline], [HAVE_LIB_READLINE=1])
-
-# This facilitates -ansi builds under Linux
-dnl AC_DEFINE([_GNU_SOURCE], [], [Enable GNU extensions in glibc])
-
-if test "x$enable_shared" = "xno" ; then
- AC_DEFINE([PCRE_STATIC], [1], [
- Define if linking statically (TODO: make nice with Libtool)])
-fi
-
-# Here is where pcre specific defines are handled
-
-if test "$enable_utf8" = "yes"; then
- AC_DEFINE([SUPPORT_UTF8], [], [
- Define to enable support for the UTF-8 Unicode encoding.])
-fi
-
-if test "$enable_unicode_properties" = "yes"; then
- AC_DEFINE([SUPPORT_UCP], [], [
- Define to enable support for Unicode properties])
-fi
-
-if test "$enable_stack_for_recursion" = "no"; then
- AC_DEFINE([NO_RECURSE], [], [
- PCRE uses recursive function calls to handle backtracking while
- matching. This can sometimes be a problem on systems that have
- stacks of limited size. Define NO_RECURSE to get a version that
- doesn't use recursion in the match() function; instead it creates
- its own stack by steam using pcre_recurse_malloc() to obtain memory
- from the heap. For more detail, see the comments and other stuff
- just above the match() function. On systems that support it,
- "configure" can be used to set this in the Makefile
- (use --disable-stack-for-recursion).])
-fi
-
-if test "$enable_pcregrep_libz" = "yes"; then
- AC_DEFINE([SUPPORT_LIBZ], [], [
- Define to allow pcregrep to be linked with libz, so that it is
- able to handle .gz files.])
-fi
-
-if test "$enable_pcregrep_libbz2" = "yes"; then
- AC_DEFINE([SUPPORT_LIBBZ2], [], [
- Define to allow pcregrep to be linked with libbz2, so that it is
- able to handle .bz2 files.])
-fi
-
-if test "$enable_pcretest_libreadline" = "yes"; then
- AC_DEFINE([SUPPORT_LIBREADLINE], [], [
- Define to allow pcretest to be linked with libreadline.])
-fi
-
-AC_DEFINE_UNQUOTED([NEWLINE], [$ac_pcre_newline_value], [
- The value of NEWLINE determines the newline character sequence. On
- systems that support it, "configure" can be used to override the
- default, which is 10. The possible values are 10 (LF), 13 (CR),
- 3338 (CRLF), -1 (ANY), or -2 (ANYCRLF).])
-
-if test "$enable_bsr_anycrlf" = "yes"; then
- AC_DEFINE([BSR_ANYCRLF], [], [
- By default, the \R escape sequence matches any Unicode line ending
- character or sequence of characters. If BSR_ANYCRLF is defined, this is
- changed so that backslash-R matches only CR, LF, or CRLF. The build-
- time default can be overridden by the user of PCRE at runtime. On
- systems that support it, "configure" can be used to override the
- default.])
-fi
-
-AC_DEFINE_UNQUOTED([LINK_SIZE], [$with_link_size], [
- The value of LINK_SIZE determines the number of bytes used to store
- links as offsets within the compiled regex. The default is 2, which
- allows for compiled patterns up to 64K long. This covers the vast
- majority of cases. However, PCRE can also be compiled to use 3 or 4
- bytes instead. This allows for longer patterns in extreme cases. On
- systems that support it, "configure" can be used to override this default.])
-
-AC_DEFINE_UNQUOTED([POSIX_MALLOC_THRESHOLD], [$with_posix_malloc_threshold], [
- When calling PCRE via the POSIX interface, additional working storage
- is required for holding the pointers to capturing substrings because
- PCRE requires three integers per substring, whereas the POSIX
- interface provides only two. If the number of expected substrings is
- small, the wrapper function uses space on the stack, because this is
- faster than using malloc() for each call. The threshold above which
- the stack is no longer used is defined by POSIX_MALLOC_THRESHOLD. On
- systems that support it, "configure" can be used to override this
- default.])
-
-AC_DEFINE_UNQUOTED([MATCH_LIMIT], [$with_match_limit], [
- The value of MATCH_LIMIT determines the default number of times the
- internal match() function can be called during a single execution of
- pcre_exec(). There is a runtime interface for setting a different
- limit. The limit exists in order to catch runaway regular
- expressions that take for ever to determine that they do not match.
- The default is set very large so that it does not accidentally catch
- legitimate cases. On systems that support it, "configure" can be
- used to override this default default.])
-
-AC_DEFINE_UNQUOTED([MATCH_LIMIT_RECURSION], [$with_match_limit_recursion], [
- The above limit applies to all calls of match(), whether or not they
- increase the recursion depth. In some environments it is desirable
- to limit the depth of recursive calls of match() more strictly, in
- order to restrict the maximum amount of stack (or heap, if
- NO_RECURSE is defined) that is used. The value of
- MATCH_LIMIT_RECURSION applies only to recursive calls of match(). To
- have any useful effect, it must be less than the value of
- MATCH_LIMIT. The default is to use the same value as MATCH_LIMIT.
- There is a runtime method for setting a different limit. On systems
- that support it, "configure" can be used to override the default.])
-
-AC_DEFINE([MAX_NAME_SIZE], [32], [
- This limit is parameterized just in case anybody ever wants to
- change it. Care must be taken if it is increased, because it guards
- against integer overflow caused by enormously large patterns.])
-
-AC_DEFINE([MAX_NAME_COUNT], [10000], [
- This limit is parameterized just in case anybody ever wants to
- change it. Care must be taken if it is increased, because it guards
- against integer overflow caused by enormously large patterns.])
-
-AH_VERBATIM([PCRE_EXP_DEFN], [
-/* If you are compiling for a system other than a Unix-like system or
- Win32, and it needs some magic to be inserted before the definition
- of a function that is exported by the library, define this macro to
- contain the relevant magic. If you do not define this macro, it
- defaults to "extern" for a C compiler and "extern C" for a C++
- compiler on non-Win32 systems. This macro apears at the start of
- every exported function that is part of the external API. It does
- not appear on functions that are "external" in the C sense, but
- which are internal to the library. */
-#undef PCRE_EXP_DEFN])
-
-if test "$enable_ebcdic" = "yes"; then
- AC_DEFINE_UNQUOTED([EBCDIC], [], [
- If you are compiling for a system that uses EBCDIC instead of ASCII
- character codes, define this macro as 1. On systems that can use
- "configure", this can be done via --enable-ebcdic.])
-fi
-
-# Platform specific issues
-NO_UNDEFINED=
-EXPORT_ALL_SYMBOLS=
-case $host_os in
- cygwin* | mingw* )
- if test X"$enable_shared" = Xyes; then
- NO_UNDEFINED="-no-undefined"
- EXPORT_ALL_SYMBOLS="-Wl,--export-all-symbols"
- fi
- ;;
-esac
-
-# The extra LDFLAGS for each particular library
-# (Note: The libpcre*_version bits are m4 variables, assigned above)
-
-EXTRA_LIBPCRE_LDFLAGS="$EXTRA_LIBPCRE_LDFLAGS \
- $NO_UNDEFINED -version-info libpcre_version"
-
-EXTRA_LIBPCREPOSIX_LDFLAGS="$EXTRA_LIBPCREPOSIX_LDFLAGS \
- $NO_UNDEFINED -version-info libpcreposix_version"
-
-EXTRA_LIBPCRECPP_LDFLAGS="$EXTRA_LIBPCRECPP_LDFLAGS \
- $NO_UNDEFINED -version-info libpcrecpp_version \
- $EXPORT_ALL_SYMBOLS"
-
-AC_SUBST(EXTRA_LIBPCRE_LDFLAGS)
-AC_SUBST(EXTRA_LIBPCREPOSIX_LDFLAGS)
-AC_SUBST(EXTRA_LIBPCRECPP_LDFLAGS)
-
-# When we run 'make distcheck', use these arguments.
-DISTCHECK_CONFIGURE_FLAGS="--enable-cpp --enable-unicode-properties"
-AC_SUBST(DISTCHECK_CONFIGURE_FLAGS)
-
-# Check that, if --enable-pcregrep-libz or --enable-pcregrep-libbz2 is
-# specified, the relevant library is available. If so, add it to LIBS.
-
-if test "$enable_pcregrep_libz" = "yes"; then
- if test "$HAVE_ZLIB_H" != "1"; then
- echo "** Cannot --enable-pcregrep-libz because zlib.h was not found"
- exit 1
- fi
- if test "$HAVE_LIBZ" != "1"; then
- echo "** Cannot --enable-pcregrep-libz because libz was not found"
- exit 1
- fi
- if test "$LIBS" = ""; then LIBS=-lz; else LIBS="$LIBS -lz"; fi
-fi
-
-if test "$enable_pcregrep_libbz2" = "yes"; then
- if test "$HAVE_BZLIB_H" != "1"; then
- echo "** Cannot --enable-pcregrep-libbz2 because bzlib.h was not found"
- exit 1
- fi
- if test "$HAVE_LIBBZ2" != "1"; then
- echo "** Cannot --enable-pcregrep-libbz2 because libbz2 was not found"
- exit 1
- fi
- if test "$LIBS" = ""; then LIBS=-lbz2; else LIBS="$LIBS -lbz2"; fi
-fi
-
-# Similarly for --enable-pcretest-readline
-
-if test "$enable_pcretest_libreadline" = "yes"; then
- if test "$HAVE_READLINE_H" != "1"; then
- echo "** Cannot --enable-pcretest-readline because readline/readline.h was not found."
- exit 1
- fi
- if test "$HAVE_HISTORY_H" != "1"; then
- echo "** Cannot --enable-pcretest-readline because readline/history.h was not found."
- exit 1
- fi
- if test "$LIBS" = ""; then LIBS=-lreadline; else LIBS="$LIBS -lreadline"; fi
-fi
-
-# Produce these files, in addition to config.h.
-AC_CONFIG_FILES(
- Makefile
- libpcre.pc
- libpcrecpp.pc
- pcre-config
- pcre.h
- pcre_stringpiece.h
- pcrecpparg.h
-)
-
-# Make the generated script files executable.
-AC_CONFIG_COMMANDS([script-chmod], [chmod a+x pcre-config])
-
-# Make sure that pcre_chartables.c is removed in case the method for
-# creating it was changed by reconfiguration.
-AC_CONFIG_COMMANDS([delete-old-chartables], [rm -f pcre_chartables.c])
-
-AC_OUTPUT
-
-# Print out a nice little message after configure is run displaying your
-# chosen options.
-
-cat <<EOF
-
-$PACKAGE-$VERSION configuration summary:
-
- Install prefix .................. : ${prefix}
- C preprocessor .................. : ${CPP}
- C compiler ...................... : ${CC}
- C++ preprocessor ................ : ${CXXCPP}
- C++ compiler .................... : ${CXX}
- Linker .......................... : ${LD}
- C preprocessor flags ............ : ${CPPFLAGS}
- C compiler flags ................ : ${CFLAGS}
- C++ compiler flags .............. : ${CXXFLAGS}
- Linker flags .................... : ${LDFLAGS}
- Extra libraries ................. : ${LIBS}
-
- Build C++ library ............... : ${enable_cpp}
- Enable UTF-8 support ............ : ${enable_utf8}
- Unicode properties .............. : ${enable_unicode_properties}
- Newline char/sequence ........... : ${enable_newline}
- \R matches only ANYCRLF ......... : ${enable_bsr_anycrlf}
- EBCDIC coding ................... : ${enable_ebcdic}
- Rebuild char tables ............. : ${enable_rebuild_chartables}
- Use stack recursion ............. : ${enable_stack_for_recursion}
- POSIX mem threshold ............. : ${with_posix_malloc_threshold}
- Internal link size .............. : ${with_link_size}
- Match limit ..................... : ${with_match_limit}
- Match limit recursion ........... : ${with_match_limit_recursion}
- Build shared libs ............... : ${enable_shared}
- Build static libs ............... : ${enable_static}
- Link pcregrep with libz ......... : ${enable_pcregrep_libz}
- Link pcregrep with libbz2 ....... : ${enable_pcregrep_libbz2}
- Link pcretest with libreadline .. : ${enable_pcretest_libreadline}
-
-EOF
-
-dnl end configure.ac
diff --git a/crawl-ref/source/util/pcre/depcomp b/crawl-ref/source/util/pcre/depcomp
deleted file mode 100644
index e5f9736c72..0000000000
--- a/crawl-ref/source/util/pcre/depcomp
+++ /dev/null
@@ -1,589 +0,0 @@
-#! /bin/sh
-# depcomp - compile a program generating dependencies as side-effects
-
-scriptversion=2007-03-29.01
-
-# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007 Free Software
-# Foundation, Inc.
-
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2, or (at your option)
-# any later version.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-# 02110-1301, USA.
-
-# As a special exception to the GNU General Public License, if you
-# distribute this file as part of a program that contains a
-# configuration script generated by Autoconf, you may include it under
-# the same distribution terms that you use for the rest of that program.
-
-# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
-
-case $1 in
- '')
- echo "$0: No command. Try \`$0 --help' for more information." 1>&2
- exit 1;
- ;;
- -h | --h*)
- cat <<\EOF
-Usage: depcomp [--help] [--version] PROGRAM [ARGS]
-
-Run PROGRAMS ARGS to compile a file, generating dependencies
-as side-effects.
-
-Environment variables:
- depmode Dependency tracking mode.
- source Source file read by `PROGRAMS ARGS'.
- object Object file output by `PROGRAMS ARGS'.
- DEPDIR directory where to store dependencies.
- depfile Dependency file to output.
- tmpdepfile Temporary file to use when outputing dependencies.
- libtool Whether libtool is used (yes/no).
-
-Report bugs to <bug-automake@gnu.org>.
-EOF
- exit $?
- ;;
- -v | --v*)
- echo "depcomp $scriptversion"
- exit $?
- ;;
-esac
-
-if test -z "$depmode" || test -z "$source" || test -z "$object"; then
- echo "depcomp: Variables source, object and depmode must be set" 1>&2
- exit 1
-fi
-
-# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
-depfile=${depfile-`echo "$object" |
- sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
-tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
-
-rm -f "$tmpdepfile"
-
-# Some modes work just like other modes, but use different flags. We
-# parameterize here, but still list the modes in the big case below,
-# to make depend.m4 easier to write. Note that we *cannot* use a case
-# here, because this file can only contain one case statement.
-if test "$depmode" = hp; then
- # HP compiler uses -M and no extra arg.
- gccflag=-M
- depmode=gcc
-fi
-
-if test "$depmode" = dashXmstdout; then
- # This is just like dashmstdout with a different argument.
- dashmflag=-xM
- depmode=dashmstdout
-fi
-
-case "$depmode" in
-gcc3)
-## gcc 3 implements dependency tracking that does exactly what
-## we want. Yay! Note: for some reason libtool 1.4 doesn't like
-## it if -MD -MP comes after the -MF stuff. Hmm.
-## Unfortunately, FreeBSD c89 acceptance of flags depends upon
-## the command line argument order; so add the flags where they
-## appear in depend2.am. Note that the slowdown incurred here
-## affects only configure: in makefiles, %FASTDEP% shortcuts this.
- for arg
- do
- case $arg in
- -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;;
- *) set fnord "$@" "$arg" ;;
- esac
- shift # fnord
- shift # $arg
- done
- "$@"
- stat=$?
- if test $stat -eq 0; then :
- else
- rm -f "$tmpdepfile"
- exit $stat
- fi
- mv "$tmpdepfile" "$depfile"
- ;;
-
-gcc)
-## There are various ways to get dependency output from gcc. Here's
-## why we pick this rather obscure method:
-## - Don't want to use -MD because we'd like the dependencies to end
-## up in a subdir. Having to rename by hand is ugly.
-## (We might end up doing this anyway to support other compilers.)
-## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
-## -MM, not -M (despite what the docs say).
-## - Using -M directly means running the compiler twice (even worse
-## than renaming).
- if test -z "$gccflag"; then
- gccflag=-MD,
- fi
- "$@" -Wp,"$gccflag$tmpdepfile"
- stat=$?
- if test $stat -eq 0; then :
- else
- rm -f "$tmpdepfile"
- exit $stat
- fi
- rm -f "$depfile"
- echo "$object : \\" > "$depfile"
- alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
-## The second -e expression handles DOS-style file names with drive letters.
- sed -e 's/^[^:]*: / /' \
- -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
-## This next piece of magic avoids the `deleted header file' problem.
-## The problem is that when a header file which appears in a .P file
-## is deleted, the dependency causes make to die (because there is
-## typically no way to rebuild the header). We avoid this by adding
-## dummy dependencies for each header file. Too bad gcc doesn't do
-## this for us directly.
- tr ' ' '
-' < "$tmpdepfile" |
-## Some versions of gcc put a space before the `:'. On the theory
-## that the space means something, we add a space to the output as
-## well.
-## Some versions of the HPUX 10.20 sed can't process this invocation
-## correctly. Breaking it into two sed invocations is a workaround.
- sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
- rm -f "$tmpdepfile"
- ;;
-
-hp)
- # This case exists only to let depend.m4 do its work. It works by
- # looking at the text of this script. This case will never be run,
- # since it is checked for above.
- exit 1
- ;;
-
-sgi)
- if test "$libtool" = yes; then
- "$@" "-Wp,-MDupdate,$tmpdepfile"
- else
- "$@" -MDupdate "$tmpdepfile"
- fi
- stat=$?
- if test $stat -eq 0; then :
- else
- rm -f "$tmpdepfile"
- exit $stat
- fi
- rm -f "$depfile"
-
- if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files
- echo "$object : \\" > "$depfile"
-
- # Clip off the initial element (the dependent). Don't try to be
- # clever and replace this with sed code, as IRIX sed won't handle
- # lines with more than a fixed number of characters (4096 in
- # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
- # the IRIX cc adds comments like `#:fec' to the end of the
- # dependency line.
- tr ' ' '
-' < "$tmpdepfile" \
- | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
- tr '
-' ' ' >> $depfile
- echo >> $depfile
-
- # The second pass generates a dummy entry for each header file.
- tr ' ' '
-' < "$tmpdepfile" \
- | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
- >> $depfile
- else
- # The sourcefile does not contain any dependencies, so just
- # store a dummy comment line, to avoid errors with the Makefile
- # "include basename.Plo" scheme.
- echo "#dummy" > "$depfile"
- fi
- rm -f "$tmpdepfile"
- ;;
-
-aix)
- # The C for AIX Compiler uses -M and outputs the dependencies
- # in a .u file. In older versions, this file always lives in the
- # current directory. Also, the AIX compiler puts `$object:' at the
- # start of each line; $object doesn't have directory information.
- # Version 6 uses the directory in both cases.
- dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
- test "x$dir" = "x$object" && dir=
- base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
- if test "$libtool" = yes; then
- tmpdepfile1=$dir$base.u
- tmpdepfile2=$base.u
- tmpdepfile3=$dir.libs/$base.u
- "$@" -Wc,-M
- else
- tmpdepfile1=$dir$base.u
- tmpdepfile2=$dir$base.u
- tmpdepfile3=$dir$base.u
- "$@" -M
- fi
- stat=$?
-
- if test $stat -eq 0; then :
- else
- rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
- exit $stat
- fi
-
- for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
- do
- test -f "$tmpdepfile" && break
- done
- if test -f "$tmpdepfile"; then
- # Each line is of the form `foo.o: dependent.h'.
- # Do two passes, one to just change these to
- # `$object: dependent.h' and one to simply `dependent.h:'.
- sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
- # That's a tab and a space in the [].
- sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
- else
- # The sourcefile does not contain any dependencies, so just
- # store a dummy comment line, to avoid errors with the Makefile
- # "include basename.Plo" scheme.
- echo "#dummy" > "$depfile"
- fi
- rm -f "$tmpdepfile"
- ;;
-
-icc)
- # Intel's C compiler understands `-MD -MF file'. However on
- # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c
- # ICC 7.0 will fill foo.d with something like
- # foo.o: sub/foo.c
- # foo.o: sub/foo.h
- # which is wrong. We want:
- # sub/foo.o: sub/foo.c
- # sub/foo.o: sub/foo.h
- # sub/foo.c:
- # sub/foo.h:
- # ICC 7.1 will output
- # foo.o: sub/foo.c sub/foo.h
- # and will wrap long lines using \ :
- # foo.o: sub/foo.c ... \
- # sub/foo.h ... \
- # ...
-
- "$@" -MD -MF "$tmpdepfile"
- stat=$?
- if test $stat -eq 0; then :
- else
- rm -f "$tmpdepfile"
- exit $stat
- fi
- rm -f "$depfile"
- # Each line is of the form `foo.o: dependent.h',
- # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
- # Do two passes, one to just change these to
- # `$object: dependent.h' and one to simply `dependent.h:'.
- sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
- # Some versions of the HPUX 10.20 sed can't process this invocation
- # correctly. Breaking it into two sed invocations is a workaround.
- sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" |
- sed -e 's/$/ :/' >> "$depfile"
- rm -f "$tmpdepfile"
- ;;
-
-hp2)
- # The "hp" stanza above does not work with aCC (C++) and HP's ia64
- # compilers, which have integrated preprocessors. The correct option
- # to use with these is +Maked; it writes dependencies to a file named
- # 'foo.d', which lands next to the object file, wherever that
- # happens to be.
- # Much of this is similar to the tru64 case; see comments there.
- dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
- test "x$dir" = "x$object" && dir=
- base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
- if test "$libtool" = yes; then
- tmpdepfile1=$dir$base.d
- tmpdepfile2=$dir.libs/$base.d
- "$@" -Wc,+Maked
- else
- tmpdepfile1=$dir$base.d
- tmpdepfile2=$dir$base.d
- "$@" +Maked
- fi
- stat=$?
- if test $stat -eq 0; then :
- else
- rm -f "$tmpdepfile1" "$tmpdepfile2"
- exit $stat
- fi
-
- for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2"
- do
- test -f "$tmpdepfile" && break
- done
- if test -f "$tmpdepfile"; then
- sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile"
- # Add `dependent.h:' lines.
- sed -ne '2,${; s/^ *//; s/ \\*$//; s/$/:/; p;}' "$tmpdepfile" >> "$depfile"
- else
- echo "#dummy" > "$depfile"
- fi
- rm -f "$tmpdepfile" "$tmpdepfile2"
- ;;
-
-tru64)
- # The Tru64 compiler uses -MD to generate dependencies as a side
- # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'.
- # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
- # dependencies in `foo.d' instead, so we check for that too.
- # Subdirectories are respected.
- dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
- test "x$dir" = "x$object" && dir=
- base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
-
- if test "$libtool" = yes; then
- # With Tru64 cc, shared objects can also be used to make a
- # static library. This mechanism is used in libtool 1.4 series to
- # handle both shared and static libraries in a single compilation.
- # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d.
- #
- # With libtool 1.5 this exception was removed, and libtool now
- # generates 2 separate objects for the 2 libraries. These two
- # compilations output dependencies in $dir.libs/$base.o.d and
- # in $dir$base.o.d. We have to check for both files, because
- # one of the two compilations can be disabled. We should prefer
- # $dir$base.o.d over $dir.libs/$base.o.d because the latter is
- # automatically cleaned when .libs/ is deleted, while ignoring
- # the former would cause a distcleancheck panic.
- tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4
- tmpdepfile2=$dir$base.o.d # libtool 1.5
- tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5
- tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504
- "$@" -Wc,-MD
- else
- tmpdepfile1=$dir$base.o.d
- tmpdepfile2=$dir$base.d
- tmpdepfile3=$dir$base.d
- tmpdepfile4=$dir$base.d
- "$@" -MD
- fi
-
- stat=$?
- if test $stat -eq 0; then :
- else
- rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
- exit $stat
- fi
-
- for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
- do
- test -f "$tmpdepfile" && break
- done
- if test -f "$tmpdepfile"; then
- sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
- # That's a tab and a space in the [].
- sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
- else
- echo "#dummy" > "$depfile"
- fi
- rm -f "$tmpdepfile"
- ;;
-
-#nosideeffect)
- # This comment above is used by automake to tell side-effect
- # dependency tracking mechanisms from slower ones.
-
-dashmstdout)
- # Important note: in order to support this mode, a compiler *must*
- # always write the preprocessed file to stdout, regardless of -o.
- "$@" || exit $?
-
- # Remove the call to Libtool.
- if test "$libtool" = yes; then
- while test $1 != '--mode=compile'; do
- shift
- done
- shift
- fi
-
- # Remove `-o $object'.
- IFS=" "
- for arg
- do
- case $arg in
- -o)
- shift
- ;;
- $object)
- shift
- ;;
- *)
- set fnord "$@" "$arg"
- shift # fnord
- shift # $arg
- ;;
- esac
- done
-
- test -z "$dashmflag" && dashmflag=-M
- # Require at least two characters before searching for `:'
- # in the target name. This is to cope with DOS-style filenames:
- # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise.
- "$@" $dashmflag |
- sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile"
- rm -f "$depfile"
- cat < "$tmpdepfile" > "$depfile"
- tr ' ' '
-' < "$tmpdepfile" | \
-## Some versions of the HPUX 10.20 sed can't process this invocation
-## correctly. Breaking it into two sed invocations is a workaround.
- sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
- rm -f "$tmpdepfile"
- ;;
-
-dashXmstdout)
- # This case only exists to satisfy depend.m4. It is never actually
- # run, as this mode is specially recognized in the preamble.
- exit 1
- ;;
-
-makedepend)
- "$@" || exit $?
- # Remove any Libtool call
- if test "$libtool" = yes; then
- while test $1 != '--mode=compile'; do
- shift
- done
- shift
- fi
- # X makedepend
- shift
- cleared=no
- for arg in "$@"; do
- case $cleared in
- no)
- set ""; shift
- cleared=yes ;;
- esac
- case "$arg" in
- -D*|-I*)
- set fnord "$@" "$arg"; shift ;;
- # Strip any option that makedepend may not understand. Remove
- # the object too, otherwise makedepend will parse it as a source file.
- -*|$object)
- ;;
- *)
- set fnord "$@" "$arg"; shift ;;
- esac
- done
- obj_suffix="`echo $object | sed 's/^.*\././'`"
- touch "$tmpdepfile"
- ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
- rm -f "$depfile"
- cat < "$tmpdepfile" > "$depfile"
- sed '1,2d' "$tmpdepfile" | tr ' ' '
-' | \
-## Some versions of the HPUX 10.20 sed can't process this invocation
-## correctly. Breaking it into two sed invocations is a workaround.
- sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
- rm -f "$tmpdepfile" "$tmpdepfile".bak
- ;;
-
-cpp)
- # Important note: in order to support this mode, a compiler *must*
- # always write the preprocessed file to stdout.
- "$@" || exit $?
-
- # Remove the call to Libtool.
- if test "$libtool" = yes; then
- while test $1 != '--mode=compile'; do
- shift
- done
- shift
- fi
-
- # Remove `-o $object'.
- IFS=" "
- for arg
- do
- case $arg in
- -o)
- shift
- ;;
- $object)
- shift
- ;;
- *)
- set fnord "$@" "$arg"
- shift # fnord
- shift # $arg
- ;;
- esac
- done
-
- "$@" -E |
- sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
- -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
- sed '$ s: \\$::' > "$tmpdepfile"
- rm -f "$depfile"
- echo "$object : \\" > "$depfile"
- cat < "$tmpdepfile" >> "$depfile"
- sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
- rm -f "$tmpdepfile"
- ;;
-
-msvisualcpp)
- # Important note: in order to support this mode, a compiler *must*
- # always write the preprocessed file to stdout, regardless of -o,
- # because we must use -o when running libtool.
- "$@" || exit $?
- IFS=" "
- for arg
- do
- case "$arg" in
- "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
- set fnord "$@"
- shift
- shift
- ;;
- *)
- set fnord "$@" "$arg"
- shift
- shift
- ;;
- esac
- done
- "$@" -E |
- sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile"
- rm -f "$depfile"
- echo "$object : \\" > "$depfile"
- . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile"
- echo " " >> "$depfile"
- . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile"
- rm -f "$tmpdepfile"
- ;;
-
-none)
- exec "$@"
- ;;
-
-*)
- echo "Unknown depmode $depmode" 1>&2
- exit 1
- ;;
-esac
-
-exit 0
-
-# Local Variables:
-# mode: shell-script
-# sh-indentation: 2
-# eval: (add-hook 'write-file-hooks 'time-stamp)
-# time-stamp-start: "scriptversion="
-# time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-end: "$"
-# End:
diff --git a/crawl-ref/source/util/pcre/dftables.c b/crawl-ref/source/util/pcre/dftables.c
deleted file mode 100644
index 12e1af1489..0000000000
--- a/crawl-ref/source/util/pcre/dftables.c
+++ /dev/null
@@ -1,199 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
- Written by Philip Hazel
- Copyright (c) 1997-2008 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-
-/* This is a freestanding support program to generate a file containing
-character tables for PCRE. The tables are built according to the current
-locale. Now that pcre_maketables is a function visible to the outside world, we
-make use of its code from here in order to be consistent. */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <ctype.h>
-#include <stdio.h>
-#include <string.h>
-#include <locale.h>
-
-#include "pcre_internal.h"
-
-#define DFTABLES /* pcre_maketables.c notices this */
-#include "pcre_maketables.c"
-
-
-int main(int argc, char **argv)
-{
-FILE *f;
-int i = 1;
-const unsigned char *tables;
-const unsigned char *base_of_tables;
-
-/* By default, the default C locale is used rather than what the building user
-happens to have set. However, if the -L option is given, set the locale from
-the LC_xxx environment variables. */
-
-if (argc > 1 && strcmp(argv[1], "-L") == 0)
- {
- setlocale(LC_ALL, ""); /* Set from environment variables */
- i++;
- }
-
-if (argc < i + 1)
- {
- fprintf(stderr, "dftables: one filename argument is required\n");
- return 1;
- }
-
-tables = pcre_maketables();
-base_of_tables = tables;
-
-f = fopen(argv[i], "wb");
-if (f == NULL)
- {
- fprintf(stderr, "dftables: failed to open %s for writing\n", argv[1]);
- return 1;
- }
-
-/* There are several fprintf() calls here, because gcc in pedantic mode
-complains about the very long string otherwise. */
-
-fprintf(f,
- "/*************************************************\n"
- "* Perl-Compatible Regular Expressions *\n"
- "*************************************************/\n\n"
- "/* This file was automatically written by the dftables auxiliary\n"
- "program. It contains character tables that are used when no external\n"
- "tables are passed to PCRE by the application that calls it. The tables\n"
- "are used only for characters whose code values are less than 256.\n\n");
-fprintf(f,
- "The following #includes are present because without them gcc 4.x may remove\n"
- "the array definition from the final binary if PCRE is built into a static\n"
- "library and dead code stripping is activated. This leads to link errors.\n"
- "Pulling in the header ensures that the array gets flagged as \"someone\n"
- "outside this compilation unit might reference this\" and so it will always\n"
- "be supplied to the linker. */\n\n"
- "#ifdef HAVE_CONFIG_H\n"
- "#include \"config.h\"\n"
- "#endif\n\n"
- "#include \"pcre_internal.h\"\n\n");
-fprintf(f,
- "const unsigned char _pcre_default_tables[] = {\n\n"
- "/* This table is a lower casing table. */\n\n");
-
-fprintf(f, " ");
-for (i = 0; i < 256; i++)
- {
- if ((i & 7) == 0 && i != 0) fprintf(f, "\n ");
- fprintf(f, "%3d", *tables++);
- if (i != 255) fprintf(f, ",");
- }
-fprintf(f, ",\n\n");
-
-fprintf(f, "/* This table is a case flipping table. */\n\n");
-
-fprintf(f, " ");
-for (i = 0; i < 256; i++)
- {
- if ((i & 7) == 0 && i != 0) fprintf(f, "\n ");
- fprintf(f, "%3d", *tables++);
- if (i != 255) fprintf(f, ",");
- }
-fprintf(f, ",\n\n");
-
-fprintf(f,
- "/* This table contains bit maps for various character classes.\n"
- "Each map is 32 bytes long and the bits run from the least\n"
- "significant end of each byte. The classes that have their own\n"
- "maps are: space, xdigit, digit, upper, lower, word, graph\n"
- "print, punct, and cntrl. Other classes are built from combinations. */\n\n");
-
-fprintf(f, " ");
-for (i = 0; i < cbit_length; i++)
- {
- if ((i & 7) == 0 && i != 0)
- {
- if ((i & 31) == 0) fprintf(f, "\n");
- fprintf(f, "\n ");
- }
- fprintf(f, "0x%02x", *tables++);
- if (i != cbit_length - 1) fprintf(f, ",");
- }
-fprintf(f, ",\n\n");
-
-fprintf(f,
- "/* This table identifies various classes of character by individual bits:\n"
- " 0x%02x white space character\n"
- " 0x%02x letter\n"
- " 0x%02x decimal digit\n"
- " 0x%02x hexadecimal digit\n"
- " 0x%02x alphanumeric or '_'\n"
- " 0x%02x regular expression metacharacter or binary zero\n*/\n\n",
- ctype_space, ctype_letter, ctype_digit, ctype_xdigit, ctype_word,
- ctype_meta);
-
-fprintf(f, " ");
-for (i = 0; i < 256; i++)
- {
- if ((i & 7) == 0 && i != 0)
- {
- fprintf(f, " /* ");
- if (isprint(i-8)) fprintf(f, " %c -", i-8);
- else fprintf(f, "%3d-", i-8);
- if (isprint(i-1)) fprintf(f, " %c ", i-1);
- else fprintf(f, "%3d", i-1);
- fprintf(f, " */\n ");
- }
- fprintf(f, "0x%02x", *tables++);
- if (i != 255) fprintf(f, ",");
- }
-
-fprintf(f, "};/* ");
-if (isprint(i-8)) fprintf(f, " %c -", i-8);
- else fprintf(f, "%3d-", i-8);
-if (isprint(i-1)) fprintf(f, " %c ", i-1);
- else fprintf(f, "%3d", i-1);
-fprintf(f, " */\n\n/* End of pcre_chartables.c */\n");
-
-fclose(f);
-free((void *)base_of_tables);
-return 0;
-}
-
-/* End of dftables.c */
diff --git a/crawl-ref/source/util/pcre/install-sh b/crawl-ref/source/util/pcre/install-sh
deleted file mode 100644
index a5897de6ea..0000000000
--- a/crawl-ref/source/util/pcre/install-sh
+++ /dev/null
@@ -1,519 +0,0 @@
-#!/bin/sh
-# install - install a program, script, or datafile
-
-scriptversion=2006-12-25.00
-
-# This originates from X11R5 (mit/util/scripts/install.sh), which was
-# later released in X11R6 (xc/config/util/install.sh) with the
-# following copyright and license.
-#
-# Copyright (C) 1994 X Consortium
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to
-# deal in the Software without restriction, including without limitation the
-# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
-# sell copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in
-# all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
-# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
-# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-#
-# Except as contained in this notice, the name of the X Consortium shall not
-# be used in advertising or otherwise to promote the sale, use or other deal-
-# ings in this Software without prior written authorization from the X Consor-
-# tium.
-#
-#
-# FSF changes to this file are in the public domain.
-#
-# Calling this script install-sh is preferred over install.sh, to prevent
-# `make' implicit rules from creating a file called install from it
-# when there is no Makefile.
-#
-# This script is compatible with the BSD install script, but was written
-# from scratch.
-
-nl='
-'
-IFS=" "" $nl"
-
-# set DOITPROG to echo to test this script
-
-# Don't use :- since 4.3BSD and earlier shells don't like it.
-doit=${DOITPROG-}
-if test -z "$doit"; then
- doit_exec=exec
-else
- doit_exec=$doit
-fi
-
-# Put in absolute file names if you don't have them in your path;
-# or use environment vars.
-
-chgrpprog=${CHGRPPROG-chgrp}
-chmodprog=${CHMODPROG-chmod}
-chownprog=${CHOWNPROG-chown}
-cmpprog=${CMPPROG-cmp}
-cpprog=${CPPROG-cp}
-mkdirprog=${MKDIRPROG-mkdir}
-mvprog=${MVPROG-mv}
-rmprog=${RMPROG-rm}
-stripprog=${STRIPPROG-strip}
-
-posix_glob='?'
-initialize_posix_glob='
- test "$posix_glob" != "?" || {
- if (set -f) 2>/dev/null; then
- posix_glob=
- else
- posix_glob=:
- fi
- }
-'
-
-posix_mkdir=
-
-# Desired mode of installed file.
-mode=0755
-
-chgrpcmd=
-chmodcmd=$chmodprog
-chowncmd=
-mvcmd=$mvprog
-rmcmd="$rmprog -f"
-stripcmd=
-
-src=
-dst=
-dir_arg=
-dst_arg=
-
-copy_on_change=false
-no_target_directory=
-
-usage="\
-Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
- or: $0 [OPTION]... SRCFILES... DIRECTORY
- or: $0 [OPTION]... -t DIRECTORY SRCFILES...
- or: $0 [OPTION]... -d DIRECTORIES...
-
-In the 1st form, copy SRCFILE to DSTFILE.
-In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
-In the 4th, create DIRECTORIES.
-
-Options:
- --help display this help and exit.
- --version display version info and exit.
-
- -c (ignored)
- -C install only if different (preserve the last data modification time)
- -d create directories instead of installing files.
- -g GROUP $chgrpprog installed files to GROUP.
- -m MODE $chmodprog installed files to MODE.
- -o USER $chownprog installed files to USER.
- -s $stripprog installed files.
- -t DIRECTORY install into DIRECTORY.
- -T report an error if DSTFILE is a directory.
-
-Environment variables override the default commands:
- CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
- RMPROG STRIPPROG
-"
-
-while test $# -ne 0; do
- case $1 in
- -c) ;;
-
- -C) copy_on_change=true;;
-
- -d) dir_arg=true;;
-
- -g) chgrpcmd="$chgrpprog $2"
- shift;;
-
- --help) echo "$usage"; exit $?;;
-
- -m) mode=$2
- case $mode in
- *' '* | *' '* | *'
-'* | *'*'* | *'?'* | *'['*)
- echo "$0: invalid mode: $mode" >&2
- exit 1;;
- esac
- shift;;
-
- -o) chowncmd="$chownprog $2"
- shift;;
-
- -s) stripcmd=$stripprog;;
-
- -t) dst_arg=$2
- shift;;
-
- -T) no_target_directory=true;;
-
- --version) echo "$0 $scriptversion"; exit $?;;
-
- --) shift
- break;;
-
- -*) echo "$0: invalid option: $1" >&2
- exit 1;;
-
- *) break;;
- esac
- shift
-done
-
-if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
- # When -d is used, all remaining arguments are directories to create.
- # When -t is used, the destination is already specified.
- # Otherwise, the last argument is the destination. Remove it from $@.
- for arg
- do
- if test -n "$dst_arg"; then
- # $@ is not empty: it contains at least $arg.
- set fnord "$@" "$dst_arg"
- shift # fnord
- fi
- shift # arg
- dst_arg=$arg
- done
-fi
-
-if test $# -eq 0; then
- if test -z "$dir_arg"; then
- echo "$0: no input file specified." >&2
- exit 1
- fi
- # It's OK to call `install-sh -d' without argument.
- # This can happen when creating conditional directories.
- exit 0
-fi
-
-if test -z "$dir_arg"; then
- trap '(exit $?); exit' 1 2 13 15
-
- # Set umask so as not to create temps with too-generous modes.
- # However, 'strip' requires both read and write access to temps.
- case $mode in
- # Optimize common cases.
- *644) cp_umask=133;;
- *755) cp_umask=22;;
-
- *[0-7])
- if test -z "$stripcmd"; then
- u_plus_rw=
- else
- u_plus_rw='% 200'
- fi
- cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
- *)
- if test -z "$stripcmd"; then
- u_plus_rw=
- else
- u_plus_rw=,u+rw
- fi
- cp_umask=$mode$u_plus_rw;;
- esac
-fi
-
-for src
-do
- # Protect names starting with `-'.
- case $src in
- -*) src=./$src;;
- esac
-
- if test -n "$dir_arg"; then
- dst=$src
- dstdir=$dst
- test -d "$dstdir"
- dstdir_status=$?
- else
-
- # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
- # might cause directories to be created, which would be especially bad
- # if $src (and thus $dsttmp) contains '*'.
- if test ! -f "$src" && test ! -d "$src"; then
- echo "$0: $src does not exist." >&2
- exit 1
- fi
-
- if test -z "$dst_arg"; then
- echo "$0: no destination specified." >&2
- exit 1
- fi
-
- dst=$dst_arg
- # Protect names starting with `-'.
- case $dst in
- -*) dst=./$dst;;
- esac
-
- # If destination is a directory, append the input filename; won't work
- # if double slashes aren't ignored.
- if test -d "$dst"; then
- if test -n "$no_target_directory"; then
- echo "$0: $dst_arg: Is a directory" >&2
- exit 1
- fi
- dstdir=$dst
- dst=$dstdir/`basename "$src"`
- dstdir_status=0
- else
- # Prefer dirname, but fall back on a substitute if dirname fails.
- dstdir=`
- (dirname "$dst") 2>/dev/null ||
- expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
- X"$dst" : 'X\(//\)[^/]' \| \
- X"$dst" : 'X\(//\)$' \| \
- X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
- echo X"$dst" |
- sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
- s//\1/
- q
- }
- /^X\(\/\/\)[^/].*/{
- s//\1/
- q
- }
- /^X\(\/\/\)$/{
- s//\1/
- q
- }
- /^X\(\/\).*/{
- s//\1/
- q
- }
- s/.*/./; q'
- `
-
- test -d "$dstdir"
- dstdir_status=$?
- fi
- fi
-
- obsolete_mkdir_used=false
-
- if test $dstdir_status != 0; then
- case $posix_mkdir in
- '')
- # Create intermediate dirs using mode 755 as modified by the umask.
- # This is like FreeBSD 'install' as of 1997-10-28.
- umask=`umask`
- case $stripcmd.$umask in
- # Optimize common cases.
- *[2367][2367]) mkdir_umask=$umask;;
- .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
-
- *[0-7])
- mkdir_umask=`expr $umask + 22 \
- - $umask % 100 % 40 + $umask % 20 \
- - $umask % 10 % 4 + $umask % 2
- `;;
- *) mkdir_umask=$umask,go-w;;
- esac
-
- # With -d, create the new directory with the user-specified mode.
- # Otherwise, rely on $mkdir_umask.
- if test -n "$dir_arg"; then
- mkdir_mode=-m$mode
- else
- mkdir_mode=
- fi
-
- posix_mkdir=false
- case $umask in
- *[123567][0-7][0-7])
- # POSIX mkdir -p sets u+wx bits regardless of umask, which
- # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
- ;;
- *)
- tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
- trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
-
- if (umask $mkdir_umask &&
- exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
- then
- if test -z "$dir_arg" || {
- # Check for POSIX incompatibilities with -m.
- # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
- # other-writeable bit of parent directory when it shouldn't.
- # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
- ls_ld_tmpdir=`ls -ld "$tmpdir"`
- case $ls_ld_tmpdir in
- d????-?r-*) different_mode=700;;
- d????-?--*) different_mode=755;;
- *) false;;
- esac &&
- $mkdirprog -m$different_mode -p -- "$tmpdir" && {
- ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
- test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
- }
- }
- then posix_mkdir=:
- fi
- rmdir "$tmpdir/d" "$tmpdir"
- else
- # Remove any dirs left behind by ancient mkdir implementations.
- rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
- fi
- trap '' 0;;
- esac;;
- esac
-
- if
- $posix_mkdir && (
- umask $mkdir_umask &&
- $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
- )
- then :
- else
-
- # The umask is ridiculous, or mkdir does not conform to POSIX,
- # or it failed possibly due to a race condition. Create the
- # directory the slow way, step by step, checking for races as we go.
-
- case $dstdir in
- /*) prefix='/';;
- -*) prefix='./';;
- *) prefix='';;
- esac
-
- eval "$initialize_posix_glob"
-
- oIFS=$IFS
- IFS=/
- $posix_glob set -f
- set fnord $dstdir
- shift
- $posix_glob set +f
- IFS=$oIFS
-
- prefixes=
-
- for d
- do
- test -z "$d" && continue
-
- prefix=$prefix$d
- if test -d "$prefix"; then
- prefixes=
- else
- if $posix_mkdir; then
- (umask=$mkdir_umask &&
- $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
- # Don't fail if two instances are running concurrently.
- test -d "$prefix" || exit 1
- else
- case $prefix in
- *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
- *) qprefix=$prefix;;
- esac
- prefixes="$prefixes '$qprefix'"
- fi
- fi
- prefix=$prefix/
- done
-
- if test -n "$prefixes"; then
- # Don't fail if two instances are running concurrently.
- (umask $mkdir_umask &&
- eval "\$doit_exec \$mkdirprog $prefixes") ||
- test -d "$dstdir" || exit 1
- obsolete_mkdir_used=true
- fi
- fi
- fi
-
- if test -n "$dir_arg"; then
- { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
- { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
- { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
- test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
- else
-
- # Make a couple of temp file names in the proper directory.
- dsttmp=$dstdir/_inst.$$_
- rmtmp=$dstdir/_rm.$$_
-
- # Trap to clean up those temp files at exit.
- trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
-
- # Copy the file name to the temp name.
- (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
-
- # and set any options; do chmod last to preserve setuid bits.
- #
- # If any of these fail, we abort the whole thing. If we want to
- # ignore errors from any of these, just make sure not to ignore
- # errors from the above "$doit $cpprog $src $dsttmp" command.
- #
- { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
- { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
- { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
- { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
-
- # If -C, don't bother to copy if it wouldn't change the file.
- if $copy_on_change &&
- old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` &&
- new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
-
- eval "$initialize_posix_glob" &&
- $posix_glob set -f &&
- set X $old && old=:$2:$4:$5:$6 &&
- set X $new && new=:$2:$4:$5:$6 &&
- $posix_glob set +f &&
-
- test "$old" = "$new" &&
- $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
- then
- rm -f "$dsttmp"
- else
- # Rename the file to the real destination.
- $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
-
- # The rename failed, perhaps because mv can't rename something else
- # to itself, or perhaps because mv is so ancient that it does not
- # support -f.
- {
- # Now remove or move aside any old file at destination location.
- # We try this two ways since rm can't unlink itself on some
- # systems and the destination file might be busy for other
- # reasons. In this case, the final cleanup might fail but the new
- # file should still install successfully.
- {
- test ! -f "$dst" ||
- $doit $rmcmd -f "$dst" 2>/dev/null ||
- { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
- { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
- } ||
- { echo "$0: cannot unlink or rename $dst" >&2
- (exit 1); exit 1
- }
- } &&
-
- # Now rename the file to the real destination.
- $doit $mvcmd "$dsttmp" "$dst"
- }
- fi || exit 1
-
- trap '' 0
- fi
-done
-
-# Local variables:
-# eval: (add-hook 'write-file-hooks 'time-stamp)
-# time-stamp-start: "scriptversion="
-# time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-end: "$"
-# End:
diff --git a/crawl-ref/source/util/pcre/libpcre.pc.in b/crawl-ref/source/util/pcre/libpcre.pc.in
deleted file mode 100644
index 0683cb0e6d..0000000000
--- a/crawl-ref/source/util/pcre/libpcre.pc.in
+++ /dev/null
@@ -1,12 +0,0 @@
-# Package Information for pkg-config
-
-prefix=@prefix@
-exec_prefix=@exec_prefix@
-libdir=@libdir@
-includedir=@includedir@
-
-Name: libpcre
-Description: PCRE - Perl compatible regular expressions C library
-Version: @PACKAGE_VERSION@
-Libs: -L${libdir} -lpcre
-Cflags: -I${includedir}
diff --git a/crawl-ref/source/util/pcre/libpcrecpp.pc.in b/crawl-ref/source/util/pcre/libpcrecpp.pc.in
deleted file mode 100644
index 204a144df9..0000000000
--- a/crawl-ref/source/util/pcre/libpcrecpp.pc.in
+++ /dev/null
@@ -1,12 +0,0 @@
-# Package Information for pkg-config
-
-prefix=@prefix@
-exec_prefix=@exec_prefix@
-libdir=@libdir@
-includedir=@includedir@
-
-Name: libpcrecpp
-Description: PCRECPP - C++ wrapper for PCRE
-Version: @PACKAGE_VERSION@
-Libs: -L${libdir} -lpcre -lpcrecpp
-Cflags: -I${includedir}
diff --git a/crawl-ref/source/util/pcre/ltmain.sh b/crawl-ref/source/util/pcre/ltmain.sh
deleted file mode 100644
index e589475dd9..0000000000
--- a/crawl-ref/source/util/pcre/ltmain.sh
+++ /dev/null
@@ -1,6975 +0,0 @@
-# ltmain.sh - Provide generalized library-building support services.
-# NOTE: Changing this file will not affect anything until you rerun configure.
-#
-# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006,
-# 2007, 2008 Free Software Foundation, Inc.
-# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# As a special exception to the GNU General Public License, if you
-# distribute this file as part of a program that contains a
-# configuration script generated by Autoconf, you may include it under
-# the same distribution terms that you use for the rest of that program.
-
-basename="s,^.*/,,g"
-
-# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh
-# is ksh but when the shell is invoked as "sh" and the current value of
-# the _XPG environment variable is not equal to 1 (one), the special
-# positional parameter $0, within a function call, is the name of the
-# function.
-progpath="$0"
-
-# The name of this program:
-progname=`echo "$progpath" | $SED $basename`
-modename="$progname"
-
-# Global variables:
-EXIT_SUCCESS=0
-EXIT_FAILURE=1
-
-PROGRAM=ltmain.sh
-PACKAGE=libtool
-VERSION=1.5.26
-TIMESTAMP=" (1.1220.2.493 2008/02/01 16:58:18)"
-
-# Be Bourne compatible (taken from Autoconf:_AS_BOURNE_COMPATIBLE).
-if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
- emulate sh
- NULLCMD=:
- # Zsh 3.x and 4.x performs 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
-BIN_SH=xpg4; export BIN_SH # for Tru64
-DUALCASE=1; export DUALCASE # for MKS sh
-
-# Check that we have a working $echo.
-if test "X$1" = X--no-reexec; then
- # Discard the --no-reexec flag, and continue.
- shift
-elif test "X$1" = X--fallback-echo; then
- # Avoid inline document here, it may be left over
- :
-elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then
- # Yippee, $echo works!
- :
-else
- # Restart under the correct shell, and then maybe $echo will work.
- exec $SHELL "$progpath" --no-reexec ${1+"$@"}
-fi
-
-if test "X$1" = X--fallback-echo; then
- # used as fallback echo
- shift
- cat <<EOF
-$*
-EOF
- exit $EXIT_SUCCESS
-fi
-
-default_mode=
-help="Try \`$progname --help' for more information."
-magic="%%%MAGIC variable%%%"
-mkdir="mkdir"
-mv="mv -f"
-rm="rm -f"
-
-# Sed substitution that helps us do robust quoting. It backslashifies
-# metacharacters that are still active within double-quoted strings.
-Xsed="${SED}"' -e 1s/^X//'
-sed_quote_subst='s/\([\\`\\"$\\\\]\)/\\\1/g'
-# test EBCDIC or ASCII
-case `echo X|tr X '\101'` in
- A) # ASCII based system
- # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr
- SP2NL='tr \040 \012'
- NL2SP='tr \015\012 \040\040'
- ;;
- *) # EBCDIC based system
- SP2NL='tr \100 \n'
- NL2SP='tr \r\n \100\100'
- ;;
-esac
-
-# NLS nuisances.
-# Only set LANG and LC_ALL to C if already set.
-# These must not be set unconditionally because not all systems understand
-# e.g. LANG=C (notably SCO).
-# We save the old values to restore during execute mode.
-lt_env=
-for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
-do
- eval "if test \"\${$lt_var+set}\" = set; then
- save_$lt_var=\$$lt_var
- lt_env=\"$lt_var=\$$lt_var \$lt_env\"
- $lt_var=C
- export $lt_var
- fi"
-done
-
-if test -n "$lt_env"; then
- lt_env="env $lt_env"
-fi
-
-# Make sure IFS has a sensible default
-lt_nl='
-'
-IFS=" $lt_nl"
-
-if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then
- $echo "$modename: not configured to build any kind of library" 1>&2
- $echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2
- exit $EXIT_FAILURE
-fi
-
-# Global variables.
-mode=$default_mode
-nonopt=
-prev=
-prevopt=
-run=
-show="$echo"
-show_help=
-execute_dlfiles=
-duplicate_deps=no
-preserve_args=
-lo2o="s/\\.lo\$/.${objext}/"
-o2lo="s/\\.${objext}\$/.lo/"
-extracted_archives=
-extracted_serial=0
-
-#####################################
-# Shell function definitions:
-# This seems to be the best place for them
-
-# func_mktempdir [string]
-# Make a temporary directory that won't clash with other running
-# libtool processes, and avoids race conditions if possible. If
-# given, STRING is the basename for that directory.
-func_mktempdir ()
-{
- my_template="${TMPDIR-/tmp}/${1-$progname}"
-
- if test "$run" = ":"; then
- # Return a directory name, but don't create it in dry-run mode
- my_tmpdir="${my_template}-$$"
- else
-
- # If mktemp works, use that first and foremost
- my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null`
-
- if test ! -d "$my_tmpdir"; then
- # Failing that, at least try and use $RANDOM to avoid a race
- my_tmpdir="${my_template}-${RANDOM-0}$$"
-
- save_mktempdir_umask=`umask`
- umask 0077
- $mkdir "$my_tmpdir"
- umask $save_mktempdir_umask
- fi
-
- # If we're not in dry-run mode, bomb out on failure
- test -d "$my_tmpdir" || {
- $echo "cannot create temporary directory \`$my_tmpdir'" 1>&2
- exit $EXIT_FAILURE
- }
- fi
-
- $echo "X$my_tmpdir" | $Xsed
-}
-
-
-# func_win32_libid arg
-# return the library type of file 'arg'
-#
-# Need a lot of goo to handle *both* DLLs and import libs
-# Has to be a shell function in order to 'eat' the argument
-# that is supplied when $file_magic_command is called.
-func_win32_libid ()
-{
- win32_libid_type="unknown"
- win32_fileres=`file -L $1 2>/dev/null`
- case $win32_fileres in
- *ar\ archive\ import\ library*) # definitely import
- win32_libid_type="x86 archive import"
- ;;
- *ar\ archive*) # could be an import, or static
- if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | \
- $EGREP -e 'file format pe-i386(.*architecture: i386)?' >/dev/null ; then
- win32_nmres=`eval $NM -f posix -A $1 | \
- $SED -n -e '1,100{
- / I /{
- s,.*,import,
- p
- q
- }
- }'`
- case $win32_nmres in
- import*) win32_libid_type="x86 archive import";;
- *) win32_libid_type="x86 archive static";;
- esac
- fi
- ;;
- *DLL*)
- win32_libid_type="x86 DLL"
- ;;
- *executable*) # but shell scripts are "executable" too...
- case $win32_fileres in
- *MS\ Windows\ PE\ Intel*)
- win32_libid_type="x86 DLL"
- ;;
- esac
- ;;
- esac
- $echo $win32_libid_type
-}
-
-
-# func_infer_tag arg
-# Infer tagged configuration to use if any are available and
-# if one wasn't chosen via the "--tag" command line option.
-# Only attempt this if the compiler in the base compile
-# command doesn't match the default compiler.
-# arg is usually of the form 'gcc ...'
-func_infer_tag ()
-{
- if test -n "$available_tags" && test -z "$tagname"; then
- CC_quoted=
- for arg in $CC; do
- case $arg in
- *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
- arg="\"$arg\""
- ;;
- esac
- CC_quoted="$CC_quoted $arg"
- done
- case $@ in
- # Blanks in the command may have been stripped by the calling shell,
- # but not from the CC environment variable when configure was run.
- " $CC "* | "$CC "* | " `$echo $CC` "* | "`$echo $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$echo $CC_quoted` "* | "`$echo $CC_quoted` "*) ;;
- # Blanks at the start of $base_compile will cause this to fail
- # if we don't check for them as well.
- *)
- for z in $available_tags; do
- if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then
- # Evaluate the configuration.
- eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`"
- CC_quoted=
- for arg in $CC; do
- # Double-quote args containing other shell metacharacters.
- case $arg in
- *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
- arg="\"$arg\""
- ;;
- esac
- CC_quoted="$CC_quoted $arg"
- done
- # user sometimes does CC=<HOST>-gcc so we need to match that to 'gcc'
- trimedcc=`echo ${CC} | $SED -e "s/${host}-//g"`
- # and sometimes libtool has CC=<HOST>-gcc but user does CC=gcc
- extendcc=${host}-${CC}
- # and sometimes libtool has CC=<OLDHOST>-gcc but user has CC=<NEWHOST>-gcc
- # (Gentoo-specific hack because we always export $CHOST)
- mungedcc=${CHOST-${host}}-${trimedcc}
- case "$@ " in
- "cc "* | " cc "* | "${host}-cc "* | " ${host}-cc "*|\
- "gcc "* | " gcc "* | "${host}-gcc "* | " ${host}-gcc "*)
- tagname=CC
- break ;;
- "$trimedcc "* | " $trimedcc "* | "`$echo $trimedcc` "* | " `$echo $trimedcc` "*|\
- "$extendcc "* | " $extendcc "* | "`$echo $extendcc` "* | " `$echo $extendcc` "*|\
- "$mungedcc "* | " $mungedcc "* | "`$echo $mungedcc` "* | " `$echo $mungedcc` "*|\
- " $CC "* | "$CC "* | " `$echo $CC` "* | "`$echo $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$echo $CC_quoted` "* | "`$echo $CC_quoted` "*)
- # The compiler in the base compile command matches
- # the one in the tagged configuration.
- # Assume this is the tagged configuration we want.
- tagname=$z
- break
- ;;
- esac
- fi
- done
- # If $tagname still isn't set, then no tagged configuration
- # was found and let the user know that the "--tag" command
- # line option must be used.
- if test -z "$tagname"; then
- $echo "$modename: unable to infer tagged configuration"
- $echo "$modename: specify a tag with \`--tag'" 1>&2
- exit $EXIT_FAILURE
-# else
-# $echo "$modename: using $tagname tagged configuration"
- fi
- ;;
- esac
- fi
-}
-
-
-# func_extract_an_archive dir oldlib
-func_extract_an_archive ()
-{
- f_ex_an_ar_dir="$1"; shift
- f_ex_an_ar_oldlib="$1"
-
- $show "(cd $f_ex_an_ar_dir && $AR x $f_ex_an_ar_oldlib)"
- $run eval "(cd \$f_ex_an_ar_dir && $AR x \$f_ex_an_ar_oldlib)" || exit $?
- if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then
- :
- else
- $echo "$modename: ERROR: object name conflicts: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" 1>&2
- exit $EXIT_FAILURE
- fi
-}
-
-# func_extract_archives gentop oldlib ...
-func_extract_archives ()
-{
- my_gentop="$1"; shift
- my_oldlibs=${1+"$@"}
- my_oldobjs=""
- my_xlib=""
- my_xabs=""
- my_xdir=""
- my_status=""
-
- $show "${rm}r $my_gentop"
- $run ${rm}r "$my_gentop"
- $show "$mkdir $my_gentop"
- $run $mkdir "$my_gentop"
- my_status=$?
- if test "$my_status" -ne 0 && test ! -d "$my_gentop"; then
- exit $my_status
- fi
-
- for my_xlib in $my_oldlibs; do
- # Extract the objects.
- case $my_xlib in
- [\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;;
- *) my_xabs=`pwd`"/$my_xlib" ;;
- esac
- my_xlib=`$echo "X$my_xlib" | $Xsed -e 's%^.*/%%'`
- my_xlib_u=$my_xlib
- while :; do
- case " $extracted_archives " in
- *" $my_xlib_u "*)
- extracted_serial=`expr $extracted_serial + 1`
- my_xlib_u=lt$extracted_serial-$my_xlib ;;
- *) break ;;
- esac
- done
- extracted_archives="$extracted_archives $my_xlib_u"
- my_xdir="$my_gentop/$my_xlib_u"
-
- $show "${rm}r $my_xdir"
- $run ${rm}r "$my_xdir"
- $show "$mkdir $my_xdir"
- $run $mkdir "$my_xdir"
- exit_status=$?
- if test "$exit_status" -ne 0 && test ! -d "$my_xdir"; then
- exit $exit_status
- fi
- case $host in
- *-darwin*)
- $show "Extracting $my_xabs"
- # Do not bother doing anything if just a dry run
- if test -z "$run"; then
- darwin_orig_dir=`pwd`
- cd $my_xdir || exit $?
- darwin_archive=$my_xabs
- darwin_curdir=`pwd`
- darwin_base_archive=`$echo "X$darwin_archive" | $Xsed -e 's%^.*/%%'`
- darwin_arches=`lipo -info "$darwin_archive" 2>/dev/null | $EGREP Architectures 2>/dev/null`
- if test -n "$darwin_arches"; then
- darwin_arches=`echo "$darwin_arches" | $SED -e 's/.*are://'`
- darwin_arch=
- $show "$darwin_base_archive has multiple architectures $darwin_arches"
- for darwin_arch in $darwin_arches ; do
- mkdir -p "unfat-$$/${darwin_base_archive}-${darwin_arch}"
- lipo -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}"
- cd "unfat-$$/${darwin_base_archive}-${darwin_arch}"
- func_extract_an_archive "`pwd`" "${darwin_base_archive}"
- cd "$darwin_curdir"
- $rm "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}"
- done # $darwin_arches
- ## Okay now we have a bunch of thin objects, gotta fatten them up :)
- darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print| xargs basename | sort -u | $NL2SP`
- darwin_file=
- darwin_files=
- for darwin_file in $darwin_filelist; do
- darwin_files=`find unfat-$$ -name $darwin_file -print | $NL2SP`
- lipo -create -output "$darwin_file" $darwin_files
- done # $darwin_filelist
- ${rm}r unfat-$$
- cd "$darwin_orig_dir"
- else
- cd "$darwin_orig_dir"
- func_extract_an_archive "$my_xdir" "$my_xabs"
- fi # $darwin_arches
- fi # $run
- ;;
- *)
- func_extract_an_archive "$my_xdir" "$my_xabs"
- ;;
- esac
- my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | $NL2SP`
- done
- func_extract_archives_result="$my_oldobjs"
-}
-# End of Shell function definitions
-#####################################
-
-# Darwin sucks
-eval std_shrext=\"$shrext_cmds\"
-
-disable_libs=no
-
-# Parse our command line options once, thoroughly.
-while test "$#" -gt 0
-do
- arg="$1"
- shift
-
- case $arg in
- -*=*) optarg=`$echo "X$arg" | $Xsed -e 's/[-_a-zA-Z0-9]*=//'` ;;
- *) optarg= ;;
- esac
-
- # If the previous option needs an argument, assign it.
- if test -n "$prev"; then
- case $prev in
- execute_dlfiles)
- execute_dlfiles="$execute_dlfiles $arg"
- ;;
- tag)
- tagname="$arg"
- preserve_args="${preserve_args}=$arg"
-
- # Check whether tagname contains only valid characters
- case $tagname in
- *[!-_A-Za-z0-9,/]*)
- $echo "$progname: invalid tag name: $tagname" 1>&2
- exit $EXIT_FAILURE
- ;;
- esac
-
- case $tagname in
- CC)
- # Don't test for the "default" C tag, as we know, it's there, but
- # not specially marked.
- ;;
- *)
- if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$" < "$progpath" > /dev/null; then
- taglist="$taglist $tagname"
- # Evaluate the configuration.
- eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$tagname'$/,/^# ### END LIBTOOL TAG CONFIG: '$tagname'$/p' < $progpath`"
- else
- $echo "$progname: ignoring unknown tag $tagname" 1>&2
- fi
- ;;
- esac
- ;;
- *)
- eval "$prev=\$arg"
- ;;
- esac
-
- prev=
- prevopt=
- continue
- fi
-
- # Have we seen a non-optional argument yet?
- case $arg in
- --help)
- show_help=yes
- ;;
-
- --version)
- echo "\
-$PROGRAM (GNU $PACKAGE) $VERSION$TIMESTAMP
-
-Copyright (C) 2008 Free Software Foundation, Inc.
-This is free software; see the source for copying conditions. There is NO
-warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
- exit $?
- ;;
-
- --config)
- ${SED} -e '1,/^# ### BEGIN LIBTOOL CONFIG/d' -e '/^# ### END LIBTOOL CONFIG/,$d' $progpath
- # Now print the configurations for the tags.
- for tagname in $taglist; do
- ${SED} -n -e "/^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$/,/^# ### END LIBTOOL TAG CONFIG: $tagname$/p" < "$progpath"
- done
- exit $?
- ;;
-
- --debug)
- $echo "$progname: enabling shell trace mode"
- set -x
- preserve_args="$preserve_args $arg"
- ;;
-
- --dry-run | -n)
- run=:
- ;;
-
- --features)
- $echo "host: $host"
- if test "$build_libtool_libs" = yes; then
- $echo "enable shared libraries"
- else
- $echo "disable shared libraries"
- fi
- if test "$build_old_libs" = yes; then
- $echo "enable static libraries"
- else
- $echo "disable static libraries"
- fi
- exit $?
- ;;
-
- --finish) mode="finish" ;;
-
- --mode) prevopt="--mode" prev=mode ;;
- --mode=*) mode="$optarg" ;;
-
- --preserve-dup-deps) duplicate_deps="yes" ;;
-
- --quiet | --silent)
- show=:
- preserve_args="$preserve_args $arg"
- ;;
-
- --tag)
- prevopt="--tag"
- prev=tag
- preserve_args="$preserve_args --tag"
- ;;
- --tag=*)
- set tag "$optarg" ${1+"$@"}
- shift
- prev=tag
- preserve_args="$preserve_args --tag"
- ;;
-
- -dlopen)
- prevopt="-dlopen"
- prev=execute_dlfiles
- ;;
-
- -*)
- $echo "$modename: unrecognized option \`$arg'" 1>&2
- $echo "$help" 1>&2
- exit $EXIT_FAILURE
- ;;
-
- *)
- nonopt="$arg"
- break
- ;;
- esac
-done
-
-if test -n "$prevopt"; then
- $echo "$modename: option \`$prevopt' requires an argument" 1>&2
- $echo "$help" 1>&2
- exit $EXIT_FAILURE
-fi
-
-case $disable_libs in
-no)
- ;;
-shared)
- build_libtool_libs=no
- build_old_libs=yes
- ;;
-static)
- build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac`
- ;;
-esac
-
-# If this variable is set in any of the actions, the command in it
-# will be execed at the end. This prevents here-documents from being
-# left over by shells.
-exec_cmd=
-
-if test -z "$show_help"; then
-
- # Infer the operation mode.
- if test -z "$mode"; then
- $echo "*** Warning: inferring the mode of operation is deprecated." 1>&2
- $echo "*** Future versions of Libtool will require --mode=MODE be specified." 1>&2
- case $nonopt in
- *cc | cc* | *++ | gcc* | *-gcc* | g++* | xlc*)
- mode=link
- for arg
- do
- case $arg in
- -c)
- mode=compile
- break
- ;;
- esac
- done
- ;;
- *db | *dbx | *strace | *truss)
- mode=execute
- ;;
- *install*|cp|mv)
- mode=install
- ;;
- *rm)
- mode=uninstall
- ;;
- *)
- # If we have no mode, but dlfiles were specified, then do execute mode.
- test -n "$execute_dlfiles" && mode=execute
-
- # Just use the default operation mode.
- if test -z "$mode"; then
- if test -n "$nonopt"; then
- $echo "$modename: warning: cannot infer operation mode from \`$nonopt'" 1>&2
- else
- $echo "$modename: warning: cannot infer operation mode without MODE-ARGS" 1>&2
- fi
- fi
- ;;
- esac
- fi
-
- # Only execute mode is allowed to have -dlopen flags.
- if test -n "$execute_dlfiles" && test "$mode" != execute; then
- $echo "$modename: unrecognized option \`-dlopen'" 1>&2
- $echo "$help" 1>&2
- exit $EXIT_FAILURE
- fi
-
- # Change the help message to a mode-specific one.
- generic_help="$help"
- help="Try \`$modename --help --mode=$mode' for more information."
-
- # These modes are in order of execution frequency so that they run quickly.
- case $mode in
- # libtool compile mode
- compile)
- modename="$modename: compile"
- # Get the compilation command and the source file.
- base_compile=
- srcfile="$nonopt" # always keep a non-empty value in "srcfile"
- suppress_opt=yes
- suppress_output=
- arg_mode=normal
- libobj=
- later=
-
- for arg
- do
- case $arg_mode in
- arg )
- # do not "continue". Instead, add this to base_compile
- lastarg="$arg"
- arg_mode=normal
- ;;
-
- target )
- libobj="$arg"
- arg_mode=normal
- continue
- ;;
-
- normal )
- # Accept any command-line options.
- case $arg in
- -o)
- if test -n "$libobj" ; then
- $echo "$modename: you cannot specify \`-o' more than once" 1>&2
- exit $EXIT_FAILURE
- fi
- arg_mode=target
- continue
- ;;
-
- -static | -prefer-pic | -prefer-non-pic)
- later="$later $arg"
- continue
- ;;
-
- -no-suppress)
- suppress_opt=no
- continue
- ;;
-
- -Xcompiler)
- arg_mode=arg # the next one goes into the "base_compile" arg list
- continue # The current "srcfile" will either be retained or
- ;; # replaced later. I would guess that would be a bug.
-
- -Wc,*)
- args=`$echo "X$arg" | $Xsed -e "s/^-Wc,//"`
- lastarg=
- save_ifs="$IFS"; IFS=','
- for arg in $args; do
- IFS="$save_ifs"
-
- # Double-quote args containing other shell metacharacters.
- # Many Bourne shells cannot handle close brackets correctly
- # in scan sets, so we specify it separately.
- case $arg in
- *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
- arg="\"$arg\""
- ;;
- esac
- lastarg="$lastarg $arg"
- done
- IFS="$save_ifs"
- lastarg=`$echo "X$lastarg" | $Xsed -e "s/^ //"`
-
- # Add the arguments to base_compile.
- base_compile="$base_compile $lastarg"
- continue
- ;;
-
- * )
- # Accept the current argument as the source file.
- # The previous "srcfile" becomes the current argument.
- #
- lastarg="$srcfile"
- srcfile="$arg"
- ;;
- esac # case $arg
- ;;
- esac # case $arg_mode
-
- # Aesthetically quote the previous argument.
- lastarg=`$echo "X$lastarg" | $Xsed -e "$sed_quote_subst"`
-
- case $lastarg in
- # Double-quote args containing other shell metacharacters.
- # Many Bourne shells cannot handle close brackets correctly
- # in scan sets, and some SunOS ksh mistreat backslash-escaping
- # in scan sets (worked around with variable expansion),
- # and furthermore cannot handle '|' '&' '(' ')' in scan sets
- # at all, so we specify them separately.
- *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
- lastarg="\"$lastarg\""
- ;;
- esac
-
- base_compile="$base_compile $lastarg"
- done # for arg
-
- case $arg_mode in
- arg)
- $echo "$modename: you must specify an argument for -Xcompile"
- exit $EXIT_FAILURE
- ;;
- target)
- $echo "$modename: you must specify a target with \`-o'" 1>&2
- exit $EXIT_FAILURE
- ;;
- *)
- # Get the name of the library object.
- [ -z "$libobj" ] && libobj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%'`
- ;;
- esac
-
- # Recognize several different file suffixes.
- # If the user specifies -o file.o, it is replaced with file.lo
- xform='[cCFSifmso]'
- case $libobj in
- *.ada) xform=ada ;;
- *.adb) xform=adb ;;
- *.ads) xform=ads ;;
- *.asm) xform=asm ;;
- *.c++) xform=c++ ;;
- *.cc) xform=cc ;;
- *.ii) xform=ii ;;
- *.class) xform=class ;;
- *.cpp) xform=cpp ;;
- *.cxx) xform=cxx ;;
- *.[fF][09]?) xform=[fF][09]. ;;
- *.for) xform=for ;;
- *.java) xform=java ;;
- *.obj) xform=obj ;;
- *.sx) xform=sx ;;
- esac
-
- libobj=`$echo "X$libobj" | $Xsed -e "s/\.$xform$/.lo/"`
-
- case $libobj in
- *.lo) obj=`$echo "X$libobj" | $Xsed -e "$lo2o"` ;;
- *)
- $echo "$modename: cannot determine name of library object from \`$libobj'" 1>&2
- exit $EXIT_FAILURE
- ;;
- esac
-
- func_infer_tag $base_compile
-
- for arg in $later; do
- case $arg in
- -static)
- build_old_libs=yes
- continue
- ;;
-
- -prefer-pic)
- pic_mode=yes
- continue
- ;;
-
- -prefer-non-pic)
- pic_mode=no
- continue
- ;;
- esac
- done
-
- qlibobj=`$echo "X$libobj" | $Xsed -e "$sed_quote_subst"`
- case $qlibobj in
- *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
- qlibobj="\"$qlibobj\"" ;;
- esac
- test "X$libobj" != "X$qlibobj" \
- && $echo "X$libobj" | grep '[]~#^*{};<>?"'"'"' &()|`$[]' \
- && $echo "$modename: libobj name \`$libobj' may not contain shell special characters."
- objname=`$echo "X$obj" | $Xsed -e 's%^.*/%%'`
- xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'`
- if test "X$xdir" = "X$obj"; then
- xdir=
- else
- xdir=$xdir/
- fi
- lobj=${xdir}$objdir/$objname
-
- if test -z "$base_compile"; then
- $echo "$modename: you must specify a compilation command" 1>&2
- $echo "$help" 1>&2
- exit $EXIT_FAILURE
- fi
-
- # Delete any leftover library objects.
- if test "$build_old_libs" = yes; then
- removelist="$obj $lobj $libobj ${libobj}T"
- else
- removelist="$lobj $libobj ${libobj}T"
- fi
-
- $run $rm $removelist
- trap "$run $rm $removelist; exit $EXIT_FAILURE" 1 2 15
-
- # On Cygwin there's no "real" PIC flag so we must build both object types
- case $host_os in
- cygwin* | mingw* | pw32* | os2*)
- pic_mode=default
- ;;
- esac
- if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then
- # non-PIC code in shared libraries is not supported
- pic_mode=default
- fi
-
- # Calculate the filename of the output object if compiler does
- # not support -o with -c
- if test "$compiler_c_o" = no; then
- output_obj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\.[^.]*$%%'`.${objext}
- lockfile="$output_obj.lock"
- removelist="$removelist $output_obj $lockfile"
- trap "$run $rm $removelist; exit $EXIT_FAILURE" 1 2 15
- else
- output_obj=
- need_locks=no
- lockfile=
- fi
-
- # Lock this critical section if it is needed
- # We use this script file to make the link, it avoids creating a new file
- if test "$need_locks" = yes; then
- until $run ln "$srcfile" "$lockfile" 2>/dev/null; do
- $show "Waiting for $lockfile to be removed"
- sleep 2
- done
- elif test "$need_locks" = warn; then
- if test -f "$lockfile"; then
- $echo "\
-*** ERROR, $lockfile exists and contains:
-`cat $lockfile 2>/dev/null`
-
-This indicates that another process is trying to use the same
-temporary object file, and libtool could not work around it because
-your compiler does not support \`-c' and \`-o' together. If you
-repeat this compilation, it may succeed, by chance, but you had better
-avoid parallel builds (make -j) in this platform, or get a better
-compiler."
-
- $run $rm $removelist
- exit $EXIT_FAILURE
- fi
- $echo "$srcfile" > "$lockfile"
- fi
-
- if test -n "$fix_srcfile_path"; then
- eval srcfile=\"$fix_srcfile_path\"
- fi
- qsrcfile=`$echo "X$srcfile" | $Xsed -e "$sed_quote_subst"`
- case $qsrcfile in
- *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
- qsrcfile="\"$qsrcfile\"" ;;
- esac
-
- $run $rm "$libobj" "${libobj}T"
-
- # Create a libtool object file (analogous to a ".la" file),
- # but don't create it if we're doing a dry run.
- test -z "$run" && cat > ${libobj}T <<EOF
-# $libobj - a libtool object file
-# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP
-#
-# Please DO NOT delete this file!
-# It is necessary for linking the library.
-
-# Name of the PIC object.
-EOF
-
- # Only build a PIC object if we are building libtool libraries.
- if test "$build_libtool_libs" = yes; then
- # Without this assignment, base_compile gets emptied.
- fbsd_hideous_sh_bug=$base_compile
-
- if test "$pic_mode" != no; then
- command="$base_compile $qsrcfile $pic_flag"
- else
- # Don't build PIC code
- command="$base_compile $qsrcfile"
- fi
-
- if test ! -d "${xdir}$objdir"; then
- $show "$mkdir ${xdir}$objdir"
- $run $mkdir ${xdir}$objdir
- exit_status=$?
- if test "$exit_status" -ne 0 && test ! -d "${xdir}$objdir"; then
- exit $exit_status
- fi
- fi
-
- if test -z "$output_obj"; then
- # Place PIC objects in $objdir
- command="$command -o $lobj"
- fi
-
- $run $rm "$lobj" "$output_obj"
-
- $show "$command"
- if $run eval $lt_env "$command"; then :
- else
- test -n "$output_obj" && $run $rm $removelist
- exit $EXIT_FAILURE
- fi
-
- if test "$need_locks" = warn &&
- test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
- $echo "\
-*** ERROR, $lockfile contains:
-`cat $lockfile 2>/dev/null`
-
-but it should contain:
-$srcfile
-
-This indicates that another process is trying to use the same
-temporary object file, and libtool could not work around it because
-your compiler does not support \`-c' and \`-o' together. If you
-repeat this compilation, it may succeed, by chance, but you had better
-avoid parallel builds (make -j) in this platform, or get a better
-compiler."
-
- $run $rm $removelist
- exit $EXIT_FAILURE
- fi
-
- # Just move the object if needed, then go on to compile the next one
- if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then
- $show "$mv $output_obj $lobj"
- if $run $mv $output_obj $lobj; then :
- else
- error=$?
- $run $rm $removelist
- exit $error
- fi
- fi
-
- # Append the name of the PIC object to the libtool object file.
- test -z "$run" && cat >> ${libobj}T <<EOF
-pic_object='$objdir/$objname'
-
-EOF
-
- # Allow error messages only from the first compilation.
- if test "$suppress_opt" = yes; then
- suppress_output=' >/dev/null 2>&1'
- fi
- else
- # No PIC object so indicate it doesn't exist in the libtool
- # object file.
- test -z "$run" && cat >> ${libobj}T <<EOF
-pic_object=none
-
-EOF
- fi
-
- # Only build a position-dependent object if we build old libraries.
- if test "$build_old_libs" = yes; then
- if test "$pic_mode" != yes; then
- # Don't build PIC code
- command="$base_compile $qsrcfile"
- else
- command="$base_compile $qsrcfile $pic_flag"
- fi
- if test "$compiler_c_o" = yes; then
- command="$command -o $obj"
- fi
-
- # Suppress compiler output if we already did a PIC compilation.
- command="$command$suppress_output"
- $run $rm "$obj" "$output_obj"
- $show "$command"
- if $run eval $lt_env "$command"; then :
- else
- $run $rm $removelist
- exit $EXIT_FAILURE
- fi
-
- if test "$need_locks" = warn &&
- test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
- $echo "\
-*** ERROR, $lockfile contains:
-`cat $lockfile 2>/dev/null`
-
-but it should contain:
-$srcfile
-
-This indicates that another process is trying to use the same
-temporary object file, and libtool could not work around it because
-your compiler does not support \`-c' and \`-o' together. If you
-repeat this compilation, it may succeed, by chance, but you had better
-avoid parallel builds (make -j) in this platform, or get a better
-compiler."
-
- $run $rm $removelist
- exit $EXIT_FAILURE
- fi
-
- # Just move the object if needed
- if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then
- $show "$mv $output_obj $obj"
- if $run $mv $output_obj $obj; then :
- else
- error=$?
- $run $rm $removelist
- exit $error
- fi
- fi
-
- # Append the name of the non-PIC object the libtool object file.
- # Only append if the libtool object file exists.
- test -z "$run" && cat >> ${libobj}T <<EOF
-# Name of the non-PIC object.
-non_pic_object='$objname'
-
-EOF
- else
- # Append the name of the non-PIC object the libtool object file.
- # Only append if the libtool object file exists.
- test -z "$run" && cat >> ${libobj}T <<EOF
-# Name of the non-PIC object.
-non_pic_object=none
-
-EOF
- fi
-
- $run $mv "${libobj}T" "${libobj}"
-
- # Unlock the critical section if it was locked
- if test "$need_locks" != no; then
- $run $rm "$lockfile"
- fi
-
- exit $EXIT_SUCCESS
- ;;
-
- # libtool link mode
- link | relink)
- modename="$modename: link"
- case $host in
- *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*)
- # It is impossible to link a dll without this setting, and
- # we shouldn't force the makefile maintainer to figure out
- # which system we are compiling for in order to pass an extra
- # flag for every libtool invocation.
- # allow_undefined=no
-
- # FIXME: Unfortunately, there are problems with the above when trying
- # to make a dll which has undefined symbols, in which case not
- # even a static library is built. For now, we need to specify
- # -no-undefined on the libtool link line when we can be certain
- # that all symbols are satisfied, otherwise we get a static library.
- allow_undefined=yes
- ;;
- *)
- allow_undefined=yes
- ;;
- esac
- libtool_args="$nonopt"
- base_compile="$nonopt $@"
- compile_command="$nonopt"
- finalize_command="$nonopt"
-
- compile_rpath=
- finalize_rpath=
- compile_shlibpath=
- finalize_shlibpath=
- convenience=
- old_convenience=
- deplibs=
- old_deplibs=
- compiler_flags=
- linker_flags=
- dllsearchpath=
- lib_search_path=`pwd`
- inst_prefix_dir=
-
- avoid_version=no
- dlfiles=
- dlprefiles=
- dlself=no
- export_dynamic=no
- export_symbols=
- export_symbols_regex=
- generated=
- libobjs=
- ltlibs=
- module=no
- no_install=no
- objs=
- non_pic_objects=
- notinst_path= # paths that contain not-installed libtool libraries
- precious_files_regex=
- prefer_static_libs=no
- preload=no
- prev=
- prevarg=
- release=
- rpath=
- xrpath=
- perm_rpath=
- temp_rpath=
- thread_safe=no
- vinfo=
- vinfo_number=no
- single_module="${wl}-single_module"
-
- func_infer_tag $base_compile
-
- # We need to know -static, to get the right output filenames.
- for arg
- do
- case $arg in
- -all-static | -static | -static-libtool-libs)
- case $arg in
- -all-static)
- if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then
- $echo "$modename: warning: complete static linking is impossible in this configuration" 1>&2
- fi
- if test -n "$link_static_flag"; then
- dlopen_self=$dlopen_self_static
- fi
- prefer_static_libs=yes
- ;;
- -static)
- if test -z "$pic_flag" && test -n "$link_static_flag"; then
- dlopen_self=$dlopen_self_static
- fi
- prefer_static_libs=built
- ;;
- -static-libtool-libs)
- if test -z "$pic_flag" && test -n "$link_static_flag"; then
- dlopen_self=$dlopen_self_static
- fi
- prefer_static_libs=yes
- ;;
- esac
- build_libtool_libs=no
- build_old_libs=yes
- break
- ;;
- esac
- done
-
- # See if our shared archives depend on static archives.
- test -n "$old_archive_from_new_cmds" && build_old_libs=yes
-
- # Go through the arguments, transforming them on the way.
- while test "$#" -gt 0; do
- arg="$1"
- shift
- case $arg in
- *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
- qarg=\"`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`\" ### testsuite: skip nested quoting test
- ;;
- *) qarg=$arg ;;
- esac
- libtool_args="$libtool_args $qarg"
-
- # If the previous option needs an argument, assign it.
- if test -n "$prev"; then
- case $prev in
- output)
- compile_command="$compile_command @OUTPUT@"
- finalize_command="$finalize_command @OUTPUT@"
- ;;
- esac
-
- case $prev in
- dlfiles|dlprefiles)
- if test "$preload" = no; then
- # Add the symbol object into the linking commands.
- compile_command="$compile_command @SYMFILE@"
- finalize_command="$finalize_command @SYMFILE@"
- preload=yes
- fi
- case $arg in
- *.la | *.lo) ;; # We handle these cases below.
- force)
- if test "$dlself" = no; then
- dlself=needless
- export_dynamic=yes
- fi
- prev=
- continue
- ;;
- self)
- if test "$prev" = dlprefiles; then
- dlself=yes
- elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then
- dlself=yes
- else
- dlself=needless
- export_dynamic=yes
- fi
- prev=
- continue
- ;;
- *)
- if test "$prev" = dlfiles; then
- dlfiles="$dlfiles $arg"
- else
- dlprefiles="$dlprefiles $arg"
- fi
- prev=
- continue
- ;;
- esac
- ;;
- expsyms)
- export_symbols="$arg"
- if test ! -f "$arg"; then
- $echo "$modename: symbol file \`$arg' does not exist"
- exit $EXIT_FAILURE
- fi
- prev=
- continue
- ;;
- expsyms_regex)
- export_symbols_regex="$arg"
- prev=
- continue
- ;;
- inst_prefix)
- inst_prefix_dir="$arg"
- prev=
- continue
- ;;
- precious_regex)
- precious_files_regex="$arg"
- prev=
- continue
- ;;
- release)
- release="-$arg"
- prev=
- continue
- ;;
- objectlist)
- if test -f "$arg"; then
- save_arg=$arg
- moreargs=
- for fil in `cat $save_arg`
- do
-# moreargs="$moreargs $fil"
- arg=$fil
- # A libtool-controlled object.
-
- # Check to see that this really is a libtool object.
- if (${SED} -e '2q' $arg | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
- pic_object=
- non_pic_object=
-
- # Read the .lo file
- # If there is no directory component, then add one.
- case $arg in
- */* | *\\*) . $arg ;;
- *) . ./$arg ;;
- esac
-
- if test -z "$pic_object" || \
- test -z "$non_pic_object" ||
- test "$pic_object" = none && \
- test "$non_pic_object" = none; then
- $echo "$modename: cannot find name of object for \`$arg'" 1>&2
- exit $EXIT_FAILURE
- fi
-
- # Extract subdirectory from the argument.
- xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'`
- if test "X$xdir" = "X$arg"; then
- xdir=
- else
- xdir="$xdir/"
- fi
-
- if test "$pic_object" != none; then
- # Prepend the subdirectory the object is found in.
- pic_object="$xdir$pic_object"
-
- if test "$prev" = dlfiles; then
- if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then
- dlfiles="$dlfiles $pic_object"
- prev=
- continue
- else
- # If libtool objects are unsupported, then we need to preload.
- prev=dlprefiles
- fi
- fi
-
- # CHECK ME: I think I busted this. -Ossama
- if test "$prev" = dlprefiles; then
- # Preload the old-style object.
- dlprefiles="$dlprefiles $pic_object"
- prev=
- fi
-
- # A PIC object.
- libobjs="$libobjs $pic_object"
- arg="$pic_object"
- fi
-
- # Non-PIC object.
- if test "$non_pic_object" != none; then
- # Prepend the subdirectory the object is found in.
- non_pic_object="$xdir$non_pic_object"
-
- # A standard non-PIC object
- non_pic_objects="$non_pic_objects $non_pic_object"
- if test -z "$pic_object" || test "$pic_object" = none ; then
- arg="$non_pic_object"
- fi
- else
- # If the PIC object exists, use it instead.
- # $xdir was prepended to $pic_object above.
- non_pic_object="$pic_object"
- non_pic_objects="$non_pic_objects $non_pic_object"
- fi
- else
- # Only an error if not doing a dry-run.
- if test -z "$run"; then
- $echo "$modename: \`$arg' is not a valid libtool object" 1>&2
- exit $EXIT_FAILURE
- else
- # Dry-run case.
-
- # Extract subdirectory from the argument.
- xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'`
- if test "X$xdir" = "X$arg"; then
- xdir=
- else
- xdir="$xdir/"
- fi
-
- pic_object=`$echo "X${xdir}${objdir}/${arg}" | $Xsed -e "$lo2o"`
- non_pic_object=`$echo "X${xdir}${arg}" | $Xsed -e "$lo2o"`
- libobjs="$libobjs $pic_object"
- non_pic_objects="$non_pic_objects $non_pic_object"
- fi
- fi
- done
- else
- $echo "$modename: link input file \`$save_arg' does not exist"
- exit $EXIT_FAILURE
- fi
- arg=$save_arg
- prev=
- continue
- ;;
- rpath | xrpath)
- # We need an absolute path.
- case $arg in
- [\\/]* | [A-Za-z]:[\\/]*) ;;
- *)
- $echo "$modename: only absolute run-paths are allowed" 1>&2
- exit $EXIT_FAILURE
- ;;
- esac
- if test "$prev" = rpath; then
- case "$rpath " in
- *" $arg "*) ;;
- *) rpath="$rpath $arg" ;;
- esac
- else
- case "$xrpath " in
- *" $arg "*) ;;
- *) xrpath="$xrpath $arg" ;;
- esac
- fi
- prev=
- continue
- ;;
- xcompiler)
- compiler_flags="$compiler_flags $qarg"
- prev=
- compile_command="$compile_command $qarg"
- finalize_command="$finalize_command $qarg"
- continue
- ;;
- xlinker)
- linker_flags="$linker_flags $qarg"
- compiler_flags="$compiler_flags $wl$qarg"
- prev=
- compile_command="$compile_command $wl$qarg"
- finalize_command="$finalize_command $wl$qarg"
- continue
- ;;
- xcclinker)
- linker_flags="$linker_flags $qarg"
- compiler_flags="$compiler_flags $qarg"
- prev=
- compile_command="$compile_command $qarg"
- finalize_command="$finalize_command $qarg"
- continue
- ;;
- shrext)
- shrext_cmds="$arg"
- prev=
- continue
- ;;
- darwin_framework|darwin_framework_skip)
- test "$prev" = "darwin_framework" && compiler_flags="$compiler_flags $arg"
- compile_command="$compile_command $arg"
- finalize_command="$finalize_command $arg"
- prev=
- continue
- ;;
- *)
- eval "$prev=\"\$arg\""
- prev=
- continue
- ;;
- esac
- fi # test -n "$prev"
-
- prevarg="$arg"
-
- case $arg in
- -all-static)
- if test -n "$link_static_flag"; then
- compile_command="$compile_command $link_static_flag"
- finalize_command="$finalize_command $link_static_flag"
- fi
- continue
- ;;
-
- -allow-undefined)
- # FIXME: remove this flag sometime in the future.
- $echo "$modename: \`-allow-undefined' is deprecated because it is the default" 1>&2
- continue
- ;;
-
- -avoid-version)
- avoid_version=yes
- continue
- ;;
-
- -dlopen)
- prev=dlfiles
- continue
- ;;
-
- -dlpreopen)
- prev=dlprefiles
- continue
- ;;
-
- -export-dynamic)
- export_dynamic=yes
- continue
- ;;
-
- -export-symbols | -export-symbols-regex)
- if test -n "$export_symbols" || test -n "$export_symbols_regex"; then
- $echo "$modename: more than one -exported-symbols argument is not allowed"
- exit $EXIT_FAILURE
- fi
- if test "X$arg" = "X-export-symbols"; then
- prev=expsyms
- else
- prev=expsyms_regex
- fi
- continue
- ;;
-
- -framework|-arch|-isysroot)
- case " $CC " in
- *" ${arg} ${1} "* | *" ${arg} ${1} "*)
- prev=darwin_framework_skip ;;
- *) compiler_flags="$compiler_flags $arg"
- prev=darwin_framework ;;
- esac
- compile_command="$compile_command $arg"
- finalize_command="$finalize_command $arg"
- continue
- ;;
-
- -inst-prefix-dir)
- prev=inst_prefix
- continue
- ;;
-
- # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:*
- # so, if we see these flags be careful not to treat them like -L
- -L[A-Z][A-Z]*:*)
- case $with_gcc/$host in
- no/*-*-irix* | /*-*-irix*)
- compile_command="$compile_command $arg"
- finalize_command="$finalize_command $arg"
- ;;
- esac
- continue
- ;;
-
- -L*)
- dir=`$echo "X$arg" | $Xsed -e 's/^-L//'`
- # We need an absolute path.
- case $dir in
- [\\/]* | [A-Za-z]:[\\/]*) ;;
- *)
- absdir=`cd "$dir" && pwd`
- if test -z "$absdir"; then
- $echo "$modename: cannot determine absolute directory name of \`$dir'" 1>&2
- absdir="$dir"
- notinst_path="$notinst_path $dir"
- fi
- dir="$absdir"
- ;;
- esac
- case "$deplibs " in
- *" -L$dir "*) ;;
- *)
- deplibs="$deplibs -L$dir"
- lib_search_path="$lib_search_path $dir"
- ;;
- esac
- case $host in
- *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*)
- testbindir=`$echo "X$dir" | $Xsed -e 's*/lib$*/bin*'`
- case :$dllsearchpath: in
- *":$dir:"*) ;;
- *) dllsearchpath="$dllsearchpath:$dir";;
- esac
- case :$dllsearchpath: in
- *":$testbindir:"*) ;;
- *) dllsearchpath="$dllsearchpath:$testbindir";;
- esac
- ;;
- esac
- continue
- ;;
-
- -l*)
- if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then
- case $host in
- *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos*)
- # These systems don't actually have a C or math library (as such)
- continue
- ;;
- *-*-os2*)
- # These systems don't actually have a C library (as such)
- test "X$arg" = "X-lc" && continue
- ;;
- *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
- # Do not include libc due to us having libc/libc_r.
- test "X$arg" = "X-lc" && continue
- ;;
- *-*-rhapsody* | *-*-darwin1.[012])
- # Rhapsody C and math libraries are in the System framework
- deplibs="$deplibs -framework System"
- continue
- ;;
- *-*-sco3.2v5* | *-*-sco5v6*)
- # Causes problems with __ctype
- test "X$arg" = "X-lc" && continue
- ;;
- *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)
- # Compiler inserts libc in the correct place for threads to work
- test "X$arg" = "X-lc" && continue
- ;;
- esac
- elif test "X$arg" = "X-lc_r"; then
- case $host in
- *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
- # Do not include libc_r directly, use -pthread flag.
- continue
- ;;
- esac
- fi
- deplibs="$deplibs $arg"
- continue
- ;;
-
- # Tru64 UNIX uses -model [arg] to determine the layout of C++
- # classes, name mangling, and exception handling.
- -model)
- compile_command="$compile_command $arg"
- compiler_flags="$compiler_flags $arg"
- finalize_command="$finalize_command $arg"
- prev=xcompiler
- continue
- ;;
-
- -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads)
- compiler_flags="$compiler_flags $arg"
- compile_command="$compile_command $arg"
- finalize_command="$finalize_command $arg"
- continue
- ;;
-
- -multi_module)
- single_module="${wl}-multi_module"
- continue
- ;;
-
- -module)
- module=yes
- continue
- ;;
-
- # -64, -mips[0-9] enable 64-bit mode on the SGI compiler
- # -r[0-9][0-9]* specifies the processor on the SGI compiler
- # -xarch=*, -xtarget=* enable 64-bit mode on the Sun compiler
- # +DA*, +DD* enable 64-bit mode on the HP compiler
- # -q* pass through compiler args for the IBM compiler
- # -m* pass through architecture-specific compiler args for GCC
- # -m*, -t[45]*, -txscale* pass through architecture-specific
- # compiler args for GCC
- # -p, -pg, --coverage, -fprofile-* pass through profiling flag for GCC
- # -F/path gives path to uninstalled frameworks, gcc on darwin
- # @file GCC response files
- -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \
- -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*)
-
- # Unknown arguments in both finalize_command and compile_command need
- # to be aesthetically quoted because they are evaled later.
- arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
- case $arg in
- *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
- arg="\"$arg\""
- ;;
- esac
- compile_command="$compile_command $arg"
- finalize_command="$finalize_command $arg"
- compiler_flags="$compiler_flags $arg"
- continue
- ;;
-
- -shrext)
- prev=shrext
- continue
- ;;
-
- -no-fast-install)
- fast_install=no
- continue
- ;;
-
- -no-install)
- case $host in
- *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin*)
- # The PATH hackery in wrapper scripts is required on Windows
- # and Darwin in order for the loader to find any dlls it needs.
- $echo "$modename: warning: \`-no-install' is ignored for $host" 1>&2
- $echo "$modename: warning: assuming \`-no-fast-install' instead" 1>&2
- fast_install=no
- ;;
- *) no_install=yes ;;
- esac
- continue
- ;;
-
- -no-undefined)
- allow_undefined=no
- continue
- ;;
-
- -objectlist)
- prev=objectlist
- continue
- ;;
-
- -o) prev=output ;;
-
- -precious-files-regex)
- prev=precious_regex
- continue
- ;;
-
- -release)
- prev=release
- continue
- ;;
-
- -rpath)
- prev=rpath
- continue
- ;;
-
- -R)
- prev=xrpath
- continue
- ;;
-
- -R*)
- dir=`$echo "X$arg" | $Xsed -e 's/^-R//'`
- # We need an absolute path.
- case $dir in
- [\\/]* | [A-Za-z]:[\\/]*) ;;
- *)
- $echo "$modename: only absolute run-paths are allowed" 1>&2
- exit $EXIT_FAILURE
- ;;
- esac
- case "$xrpath " in
- *" $dir "*) ;;
- *) xrpath="$xrpath $dir" ;;
- esac
- continue
- ;;
-
- -static | -static-libtool-libs)
- # The effects of -static are defined in a previous loop.
- # We used to do the same as -all-static on platforms that
- # didn't have a PIC flag, but the assumption that the effects
- # would be equivalent was wrong. It would break on at least
- # Digital Unix and AIX.
- continue
- ;;
-
- -thread-safe)
- thread_safe=yes
- continue
- ;;
-
- -version-info)
- prev=vinfo
- continue
- ;;
- -version-number)
- prev=vinfo
- vinfo_number=yes
- continue
- ;;
-
- -Wc,*)
- args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wc,//'`
- arg=
- save_ifs="$IFS"; IFS=','
- for flag in $args; do
- IFS="$save_ifs"
- case $flag in
- *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
- flag="\"$flag\""
- ;;
- esac
- arg="$arg $wl$flag"
- compiler_flags="$compiler_flags $flag"
- done
- IFS="$save_ifs"
- arg=`$echo "X$arg" | $Xsed -e "s/^ //"`
- ;;
-
- -Wl,*)
- args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wl,//'`
- arg=
- save_ifs="$IFS"; IFS=','
- for flag in $args; do
- IFS="$save_ifs"
- case $flag in
- *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
- flag="\"$flag\""
- ;;
- esac
- arg="$arg $wl$flag"
- compiler_flags="$compiler_flags $wl$flag"
- linker_flags="$linker_flags $flag"
- done
- IFS="$save_ifs"
- arg=`$echo "X$arg" | $Xsed -e "s/^ //"`
- ;;
-
- -Xcompiler)
- prev=xcompiler
- continue
- ;;
-
- -Xlinker)
- prev=xlinker
- continue
- ;;
-
- -XCClinker)
- prev=xcclinker
- continue
- ;;
-
- # Some other compiler flag.
- -* | +*)
- # Unknown arguments in both finalize_command and compile_command need
- # to be aesthetically quoted because they are evaled later.
- arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
- case $arg in
- *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
- arg="\"$arg\""
- ;;
- esac
- ;;
-
- *.$objext)
- # A standard object.
- objs="$objs $arg"
- ;;
-
- *.lo)
- # A libtool-controlled object.
-
- # Check to see that this really is a libtool object.
- if (${SED} -e '2q' $arg | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
- pic_object=
- non_pic_object=
-
- # Read the .lo file
- # If there is no directory component, then add one.
- case $arg in
- */* | *\\*) . $arg ;;
- *) . ./$arg ;;
- esac
-
- if test -z "$pic_object" || \
- test -z "$non_pic_object" ||
- test "$pic_object" = none && \
- test "$non_pic_object" = none; then
- $echo "$modename: cannot find name of object for \`$arg'" 1>&2
- exit $EXIT_FAILURE
- fi
-
- # Extract subdirectory from the argument.
- xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'`
- if test "X$xdir" = "X$arg"; then
- xdir=
- else
- xdir="$xdir/"
- fi
-
- if test "$pic_object" != none; then
- # Prepend the subdirectory the object is found in.
- pic_object="$xdir$pic_object"
-
- if test "$prev" = dlfiles; then
- if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then
- dlfiles="$dlfiles $pic_object"
- prev=
- continue
- else
- # If libtool objects are unsupported, then we need to preload.
- prev=dlprefiles
- fi
- fi
-
- # CHECK ME: I think I busted this. -Ossama
- if test "$prev" = dlprefiles; then
- # Preload the old-style object.
- dlprefiles="$dlprefiles $pic_object"
- prev=
- fi
-
- # A PIC object.
- libobjs="$libobjs $pic_object"
- arg="$pic_object"
- fi
-
- # Non-PIC object.
- if test "$non_pic_object" != none; then
- # Prepend the subdirectory the object is found in.
- non_pic_object="$xdir$non_pic_object"
-
- # A standard non-PIC object
- non_pic_objects="$non_pic_objects $non_pic_object"
- if test -z "$pic_object" || test "$pic_object" = none ; then
- arg="$non_pic_object"
- fi
- else
- # If the PIC object exists, use it instead.
- # $xdir was prepended to $pic_object above.
- non_pic_object="$pic_object"
- non_pic_objects="$non_pic_objects $non_pic_object"
- fi
- else
- # Only an error if not doing a dry-run.
- if test -z "$run"; then
- $echo "$modename: \`$arg' is not a valid libtool object" 1>&2
- exit $EXIT_FAILURE
- else
- # Dry-run case.
-
- # Extract subdirectory from the argument.
- xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'`
- if test "X$xdir" = "X$arg"; then
- xdir=
- else
- xdir="$xdir/"
- fi
-
- pic_object=`$echo "X${xdir}${objdir}/${arg}" | $Xsed -e "$lo2o"`
- non_pic_object=`$echo "X${xdir}${arg}" | $Xsed -e "$lo2o"`
- libobjs="$libobjs $pic_object"
- non_pic_objects="$non_pic_objects $non_pic_object"
- fi
- fi
- ;;
-
- *.$libext)
- # An archive.
- deplibs="$deplibs $arg"
- old_deplibs="$old_deplibs $arg"
- continue
- ;;
-
- *.la)
- # A libtool-controlled library.
-
- if test "$prev" = dlfiles; then
- # This library was specified with -dlopen.
- dlfiles="$dlfiles $arg"
- prev=
- elif test "$prev" = dlprefiles; then
- # The library was specified with -dlpreopen.
- dlprefiles="$dlprefiles $arg"
- prev=
- else
- deplibs="$deplibs $arg"
- fi
- continue
- ;;
-
- # Some other compiler argument.
- *)
- # Unknown arguments in both finalize_command and compile_command need
- # to be aesthetically quoted because they are evaled later.
- arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
- case $arg in
- *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
- arg="\"$arg\""
- ;;
- esac
- ;;
- esac # arg
-
- # Now actually substitute the argument into the commands.
- if test -n "$arg"; then
- compile_command="$compile_command $arg"
- finalize_command="$finalize_command $arg"
- fi
- done # argument parsing loop
-
- if test -n "$prev"; then
- $echo "$modename: the \`$prevarg' option requires an argument" 1>&2
- $echo "$help" 1>&2
- exit $EXIT_FAILURE
- fi
-
- if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then
- eval arg=\"$export_dynamic_flag_spec\"
- compile_command="$compile_command $arg"
- finalize_command="$finalize_command $arg"
- fi
-
- oldlibs=
- # calculate the name of the file, without its directory
- outputname=`$echo "X$output" | $Xsed -e 's%^.*/%%'`
- libobjs_save="$libobjs"
-
- if test -n "$shlibpath_var"; then
- # get the directories listed in $shlibpath_var
- eval shlib_search_path=\`\$echo \"X\${$shlibpath_var}\" \| \$Xsed -e \'s/:/ /g\'\`
- else
- shlib_search_path=
- fi
- eval sys_lib_search_path=\"$sys_lib_search_path_spec\"
- eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\"
-
- output_objdir=`$echo "X$output" | $Xsed -e 's%/[^/]*$%%'`
- if test "X$output_objdir" = "X$output"; then
- output_objdir="$objdir"
- else
- output_objdir="$output_objdir/$objdir"
- fi
- # Create the object directory.
- if test ! -d "$output_objdir"; then
- $show "$mkdir $output_objdir"
- $run $mkdir $output_objdir
- exit_status=$?
- if test "$exit_status" -ne 0 && test ! -d "$output_objdir"; then
- exit $exit_status
- fi
- fi
-
- # Determine the type of output
- case $output in
- "")
- $echo "$modename: you must specify an output file" 1>&2
- $echo "$help" 1>&2
- exit $EXIT_FAILURE
- ;;
- *.$libext) linkmode=oldlib ;;
- *.lo | *.$objext) linkmode=obj ;;
- *.la) linkmode=lib ;;
- *) linkmode=prog ;; # Anything else should be a program.
- esac
-
- case $host in
- *cygwin* | *mingw* | *pw32*)
- # don't eliminate duplications in $postdeps and $predeps
- duplicate_compiler_generated_deps=yes
- ;;
- *)
- duplicate_compiler_generated_deps=$duplicate_deps
- ;;
- esac
- specialdeplibs=
-
- libs=
- # Find all interdependent deplibs by searching for libraries
- # that are linked more than once (e.g. -la -lb -la)
- for deplib in $deplibs; do
- if test "X$duplicate_deps" = "Xyes" ; then
- case "$libs " in
- *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
- esac
- fi
- libs="$libs $deplib"
- done
-
- if test "$linkmode" = lib; then
- libs="$predeps $libs $compiler_lib_search_path $postdeps"
-
- # Compute libraries that are listed more than once in $predeps
- # $postdeps and mark them as special (i.e., whose duplicates are
- # not to be eliminated).
- pre_post_deps=
- if test "X$duplicate_compiler_generated_deps" = "Xyes" ; then
- for pre_post_dep in $predeps $postdeps; do
- case "$pre_post_deps " in
- *" $pre_post_dep "*) specialdeplibs="$specialdeplibs $pre_post_deps" ;;
- esac
- pre_post_deps="$pre_post_deps $pre_post_dep"
- done
- fi
- pre_post_deps=
- fi
-
- deplibs=
- newdependency_libs=
- newlib_search_path=
- need_relink=no # whether we're linking any uninstalled libtool libraries
- notinst_deplibs= # not-installed libtool libraries
- case $linkmode in
- lib)
- passes="conv link"
- for file in $dlfiles $dlprefiles; do
- case $file in
- *.la) ;;
- *)
- $echo "$modename: libraries can \`-dlopen' only libtool libraries: $file" 1>&2
- exit $EXIT_FAILURE
- ;;
- esac
- done
- ;;
- prog)
- compile_deplibs=
- finalize_deplibs=
- alldeplibs=no
- newdlfiles=
- newdlprefiles=
- passes="conv scan dlopen dlpreopen link"
- ;;
- *) passes="conv"
- ;;
- esac
- for pass in $passes; do
- if test "$linkmode,$pass" = "lib,link" ||
- test "$linkmode,$pass" = "prog,scan"; then
- libs="$deplibs"
- deplibs=
- fi
- if test "$linkmode" = prog; then
- case $pass in
- dlopen) libs="$dlfiles" ;;
- dlpreopen) libs="$dlprefiles" ;;
- link) libs="$deplibs %DEPLIBS% $dependency_libs" ;;
- esac
- fi
- if test "$pass" = dlopen; then
- # Collect dlpreopened libraries
- save_deplibs="$deplibs"
- deplibs=
- fi
- for deplib in $libs; do
- lib=
- found=no
- case $deplib in
- -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads)
- if test "$linkmode,$pass" = "prog,link"; then
- compile_deplibs="$deplib $compile_deplibs"
- finalize_deplibs="$deplib $finalize_deplibs"
- else
- compiler_flags="$compiler_flags $deplib"
- fi
- continue
- ;;
- -l*)
- if test "$linkmode" != lib && test "$linkmode" != prog; then
- $echo "$modename: warning: \`-l' is ignored for archives/objects" 1>&2
- continue
- fi
- name=`$echo "X$deplib" | $Xsed -e 's/^-l//'`
- if test "$linkmode" = lib; then
- searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path"
- else
- searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path"
- fi
- for searchdir in $searchdirs; do
- for search_ext in .la $std_shrext .so .a; do
- # Search the libtool library
- lib="$searchdir/lib${name}${search_ext}"
- if test -f "$lib"; then
- if test "$search_ext" = ".la"; then
- found=yes
- else
- found=no
- fi
- break 2
- fi
- done
- done
- if test "$found" != yes; then
- # deplib doesn't seem to be a libtool library
- if test "$linkmode,$pass" = "prog,link"; then
- compile_deplibs="$deplib $compile_deplibs"
- finalize_deplibs="$deplib $finalize_deplibs"
- else
- deplibs="$deplib $deplibs"
- test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs"
- fi
- continue
- else # deplib is a libtool library
- # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib,
- # We need to do some special things here, and not later.
- if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
- case " $predeps $postdeps " in
- *" $deplib "*)
- if (${SED} -e '2q' $lib |
- grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
- library_names=
- old_library=
- case $lib in
- */* | *\\*) . $lib ;;
- *) . ./$lib ;;
- esac
- for l in $old_library $library_names; do
- ll="$l"
- done
- if test "X$ll" = "X$old_library" ; then # only static version available
- found=no
- ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'`
- test "X$ladir" = "X$lib" && ladir="."
- lib=$ladir/$old_library
- if test "$linkmode,$pass" = "prog,link"; then
- compile_deplibs="$deplib $compile_deplibs"
- finalize_deplibs="$deplib $finalize_deplibs"
- else
- deplibs="$deplib $deplibs"
- test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs"
- fi
- continue
- fi
- fi
- ;;
- *) ;;
- esac
- fi
- fi
- ;; # -l
- -L*)
- case $linkmode in
- lib)
- deplibs="$deplib $deplibs"
- test "$pass" = conv && continue
- newdependency_libs="$deplib $newdependency_libs"
- newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`
- ;;
- prog)
- if test "$pass" = conv; then
- deplibs="$deplib $deplibs"
- continue
- fi
- if test "$pass" = scan; then
- deplibs="$deplib $deplibs"
- else
- compile_deplibs="$deplib $compile_deplibs"
- finalize_deplibs="$deplib $finalize_deplibs"
- fi
- newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`
- ;;
- *)
- $echo "$modename: warning: \`-L' is ignored for archives/objects" 1>&2
- ;;
- esac # linkmode
- continue
- ;; # -L
- -R*)
- if test "$pass" = link; then
- dir=`$echo "X$deplib" | $Xsed -e 's/^-R//'`
- # Make sure the xrpath contains only unique directories.
- case "$xrpath " in
- *" $dir "*) ;;
- *) xrpath="$xrpath $dir" ;;
- esac
- fi
- deplibs="$deplib $deplibs"
- continue
- ;;
- *.la) lib="$deplib" ;;
- *.$libext)
- if test "$pass" = conv; then
- deplibs="$deplib $deplibs"
- continue
- fi
- case $linkmode in
- lib)
- valid_a_lib=no
- case $deplibs_check_method in
- match_pattern*)
- set dummy $deplibs_check_method
- match_pattern_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"`
- if eval $echo \"$deplib\" 2>/dev/null \
- | $SED 10q \
- | $EGREP "$match_pattern_regex" > /dev/null; then
- valid_a_lib=yes
- fi
- ;;
- pass_all)
- valid_a_lib=yes
- ;;
- esac
- if test "$valid_a_lib" != yes; then
- $echo
- $echo "*** Warning: Trying to link with static lib archive $deplib."
- $echo "*** I have the capability to make that library automatically link in when"
- $echo "*** you link to this library. But I can only do this if you have a"
- $echo "*** shared version of the library, which you do not appear to have"
- $echo "*** because the file extensions .$libext of this argument makes me believe"
- $echo "*** that it is just a static archive that I should not used here."
- else
- $echo
- $echo "*** Warning: Linking the shared library $output against the"
- $echo "*** static library $deplib is not portable!"
- deplibs="$deplib $deplibs"
- fi
- continue
- ;;
- prog)
- if test "$pass" != link; then
- deplibs="$deplib $deplibs"
- else
- compile_deplibs="$deplib $compile_deplibs"
- finalize_deplibs="$deplib $finalize_deplibs"
- fi
- continue
- ;;
- esac # linkmode
- ;; # *.$libext
- *.lo | *.$objext)
- if test "$pass" = conv; then
- deplibs="$deplib $deplibs"
- elif test "$linkmode" = prog; then
- if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then
- # If there is no dlopen support or we're linking statically,
- # we need to preload.
- newdlprefiles="$newdlprefiles $deplib"
- compile_deplibs="$deplib $compile_deplibs"
- finalize_deplibs="$deplib $finalize_deplibs"
- else
- newdlfiles="$newdlfiles $deplib"
- fi
- fi
- continue
- ;;
- %DEPLIBS%)
- alldeplibs=yes
- continue
- ;;
- esac # case $deplib
- if test "$found" = yes || test -f "$lib"; then :
- else
- $echo "$modename: cannot find the library \`$lib' or unhandled argument \`$deplib'" 1>&2
- exit $EXIT_FAILURE
- fi
-
- # Check to see that this really is a libtool archive.
- if (${SED} -e '2q' $lib | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
- else
- $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2
- exit $EXIT_FAILURE
- fi
-
- ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'`
- test "X$ladir" = "X$lib" && ladir="."
-
- dlname=
- dlopen=
- dlpreopen=
- libdir=
- library_names=
- old_library=
- # If the library was installed with an old release of libtool,
- # it will not redefine variables installed, or shouldnotlink
- installed=yes
- shouldnotlink=no
- avoidtemprpath=
-
-
- # Read the .la file
- case $lib in
- */* | *\\*) . $lib ;;
- *) . ./$lib ;;
- esac
-
- if test "$linkmode,$pass" = "lib,link" ||
- test "$linkmode,$pass" = "prog,scan" ||
- { test "$linkmode" != prog && test "$linkmode" != lib; }; then
- test -n "$dlopen" && dlfiles="$dlfiles $dlopen"
- test -n "$dlpreopen" && dlprefiles="$dlprefiles $dlpreopen"
- fi
-
- if test "$pass" = conv; then
- # Only check for convenience libraries
- deplibs="$lib $deplibs"
- if test -z "$libdir"; then
- if test -z "$old_library"; then
- $echo "$modename: cannot find name of link library for \`$lib'" 1>&2
- exit $EXIT_FAILURE
- fi
- # It is a libtool convenience library, so add in its objects.
- convenience="$convenience $ladir/$objdir/$old_library"
- old_convenience="$old_convenience $ladir/$objdir/$old_library"
- tmp_libs=
- for deplib in $dependency_libs; do
- deplibs="$deplib $deplibs"
- if test "X$duplicate_deps" = "Xyes" ; then
- case "$tmp_libs " in
- *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
- esac
- fi
- tmp_libs="$tmp_libs $deplib"
- done
- elif test "$linkmode" != prog && test "$linkmode" != lib; then
- $echo "$modename: \`$lib' is not a convenience library" 1>&2
- exit $EXIT_FAILURE
- fi
- continue
- fi # $pass = conv
-
-
- # Get the name of the library we link against.
- linklib=
- for l in $old_library $library_names; do
- linklib="$l"
- done
- if test -z "$linklib"; then
- $echo "$modename: cannot find name of link library for \`$lib'" 1>&2
- exit $EXIT_FAILURE
- fi
-
- # This library was specified with -dlopen.
- if test "$pass" = dlopen; then
- if test -z "$libdir"; then
- $echo "$modename: cannot -dlopen a convenience library: \`$lib'" 1>&2
- exit $EXIT_FAILURE
- fi
- if test -z "$dlname" ||
- test "$dlopen_support" != yes ||
- test "$build_libtool_libs" = no; then
- # If there is no dlname, no dlopen support or we're linking
- # statically, we need to preload. We also need to preload any
- # dependent libraries so libltdl's deplib preloader doesn't
- # bomb out in the load deplibs phase.
- dlprefiles="$dlprefiles $lib $dependency_libs"
- else
- newdlfiles="$newdlfiles $lib"
- fi
- continue
- fi # $pass = dlopen
-
- # We need an absolute path.
- case $ladir in
- [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;;
- *)
- abs_ladir=`cd "$ladir" && pwd`
- if test -z "$abs_ladir"; then
- $echo "$modename: warning: cannot determine absolute directory name of \`$ladir'" 1>&2
- $echo "$modename: passing it literally to the linker, although it might fail" 1>&2
- abs_ladir="$ladir"
- fi
- ;;
- esac
- laname=`$echo "X$lib" | $Xsed -e 's%^.*/%%'`
-
- # Find the relevant object directory and library name.
- if test "X$installed" = Xyes; then
- if test ! -f "$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then
- $echo "$modename: warning: library \`$lib' was moved." 1>&2
- dir="$ladir"
- absdir="$abs_ladir"
- libdir="$abs_ladir"
- else
- dir="$libdir"
- absdir="$libdir"
- fi
- test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes
- else
- if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then
- dir="$ladir"
- absdir="$abs_ladir"
- # Remove this search path later
- notinst_path="$notinst_path $abs_ladir"
- else
- dir="$ladir/$objdir"
- absdir="$abs_ladir/$objdir"
- # Remove this search path later
- notinst_path="$notinst_path $abs_ladir"
- fi
- fi # $installed = yes
- name=`$echo "X$laname" | $Xsed -e 's/\.la$//' -e 's/^lib//'`
-
- # This library was specified with -dlpreopen.
- if test "$pass" = dlpreopen; then
- if test -z "$libdir"; then
- $echo "$modename: cannot -dlpreopen a convenience library: \`$lib'" 1>&2
- exit $EXIT_FAILURE
- fi
- # Prefer using a static library (so that no silly _DYNAMIC symbols
- # are required to link).
- if test -n "$old_library"; then
- newdlprefiles="$newdlprefiles $dir/$old_library"
- # Otherwise, use the dlname, so that lt_dlopen finds it.
- elif test -n "$dlname"; then
- newdlprefiles="$newdlprefiles $dir/$dlname"
- else
- newdlprefiles="$newdlprefiles $dir/$linklib"
- fi
- fi # $pass = dlpreopen
-
- if test -z "$libdir"; then
- # Link the convenience library
- if test "$linkmode" = lib; then
- deplibs="$dir/$old_library $deplibs"
- elif test "$linkmode,$pass" = "prog,link"; then
- compile_deplibs="$dir/$old_library $compile_deplibs"
- finalize_deplibs="$dir/$old_library $finalize_deplibs"
- else
- deplibs="$lib $deplibs" # used for prog,scan pass
- fi
- continue
- fi
-
-
- if test "$linkmode" = prog && test "$pass" != link; then
- newlib_search_path="$newlib_search_path $ladir"
- deplibs="$lib $deplibs"
-
- linkalldeplibs=no
- if test "$link_all_deplibs" != no || test -z "$library_names" ||
- test "$build_libtool_libs" = no; then
- linkalldeplibs=yes
- fi
-
- tmp_libs=
- for deplib in $dependency_libs; do
- case $deplib in
- -L*) newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`;; ### testsuite: skip nested quoting test
- esac
- # Need to link against all dependency_libs?
- if test "$linkalldeplibs" = yes; then
- deplibs="$deplib $deplibs"
- else
- # Need to hardcode shared library paths
- # or/and link against static libraries
- newdependency_libs="$deplib $newdependency_libs"
- fi
- if test "X$duplicate_deps" = "Xyes" ; then
- case "$tmp_libs " in
- *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
- esac
- fi
- tmp_libs="$tmp_libs $deplib"
- done # for deplib
- continue
- fi # $linkmode = prog...
-
- if test "$linkmode,$pass" = "prog,link"; then
- if test -n "$library_names" &&
- { { test "$prefer_static_libs" = no ||
- test "$prefer_static_libs,$installed" = "built,yes"; } ||
- test -z "$old_library"; }; then
- # We need to hardcode the library path
- if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then
- # Make sure the rpath contains only unique directories.
- case "$temp_rpath " in
- *" $dir "*) ;;
- *" $absdir "*) ;;
- *) temp_rpath="$temp_rpath $absdir" ;;
- esac
- fi
-
- # Hardcode the library path.
- # Skip directories that are in the system default run-time
- # search path.
- case " $sys_lib_dlsearch_path " in
- *" $absdir "*) ;;
- *)
- case "$compile_rpath " in
- *" $absdir "*) ;;
- *) compile_rpath="$compile_rpath $absdir"
- esac
- ;;
- esac
- case " $sys_lib_dlsearch_path " in
- *" $libdir "*) ;;
- *)
- case "$finalize_rpath " in
- *" $libdir "*) ;;
- *) finalize_rpath="$finalize_rpath $libdir"
- esac
- ;;
- esac
- fi # $linkmode,$pass = prog,link...
-
- if test "$alldeplibs" = yes &&
- { test "$deplibs_check_method" = pass_all ||
- { test "$build_libtool_libs" = yes &&
- test -n "$library_names"; }; }; then
- # We only need to search for static libraries
- continue
- fi
- fi
-
- link_static=no # Whether the deplib will be linked statically
- use_static_libs=$prefer_static_libs
- if test "$use_static_libs" = built && test "$installed" = yes ; then
- use_static_libs=no
- fi
- if test -n "$library_names" &&
- { test "$use_static_libs" = no || test -z "$old_library"; }; then
- if test "$installed" = no; then
- notinst_deplibs="$notinst_deplibs $lib"
- need_relink=yes
- fi
- # This is a shared library
-
- # Warn about portability, can't link against -module's on
- # some systems (darwin)
- if test "$shouldnotlink" = yes && test "$pass" = link ; then
- $echo
- if test "$linkmode" = prog; then
- $echo "*** Warning: Linking the executable $output against the loadable module"
- else
- $echo "*** Warning: Linking the shared library $output against the loadable module"
- fi
- $echo "*** $linklib is not portable!"
- fi
- if test "$linkmode" = lib &&
- test "$hardcode_into_libs" = yes; then
- # Hardcode the library path.
- # Skip directories that are in the system default run-time
- # search path.
- case " $sys_lib_dlsearch_path " in
- *" $absdir "*) ;;
- *)
- case "$compile_rpath " in
- *" $absdir "*) ;;
- *) compile_rpath="$compile_rpath $absdir"
- esac
- ;;
- esac
- case " $sys_lib_dlsearch_path " in
- *" $libdir "*) ;;
- *)
- case "$finalize_rpath " in
- *" $libdir "*) ;;
- *) finalize_rpath="$finalize_rpath $libdir"
- esac
- ;;
- esac
- fi
-
- if test -n "$old_archive_from_expsyms_cmds"; then
- # figure out the soname
- set dummy $library_names
- realname="$2"
- shift; shift
- libname=`eval \\$echo \"$libname_spec\"`
- # use dlname if we got it. it's perfectly good, no?
- if test -n "$dlname"; then
- soname="$dlname"
- elif test -n "$soname_spec"; then
- # bleh windows
- case $host in
- *cygwin* | mingw*)
- major=`expr $current - $age`
- versuffix="-$major"
- ;;
- esac
- eval soname=\"$soname_spec\"
- else
- soname="$realname"
- fi
-
- # Make a new name for the extract_expsyms_cmds to use
- soroot="$soname"
- soname=`$echo $soroot | ${SED} -e 's/^.*\///'`
- newlib="libimp-`$echo $soname | ${SED} 's/^lib//;s/\.dll$//'`.a"
-
- # If the library has no export list, then create one now
- if test -f "$output_objdir/$soname-def"; then :
- else
- $show "extracting exported symbol list from \`$soname'"
- save_ifs="$IFS"; IFS='~'
- cmds=$extract_expsyms_cmds
- for cmd in $cmds; do
- IFS="$save_ifs"
- eval cmd=\"$cmd\"
- $show "$cmd"
- $run eval "$cmd" || exit $?
- done
- IFS="$save_ifs"
- fi
-
- # Create $newlib
- if test -f "$output_objdir/$newlib"; then :; else
- $show "generating import library for \`$soname'"
- save_ifs="$IFS"; IFS='~'
- cmds=$old_archive_from_expsyms_cmds
- for cmd in $cmds; do
- IFS="$save_ifs"
- eval cmd=\"$cmd\"
- $show "$cmd"
- $run eval "$cmd" || exit $?
- done
- IFS="$save_ifs"
- fi
- # make sure the library variables are pointing to the new library
- dir=$output_objdir
- linklib=$newlib
- fi # test -n "$old_archive_from_expsyms_cmds"
-
- if test "$linkmode" = prog || test "$mode" != relink; then
- add_shlibpath=
- add_dir=
- add=
- lib_linked=yes
- case $hardcode_action in
- immediate | unsupported)
- if test "$hardcode_direct" = no; then
- add="$dir/$linklib"
- case $host in
- *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;;
- *-*-sysv4*uw2*) add_dir="-L$dir" ;;
- *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \
- *-*-unixware7*) add_dir="-L$dir" ;;
- *-*-darwin* )
- # if the lib is a module then we can not link against
- # it, someone is ignoring the new warnings I added
- if /usr/bin/file -L $add 2> /dev/null |
- $EGREP ": [^:]* bundle" >/dev/null ; then
- $echo "** Warning, lib $linklib is a module, not a shared library"
- if test -z "$old_library" ; then
- $echo
- $echo "** And there doesn't seem to be a static archive available"
- $echo "** The link will probably fail, sorry"
- else
- add="$dir/$old_library"
- fi
- fi
- esac
- elif test "$hardcode_minus_L" = no; then
- case $host in
- *-*-sunos*) add_shlibpath="$dir" ;;
- esac
- add_dir="-L$dir"
- add="-l$name"
- elif test "$hardcode_shlibpath_var" = no; then
- add_shlibpath="$dir"
- add="-l$name"
- else
- lib_linked=no
- fi
- ;;
- relink)
- if test "$hardcode_direct" = yes; then
- add="$dir/$linklib"
- elif test "$hardcode_minus_L" = yes; then
- add_dir="-L$dir"
- # Try looking first in the location we're being installed to.
- if test -n "$inst_prefix_dir"; then
- case $libdir in
- [\\/]*)
- add_dir="$add_dir -L$inst_prefix_dir$libdir"
- ;;
- esac
- fi
- add="-l$name"
- elif test "$hardcode_shlibpath_var" = yes; then
- add_shlibpath="$dir"
- add="-l$name"
- else
- lib_linked=no
- fi
- ;;
- *) lib_linked=no ;;
- esac
-
- if test "$lib_linked" != yes; then
- $echo "$modename: configuration error: unsupported hardcode properties"
- exit $EXIT_FAILURE
- fi
-
- if test -n "$add_shlibpath"; then
- case :$compile_shlibpath: in
- *":$add_shlibpath:"*) ;;
- *) compile_shlibpath="$compile_shlibpath$add_shlibpath:" ;;
- esac
- fi
- if test "$linkmode" = prog; then
- test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs"
- test -n "$add" && compile_deplibs="$add $compile_deplibs"
- else
- test -n "$add_dir" && deplibs="$add_dir $deplibs"
- test -n "$add" && deplibs="$add $deplibs"
- if test "$hardcode_direct" != yes && \
- test "$hardcode_minus_L" != yes && \
- test "$hardcode_shlibpath_var" = yes; then
- case :$finalize_shlibpath: in
- *":$libdir:"*) ;;
- *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;;
- esac
- fi
- fi
- fi
-
- if test "$linkmode" = prog || test "$mode" = relink; then
- add_shlibpath=
- add_dir=
- add=
- # Finalize command for both is simple: just hardcode it.
- if test "$hardcode_direct" = yes; then
- add="$libdir/$linklib"
- elif test "$hardcode_minus_L" = yes; then
- add_dir="-L$libdir"
- add="-l$name"
- elif test "$hardcode_shlibpath_var" = yes; then
- case :$finalize_shlibpath: in
- *":$libdir:"*) ;;
- *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;;
- esac
- add="-l$name"
- elif test "$hardcode_automatic" = yes; then
- if test -n "$inst_prefix_dir" &&
- test -f "$inst_prefix_dir$libdir/$linklib" ; then
- add="$inst_prefix_dir$libdir/$linklib"
- else
- add="$libdir/$linklib"
- fi
- else
- # We cannot seem to hardcode it, guess we'll fake it.
- add_dir="-L$libdir"
- # Try looking first in the location we're being installed to.
- if test -n "$inst_prefix_dir"; then
- case $libdir in
- [\\/]*)
- add_dir="$add_dir -L$inst_prefix_dir$libdir"
- ;;
- esac
- fi
- add="-l$name"
- fi
-
- if test "$linkmode" = prog; then
- test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs"
- test -n "$add" && finalize_deplibs="$add $finalize_deplibs"
- else
- test -n "$add_dir" && deplibs="$add_dir $deplibs"
- test -n "$add" && deplibs="$add $deplibs"
- fi
- fi
- elif test "$linkmode" = prog; then
- # Here we assume that one of hardcode_direct or hardcode_minus_L
- # is not unsupported. This is valid on all known static and
- # shared platforms.
- if test "$hardcode_direct" != unsupported; then
- test -n "$old_library" && linklib="$old_library"
- compile_deplibs="$dir/$linklib $compile_deplibs"
- finalize_deplibs="$dir/$linklib $finalize_deplibs"
- else
- compile_deplibs="-l$name -L$dir $compile_deplibs"
- finalize_deplibs="-l$name -L$dir $finalize_deplibs"
- fi
- elif test "$build_libtool_libs" = yes; then
- # Not a shared library
- if test "$deplibs_check_method" != pass_all; then
- # We're trying link a shared library against a static one
- # but the system doesn't support it.
-
- # Just print a warning and add the library to dependency_libs so
- # that the program can be linked against the static library.
- $echo
- $echo "*** Warning: This system can not link to static lib archive $lib."
- $echo "*** I have the capability to make that library automatically link in when"
- $echo "*** you link to this library. But I can only do this if you have a"
- $echo "*** shared version of the library, which you do not appear to have."
- if test "$module" = yes; then
- $echo "*** But as you try to build a module library, libtool will still create "
- $echo "*** a static module, that should work as long as the dlopening application"
- $echo "*** is linked with the -dlopen flag to resolve symbols at runtime."
- if test -z "$global_symbol_pipe"; then
- $echo
- $echo "*** However, this would only work if libtool was able to extract symbol"
- $echo "*** lists from a program, using \`nm' or equivalent, but libtool could"
- $echo "*** not find such a program. So, this module is probably useless."
- $echo "*** \`nm' from GNU binutils and a full rebuild may help."
- fi
- if test "$build_old_libs" = no; then
- build_libtool_libs=module
- build_old_libs=yes
- else
- build_libtool_libs=no
- fi
- fi
- else
- deplibs="$dir/$old_library $deplibs"
- link_static=yes
- fi
- fi # link shared/static library?
-
- if test "$linkmode" = lib; then
- if test -n "$dependency_libs" &&
- { test "$hardcode_into_libs" != yes ||
- test "$build_old_libs" = yes ||
- test "$link_static" = yes; }; then
- # Extract -R from dependency_libs
- temp_deplibs=
- for libdir in $dependency_libs; do
- case $libdir in
- -R*) temp_xrpath=`$echo "X$libdir" | $Xsed -e 's/^-R//'`
- case " $xrpath " in
- *" $temp_xrpath "*) ;;
- *) xrpath="$xrpath $temp_xrpath";;
- esac;;
- *) temp_deplibs="$temp_deplibs $libdir";;
- esac
- done
- dependency_libs="$temp_deplibs"
- fi
-
- newlib_search_path="$newlib_search_path $absdir"
- # Link against this library
- test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs"
- # ... and its dependency_libs
- tmp_libs=
- for deplib in $dependency_libs; do
- newdependency_libs="$deplib $newdependency_libs"
- if test "X$duplicate_deps" = "Xyes" ; then
- case "$tmp_libs " in
- *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
- esac
- fi
- tmp_libs="$tmp_libs $deplib"
- done
-
- if test "$link_all_deplibs" != no; then
- # Add the search paths of all dependency libraries
- for deplib in $dependency_libs; do
- case $deplib in
- -L*) path="$deplib" ;;
- *.la)
- dir=`$echo "X$deplib" | $Xsed -e 's%/[^/]*$%%'`
- test "X$dir" = "X$deplib" && dir="."
- # We need an absolute path.
- case $dir in
- [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;;
- *)
- absdir=`cd "$dir" && pwd`
- if test -z "$absdir"; then
- $echo "$modename: warning: cannot determine absolute directory name of \`$dir'" 1>&2
- absdir="$dir"
- fi
- ;;
- esac
- if grep "^installed=no" $deplib > /dev/null; then
- path="$absdir/$objdir"
- else
- eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
- if test -z "$libdir"; then
- $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2
- exit $EXIT_FAILURE
- fi
- if test "$absdir" != "$libdir"; then
- $echo "$modename: warning: \`$deplib' seems to be moved" 1>&2
- fi
- path="$absdir"
- fi
- depdepl=
- case $host in
- *-*-darwin*)
- # we do not want to link against static libs,
- # but need to link against shared
- eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib`
- eval deplibdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
- if test -n "$deplibrary_names" ; then
- for tmp in $deplibrary_names ; do
- depdepl=$tmp
- done
- if test -f "$deplibdir/$depdepl" ; then
- depdepl="$deplibdir/$depdepl"
- elif test -f "$path/$depdepl" ; then
- depdepl="$path/$depdepl"
- else
- # Can't find it, oh well...
- depdepl=
- fi
- # do not add paths which are already there
- case " $newlib_search_path " in
- *" $path "*) ;;
- *) newlib_search_path="$newlib_search_path $path";;
- esac
- fi
- path=""
- ;;
- *)
- path="-L$path"
- ;;
- esac
- ;;
- -l*)
- case $host in
- *-*-darwin*)
- # Again, we only want to link against shared libraries
- eval tmp_libs=`$echo "X$deplib" | $Xsed -e "s,^\-l,,"`
- for tmp in $newlib_search_path ; do
- if test -f "$tmp/lib$tmp_libs.dylib" ; then
- eval depdepl="$tmp/lib$tmp_libs.dylib"
- break
- fi
- done
- path=""
- ;;
- *) continue ;;
- esac
- ;;
- *) continue ;;
- esac
- case " $deplibs " in
- *" $path "*) ;;
- *) deplibs="$path $deplibs" ;;
- esac
- case " $deplibs " in
- *" $depdepl "*) ;;
- *) deplibs="$depdepl $deplibs" ;;
- esac
- done
- fi # link_all_deplibs != no
- fi # linkmode = lib
- done # for deplib in $libs
- dependency_libs="$newdependency_libs"
- if test "$pass" = dlpreopen; then
- # Link the dlpreopened libraries before other libraries
- for deplib in $save_deplibs; do
- deplibs="$deplib $deplibs"
- done
- fi
- if test "$pass" != dlopen; then
- if test "$pass" != conv; then
- # Make sure lib_search_path contains only unique directories.
- lib_search_path=
- for dir in $newlib_search_path; do
- case "$lib_search_path " in
- *" $dir "*) ;;
- *) lib_search_path="$lib_search_path $dir" ;;
- esac
- done
- newlib_search_path=
- fi
-
- if test "$linkmode,$pass" != "prog,link"; then
- vars="deplibs"
- else
- vars="compile_deplibs finalize_deplibs"
- fi
- for var in $vars dependency_libs; do
- # Add libraries to $var in reverse order
- eval tmp_libs=\"\$$var\"
- new_libs=
- for deplib in $tmp_libs; do
- # FIXME: Pedantically, this is the right thing to do, so
- # that some nasty dependency loop isn't accidentally
- # broken:
- #new_libs="$deplib $new_libs"
- # Pragmatically, this seems to cause very few problems in
- # practice:
- case $deplib in
- -L*) new_libs="$deplib $new_libs" ;;
- -R*) ;;
- *)
- # And here is the reason: when a library appears more
- # than once as an explicit dependence of a library, or
- # is implicitly linked in more than once by the
- # compiler, it is considered special, and multiple
- # occurrences thereof are not removed. Compare this
- # with having the same library being listed as a
- # dependency of multiple other libraries: in this case,
- # we know (pedantically, we assume) the library does not
- # need to be listed more than once, so we keep only the
- # last copy. This is not always right, but it is rare
- # enough that we require users that really mean to play
- # such unportable linking tricks to link the library
- # using -Wl,-lname, so that libtool does not consider it
- # for duplicate removal.
- case " $specialdeplibs " in
- *" $deplib "*) new_libs="$deplib $new_libs" ;;
- *)
- case " $new_libs " in
- *" $deplib "*) ;;
- *) new_libs="$deplib $new_libs" ;;
- esac
- ;;
- esac
- ;;
- esac
- done
- tmp_libs=
- for deplib in $new_libs; do
- case $deplib in
- -L*)
- case " $tmp_libs " in
- *" $deplib "*) ;;
- *) tmp_libs="$tmp_libs $deplib" ;;
- esac
- ;;
- *) tmp_libs="$tmp_libs $deplib" ;;
- esac
- done
- eval $var=\"$tmp_libs\"
- done # for var
- fi
- # Last step: remove runtime libs from dependency_libs
- # (they stay in deplibs)
- tmp_libs=
- for i in $dependency_libs ; do
- case " $predeps $postdeps $compiler_lib_search_path " in
- *" $i "*)
- i=""
- ;;
- esac
- if test -n "$i" ; then
- tmp_libs="$tmp_libs $i"
- fi
- done
- dependency_libs=$tmp_libs
- done # for pass
- if test "$linkmode" = prog; then
- dlfiles="$newdlfiles"
- dlprefiles="$newdlprefiles"
- fi
-
- case $linkmode in
- oldlib)
- case " $deplibs" in
- *\ -l* | *\ -L*)
- $echo "$modename: warning: \`-l' and \`-L' are ignored for archives" 1>&2 ;;
- esac
-
- if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
- $echo "$modename: warning: \`-dlopen' is ignored for archives" 1>&2
- fi
-
- if test -n "$rpath"; then
- $echo "$modename: warning: \`-rpath' is ignored for archives" 1>&2
- fi
-
- if test -n "$xrpath"; then
- $echo "$modename: warning: \`-R' is ignored for archives" 1>&2
- fi
-
- if test -n "$vinfo"; then
- $echo "$modename: warning: \`-version-info/-version-number' is ignored for archives" 1>&2
- fi
-
- if test -n "$release"; then
- $echo "$modename: warning: \`-release' is ignored for archives" 1>&2
- fi
-
- if test -n "$export_symbols" || test -n "$export_symbols_regex"; then
- $echo "$modename: warning: \`-export-symbols' is ignored for archives" 1>&2
- fi
-
- # Now set the variables for building old libraries.
- build_libtool_libs=no
- oldlibs="$output"
- objs="$objs$old_deplibs"
- ;;
-
- lib)
- # Make sure we only generate libraries of the form `libNAME.la'.
- case $outputname in
- lib*)
- name=`$echo "X$outputname" | $Xsed -e 's/\.la$//' -e 's/^lib//'`
- eval shared_ext=\"$shrext_cmds\"
- eval libname=\"$libname_spec\"
- ;;
- *)
- if test "$module" = no; then
- $echo "$modename: libtool library \`$output' must begin with \`lib'" 1>&2
- $echo "$help" 1>&2
- exit $EXIT_FAILURE
- fi
- if test "$need_lib_prefix" != no; then
- # Add the "lib" prefix for modules if required
- name=`$echo "X$outputname" | $Xsed -e 's/\.la$//'`
- eval shared_ext=\"$shrext_cmds\"
- eval libname=\"$libname_spec\"
- else
- libname=`$echo "X$outputname" | $Xsed -e 's/\.la$//'`
- fi
- ;;
- esac
-
- if test -n "$objs"; then
- if test "$deplibs_check_method" != pass_all; then
- $echo "$modename: cannot build libtool library \`$output' from non-libtool objects on this host:$objs" 2>&1
- exit $EXIT_FAILURE
- else
- $echo
- $echo "*** Warning: Linking the shared library $output against the non-libtool"
- $echo "*** objects $objs is not portable!"
- libobjs="$libobjs $objs"
- fi
- fi
-
- if test "$dlself" != no; then
- $echo "$modename: warning: \`-dlopen self' is ignored for libtool libraries" 1>&2
- fi
-
- set dummy $rpath
- if test "$#" -gt 2; then
- $echo "$modename: warning: ignoring multiple \`-rpath's for a libtool library" 1>&2
- fi
- install_libdir="$2"
-
- oldlibs=
- if test -z "$rpath"; then
- if test "$build_libtool_libs" = yes; then
- # Building a libtool convenience library.
- # Some compilers have problems with a `.al' extension so
- # convenience libraries should have the same extension an
- # archive normally would.
- oldlibs="$output_objdir/$libname.$libext $oldlibs"
- build_libtool_libs=convenience
- build_old_libs=yes
- fi
-
- if test -n "$vinfo"; then
- $echo "$modename: warning: \`-version-info/-version-number' is ignored for convenience libraries" 1>&2
- fi
-
- if test -n "$release"; then
- $echo "$modename: warning: \`-release' is ignored for convenience libraries" 1>&2
- fi
- else
-
- # Parse the version information argument.
- save_ifs="$IFS"; IFS=':'
- set dummy $vinfo 0 0 0
- IFS="$save_ifs"
-
- if test -n "$8"; then
- $echo "$modename: too many parameters to \`-version-info'" 1>&2
- $echo "$help" 1>&2
- exit $EXIT_FAILURE
- fi
-
- # convert absolute version numbers to libtool ages
- # this retains compatibility with .la files and attempts
- # to make the code below a bit more comprehensible
-
- case $vinfo_number in
- yes)
- number_major="$2"
- number_minor="$3"
- number_revision="$4"
- #
- # There are really only two kinds -- those that
- # use the current revision as the major version
- # and those that subtract age and use age as
- # a minor version. But, then there is irix
- # which has an extra 1 added just for fun
- #
- case $version_type in
- darwin|linux|osf|windows|none)
- current=`expr $number_major + $number_minor`
- age="$number_minor"
- revision="$number_revision"
- ;;
- freebsd-aout|freebsd-elf|sunos)
- current="$number_major"
- revision="$number_minor"
- age="0"
- ;;
- irix|nonstopux)
- current=`expr $number_major + $number_minor`
- age="$number_minor"
- revision="$number_minor"
- lt_irix_increment=no
- ;;
- esac
- ;;
- no)
- current="$2"
- revision="$3"
- age="$4"
- ;;
- esac
-
- # Check that each of the things are valid numbers.
- case $current in
- 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
- *)
- $echo "$modename: CURRENT \`$current' must be a nonnegative integer" 1>&2
- $echo "$modename: \`$vinfo' is not valid version information" 1>&2
- exit $EXIT_FAILURE
- ;;
- esac
-
- case $revision in
- 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
- *)
- $echo "$modename: REVISION \`$revision' must be a nonnegative integer" 1>&2
- $echo "$modename: \`$vinfo' is not valid version information" 1>&2
- exit $EXIT_FAILURE
- ;;
- esac
-
- case $age in
- 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
- *)
- $echo "$modename: AGE \`$age' must be a nonnegative integer" 1>&2
- $echo "$modename: \`$vinfo' is not valid version information" 1>&2
- exit $EXIT_FAILURE
- ;;
- esac
-
- if test "$age" -gt "$current"; then
- $echo "$modename: AGE \`$age' is greater than the current interface number \`$current'" 1>&2
- $echo "$modename: \`$vinfo' is not valid version information" 1>&2
- exit $EXIT_FAILURE
- fi
-
- # Calculate the version variables.
- major=
- versuffix=
- verstring=
- case $version_type in
- none) ;;
-
- darwin)
- # Like Linux, but with the current version available in
- # verstring for coding it into the library header
- major=.`expr $current - $age`
- versuffix="$major.$age.$revision"
- # Darwin ld doesn't like 0 for these options...
- minor_current=`expr $current + 1`
- xlcverstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision"
- verstring="-compatibility_version $minor_current -current_version $minor_current.$revision"
- ;;
-
- freebsd-aout)
- major=".$current"
- versuffix=".$current.$revision";
- ;;
-
- freebsd-elf)
- major=".$current"
- versuffix=".$current";
- ;;
-
- irix | nonstopux)
- if test "X$lt_irix_increment" = "Xno"; then
- major=`expr $current - $age`
- else
- major=`expr $current - $age + 1`
- fi
- case $version_type in
- nonstopux) verstring_prefix=nonstopux ;;
- *) verstring_prefix=sgi ;;
- esac
- verstring="$verstring_prefix$major.$revision"
-
- # Add in all the interfaces that we are compatible with.
- loop=$revision
- while test "$loop" -ne 0; do
- iface=`expr $revision - $loop`
- loop=`expr $loop - 1`
- verstring="$verstring_prefix$major.$iface:$verstring"
- done
-
- # Before this point, $major must not contain `.'.
- major=.$major
- versuffix="$major.$revision"
- ;;
-
- linux)
- major=.`expr $current - $age`
- versuffix="$major.$age.$revision"
- ;;
-
- osf)
- major=.`expr $current - $age`
- versuffix=".$current.$age.$revision"
- verstring="$current.$age.$revision"
-
- # Add in all the interfaces that we are compatible with.
- loop=$age
- while test "$loop" -ne 0; do
- iface=`expr $current - $loop`
- loop=`expr $loop - 1`
- verstring="$verstring:${iface}.0"
- done
-
- # Make executables depend on our current version.
- verstring="$verstring:${current}.0"
- ;;
-
- sunos)
- major=".$current"
- versuffix=".$current.$revision"
- ;;
-
- windows)
- # Use '-' rather than '.', since we only want one
- # extension on DOS 8.3 filesystems.
- major=`expr $current - $age`
- versuffix="-$major"
- ;;
-
- *)
- $echo "$modename: unknown library version type \`$version_type'" 1>&2
- $echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2
- exit $EXIT_FAILURE
- ;;
- esac
-
- # Clear the version info if we defaulted, and they specified a release.
- if test -z "$vinfo" && test -n "$release"; then
- major=
- case $version_type in
- darwin)
- # we can't check for "0.0" in archive_cmds due to quoting
- # problems, so we reset it completely
- verstring=
- ;;
- *)
- verstring="0.0"
- ;;
- esac
- if test "$need_version" = no; then
- versuffix=
- else
- versuffix=".0.0"
- fi
- fi
-
- # Remove version info from name if versioning should be avoided
- if test "$avoid_version" = yes && test "$need_version" = no; then
- major=
- versuffix=
- verstring=""
- fi
-
- # Check to see if the archive will have undefined symbols.
- if test "$allow_undefined" = yes; then
- if test "$allow_undefined_flag" = unsupported; then
- $echo "$modename: warning: undefined symbols not allowed in $host shared libraries" 1>&2
- build_libtool_libs=no
- build_old_libs=yes
- fi
- else
- # Don't allow undefined symbols.
- allow_undefined_flag="$no_undefined_flag"
- fi
- fi
-
- if test "$mode" != relink; then
- # Remove our outputs, but don't remove object files since they
- # may have been created when compiling PIC objects.
- removelist=
- tempremovelist=`$echo "$output_objdir/*"`
- for p in $tempremovelist; do
- case $p in
- *.$objext)
- ;;
- $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*)
- if test "X$precious_files_regex" != "X"; then
- if echo $p | $EGREP -e "$precious_files_regex" >/dev/null 2>&1
- then
- continue
- fi
- fi
- removelist="$removelist $p"
- ;;
- *) ;;
- esac
- done
- if test -n "$removelist"; then
- $show "${rm}r $removelist"
- $run ${rm}r $removelist
- fi
- fi
-
- # Now set the variables for building old libraries.
- if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then
- oldlibs="$oldlibs $output_objdir/$libname.$libext"
-
- # Transform .lo files to .o files.
- oldobjs="$objs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP`
- fi
-
- # Eliminate all temporary directories.
- #for path in $notinst_path; do
- # lib_search_path=`$echo "$lib_search_path " | ${SED} -e "s% $path % %g"`
- # deplibs=`$echo "$deplibs " | ${SED} -e "s% -L$path % %g"`
- # dependency_libs=`$echo "$dependency_libs " | ${SED} -e "s% -L$path % %g"`
- #done
-
- if test -n "$xrpath"; then
- # If the user specified any rpath flags, then add them.
- temp_xrpath=
- for libdir in $xrpath; do
- temp_xrpath="$temp_xrpath -R$libdir"
- case "$finalize_rpath " in
- *" $libdir "*) ;;
- *) finalize_rpath="$finalize_rpath $libdir" ;;
- esac
- done
- if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then
- dependency_libs="$temp_xrpath $dependency_libs"
- fi
- fi
-
- # Make sure dlfiles contains only unique files that won't be dlpreopened
- old_dlfiles="$dlfiles"
- dlfiles=
- for lib in $old_dlfiles; do
- case " $dlprefiles $dlfiles " in
- *" $lib "*) ;;
- *) dlfiles="$dlfiles $lib" ;;
- esac
- done
-
- # Make sure dlprefiles contains only unique files
- old_dlprefiles="$dlprefiles"
- dlprefiles=
- for lib in $old_dlprefiles; do
- case "$dlprefiles " in
- *" $lib "*) ;;
- *) dlprefiles="$dlprefiles $lib" ;;
- esac
- done
-
- if test "$build_libtool_libs" = yes; then
- if test -n "$rpath"; then
- case $host in
- *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos*)
- # these systems don't actually have a c library (as such)!
- ;;
- *-*-rhapsody* | *-*-darwin1.[012])
- # Rhapsody C library is in the System framework
- deplibs="$deplibs -framework System"
- ;;
- *-*-netbsd*)
- # Don't link with libc until the a.out ld.so is fixed.
- ;;
- *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
- # Do not include libc due to us having libc/libc_r.
- ;;
- *-*-sco3.2v5* | *-*-sco5v6*)
- # Causes problems with __ctype
- ;;
- *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)
- # Compiler inserts libc in the correct place for threads to work
- ;;
- *)
- # Add libc to deplibs on all other systems if necessary.
- if test "$build_libtool_need_lc" = "yes"; then
- deplibs="$deplibs -lc"
- fi
- ;;
- esac
- fi
-
- # Transform deplibs into only deplibs that can be linked in shared.
- name_save=$name
- libname_save=$libname
- release_save=$release
- versuffix_save=$versuffix
- major_save=$major
- # I'm not sure if I'm treating the release correctly. I think
- # release should show up in the -l (ie -lgmp5) so we don't want to
- # add it in twice. Is that correct?
- release=""
- versuffix=""
- major=""
- newdeplibs=
- droppeddeps=no
- case $deplibs_check_method in
- pass_all)
- # Don't check for shared/static. Everything works.
- # This might be a little naive. We might want to check
- # whether the library exists or not. But this is on
- # osf3 & osf4 and I'm not really sure... Just
- # implementing what was already the behavior.
- newdeplibs=$deplibs
- ;;
- test_compile)
- # This code stresses the "libraries are programs" paradigm to its
- # limits. Maybe even breaks it. We compile a program, linking it
- # against the deplibs as a proxy for the library. Then we can check
- # whether they linked in statically or dynamically with ldd.
- $rm conftest.c
- cat > conftest.c <<EOF
- int main() { return 0; }
-EOF
- $rm conftest
- if $LTCC $LTCFLAGS -o conftest conftest.c $deplibs; then
- ldd_output=`ldd conftest`
- for i in $deplibs; do
- name=`expr $i : '-l\(.*\)'`
- # If $name is empty we are operating on a -L argument.
- if test "$name" != "" && test "$name" != "0"; then
- if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
- case " $predeps $postdeps " in
- *" $i "*)
- newdeplibs="$newdeplibs $i"
- i=""
- ;;
- esac
- fi
- if test -n "$i" ; then
- libname=`eval \\$echo \"$libname_spec\"`
- deplib_matches=`eval \\$echo \"$library_names_spec\"`
- set dummy $deplib_matches
- deplib_match=$2
- if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
- newdeplibs="$newdeplibs $i"
- else
- droppeddeps=yes
- $echo
- $echo "*** Warning: dynamic linker does not accept needed library $i."
- $echo "*** I have the capability to make that library automatically link in when"
- $echo "*** you link to this library. But I can only do this if you have a"
- $echo "*** shared version of the library, which I believe you do not have"
- $echo "*** because a test_compile did reveal that the linker did not use it for"
- $echo "*** its dynamic dependency list that programs get resolved with at runtime."
- fi
- fi
- else
- newdeplibs="$newdeplibs $i"
- fi
- done
- else
- # Error occurred in the first compile. Let's try to salvage
- # the situation: Compile a separate program for each library.
- for i in $deplibs; do
- name=`expr $i : '-l\(.*\)'`
- # If $name is empty we are operating on a -L argument.
- if test "$name" != "" && test "$name" != "0"; then
- $rm conftest
- if $LTCC $LTCFLAGS -o conftest conftest.c $i; then
- ldd_output=`ldd conftest`
- if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
- case " $predeps $postdeps " in
- *" $i "*)
- newdeplibs="$newdeplibs $i"
- i=""
- ;;
- esac
- fi
- if test -n "$i" ; then
- libname=`eval \\$echo \"$libname_spec\"`
- deplib_matches=`eval \\$echo \"$library_names_spec\"`
- set dummy $deplib_matches
- deplib_match=$2
- if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
- newdeplibs="$newdeplibs $i"
- else
- droppeddeps=yes
- $echo
- $echo "*** Warning: dynamic linker does not accept needed library $i."
- $echo "*** I have the capability to make that library automatically link in when"
- $echo "*** you link to this library. But I can only do this if you have a"
- $echo "*** shared version of the library, which you do not appear to have"
- $echo "*** because a test_compile did reveal that the linker did not use this one"
- $echo "*** as a dynamic dependency that programs can get resolved with at runtime."
- fi
- fi
- else
- droppeddeps=yes
- $echo
- $echo "*** Warning! Library $i is needed by this library but I was not able to"
- $echo "*** make it link in! You will probably need to install it or some"
- $echo "*** library that it depends on before this library will be fully"
- $echo "*** functional. Installing it before continuing would be even better."
- fi
- else
- newdeplibs="$newdeplibs $i"
- fi
- done
- fi
- ;;
- file_magic*)
- set dummy $deplibs_check_method
- file_magic_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"`
- for a_deplib in $deplibs; do
- name=`expr $a_deplib : '-l\(.*\)'`
- # If $name is empty we are operating on a -L argument.
- if test "$name" != "" && test "$name" != "0"; then
- if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
- case " $predeps $postdeps " in
- *" $a_deplib "*)
- newdeplibs="$newdeplibs $a_deplib"
- a_deplib=""
- ;;
- esac
- fi
- if test -n "$a_deplib" ; then
- libname=`eval \\$echo \"$libname_spec\"`
- for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
- potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
- for potent_lib in $potential_libs; do
- # Follow soft links.
- if ls -lLd "$potent_lib" 2>/dev/null \
- | grep " -> " >/dev/null; then
- continue
- fi
- # The statement above tries to avoid entering an
- # endless loop below, in case of cyclic links.
- # We might still enter an endless loop, since a link
- # loop can be closed while we follow links,
- # but so what?
- potlib="$potent_lib"
- while test -h "$potlib" 2>/dev/null; do
- potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'`
- case $potliblink in
- [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";;
- *) potlib=`$echo "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";;
- esac
- done
- if eval $file_magic_cmd \"\$potlib\" 2>/dev/null \
- | ${SED} 10q \
- | $EGREP "$file_magic_regex" > /dev/null; then
- newdeplibs="$newdeplibs $a_deplib"
- a_deplib=""
- break 2
- fi
- done
- done
- fi
- if test -n "$a_deplib" ; then
- droppeddeps=yes
- $echo
- $echo "*** Warning: linker path does not have real file for library $a_deplib."
- $echo "*** I have the capability to make that library automatically link in when"
- $echo "*** you link to this library. But I can only do this if you have a"
- $echo "*** shared version of the library, which you do not appear to have"
- $echo "*** because I did check the linker path looking for a file starting"
- if test -z "$potlib" ; then
- $echo "*** with $libname but no candidates were found. (...for file magic test)"
- else
- $echo "*** with $libname and none of the candidates passed a file format test"
- $echo "*** using a file magic. Last file checked: $potlib"
- fi
- fi
- else
- # Add a -L argument.
- newdeplibs="$newdeplibs $a_deplib"
- fi
- done # Gone through all deplibs.
- ;;
- match_pattern*)
- set dummy $deplibs_check_method
- match_pattern_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"`
- for a_deplib in $deplibs; do
- name=`expr $a_deplib : '-l\(.*\)'`
- # If $name is empty we are operating on a -L argument.
- if test -n "$name" && test "$name" != "0"; then
- if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
- case " $predeps $postdeps " in
- *" $a_deplib "*)
- newdeplibs="$newdeplibs $a_deplib"
- a_deplib=""
- ;;
- esac
- fi
- if test -n "$a_deplib" ; then
- libname=`eval \\$echo \"$libname_spec\"`
- for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
- potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
- for potent_lib in $potential_libs; do
- potlib="$potent_lib" # see symlink-check above in file_magic test
- if eval $echo \"$potent_lib\" 2>/dev/null \
- | ${SED} 10q \
- | $EGREP "$match_pattern_regex" > /dev/null; then
- newdeplibs="$newdeplibs $a_deplib"
- a_deplib=""
- break 2
- fi
- done
- done
- fi
- if test -n "$a_deplib" ; then
- droppeddeps=yes
- $echo
- $echo "*** Warning: linker path does not have real file for library $a_deplib."
- $echo "*** I have the capability to make that library automatically link in when"
- $echo "*** you link to this library. But I can only do this if you have a"
- $echo "*** shared version of the library, which you do not appear to have"
- $echo "*** because I did check the linker path looking for a file starting"
- if test -z "$potlib" ; then
- $echo "*** with $libname but no candidates were found. (...for regex pattern test)"
- else
- $echo "*** with $libname and none of the candidates passed a file format test"
- $echo "*** using a regex pattern. Last file checked: $potlib"
- fi
- fi
- else
- # Add a -L argument.
- newdeplibs="$newdeplibs $a_deplib"
- fi
- done # Gone through all deplibs.
- ;;
- none | unknown | *)
- newdeplibs=""
- tmp_deplibs=`$echo "X $deplibs" | $Xsed -e 's/ -lc$//' \
- -e 's/ -[LR][^ ]*//g'`
- if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
- for i in $predeps $postdeps ; do
- # can't use Xsed below, because $i might contain '/'
- tmp_deplibs=`$echo "X $tmp_deplibs" | ${SED} -e "1s,^X,," -e "s,$i,,"`
- done
- fi
- if $echo "X $tmp_deplibs" | $Xsed -e 's/[ ]//g' \
- | grep . >/dev/null; then
- $echo
- if test "X$deplibs_check_method" = "Xnone"; then
- $echo "*** Warning: inter-library dependencies are not supported in this platform."
- else
- $echo "*** Warning: inter-library dependencies are not known to be supported."
- fi
- $echo "*** All declared inter-library dependencies are being dropped."
- droppeddeps=yes
- fi
- ;;
- esac
- versuffix=$versuffix_save
- major=$major_save
- release=$release_save
- libname=$libname_save
- name=$name_save
-
- case $host in
- *-*-rhapsody* | *-*-darwin1.[012])
- # On Rhapsody replace the C library is the System framework
- newdeplibs=`$echo "X $newdeplibs" | $Xsed -e 's/ -lc / -framework System /'`
- ;;
- esac
-
- if test "$droppeddeps" = yes; then
- if test "$module" = yes; then
- $echo
- $echo "*** Warning: libtool could not satisfy all declared inter-library"
- $echo "*** dependencies of module $libname. Therefore, libtool will create"
- $echo "*** a static module, that should work as long as the dlopening"
- $echo "*** application is linked with the -dlopen flag."
- if test -z "$global_symbol_pipe"; then
- $echo
- $echo "*** However, this would only work if libtool was able to extract symbol"
- $echo "*** lists from a program, using \`nm' or equivalent, but libtool could"
- $echo "*** not find such a program. So, this module is probably useless."
- $echo "*** \`nm' from GNU binutils and a full rebuild may help."
- fi
- if test "$build_old_libs" = no; then
- oldlibs="$output_objdir/$libname.$libext"
- build_libtool_libs=module
- build_old_libs=yes
- else
- build_libtool_libs=no
- fi
- else
- $echo "*** The inter-library dependencies that have been dropped here will be"
- $echo "*** automatically added whenever a program is linked with this library"
- $echo "*** or is declared to -dlopen it."
-
- if test "$allow_undefined" = no; then
- $echo
- $echo "*** Since this library must not contain undefined symbols,"
- $echo "*** because either the platform does not support them or"
- $echo "*** it was explicitly requested with -no-undefined,"
- $echo "*** libtool will only create a static version of it."
- if test "$build_old_libs" = no; then
- oldlibs="$output_objdir/$libname.$libext"
- build_libtool_libs=module
- build_old_libs=yes
- else
- build_libtool_libs=no
- fi
- fi
- fi
- fi
- # Done checking deplibs!
- deplibs=$newdeplibs
- fi
-
-
- # move library search paths that coincide with paths to not yet
- # installed libraries to the beginning of the library search list
- new_libs=
- for path in $notinst_path; do
- case " $new_libs " in
- *" -L$path/$objdir "*) ;;
- *)
- case " $deplibs " in
- *" -L$path/$objdir "*)
- new_libs="$new_libs -L$path/$objdir" ;;
- esac
- ;;
- esac
- done
- for deplib in $deplibs; do
- case $deplib in
- -L*)
- case " $new_libs " in
- *" $deplib "*) ;;
- *) new_libs="$new_libs $deplib" ;;
- esac
- ;;
- *) new_libs="$new_libs $deplib" ;;
- esac
- done
- deplibs="$new_libs"
-
-
- # All the library-specific variables (install_libdir is set above).
- library_names=
- old_library=
- dlname=
-
- # Test again, we may have decided not to build it any more
- if test "$build_libtool_libs" = yes; then
- if test "$hardcode_into_libs" = yes; then
- # Hardcode the library paths
- hardcode_libdirs=
- dep_rpath=
- rpath="$finalize_rpath"
- test "$mode" != relink && rpath="$compile_rpath$rpath"
- for libdir in $rpath; do
- if test -n "$hardcode_libdir_flag_spec"; then
- if test -n "$hardcode_libdir_separator"; then
- if test -z "$hardcode_libdirs"; then
- hardcode_libdirs="$libdir"
- else
- # Just accumulate the unique libdirs.
- case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
- *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
- ;;
- *)
- hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
- ;;
- esac
- fi
- else
- eval flag=\"$hardcode_libdir_flag_spec\"
- dep_rpath="$dep_rpath $flag"
- fi
- elif test -n "$runpath_var"; then
- case "$perm_rpath " in
- *" $libdir "*) ;;
- *) perm_rpath="$perm_rpath $libdir" ;;
- esac
- fi
- done
- # Substitute the hardcoded libdirs into the rpath.
- if test -n "$hardcode_libdir_separator" &&
- test -n "$hardcode_libdirs"; then
- libdir="$hardcode_libdirs"
- if test -n "$hardcode_libdir_flag_spec_ld"; then
- case $archive_cmds in
- *\$LD*) eval dep_rpath=\"$hardcode_libdir_flag_spec_ld\" ;;
- *) eval dep_rpath=\"$hardcode_libdir_flag_spec\" ;;
- esac
- else
- eval dep_rpath=\"$hardcode_libdir_flag_spec\"
- fi
- fi
- if test -n "$runpath_var" && test -n "$perm_rpath"; then
- # We should set the runpath_var.
- rpath=
- for dir in $perm_rpath; do
- rpath="$rpath$dir:"
- done
- eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var"
- fi
- test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs"
- fi
-
- shlibpath="$finalize_shlibpath"
- test "$mode" != relink && shlibpath="$compile_shlibpath$shlibpath"
- if test -n "$shlibpath"; then
- eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var"
- fi
-
- # Get the real and link names of the library.
- eval shared_ext=\"$shrext_cmds\"
- eval library_names=\"$library_names_spec\"
- set dummy $library_names
- realname="$2"
- shift; shift
-
- if test -n "$soname_spec"; then
- eval soname=\"$soname_spec\"
- else
- soname="$realname"
- fi
- if test -z "$dlname"; then
- dlname=$soname
- fi
-
- lib="$output_objdir/$realname"
- linknames=
- for link
- do
- linknames="$linknames $link"
- done
-
- # Use standard objects if they are pic
- test -z "$pic_flag" && libobjs=`$echo "X$libobjs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
-
- # Prepare the list of exported symbols
- if test -z "$export_symbols"; then
- if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then
- $show "generating symbol list for \`$libname.la'"
- export_symbols="$output_objdir/$libname.exp"
- $run $rm $export_symbols
- cmds=$export_symbols_cmds
- save_ifs="$IFS"; IFS='~'
- for cmd in $cmds; do
- IFS="$save_ifs"
- eval cmd=\"$cmd\"
- if len=`expr "X$cmd" : ".*"` &&
- test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then
- $show "$cmd"
- $run eval "$cmd" || exit $?
- skipped_export=false
- else
- # The command line is too long to execute in one step.
- $show "using reloadable object file for export list..."
- skipped_export=:
- # Break out early, otherwise skipped_export may be
- # set to false by a later but shorter cmd.
- break
- fi
- done
- IFS="$save_ifs"
- if test -n "$export_symbols_regex"; then
- $show "$EGREP -e \"$export_symbols_regex\" \"$export_symbols\" > \"${export_symbols}T\""
- $run eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
- $show "$mv \"${export_symbols}T\" \"$export_symbols\""
- $run eval '$mv "${export_symbols}T" "$export_symbols"'
- fi
- fi
- fi
-
- if test -n "$export_symbols" && test -n "$include_expsyms"; then
- $run eval '$echo "X$include_expsyms" | $SP2NL >> "$export_symbols"'
- fi
-
- tmp_deplibs=
- for test_deplib in $deplibs; do
- case " $convenience " in
- *" $test_deplib "*) ;;
- *)
- tmp_deplibs="$tmp_deplibs $test_deplib"
- ;;
- esac
- done
- deplibs="$tmp_deplibs"
-
- if test -n "$convenience"; then
- if test -n "$whole_archive_flag_spec"; then
- save_libobjs=$libobjs
- eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
- else
- gentop="$output_objdir/${outputname}x"
- generated="$generated $gentop"
-
- func_extract_archives $gentop $convenience
- libobjs="$libobjs $func_extract_archives_result"
- fi
- fi
-
- if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then
- eval flag=\"$thread_safe_flag_spec\"
- linker_flags="$linker_flags $flag"
- fi
-
- # Make a backup of the uninstalled library when relinking
- if test "$mode" = relink; then
- $run eval '(cd $output_objdir && $rm ${realname}U && $mv $realname ${realname}U)' || exit $?
- fi
-
- # Do each of the archive commands.
- if test "$module" = yes && test -n "$module_cmds" ; then
- if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
- eval test_cmds=\"$module_expsym_cmds\"
- cmds=$module_expsym_cmds
- else
- eval test_cmds=\"$module_cmds\"
- cmds=$module_cmds
- fi
- else
- if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
- eval test_cmds=\"$archive_expsym_cmds\"
- cmds=$archive_expsym_cmds
- else
- eval test_cmds=\"$archive_cmds\"
- cmds=$archive_cmds
- fi
- fi
-
- if test "X$skipped_export" != "X:" &&
- len=`expr "X$test_cmds" : ".*" 2>/dev/null` &&
- test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then
- :
- else
- # The command line is too long to link in one step, link piecewise.
- $echo "creating reloadable object files..."
-
- # Save the value of $output and $libobjs because we want to
- # use them later. If we have whole_archive_flag_spec, we
- # want to use save_libobjs as it was before
- # whole_archive_flag_spec was expanded, because we can't
- # assume the linker understands whole_archive_flag_spec.
- # This may have to be revisited, in case too many
- # convenience libraries get linked in and end up exceeding
- # the spec.
- if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then
- save_libobjs=$libobjs
- fi
- save_output=$output
- output_la=`$echo "X$output" | $Xsed -e "$basename"`
-
- # Clear the reloadable object creation command queue and
- # initialize k to one.
- test_cmds=
- concat_cmds=
- objlist=
- delfiles=
- last_robj=
- k=1
- output=$output_objdir/$output_la-${k}.$objext
- # Loop over the list of objects to be linked.
- for obj in $save_libobjs
- do
- eval test_cmds=\"$reload_cmds $objlist $last_robj\"
- if test "X$objlist" = X ||
- { len=`expr "X$test_cmds" : ".*" 2>/dev/null` &&
- test "$len" -le "$max_cmd_len"; }; then
- objlist="$objlist $obj"
- else
- # The command $test_cmds is almost too long, add a
- # command to the queue.
- if test "$k" -eq 1 ; then
- # The first file doesn't have a previous command to add.
- eval concat_cmds=\"$reload_cmds $objlist $last_robj\"
- else
- # All subsequent reloadable object files will link in
- # the last one created.
- eval concat_cmds=\"\$concat_cmds~$reload_cmds $objlist $last_robj\"
- fi
- last_robj=$output_objdir/$output_la-${k}.$objext
- k=`expr $k + 1`
- output=$output_objdir/$output_la-${k}.$objext
- objlist=$obj
- len=1
- fi
- done
- # Handle the remaining objects by creating one last
- # reloadable object file. All subsequent reloadable object
- # files will link in the last one created.
- test -z "$concat_cmds" || concat_cmds=$concat_cmds~
- eval concat_cmds=\"\${concat_cmds}$reload_cmds $objlist $last_robj\"
-
- if ${skipped_export-false}; then
- $show "generating symbol list for \`$libname.la'"
- export_symbols="$output_objdir/$libname.exp"
- $run $rm $export_symbols
- libobjs=$output
- # Append the command to create the export file.
- eval concat_cmds=\"\$concat_cmds~$export_symbols_cmds\"
- fi
-
- # Set up a command to remove the reloadable object files
- # after they are used.
- i=0
- while test "$i" -lt "$k"
- do
- i=`expr $i + 1`
- delfiles="$delfiles $output_objdir/$output_la-${i}.$objext"
- done
-
- $echo "creating a temporary reloadable object file: $output"
-
- # Loop through the commands generated above and execute them.
- save_ifs="$IFS"; IFS='~'
- for cmd in $concat_cmds; do
- IFS="$save_ifs"
- $show "$cmd"
- $run eval "$cmd" || exit $?
- done
- IFS="$save_ifs"
-
- libobjs=$output
- # Restore the value of output.
- output=$save_output
-
- if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then
- eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
- fi
- # Expand the library linking commands again to reset the
- # value of $libobjs for piecewise linking.
-
- # Do each of the archive commands.
- if test "$module" = yes && test -n "$module_cmds" ; then
- if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
- cmds=$module_expsym_cmds
- else
- cmds=$module_cmds
- fi
- else
- if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
- cmds=$archive_expsym_cmds
- else
- cmds=$archive_cmds
- fi
- fi
-
- # Append the command to remove the reloadable object files
- # to the just-reset $cmds.
- eval cmds=\"\$cmds~\$rm $delfiles\"
- fi
- save_ifs="$IFS"; IFS='~'
- for cmd in $cmds; do
- IFS="$save_ifs"
- eval cmd=\"$cmd\"
- $show "$cmd"
- $run eval "$cmd" || {
- lt_exit=$?
-
- # Restore the uninstalled library and exit
- if test "$mode" = relink; then
- $run eval '(cd $output_objdir && $rm ${realname}T && $mv ${realname}U $realname)'
- fi
-
- exit $lt_exit
- }
- done
- IFS="$save_ifs"
-
- # Restore the uninstalled library and exit
- if test "$mode" = relink; then
- $run eval '(cd $output_objdir && $rm ${realname}T && $mv $realname ${realname}T && $mv "$realname"U $realname)' || exit $?
-
- if test -n "$convenience"; then
- if test -z "$whole_archive_flag_spec"; then
- $show "${rm}r $gentop"
- $run ${rm}r "$gentop"
- fi
- fi
-
- exit $EXIT_SUCCESS
- fi
-
- # Create links to the real library.
- for linkname in $linknames; do
- if test "$realname" != "$linkname"; then
- $show "(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)"
- $run eval '(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)' || exit $?
- fi
- done
-
- # If -module or -export-dynamic was specified, set the dlname.
- if test "$module" = yes || test "$export_dynamic" = yes; then
- # On all known operating systems, these are identical.
- dlname="$soname"
- fi
- fi
- ;;
-
- obj)
- case " $deplibs" in
- *\ -l* | *\ -L*)
- $echo "$modename: warning: \`-l' and \`-L' are ignored for objects" 1>&2 ;;
- esac
-
- if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
- $echo "$modename: warning: \`-dlopen' is ignored for objects" 1>&2
- fi
-
- if test -n "$rpath"; then
- $echo "$modename: warning: \`-rpath' is ignored for objects" 1>&2
- fi
-
- if test -n "$xrpath"; then
- $echo "$modename: warning: \`-R' is ignored for objects" 1>&2
- fi
-
- if test -n "$vinfo"; then
- $echo "$modename: warning: \`-version-info' is ignored for objects" 1>&2
- fi
-
- if test -n "$release"; then
- $echo "$modename: warning: \`-release' is ignored for objects" 1>&2
- fi
-
- case $output in
- *.lo)
- if test -n "$objs$old_deplibs"; then
- $echo "$modename: cannot build library object \`$output' from non-libtool objects" 1>&2
- exit $EXIT_FAILURE
- fi
- libobj="$output"
- obj=`$echo "X$output" | $Xsed -e "$lo2o"`
- ;;
- *)
- libobj=
- obj="$output"
- ;;
- esac
-
- # Delete the old objects.
- $run $rm $obj $libobj
-
- # Objects from convenience libraries. This assumes
- # single-version convenience libraries. Whenever we create
- # different ones for PIC/non-PIC, this we'll have to duplicate
- # the extraction.
- reload_conv_objs=
- gentop=
- # reload_cmds runs $LD directly, so let us get rid of
- # -Wl from whole_archive_flag_spec and hope we can get by with
- # turning comma into space..
- wl=
-
- if test -n "$convenience"; then
- if test -n "$whole_archive_flag_spec"; then
- eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\"
- reload_conv_objs=$reload_objs\ `$echo "X$tmp_whole_archive_flags" | $Xsed -e 's|,| |g'`
- else
- gentop="$output_objdir/${obj}x"
- generated="$generated $gentop"
-
- func_extract_archives $gentop $convenience
- reload_conv_objs="$reload_objs $func_extract_archives_result"
- fi
- fi
-
- # Create the old-style object.
- reload_objs="$objs$old_deplibs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test
-
- output="$obj"
- cmds=$reload_cmds
- save_ifs="$IFS"; IFS='~'
- for cmd in $cmds; do
- IFS="$save_ifs"
- eval cmd=\"$cmd\"
- $show "$cmd"
- $run eval "$cmd" || exit $?
- done
- IFS="$save_ifs"
-
- # Exit if we aren't doing a library object file.
- if test -z "$libobj"; then
- if test -n "$gentop"; then
- $show "${rm}r $gentop"
- $run ${rm}r $gentop
- fi
-
- exit $EXIT_SUCCESS
- fi
-
- if test "$build_libtool_libs" != yes; then
- if test -n "$gentop"; then
- $show "${rm}r $gentop"
- $run ${rm}r $gentop
- fi
-
- # Create an invalid libtool object if no PIC, so that we don't
- # accidentally link it into a program.
- # $show "echo timestamp > $libobj"
- # $run eval "echo timestamp > $libobj" || exit $?
- exit $EXIT_SUCCESS
- fi
-
- if test -n "$pic_flag" || test "$pic_mode" != default; then
- # Only do commands if we really have different PIC objects.
- reload_objs="$libobjs $reload_conv_objs"
- output="$libobj"
- cmds=$reload_cmds
- save_ifs="$IFS"; IFS='~'
- for cmd in $cmds; do
- IFS="$save_ifs"
- eval cmd=\"$cmd\"
- $show "$cmd"
- $run eval "$cmd" || exit $?
- done
- IFS="$save_ifs"
- fi
-
- if test -n "$gentop"; then
- $show "${rm}r $gentop"
- $run ${rm}r $gentop
- fi
-
- exit $EXIT_SUCCESS
- ;;
-
- prog)
- case $host in
- *cygwin*) output=`$echo $output | ${SED} -e 's,.exe$,,;s,$,.exe,'` ;;
- esac
- if test -n "$vinfo"; then
- $echo "$modename: warning: \`-version-info' is ignored for programs" 1>&2
- fi
-
- if test -n "$release"; then
- $echo "$modename: warning: \`-release' is ignored for programs" 1>&2
- fi
-
- if test "$preload" = yes; then
- if test "$dlopen_support" = unknown && test "$dlopen_self" = unknown &&
- test "$dlopen_self_static" = unknown; then
- $echo "$modename: warning: \`AC_LIBTOOL_DLOPEN' not used. Assuming no dlopen support."
- fi
- fi
-
- case $host in
- *-*-rhapsody* | *-*-darwin1.[012])
- # On Rhapsody replace the C library is the System framework
- compile_deplibs=`$echo "X $compile_deplibs" | $Xsed -e 's/ -lc / -framework System /'`
- finalize_deplibs=`$echo "X $finalize_deplibs" | $Xsed -e 's/ -lc / -framework System /'`
- ;;
- esac
-
- case $host in
- *darwin*)
- # Don't allow lazy linking, it breaks C++ global constructors
- if test "$tagname" = CXX ; then
- compile_command="$compile_command ${wl}-bind_at_load"
- finalize_command="$finalize_command ${wl}-bind_at_load"
- fi
- ;;
- esac
-
-
- # move library search paths that coincide with paths to not yet
- # installed libraries to the beginning of the library search list
- new_libs=
- for path in $notinst_path; do
- case " $new_libs " in
- *" -L$path/$objdir "*) ;;
- *)
- case " $compile_deplibs " in
- *" -L$path/$objdir "*)
- new_libs="$new_libs -L$path/$objdir" ;;
- esac
- ;;
- esac
- done
- for deplib in $compile_deplibs; do
- case $deplib in
- -L*)
- case " $new_libs " in
- *" $deplib "*) ;;
- *) new_libs="$new_libs $deplib" ;;
- esac
- ;;
- *) new_libs="$new_libs $deplib" ;;
- esac
- done
- compile_deplibs="$new_libs"
-
-
- compile_command="$compile_command $compile_deplibs"
- finalize_command="$finalize_command $finalize_deplibs"
-
- if test -n "$rpath$xrpath"; then
- # If the user specified any rpath flags, then add them.
- for libdir in $rpath $xrpath; do
- # This is the magic to use -rpath.
- case "$finalize_rpath " in
- *" $libdir "*) ;;
- *) finalize_rpath="$finalize_rpath $libdir" ;;
- esac
- done
- fi
-
- # Now hardcode the library paths
- rpath=
- hardcode_libdirs=
- for libdir in $compile_rpath $finalize_rpath; do
- if test -n "$hardcode_libdir_flag_spec"; then
- if test -n "$hardcode_libdir_separator"; then
- if test -z "$hardcode_libdirs"; then
- hardcode_libdirs="$libdir"
- else
- # Just accumulate the unique libdirs.
- case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
- *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
- ;;
- *)
- hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
- ;;
- esac
- fi
- else
- eval flag=\"$hardcode_libdir_flag_spec\"
- rpath="$rpath $flag"
- fi
- elif test -n "$runpath_var"; then
- case "$perm_rpath " in
- *" $libdir "*) ;;
- *) perm_rpath="$perm_rpath $libdir" ;;
- esac
- fi
- case $host in
- *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*)
- testbindir=`$echo "X$libdir" | $Xsed -e 's*/lib$*/bin*'`
- case :$dllsearchpath: in
- *":$libdir:"*) ;;
- *) dllsearchpath="$dllsearchpath:$libdir";;
- esac
- case :$dllsearchpath: in
- *":$testbindir:"*) ;;
- *) dllsearchpath="$dllsearchpath:$testbindir";;
- esac
- ;;
- esac
- done
- # Substitute the hardcoded libdirs into the rpath.
- if test -n "$hardcode_libdir_separator" &&
- test -n "$hardcode_libdirs"; then
- libdir="$hardcode_libdirs"
- eval rpath=\" $hardcode_libdir_flag_spec\"
- fi
- compile_rpath="$rpath"
-
- rpath=
- hardcode_libdirs=
- for libdir in $finalize_rpath; do
- if test -n "$hardcode_libdir_flag_spec"; then
- if test -n "$hardcode_libdir_separator"; then
- if test -z "$hardcode_libdirs"; then
- hardcode_libdirs="$libdir"
- else
- # Just accumulate the unique libdirs.
- case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
- *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
- ;;
- *)
- hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
- ;;
- esac
- fi
- else
- eval flag=\"$hardcode_libdir_flag_spec\"
- rpath="$rpath $flag"
- fi
- elif test -n "$runpath_var"; then
- case "$finalize_perm_rpath " in
- *" $libdir "*) ;;
- *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;;
- esac
- fi
- done
- # Substitute the hardcoded libdirs into the rpath.
- if test -n "$hardcode_libdir_separator" &&
- test -n "$hardcode_libdirs"; then
- libdir="$hardcode_libdirs"
- eval rpath=\" $hardcode_libdir_flag_spec\"
- fi
- finalize_rpath="$rpath"
-
- if test -n "$libobjs" && test "$build_old_libs" = yes; then
- # Transform all the library objects into standard objects.
- compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
- finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
- fi
-
- dlsyms=
- if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
- if test -n "$NM" && test -n "$global_symbol_pipe"; then
- dlsyms="${outputname}S.c"
- else
- $echo "$modename: not configured to extract global symbols from dlpreopened files" 1>&2
- fi
- fi
-
- if test -n "$dlsyms"; then
- case $dlsyms in
- "") ;;
- *.c)
- # Discover the nlist of each of the dlfiles.
- nlist="$output_objdir/${outputname}.nm"
-
- $show "$rm $nlist ${nlist}S ${nlist}T"
- $run $rm "$nlist" "${nlist}S" "${nlist}T"
-
- # Parse the name list into a source file.
- $show "creating $output_objdir/$dlsyms"
-
- test -z "$run" && $echo > "$output_objdir/$dlsyms" "\
-/* $dlsyms - symbol resolution table for \`$outputname' dlsym emulation. */
-/* Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP */
-
-#ifdef __cplusplus
-extern \"C\" {
-#endif
-
-/* Prevent the only kind of declaration conflicts we can make. */
-#define lt_preloaded_symbols some_other_symbol
-
-/* External symbol declarations for the compiler. */\
-"
-
- if test "$dlself" = yes; then
- $show "generating symbol list for \`$output'"
-
- test -z "$run" && $echo ': @PROGRAM@ ' > "$nlist"
-
- # Add our own program objects to the symbol list.
- progfiles=`$echo "X$objs$old_deplibs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
- for arg in $progfiles; do
- $show "extracting global C symbols from \`$arg'"
- $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'"
- done
-
- if test -n "$exclude_expsyms"; then
- $run eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T'
- $run eval '$mv "$nlist"T "$nlist"'
- fi
-
- if test -n "$export_symbols_regex"; then
- $run eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T'
- $run eval '$mv "$nlist"T "$nlist"'
- fi
-
- # Prepare the list of exported symbols
- if test -z "$export_symbols"; then
- export_symbols="$output_objdir/$outputname.exp"
- $run $rm $export_symbols
- $run eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"'
- case $host in
- *cygwin* | *mingw* )
- $run eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
- $run eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"'
- ;;
- esac
- else
- $run eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"'
- $run eval 'grep -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T'
- $run eval 'mv "$nlist"T "$nlist"'
- case $host in
- *cygwin* | *mingw* )
- $run eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
- $run eval 'cat "$nlist" >> "$output_objdir/$outputname.def"'
- ;;
- esac
- fi
- fi
-
- for arg in $dlprefiles; do
- $show "extracting global C symbols from \`$arg'"
- name=`$echo "$arg" | ${SED} -e 's%^.*/%%'`
- $run eval '$echo ": $name " >> "$nlist"'
- $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'"
- done
-
- if test -z "$run"; then
- # Make sure we have at least an empty file.
- test -f "$nlist" || : > "$nlist"
-
- if test -n "$exclude_expsyms"; then
- $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T
- $mv "$nlist"T "$nlist"
- fi
-
- # Try sorting and uniquifying the output.
- if grep -v "^: " < "$nlist" |
- if sort -k 3 </dev/null >/dev/null 2>&1; then
- sort -k 3
- else
- sort +2
- fi |
- uniq > "$nlist"S; then
- :
- else
- grep -v "^: " < "$nlist" > "$nlist"S
- fi
-
- if test -f "$nlist"S; then
- eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$dlsyms"'
- else
- $echo '/* NONE */' >> "$output_objdir/$dlsyms"
- fi
-
- $echo >> "$output_objdir/$dlsyms" "\
-
-#undef lt_preloaded_symbols
-
-#if defined (__STDC__) && __STDC__
-# define lt_ptr void *
-#else
-# define lt_ptr char *
-# define const
-#endif
-
-/* The mapping between symbol names and symbols. */
-"
-
- case $host in
- *cygwin* | *mingw* )
- $echo >> "$output_objdir/$dlsyms" "\
-/* DATA imports from DLLs on WIN32 can't be const, because
- runtime relocations are performed -- see ld's documentation
- on pseudo-relocs */
-struct {
-"
- ;;
- * )
- $echo >> "$output_objdir/$dlsyms" "\
-const struct {
-"
- ;;
- esac
-
-
- $echo >> "$output_objdir/$dlsyms" "\
- const char *name;
- lt_ptr address;
-}
-lt_preloaded_symbols[] =
-{\
-"
-
- eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$dlsyms"
-
- $echo >> "$output_objdir/$dlsyms" "\
- {0, (lt_ptr) 0}
-};
-
-/* This works around a problem in FreeBSD linker */
-#ifdef FREEBSD_WORKAROUND
-static const void *lt_preloaded_setup() {
- return lt_preloaded_symbols;
-}
-#endif
-
-#ifdef __cplusplus
-}
-#endif\
-"
- fi
-
- pic_flag_for_symtable=
- case $host in
- # compiling the symbol table file with pic_flag works around
- # a FreeBSD bug that causes programs to crash when -lm is
- # linked before any other PIC object. But we must not use
- # pic_flag when linking with -static. The problem exists in
- # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1.
- *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*)
- case "$compile_command " in
- *" -static "*) ;;
- *) pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND";;
- esac;;
- *-*-hpux*)
- case "$compile_command " in
- *" -static "*) ;;
- *) pic_flag_for_symtable=" $pic_flag";;
- esac
- esac
-
- # Now compile the dynamic symbol file.
- $show "(cd $output_objdir && $LTCC $LTCFLAGS -c$no_builtin_flag$pic_flag_for_symtable \"$dlsyms\")"
- $run eval '(cd $output_objdir && $LTCC $LTCFLAGS -c$no_builtin_flag$pic_flag_for_symtable "$dlsyms")' || exit $?
-
- # Clean up the generated files.
- $show "$rm $output_objdir/$dlsyms $nlist ${nlist}S ${nlist}T"
- $run $rm "$output_objdir/$dlsyms" "$nlist" "${nlist}S" "${nlist}T"
-
- # Transform the symbol file into the correct name.
- case $host in
- *cygwin* | *mingw* )
- if test -f "$output_objdir/${outputname}.def" ; then
- compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}.def $output_objdir/${outputname}S.${objext}%" | $NL2SP`
- finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}.def $output_objdir/${outputname}S.${objext}%" | $NL2SP`
- else
- compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%" | $NL2SP`
- finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%" | $NL2SP`
- fi
- ;;
- * )
- compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%" | $NL2SP`
- finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%" | $NL2SP`
- ;;
- esac
- ;;
- *)
- $echo "$modename: unknown suffix for \`$dlsyms'" 1>&2
- exit $EXIT_FAILURE
- ;;
- esac
- else
- # We keep going just in case the user didn't refer to
- # lt_preloaded_symbols. The linker will fail if global_symbol_pipe
- # really was required.
-
- # Nullify the symbol file.
- compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "s% @SYMFILE@%%" | $NL2SP`
- finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "s% @SYMFILE@%%" | $NL2SP`
- fi
-
- if test "$need_relink" = no || test "$build_libtool_libs" != yes; then
- # Replace the output file specification.
- compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e 's%@OUTPUT@%'"$output"'%g' | $NL2SP`
- link_command="$compile_command$compile_rpath"
-
- # We have no uninstalled library dependencies, so finalize right now.
- $show "$link_command"
- $run eval "$link_command"
- exit_status=$?
-
- # Delete the generated files.
- if test -n "$dlsyms"; then
- $show "$rm $output_objdir/${outputname}S.${objext}"
- $run $rm "$output_objdir/${outputname}S.${objext}"
- fi
-
- exit $exit_status
- fi
-
- if test -n "$shlibpath_var"; then
- # We should set the shlibpath_var
- rpath=
- for dir in $temp_rpath; do
- case $dir in
- [\\/]* | [A-Za-z]:[\\/]*)
- # Absolute path.
- rpath="$rpath$dir:"
- ;;
- *)
- # Relative path: add a thisdir entry.
- rpath="$rpath\$thisdir/$dir:"
- ;;
- esac
- done
- temp_rpath="$rpath"
- fi
-
- if test -n "$compile_shlibpath$finalize_shlibpath"; then
- compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command"
- fi
- if test -n "$finalize_shlibpath"; then
- finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command"
- fi
-
- compile_var=
- finalize_var=
- if test -n "$runpath_var"; then
- if test -n "$perm_rpath"; then
- # We should set the runpath_var.
- rpath=
- for dir in $perm_rpath; do
- rpath="$rpath$dir:"
- done
- compile_var="$runpath_var=\"$rpath\$$runpath_var\" "
- fi
- if test -n "$finalize_perm_rpath"; then
- # We should set the runpath_var.
- rpath=
- for dir in $finalize_perm_rpath; do
- rpath="$rpath$dir:"
- done
- finalize_var="$runpath_var=\"$rpath\$$runpath_var\" "
- fi
- fi
-
- if test "$no_install" = yes; then
- # We don't need to create a wrapper script.
- link_command="$compile_var$compile_command$compile_rpath"
- # Replace the output file specification.
- link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'`
- # Delete the old output file.
- $run $rm $output
- # Link the executable and exit
- $show "$link_command"
- $run eval "$link_command" || exit $?
- exit $EXIT_SUCCESS
- fi
-
- if test "$hardcode_action" = relink; then
- # Fast installation is not supported
- link_command="$compile_var$compile_command$compile_rpath"
- relink_command="$finalize_var$finalize_command$finalize_rpath"
-
- $echo "$modename: warning: this platform does not like uninstalled shared libraries" 1>&2
- $echo "$modename: \`$output' will be relinked during installation" 1>&2
- else
- if test "$fast_install" != no; then
- link_command="$finalize_var$compile_command$finalize_rpath"
- if test "$fast_install" = yes; then
- relink_command=`$echo "X$compile_var$compile_command$compile_rpath" | $SP2NL | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g' | $NL2SP`
- else
- # fast_install is set to needless
- relink_command=
- fi
- else
- link_command="$compile_var$compile_command$compile_rpath"
- relink_command="$finalize_var$finalize_command$finalize_rpath"
- fi
- fi
-
- # Replace the output file specification.
- link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'`
-
- # Delete the old output files.
- $run $rm $output $output_objdir/$outputname $output_objdir/lt-$outputname
-
- $show "$link_command"
- $run eval "$link_command" || exit $?
-
- # Now create the wrapper script.
- $show "creating $output"
-
- # Quote the relink command for shipping.
- if test -n "$relink_command"; then
- # Preserve any variables that may affect compiler behavior
- for var in $variables_saved_for_relink; do
- if eval test -z \"\${$var+set}\"; then
- relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command"
- elif eval var_value=\$$var; test -z "$var_value"; then
- relink_command="$var=; export $var; $relink_command"
- else
- var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"`
- relink_command="$var=\"$var_value\"; export $var; $relink_command"
- fi
- done
- relink_command="(cd `pwd`; $relink_command)"
- relink_command=`$echo "X$relink_command" | $SP2NL | $Xsed -e "$sed_quote_subst" | $NL2SP`
- fi
-
- # Quote $echo for shipping.
- if test "X$echo" = "X$SHELL $progpath --fallback-echo"; then
- case $progpath in
- [\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $progpath --fallback-echo";;
- *) qecho="$SHELL `pwd`/$progpath --fallback-echo";;
- esac
- qecho=`$echo "X$qecho" | $Xsed -e "$sed_quote_subst"`
- else
- qecho=`$echo "X$echo" | $Xsed -e "$sed_quote_subst"`
- fi
-
- # Only actually do things if our run command is non-null.
- if test -z "$run"; then
- # win32 will think the script is a binary if it has
- # a .exe suffix, so we strip it off here.
- case $output in
- *.exe) output=`$echo $output|${SED} 's,.exe$,,'` ;;
- esac
- # test for cygwin because mv fails w/o .exe extensions
- case $host in
- *cygwin*)
- exeext=.exe
- outputname=`$echo $outputname|${SED} 's,.exe$,,'` ;;
- *) exeext= ;;
- esac
- case $host in
- *cygwin* | *mingw* )
- output_name=`basename $output`
- output_path=`dirname $output`
- cwrappersource="$output_path/$objdir/lt-$output_name.c"
- cwrapper="$output_path/$output_name.exe"
- $rm $cwrappersource $cwrapper
- trap "$rm $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15
-
- cat > $cwrappersource <<EOF
-
-/* $cwrappersource - temporary wrapper executable for $objdir/$outputname
- Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP
-
- The $output program cannot be directly executed until all the libtool
- libraries that it depends on are installed.
-
- This wrapper executable should never be moved out of the build directory.
- If it is, it will not operate correctly.
-
- Currently, it simply execs the wrapper *script* "/bin/sh $output",
- but could eventually absorb all of the scripts functionality and
- exec $objdir/$outputname directly.
-*/
-EOF
- cat >> $cwrappersource<<"EOF"
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <malloc.h>
-#include <stdarg.h>
-#include <assert.h>
-#include <string.h>
-#include <ctype.h>
-#include <sys/stat.h>
-
-#if defined(PATH_MAX)
-# define LT_PATHMAX PATH_MAX
-#elif defined(MAXPATHLEN)
-# define LT_PATHMAX MAXPATHLEN
-#else
-# define LT_PATHMAX 1024
-#endif
-
-#ifndef DIR_SEPARATOR
-# define DIR_SEPARATOR '/'
-# define PATH_SEPARATOR ':'
-#endif
-
-#if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \
- defined (__OS2__)
-# define HAVE_DOS_BASED_FILE_SYSTEM
-# ifndef DIR_SEPARATOR_2
-# define DIR_SEPARATOR_2 '\\'
-# endif
-# ifndef PATH_SEPARATOR_2
-# define PATH_SEPARATOR_2 ';'
-# endif
-#endif
-
-#ifndef DIR_SEPARATOR_2
-# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR)
-#else /* DIR_SEPARATOR_2 */
-# define IS_DIR_SEPARATOR(ch) \
- (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2))
-#endif /* DIR_SEPARATOR_2 */
-
-#ifndef PATH_SEPARATOR_2
-# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR)
-#else /* PATH_SEPARATOR_2 */
-# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2)
-#endif /* PATH_SEPARATOR_2 */
-
-#define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type)))
-#define XFREE(stale) do { \
- if (stale) { free ((void *) stale); stale = 0; } \
-} while (0)
-
-/* -DDEBUG is fairly common in CFLAGS. */
-#undef DEBUG
-#if defined DEBUGWRAPPER
-# define DEBUG(format, ...) fprintf(stderr, format, __VA_ARGS__)
-#else
-# define DEBUG(format, ...)
-#endif
-
-const char *program_name = NULL;
-
-void * xmalloc (size_t num);
-char * xstrdup (const char *string);
-const char * base_name (const char *name);
-char * find_executable(const char *wrapper);
-int check_executable(const char *path);
-char * strendzap(char *str, const char *pat);
-void lt_fatal (const char *message, ...);
-
-int
-main (int argc, char *argv[])
-{
- char **newargz;
- int i;
-
- program_name = (char *) xstrdup (base_name (argv[0]));
- DEBUG("(main) argv[0] : %s\n",argv[0]);
- DEBUG("(main) program_name : %s\n",program_name);
- newargz = XMALLOC(char *, argc+2);
-EOF
-
- cat >> $cwrappersource <<EOF
- newargz[0] = (char *) xstrdup("$SHELL");
-EOF
-
- cat >> $cwrappersource <<"EOF"
- newargz[1] = find_executable(argv[0]);
- if (newargz[1] == NULL)
- lt_fatal("Couldn't find %s", argv[0]);
- DEBUG("(main) found exe at : %s\n",newargz[1]);
- /* we know the script has the same name, without the .exe */
- /* so make sure newargz[1] doesn't end in .exe */
- strendzap(newargz[1],".exe");
- for (i = 1; i < argc; i++)
- newargz[i+1] = xstrdup(argv[i]);
- newargz[argc+1] = NULL;
-
- for (i=0; i<argc+1; i++)
- {
- DEBUG("(main) newargz[%d] : %s\n",i,newargz[i]);
- ;
- }
-
-EOF
-
- case $host_os in
- mingw*)
- cat >> $cwrappersource <<EOF
- execv("$SHELL",(char const **)newargz);
-EOF
- ;;
- *)
- cat >> $cwrappersource <<EOF
- execv("$SHELL",newargz);
-EOF
- ;;
- esac
-
- cat >> $cwrappersource <<"EOF"
- return 127;
-}
-
-void *
-xmalloc (size_t num)
-{
- void * p = (void *) malloc (num);
- if (!p)
- lt_fatal ("Memory exhausted");
-
- return p;
-}
-
-char *
-xstrdup (const char *string)
-{
- return string ? strcpy ((char *) xmalloc (strlen (string) + 1), string) : NULL
-;
-}
-
-const char *
-base_name (const char *name)
-{
- const char *base;
-
-#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
- /* Skip over the disk name in MSDOS pathnames. */
- if (isalpha ((unsigned char)name[0]) && name[1] == ':')
- name += 2;
-#endif
-
- for (base = name; *name; name++)
- if (IS_DIR_SEPARATOR (*name))
- base = name + 1;
- return base;
-}
-
-int
-check_executable(const char * path)
-{
- struct stat st;
-
- DEBUG("(check_executable) : %s\n", path ? (*path ? path : "EMPTY!") : "NULL!");
- if ((!path) || (!*path))
- return 0;
-
- if ((stat (path, &st) >= 0) &&
- (
- /* MinGW & native WIN32 do not support S_IXOTH or S_IXGRP */
-#if defined (S_IXOTH)
- ((st.st_mode & S_IXOTH) == S_IXOTH) ||
-#endif
-#if defined (S_IXGRP)
- ((st.st_mode & S_IXGRP) == S_IXGRP) ||
-#endif
- ((st.st_mode & S_IXUSR) == S_IXUSR))
- )
- return 1;
- else
- return 0;
-}
-
-/* Searches for the full path of the wrapper. Returns
- newly allocated full path name if found, NULL otherwise */
-char *
-find_executable (const char* wrapper)
-{
- int has_slash = 0;
- const char* p;
- const char* p_next;
- /* static buffer for getcwd */
- char tmp[LT_PATHMAX + 1];
- int tmp_len;
- char* concat_name;
-
- DEBUG("(find_executable) : %s\n", wrapper ? (*wrapper ? wrapper : "EMPTY!") : "NULL!");
-
- if ((wrapper == NULL) || (*wrapper == '\0'))
- return NULL;
-
- /* Absolute path? */
-#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
- if (isalpha ((unsigned char)wrapper[0]) && wrapper[1] == ':')
- {
- concat_name = xstrdup (wrapper);
- if (check_executable(concat_name))
- return concat_name;
- XFREE(concat_name);
- }
- else
- {
-#endif
- if (IS_DIR_SEPARATOR (wrapper[0]))
- {
- concat_name = xstrdup (wrapper);
- if (check_executable(concat_name))
- return concat_name;
- XFREE(concat_name);
- }
-#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
- }
-#endif
-
- for (p = wrapper; *p; p++)
- if (*p == '/')
- {
- has_slash = 1;
- break;
- }
- if (!has_slash)
- {
- /* no slashes; search PATH */
- const char* path = getenv ("PATH");
- if (path != NULL)
- {
- for (p = path; *p; p = p_next)
- {
- const char* q;
- size_t p_len;
- for (q = p; *q; q++)
- if (IS_PATH_SEPARATOR(*q))
- break;
- p_len = q - p;
- p_next = (*q == '\0' ? q : q + 1);
- if (p_len == 0)
- {
- /* empty path: current directory */
- if (getcwd (tmp, LT_PATHMAX) == NULL)
- lt_fatal ("getcwd failed");
- tmp_len = strlen(tmp);
- concat_name = XMALLOC(char, tmp_len + 1 + strlen(wrapper) + 1);
- memcpy (concat_name, tmp, tmp_len);
- concat_name[tmp_len] = '/';
- strcpy (concat_name + tmp_len + 1, wrapper);
- }
- else
- {
- concat_name = XMALLOC(char, p_len + 1 + strlen(wrapper) + 1);
- memcpy (concat_name, p, p_len);
- concat_name[p_len] = '/';
- strcpy (concat_name + p_len + 1, wrapper);
- }
- if (check_executable(concat_name))
- return concat_name;
- XFREE(concat_name);
- }
- }
- /* not found in PATH; assume curdir */
- }
- /* Relative path | not found in path: prepend cwd */
- if (getcwd (tmp, LT_PATHMAX) == NULL)
- lt_fatal ("getcwd failed");
- tmp_len = strlen(tmp);
- concat_name = XMALLOC(char, tmp_len + 1 + strlen(wrapper) + 1);
- memcpy (concat_name, tmp, tmp_len);
- concat_name[tmp_len] = '/';
- strcpy (concat_name + tmp_len + 1, wrapper);
-
- if (check_executable(concat_name))
- return concat_name;
- XFREE(concat_name);
- return NULL;
-}
-
-char *
-strendzap(char *str, const char *pat)
-{
- size_t len, patlen;
-
- assert(str != NULL);
- assert(pat != NULL);
-
- len = strlen(str);
- patlen = strlen(pat);
-
- if (patlen <= len)
- {
- str += len - patlen;
- if (strcmp(str, pat) == 0)
- *str = '\0';
- }
- return str;
-}
-
-static void
-lt_error_core (int exit_status, const char * mode,
- const char * message, va_list ap)
-{
- fprintf (stderr, "%s: %s: ", program_name, mode);
- vfprintf (stderr, message, ap);
- fprintf (stderr, ".\n");
-
- if (exit_status >= 0)
- exit (exit_status);
-}
-
-void
-lt_fatal (const char *message, ...)
-{
- va_list ap;
- va_start (ap, message);
- lt_error_core (EXIT_FAILURE, "FATAL", message, ap);
- va_end (ap);
-}
-EOF
- # we should really use a build-platform specific compiler
- # here, but OTOH, the wrappers (shell script and this C one)
- # are only useful if you want to execute the "real" binary.
- # Since the "real" binary is built for $host, then this
- # wrapper might as well be built for $host, too.
- $run $LTCC $LTCFLAGS -s -o $cwrapper $cwrappersource
- ;;
- esac
- $rm $output
- trap "$rm $output; exit $EXIT_FAILURE" 1 2 15
-
- $echo > $output "\
-#! $SHELL
-
-# $output - temporary wrapper script for $objdir/$outputname
-# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP
-#
-# The $output program cannot be directly executed until all the libtool
-# libraries that it depends on are installed.
-#
-# This wrapper script should never be moved out of the build directory.
-# If it is, it will not operate correctly.
-
-# Sed substitution that helps us do robust quoting. It backslashifies
-# metacharacters that are still active within double-quoted strings.
-Xsed='${SED} -e 1s/^X//'
-sed_quote_subst='$sed_quote_subst'
-
-# Be Bourne compatible (taken from Autoconf:_AS_BOURNE_COMPATIBLE).
-if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then
- emulate sh
- NULLCMD=:
- # Zsh 3.x and 4.x performs 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
-BIN_SH=xpg4; export BIN_SH # for Tru64
-DUALCASE=1; export DUALCASE # for MKS sh
-
-# The HP-UX ksh and POSIX shell print the target directory to stdout
-# if CDPATH is set.
-(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
-
-relink_command=\"$relink_command\"
-
-# This environment variable determines our operation mode.
-if test \"\$libtool_install_magic\" = \"$magic\"; then
- # install mode needs the following variable:
- notinst_deplibs='$notinst_deplibs'
-else
- # When we are sourced in execute mode, \$file and \$echo are already set.
- if test \"\$libtool_execute_magic\" != \"$magic\"; then
- echo=\"$qecho\"
- file=\"\$0\"
- # Make sure echo works.
- if test \"X\$1\" = X--no-reexec; then
- # Discard the --no-reexec flag, and continue.
- shift
- elif test \"X\`(\$echo '\t') 2>/dev/null\`\" = 'X\t'; then
- # Yippee, \$echo works!
- :
- else
- # Restart under the correct shell, and then maybe \$echo will work.
- exec $SHELL \"\$0\" --no-reexec \${1+\"\$@\"}
- fi
- fi\
-"
- $echo >> $output "\
-
- # Find the directory that this script lives in.
- thisdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\`
- test \"x\$thisdir\" = \"x\$file\" && thisdir=.
-
- # Follow symbolic links until we get to the real thisdir.
- file=\`ls -ld \"\$file\" | ${SED} -n 's/.*-> //p'\`
- while test -n \"\$file\"; do
- destdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\`
-
- # If there was a directory component, then change thisdir.
- if test \"x\$destdir\" != \"x\$file\"; then
- case \"\$destdir\" in
- [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;;
- *) thisdir=\"\$thisdir/\$destdir\" ;;
- esac
- fi
-
- file=\`\$echo \"X\$file\" | \$Xsed -e 's%^.*/%%'\`
- file=\`ls -ld \"\$thisdir/\$file\" | ${SED} -n 's/.*-> //p'\`
- done
-
- # Try to get the absolute directory name.
- absdir=\`cd \"\$thisdir\" && pwd\`
- test -n \"\$absdir\" && thisdir=\"\$absdir\"
-"
-
- if test "$fast_install" = yes; then
- $echo >> $output "\
- program=lt-'$outputname'$exeext
- progdir=\"\$thisdir/$objdir\"
-
- if test ! -f \"\$progdir/\$program\" || \\
- { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\
- test \"X\$file\" != \"X\$progdir/\$program\"; }; then
-
- file=\"\$\$-\$program\"
-
- if test ! -d \"\$progdir\"; then
- $mkdir \"\$progdir\"
- else
- $rm \"\$progdir/\$file\"
- fi"
-
- $echo >> $output "\
-
- # relink executable if necessary
- if test -n \"\$relink_command\"; then
- if relink_command_output=\`eval \$relink_command 2>&1\`; then :
- else
- $echo \"\$relink_command_output\" >&2
- $rm \"\$progdir/\$file\"
- exit $EXIT_FAILURE
- fi
- fi
-
- $mv \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null ||
- { $rm \"\$progdir/\$program\";
- $mv \"\$progdir/\$file\" \"\$progdir/\$program\"; }
- $rm \"\$progdir/\$file\"
- fi"
- else
- $echo >> $output "\
- program='$outputname'
- progdir=\"\$thisdir/$objdir\"
-"
- fi
-
- $echo >> $output "\
-
- if test -f \"\$progdir/\$program\"; then"
-
- # Export our shlibpath_var if we have one.
- if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
- $echo >> $output "\
- # Add our own library path to $shlibpath_var
- $shlibpath_var=\"$temp_rpath\$$shlibpath_var\"
-
- # Some systems cannot cope with colon-terminated $shlibpath_var
- # The second colon is a workaround for a bug in BeOS R4 sed
- $shlibpath_var=\`\$echo \"X\$$shlibpath_var\" | \$Xsed -e 's/::*\$//'\`
-
- export $shlibpath_var
-"
- fi
-
- # fixup the dll searchpath if we need to.
- if test -n "$dllsearchpath"; then
- $echo >> $output "\
- # Add the dll search path components to the executable PATH
- PATH=$dllsearchpath:\$PATH
-"
- fi
-
- $echo >> $output "\
- if test \"\$libtool_execute_magic\" != \"$magic\"; then
- # Run the actual program with our arguments.
-
- # Make sure env LD_LIBRARY_PATH does not mess us up
- if test -n \"\${LD_LIBRARY_PATH+set}\"; then
- export LD_LIBRARY_PATH=\$progdir:\$LD_LIBRARY_PATH
- fi
-"
- case $host in
- # Backslashes separate directories on plain windows
- *-*-mingw | *-*-os2*)
- $echo >> $output "\
- exec \"\$progdir\\\\\$program\" \${1+\"\$@\"}
-"
- ;;
-
- *)
- $echo >> $output "\
- exec \"\$progdir/\$program\" \${1+\"\$@\"}
-"
- ;;
- esac
- $echo >> $output "\
- \$echo \"\$0: cannot exec \$program \$*\"
- exit $EXIT_FAILURE
- fi
- else
- # The program doesn't exist.
- \$echo \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2
- \$echo \"This script is just a wrapper for \$program.\" 1>&2
- $echo \"See the $PACKAGE documentation for more information.\" 1>&2
- exit $EXIT_FAILURE
- fi
-fi\
-"
- chmod +x $output
- fi
- exit $EXIT_SUCCESS
- ;;
- esac
-
- # See if we need to build an old-fashioned archive.
- for oldlib in $oldlibs; do
-
- if test "$build_libtool_libs" = convenience; then
- oldobjs="$libobjs_save"
- addlibs="$convenience"
- build_libtool_libs=no
- else
- if test "$build_libtool_libs" = module; then
- oldobjs="$libobjs_save"
- build_libtool_libs=no
- else
- oldobjs="$old_deplibs $non_pic_objects"
- fi
- addlibs="$old_convenience"
- fi
-
- if test -n "$addlibs"; then
- gentop="$output_objdir/${outputname}x"
- generated="$generated $gentop"
-
- func_extract_archives $gentop $addlibs
- oldobjs="$oldobjs $func_extract_archives_result"
- fi
-
- # Do each command in the archive commands.
- if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then
- cmds=$old_archive_from_new_cmds
- else
- # POSIX demands no paths to be encoded in archives. We have
- # to avoid creating archives with duplicate basenames if we
- # might have to extract them afterwards, e.g., when creating a
- # static archive out of a convenience library, or when linking
- # the entirety of a libtool archive into another (currently
- # not supported by libtool).
- if (for obj in $oldobjs
- do
- $echo "X$obj" | $Xsed -e 's%^.*/%%'
- done | sort | sort -uc >/dev/null 2>&1); then
- :
- else
- $echo "copying selected object files to avoid basename conflicts..."
-
- if test -z "$gentop"; then
- gentop="$output_objdir/${outputname}x"
- generated="$generated $gentop"
-
- $show "${rm}r $gentop"
- $run ${rm}r "$gentop"
- $show "$mkdir $gentop"
- $run $mkdir "$gentop"
- exit_status=$?
- if test "$exit_status" -ne 0 && test ! -d "$gentop"; then
- exit $exit_status
- fi
- fi
-
- save_oldobjs=$oldobjs
- oldobjs=
- counter=1
- for obj in $save_oldobjs
- do
- objbase=`$echo "X$obj" | $Xsed -e 's%^.*/%%'`
- case " $oldobjs " in
- " ") oldobjs=$obj ;;
- *[\ /]"$objbase "*)
- while :; do
- # Make sure we don't pick an alternate name that also
- # overlaps.
- newobj=lt$counter-$objbase
- counter=`expr $counter + 1`
- case " $oldobjs " in
- *[\ /]"$newobj "*) ;;
- *) if test ! -f "$gentop/$newobj"; then break; fi ;;
- esac
- done
- $show "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj"
- $run ln "$obj" "$gentop/$newobj" ||
- $run cp "$obj" "$gentop/$newobj"
- oldobjs="$oldobjs $gentop/$newobj"
- ;;
- *) oldobjs="$oldobjs $obj" ;;
- esac
- done
- fi
-
- eval cmds=\"$old_archive_cmds\"
-
- if len=`expr "X$cmds" : ".*"` &&
- test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then
- cmds=$old_archive_cmds
- else
- # the command line is too long to link in one step, link in parts
- $echo "using piecewise archive linking..."
- save_RANLIB=$RANLIB
- RANLIB=:
- objlist=
- concat_cmds=
- save_oldobjs=$oldobjs
-
- # Is there a better way of finding the last object in the list?
- for obj in $save_oldobjs
- do
- last_oldobj=$obj
- done
- for obj in $save_oldobjs
- do
- oldobjs="$objlist $obj"
- objlist="$objlist $obj"
- eval test_cmds=\"$old_archive_cmds\"
- if len=`expr "X$test_cmds" : ".*" 2>/dev/null` &&
- test "$len" -le "$max_cmd_len"; then
- :
- else
- # the above command should be used before it gets too long
- oldobjs=$objlist
- if test "$obj" = "$last_oldobj" ; then
- RANLIB=$save_RANLIB
- fi
- test -z "$concat_cmds" || concat_cmds=$concat_cmds~
- eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\"
- objlist=
- fi
- done
- RANLIB=$save_RANLIB
- oldobjs=$objlist
- if test "X$oldobjs" = "X" ; then
- eval cmds=\"\$concat_cmds\"
- else
- eval cmds=\"\$concat_cmds~\$old_archive_cmds\"
- fi
- fi
- fi
- save_ifs="$IFS"; IFS='~'
- for cmd in $cmds; do
- eval cmd=\"$cmd\"
- IFS="$save_ifs"
- $show "$cmd"
- $run eval "$cmd" || exit $?
- done
- IFS="$save_ifs"
- done
-
- if test -n "$generated"; then
- $show "${rm}r$generated"
- $run ${rm}r$generated
- fi
-
- # Now create the libtool archive.
- case $output in
- *.la)
- old_library=
- test "$build_old_libs" = yes && old_library="$libname.$libext"
- $show "creating $output"
-
- # Preserve any variables that may affect compiler behavior
- for var in $variables_saved_for_relink; do
- if eval test -z \"\${$var+set}\"; then
- relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command"
- elif eval var_value=\$$var; test -z "$var_value"; then
- relink_command="$var=; export $var; $relink_command"
- else
- var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"`
- relink_command="$var=\"$var_value\"; export $var; $relink_command"
- fi
- done
- # Quote the link command for shipping.
- relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)"
- relink_command=`$echo "X$relink_command" | $SP2NL | $Xsed -e "$sed_quote_subst" | $NL2SP`
- if test "$hardcode_automatic" = yes ; then
- relink_command=
- fi
-
-
- # Only create the output if not a dry run.
- if test -z "$run"; then
- for installed in no yes; do
- if test "$installed" = yes; then
- if test -z "$install_libdir"; then
- break
- fi
- output="$output_objdir/$outputname"i
- # Replace all uninstalled libtool libraries with the installed ones
- newdependency_libs=
- for deplib in $dependency_libs; do
- case $deplib in
- *.la)
- name=`$echo "X$deplib" | $Xsed -e 's%^.*/%%'`
- eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
- if test -z "$libdir"; then
- $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2
- exit $EXIT_FAILURE
- fi
- newdependency_libs="$newdependency_libs $libdir/$name"
- ;;
- *) newdependency_libs="$newdependency_libs $deplib" ;;
- esac
- done
- dependency_libs="$newdependency_libs"
- newdlfiles=
- for lib in $dlfiles; do
- name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'`
- eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
- if test -z "$libdir"; then
- $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2
- exit $EXIT_FAILURE
- fi
- newdlfiles="$newdlfiles $libdir/$name"
- done
- dlfiles="$newdlfiles"
- newdlprefiles=
- for lib in $dlprefiles; do
- name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'`
- eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
- if test -z "$libdir"; then
- $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2
- exit $EXIT_FAILURE
- fi
- newdlprefiles="$newdlprefiles $libdir/$name"
- done
- dlprefiles="$newdlprefiles"
- else
- newdlfiles=
- for lib in $dlfiles; do
- case $lib in
- [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;;
- *) abs=`pwd`"/$lib" ;;
- esac
- newdlfiles="$newdlfiles $abs"
- done
- dlfiles="$newdlfiles"
- newdlprefiles=
- for lib in $dlprefiles; do
- case $lib in
- [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;;
- *) abs=`pwd`"/$lib" ;;
- esac
- newdlprefiles="$newdlprefiles $abs"
- done
- dlprefiles="$newdlprefiles"
- fi
- $rm $output
- # place dlname in correct position for cygwin
- tdlname=$dlname
- case $host,$output,$installed,$module,$dlname in
- *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll) tdlname=../bin/$dlname ;;
- esac
- $echo > $output "\
-# $outputname - a libtool library file
-# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP
-#
-# Please DO NOT delete this file!
-# It is necessary for linking the library.
-
-# The name that we can dlopen(3).
-dlname='$tdlname'
-
-# Names of this library.
-library_names='$library_names'
-
-# The name of the static archive.
-old_library='$old_library'
-
-# Libraries that this one depends upon.
-dependency_libs='$dependency_libs'
-
-# Version information for $libname.
-current=$current
-age=$age
-revision=$revision
-
-# Is this an already installed library?
-installed=$installed
-
-# Should we warn about portability when linking against -modules?
-shouldnotlink=$module
-
-# Files to dlopen/dlpreopen
-dlopen='$dlfiles'
-dlpreopen='$dlprefiles'
-
-# Directory that this library needs to be installed in:
-libdir='$install_libdir'"
- if test "$installed" = no && test "$need_relink" = yes; then
- $echo >> $output "\
-relink_command=\"$relink_command\""
- fi
- done
- fi
-
- # Do a symbolic link so that the libtool archive can be found in
- # LD_LIBRARY_PATH before the program is installed.
- $show "(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)"
- $run eval '(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)' || exit $?
- ;;
- esac
- exit $EXIT_SUCCESS
- ;;
-
- # libtool install mode
- install)
- modename="$modename: install"
-
- # There may be an optional sh(1) argument at the beginning of
- # install_prog (especially on Windows NT).
- if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh ||
- # Allow the use of GNU shtool's install command.
- $echo "X$nonopt" | grep shtool > /dev/null; then
- # Aesthetically quote it.
- arg=`$echo "X$nonopt" | $Xsed -e "$sed_quote_subst"`
- case $arg in
- *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
- arg="\"$arg\""
- ;;
- esac
- install_prog="$arg "
- arg="$1"
- shift
- else
- install_prog=
- arg=$nonopt
- fi
-
- # The real first argument should be the name of the installation program.
- # Aesthetically quote it.
- arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
- case $arg in
- *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
- arg="\"$arg\""
- ;;
- esac
- install_prog="$install_prog$arg"
-
- # We need to accept at least all the BSD install flags.
- dest=
- files=
- opts=
- prev=
- install_type=
- isdir=no
- stripme=
- for arg
- do
- if test -n "$dest"; then
- files="$files $dest"
- dest=$arg
- continue
- fi
-
- case $arg in
- -d) isdir=yes ;;
- -f)
- case " $install_prog " in
- *[\\\ /]cp\ *) ;;
- *) prev=$arg ;;
- esac
- ;;
- -g | -m | -o) prev=$arg ;;
- -s)
- stripme=" -s"
- continue
- ;;
- -*)
- ;;
- *)
- # If the previous option needed an argument, then skip it.
- if test -n "$prev"; then
- prev=
- else
- dest=$arg
- continue
- fi
- ;;
- esac
-
- # Aesthetically quote the argument.
- arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
- case $arg in
- *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
- arg="\"$arg\""
- ;;
- esac
- install_prog="$install_prog $arg"
- done
-
- if test -z "$install_prog"; then
- $echo "$modename: you must specify an install program" 1>&2
- $echo "$help" 1>&2
- exit $EXIT_FAILURE
- fi
-
- if test -n "$prev"; then
- $echo "$modename: the \`$prev' option requires an argument" 1>&2
- $echo "$help" 1>&2
- exit $EXIT_FAILURE
- fi
-
- if test -z "$files"; then
- if test -z "$dest"; then
- $echo "$modename: no file or destination specified" 1>&2
- else
- $echo "$modename: you must specify a destination" 1>&2
- fi
- $echo "$help" 1>&2
- exit $EXIT_FAILURE
- fi
-
- # Strip any trailing slash from the destination.
- dest=`$echo "X$dest" | $Xsed -e 's%/$%%'`
-
- # Check to see that the destination is a directory.
- test -d "$dest" && isdir=yes
- if test "$isdir" = yes; then
- destdir="$dest"
- destname=
- else
- destdir=`$echo "X$dest" | $Xsed -e 's%/[^/]*$%%'`
- test "X$destdir" = "X$dest" && destdir=.
- destname=`$echo "X$dest" | $Xsed -e 's%^.*/%%'`
-
- # Not a directory, so check to see that there is only one file specified.
- set dummy $files
- if test "$#" -gt 2; then
- $echo "$modename: \`$dest' is not a directory" 1>&2
- $echo "$help" 1>&2
- exit $EXIT_FAILURE
- fi
- fi
- case $destdir in
- [\\/]* | [A-Za-z]:[\\/]*) ;;
- *)
- for file in $files; do
- case $file in
- *.lo) ;;
- *)
- $echo "$modename: \`$destdir' must be an absolute directory name" 1>&2
- $echo "$help" 1>&2
- exit $EXIT_FAILURE
- ;;
- esac
- done
- ;;
- esac
-
- # This variable tells wrapper scripts just to set variables rather
- # than running their programs.
- libtool_install_magic="$magic"
-
- staticlibs=
- future_libdirs=
- current_libdirs=
- for file in $files; do
-
- # Do each installation.
- case $file in
- *.$libext)
- # Do the static libraries later.
- staticlibs="$staticlibs $file"
- ;;
-
- *.la)
- # Check to see that this really is a libtool archive.
- if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
- else
- $echo "$modename: \`$file' is not a valid libtool archive" 1>&2
- $echo "$help" 1>&2
- exit $EXIT_FAILURE
- fi
-
- library_names=
- old_library=
- relink_command=
- # If there is no directory component, then add one.
- case $file in
- */* | *\\*) . $file ;;
- *) . ./$file ;;
- esac
-
- # Add the libdir to current_libdirs if it is the destination.
- if test "X$destdir" = "X$libdir"; then
- case "$current_libdirs " in
- *" $libdir "*) ;;
- *) current_libdirs="$current_libdirs $libdir" ;;
- esac
- else
- # Note the libdir as a future libdir.
- case "$future_libdirs " in
- *" $libdir "*) ;;
- *) future_libdirs="$future_libdirs $libdir" ;;
- esac
- fi
-
- dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`/
- test "X$dir" = "X$file/" && dir=
- dir="$dir$objdir"
-
- if test -n "$relink_command"; then
- # Determine the prefix the user has applied to our future dir.
- inst_prefix_dir=`$echo "$destdir" | $SED "s%$libdir\$%%"`
-
- # Don't allow the user to place us outside of our expected
- # location b/c this prevents finding dependent libraries that
- # are installed to the same prefix.
- # At present, this check doesn't affect windows .dll's that
- # are installed into $libdir/../bin (currently, that works fine)
- # but it's something to keep an eye on.
- if test "$inst_prefix_dir" = "$destdir"; then
- $echo "$modename: error: cannot install \`$file' to a directory not ending in $libdir" 1>&2
- exit $EXIT_FAILURE
- fi
-
- if test -n "$inst_prefix_dir"; then
- # Stick the inst_prefix_dir data into the link command.
- relink_command=`$echo "$relink_command" | $SP2NL | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%" | $NL2SP`
- else
- relink_command=`$echo "$relink_command" | $SP2NL | $SED "s%@inst_prefix_dir@%%" | $NL2SP`
- fi
-
- $echo "$modename: warning: relinking \`$file'" 1>&2
- $show "$relink_command"
- if $run eval "$relink_command"; then :
- else
- $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2
- exit $EXIT_FAILURE
- fi
- fi
-
- # See the names of the shared library.
- set dummy $library_names
- if test -n "$2"; then
- realname="$2"
- shift
- shift
-
- srcname="$realname"
- test -n "$relink_command" && srcname="$realname"T
-
- # Install the shared library and build the symlinks.
- $show "$install_prog $dir/$srcname $destdir/$realname"
- $run eval "$install_prog $dir/$srcname $destdir/$realname" || exit $?
- if test -n "$stripme" && test -n "$striplib"; then
- $show "$striplib $destdir/$realname"
- $run eval "$striplib $destdir/$realname" || exit $?
- fi
-
- if test "$#" -gt 0; then
- # Delete the old symlinks, and create new ones.
- # Try `ln -sf' first, because the `ln' binary might depend on
- # the symlink we replace! Solaris /bin/ln does not understand -f,
- # so we also need to try rm && ln -s.
- for linkname
- do
- if test "$linkname" != "$realname"; then
- $show "(cd $destdir && { $LN_S -f $realname $linkname || { $rm $linkname && $LN_S $realname $linkname; }; })"
- $run eval "(cd $destdir && { $LN_S -f $realname $linkname || { $rm $linkname && $LN_S $realname $linkname; }; })"
- fi
- done
- fi
-
- # Do each command in the postinstall commands.
- lib="$destdir/$realname"
- cmds=$postinstall_cmds
- save_ifs="$IFS"; IFS='~'
- for cmd in $cmds; do
- IFS="$save_ifs"
- eval cmd=\"$cmd\"
- $show "$cmd"
- $run eval "$cmd" || {
- lt_exit=$?
-
- # Restore the uninstalled library and exit
- if test "$mode" = relink; then
- $run eval '(cd $output_objdir && $rm ${realname}T && $mv ${realname}U $realname)'
- fi
-
- exit $lt_exit
- }
- done
- IFS="$save_ifs"
- fi
-
- # Install the pseudo-library for information purposes.
- name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
- instname="$dir/$name"i
- $show "$install_prog $instname $destdir/$name"
- $run eval "$install_prog $instname $destdir/$name" || exit $?
-
- # Maybe install the static library, too.
- test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library"
- ;;
-
- *.lo)
- # Install (i.e. copy) a libtool object.
-
- # Figure out destination file name, if it wasn't already specified.
- if test -n "$destname"; then
- destfile="$destdir/$destname"
- else
- destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
- destfile="$destdir/$destfile"
- fi
-
- # Deduce the name of the destination old-style object file.
- case $destfile in
- *.lo)
- staticdest=`$echo "X$destfile" | $Xsed -e "$lo2o"`
- ;;
- *.$objext)
- staticdest="$destfile"
- destfile=
- ;;
- *)
- $echo "$modename: cannot copy a libtool object to \`$destfile'" 1>&2
- $echo "$help" 1>&2
- exit $EXIT_FAILURE
- ;;
- esac
-
- # Install the libtool object if requested.
- if test -n "$destfile"; then
- $show "$install_prog $file $destfile"
- $run eval "$install_prog $file $destfile" || exit $?
- fi
-
- # Install the old object if enabled.
- if test "$build_old_libs" = yes; then
- # Deduce the name of the old-style object file.
- staticobj=`$echo "X$file" | $Xsed -e "$lo2o"`
-
- $show "$install_prog $staticobj $staticdest"
- $run eval "$install_prog \$staticobj \$staticdest" || exit $?
- fi
- exit $EXIT_SUCCESS
- ;;
-
- *)
- # Figure out destination file name, if it wasn't already specified.
- if test -n "$destname"; then
- destfile="$destdir/$destname"
- else
- destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
- destfile="$destdir/$destfile"
- fi
-
- # If the file is missing, and there is a .exe on the end, strip it
- # because it is most likely a libtool script we actually want to
- # install
- stripped_ext=""
- case $file in
- *.exe)
- if test ! -f "$file"; then
- file=`$echo $file|${SED} 's,.exe$,,'`
- stripped_ext=".exe"
- fi
- ;;
- esac
-
- # Do a test to see if this is really a libtool program.
- case $host in
- *cygwin*|*mingw*)
- wrapper=`$echo $file | ${SED} -e 's,.exe$,,'`
- ;;
- *)
- wrapper=$file
- ;;
- esac
- if (${SED} -e '4q' $wrapper | grep "^# Generated by .*$PACKAGE")>/dev/null 2>&1; then
- notinst_deplibs=
- relink_command=
-
- # Note that it is not necessary on cygwin/mingw to append a dot to
- # foo even if both foo and FILE.exe exist: automatic-append-.exe
- # behavior happens only for exec(3), not for open(2)! Also, sourcing
- # `FILE.' does not work on cygwin managed mounts.
- #
- # If there is no directory component, then add one.
- case $wrapper in
- */* | *\\*) . ${wrapper} ;;
- *) . ./${wrapper} ;;
- esac
-
- # Check the variables that should have been set.
- if test -z "$notinst_deplibs"; then
- $echo "$modename: invalid libtool wrapper script \`$wrapper'" 1>&2
- exit $EXIT_FAILURE
- fi
-
- finalize=yes
- for lib in $notinst_deplibs; do
- # Check to see that each library is installed.
- libdir=
- if test -f "$lib"; then
- # If there is no directory component, then add one.
- case $lib in
- */* | *\\*) . $lib ;;
- *) . ./$lib ;;
- esac
- fi
- libfile="$libdir/"`$echo "X$lib" | $Xsed -e 's%^.*/%%g'` ### testsuite: skip nested quoting test
- if test -n "$libdir" && test ! -f "$libfile"; then
- $echo "$modename: warning: \`$lib' has not been installed in \`$libdir'" 1>&2
- finalize=no
- fi
- done
-
- relink_command=
- # Note that it is not necessary on cygwin/mingw to append a dot to
- # foo even if both foo and FILE.exe exist: automatic-append-.exe
- # behavior happens only for exec(3), not for open(2)! Also, sourcing
- # `FILE.' does not work on cygwin managed mounts.
- #
- # If there is no directory component, then add one.
- case $wrapper in
- */* | *\\*) . ${wrapper} ;;
- *) . ./${wrapper} ;;
- esac
-
- outputname=
- if test "$fast_install" = no && test -n "$relink_command"; then
- if test "$finalize" = yes && test -z "$run"; then
- tmpdir=`func_mktempdir`
- file=`$echo "X$file$stripped_ext" | $Xsed -e 's%^.*/%%'`
- outputname="$tmpdir/$file"
- # Replace the output file specification.
- relink_command=`$echo "X$relink_command" | $SP2NL | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g' | $NL2SP`
-
- $show "$relink_command"
- if $run eval "$relink_command"; then :
- else
- $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2
- ${rm}r "$tmpdir"
- continue
- fi
- file="$outputname"
- else
- $echo "$modename: warning: cannot relink \`$file'" 1>&2
- fi
- else
- # Install the binary that we compiled earlier.
- file=`$echo "X$file$stripped_ext" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"`
- fi
- fi
-
- # remove .exe since cygwin /usr/bin/install will append another
- # one anyway
- case $install_prog,$host in
- */usr/bin/install*,*cygwin*)
- case $file:$destfile in
- *.exe:*.exe)
- # this is ok
- ;;
- *.exe:*)
- destfile=$destfile.exe
- ;;
- *:*.exe)
- destfile=`$echo $destfile | ${SED} -e 's,.exe$,,'`
- ;;
- esac
- ;;
- esac
- $show "$install_prog$stripme $file $destfile"
- $run eval "$install_prog\$stripme \$file \$destfile" || exit $?
- test -n "$outputname" && ${rm}r "$tmpdir"
- ;;
- esac
- done
-
- for file in $staticlibs; do
- name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
-
- # Set up the ranlib parameters.
- oldlib="$destdir/$name"
-
- $show "$install_prog $file $oldlib"
- $run eval "$install_prog \$file \$oldlib" || exit $?
-
- if test -n "$stripme" && test -n "$old_striplib"; then
- $show "$old_striplib $oldlib"
- $run eval "$old_striplib $oldlib" || exit $?
- fi
-
- # Do each command in the postinstall commands.
- cmds=$old_postinstall_cmds
- save_ifs="$IFS"; IFS='~'
- for cmd in $cmds; do
- IFS="$save_ifs"
- eval cmd=\"$cmd\"
- $show "$cmd"
- $run eval "$cmd" || exit $?
- done
- IFS="$save_ifs"
- done
-
- if test -n "$future_libdirs"; then
- $echo "$modename: warning: remember to run \`$progname --finish$future_libdirs'" 1>&2
- fi
-
- if test -n "$current_libdirs"; then
- # Maybe just do a dry run.
- test -n "$run" && current_libdirs=" -n$current_libdirs"
- exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs'
- else
- exit $EXIT_SUCCESS
- fi
- ;;
-
- # libtool finish mode
- finish)
- modename="$modename: finish"
- libdirs="$nonopt"
- admincmds=
-
- if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
- for dir
- do
- libdirs="$libdirs $dir"
- done
-
- for libdir in $libdirs; do
- if test -n "$finish_cmds"; then
- # Do each command in the finish commands.
- cmds=$finish_cmds
- save_ifs="$IFS"; IFS='~'
- for cmd in $cmds; do
- IFS="$save_ifs"
- eval cmd=\"$cmd\"
- $show "$cmd"
- $run eval "$cmd" || admincmds="$admincmds
- $cmd"
- done
- IFS="$save_ifs"
- fi
- if test -n "$finish_eval"; then
- # Do the single finish_eval.
- eval cmds=\"$finish_eval\"
- $run eval "$cmds" || admincmds="$admincmds
- $cmds"
- fi
- done
- fi
-
- # Exit here if they wanted silent mode.
- test "$show" = : && exit $EXIT_SUCCESS
-
- $echo "X----------------------------------------------------------------------" | $Xsed
- $echo "Libraries have been installed in:"
- for libdir in $libdirs; do
- $echo " $libdir"
- done
- $echo
- $echo "If you ever happen to want to link against installed libraries"
- $echo "in a given directory, LIBDIR, you must either use libtool, and"
- $echo "specify the full pathname of the library, or use the \`-LLIBDIR'"
- $echo "flag during linking and do at least one of the following:"
- if test -n "$shlibpath_var"; then
- $echo " - add LIBDIR to the \`$shlibpath_var' environment variable"
- $echo " during execution"
- fi
- if test -n "$runpath_var"; then
- $echo " - add LIBDIR to the \`$runpath_var' environment variable"
- $echo " during linking"
- fi
- if test -n "$hardcode_libdir_flag_spec"; then
- libdir=LIBDIR
- eval flag=\"$hardcode_libdir_flag_spec\"
-
- $echo " - use the \`$flag' linker flag"
- fi
- if test -n "$admincmds"; then
- $echo " - have your system administrator run these commands:$admincmds"
- fi
- if test -f /etc/ld.so.conf; then
- $echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'"
- fi
- $echo
- $echo "See any operating system documentation about shared libraries for"
- $echo "more information, such as the ld(1) and ld.so(8) manual pages."
- $echo "X----------------------------------------------------------------------" | $Xsed
- exit $EXIT_SUCCESS
- ;;
-
- # libtool execute mode
- execute)
- modename="$modename: execute"
-
- # The first argument is the command name.
- cmd="$nonopt"
- if test -z "$cmd"; then
- $echo "$modename: you must specify a COMMAND" 1>&2
- $echo "$help"
- exit $EXIT_FAILURE
- fi
-
- # Handle -dlopen flags immediately.
- for file in $execute_dlfiles; do
- if test ! -f "$file"; then
- $echo "$modename: \`$file' is not a file" 1>&2
- $echo "$help" 1>&2
- exit $EXIT_FAILURE
- fi
-
- dir=
- case $file in
- *.la)
- # Check to see that this really is a libtool archive.
- if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
- else
- $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2
- $echo "$help" 1>&2
- exit $EXIT_FAILURE
- fi
-
- # Read the libtool library.
- dlname=
- library_names=
-
- # If there is no directory component, then add one.
- case $file in
- */* | *\\*) . $file ;;
- *) . ./$file ;;
- esac
-
- # Skip this library if it cannot be dlopened.
- if test -z "$dlname"; then
- # Warn if it was a shared library.
- test -n "$library_names" && $echo "$modename: warning: \`$file' was not linked with \`-export-dynamic'"
- continue
- fi
-
- dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
- test "X$dir" = "X$file" && dir=.
-
- if test -f "$dir/$objdir/$dlname"; then
- dir="$dir/$objdir"
- else
- if test ! -f "$dir/$dlname"; then
- $echo "$modename: cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" 1>&2
- exit $EXIT_FAILURE
- fi
- fi
- ;;
-
- *.lo)
- # Just add the directory containing the .lo file.
- dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
- test "X$dir" = "X$file" && dir=.
- ;;
-
- *)
- $echo "$modename: warning \`-dlopen' is ignored for non-libtool libraries and objects" 1>&2
- continue
- ;;
- esac
-
- # Get the absolute pathname.
- absdir=`cd "$dir" && pwd`
- test -n "$absdir" && dir="$absdir"
-
- # Now add the directory to shlibpath_var.
- if eval "test -z \"\$$shlibpath_var\""; then
- eval "$shlibpath_var=\"\$dir\""
- else
- eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\""
- fi
- done
-
- # This variable tells wrapper scripts just to set shlibpath_var
- # rather than running their programs.
- libtool_execute_magic="$magic"
-
- # Check if any of the arguments is a wrapper script.
- args=
- for file
- do
- case $file in
- -*) ;;
- *)
- # Do a test to see if this is really a libtool program.
- if (${SED} -e '4q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
- # If there is no directory component, then add one.
- case $file in
- */* | *\\*) . $file ;;
- *) . ./$file ;;
- esac
-
- # Transform arg to wrapped name.
- file="$progdir/$program"
- fi
- ;;
- esac
- # Quote arguments (to preserve shell metacharacters).
- file=`$echo "X$file" | $Xsed -e "$sed_quote_subst"`
- args="$args \"$file\""
- done
-
- if test -z "$run"; then
- if test -n "$shlibpath_var"; then
- # Export the shlibpath_var.
- eval "export $shlibpath_var"
- fi
-
- # Restore saved environment variables
- for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
- do
- eval "if test \"\${save_$lt_var+set}\" = set; then
- $lt_var=\$save_$lt_var; export $lt_var
- fi"
- done
-
- # Now prepare to actually exec the command.
- exec_cmd="\$cmd$args"
- else
- # Display what would be done.
- if test -n "$shlibpath_var"; then
- eval "\$echo \"\$shlibpath_var=\$$shlibpath_var\""
- $echo "export $shlibpath_var"
- fi
- $echo "$cmd$args"
- exit $EXIT_SUCCESS
- fi
- ;;
-
- # libtool clean and uninstall mode
- clean | uninstall)
- modename="$modename: $mode"
- rm="$nonopt"
- files=
- rmforce=
- exit_status=0
-
- # This variable tells wrapper scripts just to set variables rather
- # than running their programs.
- libtool_install_magic="$magic"
-
- for arg
- do
- case $arg in
- -f) rm="$rm $arg"; rmforce=yes ;;
- -*) rm="$rm $arg" ;;
- *) files="$files $arg" ;;
- esac
- done
-
- if test -z "$rm"; then
- $echo "$modename: you must specify an RM program" 1>&2
- $echo "$help" 1>&2
- exit $EXIT_FAILURE
- fi
-
- rmdirs=
-
- origobjdir="$objdir"
- for file in $files; do
- dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
- if test "X$dir" = "X$file"; then
- dir=.
- objdir="$origobjdir"
- else
- objdir="$dir/$origobjdir"
- fi
- name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
- test "$mode" = uninstall && objdir="$dir"
-
- # Remember objdir for removal later, being careful to avoid duplicates
- if test "$mode" = clean; then
- case " $rmdirs " in
- *" $objdir "*) ;;
- *) rmdirs="$rmdirs $objdir" ;;
- esac
- fi
-
- # Don't error if the file doesn't exist and rm -f was used.
- if (test -L "$file") >/dev/null 2>&1 \
- || (test -h "$file") >/dev/null 2>&1 \
- || test -f "$file"; then
- :
- elif test -d "$file"; then
- exit_status=1
- continue
- elif test "$rmforce" = yes; then
- continue
- fi
-
- rmfiles="$file"
-
- case $name in
- *.la)
- # Possibly a libtool archive, so verify it.
- if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
- . $dir/$name
-
- # Delete the libtool libraries and symlinks.
- for n in $library_names; do
- rmfiles="$rmfiles $objdir/$n"
- done
- test -n "$old_library" && rmfiles="$rmfiles $objdir/$old_library"
-
- case "$mode" in
- clean)
- case " $library_names " in
- # " " in the beginning catches empty $dlname
- *" $dlname "*) ;;
- *) rmfiles="$rmfiles $objdir/$dlname" ;;
- esac
- test -n "$libdir" && rmfiles="$rmfiles $objdir/$name $objdir/${name}i"
- ;;
- uninstall)
- if test -n "$library_names"; then
- # Do each command in the postuninstall commands.
- cmds=$postuninstall_cmds
- save_ifs="$IFS"; IFS='~'
- for cmd in $cmds; do
- IFS="$save_ifs"
- eval cmd=\"$cmd\"
- $show "$cmd"
- $run eval "$cmd"
- if test "$?" -ne 0 && test "$rmforce" != yes; then
- exit_status=1
- fi
- done
- IFS="$save_ifs"
- fi
-
- if test -n "$old_library"; then
- # Do each command in the old_postuninstall commands.
- cmds=$old_postuninstall_cmds
- save_ifs="$IFS"; IFS='~'
- for cmd in $cmds; do
- IFS="$save_ifs"
- eval cmd=\"$cmd\"
- $show "$cmd"
- $run eval "$cmd"
- if test "$?" -ne 0 && test "$rmforce" != yes; then
- exit_status=1
- fi
- done
- IFS="$save_ifs"
- fi
- # FIXME: should reinstall the best remaining shared library.
- ;;
- esac
- fi
- ;;
-
- *.lo)
- # Possibly a libtool object, so verify it.
- if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
-
- # Read the .lo file
- . $dir/$name
-
- # Add PIC object to the list of files to remove.
- if test -n "$pic_object" \
- && test "$pic_object" != none; then
- rmfiles="$rmfiles $dir/$pic_object"
- fi
-
- # Add non-PIC object to the list of files to remove.
- if test -n "$non_pic_object" \
- && test "$non_pic_object" != none; then
- rmfiles="$rmfiles $dir/$non_pic_object"
- fi
- fi
- ;;
-
- *)
- if test "$mode" = clean ; then
- noexename=$name
- case $file in
- *.exe)
- file=`$echo $file|${SED} 's,.exe$,,'`
- noexename=`$echo $name|${SED} 's,.exe$,,'`
- # $file with .exe has already been added to rmfiles,
- # add $file without .exe
- rmfiles="$rmfiles $file"
- ;;
- esac
- # Do a test to see if this is a libtool program.
- if (${SED} -e '4q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
- relink_command=
- . $dir/$noexename
-
- # note $name still contains .exe if it was in $file originally
- # as does the version of $file that was added into $rmfiles
- rmfiles="$rmfiles $objdir/$name $objdir/${name}S.${objext}"
- if test "$fast_install" = yes && test -n "$relink_command"; then
- rmfiles="$rmfiles $objdir/lt-$name"
- fi
- if test "X$noexename" != "X$name" ; then
- rmfiles="$rmfiles $objdir/lt-${noexename}.c"
- fi
- fi
- fi
- ;;
- esac
- $show "$rm $rmfiles"
- $run $rm $rmfiles || exit_status=1
- done
- objdir="$origobjdir"
-
- # Try to remove the ${objdir}s in the directories where we deleted files
- for dir in $rmdirs; do
- if test -d "$dir"; then
- $show "rmdir $dir"
- $run rmdir $dir >/dev/null 2>&1
- fi
- done
-
- exit $exit_status
- ;;
-
- "")
- $echo "$modename: you must specify a MODE" 1>&2
- $echo "$generic_help" 1>&2
- exit $EXIT_FAILURE
- ;;
- esac
-
- if test -z "$exec_cmd"; then
- $echo "$modename: invalid operation mode \`$mode'" 1>&2
- $echo "$generic_help" 1>&2
- exit $EXIT_FAILURE
- fi
-fi # test -z "$show_help"
-
-if test -n "$exec_cmd"; then
- eval exec $exec_cmd
- exit $EXIT_FAILURE
-fi
-
-# We need to display help for each of the modes.
-case $mode in
-"") $echo \
-"Usage: $modename [OPTION]... [MODE-ARG]...
-
-Provide generalized library-building support services.
-
- --config show all configuration variables
- --debug enable verbose shell tracing
--n, --dry-run display commands without modifying any files
- --features display basic configuration information and exit
- --finish same as \`--mode=finish'
- --help display this help message and exit
- --mode=MODE use operation mode MODE [default=inferred from MODE-ARGS]
- --quiet same as \`--silent'
- --silent don't print informational messages
- --tag=TAG use configuration variables from tag TAG
- --version print version information
-
-MODE must be one of the following:
-
- clean remove files from the build directory
- compile compile a source file into a libtool object
- execute automatically set library path, then run a program
- finish complete the installation of libtool libraries
- install install libraries or executables
- link create a library or an executable
- uninstall remove libraries from an installed directory
-
-MODE-ARGS vary depending on the MODE. Try \`$modename --help --mode=MODE' for
-a more detailed description of MODE.
-
-Report bugs to <bug-libtool@gnu.org>."
- exit $EXIT_SUCCESS
- ;;
-
-clean)
- $echo \
-"Usage: $modename [OPTION]... --mode=clean RM [RM-OPTION]... FILE...
-
-Remove files from the build directory.
-
-RM is the name of the program to use to delete files associated with each FILE
-(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed
-to RM.
-
-If FILE is a libtool library, object or program, all the files associated
-with it are deleted. Otherwise, only FILE itself is deleted using RM."
- ;;
-
-compile)
- $echo \
-"Usage: $modename [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE
-
-Compile a source file into a libtool library object.
-
-This mode accepts the following additional options:
-
- -o OUTPUT-FILE set the output file name to OUTPUT-FILE
- -prefer-pic try to building PIC objects only
- -prefer-non-pic try to building non-PIC objects only
- -static always build a \`.o' file suitable for static linking
-
-COMPILE-COMMAND is a command to be used in creating a \`standard' object file
-from the given SOURCEFILE.
-
-The output file name is determined by removing the directory component from
-SOURCEFILE, then substituting the C source code suffix \`.c' with the
-library object suffix, \`.lo'."
- ;;
-
-execute)
- $echo \
-"Usage: $modename [OPTION]... --mode=execute COMMAND [ARGS]...
-
-Automatically set library path, then run a program.
-
-This mode accepts the following additional options:
-
- -dlopen FILE add the directory containing FILE to the library path
-
-This mode sets the library path environment variable according to \`-dlopen'
-flags.
-
-If any of the ARGS are libtool executable wrappers, then they are translated
-into their corresponding uninstalled binary, and any of their required library
-directories are added to the library path.
-
-Then, COMMAND is executed, with ARGS as arguments."
- ;;
-
-finish)
- $echo \
-"Usage: $modename [OPTION]... --mode=finish [LIBDIR]...
-
-Complete the installation of libtool libraries.
-
-Each LIBDIR is a directory that contains libtool libraries.
-
-The commands that this mode executes may require superuser privileges. Use
-the \`--dry-run' option if you just want to see what would be executed."
- ;;
-
-install)
- $echo \
-"Usage: $modename [OPTION]... --mode=install INSTALL-COMMAND...
-
-Install executables or libraries.
-
-INSTALL-COMMAND is the installation command. The first component should be
-either the \`install' or \`cp' program.
-
-The rest of the components are interpreted as arguments to that command (only
-BSD-compatible install options are recognized)."
- ;;
-
-link)
- $echo \
-"Usage: $modename [OPTION]... --mode=link LINK-COMMAND...
-
-Link object files or libraries together to form another library, or to
-create an executable program.
-
-LINK-COMMAND is a command using the C compiler that you would use to create
-a program from several object files.
-
-The following components of LINK-COMMAND are treated specially:
-
- -all-static do not do any dynamic linking at all
- -avoid-version do not add a version suffix if possible
- -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime
- -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols
- -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3)
- -export-symbols SYMFILE
- try to export only the symbols listed in SYMFILE
- -export-symbols-regex REGEX
- try to export only the symbols matching REGEX
- -LLIBDIR search LIBDIR for required installed libraries
- -lNAME OUTPUT-FILE requires the installed library libNAME
- -module build a library that can dlopened
- -no-fast-install disable the fast-install mode
- -no-install link a not-installable executable
- -no-undefined declare that a library does not refer to external symbols
- -o OUTPUT-FILE create OUTPUT-FILE from the specified objects
- -objectlist FILE Use a list of object files found in FILE to specify objects
- -precious-files-regex REGEX
- don't remove output files matching REGEX
- -release RELEASE specify package release information
- -rpath LIBDIR the created library will eventually be installed in LIBDIR
- -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries
- -static do not do any dynamic linking of uninstalled libtool libraries
- -static-libtool-libs
- do not do any dynamic linking of libtool libraries
- -version-info CURRENT[:REVISION[:AGE]]
- specify library version info [each variable defaults to 0]
-
-All other options (arguments beginning with \`-') are ignored.
-
-Every other argument is treated as a filename. Files ending in \`.la' are
-treated as uninstalled libtool libraries, other files are standard or library
-object files.
-
-If the OUTPUT-FILE ends in \`.la', then a libtool library is created,
-only library objects (\`.lo' files) may be specified, and \`-rpath' is
-required, except when creating a convenience library.
-
-If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created
-using \`ar' and \`ranlib', or on Windows using \`lib'.
-
-If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file
-is created, otherwise an executable program is created."
- ;;
-
-uninstall)
- $echo \
-"Usage: $modename [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE...
-
-Remove libraries from an installation directory.
-
-RM is the name of the program to use to delete files associated with each FILE
-(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed
-to RM.
-
-If FILE is a libtool library, all the files associated with it are deleted.
-Otherwise, only FILE itself is deleted using RM."
- ;;
-
-*)
- $echo "$modename: invalid operation mode \`$mode'" 1>&2
- $echo "$help" 1>&2
- exit $EXIT_FAILURE
- ;;
-esac
-
-$echo
-$echo "Try \`$modename --help' for more information about other modes."
-
-exit $?
-
-# The TAGs below are defined such that we never get into a situation
-# in which we disable both kinds of libraries. Given conflicting
-# choices, we go for a static library, that is the most portable,
-# since we can't tell whether shared libraries were disabled because
-# the user asked for that or because the platform doesn't support
-# them. This is particularly important on AIX, because we don't
-# support having both static and shared libraries enabled at the same
-# time on that platform, so we default to a shared-only configuration.
-# If a disable-shared tag is given, we'll fallback to a static-only
-# configuration. But we'll never go from static-only to shared-only.
-
-# ### BEGIN LIBTOOL TAG CONFIG: disable-shared
-disable_libs=shared
-# ### END LIBTOOL TAG CONFIG: disable-shared
-
-# ### BEGIN LIBTOOL TAG CONFIG: disable-static
-disable_libs=static
-# ### END LIBTOOL TAG CONFIG: disable-static
-
-# Local Variables:
-# mode:shell-script
-# sh-indentation:2
-# End:
diff --git a/crawl-ref/source/util/pcre/makevp.bat b/crawl-ref/source/util/pcre/makevp.bat
deleted file mode 100644
index 93ff539277..0000000000
--- a/crawl-ref/source/util/pcre/makevp.bat
+++ /dev/null
@@ -1,44 +0,0 @@
-@echo off
-
-:: AH 20-12-06 modified for new PCRE-7.0 and VP/BCC
-:: PH 19-03-07 renamed !compile.txt and !linklib.txt as makevp-compile.txt and
-:: makevp-linklib.txt
-:: PH 26-03-07 re-renamed !compile.txt and !linklib.txt as makevp-c.txt and
-:: makevp-l.txt
-:: PH 29-03-07 hopefully the final rename to makevp_c and makevp_l
-
-REM This file was contributed by Alexander Tokarev for building PCRE for use
-REM with Virtual Pascal. It has not been tested with the latest PCRE release.
-
-REM CHANGE THIS FOR YOUR BORLAND C++ COMPILER PATH
-
-SET BORLAND=F:\bcc
-SET PATH=%PATH%;%BORLAND%\bin;f:\tasm\bin
-SET PCRE_VER=70
-
-:: sh configure
-
-bcc32 -DDFTABLES -DSTATIC -I%BORLAND%\include -L%BORLAND%\lib dftables.c
-:: bcc32 -DDFTABLES -DSTATIC -DVPCOMPAT -I%BORLAND%\include -L%BORLAND%\lib dftables.c
-IF ERRORLEVEL 1 EXIT
-
-:: dftables > chartables.c
-dftables pcre_chartables.c
-
-REM compile and link the PCRE library into lib: option -B for ASM compile works too
-bcc32 -a4 -c -RT- -y- -v- -u- -R- -Q- -X -d -fp -ff -P- -O2 -Oc -Ov -3 -w-8004 -w-8064 -w-8065 -w-8012 -DSTATIC -DVPCOMPAT -UDFTABLES -I%BORLAND%\include @makevp_c.txt
-:: bcc32 -c -RT- -y- -v- -u- -P- -O2 -5 -DSTATIC -DVPCOMPAT -UDFTABLES -I%BORLAND%\include get.c maketables.c pcre.c study.c
-IF ERRORLEVEL 1 EXIT
-
-tlib %BORLAND%\lib\cw32.lib *calloc *del *strncmp *memcpy *memmove *memset *memcmp *strlen
-:: tlib %BORLAND%\lib\cw32.lib *calloc *del *strncmp *memcpy *memmove *memset
-IF ERRORLEVEL 1 EXIT
-tlib pcre%PCRE_VER%.lib @makevp_l.txt +calloc.obj +del.obj +strncmp.obj +memcpy.obj +memmove.obj +memset.obj +memcmp.obj +strlen.obj
-:: tlib pcre.lib +get.obj +maketables.obj +pcre.obj +study.obj +calloc.obj +del.obj +strncmp.obj +memcpy.obj +memmove.obj +memset.obj
-IF ERRORLEVEL 1 EXIT
-
-del *.obj *.tds *.bak >nul 2>nul
-
-echo ---
-echo Now the library should be complete. Please check all messages above.
-echo Don't care for warnings, it's OK.
diff --git a/crawl-ref/source/util/pcre/makevp_c.txt b/crawl-ref/source/util/pcre/makevp_c.txt
deleted file mode 100644
index 6048517521..0000000000
--- a/crawl-ref/source/util/pcre/makevp_c.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-pcre_chartables.c
-pcre_compile.c
-pcre_config.c
-pcre_dfa_exec.c
-pcre_exec.c
-pcre_fullinfo.c
-pcre_get.c
-pcre_globals.c
-pcre_info.c
-pcre_maketables.c
-pcre_newline.c
-pcre_ord2utf8.c
-pcre_refcount.c
-pcre_study.c
-pcre_tables.c
-pcre_try_flipped.c
-pcre_ucp_searchfuncs.c
-pcre_valid_utf8.c
-pcre_version.c
-pcre_xclass.c
diff --git a/crawl-ref/source/util/pcre/makevp_l.txt b/crawl-ref/source/util/pcre/makevp_l.txt
deleted file mode 100644
index cd02aa5236..0000000000
--- a/crawl-ref/source/util/pcre/makevp_l.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-+pcre_chartables.obj &
-+pcre_compile.obj &
-+pcre_config.obj &
-+pcre_dfa_exec.obj &
-+pcre_exec.obj &
-+pcre_fullinfo.obj &
-+pcre_get.obj &
-+pcre_globals.obj &
-+pcre_info.obj &
-+pcre_maketables.obj &
-+pcre_newline.obj &
-+pcre_ord2utf8.obj &
-+pcre_refcount.obj &
-+pcre_study.obj &
-+pcre_tables.obj &
-+pcre_try_flipped.obj &
-+pcre_ucp_searchfuncs.obj &
-+pcre_valid_utf8.obj &
-+pcre_version.obj &
-+pcre_xclass.obj
diff --git a/crawl-ref/source/util/pcre/missing b/crawl-ref/source/util/pcre/missing
deleted file mode 100644
index 1c8ff7049d..0000000000
--- a/crawl-ref/source/util/pcre/missing
+++ /dev/null
@@ -1,367 +0,0 @@
-#! /bin/sh
-# Common stub for a few missing GNU programs while installing.
-
-scriptversion=2006-05-10.23
-
-# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006
-# Free Software Foundation, Inc.
-# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
-
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2, or (at your option)
-# any later version.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-# 02110-1301, USA.
-
-# As a special exception to the GNU General Public License, if you
-# distribute this file as part of a program that contains a
-# configuration script generated by Autoconf, you may include it under
-# the same distribution terms that you use for the rest of that program.
-
-if test $# -eq 0; then
- echo 1>&2 "Try \`$0 --help' for more information"
- exit 1
-fi
-
-run=:
-sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p'
-sed_minuso='s/.* -o \([^ ]*\).*/\1/p'
-
-# In the cases where this matters, `missing' is being run in the
-# srcdir already.
-if test -f configure.ac; then
- configure_ac=configure.ac
-else
- configure_ac=configure.in
-fi
-
-msg="missing on your system"
-
-case $1 in
---run)
- # Try to run requested program, and just exit if it succeeds.
- run=
- shift
- "$@" && exit 0
- # Exit code 63 means version mismatch. This often happens
- # when the user try to use an ancient version of a tool on
- # a file that requires a minimum version. In this case we
- # we should proceed has if the program had been absent, or
- # if --run hadn't been passed.
- if test $? = 63; then
- run=:
- msg="probably too old"
- fi
- ;;
-
- -h|--h|--he|--hel|--help)
- echo "\
-$0 [OPTION]... PROGRAM [ARGUMENT]...
-
-Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
-error status if there is no known handling for PROGRAM.
-
-Options:
- -h, --help display this help and exit
- -v, --version output version information and exit
- --run try to run the given command, and emulate it if it fails
-
-Supported PROGRAM values:
- aclocal touch file \`aclocal.m4'
- autoconf touch file \`configure'
- autoheader touch file \`config.h.in'
- autom4te touch the output file, or create a stub one
- automake touch all \`Makefile.in' files
- bison create \`y.tab.[ch]', if possible, from existing .[ch]
- flex create \`lex.yy.c', if possible, from existing .c
- help2man touch the output file
- lex create \`lex.yy.c', if possible, from existing .c
- makeinfo touch the output file
- tar try tar, gnutar, gtar, then tar without non-portable flags
- yacc create \`y.tab.[ch]', if possible, from existing .[ch]
-
-Send bug reports to <bug-automake@gnu.org>."
- exit $?
- ;;
-
- -v|--v|--ve|--ver|--vers|--versi|--versio|--version)
- echo "missing $scriptversion (GNU Automake)"
- exit $?
- ;;
-
- -*)
- echo 1>&2 "$0: Unknown \`$1' option"
- echo 1>&2 "Try \`$0 --help' for more information"
- exit 1
- ;;
-
-esac
-
-# Now exit if we have it, but it failed. Also exit now if we
-# don't have it and --version was passed (most likely to detect
-# the program).
-case $1 in
- lex|yacc)
- # Not GNU programs, they don't have --version.
- ;;
-
- tar)
- if test -n "$run"; then
- echo 1>&2 "ERROR: \`tar' requires --run"
- exit 1
- elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
- exit 1
- fi
- ;;
-
- *)
- if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
- # We have it, but it failed.
- exit 1
- elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
- # Could not run --version or --help. This is probably someone
- # running `$TOOL --version' or `$TOOL --help' to check whether
- # $TOOL exists and not knowing $TOOL uses missing.
- exit 1
- fi
- ;;
-esac
-
-# If it does not exist, or fails to run (possibly an outdated version),
-# try to emulate it.
-case $1 in
- aclocal*)
- echo 1>&2 "\
-WARNING: \`$1' is $msg. You should only need it if
- you modified \`acinclude.m4' or \`${configure_ac}'. You might want
- to install the \`Automake' and \`Perl' packages. Grab them from
- any GNU archive site."
- touch aclocal.m4
- ;;
-
- autoconf)
- echo 1>&2 "\
-WARNING: \`$1' is $msg. You should only need it if
- you modified \`${configure_ac}'. You might want to install the
- \`Autoconf' and \`GNU m4' packages. Grab them from any GNU
- archive site."
- touch configure
- ;;
-
- autoheader)
- echo 1>&2 "\
-WARNING: \`$1' is $msg. You should only need it if
- you modified \`acconfig.h' or \`${configure_ac}'. You might want
- to install the \`Autoconf' and \`GNU m4' packages. Grab them
- from any GNU archive site."
- files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}`
- test -z "$files" && files="config.h"
- touch_files=
- for f in $files; do
- case $f in
- *:*) touch_files="$touch_files "`echo "$f" |
- sed -e 's/^[^:]*://' -e 's/:.*//'`;;
- *) touch_files="$touch_files $f.in";;
- esac
- done
- touch $touch_files
- ;;
-
- automake*)
- echo 1>&2 "\
-WARNING: \`$1' is $msg. You should only need it if
- you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'.
- You might want to install the \`Automake' and \`Perl' packages.
- Grab them from any GNU archive site."
- find . -type f -name Makefile.am -print |
- sed 's/\.am$/.in/' |
- while read f; do touch "$f"; done
- ;;
-
- autom4te)
- echo 1>&2 "\
-WARNING: \`$1' is needed, but is $msg.
- You might have modified some files without having the
- proper tools for further handling them.
- You can get \`$1' as part of \`Autoconf' from any GNU
- archive site."
-
- file=`echo "$*" | sed -n "$sed_output"`
- test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
- if test -f "$file"; then
- touch $file
- else
- test -z "$file" || exec >$file
- echo "#! /bin/sh"
- echo "# Created by GNU Automake missing as a replacement of"
- echo "# $ $@"
- echo "exit 0"
- chmod +x $file
- exit 1
- fi
- ;;
-
- bison|yacc)
- echo 1>&2 "\
-WARNING: \`$1' $msg. You should only need it if
- you modified a \`.y' file. You may need the \`Bison' package
- in order for those modifications to take effect. You can get
- \`Bison' from any GNU archive site."
- rm -f y.tab.c y.tab.h
- if test $# -ne 1; then
- eval LASTARG="\${$#}"
- case $LASTARG in
- *.y)
- SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
- if test -f "$SRCFILE"; then
- cp "$SRCFILE" y.tab.c
- fi
- SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
- if test -f "$SRCFILE"; then
- cp "$SRCFILE" y.tab.h
- fi
- ;;
- esac
- fi
- if test ! -f y.tab.h; then
- echo >y.tab.h
- fi
- if test ! -f y.tab.c; then
- echo 'main() { return 0; }' >y.tab.c
- fi
- ;;
-
- lex|flex)
- echo 1>&2 "\
-WARNING: \`$1' is $msg. You should only need it if
- you modified a \`.l' file. You may need the \`Flex' package
- in order for those modifications to take effect. You can get
- \`Flex' from any GNU archive site."
- rm -f lex.yy.c
- if test $# -ne 1; then
- eval LASTARG="\${$#}"
- case $LASTARG in
- *.l)
- SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
- if test -f "$SRCFILE"; then
- cp "$SRCFILE" lex.yy.c
- fi
- ;;
- esac
- fi
- if test ! -f lex.yy.c; then
- echo 'main() { return 0; }' >lex.yy.c
- fi
- ;;
-
- help2man)
- echo 1>&2 "\
-WARNING: \`$1' is $msg. You should only need it if
- you modified a dependency of a manual page. You may need the
- \`Help2man' package in order for those modifications to take
- effect. You can get \`Help2man' from any GNU archive site."
-
- file=`echo "$*" | sed -n "$sed_output"`
- test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
- if test -f "$file"; then
- touch $file
- else
- test -z "$file" || exec >$file
- echo ".ab help2man is required to generate this page"
- exit 1
- fi
- ;;
-
- makeinfo)
- echo 1>&2 "\
-WARNING: \`$1' is $msg. You should only need it if
- you modified a \`.texi' or \`.texinfo' file, or any other file
- indirectly affecting the aspect of the manual. The spurious
- call might also be the consequence of using a buggy \`make' (AIX,
- DU, IRIX). You might want to install the \`Texinfo' package or
- the \`GNU make' package. Grab either from any GNU archive site."
- # The file to touch is that specified with -o ...
- file=`echo "$*" | sed -n "$sed_output"`
- test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
- if test -z "$file"; then
- # ... or it is the one specified with @setfilename ...
- infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
- file=`sed -n '
- /^@setfilename/{
- s/.* \([^ ]*\) *$/\1/
- p
- q
- }' $infile`
- # ... or it is derived from the source name (dir/f.texi becomes f.info)
- test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info
- fi
- # If the file does not exist, the user really needs makeinfo;
- # let's fail without touching anything.
- test -f $file || exit 1
- touch $file
- ;;
-
- tar)
- shift
-
- # We have already tried tar in the generic part.
- # Look for gnutar/gtar before invocation to avoid ugly error
- # messages.
- if (gnutar --version > /dev/null 2>&1); then
- gnutar "$@" && exit 0
- fi
- if (gtar --version > /dev/null 2>&1); then
- gtar "$@" && exit 0
- fi
- firstarg="$1"
- if shift; then
- case $firstarg in
- *o*)
- firstarg=`echo "$firstarg" | sed s/o//`
- tar "$firstarg" "$@" && exit 0
- ;;
- esac
- case $firstarg in
- *h*)
- firstarg=`echo "$firstarg" | sed s/h//`
- tar "$firstarg" "$@" && exit 0
- ;;
- esac
- fi
-
- echo 1>&2 "\
-WARNING: I can't seem to be able to run \`tar' with the given arguments.
- You may want to install GNU tar or Free paxutils, or check the
- command line arguments."
- exit 1
- ;;
-
- *)
- echo 1>&2 "\
-WARNING: \`$1' is needed, and is $msg.
- You might have modified some files without having the
- proper tools for further handling them. Check the \`README' file,
- it often tells you about the needed prerequisites for installing
- this package. You may also peek at any GNU archive site, in case
- some other package would contain this missing \`$1' program."
- exit 1
- ;;
-esac
-
-exit 0
-
-# Local variables:
-# eval: (add-hook 'write-file-hooks 'time-stamp)
-# time-stamp-start: "scriptversion="
-# time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-end: "$"
-# End:
diff --git a/crawl-ref/source/util/pcre/pcre-config.in b/crawl-ref/source/util/pcre/pcre-config.in
deleted file mode 100644
index 3b52101b9b..0000000000
--- a/crawl-ref/source/util/pcre/pcre-config.in
+++ /dev/null
@@ -1,69 +0,0 @@
-#!/bin/sh
-
-prefix=@prefix@
-exec_prefix=@exec_prefix@
-exec_prefix_set=no
-
-usage="\
-Usage: pcre-config [--prefix] [--exec-prefix] [--version] [--libs] [--libs-posix] [--cflags] [--cflags-posix]"
-
-if test $# -eq 0; then
- echo "${usage}" 1>&2
- exit 1
-fi
-
-libR=
-case `uname -s` in
- *SunOS*)
- libR=" -R@libdir@"
- ;;
- *BSD*)
- libR=" -Wl,-R@libdir@"
- ;;
-esac
-
-while test $# -gt 0; do
- case "$1" in
- -*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
- *) optarg= ;;
- esac
-
- case $1 in
- --prefix=*)
- prefix=$optarg
- if test $exec_prefix_set = no ; then
- exec_prefix=$optarg
- fi
- ;;
- --prefix)
- echo $prefix
- ;;
- --exec-prefix=*)
- exec_prefix=$optarg
- exec_prefix_set=yes
- ;;
- --exec-prefix)
- echo $exec_prefix
- ;;
- --version)
- echo @PACKAGE_VERSION@
- ;;
- --cflags | --cflags-posix)
- if test @includedir@ != /usr/include ; then
- includes=-I@includedir@
- fi
- echo $includes
- ;;
- --libs-posix)
- echo -L@libdir@$libR -lpcreposix -lpcre
- ;;
- --libs)
- echo -L@libdir@$libR -lpcre
- ;;
- *)
- echo "${usage}" 1>&2
- exit 1
- ;;
- esac
- shift
-done
diff --git a/crawl-ref/source/util/pcre/pcre.h b/crawl-ref/source/util/pcre/pcre.h
deleted file mode 100644
index 6f6a3328e5..0000000000
--- a/crawl-ref/source/util/pcre/pcre.h
+++ /dev/null
@@ -1,304 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* This is the public header file for the PCRE library, to be #included by
-applications that call the PCRE functions.
-
- Copyright (c) 1997-2008 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-#ifndef _PCRE_H
-#define _PCRE_H
-
-/* The current PCRE version information. */
-
-#define PCRE_MAJOR 7
-#define PCRE_MINOR 7
-#define PCRE_PRERELEASE
-#define PCRE_DATE 2008-05-07
-
-/* When an application links to a PCRE DLL in Windows, the symbols that are
-imported have to be identified as such. When building PCRE, the appropriate
-export setting is defined in pcre_internal.h, which includes this file. So we
-don't change existing definitions of PCRE_EXP_DECL and PCRECPP_EXP_DECL. */
-
-#if defined(_WIN32) && !defined(PCRE_STATIC)
-# ifndef PCRE_EXP_DECL
-# define PCRE_EXP_DECL extern __declspec(dllimport)
-# endif
-# ifdef __cplusplus
-# ifndef PCRECPP_EXP_DECL
-# define PCRECPP_EXP_DECL extern __declspec(dllimport)
-# endif
-# ifndef PCRECPP_EXP_DEFN
-# define PCRECPP_EXP_DEFN __declspec(dllimport)
-# endif
-# endif
-#endif
-
-/* By default, we use the standard "extern" declarations. */
-
-#ifndef PCRE_EXP_DECL
-# ifdef __cplusplus
-# define PCRE_EXP_DECL extern "C"
-# else
-# define PCRE_EXP_DECL extern
-# endif
-#endif
-
-#ifdef __cplusplus
-# ifndef PCRECPP_EXP_DECL
-# define PCRECPP_EXP_DECL extern
-# endif
-# ifndef PCRECPP_EXP_DEFN
-# define PCRECPP_EXP_DEFN
-# endif
-#endif
-
-/* Have to include stdlib.h in order to ensure that size_t is defined;
-it is needed here for malloc. */
-
-#include <stdlib.h>
-
-/* Allow for C++ users */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Options */
-
-#define PCRE_CASELESS 0x00000001
-#define PCRE_MULTILINE 0x00000002
-#define PCRE_DOTALL 0x00000004
-#define PCRE_EXTENDED 0x00000008
-#define PCRE_ANCHORED 0x00000010
-#define PCRE_DOLLAR_ENDONLY 0x00000020
-#define PCRE_EXTRA 0x00000040
-#define PCRE_NOTBOL 0x00000080
-#define PCRE_NOTEOL 0x00000100
-#define PCRE_UNGREEDY 0x00000200
-#define PCRE_NOTEMPTY 0x00000400
-#define PCRE_UTF8 0x00000800
-#define PCRE_NO_AUTO_CAPTURE 0x00001000
-#define PCRE_NO_UTF8_CHECK 0x00002000
-#define PCRE_AUTO_CALLOUT 0x00004000
-#define PCRE_PARTIAL 0x00008000
-#define PCRE_DFA_SHORTEST 0x00010000
-#define PCRE_DFA_RESTART 0x00020000
-#define PCRE_FIRSTLINE 0x00040000
-#define PCRE_DUPNAMES 0x00080000
-#define PCRE_NEWLINE_CR 0x00100000
-#define PCRE_NEWLINE_LF 0x00200000
-#define PCRE_NEWLINE_CRLF 0x00300000
-#define PCRE_NEWLINE_ANY 0x00400000
-#define PCRE_NEWLINE_ANYCRLF 0x00500000
-#define PCRE_BSR_ANYCRLF 0x00800000
-#define PCRE_BSR_UNICODE 0x01000000
-#define PCRE_JAVASCRIPT_COMPAT 0x02000000
-
-/* Exec-time and get/set-time error codes */
-
-#define PCRE_ERROR_NOMATCH (-1)
-#define PCRE_ERROR_NULL (-2)
-#define PCRE_ERROR_BADOPTION (-3)
-#define PCRE_ERROR_BADMAGIC (-4)
-#define PCRE_ERROR_UNKNOWN_OPCODE (-5)
-#define PCRE_ERROR_UNKNOWN_NODE (-5) /* For backward compatibility */
-#define PCRE_ERROR_NOMEMORY (-6)
-#define PCRE_ERROR_NOSUBSTRING (-7)
-#define PCRE_ERROR_MATCHLIMIT (-8)
-#define PCRE_ERROR_CALLOUT (-9) /* Never used by PCRE itself */
-#define PCRE_ERROR_BADUTF8 (-10)
-#define PCRE_ERROR_BADUTF8_OFFSET (-11)
-#define PCRE_ERROR_PARTIAL (-12)
-#define PCRE_ERROR_BADPARTIAL (-13)
-#define PCRE_ERROR_INTERNAL (-14)
-#define PCRE_ERROR_BADCOUNT (-15)
-#define PCRE_ERROR_DFA_UITEM (-16)
-#define PCRE_ERROR_DFA_UCOND (-17)
-#define PCRE_ERROR_DFA_UMLIMIT (-18)
-#define PCRE_ERROR_DFA_WSSIZE (-19)
-#define PCRE_ERROR_DFA_RECURSE (-20)
-#define PCRE_ERROR_RECURSIONLIMIT (-21)
-#define PCRE_ERROR_NULLWSLIMIT (-22) /* No longer actually used */
-#define PCRE_ERROR_BADNEWLINE (-23)
-
-/* Request types for pcre_fullinfo() */
-
-#define PCRE_INFO_OPTIONS 0
-#define PCRE_INFO_SIZE 1
-#define PCRE_INFO_CAPTURECOUNT 2
-#define PCRE_INFO_BACKREFMAX 3
-#define PCRE_INFO_FIRSTBYTE 4
-#define PCRE_INFO_FIRSTCHAR 4 /* For backwards compatibility */
-#define PCRE_INFO_FIRSTTABLE 5
-#define PCRE_INFO_LASTLITERAL 6
-#define PCRE_INFO_NAMEENTRYSIZE 7
-#define PCRE_INFO_NAMECOUNT 8
-#define PCRE_INFO_NAMETABLE 9
-#define PCRE_INFO_STUDYSIZE 10
-#define PCRE_INFO_DEFAULT_TABLES 11
-#define PCRE_INFO_OKPARTIAL 12
-#define PCRE_INFO_JCHANGED 13
-#define PCRE_INFO_HASCRORLF 14
-
-/* Request types for pcre_config(). Do not re-arrange, in order to remain
-compatible. */
-
-#define PCRE_CONFIG_UTF8 0
-#define PCRE_CONFIG_NEWLINE 1
-#define PCRE_CONFIG_LINK_SIZE 2
-#define PCRE_CONFIG_POSIX_MALLOC_THRESHOLD 3
-#define PCRE_CONFIG_MATCH_LIMIT 4
-#define PCRE_CONFIG_STACKRECURSE 5
-#define PCRE_CONFIG_UNICODE_PROPERTIES 6
-#define PCRE_CONFIG_MATCH_LIMIT_RECURSION 7
-#define PCRE_CONFIG_BSR 8
-
-/* Bit flags for the pcre_extra structure. Do not re-arrange or redefine
-these bits, just add new ones on the end, in order to remain compatible. */
-
-#define PCRE_EXTRA_STUDY_DATA 0x0001
-#define PCRE_EXTRA_MATCH_LIMIT 0x0002
-#define PCRE_EXTRA_CALLOUT_DATA 0x0004
-#define PCRE_EXTRA_TABLES 0x0008
-#define PCRE_EXTRA_MATCH_LIMIT_RECURSION 0x0010
-
-/* Types */
-
-struct real_pcre; /* declaration; the definition is private */
-typedef struct real_pcre pcre;
-
-/* When PCRE is compiled as a C++ library, the subject pointer type can be
-replaced with a custom type. For conventional use, the public interface is a
-const char *. */
-
-#ifndef PCRE_SPTR
-#define PCRE_SPTR const char *
-#endif
-
-/* The structure for passing additional data to pcre_exec(). This is defined in
-such as way as to be extensible. Always add new fields at the end, in order to
-remain compatible. */
-
-typedef struct pcre_extra {
- unsigned long int flags; /* Bits for which fields are set */
- void *study_data; /* Opaque data from pcre_study() */
- unsigned long int match_limit; /* Maximum number of calls to match() */
- void *callout_data; /* Data passed back in callouts */
- const unsigned char *tables; /* Pointer to character tables */
- unsigned long int match_limit_recursion; /* Max recursive calls to match() */
-} pcre_extra;
-
-/* The structure for passing out data via the pcre_callout_function. We use a
-structure so that new fields can be added on the end in future versions,
-without changing the API of the function, thereby allowing old clients to work
-without modification. */
-
-typedef struct pcre_callout_block {
- int version; /* Identifies version of block */
- /* ------------------------ Version 0 ------------------------------- */
- int callout_number; /* Number compiled into pattern */
- int *offset_vector; /* The offset vector */
- PCRE_SPTR subject; /* The subject being matched */
- int subject_length; /* The length of the subject */
- int start_match; /* Offset to start of this match attempt */
- int current_position; /* Where we currently are in the subject */
- int capture_top; /* Max current capture */
- int capture_last; /* Most recently closed capture */
- void *callout_data; /* Data passed in with the call */
- /* ------------------- Added for Version 1 -------------------------- */
- int pattern_position; /* Offset to next item in the pattern */
- int next_item_length; /* Length of next item in the pattern */
- /* ------------------------------------------------------------------ */
-} pcre_callout_block;
-
-/* Indirection for store get and free functions. These can be set to
-alternative malloc/free functions if required. Special ones are used in the
-non-recursive case for "frames". There is also an optional callout function
-that is triggered by the (?) regex item. For Virtual Pascal, these definitions
-have to take another form. */
-
-#ifndef VPCOMPAT
-PCRE_EXP_DECL void *(*pcre_malloc)(size_t);
-PCRE_EXP_DECL void (*pcre_free)(void *);
-PCRE_EXP_DECL void *(*pcre_stack_malloc)(size_t);
-PCRE_EXP_DECL void (*pcre_stack_free)(void *);
-PCRE_EXP_DECL int (*pcre_callout)(pcre_callout_block *);
-#else /* VPCOMPAT */
-PCRE_EXP_DECL void *pcre_malloc(size_t);
-PCRE_EXP_DECL void pcre_free(void *);
-PCRE_EXP_DECL void *pcre_stack_malloc(size_t);
-PCRE_EXP_DECL void pcre_stack_free(void *);
-PCRE_EXP_DECL int pcre_callout(pcre_callout_block *);
-#endif /* VPCOMPAT */
-
-/* Exported PCRE functions */
-
-PCRE_EXP_DECL pcre *pcre_compile(const char *, int, const char **, int *,
- const unsigned char *);
-PCRE_EXP_DECL pcre *pcre_compile2(const char *, int, int *, const char **,
- int *, const unsigned char *);
-PCRE_EXP_DECL int pcre_config(int, void *);
-PCRE_EXP_DECL int pcre_copy_named_substring(const pcre *, const char *,
- int *, int, const char *, char *, int);
-PCRE_EXP_DECL int pcre_copy_substring(const char *, int *, int, int, char *,
- int);
-PCRE_EXP_DECL int pcre_dfa_exec(const pcre *, const pcre_extra *,
- const char *, int, int, int, int *, int , int *, int);
-PCRE_EXP_DECL int pcre_exec(const pcre *, const pcre_extra *, PCRE_SPTR,
- int, int, int, int *, int);
-PCRE_EXP_DECL void pcre_free_substring(const char *);
-PCRE_EXP_DECL void pcre_free_substring_list(const char **);
-PCRE_EXP_DECL int pcre_fullinfo(const pcre *, const pcre_extra *, int,
- void *);
-PCRE_EXP_DECL int pcre_get_named_substring(const pcre *, const char *,
- int *, int, const char *, const char **);
-PCRE_EXP_DECL int pcre_get_stringnumber(const pcre *, const char *);
-PCRE_EXP_DECL int pcre_get_stringtable_entries(const pcre *, const char *,
- char **, char **);
-PCRE_EXP_DECL int pcre_get_substring(const char *, int *, int, int,
- const char **);
-PCRE_EXP_DECL int pcre_get_substring_list(const char *, int *, int,
- const char ***);
-PCRE_EXP_DECL int pcre_info(const pcre *, int *, int *);
-PCRE_EXP_DECL const unsigned char *pcre_maketables(void);
-PCRE_EXP_DECL int pcre_refcount(pcre *, int);
-PCRE_EXP_DECL pcre_extra *pcre_study(const pcre *, int, const char **);
-PCRE_EXP_DECL const char *pcre_version(void);
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif /* End of pcre.h */
diff --git a/crawl-ref/source/util/pcre/pcre.h.in b/crawl-ref/source/util/pcre/pcre.h.in
deleted file mode 100644
index bb82c82f43..0000000000
--- a/crawl-ref/source/util/pcre/pcre.h.in
+++ /dev/null
@@ -1,304 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* This is the public header file for the PCRE library, to be #included by
-applications that call the PCRE functions.
-
- Copyright (c) 1997-2008 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-#ifndef _PCRE_H
-#define _PCRE_H
-
-/* The current PCRE version information. */
-
-#define PCRE_MAJOR @PCRE_MAJOR@
-#define PCRE_MINOR @PCRE_MINOR@
-#define PCRE_PRERELEASE @PCRE_PRERELEASE@
-#define PCRE_DATE @PCRE_DATE@
-
-/* When an application links to a PCRE DLL in Windows, the symbols that are
-imported have to be identified as such. When building PCRE, the appropriate
-export setting is defined in pcre_internal.h, which includes this file. So we
-don't change existing definitions of PCRE_EXP_DECL and PCRECPP_EXP_DECL. */
-
-#if defined(_WIN32) && !defined(PCRE_STATIC)
-# ifndef PCRE_EXP_DECL
-# define PCRE_EXP_DECL extern __declspec(dllimport)
-# endif
-# ifdef __cplusplus
-# ifndef PCRECPP_EXP_DECL
-# define PCRECPP_EXP_DECL extern __declspec(dllimport)
-# endif
-# ifndef PCRECPP_EXP_DEFN
-# define PCRECPP_EXP_DEFN __declspec(dllimport)
-# endif
-# endif
-#endif
-
-/* By default, we use the standard "extern" declarations. */
-
-#ifndef PCRE_EXP_DECL
-# ifdef __cplusplus
-# define PCRE_EXP_DECL extern "C"
-# else
-# define PCRE_EXP_DECL extern
-# endif
-#endif
-
-#ifdef __cplusplus
-# ifndef PCRECPP_EXP_DECL
-# define PCRECPP_EXP_DECL extern
-# endif
-# ifndef PCRECPP_EXP_DEFN
-# define PCRECPP_EXP_DEFN
-# endif
-#endif
-
-/* Have to include stdlib.h in order to ensure that size_t is defined;
-it is needed here for malloc. */
-
-#include <stdlib.h>
-
-/* Allow for C++ users */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Options */
-
-#define PCRE_CASELESS 0x00000001
-#define PCRE_MULTILINE 0x00000002
-#define PCRE_DOTALL 0x00000004
-#define PCRE_EXTENDED 0x00000008
-#define PCRE_ANCHORED 0x00000010
-#define PCRE_DOLLAR_ENDONLY 0x00000020
-#define PCRE_EXTRA 0x00000040
-#define PCRE_NOTBOL 0x00000080
-#define PCRE_NOTEOL 0x00000100
-#define PCRE_UNGREEDY 0x00000200
-#define PCRE_NOTEMPTY 0x00000400
-#define PCRE_UTF8 0x00000800
-#define PCRE_NO_AUTO_CAPTURE 0x00001000
-#define PCRE_NO_UTF8_CHECK 0x00002000
-#define PCRE_AUTO_CALLOUT 0x00004000
-#define PCRE_PARTIAL 0x00008000
-#define PCRE_DFA_SHORTEST 0x00010000
-#define PCRE_DFA_RESTART 0x00020000
-#define PCRE_FIRSTLINE 0x00040000
-#define PCRE_DUPNAMES 0x00080000
-#define PCRE_NEWLINE_CR 0x00100000
-#define PCRE_NEWLINE_LF 0x00200000
-#define PCRE_NEWLINE_CRLF 0x00300000
-#define PCRE_NEWLINE_ANY 0x00400000
-#define PCRE_NEWLINE_ANYCRLF 0x00500000
-#define PCRE_BSR_ANYCRLF 0x00800000
-#define PCRE_BSR_UNICODE 0x01000000
-#define PCRE_JAVASCRIPT_COMPAT 0x02000000
-
-/* Exec-time and get/set-time error codes */
-
-#define PCRE_ERROR_NOMATCH (-1)
-#define PCRE_ERROR_NULL (-2)
-#define PCRE_ERROR_BADOPTION (-3)
-#define PCRE_ERROR_BADMAGIC (-4)
-#define PCRE_ERROR_UNKNOWN_OPCODE (-5)
-#define PCRE_ERROR_UNKNOWN_NODE (-5) /* For backward compatibility */
-#define PCRE_ERROR_NOMEMORY (-6)
-#define PCRE_ERROR_NOSUBSTRING (-7)
-#define PCRE_ERROR_MATCHLIMIT (-8)
-#define PCRE_ERROR_CALLOUT (-9) /* Never used by PCRE itself */
-#define PCRE_ERROR_BADUTF8 (-10)
-#define PCRE_ERROR_BADUTF8_OFFSET (-11)
-#define PCRE_ERROR_PARTIAL (-12)
-#define PCRE_ERROR_BADPARTIAL (-13)
-#define PCRE_ERROR_INTERNAL (-14)
-#define PCRE_ERROR_BADCOUNT (-15)
-#define PCRE_ERROR_DFA_UITEM (-16)
-#define PCRE_ERROR_DFA_UCOND (-17)
-#define PCRE_ERROR_DFA_UMLIMIT (-18)
-#define PCRE_ERROR_DFA_WSSIZE (-19)
-#define PCRE_ERROR_DFA_RECURSE (-20)
-#define PCRE_ERROR_RECURSIONLIMIT (-21)
-#define PCRE_ERROR_NULLWSLIMIT (-22) /* No longer actually used */
-#define PCRE_ERROR_BADNEWLINE (-23)
-
-/* Request types for pcre_fullinfo() */
-
-#define PCRE_INFO_OPTIONS 0
-#define PCRE_INFO_SIZE 1
-#define PCRE_INFO_CAPTURECOUNT 2
-#define PCRE_INFO_BACKREFMAX 3
-#define PCRE_INFO_FIRSTBYTE 4
-#define PCRE_INFO_FIRSTCHAR 4 /* For backwards compatibility */
-#define PCRE_INFO_FIRSTTABLE 5
-#define PCRE_INFO_LASTLITERAL 6
-#define PCRE_INFO_NAMEENTRYSIZE 7
-#define PCRE_INFO_NAMECOUNT 8
-#define PCRE_INFO_NAMETABLE 9
-#define PCRE_INFO_STUDYSIZE 10
-#define PCRE_INFO_DEFAULT_TABLES 11
-#define PCRE_INFO_OKPARTIAL 12
-#define PCRE_INFO_JCHANGED 13
-#define PCRE_INFO_HASCRORLF 14
-
-/* Request types for pcre_config(). Do not re-arrange, in order to remain
-compatible. */
-
-#define PCRE_CONFIG_UTF8 0
-#define PCRE_CONFIG_NEWLINE 1
-#define PCRE_CONFIG_LINK_SIZE 2
-#define PCRE_CONFIG_POSIX_MALLOC_THRESHOLD 3
-#define PCRE_CONFIG_MATCH_LIMIT 4
-#define PCRE_CONFIG_STACKRECURSE 5
-#define PCRE_CONFIG_UNICODE_PROPERTIES 6
-#define PCRE_CONFIG_MATCH_LIMIT_RECURSION 7
-#define PCRE_CONFIG_BSR 8
-
-/* Bit flags for the pcre_extra structure. Do not re-arrange or redefine
-these bits, just add new ones on the end, in order to remain compatible. */
-
-#define PCRE_EXTRA_STUDY_DATA 0x0001
-#define PCRE_EXTRA_MATCH_LIMIT 0x0002
-#define PCRE_EXTRA_CALLOUT_DATA 0x0004
-#define PCRE_EXTRA_TABLES 0x0008
-#define PCRE_EXTRA_MATCH_LIMIT_RECURSION 0x0010
-
-/* Types */
-
-struct real_pcre; /* declaration; the definition is private */
-typedef struct real_pcre pcre;
-
-/* When PCRE is compiled as a C++ library, the subject pointer type can be
-replaced with a custom type. For conventional use, the public interface is a
-const char *. */
-
-#ifndef PCRE_SPTR
-#define PCRE_SPTR const char *
-#endif
-
-/* The structure for passing additional data to pcre_exec(). This is defined in
-such as way as to be extensible. Always add new fields at the end, in order to
-remain compatible. */
-
-typedef struct pcre_extra {
- unsigned long int flags; /* Bits for which fields are set */
- void *study_data; /* Opaque data from pcre_study() */
- unsigned long int match_limit; /* Maximum number of calls to match() */
- void *callout_data; /* Data passed back in callouts */
- const unsigned char *tables; /* Pointer to character tables */
- unsigned long int match_limit_recursion; /* Max recursive calls to match() */
-} pcre_extra;
-
-/* The structure for passing out data via the pcre_callout_function. We use a
-structure so that new fields can be added on the end in future versions,
-without changing the API of the function, thereby allowing old clients to work
-without modification. */
-
-typedef struct pcre_callout_block {
- int version; /* Identifies version of block */
- /* ------------------------ Version 0 ------------------------------- */
- int callout_number; /* Number compiled into pattern */
- int *offset_vector; /* The offset vector */
- PCRE_SPTR subject; /* The subject being matched */
- int subject_length; /* The length of the subject */
- int start_match; /* Offset to start of this match attempt */
- int current_position; /* Where we currently are in the subject */
- int capture_top; /* Max current capture */
- int capture_last; /* Most recently closed capture */
- void *callout_data; /* Data passed in with the call */
- /* ------------------- Added for Version 1 -------------------------- */
- int pattern_position; /* Offset to next item in the pattern */
- int next_item_length; /* Length of next item in the pattern */
- /* ------------------------------------------------------------------ */
-} pcre_callout_block;
-
-/* Indirection for store get and free functions. These can be set to
-alternative malloc/free functions if required. Special ones are used in the
-non-recursive case for "frames". There is also an optional callout function
-that is triggered by the (?) regex item. For Virtual Pascal, these definitions
-have to take another form. */
-
-#ifndef VPCOMPAT
-PCRE_EXP_DECL void *(*pcre_malloc)(size_t);
-PCRE_EXP_DECL void (*pcre_free)(void *);
-PCRE_EXP_DECL void *(*pcre_stack_malloc)(size_t);
-PCRE_EXP_DECL void (*pcre_stack_free)(void *);
-PCRE_EXP_DECL int (*pcre_callout)(pcre_callout_block *);
-#else /* VPCOMPAT */
-PCRE_EXP_DECL void *pcre_malloc(size_t);
-PCRE_EXP_DECL void pcre_free(void *);
-PCRE_EXP_DECL void *pcre_stack_malloc(size_t);
-PCRE_EXP_DECL void pcre_stack_free(void *);
-PCRE_EXP_DECL int pcre_callout(pcre_callout_block *);
-#endif /* VPCOMPAT */
-
-/* Exported PCRE functions */
-
-PCRE_EXP_DECL pcre *pcre_compile(const char *, int, const char **, int *,
- const unsigned char *);
-PCRE_EXP_DECL pcre *pcre_compile2(const char *, int, int *, const char **,
- int *, const unsigned char *);
-PCRE_EXP_DECL int pcre_config(int, void *);
-PCRE_EXP_DECL int pcre_copy_named_substring(const pcre *, const char *,
- int *, int, const char *, char *, int);
-PCRE_EXP_DECL int pcre_copy_substring(const char *, int *, int, int, char *,
- int);
-PCRE_EXP_DECL int pcre_dfa_exec(const pcre *, const pcre_extra *,
- const char *, int, int, int, int *, int , int *, int);
-PCRE_EXP_DECL int pcre_exec(const pcre *, const pcre_extra *, PCRE_SPTR,
- int, int, int, int *, int);
-PCRE_EXP_DECL void pcre_free_substring(const char *);
-PCRE_EXP_DECL void pcre_free_substring_list(const char **);
-PCRE_EXP_DECL int pcre_fullinfo(const pcre *, const pcre_extra *, int,
- void *);
-PCRE_EXP_DECL int pcre_get_named_substring(const pcre *, const char *,
- int *, int, const char *, const char **);
-PCRE_EXP_DECL int pcre_get_stringnumber(const pcre *, const char *);
-PCRE_EXP_DECL int pcre_get_stringtable_entries(const pcre *, const char *,
- char **, char **);
-PCRE_EXP_DECL int pcre_get_substring(const char *, int *, int, int,
- const char **);
-PCRE_EXP_DECL int pcre_get_substring_list(const char *, int *, int,
- const char ***);
-PCRE_EXP_DECL int pcre_info(const pcre *, int *, int *);
-PCRE_EXP_DECL const unsigned char *pcre_maketables(void);
-PCRE_EXP_DECL int pcre_refcount(pcre *, int);
-PCRE_EXP_DECL pcre_extra *pcre_study(const pcre *, int, const char **);
-PCRE_EXP_DECL const char *pcre_version(void);
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif /* End of pcre.h */
diff --git a/crawl-ref/source/util/pcre/pcre_chartables.c b/crawl-ref/source/util/pcre/pcre_chartables.c
deleted file mode 100644
index ae45db0ca3..0000000000
--- a/crawl-ref/source/util/pcre/pcre_chartables.c
+++ /dev/null
@@ -1,198 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* This file contains character tables that are used when no external tables
-are passed to PCRE by the application that calls it. The tables are used only
-for characters whose code values are less than 256.
-
-This is a default version of the tables that assumes ASCII encoding. A program
-called dftables (which is distributed with PCRE) can be used to build
-alternative versions of this file. This is necessary if you are running in an
-EBCDIC environment, or if you want to default to a different encoding, for
-example ISO-8859-1. When dftables is run, it creates these tables in the
-current locale. If PCRE is configured with --enable-rebuild-chartables, this
-happens automatically.
-
-The following #includes are present because without the gcc 4.x may remove the
-array definition from the final binary if PCRE is built into a static library
-and dead code stripping is activated. This leads to link errors. Pulling in the
-header ensures that the array gets flagged as "someone outside this compilation
-unit might reference this" and so it will always be supplied to the linker. */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "pcre_internal.h"
-
-const unsigned char _pcre_default_tables[] = {
-
-/* This table is a lower casing table. */
-
- 0, 1, 2, 3, 4, 5, 6, 7,
- 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23,
- 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39,
- 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55,
- 56, 57, 58, 59, 60, 61, 62, 63,
- 64, 97, 98, 99,100,101,102,103,
- 104,105,106,107,108,109,110,111,
- 112,113,114,115,116,117,118,119,
- 120,121,122, 91, 92, 93, 94, 95,
- 96, 97, 98, 99,100,101,102,103,
- 104,105,106,107,108,109,110,111,
- 112,113,114,115,116,117,118,119,
- 120,121,122,123,124,125,126,127,
- 128,129,130,131,132,133,134,135,
- 136,137,138,139,140,141,142,143,
- 144,145,146,147,148,149,150,151,
- 152,153,154,155,156,157,158,159,
- 160,161,162,163,164,165,166,167,
- 168,169,170,171,172,173,174,175,
- 176,177,178,179,180,181,182,183,
- 184,185,186,187,188,189,190,191,
- 192,193,194,195,196,197,198,199,
- 200,201,202,203,204,205,206,207,
- 208,209,210,211,212,213,214,215,
- 216,217,218,219,220,221,222,223,
- 224,225,226,227,228,229,230,231,
- 232,233,234,235,236,237,238,239,
- 240,241,242,243,244,245,246,247,
- 248,249,250,251,252,253,254,255,
-
-/* This table is a case flipping table. */
-
- 0, 1, 2, 3, 4, 5, 6, 7,
- 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23,
- 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39,
- 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55,
- 56, 57, 58, 59, 60, 61, 62, 63,
- 64, 97, 98, 99,100,101,102,103,
- 104,105,106,107,108,109,110,111,
- 112,113,114,115,116,117,118,119,
- 120,121,122, 91, 92, 93, 94, 95,
- 96, 65, 66, 67, 68, 69, 70, 71,
- 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87,
- 88, 89, 90,123,124,125,126,127,
- 128,129,130,131,132,133,134,135,
- 136,137,138,139,140,141,142,143,
- 144,145,146,147,148,149,150,151,
- 152,153,154,155,156,157,158,159,
- 160,161,162,163,164,165,166,167,
- 168,169,170,171,172,173,174,175,
- 176,177,178,179,180,181,182,183,
- 184,185,186,187,188,189,190,191,
- 192,193,194,195,196,197,198,199,
- 200,201,202,203,204,205,206,207,
- 208,209,210,211,212,213,214,215,
- 216,217,218,219,220,221,222,223,
- 224,225,226,227,228,229,230,231,
- 232,233,234,235,236,237,238,239,
- 240,241,242,243,244,245,246,247,
- 248,249,250,251,252,253,254,255,
-
-/* This table contains bit maps for various character classes. Each map is 32
-bytes long and the bits run from the least significant end of each byte. The
-classes that have their own maps are: space, xdigit, digit, upper, lower, word,
-graph, print, punct, and cntrl. Other classes are built from combinations. */
-
- 0x00,0x3e,0x00,0x00,0x01,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-
- 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03,
- 0x7e,0x00,0x00,0x00,0x7e,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-
- 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0xfe,0xff,0xff,0x07,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0x07,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-
- 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03,
- 0xfe,0xff,0xff,0x87,0xfe,0xff,0xff,0x07,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-
- 0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-
- 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-
- 0x00,0x00,0x00,0x00,0xfe,0xff,0x00,0xfc,
- 0x01,0x00,0x00,0xf8,0x01,0x00,0x00,0x78,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-
- 0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-
-/* This table identifies various classes of character by individual bits:
- 0x01 white space character
- 0x02 letter
- 0x04 decimal digit
- 0x08 hexadecimal digit
- 0x10 alphanumeric or '_'
- 0x80 regular expression metacharacter or binary zero
-*/
-
- 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0- 7 */
- 0x00,0x01,0x01,0x00,0x01,0x01,0x00,0x00, /* 8- 15 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 16- 23 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 24- 31 */
- 0x01,0x00,0x00,0x00,0x80,0x00,0x00,0x00, /* - ' */
- 0x80,0x80,0x80,0x80,0x00,0x00,0x80,0x00, /* ( - / */
- 0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c, /* 0 - 7 */
- 0x1c,0x1c,0x00,0x00,0x00,0x00,0x00,0x80, /* 8 - ? */
- 0x00,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x12, /* @ - G */
- 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* H - O */
- 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* P - W */
- 0x12,0x12,0x12,0x80,0x80,0x00,0x80,0x10, /* X - _ */
- 0x00,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x12, /* ` - g */
- 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* h - o */
- 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* p - w */
- 0x12,0x12,0x12,0x80,0x80,0x00,0x00,0x00, /* x -127 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 128-135 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 136-143 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 144-151 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 152-159 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 160-167 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 168-175 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 176-183 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 184-191 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 192-199 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 200-207 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 208-215 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 216-223 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 224-231 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 232-239 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 240-247 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};/* 248-255 */
-
-/* End of pcre_chartables.c */
diff --git a/crawl-ref/source/util/pcre/pcre_compile.c b/crawl-ref/source/util/pcre/pcre_compile.c
deleted file mode 100644
index 4b28343722..0000000000
--- a/crawl-ref/source/util/pcre/pcre_compile.c
+++ /dev/null
@@ -1,6379 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
- Written by Philip Hazel
- Copyright (c) 1997-2008 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-
-/* This module contains the external function pcre_compile(), along with
-supporting internal functions that are not used by other modules. */
-
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#define NLBLOCK cd /* Block containing newline information */
-#define PSSTART start_pattern /* Field containing processed string start */
-#define PSEND end_pattern /* Field containing processed string end */
-
-#include "pcre_internal.h"
-
-
-/* When DEBUG is defined, we need the pcre_printint() function, which is also
-used by pcretest. DEBUG is not defined when building a production library. */
-
-#ifdef DEBUG
-#include "pcre_printint.src"
-#endif
-
-
-/* Macro for setting individual bits in class bitmaps. */
-
-#define SETBIT(a,b) a[b/8] |= (1 << (b%8))
-
-/* Maximum length value to check against when making sure that the integer that
-holds the compiled pattern length does not overflow. We make it a bit less than
-INT_MAX to allow for adding in group terminating bytes, so that we don't have
-to check them every time. */
-
-#define OFLOW_MAX (INT_MAX - 20)
-
-
-/*************************************************
-* Code parameters and static tables *
-*************************************************/
-
-/* This value specifies the size of stack workspace that is used during the
-first pre-compile phase that determines how much memory is required. The regex
-is partly compiled into this space, but the compiled parts are discarded as
-soon as they can be, so that hopefully there will never be an overrun. The code
-does, however, check for an overrun. The largest amount I've seen used is 218,
-so this number is very generous.
-
-The same workspace is used during the second, actual compile phase for
-remembering forward references to groups so that they can be filled in at the
-end. Each entry in this list occupies LINK_SIZE bytes, so even when LINK_SIZE
-is 4 there is plenty of room. */
-
-#define COMPILE_WORK_SIZE (4096)
-
-
-/* Table for handling escaped characters in the range '0'-'z'. Positive returns
-are simple data values; negative values are for special things like \d and so
-on. Zero means further processing is needed (for things like \x), or the escape
-is invalid. */
-
-#ifndef EBCDIC /* This is the "normal" table for ASCII systems */
-static const short int escapes[] = {
- 0, 0, 0, 0, 0, 0, 0, 0, /* 0 - 7 */
- 0, 0, ':', ';', '<', '=', '>', '?', /* 8 - ? */
- '@', -ESC_A, -ESC_B, -ESC_C, -ESC_D, -ESC_E, 0, -ESC_G, /* @ - G */
--ESC_H, 0, 0, -ESC_K, 0, 0, 0, 0, /* H - O */
--ESC_P, -ESC_Q, -ESC_R, -ESC_S, 0, 0, -ESC_V, -ESC_W, /* P - W */
--ESC_X, 0, -ESC_Z, '[', '\\', ']', '^', '_', /* X - _ */
- '`', 7, -ESC_b, 0, -ESC_d, ESC_e, ESC_f, 0, /* ` - g */
--ESC_h, 0, 0, -ESC_k, 0, 0, ESC_n, 0, /* h - o */
--ESC_p, 0, ESC_r, -ESC_s, ESC_tee, 0, -ESC_v, -ESC_w, /* p - w */
- 0, 0, -ESC_z /* x - z */
-};
-
-#else /* This is the "abnormal" table for EBCDIC systems */
-static const short int escapes[] = {
-/* 48 */ 0, 0, 0, '.', '<', '(', '+', '|',
-/* 50 */ '&', 0, 0, 0, 0, 0, 0, 0,
-/* 58 */ 0, 0, '!', '$', '*', ')', ';', '~',
-/* 60 */ '-', '/', 0, 0, 0, 0, 0, 0,
-/* 68 */ 0, 0, '|', ',', '%', '_', '>', '?',
-/* 70 */ 0, 0, 0, 0, 0, 0, 0, 0,
-/* 78 */ 0, '`', ':', '#', '@', '\'', '=', '"',
-/* 80 */ 0, 7, -ESC_b, 0, -ESC_d, ESC_e, ESC_f, 0,
-/* 88 */-ESC_h, 0, 0, '{', 0, 0, 0, 0,
-/* 90 */ 0, 0, -ESC_k, 'l', 0, ESC_n, 0, -ESC_p,
-/* 98 */ 0, ESC_r, 0, '}', 0, 0, 0, 0,
-/* A0 */ 0, '~', -ESC_s, ESC_tee, 0,-ESC_v, -ESC_w, 0,
-/* A8 */ 0,-ESC_z, 0, 0, 0, '[', 0, 0,
-/* B0 */ 0, 0, 0, 0, 0, 0, 0, 0,
-/* B8 */ 0, 0, 0, 0, 0, ']', '=', '-',
-/* C0 */ '{',-ESC_A, -ESC_B, -ESC_C, -ESC_D,-ESC_E, 0, -ESC_G,
-/* C8 */-ESC_H, 0, 0, 0, 0, 0, 0, 0,
-/* D0 */ '}', 0, -ESC_K, 0, 0, 0, 0, -ESC_P,
-/* D8 */-ESC_Q,-ESC_R, 0, 0, 0, 0, 0, 0,
-/* E0 */ '\\', 0, -ESC_S, 0, 0,-ESC_V, -ESC_W, -ESC_X,
-/* E8 */ 0,-ESC_Z, 0, 0, 0, 0, 0, 0,
-/* F0 */ 0, 0, 0, 0, 0, 0, 0, 0,
-/* F8 */ 0, 0, 0, 0, 0, 0, 0, 0
-};
-#endif
-
-
-/* Table of special "verbs" like (*PRUNE). This is a short table, so it is
-searched linearly. Put all the names into a single string, in order to reduce
-the number of relocations when a shared library is dynamically linked. */
-
-typedef struct verbitem {
- int len;
- int op;
-} verbitem;
-
-static const char verbnames[] =
- "ACCEPT\0"
- "COMMIT\0"
- "F\0"
- "FAIL\0"
- "PRUNE\0"
- "SKIP\0"
- "THEN";
-
-static const verbitem verbs[] = {
- { 6, OP_ACCEPT },
- { 6, OP_COMMIT },
- { 1, OP_FAIL },
- { 4, OP_FAIL },
- { 5, OP_PRUNE },
- { 4, OP_SKIP },
- { 4, OP_THEN }
-};
-
-static const int verbcount = sizeof(verbs)/sizeof(verbitem);
-
-
-/* Tables of names of POSIX character classes and their lengths. The names are
-now all in a single string, to reduce the number of relocations when a shared
-library is dynamically loaded. The list of lengths is terminated by a zero
-length entry. The first three must be alpha, lower, upper, as this is assumed
-for handling case independence. */
-
-static const char posix_names[] =
- "alpha\0" "lower\0" "upper\0" "alnum\0" "ascii\0" "blank\0"
- "cntrl\0" "digit\0" "graph\0" "print\0" "punct\0" "space\0"
- "word\0" "xdigit";
-
-static const uschar posix_name_lengths[] = {
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 6, 0 };
-
-/* Table of class bit maps for each POSIX class. Each class is formed from a
-base map, with an optional addition or removal of another map. Then, for some
-classes, there is some additional tweaking: for [:blank:] the vertical space
-characters are removed, and for [:alpha:] and [:alnum:] the underscore
-character is removed. The triples in the table consist of the base map offset,
-second map offset or -1 if no second map, and a non-negative value for map
-addition or a negative value for map subtraction (if there are two maps). The
-absolute value of the third field has these meanings: 0 => no tweaking, 1 =>
-remove vertical space characters, 2 => remove underscore. */
-
-static const int posix_class_maps[] = {
- cbit_word, cbit_digit, -2, /* alpha */
- cbit_lower, -1, 0, /* lower */
- cbit_upper, -1, 0, /* upper */
- cbit_word, -1, 2, /* alnum - word without underscore */
- cbit_print, cbit_cntrl, 0, /* ascii */
- cbit_space, -1, 1, /* blank - a GNU extension */
- cbit_cntrl, -1, 0, /* cntrl */
- cbit_digit, -1, 0, /* digit */
- cbit_graph, -1, 0, /* graph */
- cbit_print, -1, 0, /* print */
- cbit_punct, -1, 0, /* punct */
- cbit_space, -1, 0, /* space */
- cbit_word, -1, 0, /* word - a Perl extension */
- cbit_xdigit,-1, 0 /* xdigit */
-};
-
-
-#define STRING(a) # a
-#define XSTRING(s) STRING(s)
-
-/* The texts of compile-time error messages. These are "char *" because they
-are passed to the outside world. Do not ever re-use any error number, because
-they are documented. Always add a new error instead. Messages marked DEAD below
-are no longer used. This used to be a table of strings, but in order to reduce
-the number of relocations needed when a shared library is loaded dynamically,
-it is now one long string. We cannot use a table of offsets, because the
-lengths of inserts such as XSTRING(MAX_NAME_SIZE) are not known. Instead, we
-simply count through to the one we want - this isn't a performance issue
-because these strings are used only when there is a compilation error. */
-
-static const char error_texts[] =
- "no error\0"
- "\\ at end of pattern\0"
- "\\c at end of pattern\0"
- "unrecognized character follows \\\0"
- "numbers out of order in {} quantifier\0"
- /* 5 */
- "number too big in {} quantifier\0"
- "missing terminating ] for character class\0"
- "invalid escape sequence in character class\0"
- "range out of order in character class\0"
- "nothing to repeat\0"
- /* 10 */
- "operand of unlimited repeat could match the empty string\0" /** DEAD **/
- "internal error: unexpected repeat\0"
- "unrecognized character after (? or (?-\0"
- "POSIX named classes are supported only within a class\0"
- "missing )\0"
- /* 15 */
- "reference to non-existent subpattern\0"
- "erroffset passed as NULL\0"
- "unknown option bit(s) set\0"
- "missing ) after comment\0"
- "parentheses nested too deeply\0" /** DEAD **/
- /* 20 */
- "regular expression is too large\0"
- "failed to get memory\0"
- "unmatched parentheses\0"
- "internal error: code overflow\0"
- "unrecognized character after (?<\0"
- /* 25 */
- "lookbehind assertion is not fixed length\0"
- "malformed number or name after (?(\0"
- "conditional group contains more than two branches\0"
- "assertion expected after (?(\0"
- "(?R or (?[+-]digits must be followed by )\0"
- /* 30 */
- "unknown POSIX class name\0"
- "POSIX collating elements are not supported\0"
- "this version of PCRE is not compiled with PCRE_UTF8 support\0"
- "spare error\0" /** DEAD **/
- "character value in \\x{...} sequence is too large\0"
- /* 35 */
- "invalid condition (?(0)\0"
- "\\C not allowed in lookbehind assertion\0"
- "PCRE does not support \\L, \\l, \\N, \\U, or \\u\0"
- "number after (?C is > 255\0"
- "closing ) for (?C expected\0"
- /* 40 */
- "recursive call could loop indefinitely\0"
- "unrecognized character after (?P\0"
- "syntax error in subpattern name (missing terminator)\0"
- "two named subpatterns have the same name\0"
- "invalid UTF-8 string\0"
- /* 45 */
- "support for \\P, \\p, and \\X has not been compiled\0"
- "malformed \\P or \\p sequence\0"
- "unknown property name after \\P or \\p\0"
- "subpattern name is too long (maximum " XSTRING(MAX_NAME_SIZE) " characters)\0"
- "too many named subpatterns (maximum " XSTRING(MAX_NAME_COUNT) ")\0"
- /* 50 */
- "repeated subpattern is too long\0" /** DEAD **/
- "octal value is greater than \\377 (not in UTF-8 mode)\0"
- "internal error: overran compiling workspace\0"
- "internal error: previously-checked referenced subpattern not found\0"
- "DEFINE group contains more than one branch\0"
- /* 55 */
- "repeating a DEFINE group is not allowed\0"
- "inconsistent NEWLINE options\0"
- "\\g is not followed by a braced, angle-bracketed, or quoted name/number or by a plain number\0"
- "a numbered reference must not be zero\0"
- "(*VERB) with an argument is not supported\0"
- /* 60 */
- "(*VERB) not recognized\0"
- "number is too big\0"
- "subpattern name expected\0"
- "digit expected after (?+\0"
- "] is an invalid data character in JavaScript compatibility mode";
-
-
-/* Table to identify digits and hex digits. This is used when compiling
-patterns. Note that the tables in chartables are dependent on the locale, and
-may mark arbitrary characters as digits - but the PCRE compiling code expects
-to handle only 0-9, a-z, and A-Z as digits when compiling. That is why we have
-a private table here. It costs 256 bytes, but it is a lot faster than doing
-character value tests (at least in some simple cases I timed), and in some
-applications one wants PCRE to compile efficiently as well as match
-efficiently.
-
-For convenience, we use the same bit definitions as in chartables:
-
- 0x04 decimal digit
- 0x08 hexadecimal digit
-
-Then we can use ctype_digit and ctype_xdigit in the code. */
-
-#ifndef EBCDIC /* This is the "normal" case, for ASCII systems */
-static const unsigned char digitab[] =
- {
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0- 7 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 8- 15 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 16- 23 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 24- 31 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* - ' */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* ( - / */
- 0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c, /* 0 - 7 */
- 0x0c,0x0c,0x00,0x00,0x00,0x00,0x00,0x00, /* 8 - ? */
- 0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x00, /* @ - G */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* H - O */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* P - W */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* X - _ */
- 0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x00, /* ` - g */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* h - o */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p - w */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* x -127 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 128-135 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 136-143 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 144-151 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 152-159 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 160-167 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 168-175 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 176-183 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 184-191 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 192-199 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 200-207 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 208-215 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 216-223 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 224-231 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 232-239 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 240-247 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};/* 248-255 */
-
-#else /* This is the "abnormal" case, for EBCDIC systems */
-static const unsigned char digitab[] =
- {
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0- 7 0 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 8- 15 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 16- 23 10 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 24- 31 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 32- 39 20 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 40- 47 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 48- 55 30 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 56- 63 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* - 71 40 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 72- | */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* & - 87 50 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 88- 95 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* - -103 60 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 104- ? */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 112-119 70 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 120- " */
- 0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x00, /* 128- g 80 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* h -143 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 144- p 90 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* q -159 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 160- x A0 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* y -175 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* ^ -183 B0 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 184-191 */
- 0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x00, /* { - G C0 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* H -207 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* } - P D0 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* Q -223 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* \ - X E0 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* Y -239 */
- 0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c, /* 0 - 7 F0 */
- 0x0c,0x0c,0x00,0x00,0x00,0x00,0x00,0x00};/* 8 -255 */
-
-static const unsigned char ebcdic_chartab[] = { /* chartable partial dup */
- 0x80,0x00,0x00,0x00,0x00,0x01,0x00,0x00, /* 0- 7 */
- 0x00,0x00,0x00,0x00,0x01,0x01,0x00,0x00, /* 8- 15 */
- 0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00, /* 16- 23 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 24- 31 */
- 0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00, /* 32- 39 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 40- 47 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 48- 55 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 56- 63 */
- 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* - 71 */
- 0x00,0x00,0x00,0x80,0x00,0x80,0x80,0x80, /* 72- | */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* & - 87 */
- 0x00,0x00,0x00,0x80,0x80,0x80,0x00,0x00, /* 88- 95 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* - -103 */
- 0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x80, /* 104- ? */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 112-119 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 120- " */
- 0x00,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x12, /* 128- g */
- 0x12,0x12,0x00,0x00,0x00,0x00,0x00,0x00, /* h -143 */
- 0x00,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* 144- p */
- 0x12,0x12,0x00,0x00,0x00,0x00,0x00,0x00, /* q -159 */
- 0x00,0x00,0x12,0x12,0x12,0x12,0x12,0x12, /* 160- x */
- 0x12,0x12,0x00,0x00,0x00,0x00,0x00,0x00, /* y -175 */
- 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* ^ -183 */
- 0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00, /* 184-191 */
- 0x80,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x12, /* { - G */
- 0x12,0x12,0x00,0x00,0x00,0x00,0x00,0x00, /* H -207 */
- 0x00,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* } - P */
- 0x12,0x12,0x00,0x00,0x00,0x00,0x00,0x00, /* Q -223 */
- 0x00,0x00,0x12,0x12,0x12,0x12,0x12,0x12, /* \ - X */
- 0x12,0x12,0x00,0x00,0x00,0x00,0x00,0x00, /* Y -239 */
- 0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c, /* 0 - 7 */
- 0x1c,0x1c,0x00,0x00,0x00,0x00,0x00,0x00};/* 8 -255 */
-#endif
-
-
-/* Definition to allow mutual recursion */
-
-static BOOL
- compile_regex(int, int, uschar **, const uschar **, int *, BOOL, BOOL, int,
- int *, int *, branch_chain *, compile_data *, int *);
-
-
-
-/*************************************************
-* Find an error text *
-*************************************************/
-
-/* The error texts are now all in one long string, to save on relocations. As
-some of the text is of unknown length, we can't use a table of offsets.
-Instead, just count through the strings. This is not a performance issue
-because it happens only when there has been a compilation error.
-
-Argument: the error number
-Returns: pointer to the error string
-*/
-
-static const char *
-find_error_text(int n)
-{
-const char *s = error_texts;
-for (; n > 0; n--) while (*s++ != 0);
-return s;
-}
-
-
-/*************************************************
-* Handle escapes *
-*************************************************/
-
-/* This function is called when a \ has been encountered. It either returns a
-positive value for a simple escape such as \n, or a negative value which
-encodes one of the more complicated things such as \d. A backreference to group
-n is returned as -(ESC_REF + n); ESC_REF is the highest ESC_xxx macro. When
-UTF-8 is enabled, a positive value greater than 255 may be returned. On entry,
-ptr is pointing at the \. On exit, it is on the final character of the escape
-sequence.
-
-Arguments:
- ptrptr points to the pattern position pointer
- errorcodeptr points to the errorcode variable
- bracount number of previous extracting brackets
- options the options bits
- isclass TRUE if inside a character class
-
-Returns: zero or positive => a data character
- negative => a special escape sequence
- on error, errorcodeptr is set
-*/
-
-static int
-check_escape(const uschar **ptrptr, int *errorcodeptr, int bracount,
- int options, BOOL isclass)
-{
-BOOL utf8 = (options & PCRE_UTF8) != 0;
-const uschar *ptr = *ptrptr + 1;
-int c, i;
-
-GETCHARINCTEST(c, ptr); /* Get character value, increment pointer */
-ptr--; /* Set pointer back to the last byte */
-
-/* If backslash is at the end of the pattern, it's an error. */
-
-if (c == 0) *errorcodeptr = ERR1;
-
-/* Non-alphanumerics are literals. For digits or letters, do an initial lookup
-in a table. A non-zero result is something that can be returned immediately.
-Otherwise further processing may be required. */
-
-#ifndef EBCDIC /* ASCII coding */
-else if (c < '0' || c > 'z') {} /* Not alphanumeric */
-else if ((i = escapes[c - '0']) != 0) c = i;
-
-#else /* EBCDIC coding */
-else if (c < 'a' || (ebcdic_chartab[c] & 0x0E) == 0) {} /* Not alphanumeric */
-else if ((i = escapes[c - 0x48]) != 0) c = i;
-#endif
-
-/* Escapes that need further processing, or are illegal. */
-
-else
- {
- const uschar *oldptr;
- BOOL braced, negated;
-
- switch (c)
- {
- /* A number of Perl escapes are not handled by PCRE. We give an explicit
- error. */
-
- case 'l':
- case 'L':
- case 'N':
- case 'u':
- case 'U':
- *errorcodeptr = ERR37;
- break;
-
- /* \g must be followed by one of a number of specific things:
-
- (1) A number, either plain or braced. If positive, it is an absolute
- backreference. If negative, it is a relative backreference. This is a Perl
- 5.10 feature.
-
- (2) Perl 5.10 also supports \g{name} as a reference to a named group. This
- is part of Perl's movement towards a unified syntax for back references. As
- this is synonymous with \k{name}, we fudge it up by pretending it really
- was \k.
-
- (3) For Oniguruma compatibility we also support \g followed by a name or a
- number either in angle brackets or in single quotes. However, these are
- (possibly recursive) subroutine calls, _not_ backreferences. Just return
- the -ESC_g code (cf \k). */
-
- case 'g':
- if (ptr[1] == '<' || ptr[1] == '\'')
- {
- c = -ESC_g;
- break;
- }
-
- /* Handle the Perl-compatible cases */
-
- if (ptr[1] == '{')
- {
- const uschar *p;
- for (p = ptr+2; *p != 0 && *p != '}'; p++)
- if (*p != '-' && (digitab[*p] & ctype_digit) == 0) break;
- if (*p != 0 && *p != '}')
- {
- c = -ESC_k;
- break;
- }
- braced = TRUE;
- ptr++;
- }
- else braced = FALSE;
-
- if (ptr[1] == '-')
- {
- negated = TRUE;
- ptr++;
- }
- else negated = FALSE;
-
- c = 0;
- while ((digitab[ptr[1]] & ctype_digit) != 0)
- c = c * 10 + *(++ptr) - '0';
-
- if (c < 0) /* Integer overflow */
- {
- *errorcodeptr = ERR61;
- break;
- }
-
- if (braced && *(++ptr) != '}')
- {
- *errorcodeptr = ERR57;
- break;
- }
-
- if (c == 0)
- {
- *errorcodeptr = ERR58;
- break;
- }
-
- if (negated)
- {
- if (c > bracount)
- {
- *errorcodeptr = ERR15;
- break;
- }
- c = bracount - (c - 1);
- }
-
- c = -(ESC_REF + c);
- break;
-
- /* The handling of escape sequences consisting of a string of digits
- starting with one that is not zero is not straightforward. By experiment,
- the way Perl works seems to be as follows:
-
- Outside a character class, the digits are read as a decimal number. If the
- number is less than 10, or if there are that many previous extracting
- left brackets, then it is a back reference. Otherwise, up to three octal
- digits are read to form an escaped byte. Thus \123 is likely to be octal
- 123 (cf \0123, which is octal 012 followed by the literal 3). If the octal
- value is greater than 377, the least significant 8 bits are taken. Inside a
- character class, \ followed by a digit is always an octal number. */
-
- case '1': case '2': case '3': case '4': case '5':
- case '6': case '7': case '8': case '9':
-
- if (!isclass)
- {
- oldptr = ptr;
- c -= '0';
- while ((digitab[ptr[1]] & ctype_digit) != 0)
- c = c * 10 + *(++ptr) - '0';
- if (c < 0) /* Integer overflow */
- {
- *errorcodeptr = ERR61;
- break;
- }
- if (c < 10 || c <= bracount)
- {
- c = -(ESC_REF + c);
- break;
- }
- ptr = oldptr; /* Put the pointer back and fall through */
- }
-
- /* Handle an octal number following \. If the first digit is 8 or 9, Perl
- generates a binary zero byte and treats the digit as a following literal.
- Thus we have to pull back the pointer by one. */
-
- if ((c = *ptr) >= '8')
- {
- ptr--;
- c = 0;
- break;
- }
-
- /* \0 always starts an octal number, but we may drop through to here with a
- larger first octal digit. The original code used just to take the least
- significant 8 bits of octal numbers (I think this is what early Perls used
- to do). Nowadays we allow for larger numbers in UTF-8 mode, but no more
- than 3 octal digits. */
-
- case '0':
- c -= '0';
- while(i++ < 2 && ptr[1] >= '0' && ptr[1] <= '7')
- c = c * 8 + *(++ptr) - '0';
- if (!utf8 && c > 255) *errorcodeptr = ERR51;
- break;
-
- /* \x is complicated. \x{ddd} is a character number which can be greater
- than 0xff in utf8 mode, but only if the ddd are hex digits. If not, { is
- treated as a data character. */
-
- case 'x':
- if (ptr[1] == '{')
- {
- const uschar *pt = ptr + 2;
- int count = 0;
-
- c = 0;
- while ((digitab[*pt] & ctype_xdigit) != 0)
- {
- register int cc = *pt++;
- if (c == 0 && cc == '0') continue; /* Leading zeroes */
- count++;
-
-#ifndef EBCDIC /* ASCII coding */
- if (cc >= 'a') cc -= 32; /* Convert to upper case */
- c = (c << 4) + cc - ((cc < 'A')? '0' : ('A' - 10));
-#else /* EBCDIC coding */
- if (cc >= 'a' && cc <= 'z') cc += 64; /* Convert to upper case */
- c = (c << 4) + cc - ((cc >= '0')? '0' : ('A' - 10));
-#endif
- }
-
- if (*pt == '}')
- {
- if (c < 0 || count > (utf8? 8 : 2)) *errorcodeptr = ERR34;
- ptr = pt;
- break;
- }
-
- /* If the sequence of hex digits does not end with '}', then we don't
- recognize this construct; fall through to the normal \x handling. */
- }
-
- /* Read just a single-byte hex-defined char */
-
- c = 0;
- while (i++ < 2 && (digitab[ptr[1]] & ctype_xdigit) != 0)
- {
- int cc; /* Some compilers don't like ++ */
- cc = *(++ptr); /* in initializers */
-#ifndef EBCDIC /* ASCII coding */
- if (cc >= 'a') cc -= 32; /* Convert to upper case */
- c = c * 16 + cc - ((cc < 'A')? '0' : ('A' - 10));
-#else /* EBCDIC coding */
- if (cc <= 'z') cc += 64; /* Convert to upper case */
- c = c * 16 + cc - ((cc >= '0')? '0' : ('A' - 10));
-#endif
- }
- break;
-
- /* For \c, a following letter is upper-cased; then the 0x40 bit is flipped.
- This coding is ASCII-specific, but then the whole concept of \cx is
- ASCII-specific. (However, an EBCDIC equivalent has now been added.) */
-
- case 'c':
- c = *(++ptr);
- if (c == 0)
- {
- *errorcodeptr = ERR2;
- break;
- }
-
-#ifndef EBCDIC /* ASCII coding */
- if (c >= 'a' && c <= 'z') c -= 32;
- c ^= 0x40;
-#else /* EBCDIC coding */
- if (c >= 'a' && c <= 'z') c += 64;
- c ^= 0xC0;
-#endif
- break;
-
- /* PCRE_EXTRA enables extensions to Perl in the matter of escapes. Any
- other alphanumeric following \ is an error if PCRE_EXTRA was set;
- otherwise, for Perl compatibility, it is a literal. This code looks a bit
- odd, but there used to be some cases other than the default, and there may
- be again in future, so I haven't "optimized" it. */
-
- default:
- if ((options & PCRE_EXTRA) != 0) switch(c)
- {
- default:
- *errorcodeptr = ERR3;
- break;
- }
- break;
- }
- }
-
-*ptrptr = ptr;
-return c;
-}
-
-
-
-#ifdef SUPPORT_UCP
-/*************************************************
-* Handle \P and \p *
-*************************************************/
-
-/* This function is called after \P or \p has been encountered, provided that
-PCRE is compiled with support for Unicode properties. On entry, ptrptr is
-pointing at the P or p. On exit, it is pointing at the final character of the
-escape sequence.
-
-Argument:
- ptrptr points to the pattern position pointer
- negptr points to a boolean that is set TRUE for negation else FALSE
- dptr points to an int that is set to the detailed property value
- errorcodeptr points to the error code variable
-
-Returns: type value from ucp_type_table, or -1 for an invalid type
-*/
-
-static int
-get_ucp(const uschar **ptrptr, BOOL *negptr, int *dptr, int *errorcodeptr)
-{
-int c, i, bot, top;
-const uschar *ptr = *ptrptr;
-char name[32];
-
-c = *(++ptr);
-if (c == 0) goto ERROR_RETURN;
-
-*negptr = FALSE;
-
-/* \P or \p can be followed by a name in {}, optionally preceded by ^ for
-negation. */
-
-if (c == '{')
- {
- if (ptr[1] == '^')
- {
- *negptr = TRUE;
- ptr++;
- }
- for (i = 0; i < (int)sizeof(name) - 1; i++)
- {
- c = *(++ptr);
- if (c == 0) goto ERROR_RETURN;
- if (c == '}') break;
- name[i] = c;
- }
- if (c !='}') goto ERROR_RETURN;
- name[i] = 0;
- }
-
-/* Otherwise there is just one following character */
-
-else
- {
- name[0] = c;
- name[1] = 0;
- }
-
-*ptrptr = ptr;
-
-/* Search for a recognized property name using binary chop */
-
-bot = 0;
-top = _pcre_utt_size;
-
-while (bot < top)
- {
- i = (bot + top) >> 1;
- c = strcmp(name, _pcre_utt_names + _pcre_utt[i].name_offset);
- if (c == 0)
- {
- *dptr = _pcre_utt[i].value;
- return _pcre_utt[i].type;
- }
- if (c > 0) bot = i + 1; else top = i;
- }
-
-*errorcodeptr = ERR47;
-*ptrptr = ptr;
-return -1;
-
-ERROR_RETURN:
-*errorcodeptr = ERR46;
-*ptrptr = ptr;
-return -1;
-}
-#endif
-
-
-
-
-/*************************************************
-* Check for counted repeat *
-*************************************************/
-
-/* This function is called when a '{' is encountered in a place where it might
-start a quantifier. It looks ahead to see if it really is a quantifier or not.
-It is only a quantifier if it is one of the forms {ddd} {ddd,} or {ddd,ddd}
-where the ddds are digits.
-
-Arguments:
- p pointer to the first char after '{'
-
-Returns: TRUE or FALSE
-*/
-
-static BOOL
-is_counted_repeat(const uschar *p)
-{
-if ((digitab[*p++] & ctype_digit) == 0) return FALSE;
-while ((digitab[*p] & ctype_digit) != 0) p++;
-if (*p == '}') return TRUE;
-
-if (*p++ != ',') return FALSE;
-if (*p == '}') return TRUE;
-
-if ((digitab[*p++] & ctype_digit) == 0) return FALSE;
-while ((digitab[*p] & ctype_digit) != 0) p++;
-
-return (*p == '}');
-}
-
-
-
-/*************************************************
-* Read repeat counts *
-*************************************************/
-
-/* Read an item of the form {n,m} and return the values. This is called only
-after is_counted_repeat() has confirmed that a repeat-count quantifier exists,
-so the syntax is guaranteed to be correct, but we need to check the values.
-
-Arguments:
- p pointer to first char after '{'
- minp pointer to int for min
- maxp pointer to int for max
- returned as -1 if no max
- errorcodeptr points to error code variable
-
-Returns: pointer to '}' on success;
- current ptr on error, with errorcodeptr set non-zero
-*/
-
-static const uschar *
-read_repeat_counts(const uschar *p, int *minp, int *maxp, int *errorcodeptr)
-{
-int min = 0;
-int max = -1;
-
-/* Read the minimum value and do a paranoid check: a negative value indicates
-an integer overflow. */
-
-while ((digitab[*p] & ctype_digit) != 0) min = min * 10 + *p++ - '0';
-if (min < 0 || min > 65535)
- {
- *errorcodeptr = ERR5;
- return p;
- }
-
-/* Read the maximum value if there is one, and again do a paranoid on its size.
-Also, max must not be less than min. */
-
-if (*p == '}') max = min; else
- {
- if (*(++p) != '}')
- {
- max = 0;
- while((digitab[*p] & ctype_digit) != 0) max = max * 10 + *p++ - '0';
- if (max < 0 || max > 65535)
- {
- *errorcodeptr = ERR5;
- return p;
- }
- if (max < min)
- {
- *errorcodeptr = ERR4;
- return p;
- }
- }
- }
-
-/* Fill in the required variables, and pass back the pointer to the terminating
-'}'. */
-
-*minp = min;
-*maxp = max;
-return p;
-}
-
-
-
-/*************************************************
-* Find forward referenced subpattern *
-*************************************************/
-
-/* This function scans along a pattern's text looking for capturing
-subpatterns, and counting them. If it finds a named pattern that matches the
-name it is given, it returns its number. Alternatively, if the name is NULL, it
-returns when it reaches a given numbered subpattern. This is used for forward
-references to subpatterns. We know that if (?P< is encountered, the name will
-be terminated by '>' because that is checked in the first pass.
-
-Arguments:
- ptr current position in the pattern
- cd compile background data
- name name to seek, or NULL if seeking a numbered subpattern
- lorn name length, or subpattern number if name is NULL
- xmode TRUE if we are in /x mode
-
-Returns: the number of the named subpattern, or -1 if not found
-*/
-
-static int
-find_parens(const uschar *ptr, compile_data *cd, const uschar *name, int lorn,
- BOOL xmode)
-{
-const uschar *thisname;
-int count = cd->bracount;
-
-for (; *ptr != 0; ptr++)
- {
- int term;
-
- /* Skip over backslashed characters and also entire \Q...\E */
-
- if (*ptr == '\\')
- {
- if (*(++ptr) == 0) return -1;
- if (*ptr == 'Q') for (;;)
- {
- while (*(++ptr) != 0 && *ptr != '\\');
- if (*ptr == 0) return -1;
- if (*(++ptr) == 'E') break;
- }
- continue;
- }
-
- /* Skip over character classes; this logic must be similar to the way they
- are handled for real. If the first character is '^', skip it. Also, if the
- first few characters (either before or after ^) are \Q\E or \E we skip them
- too. This makes for compatibility with Perl. */
-
- if (*ptr == '[')
- {
- BOOL negate_class = FALSE;
- for (;;)
- {
- int c = *(++ptr);
- if (c == '\\')
- {
- if (ptr[1] == 'E') ptr++;
- else if (strncmp((const char *)ptr+1, "Q\\E", 3) == 0) ptr += 3;
- else break;
- }
- else if (!negate_class && c == '^')
- negate_class = TRUE;
- else break;
- }
-
- /* If the next character is ']', it is a data character that must be
- skipped, except in JavaScript compatibility mode. */
-
- if (ptr[1] == ']' && (cd->external_options & PCRE_JAVASCRIPT_COMPAT) == 0)
- ptr++;
-
- while (*(++ptr) != ']')
- {
- if (*ptr == 0) return -1;
- if (*ptr == '\\')
- {
- if (*(++ptr) == 0) return -1;
- if (*ptr == 'Q') for (;;)
- {
- while (*(++ptr) != 0 && *ptr != '\\');
- if (*ptr == 0) return -1;
- if (*(++ptr) == 'E') break;
- }
- continue;
- }
- }
- continue;
- }
-
- /* Skip comments in /x mode */
-
- if (xmode && *ptr == '#')
- {
- while (*(++ptr) != 0 && *ptr != '\n');
- if (*ptr == 0) return -1;
- continue;
- }
-
- /* An opening parens must now be a real metacharacter */
-
- if (*ptr != '(') continue;
- if (ptr[1] != '?' && ptr[1] != '*')
- {
- count++;
- if (name == NULL && count == lorn) return count;
- continue;
- }
-
- ptr += 2;
- if (*ptr == 'P') ptr++; /* Allow optional P */
-
- /* We have to disambiguate (?<! and (?<= from (?<name> */
-
- if ((*ptr != '<' || ptr[1] == '!' || ptr[1] == '=') &&
- *ptr != '\'')
- continue;
-
- count++;
-
- if (name == NULL && count == lorn) return count;
- term = *ptr++;
- if (term == '<') term = '>';
- thisname = ptr;
- while (*ptr != term) ptr++;
- if (name != NULL && lorn == ptr - thisname &&
- strncmp((const char *)name, (const char *)thisname, lorn) == 0)
- return count;
- }
-
-return -1;
-}
-
-
-
-/*************************************************
-* Find first significant op code *
-*************************************************/
-
-/* This is called by several functions that scan a compiled expression looking
-for a fixed first character, or an anchoring op code etc. It skips over things
-that do not influence this. For some calls, a change of option is important.
-For some calls, it makes sense to skip negative forward and all backward
-assertions, and also the \b assertion; for others it does not.
-
-Arguments:
- code pointer to the start of the group
- options pointer to external options
- optbit the option bit whose changing is significant, or
- zero if none are
- skipassert TRUE if certain assertions are to be skipped
-
-Returns: pointer to the first significant opcode
-*/
-
-static const uschar*
-first_significant_code(const uschar *code, int *options, int optbit,
- BOOL skipassert)
-{
-for (;;)
- {
- switch ((int)*code)
- {
- case OP_OPT:
- if (optbit > 0 && ((int)code[1] & optbit) != (*options & optbit))
- *options = (int)code[1];
- code += 2;
- break;
-
- case OP_ASSERT_NOT:
- case OP_ASSERTBACK:
- case OP_ASSERTBACK_NOT:
- if (!skipassert) return code;
- do code += GET(code, 1); while (*code == OP_ALT);
- code += _pcre_OP_lengths[*code];
- break;
-
- case OP_WORD_BOUNDARY:
- case OP_NOT_WORD_BOUNDARY:
- if (!skipassert) return code;
- /* Fall through */
-
- case OP_CALLOUT:
- case OP_CREF:
- case OP_RREF:
- case OP_DEF:
- code += _pcre_OP_lengths[*code];
- break;
-
- default:
- return code;
- }
- }
-/* Control never reaches here */
-}
-
-
-
-
-/*************************************************
-* Find the fixed length of a pattern *
-*************************************************/
-
-/* Scan a pattern and compute the fixed length of subject that will match it,
-if the length is fixed. This is needed for dealing with backward assertions.
-In UTF8 mode, the result is in characters rather than bytes.
-
-Arguments:
- code points to the start of the pattern (the bracket)
- options the compiling options
-
-Returns: the fixed length, or -1 if there is no fixed length,
- or -2 if \C was encountered
-*/
-
-static int
-find_fixedlength(uschar *code, int options)
-{
-int length = -1;
-
-register int branchlength = 0;
-register uschar *cc = code + 1 + LINK_SIZE;
-
-/* Scan along the opcodes for this branch. If we get to the end of the
-branch, check the length against that of the other branches. */
-
-for (;;)
- {
- int d;
- register int op = *cc;
- switch (op)
- {
- case OP_CBRA:
- case OP_BRA:
- case OP_ONCE:
- case OP_COND:
- d = find_fixedlength(cc + ((op == OP_CBRA)? 2:0), options);
- if (d < 0) return d;
- branchlength += d;
- do cc += GET(cc, 1); while (*cc == OP_ALT);
- cc += 1 + LINK_SIZE;
- break;
-
- /* Reached end of a branch; if it's a ket it is the end of a nested
- call. If it's ALT it is an alternation in a nested call. If it is
- END it's the end of the outer call. All can be handled by the same code. */
-
- case OP_ALT:
- case OP_KET:
- case OP_KETRMAX:
- case OP_KETRMIN:
- case OP_END:
- if (length < 0) length = branchlength;
- else if (length != branchlength) return -1;
- if (*cc != OP_ALT) return length;
- cc += 1 + LINK_SIZE;
- branchlength = 0;
- break;
-
- /* Skip over assertive subpatterns */
-
- case OP_ASSERT:
- case OP_ASSERT_NOT:
- case OP_ASSERTBACK:
- case OP_ASSERTBACK_NOT:
- do cc += GET(cc, 1); while (*cc == OP_ALT);
- /* Fall through */
-
- /* Skip over things that don't match chars */
-
- case OP_REVERSE:
- case OP_CREF:
- case OP_RREF:
- case OP_DEF:
- case OP_OPT:
- case OP_CALLOUT:
- case OP_SOD:
- case OP_SOM:
- case OP_EOD:
- case OP_EODN:
- case OP_CIRC:
- case OP_DOLL:
- case OP_NOT_WORD_BOUNDARY:
- case OP_WORD_BOUNDARY:
- cc += _pcre_OP_lengths[*cc];
- break;
-
- /* Handle literal characters */
-
- case OP_CHAR:
- case OP_CHARNC:
- case OP_NOT:
- branchlength++;
- cc += 2;
-#ifdef SUPPORT_UTF8
- if ((options & PCRE_UTF8) != 0)
- {
- while ((*cc & 0xc0) == 0x80) cc++;
- }
-#endif
- break;
-
- /* Handle exact repetitions. The count is already in characters, but we
- need to skip over a multibyte character in UTF8 mode. */
-
- case OP_EXACT:
- branchlength += GET2(cc,1);
- cc += 4;
-#ifdef SUPPORT_UTF8
- if ((options & PCRE_UTF8) != 0)
- {
- while((*cc & 0x80) == 0x80) cc++;
- }
-#endif
- break;
-
- case OP_TYPEEXACT:
- branchlength += GET2(cc,1);
- if (cc[3] == OP_PROP || cc[3] == OP_NOTPROP) cc += 2;
- cc += 4;
- break;
-
- /* Handle single-char matchers */
-
- case OP_PROP:
- case OP_NOTPROP:
- cc += 2;
- /* Fall through */
-
- case OP_NOT_DIGIT:
- case OP_DIGIT:
- case OP_NOT_WHITESPACE:
- case OP_WHITESPACE:
- case OP_NOT_WORDCHAR:
- case OP_WORDCHAR:
- case OP_ANY:
- case OP_ALLANY:
- branchlength++;
- cc++;
- break;
-
- /* The single-byte matcher isn't allowed */
-
- case OP_ANYBYTE:
- return -2;
-
- /* Check a class for variable quantification */
-
-#ifdef SUPPORT_UTF8
- case OP_XCLASS:
- cc += GET(cc, 1) - 33;
- /* Fall through */
-#endif
-
- case OP_CLASS:
- case OP_NCLASS:
- cc += 33;
-
- switch (*cc)
- {
- case OP_CRSTAR:
- case OP_CRMINSTAR:
- case OP_CRQUERY:
- case OP_CRMINQUERY:
- return -1;
-
- case OP_CRRANGE:
- case OP_CRMINRANGE:
- if (GET2(cc,1) != GET2(cc,3)) return -1;
- branchlength += GET2(cc,1);
- cc += 5;
- break;
-
- default:
- branchlength++;
- }
- break;
-
- /* Anything else is variable length */
-
- default:
- return -1;
- }
- }
-/* Control never gets here */
-}
-
-
-
-
-/*************************************************
-* Scan compiled regex for numbered bracket *
-*************************************************/
-
-/* This little function scans through a compiled pattern until it finds a
-capturing bracket with the given number.
-
-Arguments:
- code points to start of expression
- utf8 TRUE in UTF-8 mode
- number the required bracket number
-
-Returns: pointer to the opcode for the bracket, or NULL if not found
-*/
-
-static const uschar *
-find_bracket(const uschar *code, BOOL utf8, int number)
-{
-for (;;)
- {
- register int c = *code;
- if (c == OP_END) return NULL;
-
- /* XCLASS is used for classes that cannot be represented just by a bit
- map. This includes negated single high-valued characters. The length in
- the table is zero; the actual length is stored in the compiled code. */
-
- if (c == OP_XCLASS) code += GET(code, 1);
-
- /* Handle capturing bracket */
-
- else if (c == OP_CBRA)
- {
- int n = GET2(code, 1+LINK_SIZE);
- if (n == number) return (uschar *)code;
- code += _pcre_OP_lengths[c];
- }
-
- /* Otherwise, we can get the item's length from the table, except that for
- repeated character types, we have to test for \p and \P, which have an extra
- two bytes of parameters. */
-
- else
- {
- switch(c)
- {
- case OP_TYPESTAR:
- case OP_TYPEMINSTAR:
- case OP_TYPEPLUS:
- case OP_TYPEMINPLUS:
- case OP_TYPEQUERY:
- case OP_TYPEMINQUERY:
- case OP_TYPEPOSSTAR:
- case OP_TYPEPOSPLUS:
- case OP_TYPEPOSQUERY:
- if (code[1] == OP_PROP || code[1] == OP_NOTPROP) code += 2;
- break;
-
- case OP_TYPEUPTO:
- case OP_TYPEMINUPTO:
- case OP_TYPEEXACT:
- case OP_TYPEPOSUPTO:
- if (code[3] == OP_PROP || code[3] == OP_NOTPROP) code += 2;
- break;
- }
-
- /* Add in the fixed length from the table */
-
- code += _pcre_OP_lengths[c];
-
- /* In UTF-8 mode, opcodes that are followed by a character may be followed by
- a multi-byte character. The length in the table is a minimum, so we have to
- arrange to skip the extra bytes. */
-
-#ifdef SUPPORT_UTF8
- if (utf8) switch(c)
- {
- case OP_CHAR:
- case OP_CHARNC:
- case OP_EXACT:
- case OP_UPTO:
- case OP_MINUPTO:
- case OP_POSUPTO:
- case OP_STAR:
- case OP_MINSTAR:
- case OP_POSSTAR:
- case OP_PLUS:
- case OP_MINPLUS:
- case OP_POSPLUS:
- case OP_QUERY:
- case OP_MINQUERY:
- case OP_POSQUERY:
- if (code[-1] >= 0xc0) code += _pcre_utf8_table4[code[-1] & 0x3f];
- break;
- }
-#endif
- }
- }
-}
-
-
-
-/*************************************************
-* Scan compiled regex for recursion reference *
-*************************************************/
-
-/* This little function scans through a compiled pattern until it finds an
-instance of OP_RECURSE.
-
-Arguments:
- code points to start of expression
- utf8 TRUE in UTF-8 mode
-
-Returns: pointer to the opcode for OP_RECURSE, or NULL if not found
-*/
-
-static const uschar *
-find_recurse(const uschar *code, BOOL utf8)
-{
-for (;;)
- {
- register int c = *code;
- if (c == OP_END) return NULL;
- if (c == OP_RECURSE) return code;
-
- /* XCLASS is used for classes that cannot be represented just by a bit
- map. This includes negated single high-valued characters. The length in
- the table is zero; the actual length is stored in the compiled code. */
-
- if (c == OP_XCLASS) code += GET(code, 1);
-
- /* Otherwise, we can get the item's length from the table, except that for
- repeated character types, we have to test for \p and \P, which have an extra
- two bytes of parameters. */
-
- else
- {
- switch(c)
- {
- case OP_TYPESTAR:
- case OP_TYPEMINSTAR:
- case OP_TYPEPLUS:
- case OP_TYPEMINPLUS:
- case OP_TYPEQUERY:
- case OP_TYPEMINQUERY:
- case OP_TYPEPOSSTAR:
- case OP_TYPEPOSPLUS:
- case OP_TYPEPOSQUERY:
- if (code[1] == OP_PROP || code[1] == OP_NOTPROP) code += 2;
- break;
-
- case OP_TYPEPOSUPTO:
- case OP_TYPEUPTO:
- case OP_TYPEMINUPTO:
- case OP_TYPEEXACT:
- if (code[3] == OP_PROP || code[3] == OP_NOTPROP) code += 2;
- break;
- }
-
- /* Add in the fixed length from the table */
-
- code += _pcre_OP_lengths[c];
-
- /* In UTF-8 mode, opcodes that are followed by a character may be followed
- by a multi-byte character. The length in the table is a minimum, so we have
- to arrange to skip the extra bytes. */
-
-#ifdef SUPPORT_UTF8
- if (utf8) switch(c)
- {
- case OP_CHAR:
- case OP_CHARNC:
- case OP_EXACT:
- case OP_UPTO:
- case OP_MINUPTO:
- case OP_POSUPTO:
- case OP_STAR:
- case OP_MINSTAR:
- case OP_POSSTAR:
- case OP_PLUS:
- case OP_MINPLUS:
- case OP_POSPLUS:
- case OP_QUERY:
- case OP_MINQUERY:
- case OP_POSQUERY:
- if (code[-1] >= 0xc0) code += _pcre_utf8_table4[code[-1] & 0x3f];
- break;
- }
-#endif
- }
- }
-}
-
-
-
-/*************************************************
-* Scan compiled branch for non-emptiness *
-*************************************************/
-
-/* This function scans through a branch of a compiled pattern to see whether it
-can match the empty string or not. It is called from could_be_empty()
-below and from compile_branch() when checking for an unlimited repeat of a
-group that can match nothing. Note that first_significant_code() skips over
-backward and negative forward assertions when its final argument is TRUE. If we
-hit an unclosed bracket, we return "empty" - this means we've struck an inner
-bracket whose current branch will already have been scanned.
-
-Arguments:
- code points to start of search
- endcode points to where to stop
- utf8 TRUE if in UTF8 mode
-
-Returns: TRUE if what is matched could be empty
-*/
-
-static BOOL
-could_be_empty_branch(const uschar *code, const uschar *endcode, BOOL utf8)
-{
-register int c;
-for (code = first_significant_code(code + _pcre_OP_lengths[*code], NULL, 0, TRUE);
- code < endcode;
- code = first_significant_code(code + _pcre_OP_lengths[c], NULL, 0, TRUE))
- {
- const uschar *ccode;
-
- c = *code;
-
- /* Skip over forward assertions; the other assertions are skipped by
- first_significant_code() with a TRUE final argument. */
-
- if (c == OP_ASSERT)
- {
- do code += GET(code, 1); while (*code == OP_ALT);
- c = *code;
- continue;
- }
-
- /* Groups with zero repeats can of course be empty; skip them. */
-
- if (c == OP_BRAZERO || c == OP_BRAMINZERO || c == OP_SKIPZERO)
- {
- code += _pcre_OP_lengths[c];
- do code += GET(code, 1); while (*code == OP_ALT);
- c = *code;
- continue;
- }
-
- /* For other groups, scan the branches. */
-
- if (c == OP_BRA || c == OP_CBRA || c == OP_ONCE || c == OP_COND)
- {
- BOOL empty_branch;
- if (GET(code, 1) == 0) return TRUE; /* Hit unclosed bracket */
-
- /* Scan a closed bracket */
-
- empty_branch = FALSE;
- do
- {
- if (!empty_branch && could_be_empty_branch(code, endcode, utf8))
- empty_branch = TRUE;
- code += GET(code, 1);
- }
- while (*code == OP_ALT);
- if (!empty_branch) return FALSE; /* All branches are non-empty */
- c = *code;
- continue;
- }
-
- /* Handle the other opcodes */
-
- switch (c)
- {
- /* Check for quantifiers after a class. XCLASS is used for classes that
- cannot be represented just by a bit map. This includes negated single
- high-valued characters. The length in _pcre_OP_lengths[] is zero; the
- actual length is stored in the compiled code, so we must update "code"
- here. */
-
-#ifdef SUPPORT_UTF8
- case OP_XCLASS:
- ccode = code += GET(code, 1);
- goto CHECK_CLASS_REPEAT;
-#endif
-
- case OP_CLASS:
- case OP_NCLASS:
- ccode = code + 33;
-
-#ifdef SUPPORT_UTF8
- CHECK_CLASS_REPEAT:
-#endif
-
- switch (*ccode)
- {
- case OP_CRSTAR: /* These could be empty; continue */
- case OP_CRMINSTAR:
- case OP_CRQUERY:
- case OP_CRMINQUERY:
- break;
-
- default: /* Non-repeat => class must match */
- case OP_CRPLUS: /* These repeats aren't empty */
- case OP_CRMINPLUS:
- return FALSE;
-
- case OP_CRRANGE:
- case OP_CRMINRANGE:
- if (GET2(ccode, 1) > 0) return FALSE; /* Minimum > 0 */
- break;
- }
- break;
-
- /* Opcodes that must match a character */
-
- case OP_PROP:
- case OP_NOTPROP:
- case OP_EXTUNI:
- case OP_NOT_DIGIT:
- case OP_DIGIT:
- case OP_NOT_WHITESPACE:
- case OP_WHITESPACE:
- case OP_NOT_WORDCHAR:
- case OP_WORDCHAR:
- case OP_ANY:
- case OP_ALLANY:
- case OP_ANYBYTE:
- case OP_CHAR:
- case OP_CHARNC:
- case OP_NOT:
- case OP_PLUS:
- case OP_MINPLUS:
- case OP_POSPLUS:
- case OP_EXACT:
- case OP_NOTPLUS:
- case OP_NOTMINPLUS:
- case OP_NOTPOSPLUS:
- case OP_NOTEXACT:
- case OP_TYPEPLUS:
- case OP_TYPEMINPLUS:
- case OP_TYPEPOSPLUS:
- case OP_TYPEEXACT:
- return FALSE;
-
- /* These are going to continue, as they may be empty, but we have to
- fudge the length for the \p and \P cases. */
-
- case OP_TYPESTAR:
- case OP_TYPEMINSTAR:
- case OP_TYPEPOSSTAR:
- case OP_TYPEQUERY:
- case OP_TYPEMINQUERY:
- case OP_TYPEPOSQUERY:
- if (code[1] == OP_PROP || code[1] == OP_NOTPROP) code += 2;
- break;
-
- /* Same for these */
-
- case OP_TYPEUPTO:
- case OP_TYPEMINUPTO:
- case OP_TYPEPOSUPTO:
- if (code[3] == OP_PROP || code[3] == OP_NOTPROP) code += 2;
- break;
-
- /* End of branch */
-
- case OP_KET:
- case OP_KETRMAX:
- case OP_KETRMIN:
- case OP_ALT:
- return TRUE;
-
- /* In UTF-8 mode, STAR, MINSTAR, POSSTAR, QUERY, MINQUERY, POSQUERY, UPTO,
- MINUPTO, and POSUPTO may be followed by a multibyte character */
-
-#ifdef SUPPORT_UTF8
- case OP_STAR:
- case OP_MINSTAR:
- case OP_POSSTAR:
- case OP_QUERY:
- case OP_MINQUERY:
- case OP_POSQUERY:
- case OP_UPTO:
- case OP_MINUPTO:
- case OP_POSUPTO:
- if (utf8) while ((code[2] & 0xc0) == 0x80) code++;
- break;
-#endif
- }
- }
-
-return TRUE;
-}
-
-
-
-/*************************************************
-* Scan compiled regex for non-emptiness *
-*************************************************/
-
-/* This function is called to check for left recursive calls. We want to check
-the current branch of the current pattern to see if it could match the empty
-string. If it could, we must look outwards for branches at other levels,
-stopping when we pass beyond the bracket which is the subject of the recursion.
-
-Arguments:
- code points to start of the recursion
- endcode points to where to stop (current RECURSE item)
- bcptr points to the chain of current (unclosed) branch starts
- utf8 TRUE if in UTF-8 mode
-
-Returns: TRUE if what is matched could be empty
-*/
-
-static BOOL
-could_be_empty(const uschar *code, const uschar *endcode, branch_chain *bcptr,
- BOOL utf8)
-{
-while (bcptr != NULL && bcptr->current >= code)
- {
- if (!could_be_empty_branch(bcptr->current, endcode, utf8)) return FALSE;
- bcptr = bcptr->outer;
- }
-return TRUE;
-}
-
-
-
-/*************************************************
-* Check for POSIX class syntax *
-*************************************************/
-
-/* This function is called when the sequence "[:" or "[." or "[=" is
-encountered in a character class. It checks whether this is followed by a
-sequence of characters terminated by a matching ":]" or ".]" or "=]". If we
-reach an unescaped ']' without the special preceding character, return FALSE.
-
-Originally, this function only recognized a sequence of letters between the
-terminators, but it seems that Perl recognizes any sequence of characters,
-though of course unknown POSIX names are subsequently rejected. Perl gives an
-"Unknown POSIX class" error for [:f\oo:] for example, where previously PCRE
-didn't consider this to be a POSIX class. Likewise for [:1234:].
-
-The problem in trying to be exactly like Perl is in the handling of escapes. We
-have to be sure that [abc[:x\]pqr] is *not* treated as containing a POSIX
-class, but [abc[:x\]pqr:]] is (so that an error can be generated). The code
-below handles the special case of \], but does not try to do any other escape
-processing. This makes it different from Perl for cases such as [:l\ower:]
-where Perl recognizes it as the POSIX class "lower" but PCRE does not recognize
-"l\ower". This is a lesser evil that not diagnosing bad classes when Perl does,
-I think.
-
-Arguments:
- ptr pointer to the initial [
- endptr where to return the end pointer
-
-Returns: TRUE or FALSE
-*/
-
-static BOOL
-check_posix_syntax(const uschar *ptr, const uschar **endptr)
-{
-int terminator; /* Don't combine these lines; the Solaris cc */
-terminator = *(++ptr); /* compiler warns about "non-constant" initializer. */
-for (++ptr; *ptr != 0; ptr++)
- {
- if (*ptr == '\\' && ptr[1] == ']') ptr++; else
- {
- if (*ptr == ']') return FALSE;
- if (*ptr == terminator && ptr[1] == ']')
- {
- *endptr = ptr;
- return TRUE;
- }
- }
- }
-return FALSE;
-}
-
-
-
-
-/*************************************************
-* Check POSIX class name *
-*************************************************/
-
-/* This function is called to check the name given in a POSIX-style class entry
-such as [:alnum:].
-
-Arguments:
- ptr points to the first letter
- len the length of the name
-
-Returns: a value representing the name, or -1 if unknown
-*/
-
-static int
-check_posix_name(const uschar *ptr, int len)
-{
-const char *pn = posix_names;
-register int yield = 0;
-while (posix_name_lengths[yield] != 0)
- {
- if (len == posix_name_lengths[yield] &&
- strncmp((const char *)ptr, pn, len) == 0) return yield;
- pn += posix_name_lengths[yield] + 1;
- yield++;
- }
-return -1;
-}
-
-
-/*************************************************
-* Adjust OP_RECURSE items in repeated group *
-*************************************************/
-
-/* OP_RECURSE items contain an offset from the start of the regex to the group
-that is referenced. This means that groups can be replicated for fixed
-repetition simply by copying (because the recursion is allowed to refer to
-earlier groups that are outside the current group). However, when a group is
-optional (i.e. the minimum quantifier is zero), OP_BRAZERO or OP_SKIPZERO is
-inserted before it, after it has been compiled. This means that any OP_RECURSE
-items within it that refer to the group itself or any contained groups have to
-have their offsets adjusted. That one of the jobs of this function. Before it
-is called, the partially compiled regex must be temporarily terminated with
-OP_END.
-
-This function has been extended with the possibility of forward references for
-recursions and subroutine calls. It must also check the list of such references
-for the group we are dealing with. If it finds that one of the recursions in
-the current group is on this list, it adjusts the offset in the list, not the
-value in the reference (which is a group number).
-
-Arguments:
- group points to the start of the group
- adjust the amount by which the group is to be moved
- utf8 TRUE in UTF-8 mode
- cd contains pointers to tables etc.
- save_hwm the hwm forward reference pointer at the start of the group
-
-Returns: nothing
-*/
-
-static void
-adjust_recurse(uschar *group, int adjust, BOOL utf8, compile_data *cd,
- uschar *save_hwm)
-{
-uschar *ptr = group;
-
-while ((ptr = (uschar *)find_recurse(ptr, utf8)) != NULL)
- {
- int offset;
- uschar *hc;
-
- /* See if this recursion is on the forward reference list. If so, adjust the
- reference. */
-
- for (hc = save_hwm; hc < cd->hwm; hc += LINK_SIZE)
- {
- offset = GET(hc, 0);
- if (cd->start_code + offset == ptr + 1)
- {
- PUT(hc, 0, offset + adjust);
- break;
- }
- }
-
- /* Otherwise, adjust the recursion offset if it's after the start of this
- group. */
-
- if (hc >= cd->hwm)
- {
- offset = GET(ptr, 1);
- if (cd->start_code + offset >= group) PUT(ptr, 1, offset + adjust);
- }
-
- ptr += 1 + LINK_SIZE;
- }
-}
-
-
-
-/*************************************************
-* Insert an automatic callout point *
-*************************************************/
-
-/* This function is called when the PCRE_AUTO_CALLOUT option is set, to insert
-callout points before each pattern item.
-
-Arguments:
- code current code pointer
- ptr current pattern pointer
- cd pointers to tables etc
-
-Returns: new code pointer
-*/
-
-static uschar *
-auto_callout(uschar *code, const uschar *ptr, compile_data *cd)
-{
-*code++ = OP_CALLOUT;
-*code++ = 255;
-PUT(code, 0, ptr - cd->start_pattern); /* Pattern offset */
-PUT(code, LINK_SIZE, 0); /* Default length */
-return code + 2*LINK_SIZE;
-}
-
-
-
-/*************************************************
-* Complete a callout item *
-*************************************************/
-
-/* A callout item contains the length of the next item in the pattern, which
-we can't fill in till after we have reached the relevant point. This is used
-for both automatic and manual callouts.
-
-Arguments:
- previous_callout points to previous callout item
- ptr current pattern pointer
- cd pointers to tables etc
-
-Returns: nothing
-*/
-
-static void
-complete_callout(uschar *previous_callout, const uschar *ptr, compile_data *cd)
-{
-int length = ptr - cd->start_pattern - GET(previous_callout, 2);
-PUT(previous_callout, 2 + LINK_SIZE, length);
-}
-
-
-
-#ifdef SUPPORT_UCP
-/*************************************************
-* Get othercase range *
-*************************************************/
-
-/* This function is passed the start and end of a class range, in UTF-8 mode
-with UCP support. It searches up the characters, looking for internal ranges of
-characters in the "other" case. Each call returns the next one, updating the
-start address.
-
-Arguments:
- cptr points to starting character value; updated
- d end value
- ocptr where to put start of othercase range
- odptr where to put end of othercase range
-
-Yield: TRUE when range returned; FALSE when no more
-*/
-
-static BOOL
-get_othercase_range(unsigned int *cptr, unsigned int d, unsigned int *ocptr,
- unsigned int *odptr)
-{
-unsigned int c, othercase, next;
-
-for (c = *cptr; c <= d; c++)
- { if ((othercase = _pcre_ucp_othercase(c)) != NOTACHAR) break; }
-
-if (c > d) return FALSE;
-
-*ocptr = othercase;
-next = othercase + 1;
-
-for (++c; c <= d; c++)
- {
- if (_pcre_ucp_othercase(c) != next) break;
- next++;
- }
-
-*odptr = next - 1;
-*cptr = c;
-
-return TRUE;
-}
-#endif /* SUPPORT_UCP */
-
-
-
-/*************************************************
-* Check if auto-possessifying is possible *
-*************************************************/
-
-/* This function is called for unlimited repeats of certain items, to see
-whether the next thing could possibly match the repeated item. If not, it makes
-sense to automatically possessify the repeated item.
-
-Arguments:
- op_code the repeated op code
- this data for this item, depends on the opcode
- utf8 TRUE in UTF-8 mode
- utf8_char used for utf8 character bytes, NULL if not relevant
- ptr next character in pattern
- options options bits
- cd contains pointers to tables etc.
-
-Returns: TRUE if possessifying is wanted
-*/
-
-static BOOL
-check_auto_possessive(int op_code, int item, BOOL utf8, uschar *utf8_char,
- const uschar *ptr, int options, compile_data *cd)
-{
-int next;
-
-/* Skip whitespace and comments in extended mode */
-
-if ((options & PCRE_EXTENDED) != 0)
- {
- for (;;)
- {
- while ((cd->ctypes[*ptr] & ctype_space) != 0) ptr++;
- if (*ptr == '#')
- {
- while (*(++ptr) != 0)
- if (IS_NEWLINE(ptr)) { ptr += cd->nllen; break; }
- }
- else break;
- }
- }
-
-/* If the next item is one that we can handle, get its value. A non-negative
-value is a character, a negative value is an escape value. */
-
-if (*ptr == '\\')
- {
- int temperrorcode = 0;
- next = check_escape(&ptr, &temperrorcode, cd->bracount, options, FALSE);
- if (temperrorcode != 0) return FALSE;
- ptr++; /* Point after the escape sequence */
- }
-
-else if ((cd->ctypes[*ptr] & ctype_meta) == 0)
- {
-#ifdef SUPPORT_UTF8
- if (utf8) { GETCHARINC(next, ptr); } else
-#endif
- next = *ptr++;
- }
-
-else return FALSE;
-
-/* Skip whitespace and comments in extended mode */
-
-if ((options & PCRE_EXTENDED) != 0)
- {
- for (;;)
- {
- while ((cd->ctypes[*ptr] & ctype_space) != 0) ptr++;
- if (*ptr == '#')
- {
- while (*(++ptr) != 0)
- if (IS_NEWLINE(ptr)) { ptr += cd->nllen; break; }
- }
- else break;
- }
- }
-
-/* If the next thing is itself optional, we have to give up. */
-
-if (*ptr == '*' || *ptr == '?' || strncmp((char *)ptr, "{0,", 3) == 0)
- return FALSE;
-
-/* Now compare the next item with the previous opcode. If the previous is a
-positive single character match, "item" either contains the character or, if
-"item" is greater than 127 in utf8 mode, the character's bytes are in
-utf8_char. */
-
-
-/* Handle cases when the next item is a character. */
-
-if (next >= 0) switch(op_code)
- {
- case OP_CHAR:
-#ifdef SUPPORT_UTF8
- if (utf8 && item > 127) { GETCHAR(item, utf8_char); }
-#endif
- return item != next;
-
- /* For CHARNC (caseless character) we must check the other case. If we have
- Unicode property support, we can use it to test the other case of
- high-valued characters. */
-
- case OP_CHARNC:
-#ifdef SUPPORT_UTF8
- if (utf8 && item > 127) { GETCHAR(item, utf8_char); }
-#endif
- if (item == next) return FALSE;
-#ifdef SUPPORT_UTF8
- if (utf8)
- {
- unsigned int othercase;
- if (next < 128) othercase = cd->fcc[next]; else
-#ifdef SUPPORT_UCP
- othercase = _pcre_ucp_othercase((unsigned int)next);
-#else
- othercase = NOTACHAR;
-#endif
- return (unsigned int)item != othercase;
- }
- else
-#endif /* SUPPORT_UTF8 */
- return (item != cd->fcc[next]); /* Non-UTF-8 mode */
-
- /* For OP_NOT, "item" must be a single-byte character. */
-
- case OP_NOT:
- if (item == next) return TRUE;
- if ((options & PCRE_CASELESS) == 0) return FALSE;
-#ifdef SUPPORT_UTF8
- if (utf8)
- {
- unsigned int othercase;
- if (next < 128) othercase = cd->fcc[next]; else
-#ifdef SUPPORT_UCP
- othercase = _pcre_ucp_othercase(next);
-#else
- othercase = NOTACHAR;
-#endif
- return (unsigned int)item == othercase;
- }
- else
-#endif /* SUPPORT_UTF8 */
- return (item == cd->fcc[next]); /* Non-UTF-8 mode */
-
- case OP_DIGIT:
- return next > 127 || (cd->ctypes[next] & ctype_digit) == 0;
-
- case OP_NOT_DIGIT:
- return next <= 127 && (cd->ctypes[next] & ctype_digit) != 0;
-
- case OP_WHITESPACE:
- return next > 127 || (cd->ctypes[next] & ctype_space) == 0;
-
- case OP_NOT_WHITESPACE:
- return next <= 127 && (cd->ctypes[next] & ctype_space) != 0;
-
- case OP_WORDCHAR:
- return next > 127 || (cd->ctypes[next] & ctype_word) == 0;
-
- case OP_NOT_WORDCHAR:
- return next <= 127 && (cd->ctypes[next] & ctype_word) != 0;
-
- case OP_HSPACE:
- case OP_NOT_HSPACE:
- switch(next)
- {
- case 0x09:
- case 0x20:
- case 0xa0:
- case 0x1680:
- case 0x180e:
- case 0x2000:
- case 0x2001:
- case 0x2002:
- case 0x2003:
- case 0x2004:
- case 0x2005:
- case 0x2006:
- case 0x2007:
- case 0x2008:
- case 0x2009:
- case 0x200A:
- case 0x202f:
- case 0x205f:
- case 0x3000:
- return op_code != OP_HSPACE;
- default:
- return op_code == OP_HSPACE;
- }
-
- case OP_VSPACE:
- case OP_NOT_VSPACE:
- switch(next)
- {
- case 0x0a:
- case 0x0b:
- case 0x0c:
- case 0x0d:
- case 0x85:
- case 0x2028:
- case 0x2029:
- return op_code != OP_VSPACE;
- default:
- return op_code == OP_VSPACE;
- }
-
- default:
- return FALSE;
- }
-
-
-/* Handle the case when the next item is \d, \s, etc. */
-
-switch(op_code)
- {
- case OP_CHAR:
- case OP_CHARNC:
-#ifdef SUPPORT_UTF8
- if (utf8 && item > 127) { GETCHAR(item, utf8_char); }
-#endif
- switch(-next)
- {
- case ESC_d:
- return item > 127 || (cd->ctypes[item] & ctype_digit) == 0;
-
- case ESC_D:
- return item <= 127 && (cd->ctypes[item] & ctype_digit) != 0;
-
- case ESC_s:
- return item > 127 || (cd->ctypes[item] & ctype_space) == 0;
-
- case ESC_S:
- return item <= 127 && (cd->ctypes[item] & ctype_space) != 0;
-
- case ESC_w:
- return item > 127 || (cd->ctypes[item] & ctype_word) == 0;
-
- case ESC_W:
- return item <= 127 && (cd->ctypes[item] & ctype_word) != 0;
-
- case ESC_h:
- case ESC_H:
- switch(item)
- {
- case 0x09:
- case 0x20:
- case 0xa0:
- case 0x1680:
- case 0x180e:
- case 0x2000:
- case 0x2001:
- case 0x2002:
- case 0x2003:
- case 0x2004:
- case 0x2005:
- case 0x2006:
- case 0x2007:
- case 0x2008:
- case 0x2009:
- case 0x200A:
- case 0x202f:
- case 0x205f:
- case 0x3000:
- return -next != ESC_h;
- default:
- return -next == ESC_h;
- }
-
- case ESC_v:
- case ESC_V:
- switch(item)
- {
- case 0x0a:
- case 0x0b:
- case 0x0c:
- case 0x0d:
- case 0x85:
- case 0x2028:
- case 0x2029:
- return -next != ESC_v;
- default:
- return -next == ESC_v;
- }
-
- default:
- return FALSE;
- }
-
- case OP_DIGIT:
- return next == -ESC_D || next == -ESC_s || next == -ESC_W ||
- next == -ESC_h || next == -ESC_v;
-
- case OP_NOT_DIGIT:
- return next == -ESC_d;
-
- case OP_WHITESPACE:
- return next == -ESC_S || next == -ESC_d || next == -ESC_w;
-
- case OP_NOT_WHITESPACE:
- return next == -ESC_s || next == -ESC_h || next == -ESC_v;
-
- case OP_HSPACE:
- return next == -ESC_S || next == -ESC_H || next == -ESC_d || next == -ESC_w;
-
- case OP_NOT_HSPACE:
- return next == -ESC_h;
-
- /* Can't have \S in here because VT matches \S (Perl anomaly) */
- case OP_VSPACE:
- return next == -ESC_V || next == -ESC_d || next == -ESC_w;
-
- case OP_NOT_VSPACE:
- return next == -ESC_v;
-
- case OP_WORDCHAR:
- return next == -ESC_W || next == -ESC_s || next == -ESC_h || next == -ESC_v;
-
- case OP_NOT_WORDCHAR:
- return next == -ESC_w || next == -ESC_d;
-
- default:
- return FALSE;
- }
-
-/* Control does not reach here */
-}
-
-
-
-/*************************************************
-* Compile one branch *
-*************************************************/
-
-/* Scan the pattern, compiling it into the a vector. If the options are
-changed during the branch, the pointer is used to change the external options
-bits. This function is used during the pre-compile phase when we are trying
-to find out the amount of memory needed, as well as during the real compile
-phase. The value of lengthptr distinguishes the two phases.
-
-Arguments:
- optionsptr pointer to the option bits
- codeptr points to the pointer to the current code point
- ptrptr points to the current pattern pointer
- errorcodeptr points to error code variable
- firstbyteptr set to initial literal character, or < 0 (REQ_UNSET, REQ_NONE)
- reqbyteptr set to the last literal character required, else < 0
- bcptr points to current branch chain
- cd contains pointers to tables etc.
- lengthptr NULL during the real compile phase
- points to length accumulator during pre-compile phase
-
-Returns: TRUE on success
- FALSE, with *errorcodeptr set non-zero on error
-*/
-
-static BOOL
-compile_branch(int *optionsptr, uschar **codeptr, const uschar **ptrptr,
- int *errorcodeptr, int *firstbyteptr, int *reqbyteptr, branch_chain *bcptr,
- compile_data *cd, int *lengthptr)
-{
-int repeat_type, op_type;
-int repeat_min = 0, repeat_max = 0; /* To please picky compilers */
-int bravalue = 0;
-int greedy_default, greedy_non_default;
-int firstbyte, reqbyte;
-int zeroreqbyte, zerofirstbyte;
-int req_caseopt, reqvary, tempreqvary;
-int options = *optionsptr;
-int after_manual_callout = 0;
-int length_prevgroup = 0;
-register int c;
-register uschar *code = *codeptr;
-uschar *last_code = code;
-uschar *orig_code = code;
-uschar *tempcode;
-BOOL inescq = FALSE;
-BOOL groupsetfirstbyte = FALSE;
-const uschar *ptr = *ptrptr;
-const uschar *tempptr;
-uschar *previous = NULL;
-uschar *previous_callout = NULL;
-uschar *save_hwm = NULL;
-uschar classbits[32];
-
-#ifdef SUPPORT_UTF8
-BOOL class_utf8;
-BOOL utf8 = (options & PCRE_UTF8) != 0;
-uschar *class_utf8data;
-uschar *class_utf8data_base;
-uschar utf8_char[6];
-#else
-BOOL utf8 = FALSE;
-uschar *utf8_char = NULL;
-#endif
-
-#ifdef DEBUG
-if (lengthptr != NULL) DPRINTF((">> start branch\n"));
-#endif
-
-/* Set up the default and non-default settings for greediness */
-
-greedy_default = ((options & PCRE_UNGREEDY) != 0);
-greedy_non_default = greedy_default ^ 1;
-
-/* Initialize no first byte, no required byte. REQ_UNSET means "no char
-matching encountered yet". It gets changed to REQ_NONE if we hit something that
-matches a non-fixed char first char; reqbyte just remains unset if we never
-find one.
-
-When we hit a repeat whose minimum is zero, we may have to adjust these values
-to take the zero repeat into account. This is implemented by setting them to
-zerofirstbyte and zeroreqbyte when such a repeat is encountered. The individual
-item types that can be repeated set these backoff variables appropriately. */
-
-firstbyte = reqbyte = zerofirstbyte = zeroreqbyte = REQ_UNSET;
-
-/* The variable req_caseopt contains either the REQ_CASELESS value or zero,
-according to the current setting of the caseless flag. REQ_CASELESS is a bit
-value > 255. It is added into the firstbyte or reqbyte variables to record the
-case status of the value. This is used only for ASCII characters. */
-
-req_caseopt = ((options & PCRE_CASELESS) != 0)? REQ_CASELESS : 0;
-
-/* Switch on next character until the end of the branch */
-
-for (;; ptr++)
- {
- BOOL negate_class;
- BOOL should_flip_negation;
- BOOL possessive_quantifier;
- BOOL is_quantifier;
- BOOL is_recurse;
- BOOL reset_bracount;
- int class_charcount;
- int class_lastchar;
- int newoptions;
- int recno;
- int refsign;
- int skipbytes;
- int subreqbyte;
- int subfirstbyte;
- int terminator;
- int mclength;
- uschar mcbuffer[8];
-
- /* Get next byte in the pattern */
-
- c = *ptr;
-
- /* If we are in the pre-compile phase, accumulate the length used for the
- previous cycle of this loop. */
-
- if (lengthptr != NULL)
- {
-#ifdef DEBUG
- if (code > cd->hwm) cd->hwm = code; /* High water info */
-#endif
- if (code > cd->start_workspace + COMPILE_WORK_SIZE) /* Check for overrun */
- {
- *errorcodeptr = ERR52;
- goto FAILED;
- }
-
- /* There is at least one situation where code goes backwards: this is the
- case of a zero quantifier after a class (e.g. [ab]{0}). At compile time,
- the class is simply eliminated. However, it is created first, so we have to
- allow memory for it. Therefore, don't ever reduce the length at this point.
- */
-
- if (code < last_code) code = last_code;
-
- /* Paranoid check for integer overflow */
-
- if (OFLOW_MAX - *lengthptr < code - last_code)
- {
- *errorcodeptr = ERR20;
- goto FAILED;
- }
-
- *lengthptr += code - last_code;
- DPRINTF(("length=%d added %d c=%c\n", *lengthptr, code - last_code, c));
-
- /* If "previous" is set and it is not at the start of the work space, move
- it back to there, in order to avoid filling up the work space. Otherwise,
- if "previous" is NULL, reset the current code pointer to the start. */
-
- if (previous != NULL)
- {
- if (previous > orig_code)
- {
- memmove(orig_code, previous, code - previous);
- code -= previous - orig_code;
- previous = orig_code;
- }
- }
- else code = orig_code;
-
- /* Remember where this code item starts so we can pick up the length
- next time round. */
-
- last_code = code;
- }
-
- /* In the real compile phase, just check the workspace used by the forward
- reference list. */
-
- else if (cd->hwm > cd->start_workspace + COMPILE_WORK_SIZE)
- {
- *errorcodeptr = ERR52;
- goto FAILED;
- }
-
- /* If in \Q...\E, check for the end; if not, we have a literal */
-
- if (inescq && c != 0)
- {
- if (c == '\\' && ptr[1] == 'E')
- {
- inescq = FALSE;
- ptr++;
- continue;
- }
- else
- {
- if (previous_callout != NULL)
- {
- if (lengthptr == NULL) /* Don't attempt in pre-compile phase */
- complete_callout(previous_callout, ptr, cd);
- previous_callout = NULL;
- }
- if ((options & PCRE_AUTO_CALLOUT) != 0)
- {
- previous_callout = code;
- code = auto_callout(code, ptr, cd);
- }
- goto NORMAL_CHAR;
- }
- }
-
- /* Fill in length of a previous callout, except when the next thing is
- a quantifier. */
-
- is_quantifier = c == '*' || c == '+' || c == '?' ||
- (c == '{' && is_counted_repeat(ptr+1));
-
- if (!is_quantifier && previous_callout != NULL &&
- after_manual_callout-- <= 0)
- {
- if (lengthptr == NULL) /* Don't attempt in pre-compile phase */
- complete_callout(previous_callout, ptr, cd);
- previous_callout = NULL;
- }
-
- /* In extended mode, skip white space and comments */
-
- if ((options & PCRE_EXTENDED) != 0)
- {
- if ((cd->ctypes[c] & ctype_space) != 0) continue;
- if (c == '#')
- {
- while (*(++ptr) != 0)
- {
- if (IS_NEWLINE(ptr)) { ptr += cd->nllen - 1; break; }
- }
- if (*ptr != 0) continue;
-
- /* Else fall through to handle end of string */
- c = 0;
- }
- }
-
- /* No auto callout for quantifiers. */
-
- if ((options & PCRE_AUTO_CALLOUT) != 0 && !is_quantifier)
- {
- previous_callout = code;
- code = auto_callout(code, ptr, cd);
- }
-
- switch(c)
- {
- /* ===================================================================*/
- case 0: /* The branch terminates at string end */
- case '|': /* or | or ) */
- case ')':
- *firstbyteptr = firstbyte;
- *reqbyteptr = reqbyte;
- *codeptr = code;
- *ptrptr = ptr;
- if (lengthptr != NULL)
- {
- if (OFLOW_MAX - *lengthptr < code - last_code)
- {
- *errorcodeptr = ERR20;
- goto FAILED;
- }
- *lengthptr += code - last_code; /* To include callout length */
- DPRINTF((">> end branch\n"));
- }
- return TRUE;
-
-
- /* ===================================================================*/
- /* Handle single-character metacharacters. In multiline mode, ^ disables
- the setting of any following char as a first character. */
-
- case '^':
- if ((options & PCRE_MULTILINE) != 0)
- {
- if (firstbyte == REQ_UNSET) firstbyte = REQ_NONE;
- }
- previous = NULL;
- *code++ = OP_CIRC;
- break;
-
- case '$':
- previous = NULL;
- *code++ = OP_DOLL;
- break;
-
- /* There can never be a first char if '.' is first, whatever happens about
- repeats. The value of reqbyte doesn't change either. */
-
- case '.':
- if (firstbyte == REQ_UNSET) firstbyte = REQ_NONE;
- zerofirstbyte = firstbyte;
- zeroreqbyte = reqbyte;
- previous = code;
- *code++ = ((options & PCRE_DOTALL) != 0)? OP_ALLANY: OP_ANY;
- break;
-
-
- /* ===================================================================*/
- /* Character classes. If the included characters are all < 256, we build a
- 32-byte bitmap of the permitted characters, except in the special case
- where there is only one such character. For negated classes, we build the
- map as usual, then invert it at the end. However, we use a different opcode
- so that data characters > 255 can be handled correctly.
-
- If the class contains characters outside the 0-255 range, a different
- opcode is compiled. It may optionally have a bit map for characters < 256,
- but those above are are explicitly listed afterwards. A flag byte tells
- whether the bitmap is present, and whether this is a negated class or not.
-
- In JavaScript compatibility mode, an isolated ']' causes an error. In
- default (Perl) mode, it is treated as a data character. */
-
- case ']':
- if ((cd->external_options & PCRE_JAVASCRIPT_COMPAT) != 0)
- {
- *errorcodeptr = ERR64;
- goto FAILED;
- }
- goto NORMAL_CHAR;
-
- case '[':
- previous = code;
-
- /* PCRE supports POSIX class stuff inside a class. Perl gives an error if
- they are encountered at the top level, so we'll do that too. */
-
- if ((ptr[1] == ':' || ptr[1] == '.' || ptr[1] == '=') &&
- check_posix_syntax(ptr, &tempptr))
- {
- *errorcodeptr = (ptr[1] == ':')? ERR13 : ERR31;
- goto FAILED;
- }
-
- /* If the first character is '^', set the negation flag and skip it. Also,
- if the first few characters (either before or after ^) are \Q\E or \E we
- skip them too. This makes for compatibility with Perl. */
-
- negate_class = FALSE;
- for (;;)
- {
- c = *(++ptr);
- if (c == '\\')
- {
- if (ptr[1] == 'E') ptr++;
- else if (strncmp((const char *)ptr+1, "Q\\E", 3) == 0) ptr += 3;
- else break;
- }
- else if (!negate_class && c == '^')
- negate_class = TRUE;
- else break;
- }
-
- /* Empty classes are allowed in JavaScript compatibility mode. Otherwise,
- an initial ']' is taken as a data character -- the code below handles
- that. In JS mode, [] must always fail, so generate OP_FAIL, whereas
- [^] must match any character, so generate OP_ALLANY. */
-
- if (c ==']' && (cd->external_options & PCRE_JAVASCRIPT_COMPAT) != 0)
- {
- *code++ = negate_class? OP_ALLANY : OP_FAIL;
- if (firstbyte == REQ_UNSET) firstbyte = REQ_NONE;
- zerofirstbyte = firstbyte;
- break;
- }
-
- /* If a class contains a negative special such as \S, we need to flip the
- negation flag at the end, so that support for characters > 255 works
- correctly (they are all included in the class). */
-
- should_flip_negation = FALSE;
-
- /* Keep a count of chars with values < 256 so that we can optimize the case
- of just a single character (as long as it's < 256). However, For higher
- valued UTF-8 characters, we don't yet do any optimization. */
-
- class_charcount = 0;
- class_lastchar = -1;
-
- /* Initialize the 32-char bit map to all zeros. We build the map in a
- temporary bit of memory, in case the class contains only 1 character (less
- than 256), because in that case the compiled code doesn't use the bit map.
- */
-
- memset(classbits, 0, 32 * sizeof(uschar));
-
-#ifdef SUPPORT_UTF8
- class_utf8 = FALSE; /* No chars >= 256 */
- class_utf8data = code + LINK_SIZE + 2; /* For UTF-8 items */
- class_utf8data_base = class_utf8data; /* For resetting in pass 1 */
-#endif
-
- /* Process characters until ] is reached. By writing this as a "do" it
- means that an initial ] is taken as a data character. At the start of the
- loop, c contains the first byte of the character. */
-
- if (c != 0) do
- {
- const uschar *oldptr;
-
-#ifdef SUPPORT_UTF8
- if (utf8 && c > 127)
- { /* Braces are required because the */
- GETCHARLEN(c, ptr, ptr); /* macro generates multiple statements */
- }
-
- /* In the pre-compile phase, accumulate the length of any UTF-8 extra
- data and reset the pointer. This is so that very large classes that
- contain a zillion UTF-8 characters no longer overwrite the work space
- (which is on the stack). */
-
- if (lengthptr != NULL)
- {
- *lengthptr += class_utf8data - class_utf8data_base;
- class_utf8data = class_utf8data_base;
- }
-
-#endif
-
- /* Inside \Q...\E everything is literal except \E */
-
- if (inescq)
- {
- if (c == '\\' && ptr[1] == 'E') /* If we are at \E */
- {
- inescq = FALSE; /* Reset literal state */
- ptr++; /* Skip the 'E' */
- continue; /* Carry on with next */
- }
- goto CHECK_RANGE; /* Could be range if \E follows */
- }
-
- /* Handle POSIX class names. Perl allows a negation extension of the
- form [:^name:]. A square bracket that doesn't match the syntax is
- treated as a literal. We also recognize the POSIX constructions
- [.ch.] and [=ch=] ("collating elements") and fault them, as Perl
- 5.6 and 5.8 do. */
-
- if (c == '[' &&
- (ptr[1] == ':' || ptr[1] == '.' || ptr[1] == '=') &&
- check_posix_syntax(ptr, &tempptr))
- {
- BOOL local_negate = FALSE;
- int posix_class, taboffset, tabopt;
- register const uschar *cbits = cd->cbits;
- uschar pbits[32];
-
- if (ptr[1] != ':')
- {
- *errorcodeptr = ERR31;
- goto FAILED;
- }
-
- ptr += 2;
- if (*ptr == '^')
- {
- local_negate = TRUE;
- should_flip_negation = TRUE; /* Note negative special */
- ptr++;
- }
-
- posix_class = check_posix_name(ptr, tempptr - ptr);
- if (posix_class < 0)
- {
- *errorcodeptr = ERR30;
- goto FAILED;
- }
-
- /* If matching is caseless, upper and lower are converted to
- alpha. This relies on the fact that the class table starts with
- alpha, lower, upper as the first 3 entries. */
-
- if ((options & PCRE_CASELESS) != 0 && posix_class <= 2)
- posix_class = 0;
-
- /* We build the bit map for the POSIX class in a chunk of local store
- because we may be adding and subtracting from it, and we don't want to
- subtract bits that may be in the main map already. At the end we or the
- result into the bit map that is being built. */
-
- posix_class *= 3;
-
- /* Copy in the first table (always present) */
-
- memcpy(pbits, cbits + posix_class_maps[posix_class],
- 32 * sizeof(uschar));
-
- /* If there is a second table, add or remove it as required. */
-
- taboffset = posix_class_maps[posix_class + 1];
- tabopt = posix_class_maps[posix_class + 2];
-
- if (taboffset >= 0)
- {
- if (tabopt >= 0)
- for (c = 0; c < 32; c++) pbits[c] |= cbits[c + taboffset];
- else
- for (c = 0; c < 32; c++) pbits[c] &= ~cbits[c + taboffset];
- }
-
- /* Not see if we need to remove any special characters. An option
- value of 1 removes vertical space and 2 removes underscore. */
-
- if (tabopt < 0) tabopt = -tabopt;
- if (tabopt == 1) pbits[1] &= ~0x3c;
- else if (tabopt == 2) pbits[11] &= 0x7f;
-
- /* Add the POSIX table or its complement into the main table that is
- being built and we are done. */
-
- if (local_negate)
- for (c = 0; c < 32; c++) classbits[c] |= ~pbits[c];
- else
- for (c = 0; c < 32; c++) classbits[c] |= pbits[c];
-
- ptr = tempptr + 1;
- class_charcount = 10; /* Set > 1; assumes more than 1 per class */
- continue; /* End of POSIX syntax handling */
- }
-
- /* Backslash may introduce a single character, or it may introduce one
- of the specials, which just set a flag. The sequence \b is a special
- case. Inside a class (and only there) it is treated as backspace.
- Elsewhere it marks a word boundary. Other escapes have preset maps ready
- to 'or' into the one we are building. We assume they have more than one
- character in them, so set class_charcount bigger than one. */
-
- if (c == '\\')
- {
- c = check_escape(&ptr, errorcodeptr, cd->bracount, options, TRUE);
- if (*errorcodeptr != 0) goto FAILED;
-
- if (-c == ESC_b) c = '\b'; /* \b is backspace in a class */
- else if (-c == ESC_X) c = 'X'; /* \X is literal X in a class */
- else if (-c == ESC_R) c = 'R'; /* \R is literal R in a class */
- else if (-c == ESC_Q) /* Handle start of quoted string */
- {
- if (ptr[1] == '\\' && ptr[2] == 'E')
- {
- ptr += 2; /* avoid empty string */
- }
- else inescq = TRUE;
- continue;
- }
- else if (-c == ESC_E) continue; /* Ignore orphan \E */
-
- if (c < 0)
- {
- register const uschar *cbits = cd->cbits;
- class_charcount += 2; /* Greater than 1 is what matters */
-
- /* Save time by not doing this in the pre-compile phase. */
-
- if (lengthptr == NULL) switch (-c)
- {
- case ESC_d:
- for (c = 0; c < 32; c++) classbits[c] |= cbits[c+cbit_digit];
- continue;
-
- case ESC_D:
- should_flip_negation = TRUE;
- for (c = 0; c < 32; c++) classbits[c] |= ~cbits[c+cbit_digit];
- continue;
-
- case ESC_w:
- for (c = 0; c < 32; c++) classbits[c] |= cbits[c+cbit_word];
- continue;
-
- case ESC_W:
- should_flip_negation = TRUE;
- for (c = 0; c < 32; c++) classbits[c] |= ~cbits[c+cbit_word];
- continue;
-
- case ESC_s:
- for (c = 0; c < 32; c++) classbits[c] |= cbits[c+cbit_space];
- classbits[1] &= ~0x08; /* Perl 5.004 onwards omits VT from \s */
- continue;
-
- case ESC_S:
- should_flip_negation = TRUE;
- for (c = 0; c < 32; c++) classbits[c] |= ~cbits[c+cbit_space];
- classbits[1] |= 0x08; /* Perl 5.004 onwards omits VT from \s */
- continue;
-
- default: /* Not recognized; fall through */
- break; /* Need "default" setting to stop compiler warning. */
- }
-
- /* In the pre-compile phase, just do the recognition. */
-
- else if (c == -ESC_d || c == -ESC_D || c == -ESC_w ||
- c == -ESC_W || c == -ESC_s || c == -ESC_S) continue;
-
- /* We need to deal with \H, \h, \V, and \v in both phases because
- they use extra memory. */
-
- if (-c == ESC_h)
- {
- SETBIT(classbits, 0x09); /* VT */
- SETBIT(classbits, 0x20); /* SPACE */
- SETBIT(classbits, 0xa0); /* NSBP */
-#ifdef SUPPORT_UTF8
- if (utf8)
- {
- class_utf8 = TRUE;
- *class_utf8data++ = XCL_SINGLE;
- class_utf8data += _pcre_ord2utf8(0x1680, class_utf8data);
- *class_utf8data++ = XCL_SINGLE;
- class_utf8data += _pcre_ord2utf8(0x180e, class_utf8data);
- *class_utf8data++ = XCL_RANGE;
- class_utf8data += _pcre_ord2utf8(0x2000, class_utf8data);
- class_utf8data += _pcre_ord2utf8(0x200A, class_utf8data);
- *class_utf8data++ = XCL_SINGLE;
- class_utf8data += _pcre_ord2utf8(0x202f, class_utf8data);
- *class_utf8data++ = XCL_SINGLE;
- class_utf8data += _pcre_ord2utf8(0x205f, class_utf8data);
- *class_utf8data++ = XCL_SINGLE;
- class_utf8data += _pcre_ord2utf8(0x3000, class_utf8data);
- }
-#endif
- continue;
- }
-
- if (-c == ESC_H)
- {
- for (c = 0; c < 32; c++)
- {
- int x = 0xff;
- switch (c)
- {
- case 0x09/8: x ^= 1 << (0x09%8); break;
- case 0x20/8: x ^= 1 << (0x20%8); break;
- case 0xa0/8: x ^= 1 << (0xa0%8); break;
- default: break;
- }
- classbits[c] |= x;
- }
-
-#ifdef SUPPORT_UTF8
- if (utf8)
- {
- class_utf8 = TRUE;
- *class_utf8data++ = XCL_RANGE;
- class_utf8data += _pcre_ord2utf8(0x0100, class_utf8data);
- class_utf8data += _pcre_ord2utf8(0x167f, class_utf8data);
- *class_utf8data++ = XCL_RANGE;
- class_utf8data += _pcre_ord2utf8(0x1681, class_utf8data);
- class_utf8data += _pcre_ord2utf8(0x180d, class_utf8data);
- *class_utf8data++ = XCL_RANGE;
- class_utf8data += _pcre_ord2utf8(0x180f, class_utf8data);
- class_utf8data += _pcre_ord2utf8(0x1fff, class_utf8data);
- *class_utf8data++ = XCL_RANGE;
- class_utf8data += _pcre_ord2utf8(0x200B, class_utf8data);
- class_utf8data += _pcre_ord2utf8(0x202e, class_utf8data);
- *class_utf8data++ = XCL_RANGE;
- class_utf8data += _pcre_ord2utf8(0x2030, class_utf8data);
- class_utf8data += _pcre_ord2utf8(0x205e, class_utf8data);
- *class_utf8data++ = XCL_RANGE;
- class_utf8data += _pcre_ord2utf8(0x2060, class_utf8data);
- class_utf8data += _pcre_ord2utf8(0x2fff, class_utf8data);
- *class_utf8data++ = XCL_RANGE;
- class_utf8data += _pcre_ord2utf8(0x3001, class_utf8data);
- class_utf8data += _pcre_ord2utf8(0x7fffffff, class_utf8data);
- }
-#endif
- continue;
- }
-
- if (-c == ESC_v)
- {
- SETBIT(classbits, 0x0a); /* LF */
- SETBIT(classbits, 0x0b); /* VT */
- SETBIT(classbits, 0x0c); /* FF */
- SETBIT(classbits, 0x0d); /* CR */
- SETBIT(classbits, 0x85); /* NEL */
-#ifdef SUPPORT_UTF8
- if (utf8)
- {
- class_utf8 = TRUE;
- *class_utf8data++ = XCL_RANGE;
- class_utf8data += _pcre_ord2utf8(0x2028, class_utf8data);
- class_utf8data += _pcre_ord2utf8(0x2029, class_utf8data);
- }
-#endif
- continue;
- }
-
- if (-c == ESC_V)
- {
- for (c = 0; c < 32; c++)
- {
- int x = 0xff;
- switch (c)
- {
- case 0x0a/8: x ^= 1 << (0x0a%8);
- x ^= 1 << (0x0b%8);
- x ^= 1 << (0x0c%8);
- x ^= 1 << (0x0d%8);
- break;
- case 0x85/8: x ^= 1 << (0x85%8); break;
- default: break;
- }
- classbits[c] |= x;
- }
-
-#ifdef SUPPORT_UTF8
- if (utf8)
- {
- class_utf8 = TRUE;
- *class_utf8data++ = XCL_RANGE;
- class_utf8data += _pcre_ord2utf8(0x0100, class_utf8data);
- class_utf8data += _pcre_ord2utf8(0x2027, class_utf8data);
- *class_utf8data++ = XCL_RANGE;
- class_utf8data += _pcre_ord2utf8(0x2029, class_utf8data);
- class_utf8data += _pcre_ord2utf8(0x7fffffff, class_utf8data);
- }
-#endif
- continue;
- }
-
- /* We need to deal with \P and \p in both phases. */
-
-#ifdef SUPPORT_UCP
- if (-c == ESC_p || -c == ESC_P)
- {
- BOOL negated;
- int pdata;
- int ptype = get_ucp(&ptr, &negated, &pdata, errorcodeptr);
- if (ptype < 0) goto FAILED;
- class_utf8 = TRUE;
- *class_utf8data++ = ((-c == ESC_p) != negated)?
- XCL_PROP : XCL_NOTPROP;
- *class_utf8data++ = ptype;
- *class_utf8data++ = pdata;
- class_charcount -= 2; /* Not a < 256 character */
- continue;
- }
-#endif
- /* Unrecognized escapes are faulted if PCRE is running in its
- strict mode. By default, for compatibility with Perl, they are
- treated as literals. */
-
- if ((options & PCRE_EXTRA) != 0)
- {
- *errorcodeptr = ERR7;
- goto FAILED;
- }
-
- class_charcount -= 2; /* Undo the default count from above */
- c = *ptr; /* Get the final character and fall through */
- }
-
- /* Fall through if we have a single character (c >= 0). This may be
- greater than 256 in UTF-8 mode. */
-
- } /* End of backslash handling */
-
- /* A single character may be followed by '-' to form a range. However,
- Perl does not permit ']' to be the end of the range. A '-' character
- at the end is treated as a literal. Perl ignores orphaned \E sequences
- entirely. The code for handling \Q and \E is messy. */
-
- CHECK_RANGE:
- while (ptr[1] == '\\' && ptr[2] == 'E')
- {
- inescq = FALSE;
- ptr += 2;
- }
-
- oldptr = ptr;
-
- /* Remember \r or \n */
-
- if (c == '\r' || c == '\n') cd->external_flags |= PCRE_HASCRORLF;
-
- /* Check for range */
-
- if (!inescq && ptr[1] == '-')
- {
- int d;
- ptr += 2;
- while (*ptr == '\\' && ptr[1] == 'E') ptr += 2;
-
- /* If we hit \Q (not followed by \E) at this point, go into escaped
- mode. */
-
- while (*ptr == '\\' && ptr[1] == 'Q')
- {
- ptr += 2;
- if (*ptr == '\\' && ptr[1] == 'E') { ptr += 2; continue; }
- inescq = TRUE;
- break;
- }
-
- if (*ptr == 0 || (!inescq && *ptr == ']'))
- {
- ptr = oldptr;
- goto LONE_SINGLE_CHARACTER;
- }
-
-#ifdef SUPPORT_UTF8
- if (utf8)
- { /* Braces are required because the */
- GETCHARLEN(d, ptr, ptr); /* macro generates multiple statements */
- }
- else
-#endif
- d = *ptr; /* Not UTF-8 mode */
-
- /* The second part of a range can be a single-character escape, but
- not any of the other escapes. Perl 5.6 treats a hyphen as a literal
- in such circumstances. */
-
- if (!inescq && d == '\\')
- {
- d = check_escape(&ptr, errorcodeptr, cd->bracount, options, TRUE);
- if (*errorcodeptr != 0) goto FAILED;
-
- /* \b is backspace; \X is literal X; \R is literal R; any other
- special means the '-' was literal */
-
- if (d < 0)
- {
- if (d == -ESC_b) d = '\b';
- else if (d == -ESC_X) d = 'X';
- else if (d == -ESC_R) d = 'R'; else
- {
- ptr = oldptr;
- goto LONE_SINGLE_CHARACTER; /* A few lines below */
- }
- }
- }
-
- /* Check that the two values are in the correct order. Optimize
- one-character ranges */
-
- if (d < c)
- {
- *errorcodeptr = ERR8;
- goto FAILED;
- }
-
- if (d == c) goto LONE_SINGLE_CHARACTER; /* A few lines below */
-
- /* Remember \r or \n */
-
- if (d == '\r' || d == '\n') cd->external_flags |= PCRE_HASCRORLF;
-
- /* In UTF-8 mode, if the upper limit is > 255, or > 127 for caseless
- matching, we have to use an XCLASS with extra data items. Caseless
- matching for characters > 127 is available only if UCP support is
- available. */
-
-#ifdef SUPPORT_UTF8
- if (utf8 && (d > 255 || ((options & PCRE_CASELESS) != 0 && d > 127)))
- {
- class_utf8 = TRUE;
-
- /* With UCP support, we can find the other case equivalents of
- the relevant characters. There may be several ranges. Optimize how
- they fit with the basic range. */
-
-#ifdef SUPPORT_UCP
- if ((options & PCRE_CASELESS) != 0)
- {
- unsigned int occ, ocd;
- unsigned int cc = c;
- unsigned int origd = d;
- while (get_othercase_range(&cc, origd, &occ, &ocd))
- {
- if (occ >= (unsigned int)c &&
- ocd <= (unsigned int)d)
- continue; /* Skip embedded ranges */
-
- if (occ < (unsigned int)c &&
- ocd >= (unsigned int)c - 1) /* Extend the basic range */
- { /* if there is overlap, */
- c = occ; /* noting that if occ < c */
- continue; /* we can't have ocd > d */
- } /* because a subrange is */
- if (ocd > (unsigned int)d &&
- occ <= (unsigned int)d + 1) /* always shorter than */
- { /* the basic range. */
- d = ocd;
- continue;
- }
-
- if (occ == ocd)
- {
- *class_utf8data++ = XCL_SINGLE;
- }
- else
- {
- *class_utf8data++ = XCL_RANGE;
- class_utf8data += _pcre_ord2utf8(occ, class_utf8data);
- }
- class_utf8data += _pcre_ord2utf8(ocd, class_utf8data);
- }
- }
-#endif /* SUPPORT_UCP */
-
- /* Now record the original range, possibly modified for UCP caseless
- overlapping ranges. */
-
- *class_utf8data++ = XCL_RANGE;
- class_utf8data += _pcre_ord2utf8(c, class_utf8data);
- class_utf8data += _pcre_ord2utf8(d, class_utf8data);
-
- /* With UCP support, we are done. Without UCP support, there is no
- caseless matching for UTF-8 characters > 127; we can use the bit map
- for the smaller ones. */
-
-#ifdef SUPPORT_UCP
- continue; /* With next character in the class */
-#else
- if ((options & PCRE_CASELESS) == 0 || c > 127) continue;
-
- /* Adjust upper limit and fall through to set up the map */
-
- d = 127;
-
-#endif /* SUPPORT_UCP */
- }
-#endif /* SUPPORT_UTF8 */
-
- /* We use the bit map for all cases when not in UTF-8 mode; else
- ranges that lie entirely within 0-127 when there is UCP support; else
- for partial ranges without UCP support. */
-
- class_charcount += d - c + 1;
- class_lastchar = d;
-
- /* We can save a bit of time by skipping this in the pre-compile. */
-
- if (lengthptr == NULL) for (; c <= d; c++)
- {
- classbits[c/8] |= (1 << (c&7));
- if ((options & PCRE_CASELESS) != 0)
- {
- int uc = cd->fcc[c]; /* flip case */
- classbits[uc/8] |= (1 << (uc&7));
- }
- }
-
- continue; /* Go get the next char in the class */
- }
-
- /* Handle a lone single character - we can get here for a normal
- non-escape char, or after \ that introduces a single character or for an
- apparent range that isn't. */
-
- LONE_SINGLE_CHARACTER:
-
- /* Handle a character that cannot go in the bit map */
-
-#ifdef SUPPORT_UTF8
- if (utf8 && (c > 255 || ((options & PCRE_CASELESS) != 0 && c > 127)))
- {
- class_utf8 = TRUE;
- *class_utf8data++ = XCL_SINGLE;
- class_utf8data += _pcre_ord2utf8(c, class_utf8data);
-
-#ifdef SUPPORT_UCP
- if ((options & PCRE_CASELESS) != 0)
- {
- unsigned int othercase;
- if ((othercase = _pcre_ucp_othercase(c)) != NOTACHAR)
- {
- *class_utf8data++ = XCL_SINGLE;
- class_utf8data += _pcre_ord2utf8(othercase, class_utf8data);
- }
- }
-#endif /* SUPPORT_UCP */
-
- }
- else
-#endif /* SUPPORT_UTF8 */
-
- /* Handle a single-byte character */
- {
- classbits[c/8] |= (1 << (c&7));
- if ((options & PCRE_CASELESS) != 0)
- {
- c = cd->fcc[c]; /* flip case */
- classbits[c/8] |= (1 << (c&7));
- }
- class_charcount++;
- class_lastchar = c;
- }
- }
-
- /* Loop until ']' reached. This "while" is the end of the "do" above. */
-
- while ((c = *(++ptr)) != 0 && (c != ']' || inescq));
-
- if (c == 0) /* Missing terminating ']' */
- {
- *errorcodeptr = ERR6;
- goto FAILED;
- }
-
-
-/* This code has been disabled because it would mean that \s counts as
-an explicit \r or \n reference, and that's not really what is wanted. Now
-we set the flag only if there is a literal "\r" or "\n" in the class. */
-
-#if 0
- /* Remember whether \r or \n are in this class */
-
- if (negate_class)
- {
- if ((classbits[1] & 0x24) != 0x24) cd->external_flags |= PCRE_HASCRORLF;
- }
- else
- {
- if ((classbits[1] & 0x24) != 0) cd->external_flags |= PCRE_HASCRORLF;
- }
-#endif
-
-
- /* If class_charcount is 1, we saw precisely one character whose value is
- less than 256. As long as there were no characters >= 128 and there was no
- use of \p or \P, in other words, no use of any XCLASS features, we can
- optimize.
-
- In UTF-8 mode, we can optimize the negative case only if there were no
- characters >= 128 because OP_NOT and the related opcodes like OP_NOTSTAR
- operate on single-bytes only. This is an historical hangover. Maybe one day
- we can tidy these opcodes to handle multi-byte characters.
-
- The optimization throws away the bit map. We turn the item into a
- 1-character OP_CHAR[NC] if it's positive, or OP_NOT if it's negative. Note
- that OP_NOT does not support multibyte characters. In the positive case, it
- can cause firstbyte to be set. Otherwise, there can be no first char if
- this item is first, whatever repeat count may follow. In the case of
- reqbyte, save the previous value for reinstating. */
-
-#ifdef SUPPORT_UTF8
- if (class_charcount == 1 && !class_utf8 &&
- (!utf8 || !negate_class || class_lastchar < 128))
-#else
- if (class_charcount == 1)
-#endif
- {
- zeroreqbyte = reqbyte;
-
- /* The OP_NOT opcode works on one-byte characters only. */
-
- if (negate_class)
- {
- if (firstbyte == REQ_UNSET) firstbyte = REQ_NONE;
- zerofirstbyte = firstbyte;
- *code++ = OP_NOT;
- *code++ = class_lastchar;
- break;
- }
-
- /* For a single, positive character, get the value into mcbuffer, and
- then we can handle this with the normal one-character code. */
-
-#ifdef SUPPORT_UTF8
- if (utf8 && class_lastchar > 127)
- mclength = _pcre_ord2utf8(class_lastchar, mcbuffer);
- else
-#endif
- {
- mcbuffer[0] = class_lastchar;
- mclength = 1;
- }
- goto ONE_CHAR;
- } /* End of 1-char optimization */
-
- /* The general case - not the one-char optimization. If this is the first
- thing in the branch, there can be no first char setting, whatever the
- repeat count. Any reqbyte setting must remain unchanged after any kind of
- repeat. */
-
- if (firstbyte == REQ_UNSET) firstbyte = REQ_NONE;
- zerofirstbyte = firstbyte;
- zeroreqbyte = reqbyte;
-
- /* If there are characters with values > 255, we have to compile an
- extended class, with its own opcode, unless there was a negated special
- such as \S in the class, because in that case all characters > 255 are in
- the class, so any that were explicitly given as well can be ignored. If
- (when there are explicit characters > 255 that must be listed) there are no
- characters < 256, we can omit the bitmap in the actual compiled code. */
-
-#ifdef SUPPORT_UTF8
- if (class_utf8 && !should_flip_negation)
- {
- *class_utf8data++ = XCL_END; /* Marks the end of extra data */
- *code++ = OP_XCLASS;
- code += LINK_SIZE;
- *code = negate_class? XCL_NOT : 0;
-
- /* If the map is required, move up the extra data to make room for it;
- otherwise just move the code pointer to the end of the extra data. */
-
- if (class_charcount > 0)
- {
- *code++ |= XCL_MAP;
- memmove(code + 32, code, class_utf8data - code);
- memcpy(code, classbits, 32);
- code = class_utf8data + 32;
- }
- else code = class_utf8data;
-
- /* Now fill in the complete length of the item */
-
- PUT(previous, 1, code - previous);
- break; /* End of class handling */
- }
-#endif
-
- /* If there are no characters > 255, set the opcode to OP_CLASS or
- OP_NCLASS, depending on whether the whole class was negated and whether
- there were negative specials such as \S in the class. Then copy the 32-byte
- map into the code vector, negating it if necessary. */
-
- *code++ = (negate_class == should_flip_negation) ? OP_CLASS : OP_NCLASS;
- if (negate_class)
- {
- if (lengthptr == NULL) /* Save time in the pre-compile phase */
- for (c = 0; c < 32; c++) code[c] = ~classbits[c];
- }
- else
- {
- memcpy(code, classbits, 32);
- }
- code += 32;
- break;
-
-
- /* ===================================================================*/
- /* Various kinds of repeat; '{' is not necessarily a quantifier, but this
- has been tested above. */
-
- case '{':
- if (!is_quantifier) goto NORMAL_CHAR;
- ptr = read_repeat_counts(ptr+1, &repeat_min, &repeat_max, errorcodeptr);
- if (*errorcodeptr != 0) goto FAILED;
- goto REPEAT;
-
- case '*':
- repeat_min = 0;
- repeat_max = -1;
- goto REPEAT;
-
- case '+':
- repeat_min = 1;
- repeat_max = -1;
- goto REPEAT;
-
- case '?':
- repeat_min = 0;
- repeat_max = 1;
-
- REPEAT:
- if (previous == NULL)
- {
- *errorcodeptr = ERR9;
- goto FAILED;
- }
-
- if (repeat_min == 0)
- {
- firstbyte = zerofirstbyte; /* Adjust for zero repeat */
- reqbyte = zeroreqbyte; /* Ditto */
- }
-
- /* Remember whether this is a variable length repeat */
-
- reqvary = (repeat_min == repeat_max)? 0 : REQ_VARY;
-
- op_type = 0; /* Default single-char op codes */
- possessive_quantifier = FALSE; /* Default not possessive quantifier */
-
- /* Save start of previous item, in case we have to move it up to make space
- for an inserted OP_ONCE for the additional '+' extension. */
-
- tempcode = previous;
-
- /* If the next character is '+', we have a possessive quantifier. This
- implies greediness, whatever the setting of the PCRE_UNGREEDY option.
- If the next character is '?' this is a minimizing repeat, by default,
- but if PCRE_UNGREEDY is set, it works the other way round. We change the
- repeat type to the non-default. */
-
- if (ptr[1] == '+')
- {
- repeat_type = 0; /* Force greedy */
- possessive_quantifier = TRUE;
- ptr++;
- }
- else if (ptr[1] == '?')
- {
- repeat_type = greedy_non_default;
- ptr++;
- }
- else repeat_type = greedy_default;
-
- /* If previous was a character match, abolish the item and generate a
- repeat item instead. If a char item has a minumum of more than one, ensure
- that it is set in reqbyte - it might not be if a sequence such as x{3} is
- the first thing in a branch because the x will have gone into firstbyte
- instead. */
-
- if (*previous == OP_CHAR || *previous == OP_CHARNC)
- {
- /* Deal with UTF-8 characters that take up more than one byte. It's
- easier to write this out separately than try to macrify it. Use c to
- hold the length of the character in bytes, plus 0x80 to flag that it's a
- length rather than a small character. */
-
-#ifdef SUPPORT_UTF8
- if (utf8 && (code[-1] & 0x80) != 0)
- {
- uschar *lastchar = code - 1;
- while((*lastchar & 0xc0) == 0x80) lastchar--;
- c = code - lastchar; /* Length of UTF-8 character */
- memcpy(utf8_char, lastchar, c); /* Save the char */
- c |= 0x80; /* Flag c as a length */
- }
- else
-#endif
-
- /* Handle the case of a single byte - either with no UTF8 support, or
- with UTF-8 disabled, or for a UTF-8 character < 128. */
-
- {
- c = code[-1];
- if (repeat_min > 1) reqbyte = c | req_caseopt | cd->req_varyopt;
- }
-
- /* If the repetition is unlimited, it pays to see if the next thing on
- the line is something that cannot possibly match this character. If so,
- automatically possessifying this item gains some performance in the case
- where the match fails. */
-
- if (!possessive_quantifier &&
- repeat_max < 0 &&
- check_auto_possessive(*previous, c, utf8, utf8_char, ptr + 1,
- options, cd))
- {
- repeat_type = 0; /* Force greedy */
- possessive_quantifier = TRUE;
- }
-
- goto OUTPUT_SINGLE_REPEAT; /* Code shared with single character types */
- }
-
- /* If previous was a single negated character ([^a] or similar), we use
- one of the special opcodes, replacing it. The code is shared with single-
- character repeats by setting opt_type to add a suitable offset into
- repeat_type. We can also test for auto-possessification. OP_NOT is
- currently used only for single-byte chars. */
-
- else if (*previous == OP_NOT)
- {
- op_type = OP_NOTSTAR - OP_STAR; /* Use "not" opcodes */
- c = previous[1];
- if (!possessive_quantifier &&
- repeat_max < 0 &&
- check_auto_possessive(OP_NOT, c, utf8, NULL, ptr + 1, options, cd))
- {
- repeat_type = 0; /* Force greedy */
- possessive_quantifier = TRUE;
- }
- goto OUTPUT_SINGLE_REPEAT;
- }
-
- /* If previous was a character type match (\d or similar), abolish it and
- create a suitable repeat item. The code is shared with single-character
- repeats by setting op_type to add a suitable offset into repeat_type. Note
- the the Unicode property types will be present only when SUPPORT_UCP is
- defined, but we don't wrap the little bits of code here because it just
- makes it horribly messy. */
-
- else if (*previous < OP_EODN)
- {
- uschar *oldcode;
- int prop_type, prop_value;
- op_type = OP_TYPESTAR - OP_STAR; /* Use type opcodes */
- c = *previous;
-
- if (!possessive_quantifier &&
- repeat_max < 0 &&
- check_auto_possessive(c, 0, utf8, NULL, ptr + 1, options, cd))
- {
- repeat_type = 0; /* Force greedy */
- possessive_quantifier = TRUE;
- }
-
- OUTPUT_SINGLE_REPEAT:
- if (*previous == OP_PROP || *previous == OP_NOTPROP)
- {
- prop_type = previous[1];
- prop_value = previous[2];
- }
- else prop_type = prop_value = -1;
-
- oldcode = code;
- code = previous; /* Usually overwrite previous item */
-
- /* If the maximum is zero then the minimum must also be zero; Perl allows
- this case, so we do too - by simply omitting the item altogether. */
-
- if (repeat_max == 0) goto END_REPEAT;
-
- /* All real repeats make it impossible to handle partial matching (maybe
- one day we will be able to remove this restriction). */
-
- if (repeat_max != 1) cd->external_flags |= PCRE_NOPARTIAL;
-
- /* Combine the op_type with the repeat_type */
-
- repeat_type += op_type;
-
- /* A minimum of zero is handled either as the special case * or ?, or as
- an UPTO, with the maximum given. */
-
- if (repeat_min == 0)
- {
- if (repeat_max == -1) *code++ = OP_STAR + repeat_type;
- else if (repeat_max == 1) *code++ = OP_QUERY + repeat_type;
- else
- {
- *code++ = OP_UPTO + repeat_type;
- PUT2INC(code, 0, repeat_max);
- }
- }
-
- /* A repeat minimum of 1 is optimized into some special cases. If the
- maximum is unlimited, we use OP_PLUS. Otherwise, the original item is
- left in place and, if the maximum is greater than 1, we use OP_UPTO with
- one less than the maximum. */
-
- else if (repeat_min == 1)
- {
- if (repeat_max == -1)
- *code++ = OP_PLUS + repeat_type;
- else
- {
- code = oldcode; /* leave previous item in place */
- if (repeat_max == 1) goto END_REPEAT;
- *code++ = OP_UPTO + repeat_type;
- PUT2INC(code, 0, repeat_max - 1);
- }
- }
-
- /* The case {n,n} is just an EXACT, while the general case {n,m} is
- handled as an EXACT followed by an UPTO. */
-
- else
- {
- *code++ = OP_EXACT + op_type; /* NB EXACT doesn't have repeat_type */
- PUT2INC(code, 0, repeat_min);
-
- /* If the maximum is unlimited, insert an OP_STAR. Before doing so,
- we have to insert the character for the previous code. For a repeated
- Unicode property match, there are two extra bytes that define the
- required property. In UTF-8 mode, long characters have their length in
- c, with the 0x80 bit as a flag. */
-
- if (repeat_max < 0)
- {
-#ifdef SUPPORT_UTF8
- if (utf8 && c >= 128)
- {
- memcpy(code, utf8_char, c & 7);
- code += c & 7;
- }
- else
-#endif
- {
- *code++ = c;
- if (prop_type >= 0)
- {
- *code++ = prop_type;
- *code++ = prop_value;
- }
- }
- *code++ = OP_STAR + repeat_type;
- }
-
- /* Else insert an UPTO if the max is greater than the min, again
- preceded by the character, for the previously inserted code. If the
- UPTO is just for 1 instance, we can use QUERY instead. */
-
- else if (repeat_max != repeat_min)
- {
-#ifdef SUPPORT_UTF8
- if (utf8 && c >= 128)
- {
- memcpy(code, utf8_char, c & 7);
- code += c & 7;
- }
- else
-#endif
- *code++ = c;
- if (prop_type >= 0)
- {
- *code++ = prop_type;
- *code++ = prop_value;
- }
- repeat_max -= repeat_min;
-
- if (repeat_max == 1)
- {
- *code++ = OP_QUERY + repeat_type;
- }
- else
- {
- *code++ = OP_UPTO + repeat_type;
- PUT2INC(code, 0, repeat_max);
- }
- }
- }
-
- /* The character or character type itself comes last in all cases. */
-
-#ifdef SUPPORT_UTF8
- if (utf8 && c >= 128)
- {
- memcpy(code, utf8_char, c & 7);
- code += c & 7;
- }
- else
-#endif
- *code++ = c;
-
- /* For a repeated Unicode property match, there are two extra bytes that
- define the required property. */
-
-#ifdef SUPPORT_UCP
- if (prop_type >= 0)
- {
- *code++ = prop_type;
- *code++ = prop_value;
- }
-#endif
- }
-
- /* If previous was a character class or a back reference, we put the repeat
- stuff after it, but just skip the item if the repeat was {0,0}. */
-
- else if (*previous == OP_CLASS ||
- *previous == OP_NCLASS ||
-#ifdef SUPPORT_UTF8
- *previous == OP_XCLASS ||
-#endif
- *previous == OP_REF)
- {
- if (repeat_max == 0)
- {
- code = previous;
- goto END_REPEAT;
- }
-
- /* All real repeats make it impossible to handle partial matching (maybe
- one day we will be able to remove this restriction). */
-
- if (repeat_max != 1) cd->external_flags |= PCRE_NOPARTIAL;
-
- if (repeat_min == 0 && repeat_max == -1)
- *code++ = OP_CRSTAR + repeat_type;
- else if (repeat_min == 1 && repeat_max == -1)
- *code++ = OP_CRPLUS + repeat_type;
- else if (repeat_min == 0 && repeat_max == 1)
- *code++ = OP_CRQUERY + repeat_type;
- else
- {
- *code++ = OP_CRRANGE + repeat_type;
- PUT2INC(code, 0, repeat_min);
- if (repeat_max == -1) repeat_max = 0; /* 2-byte encoding for max */
- PUT2INC(code, 0, repeat_max);
- }
- }
-
- /* If previous was a bracket group, we may have to replicate it in certain
- cases. */
-
- else if (*previous == OP_BRA || *previous == OP_CBRA ||
- *previous == OP_ONCE || *previous == OP_COND)
- {
- register int i;
- int ketoffset = 0;
- int len = code - previous;
- uschar *bralink = NULL;
-
- /* Repeating a DEFINE group is pointless */
-
- if (*previous == OP_COND && previous[LINK_SIZE+1] == OP_DEF)
- {
- *errorcodeptr = ERR55;
- goto FAILED;
- }
-
- /* If the maximum repeat count is unlimited, find the end of the bracket
- by scanning through from the start, and compute the offset back to it
- from the current code pointer. There may be an OP_OPT setting following
- the final KET, so we can't find the end just by going back from the code
- pointer. */
-
- if (repeat_max == -1)
- {
- register uschar *ket = previous;
- do ket += GET(ket, 1); while (*ket != OP_KET);
- ketoffset = code - ket;
- }
-
- /* The case of a zero minimum is special because of the need to stick
- OP_BRAZERO in front of it, and because the group appears once in the
- data, whereas in other cases it appears the minimum number of times. For
- this reason, it is simplest to treat this case separately, as otherwise
- the code gets far too messy. There are several special subcases when the
- minimum is zero. */
-
- if (repeat_min == 0)
- {
- /* If the maximum is also zero, we used to just omit the group from the
- output altogether, like this:
-
- ** if (repeat_max == 0)
- ** {
- ** code = previous;
- ** goto END_REPEAT;
- ** }
-
- However, that fails when a group is referenced as a subroutine from
- elsewhere in the pattern, so now we stick in OP_SKIPZERO in front of it
- so that it is skipped on execution. As we don't have a list of which
- groups are referenced, we cannot do this selectively.
-
- If the maximum is 1 or unlimited, we just have to stick in the BRAZERO
- and do no more at this point. However, we do need to adjust any
- OP_RECURSE calls inside the group that refer to the group itself or any
- internal or forward referenced group, because the offset is from the
- start of the whole regex. Temporarily terminate the pattern while doing
- this. */
-
- if (repeat_max <= 1) /* Covers 0, 1, and unlimited */
- {
- *code = OP_END;
- adjust_recurse(previous, 1, utf8, cd, save_hwm);
- memmove(previous+1, previous, len);
- code++;
- if (repeat_max == 0)
- {
- *previous++ = OP_SKIPZERO;
- goto END_REPEAT;
- }
- *previous++ = OP_BRAZERO + repeat_type;
- }
-
- /* If the maximum is greater than 1 and limited, we have to replicate
- in a nested fashion, sticking OP_BRAZERO before each set of brackets.
- The first one has to be handled carefully because it's the original
- copy, which has to be moved up. The remainder can be handled by code
- that is common with the non-zero minimum case below. We have to
- adjust the value or repeat_max, since one less copy is required. Once
- again, we may have to adjust any OP_RECURSE calls inside the group. */
-
- else
- {
- int offset;
- *code = OP_END;
- adjust_recurse(previous, 2 + LINK_SIZE, utf8, cd, save_hwm);
- memmove(previous + 2 + LINK_SIZE, previous, len);
- code += 2 + LINK_SIZE;
- *previous++ = OP_BRAZERO + repeat_type;
- *previous++ = OP_BRA;
-
- /* We chain together the bracket offset fields that have to be
- filled in later when the ends of the brackets are reached. */
-
- offset = (bralink == NULL)? 0 : previous - bralink;
- bralink = previous;
- PUTINC(previous, 0, offset);
- }
-
- repeat_max--;
- }
-
- /* If the minimum is greater than zero, replicate the group as many
- times as necessary, and adjust the maximum to the number of subsequent
- copies that we need. If we set a first char from the group, and didn't
- set a required char, copy the latter from the former. If there are any
- forward reference subroutine calls in the group, there will be entries on
- the workspace list; replicate these with an appropriate increment. */
-
- else
- {
- if (repeat_min > 1)
- {
- /* In the pre-compile phase, we don't actually do the replication. We
- just adjust the length as if we had. Do some paranoid checks for
- potential integer overflow. */
-
- if (lengthptr != NULL)
- {
- int delta = (repeat_min - 1)*length_prevgroup;
- if ((double)(repeat_min - 1)*(double)length_prevgroup >
- (double)INT_MAX ||
- OFLOW_MAX - *lengthptr < delta)
- {
- *errorcodeptr = ERR20;
- goto FAILED;
- }
- *lengthptr += delta;
- }
-
- /* This is compiling for real */
-
- else
- {
- if (groupsetfirstbyte && reqbyte < 0) reqbyte = firstbyte;
- for (i = 1; i < repeat_min; i++)
- {
- uschar *hc;
- uschar *this_hwm = cd->hwm;
- memcpy(code, previous, len);
- for (hc = save_hwm; hc < this_hwm; hc += LINK_SIZE)
- {
- PUT(cd->hwm, 0, GET(hc, 0) + len);
- cd->hwm += LINK_SIZE;
- }
- save_hwm = this_hwm;
- code += len;
- }
- }
- }
-
- if (repeat_max > 0) repeat_max -= repeat_min;
- }
-
- /* This code is common to both the zero and non-zero minimum cases. If
- the maximum is limited, it replicates the group in a nested fashion,
- remembering the bracket starts on a stack. In the case of a zero minimum,
- the first one was set up above. In all cases the repeat_max now specifies
- the number of additional copies needed. Again, we must remember to
- replicate entries on the forward reference list. */
-
- if (repeat_max >= 0)
- {
- /* In the pre-compile phase, we don't actually do the replication. We
- just adjust the length as if we had. For each repetition we must add 1
- to the length for BRAZERO and for all but the last repetition we must
- add 2 + 2*LINKSIZE to allow for the nesting that occurs. Do some
- paranoid checks to avoid integer overflow. */
-
- if (lengthptr != NULL && repeat_max > 0)
- {
- int delta = repeat_max * (length_prevgroup + 1 + 2 + 2*LINK_SIZE) -
- 2 - 2*LINK_SIZE; /* Last one doesn't nest */
- if ((double)repeat_max *
- (double)(length_prevgroup + 1 + 2 + 2*LINK_SIZE)
- > (double)INT_MAX ||
- OFLOW_MAX - *lengthptr < delta)
- {
- *errorcodeptr = ERR20;
- goto FAILED;
- }
- *lengthptr += delta;
- }
-
- /* This is compiling for real */
-
- else for (i = repeat_max - 1; i >= 0; i--)
- {
- uschar *hc;
- uschar *this_hwm = cd->hwm;
-
- *code++ = OP_BRAZERO + repeat_type;
-
- /* All but the final copy start a new nesting, maintaining the
- chain of brackets outstanding. */
-
- if (i != 0)
- {
- int offset;
- *code++ = OP_BRA;
- offset = (bralink == NULL)? 0 : code - bralink;
- bralink = code;
- PUTINC(code, 0, offset);
- }
-
- memcpy(code, previous, len);
- for (hc = save_hwm; hc < this_hwm; hc += LINK_SIZE)
- {
- PUT(cd->hwm, 0, GET(hc, 0) + len + ((i != 0)? 2+LINK_SIZE : 1));
- cd->hwm += LINK_SIZE;
- }
- save_hwm = this_hwm;
- code += len;
- }
-
- /* Now chain through the pending brackets, and fill in their length
- fields (which are holding the chain links pro tem). */
-
- while (bralink != NULL)
- {
- int oldlinkoffset;
- int offset = code - bralink + 1;
- uschar *bra = code - offset;
- oldlinkoffset = GET(bra, 1);
- bralink = (oldlinkoffset == 0)? NULL : bralink - oldlinkoffset;
- *code++ = OP_KET;
- PUTINC(code, 0, offset);
- PUT(bra, 1, offset);
- }
- }
-
- /* If the maximum is unlimited, set a repeater in the final copy. We
- can't just offset backwards from the current code point, because we
- don't know if there's been an options resetting after the ket. The
- correct offset was computed above.
-
- Then, when we are doing the actual compile phase, check to see whether
- this group is a non-atomic one that could match an empty string. If so,
- convert the initial operator to the S form (e.g. OP_BRA -> OP_SBRA) so
- that runtime checking can be done. [This check is also applied to
- atomic groups at runtime, but in a different way.] */
-
- else
- {
- uschar *ketcode = code - ketoffset;
- uschar *bracode = ketcode - GET(ketcode, 1);
- *ketcode = OP_KETRMAX + repeat_type;
- if (lengthptr == NULL && *bracode != OP_ONCE)
- {
- uschar *scode = bracode;
- do
- {
- if (could_be_empty_branch(scode, ketcode, utf8))
- {
- *bracode += OP_SBRA - OP_BRA;
- break;
- }
- scode += GET(scode, 1);
- }
- while (*scode == OP_ALT);
- }
- }
- }
-
- /* If previous is OP_FAIL, it was generated by an empty class [] in
- JavaScript mode. The other ways in which OP_FAIL can be generated, that is
- by (*FAIL) or (?!) set previous to NULL, which gives a "nothing to repeat"
- error above. We can just ignore the repeat in JS case. */
-
- else if (*previous == OP_FAIL) goto END_REPEAT;
-
- /* Else there's some kind of shambles */
-
- else
- {
- *errorcodeptr = ERR11;
- goto FAILED;
- }
-
- /* If the character following a repeat is '+', or if certain optimization
- tests above succeeded, possessive_quantifier is TRUE. For some of the
- simpler opcodes, there is an special alternative opcode for this. For
- anything else, we wrap the entire repeated item inside OP_ONCE brackets.
- The '+' notation is just syntactic sugar, taken from Sun's Java package,
- but the special opcodes can optimize it a bit. The repeated item starts at
- tempcode, not at previous, which might be the first part of a string whose
- (former) last char we repeated.
-
- Possessifying an 'exact' quantifier has no effect, so we can ignore it. But
- an 'upto' may follow. We skip over an 'exact' item, and then test the
- length of what remains before proceeding. */
-
- if (possessive_quantifier)
- {
- int len;
- if (*tempcode == OP_EXACT || *tempcode == OP_TYPEEXACT ||
- *tempcode == OP_NOTEXACT)
- tempcode += _pcre_OP_lengths[*tempcode] +
- ((*tempcode == OP_TYPEEXACT &&
- (tempcode[3] == OP_PROP || tempcode[3] == OP_NOTPROP))? 2:0);
- len = code - tempcode;
- if (len > 0) switch (*tempcode)
- {
- case OP_STAR: *tempcode = OP_POSSTAR; break;
- case OP_PLUS: *tempcode = OP_POSPLUS; break;
- case OP_QUERY: *tempcode = OP_POSQUERY; break;
- case OP_UPTO: *tempcode = OP_POSUPTO; break;
-
- case OP_TYPESTAR: *tempcode = OP_TYPEPOSSTAR; break;
- case OP_TYPEPLUS: *tempcode = OP_TYPEPOSPLUS; break;
- case OP_TYPEQUERY: *tempcode = OP_TYPEPOSQUERY; break;
- case OP_TYPEUPTO: *tempcode = OP_TYPEPOSUPTO; break;
-
- case OP_NOTSTAR: *tempcode = OP_NOTPOSSTAR; break;
- case OP_NOTPLUS: *tempcode = OP_NOTPOSPLUS; break;
- case OP_NOTQUERY: *tempcode = OP_NOTPOSQUERY; break;
- case OP_NOTUPTO: *tempcode = OP_NOTPOSUPTO; break;
-
- default:
- memmove(tempcode + 1+LINK_SIZE, tempcode, len);
- code += 1 + LINK_SIZE;
- len += 1 + LINK_SIZE;
- tempcode[0] = OP_ONCE;
- *code++ = OP_KET;
- PUTINC(code, 0, len);
- PUT(tempcode, 1, len);
- break;
- }
- }
-
- /* In all case we no longer have a previous item. We also set the
- "follows varying string" flag for subsequently encountered reqbytes if
- it isn't already set and we have just passed a varying length item. */
-
- END_REPEAT:
- previous = NULL;
- cd->req_varyopt |= reqvary;
- break;
-
-
- /* ===================================================================*/
- /* Start of nested parenthesized sub-expression, or comment or lookahead or
- lookbehind or option setting or condition or all the other extended
- parenthesis forms. */
-
- case '(':
- newoptions = options;
- skipbytes = 0;
- bravalue = OP_CBRA;
- save_hwm = cd->hwm;
- reset_bracount = FALSE;
-
- /* First deal with various "verbs" that can be introduced by '*'. */
-
- if (*(++ptr) == '*' && (cd->ctypes[ptr[1]] & ctype_letter) != 0)
- {
- int i, namelen;
- const char *vn = verbnames;
- const uschar *name = ++ptr;
- previous = NULL;
- while ((cd->ctypes[*++ptr] & ctype_letter) != 0);
- if (*ptr == ':')
- {
- *errorcodeptr = ERR59; /* Not supported */
- goto FAILED;
- }
- if (*ptr != ')')
- {
- *errorcodeptr = ERR60;
- goto FAILED;
- }
- namelen = ptr - name;
- for (i = 0; i < verbcount; i++)
- {
- if (namelen == verbs[i].len &&
- strncmp((char *)name, vn, namelen) == 0)
- {
- *code = verbs[i].op;
- if (*code++ == OP_ACCEPT) cd->had_accept = TRUE;
- break;
- }
- vn += verbs[i].len + 1;
- }
- if (i < verbcount) continue;
- *errorcodeptr = ERR60;
- goto FAILED;
- }
-
- /* Deal with the extended parentheses; all are introduced by '?', and the
- appearance of any of them means that this is not a capturing group. */
-
- else if (*ptr == '?')
- {
- int i, set, unset, namelen;
- int *optset;
- const uschar *name;
- uschar *slot;
-
- switch (*(++ptr))
- {
- case '#': /* Comment; skip to ket */
- ptr++;
- while (*ptr != 0 && *ptr != ')') ptr++;
- if (*ptr == 0)
- {
- *errorcodeptr = ERR18;
- goto FAILED;
- }
- continue;
-
-
- /* ------------------------------------------------------------ */
- case '|': /* Reset capture count for each branch */
- reset_bracount = TRUE;
- /* Fall through */
-
- /* ------------------------------------------------------------ */
- case ':': /* Non-capturing bracket */
- bravalue = OP_BRA;
- ptr++;
- break;
-
-
- /* ------------------------------------------------------------ */
- case '(':
- bravalue = OP_COND; /* Conditional group */
-
- /* A condition can be an assertion, a number (referring to a numbered
- group), a name (referring to a named group), or 'R', referring to
- recursion. R<digits> and R&name are also permitted for recursion tests.
-
- There are several syntaxes for testing a named group: (?(name)) is used
- by Python; Perl 5.10 onwards uses (?(<name>) or (?('name')).
-
- There are two unfortunate ambiguities, caused by history. (a) 'R' can
- be the recursive thing or the name 'R' (and similarly for 'R' followed
- by digits), and (b) a number could be a name that consists of digits.
- In both cases, we look for a name first; if not found, we try the other
- cases. */
-
- /* For conditions that are assertions, check the syntax, and then exit
- the switch. This will take control down to where bracketed groups,
- including assertions, are processed. */
-
- if (ptr[1] == '?' && (ptr[2] == '=' || ptr[2] == '!' || ptr[2] == '<'))
- break;
-
- /* Most other conditions use OP_CREF (a couple change to OP_RREF
- below), and all need to skip 3 bytes at the start of the group. */
-
- code[1+LINK_SIZE] = OP_CREF;
- skipbytes = 3;
- refsign = -1;
-
- /* Check for a test for recursion in a named group. */
-
- if (ptr[1] == 'R' && ptr[2] == '&')
- {
- terminator = -1;
- ptr += 2;
- code[1+LINK_SIZE] = OP_RREF; /* Change the type of test */
- }
-
- /* Check for a test for a named group's having been set, using the Perl
- syntax (?(<name>) or (?('name') */
-
- else if (ptr[1] == '<')
- {
- terminator = '>';
- ptr++;
- }
- else if (ptr[1] == '\'')
- {
- terminator = '\'';
- ptr++;
- }
- else
- {
- terminator = 0;
- if (ptr[1] == '-' || ptr[1] == '+') refsign = *(++ptr);
- }
-
- /* We now expect to read a name; any thing else is an error */
-
- if ((cd->ctypes[ptr[1]] & ctype_word) == 0)
- {
- ptr += 1; /* To get the right offset */
- *errorcodeptr = ERR28;
- goto FAILED;
- }
-
- /* Read the name, but also get it as a number if it's all digits */
-
- recno = 0;
- name = ++ptr;
- while ((cd->ctypes[*ptr] & ctype_word) != 0)
- {
- if (recno >= 0)
- recno = ((digitab[*ptr] & ctype_digit) != 0)?
- recno * 10 + *ptr - '0' : -1;
- ptr++;
- }
- namelen = ptr - name;
-
- if ((terminator > 0 && *ptr++ != terminator) || *ptr++ != ')')
- {
- ptr--; /* Error offset */
- *errorcodeptr = ERR26;
- goto FAILED;
- }
-
- /* Do no further checking in the pre-compile phase. */
-
- if (lengthptr != NULL) break;
-
- /* In the real compile we do the work of looking for the actual
- reference. If the string started with "+" or "-" we require the rest to
- be digits, in which case recno will be set. */
-
- if (refsign > 0)
- {
- if (recno <= 0)
- {
- *errorcodeptr = ERR58;
- goto FAILED;
- }
- recno = (refsign == '-')?
- cd->bracount - recno + 1 : recno +cd->bracount;
- if (recno <= 0 || recno > cd->final_bracount)
- {
- *errorcodeptr = ERR15;
- goto FAILED;
- }
- PUT2(code, 2+LINK_SIZE, recno);
- break;
- }
-
- /* Otherwise (did not start with "+" or "-"), start by looking for the
- name. */
-
- slot = cd->name_table;
- for (i = 0; i < cd->names_found; i++)
- {
- if (strncmp((char *)name, (char *)slot+2, namelen) == 0) break;
- slot += cd->name_entry_size;
- }
-
- /* Found a previous named subpattern */
-
- if (i < cd->names_found)
- {
- recno = GET2(slot, 0);
- PUT2(code, 2+LINK_SIZE, recno);
- }
-
- /* Search the pattern for a forward reference */
-
- else if ((i = find_parens(ptr, cd, name, namelen,
- (options & PCRE_EXTENDED) != 0)) > 0)
- {
- PUT2(code, 2+LINK_SIZE, i);
- }
-
- /* If terminator == 0 it means that the name followed directly after
- the opening parenthesis [e.g. (?(abc)...] and in this case there are
- some further alternatives to try. For the cases where terminator != 0
- [things like (?(<name>... or (?('name')... or (?(R&name)... ] we have
- now checked all the possibilities, so give an error. */
-
- else if (terminator != 0)
- {
- *errorcodeptr = ERR15;
- goto FAILED;
- }
-
- /* Check for (?(R) for recursion. Allow digits after R to specify a
- specific group number. */
-
- else if (*name == 'R')
- {
- recno = 0;
- for (i = 1; i < namelen; i++)
- {
- if ((digitab[name[i]] & ctype_digit) == 0)
- {
- *errorcodeptr = ERR15;
- goto FAILED;
- }
- recno = recno * 10 + name[i] - '0';
- }
- if (recno == 0) recno = RREF_ANY;
- code[1+LINK_SIZE] = OP_RREF; /* Change test type */
- PUT2(code, 2+LINK_SIZE, recno);
- }
-
- /* Similarly, check for the (?(DEFINE) "condition", which is always
- false. */
-
- else if (namelen == 6 && strncmp((char *)name, "DEFINE", 6) == 0)
- {
- code[1+LINK_SIZE] = OP_DEF;
- skipbytes = 1;
- }
-
- /* Check for the "name" actually being a subpattern number. We are
- in the second pass here, so final_bracount is set. */
-
- else if (recno > 0 && recno <= cd->final_bracount)
- {
- PUT2(code, 2+LINK_SIZE, recno);
- }
-
- /* Either an unidentified subpattern, or a reference to (?(0) */
-
- else
- {
- *errorcodeptr = (recno == 0)? ERR35: ERR15;
- goto FAILED;
- }
- break;
-
-
- /* ------------------------------------------------------------ */
- case '=': /* Positive lookahead */
- bravalue = OP_ASSERT;
- ptr++;
- break;
-
-
- /* ------------------------------------------------------------ */
- case '!': /* Negative lookahead */
- ptr++;
- if (*ptr == ')') /* Optimize (?!) */
- {
- *code++ = OP_FAIL;
- previous = NULL;
- continue;
- }
- bravalue = OP_ASSERT_NOT;
- break;
-
-
- /* ------------------------------------------------------------ */
- case '<': /* Lookbehind or named define */
- switch (ptr[1])
- {
- case '=': /* Positive lookbehind */
- bravalue = OP_ASSERTBACK;
- ptr += 2;
- break;
-
- case '!': /* Negative lookbehind */
- bravalue = OP_ASSERTBACK_NOT;
- ptr += 2;
- break;
-
- default: /* Could be name define, else bad */
- if ((cd->ctypes[ptr[1]] & ctype_word) != 0) goto DEFINE_NAME;
- ptr++; /* Correct offset for error */
- *errorcodeptr = ERR24;
- goto FAILED;
- }
- break;
-
-
- /* ------------------------------------------------------------ */
- case '>': /* One-time brackets */
- bravalue = OP_ONCE;
- ptr++;
- break;
-
-
- /* ------------------------------------------------------------ */
- case 'C': /* Callout - may be followed by digits; */
- previous_callout = code; /* Save for later completion */
- after_manual_callout = 1; /* Skip one item before completing */
- *code++ = OP_CALLOUT;
- {
- int n = 0;
- while ((digitab[*(++ptr)] & ctype_digit) != 0)
- n = n * 10 + *ptr - '0';
- if (*ptr != ')')
- {
- *errorcodeptr = ERR39;
- goto FAILED;
- }
- if (n > 255)
- {
- *errorcodeptr = ERR38;
- goto FAILED;
- }
- *code++ = n;
- PUT(code, 0, ptr - cd->start_pattern + 1); /* Pattern offset */
- PUT(code, LINK_SIZE, 0); /* Default length */
- code += 2 * LINK_SIZE;
- }
- previous = NULL;
- continue;
-
-
- /* ------------------------------------------------------------ */
- case 'P': /* Python-style named subpattern handling */
- if (*(++ptr) == '=' || *ptr == '>') /* Reference or recursion */
- {
- is_recurse = *ptr == '>';
- terminator = ')';
- goto NAMED_REF_OR_RECURSE;
- }
- else if (*ptr != '<') /* Test for Python-style definition */
- {
- *errorcodeptr = ERR41;
- goto FAILED;
- }
- /* Fall through to handle (?P< as (?< is handled */
-
-
- /* ------------------------------------------------------------ */
- DEFINE_NAME: /* Come here from (?< handling */
- case '\'':
- {
- terminator = (*ptr == '<')? '>' : '\'';
- name = ++ptr;
-
- while ((cd->ctypes[*ptr] & ctype_word) != 0) ptr++;
- namelen = ptr - name;
-
- /* In the pre-compile phase, just do a syntax check. */
-
- if (lengthptr != NULL)
- {
- if (*ptr != terminator)
- {
- *errorcodeptr = ERR42;
- goto FAILED;
- }
- if (cd->names_found >= MAX_NAME_COUNT)
- {
- *errorcodeptr = ERR49;
- goto FAILED;
- }
- if (namelen + 3 > cd->name_entry_size)
- {
- cd->name_entry_size = namelen + 3;
- if (namelen > MAX_NAME_SIZE)
- {
- *errorcodeptr = ERR48;
- goto FAILED;
- }
- }
- }
-
- /* In the real compile, create the entry in the table */
-
- else
- {
- slot = cd->name_table;
- for (i = 0; i < cd->names_found; i++)
- {
- int crc = memcmp(name, slot+2, namelen);
- if (crc == 0)
- {
- if (slot[2+namelen] == 0)
- {
- if ((options & PCRE_DUPNAMES) == 0)
- {
- *errorcodeptr = ERR43;
- goto FAILED;
- }
- }
- else crc = -1; /* Current name is substring */
- }
- if (crc < 0)
- {
- memmove(slot + cd->name_entry_size, slot,
- (cd->names_found - i) * cd->name_entry_size);
- break;
- }
- slot += cd->name_entry_size;
- }
-
- PUT2(slot, 0, cd->bracount + 1);
- memcpy(slot + 2, name, namelen);
- slot[2+namelen] = 0;
- }
- }
-
- /* In both cases, count the number of names we've encountered. */
-
- ptr++; /* Move past > or ' */
- cd->names_found++;
- goto NUMBERED_GROUP;
-
-
- /* ------------------------------------------------------------ */
- case '&': /* Perl recursion/subroutine syntax */
- terminator = ')';
- is_recurse = TRUE;
- /* Fall through */
-
- /* We come here from the Python syntax above that handles both
- references (?P=name) and recursion (?P>name), as well as falling
- through from the Perl recursion syntax (?&name). We also come here from
- the Perl \k<name> or \k'name' back reference syntax and the \k{name}
- .NET syntax, and the Oniguruma \g<...> and \g'...' subroutine syntax. */
-
- NAMED_REF_OR_RECURSE:
- name = ++ptr;
- while ((cd->ctypes[*ptr] & ctype_word) != 0) ptr++;
- namelen = ptr - name;
-
- /* In the pre-compile phase, do a syntax check and set a dummy
- reference number. */
-
- if (lengthptr != NULL)
- {
- if (namelen == 0)
- {
- *errorcodeptr = ERR62;
- goto FAILED;
- }
- if (*ptr != terminator)
- {
- *errorcodeptr = ERR42;
- goto FAILED;
- }
- if (namelen > MAX_NAME_SIZE)
- {
- *errorcodeptr = ERR48;
- goto FAILED;
- }
- recno = 0;
- }
-
- /* In the real compile, seek the name in the table. We check the name
- first, and then check that we have reached the end of the name in the
- table. That way, if the name that is longer than any in the table,
- the comparison will fail without reading beyond the table entry. */
-
- else
- {
- slot = cd->name_table;
- for (i = 0; i < cd->names_found; i++)
- {
- if (strncmp((char *)name, (char *)slot+2, namelen) == 0 &&
- slot[2+namelen] == 0)
- break;
- slot += cd->name_entry_size;
- }
-
- if (i < cd->names_found) /* Back reference */
- {
- recno = GET2(slot, 0);
- }
- else if ((recno = /* Forward back reference */
- find_parens(ptr, cd, name, namelen,
- (options & PCRE_EXTENDED) != 0)) <= 0)
- {
- *errorcodeptr = ERR15;
- goto FAILED;
- }
- }
-
- /* In both phases, we can now go to the code than handles numerical
- recursion or backreferences. */
-
- if (is_recurse) goto HANDLE_RECURSION;
- else goto HANDLE_REFERENCE;
-
-
- /* ------------------------------------------------------------ */
- case 'R': /* Recursion */
- ptr++; /* Same as (?0) */
- /* Fall through */
-
-
- /* ------------------------------------------------------------ */
- case '-': case '+':
- case '0': case '1': case '2': case '3': case '4': /* Recursion or */
- case '5': case '6': case '7': case '8': case '9': /* subroutine */
- {
- const uschar *called;
- terminator = ')';
-
- /* Come here from the \g<...> and \g'...' code (Oniguruma
- compatibility). However, the syntax has been checked to ensure that
- the ... are a (signed) number, so that neither ERR63 nor ERR29 will
- be called on this path, nor with the jump to OTHER_CHAR_AFTER_QUERY
- ever be taken. */
-
- HANDLE_NUMERICAL_RECURSION:
-
- if ((refsign = *ptr) == '+')
- {
- ptr++;
- if ((digitab[*ptr] & ctype_digit) == 0)
- {
- *errorcodeptr = ERR63;
- goto FAILED;
- }
- }
- else if (refsign == '-')
- {
- if ((digitab[ptr[1]] & ctype_digit) == 0)
- goto OTHER_CHAR_AFTER_QUERY;
- ptr++;
- }
-
- recno = 0;
- while((digitab[*ptr] & ctype_digit) != 0)
- recno = recno * 10 + *ptr++ - '0';
-
- if (*ptr != terminator)
- {
- *errorcodeptr = ERR29;
- goto FAILED;
- }
-
- if (refsign == '-')
- {
- if (recno == 0)
- {
- *errorcodeptr = ERR58;
- goto FAILED;
- }
- recno = cd->bracount - recno + 1;
- if (recno <= 0)
- {
- *errorcodeptr = ERR15;
- goto FAILED;
- }
- }
- else if (refsign == '+')
- {
- if (recno == 0)
- {
- *errorcodeptr = ERR58;
- goto FAILED;
- }
- recno += cd->bracount;
- }
-
- /* Come here from code above that handles a named recursion */
-
- HANDLE_RECURSION:
-
- previous = code;
- called = cd->start_code;
-
- /* When we are actually compiling, find the bracket that is being
- referenced. Temporarily end the regex in case it doesn't exist before
- this point. If we end up with a forward reference, first check that
- the bracket does occur later so we can give the error (and position)
- now. Then remember this forward reference in the workspace so it can
- be filled in at the end. */
-
- if (lengthptr == NULL)
- {
- *code = OP_END;
- if (recno != 0) called = find_bracket(cd->start_code, utf8, recno);
-
- /* Forward reference */
-
- if (called == NULL)
- {
- if (find_parens(ptr, cd, NULL, recno,
- (options & PCRE_EXTENDED) != 0) < 0)
- {
- *errorcodeptr = ERR15;
- goto FAILED;
- }
- called = cd->start_code + recno;
- PUTINC(cd->hwm, 0, code + 2 + LINK_SIZE - cd->start_code);
- }
-
- /* If not a forward reference, and the subpattern is still open,
- this is a recursive call. We check to see if this is a left
- recursion that could loop for ever, and diagnose that case. */
-
- else if (GET(called, 1) == 0 &&
- could_be_empty(called, code, bcptr, utf8))
- {
- *errorcodeptr = ERR40;
- goto FAILED;
- }
- }
-
- /* Insert the recursion/subroutine item, automatically wrapped inside
- "once" brackets. Set up a "previous group" length so that a
- subsequent quantifier will work. */
-
- *code = OP_ONCE;
- PUT(code, 1, 2 + 2*LINK_SIZE);
- code += 1 + LINK_SIZE;
-
- *code = OP_RECURSE;
- PUT(code, 1, called - cd->start_code);
- code += 1 + LINK_SIZE;
-
- *code = OP_KET;
- PUT(code, 1, 2 + 2*LINK_SIZE);
- code += 1 + LINK_SIZE;
-
- length_prevgroup = 3 + 3*LINK_SIZE;
- }
-
- /* Can't determine a first byte now */
-
- if (firstbyte == REQ_UNSET) firstbyte = REQ_NONE;
- continue;
-
-
- /* ------------------------------------------------------------ */
- default: /* Other characters: check option setting */
- OTHER_CHAR_AFTER_QUERY:
- set = unset = 0;
- optset = &set;
-
- while (*ptr != ')' && *ptr != ':')
- {
- switch (*ptr++)
- {
- case '-': optset = &unset; break;
-
- case 'J': /* Record that it changed in the external options */
- *optset |= PCRE_DUPNAMES;
- cd->external_flags |= PCRE_JCHANGED;
- break;
-
- case 'i': *optset |= PCRE_CASELESS; break;
- case 'm': *optset |= PCRE_MULTILINE; break;
- case 's': *optset |= PCRE_DOTALL; break;
- case 'x': *optset |= PCRE_EXTENDED; break;
- case 'U': *optset |= PCRE_UNGREEDY; break;
- case 'X': *optset |= PCRE_EXTRA; break;
-
- default: *errorcodeptr = ERR12;
- ptr--; /* Correct the offset */
- goto FAILED;
- }
- }
-
- /* Set up the changed option bits, but don't change anything yet. */
-
- newoptions = (options | set) & (~unset);
-
- /* If the options ended with ')' this is not the start of a nested
- group with option changes, so the options change at this level. If this
- item is right at the start of the pattern, the options can be
- abstracted and made external in the pre-compile phase, and ignored in
- the compile phase. This can be helpful when matching -- for instance in
- caseless checking of required bytes.
-
- If the code pointer is not (cd->start_code + 1 + LINK_SIZE), we are
- definitely *not* at the start of the pattern because something has been
- compiled. In the pre-compile phase, however, the code pointer can have
- that value after the start, because it gets reset as code is discarded
- during the pre-compile. However, this can happen only at top level - if
- we are within parentheses, the starting BRA will still be present. At
- any parenthesis level, the length value can be used to test if anything
- has been compiled at that level. Thus, a test for both these conditions
- is necessary to ensure we correctly detect the start of the pattern in
- both phases.
-
- If we are not at the pattern start, compile code to change the ims
- options if this setting actually changes any of them. We also pass the
- new setting back so that it can be put at the start of any following
- branches, and when this group ends (if we are in a group), a resetting
- item can be compiled. */
-
- if (*ptr == ')')
- {
- if (code == cd->start_code + 1 + LINK_SIZE &&
- (lengthptr == NULL || *lengthptr == 2 + 2*LINK_SIZE))
- {
- cd->external_options = newoptions;
- options = newoptions;
- }
- else
- {
- if ((options & PCRE_IMS) != (newoptions & PCRE_IMS))
- {
- *code++ = OP_OPT;
- *code++ = newoptions & PCRE_IMS;
- }
-
- /* Change options at this level, and pass them back for use
- in subsequent branches. Reset the greedy defaults and the case
- value for firstbyte and reqbyte. */
-
- *optionsptr = options = newoptions;
- greedy_default = ((newoptions & PCRE_UNGREEDY) != 0);
- greedy_non_default = greedy_default ^ 1;
- req_caseopt = ((options & PCRE_CASELESS) != 0)? REQ_CASELESS : 0;
- }
-
- previous = NULL; /* This item can't be repeated */
- continue; /* It is complete */
- }
-
- /* If the options ended with ':' we are heading into a nested group
- with possible change of options. Such groups are non-capturing and are
- not assertions of any kind. All we need to do is skip over the ':';
- the newoptions value is handled below. */
-
- bravalue = OP_BRA;
- ptr++;
- } /* End of switch for character following (? */
- } /* End of (? handling */
-
- /* Opening parenthesis not followed by '?'. If PCRE_NO_AUTO_CAPTURE is set,
- all unadorned brackets become non-capturing and behave like (?:...)
- brackets. */
-
- else if ((options & PCRE_NO_AUTO_CAPTURE) != 0)
- {
- bravalue = OP_BRA;
- }
-
- /* Else we have a capturing group. */
-
- else
- {
- NUMBERED_GROUP:
- cd->bracount += 1;
- PUT2(code, 1+LINK_SIZE, cd->bracount);
- skipbytes = 2;
- }
-
- /* Process nested bracketed regex. Assertions may not be repeated, but
- other kinds can be. All their opcodes are >= OP_ONCE. We copy code into a
- non-register variable in order to be able to pass its address because some
- compilers complain otherwise. Pass in a new setting for the ims options if
- they have changed. */
-
- previous = (bravalue >= OP_ONCE)? code : NULL;
- *code = bravalue;
- tempcode = code;
- tempreqvary = cd->req_varyopt; /* Save value before bracket */
- length_prevgroup = 0; /* Initialize for pre-compile phase */
-
- if (!compile_regex(
- newoptions, /* The complete new option state */
- options & PCRE_IMS, /* The previous ims option state */
- &tempcode, /* Where to put code (updated) */
- &ptr, /* Input pointer (updated) */
- errorcodeptr, /* Where to put an error message */
- (bravalue == OP_ASSERTBACK ||
- bravalue == OP_ASSERTBACK_NOT), /* TRUE if back assert */
- reset_bracount, /* True if (?| group */
- skipbytes, /* Skip over bracket number */
- &subfirstbyte, /* For possible first char */
- &subreqbyte, /* For possible last char */
- bcptr, /* Current branch chain */
- cd, /* Tables block */
- (lengthptr == NULL)? NULL : /* Actual compile phase */
- &length_prevgroup /* Pre-compile phase */
- ))
- goto FAILED;
-
- /* At the end of compiling, code is still pointing to the start of the
- group, while tempcode has been updated to point past the end of the group
- and any option resetting that may follow it. The pattern pointer (ptr)
- is on the bracket. */
-
- /* If this is a conditional bracket, check that there are no more than
- two branches in the group, or just one if it's a DEFINE group. We do this
- in the real compile phase, not in the pre-pass, where the whole group may
- not be available. */
-
- if (bravalue == OP_COND && lengthptr == NULL)
- {
- uschar *tc = code;
- int condcount = 0;
-
- do {
- condcount++;
- tc += GET(tc,1);
- }
- while (*tc != OP_KET);
-
- /* A DEFINE group is never obeyed inline (the "condition" is always
- false). It must have only one branch. */
-
- if (code[LINK_SIZE+1] == OP_DEF)
- {
- if (condcount > 1)
- {
- *errorcodeptr = ERR54;
- goto FAILED;
- }
- bravalue = OP_DEF; /* Just a flag to suppress char handling below */
- }
-
- /* A "normal" conditional group. If there is just one branch, we must not
- make use of its firstbyte or reqbyte, because this is equivalent to an
- empty second branch. */
-
- else
- {
- if (condcount > 2)
- {
- *errorcodeptr = ERR27;
- goto FAILED;
- }
- if (condcount == 1) subfirstbyte = subreqbyte = REQ_NONE;
- }
- }
-
- /* Error if hit end of pattern */
-
- if (*ptr != ')')
- {
- *errorcodeptr = ERR14;
- goto FAILED;
- }
-
- /* In the pre-compile phase, update the length by the length of the group,
- less the brackets at either end. Then reduce the compiled code to just a
- set of non-capturing brackets so that it doesn't use much memory if it is
- duplicated by a quantifier.*/
-
- if (lengthptr != NULL)
- {
- if (OFLOW_MAX - *lengthptr < length_prevgroup - 2 - 2*LINK_SIZE)
- {
- *errorcodeptr = ERR20;
- goto FAILED;
- }
- *lengthptr += length_prevgroup - 2 - 2*LINK_SIZE;
- *code++ = OP_BRA;
- PUTINC(code, 0, 1 + LINK_SIZE);
- *code++ = OP_KET;
- PUTINC(code, 0, 1 + LINK_SIZE);
- break; /* No need to waste time with special character handling */
- }
-
- /* Otherwise update the main code pointer to the end of the group. */
-
- code = tempcode;
-
- /* For a DEFINE group, required and first character settings are not
- relevant. */
-
- if (bravalue == OP_DEF) break;
-
- /* Handle updating of the required and first characters for other types of
- group. Update for normal brackets of all kinds, and conditions with two
- branches (see code above). If the bracket is followed by a quantifier with
- zero repeat, we have to back off. Hence the definition of zeroreqbyte and
- zerofirstbyte outside the main loop so that they can be accessed for the
- back off. */
-
- zeroreqbyte = reqbyte;
- zerofirstbyte = firstbyte;
- groupsetfirstbyte = FALSE;
-
- if (bravalue >= OP_ONCE)
- {
- /* If we have not yet set a firstbyte in this branch, take it from the
- subpattern, remembering that it was set here so that a repeat of more
- than one can replicate it as reqbyte if necessary. If the subpattern has
- no firstbyte, set "none" for the whole branch. In both cases, a zero
- repeat forces firstbyte to "none". */
-
- if (firstbyte == REQ_UNSET)
- {
- if (subfirstbyte >= 0)
- {
- firstbyte = subfirstbyte;
- groupsetfirstbyte = TRUE;
- }
- else firstbyte = REQ_NONE;
- zerofirstbyte = REQ_NONE;
- }
-
- /* If firstbyte was previously set, convert the subpattern's firstbyte
- into reqbyte if there wasn't one, using the vary flag that was in
- existence beforehand. */
-
- else if (subfirstbyte >= 0 && subreqbyte < 0)
- subreqbyte = subfirstbyte | tempreqvary;
-
- /* If the subpattern set a required byte (or set a first byte that isn't
- really the first byte - see above), set it. */
-
- if (subreqbyte >= 0) reqbyte = subreqbyte;
- }
-
- /* For a forward assertion, we take the reqbyte, if set. This can be
- helpful if the pattern that follows the assertion doesn't set a different
- char. For example, it's useful for /(?=abcde).+/. We can't set firstbyte
- for an assertion, however because it leads to incorrect effect for patterns
- such as /(?=a)a.+/ when the "real" "a" would then become a reqbyte instead
- of a firstbyte. This is overcome by a scan at the end if there's no
- firstbyte, looking for an asserted first char. */
-
- else if (bravalue == OP_ASSERT && subreqbyte >= 0) reqbyte = subreqbyte;
- break; /* End of processing '(' */
-
-
- /* ===================================================================*/
- /* Handle metasequences introduced by \. For ones like \d, the ESC_ values
- are arranged to be the negation of the corresponding OP_values. For the
- back references, the values are ESC_REF plus the reference number. Only
- back references and those types that consume a character may be repeated.
- We can test for values between ESC_b and ESC_Z for the latter; this may
- have to change if any new ones are ever created. */
-
- case '\\':
- tempptr = ptr;
- c = check_escape(&ptr, errorcodeptr, cd->bracount, options, FALSE);
- if (*errorcodeptr != 0) goto FAILED;
-
- if (c < 0)
- {
- if (-c == ESC_Q) /* Handle start of quoted string */
- {
- if (ptr[1] == '\\' && ptr[2] == 'E') ptr += 2; /* avoid empty string */
- else inescq = TRUE;
- continue;
- }
-
- if (-c == ESC_E) continue; /* Perl ignores an orphan \E */
-
- /* For metasequences that actually match a character, we disable the
- setting of a first character if it hasn't already been set. */
-
- if (firstbyte == REQ_UNSET && -c > ESC_b && -c < ESC_Z)
- firstbyte = REQ_NONE;
-
- /* Set values to reset to if this is followed by a zero repeat. */
-
- zerofirstbyte = firstbyte;
- zeroreqbyte = reqbyte;
-
- /* \g<name> or \g'name' is a subroutine call by name and \g<n> or \g'n'
- is a subroutine call by number (Oniguruma syntax). In fact, the value
- -ESC_g is returned only for these cases. So we don't need to check for <
- or ' if the value is -ESC_g. For the Perl syntax \g{n} the value is
- -ESC_REF+n, and for the Perl syntax \g{name} the result is -ESC_k (as
- that is a synonym for a named back reference). */
-
- if (-c == ESC_g)
- {
- const uschar *p;
- save_hwm = cd->hwm; /* Normally this is set when '(' is read */
- terminator = (*(++ptr) == '<')? '>' : '\'';
-
- /* These two statements stop the compiler for warning about possibly
- unset variables caused by the jump to HANDLE_NUMERICAL_RECURSION. In
- fact, because we actually check for a number below, the paths that
- would actually be in error are never taken. */
-
- skipbytes = 0;
- reset_bracount = FALSE;
-
- /* Test for a name */
-
- if (ptr[1] != '+' && ptr[1] != '-')
- {
- BOOL isnumber = TRUE;
- for (p = ptr + 1; *p != 0 && *p != terminator; p++)
- {
- if ((cd->ctypes[*p] & ctype_digit) == 0) isnumber = FALSE;
- if ((cd->ctypes[*p] & ctype_word) == 0) break;
- }
- if (*p != terminator)
- {
- *errorcodeptr = ERR57;
- break;
- }
- if (isnumber)
- {
- ptr++;
- goto HANDLE_NUMERICAL_RECURSION;
- }
- is_recurse = TRUE;
- goto NAMED_REF_OR_RECURSE;
- }
-
- /* Test a signed number in angle brackets or quotes. */
-
- p = ptr + 2;
- while ((digitab[*p] & ctype_digit) != 0) p++;
- if (*p != terminator)
- {
- *errorcodeptr = ERR57;
- break;
- }
- ptr++;
- goto HANDLE_NUMERICAL_RECURSION;
- }
-
- /* \k<name> or \k'name' is a back reference by name (Perl syntax).
- We also support \k{name} (.NET syntax) */
-
- if (-c == ESC_k && (ptr[1] == '<' || ptr[1] == '\'' || ptr[1] == '{'))
- {
- is_recurse = FALSE;
- terminator = (*(++ptr) == '<')? '>' : (*ptr == '\'')? '\'' : '}';
- goto NAMED_REF_OR_RECURSE;
- }
-
- /* Back references are handled specially; must disable firstbyte if
- not set to cope with cases like (?=(\w+))\1: which would otherwise set
- ':' later. */
-
- if (-c >= ESC_REF)
- {
- recno = -c - ESC_REF;
-
- HANDLE_REFERENCE: /* Come here from named backref handling */
- if (firstbyte == REQ_UNSET) firstbyte = REQ_NONE;
- previous = code;
- *code++ = OP_REF;
- PUT2INC(code, 0, recno);
- cd->backref_map |= (recno < 32)? (1 << recno) : 1;
- if (recno > cd->top_backref) cd->top_backref = recno;
- }
-
- /* So are Unicode property matches, if supported. */
-
-#ifdef SUPPORT_UCP
- else if (-c == ESC_P || -c == ESC_p)
- {
- BOOL negated;
- int pdata;
- int ptype = get_ucp(&ptr, &negated, &pdata, errorcodeptr);
- if (ptype < 0) goto FAILED;
- previous = code;
- *code++ = ((-c == ESC_p) != negated)? OP_PROP : OP_NOTPROP;
- *code++ = ptype;
- *code++ = pdata;
- }
-#else
-
- /* If Unicode properties are not supported, \X, \P, and \p are not
- allowed. */
-
- else if (-c == ESC_X || -c == ESC_P || -c == ESC_p)
- {
- *errorcodeptr = ERR45;
- goto FAILED;
- }
-#endif
-
- /* For the rest (including \X when Unicode properties are supported), we
- can obtain the OP value by negating the escape value. */
-
- else
- {
- previous = (-c > ESC_b && -c < ESC_Z)? code : NULL;
- *code++ = -c;
- }
- continue;
- }
-
- /* We have a data character whose value is in c. In UTF-8 mode it may have
- a value > 127. We set its representation in the length/buffer, and then
- handle it as a data character. */
-
-#ifdef SUPPORT_UTF8
- if (utf8 && c > 127)
- mclength = _pcre_ord2utf8(c, mcbuffer);
- else
-#endif
-
- {
- mcbuffer[0] = c;
- mclength = 1;
- }
- goto ONE_CHAR;
-
-
- /* ===================================================================*/
- /* Handle a literal character. It is guaranteed not to be whitespace or #
- when the extended flag is set. If we are in UTF-8 mode, it may be a
- multi-byte literal character. */
-
- default:
- NORMAL_CHAR:
- mclength = 1;
- mcbuffer[0] = c;
-
-#ifdef SUPPORT_UTF8
- if (utf8 && c >= 0xc0)
- {
- while ((ptr[1] & 0xc0) == 0x80)
- mcbuffer[mclength++] = *(++ptr);
- }
-#endif
-
- /* At this point we have the character's bytes in mcbuffer, and the length
- in mclength. When not in UTF-8 mode, the length is always 1. */
-
- ONE_CHAR:
- previous = code;
- *code++ = ((options & PCRE_CASELESS) != 0)? OP_CHARNC : OP_CHAR;
- for (c = 0; c < mclength; c++) *code++ = mcbuffer[c];
-
- /* Remember if \r or \n were seen */
-
- if (mcbuffer[0] == '\r' || mcbuffer[0] == '\n')
- cd->external_flags |= PCRE_HASCRORLF;
-
- /* Set the first and required bytes appropriately. If no previous first
- byte, set it from this character, but revert to none on a zero repeat.
- Otherwise, leave the firstbyte value alone, and don't change it on a zero
- repeat. */
-
- if (firstbyte == REQ_UNSET)
- {
- zerofirstbyte = REQ_NONE;
- zeroreqbyte = reqbyte;
-
- /* If the character is more than one byte long, we can set firstbyte
- only if it is not to be matched caselessly. */
-
- if (mclength == 1 || req_caseopt == 0)
- {
- firstbyte = mcbuffer[0] | req_caseopt;
- if (mclength != 1) reqbyte = code[-1] | cd->req_varyopt;
- }
- else firstbyte = reqbyte = REQ_NONE;
- }
-
- /* firstbyte was previously set; we can set reqbyte only the length is
- 1 or the matching is caseful. */
-
- else
- {
- zerofirstbyte = firstbyte;
- zeroreqbyte = reqbyte;
- if (mclength == 1 || req_caseopt == 0)
- reqbyte = code[-1] | req_caseopt | cd->req_varyopt;
- }
-
- break; /* End of literal character handling */
- }
- } /* end of big loop */
-
-
-/* Control never reaches here by falling through, only by a goto for all the
-error states. Pass back the position in the pattern so that it can be displayed
-to the user for diagnosing the error. */
-
-FAILED:
-*ptrptr = ptr;
-return FALSE;
-}
-
-
-
-
-/*************************************************
-* Compile sequence of alternatives *
-*************************************************/
-
-/* On entry, ptr is pointing past the bracket character, but on return it
-points to the closing bracket, or vertical bar, or end of string. The code
-variable is pointing at the byte into which the BRA operator has been stored.
-If the ims options are changed at the start (for a (?ims: group) or during any
-branch, we need to insert an OP_OPT item at the start of every following branch
-to ensure they get set correctly at run time, and also pass the new options
-into every subsequent branch compile.
-
-This function is used during the pre-compile phase when we are trying to find
-out the amount of memory needed, as well as during the real compile phase. The
-value of lengthptr distinguishes the two phases.
-
-Arguments:
- options option bits, including any changes for this subpattern
- oldims previous settings of ims option bits
- codeptr -> the address of the current code pointer
- ptrptr -> the address of the current pattern pointer
- errorcodeptr -> pointer to error code variable
- lookbehind TRUE if this is a lookbehind assertion
- reset_bracount TRUE to reset the count for each branch
- skipbytes skip this many bytes at start (for brackets and OP_COND)
- firstbyteptr place to put the first required character, or a negative number
- reqbyteptr place to put the last required character, or a negative number
- bcptr pointer to the chain of currently open branches
- cd points to the data block with tables pointers etc.
- lengthptr NULL during the real compile phase
- points to length accumulator during pre-compile phase
-
-Returns: TRUE on success
-*/
-
-static BOOL
-compile_regex(int options, int oldims, uschar **codeptr, const uschar **ptrptr,
- int *errorcodeptr, BOOL lookbehind, BOOL reset_bracount, int skipbytes,
- int *firstbyteptr, int *reqbyteptr, branch_chain *bcptr, compile_data *cd,
- int *lengthptr)
-{
-const uschar *ptr = *ptrptr;
-uschar *code = *codeptr;
-uschar *last_branch = code;
-uschar *start_bracket = code;
-uschar *reverse_count = NULL;
-int firstbyte, reqbyte;
-int branchfirstbyte, branchreqbyte;
-int length;
-int orig_bracount;
-int max_bracount;
-branch_chain bc;
-
-bc.outer = bcptr;
-bc.current = code;
-
-firstbyte = reqbyte = REQ_UNSET;
-
-/* Accumulate the length for use in the pre-compile phase. Start with the
-length of the BRA and KET and any extra bytes that are required at the
-beginning. We accumulate in a local variable to save frequent testing of
-lenthptr for NULL. We cannot do this by looking at the value of code at the
-start and end of each alternative, because compiled items are discarded during
-the pre-compile phase so that the work space is not exceeded. */
-
-length = 2 + 2*LINK_SIZE + skipbytes;
-
-/* WARNING: If the above line is changed for any reason, you must also change
-the code that abstracts option settings at the start of the pattern and makes
-them global. It tests the value of length for (2 + 2*LINK_SIZE) in the
-pre-compile phase to find out whether anything has yet been compiled or not. */
-
-/* Offset is set zero to mark that this bracket is still open */
-
-PUT(code, 1, 0);
-code += 1 + LINK_SIZE + skipbytes;
-
-/* Loop for each alternative branch */
-
-orig_bracount = max_bracount = cd->bracount;
-for (;;)
- {
- /* For a (?| group, reset the capturing bracket count so that each branch
- uses the same numbers. */
-
- if (reset_bracount) cd->bracount = orig_bracount;
-
- /* Handle a change of ims options at the start of the branch */
-
- if ((options & PCRE_IMS) != oldims)
- {
- *code++ = OP_OPT;
- *code++ = options & PCRE_IMS;
- length += 2;
- }
-
- /* Set up dummy OP_REVERSE if lookbehind assertion */
-
- if (lookbehind)
- {
- *code++ = OP_REVERSE;
- reverse_count = code;
- PUTINC(code, 0, 0);
- length += 1 + LINK_SIZE;
- }
-
- /* Now compile the branch; in the pre-compile phase its length gets added
- into the length. */
-
- if (!compile_branch(&options, &code, &ptr, errorcodeptr, &branchfirstbyte,
- &branchreqbyte, &bc, cd, (lengthptr == NULL)? NULL : &length))
- {
- *ptrptr = ptr;
- return FALSE;
- }
-
- /* Keep the highest bracket count in case (?| was used and some branch
- has fewer than the rest. */
-
- if (cd->bracount > max_bracount) max_bracount = cd->bracount;
-
- /* In the real compile phase, there is some post-processing to be done. */
-
- if (lengthptr == NULL)
- {
- /* If this is the first branch, the firstbyte and reqbyte values for the
- branch become the values for the regex. */
-
- if (*last_branch != OP_ALT)
- {
- firstbyte = branchfirstbyte;
- reqbyte = branchreqbyte;
- }
-
- /* If this is not the first branch, the first char and reqbyte have to
- match the values from all the previous branches, except that if the
- previous value for reqbyte didn't have REQ_VARY set, it can still match,
- and we set REQ_VARY for the regex. */
-
- else
- {
- /* If we previously had a firstbyte, but it doesn't match the new branch,
- we have to abandon the firstbyte for the regex, but if there was
- previously no reqbyte, it takes on the value of the old firstbyte. */
-
- if (firstbyte >= 0 && firstbyte != branchfirstbyte)
- {
- if (reqbyte < 0) reqbyte = firstbyte;
- firstbyte = REQ_NONE;
- }
-
- /* If we (now or from before) have no firstbyte, a firstbyte from the
- branch becomes a reqbyte if there isn't a branch reqbyte. */
-
- if (firstbyte < 0 && branchfirstbyte >= 0 && branchreqbyte < 0)
- branchreqbyte = branchfirstbyte;
-
- /* Now ensure that the reqbytes match */
-
- if ((reqbyte & ~REQ_VARY) != (branchreqbyte & ~REQ_VARY))
- reqbyte = REQ_NONE;
- else reqbyte |= branchreqbyte; /* To "or" REQ_VARY */
- }
-
- /* If lookbehind, check that this branch matches a fixed-length string, and
- put the length into the OP_REVERSE item. Temporarily mark the end of the
- branch with OP_END. */
-
- if (lookbehind)
- {
- int fixed_length;
- *code = OP_END;
- fixed_length = find_fixedlength(last_branch, options);
- DPRINTF(("fixed length = %d\n", fixed_length));
- if (fixed_length < 0)
- {
- *errorcodeptr = (fixed_length == -2)? ERR36 : ERR25;
- *ptrptr = ptr;
- return FALSE;
- }
- PUT(reverse_count, 0, fixed_length);
- }
- }
-
- /* Reached end of expression, either ')' or end of pattern. In the real
- compile phase, go back through the alternative branches and reverse the chain
- of offsets, with the field in the BRA item now becoming an offset to the
- first alternative. If there are no alternatives, it points to the end of the
- group. The length in the terminating ket is always the length of the whole
- bracketed item. If any of the ims options were changed inside the group,
- compile a resetting op-code following, except at the very end of the pattern.
- Return leaving the pointer at the terminating char. */
-
- if (*ptr != '|')
- {
- if (lengthptr == NULL)
- {
- int branch_length = code - last_branch;
- do
- {
- int prev_length = GET(last_branch, 1);
- PUT(last_branch, 1, branch_length);
- branch_length = prev_length;
- last_branch -= branch_length;
- }
- while (branch_length > 0);
- }
-
- /* Fill in the ket */
-
- *code = OP_KET;
- PUT(code, 1, code - start_bracket);
- code += 1 + LINK_SIZE;
-
- /* Resetting option if needed */
-
- if ((options & PCRE_IMS) != oldims && *ptr == ')')
- {
- *code++ = OP_OPT;
- *code++ = oldims;
- length += 2;
- }
-
- /* Retain the highest bracket number, in case resetting was used. */
-
- cd->bracount = max_bracount;
-
- /* Set values to pass back */
-
- *codeptr = code;
- *ptrptr = ptr;
- *firstbyteptr = firstbyte;
- *reqbyteptr = reqbyte;
- if (lengthptr != NULL)
- {
- if (OFLOW_MAX - *lengthptr < length)
- {
- *errorcodeptr = ERR20;
- return FALSE;
- }
- *lengthptr += length;
- }
- return TRUE;
- }
-
- /* Another branch follows. In the pre-compile phase, we can move the code
- pointer back to where it was for the start of the first branch. (That is,
- pretend that each branch is the only one.)
-
- In the real compile phase, insert an ALT node. Its length field points back
- to the previous branch while the bracket remains open. At the end the chain
- is reversed. It's done like this so that the start of the bracket has a
- zero offset until it is closed, making it possible to detect recursion. */
-
- if (lengthptr != NULL)
- {
- code = *codeptr + 1 + LINK_SIZE + skipbytes;
- length += 1 + LINK_SIZE;
- }
- else
- {
- *code = OP_ALT;
- PUT(code, 1, code - last_branch);
- bc.current = last_branch = code;
- code += 1 + LINK_SIZE;
- }
-
- ptr++;
- }
-/* Control never reaches here */
-}
-
-
-
-
-/*************************************************
-* Check for anchored expression *
-*************************************************/
-
-/* Try to find out if this is an anchored regular expression. Consider each
-alternative branch. If they all start with OP_SOD or OP_CIRC, or with a bracket
-all of whose alternatives start with OP_SOD or OP_CIRC (recurse ad lib), then
-it's anchored. However, if this is a multiline pattern, then only OP_SOD
-counts, since OP_CIRC can match in the middle.
-
-We can also consider a regex to be anchored if OP_SOM starts all its branches.
-This is the code for \G, which means "match at start of match position, taking
-into account the match offset".
-
-A branch is also implicitly anchored if it starts with .* and DOTALL is set,
-because that will try the rest of the pattern at all possible matching points,
-so there is no point trying again.... er ....
-
-.... except when the .* appears inside capturing parentheses, and there is a
-subsequent back reference to those parentheses. We haven't enough information
-to catch that case precisely.
-
-At first, the best we could do was to detect when .* was in capturing brackets
-and the highest back reference was greater than or equal to that level.
-However, by keeping a bitmap of the first 31 back references, we can catch some
-of the more common cases more precisely.
-
-Arguments:
- code points to start of expression (the bracket)
- options points to the options setting
- bracket_map a bitmap of which brackets we are inside while testing; this
- handles up to substring 31; after that we just have to take
- the less precise approach
- backref_map the back reference bitmap
-
-Returns: TRUE or FALSE
-*/
-
-static BOOL
-is_anchored(register const uschar *code, int *options, unsigned int bracket_map,
- unsigned int backref_map)
-{
-do {
- const uschar *scode = first_significant_code(code + _pcre_OP_lengths[*code],
- options, PCRE_MULTILINE, FALSE);
- register int op = *scode;
-
- /* Non-capturing brackets */
-
- if (op == OP_BRA)
- {
- if (!is_anchored(scode, options, bracket_map, backref_map)) return FALSE;
- }
-
- /* Capturing brackets */
-
- else if (op == OP_CBRA)
- {
- int n = GET2(scode, 1+LINK_SIZE);
- int new_map = bracket_map | ((n < 32)? (1 << n) : 1);
- if (!is_anchored(scode, options, new_map, backref_map)) return FALSE;
- }
-
- /* Other brackets */
-
- else if (op == OP_ASSERT || op == OP_ONCE || op == OP_COND)
- {
- if (!is_anchored(scode, options, bracket_map, backref_map)) return FALSE;
- }
-
- /* .* is not anchored unless DOTALL is set (which generates OP_ALLANY) and
- it isn't in brackets that are or may be referenced. */
-
- else if ((op == OP_TYPESTAR || op == OP_TYPEMINSTAR ||
- op == OP_TYPEPOSSTAR))
- {
- if (scode[1] != OP_ALLANY || (bracket_map & backref_map) != 0)
- return FALSE;
- }
-
- /* Check for explicit anchoring */
-
- else if (op != OP_SOD && op != OP_SOM &&
- ((*options & PCRE_MULTILINE) != 0 || op != OP_CIRC))
- return FALSE;
- code += GET(code, 1);
- }
-while (*code == OP_ALT); /* Loop for each alternative */
-return TRUE;
-}
-
-
-
-/*************************************************
-* Check for starting with ^ or .* *
-*************************************************/
-
-/* This is called to find out if every branch starts with ^ or .* so that
-"first char" processing can be done to speed things up in multiline
-matching and for non-DOTALL patterns that start with .* (which must start at
-the beginning or after \n). As in the case of is_anchored() (see above), we
-have to take account of back references to capturing brackets that contain .*
-because in that case we can't make the assumption.
-
-Arguments:
- code points to start of expression (the bracket)
- bracket_map a bitmap of which brackets we are inside while testing; this
- handles up to substring 31; after that we just have to take
- the less precise approach
- backref_map the back reference bitmap
-
-Returns: TRUE or FALSE
-*/
-
-static BOOL
-is_startline(const uschar *code, unsigned int bracket_map,
- unsigned int backref_map)
-{
-do {
- const uschar *scode = first_significant_code(code + _pcre_OP_lengths[*code],
- NULL, 0, FALSE);
- register int op = *scode;
-
- /* Non-capturing brackets */
-
- if (op == OP_BRA)
- {
- if (!is_startline(scode, bracket_map, backref_map)) return FALSE;
- }
-
- /* Capturing brackets */
-
- else if (op == OP_CBRA)
- {
- int n = GET2(scode, 1+LINK_SIZE);
- int new_map = bracket_map | ((n < 32)? (1 << n) : 1);
- if (!is_startline(scode, new_map, backref_map)) return FALSE;
- }
-
- /* Other brackets */
-
- else if (op == OP_ASSERT || op == OP_ONCE || op == OP_COND)
- { if (!is_startline(scode, bracket_map, backref_map)) return FALSE; }
-
- /* .* means "start at start or after \n" if it isn't in brackets that
- may be referenced. */
-
- else if (op == OP_TYPESTAR || op == OP_TYPEMINSTAR || op == OP_TYPEPOSSTAR)
- {
- if (scode[1] != OP_ANY || (bracket_map & backref_map) != 0) return FALSE;
- }
-
- /* Check for explicit circumflex */
-
- else if (op != OP_CIRC) return FALSE;
-
- /* Move on to the next alternative */
-
- code += GET(code, 1);
- }
-while (*code == OP_ALT); /* Loop for each alternative */
-return TRUE;
-}
-
-
-
-/*************************************************
-* Check for asserted fixed first char *
-*************************************************/
-
-/* During compilation, the "first char" settings from forward assertions are
-discarded, because they can cause conflicts with actual literals that follow.
-However, if we end up without a first char setting for an unanchored pattern,
-it is worth scanning the regex to see if there is an initial asserted first
-char. If all branches start with the same asserted char, or with a bracket all
-of whose alternatives start with the same asserted char (recurse ad lib), then
-we return that char, otherwise -1.
-
-Arguments:
- code points to start of expression (the bracket)
- options pointer to the options (used to check casing changes)
- inassert TRUE if in an assertion
-
-Returns: -1 or the fixed first char
-*/
-
-static int
-find_firstassertedchar(const uschar *code, int *options, BOOL inassert)
-{
-register int c = -1;
-do {
- int d;
- const uschar *scode =
- first_significant_code(code + 1+LINK_SIZE, options, PCRE_CASELESS, TRUE);
- register int op = *scode;
-
- switch(op)
- {
- default:
- return -1;
-
- case OP_BRA:
- case OP_CBRA:
- case OP_ASSERT:
- case OP_ONCE:
- case OP_COND:
- if ((d = find_firstassertedchar(scode, options, op == OP_ASSERT)) < 0)
- return -1;
- if (c < 0) c = d; else if (c != d) return -1;
- break;
-
- case OP_EXACT: /* Fall through */
- scode += 2;
-
- case OP_CHAR:
- case OP_CHARNC:
- case OP_PLUS:
- case OP_MINPLUS:
- case OP_POSPLUS:
- if (!inassert) return -1;
- if (c < 0)
- {
- c = scode[1];
- if ((*options & PCRE_CASELESS) != 0) c |= REQ_CASELESS;
- }
- else if (c != scode[1]) return -1;
- break;
- }
-
- code += GET(code, 1);
- }
-while (*code == OP_ALT);
-return c;
-}
-
-
-
-/*************************************************
-* Compile a Regular Expression *
-*************************************************/
-
-/* This function takes a string and returns a pointer to a block of store
-holding a compiled version of the expression. The original API for this
-function had no error code return variable; it is retained for backwards
-compatibility. The new function is given a new name.
-
-Arguments:
- pattern the regular expression
- options various option bits
- errorcodeptr pointer to error code variable (pcre_compile2() only)
- can be NULL if you don't want a code value
- errorptr pointer to pointer to error text
- erroroffset ptr offset in pattern where error was detected
- tables pointer to character tables or NULL
-
-Returns: pointer to compiled data block, or NULL on error,
- with errorptr and erroroffset set
-*/
-
-PCRE_EXP_DEFN pcre *
-pcre_compile(const char *pattern, int options, const char **errorptr,
- int *erroroffset, const unsigned char *tables)
-{
-return pcre_compile2(pattern, options, NULL, errorptr, erroroffset, tables);
-}
-
-
-PCRE_EXP_DEFN pcre *
-pcre_compile2(const char *pattern, int options, int *errorcodeptr,
- const char **errorptr, int *erroroffset, const unsigned char *tables)
-{
-real_pcre *re;
-int length = 1; /* For final END opcode */
-int firstbyte, reqbyte, newline;
-int errorcode = 0;
-int skipatstart = 0;
-#ifdef SUPPORT_UTF8
-BOOL utf8;
-#endif
-size_t size;
-uschar *code;
-const uschar *codestart;
-const uschar *ptr;
-compile_data compile_block;
-compile_data *cd = &compile_block;
-
-/* This space is used for "compiling" into during the first phase, when we are
-computing the amount of memory that is needed. Compiled items are thrown away
-as soon as possible, so that a fairly large buffer should be sufficient for
-this purpose. The same space is used in the second phase for remembering where
-to fill in forward references to subpatterns. */
-
-uschar cworkspace[COMPILE_WORK_SIZE];
-
-/* Set this early so that early errors get offset 0. */
-
-ptr = (const uschar *)pattern;
-
-/* We can't pass back an error message if errorptr is NULL; I guess the best we
-can do is just return NULL, but we can set a code value if there is a code
-pointer. */
-
-if (errorptr == NULL)
- {
- if (errorcodeptr != NULL) *errorcodeptr = 99;
- return NULL;
- }
-
-*errorptr = NULL;
-if (errorcodeptr != NULL) *errorcodeptr = ERR0;
-
-/* However, we can give a message for this error */
-
-if (erroroffset == NULL)
- {
- errorcode = ERR16;
- goto PCRE_EARLY_ERROR_RETURN2;
- }
-
-*erroroffset = 0;
-
-/* Can't support UTF8 unless PCRE has been compiled to include the code. */
-
-#ifdef SUPPORT_UTF8
-utf8 = (options & PCRE_UTF8) != 0;
-if (utf8 && (options & PCRE_NO_UTF8_CHECK) == 0 &&
- (*erroroffset = _pcre_valid_utf8((uschar *)pattern, -1)) >= 0)
- {
- errorcode = ERR44;
- goto PCRE_EARLY_ERROR_RETURN2;
- }
-#else
-if ((options & PCRE_UTF8) != 0)
- {
- errorcode = ERR32;
- goto PCRE_EARLY_ERROR_RETURN;
- }
-#endif
-
-if ((options & ~PUBLIC_OPTIONS) != 0)
- {
- errorcode = ERR17;
- goto PCRE_EARLY_ERROR_RETURN;
- }
-
-/* Set up pointers to the individual character tables */
-
-if (tables == NULL) tables = _pcre_default_tables;
-cd->lcc = tables + lcc_offset;
-cd->fcc = tables + fcc_offset;
-cd->cbits = tables + cbits_offset;
-cd->ctypes = tables + ctypes_offset;
-
-/* Check for global one-time settings at the start of the pattern, and remember
-the offset for later. */
-
-while (ptr[skipatstart] == '(' && ptr[skipatstart+1] == '*')
- {
- int newnl = 0;
- int newbsr = 0;
-
- if (strncmp((char *)(ptr+skipatstart+2), "CR)", 3) == 0)
- { skipatstart += 5; newnl = PCRE_NEWLINE_CR; }
- else if (strncmp((char *)(ptr+skipatstart+2), "LF)", 3) == 0)
- { skipatstart += 5; newnl = PCRE_NEWLINE_LF; }
- else if (strncmp((char *)(ptr+skipatstart+2), "CRLF)", 5) == 0)
- { skipatstart += 7; newnl = PCRE_NEWLINE_CR + PCRE_NEWLINE_LF; }
- else if (strncmp((char *)(ptr+skipatstart+2), "ANY)", 4) == 0)
- { skipatstart += 6; newnl = PCRE_NEWLINE_ANY; }
- else if (strncmp((char *)(ptr+skipatstart+2), "ANYCRLF)", 8) == 0)
- { skipatstart += 10; newnl = PCRE_NEWLINE_ANYCRLF; }
-
- else if (strncmp((char *)(ptr+skipatstart+2), "BSR_ANYCRLF)", 12) == 0)
- { skipatstart += 14; newbsr = PCRE_BSR_ANYCRLF; }
- else if (strncmp((char *)(ptr+skipatstart+2), "BSR_UNICODE)", 12) == 0)
- { skipatstart += 14; newbsr = PCRE_BSR_UNICODE; }
-
- if (newnl != 0)
- options = (options & ~PCRE_NEWLINE_BITS) | newnl;
- else if (newbsr != 0)
- options = (options & ~(PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE)) | newbsr;
- else break;
- }
-
-/* Check validity of \R options. */
-
-switch (options & (PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE))
- {
- case 0:
- case PCRE_BSR_ANYCRLF:
- case PCRE_BSR_UNICODE:
- break;
- default: errorcode = ERR56; goto PCRE_EARLY_ERROR_RETURN;
- }
-
-/* Handle different types of newline. The three bits give seven cases. The
-current code allows for fixed one- or two-byte sequences, plus "any" and
-"anycrlf". */
-
-switch (options & PCRE_NEWLINE_BITS)
- {
- case 0: newline = NEWLINE; break; /* Build-time default */
- case PCRE_NEWLINE_CR: newline = '\r'; break;
- case PCRE_NEWLINE_LF: newline = '\n'; break;
- case PCRE_NEWLINE_CR+
- PCRE_NEWLINE_LF: newline = ('\r' << 8) | '\n'; break;
- case PCRE_NEWLINE_ANY: newline = -1; break;
- case PCRE_NEWLINE_ANYCRLF: newline = -2; break;
- default: errorcode = ERR56; goto PCRE_EARLY_ERROR_RETURN;
- }
-
-if (newline == -2)
- {
- cd->nltype = NLTYPE_ANYCRLF;
- }
-else if (newline < 0)
- {
- cd->nltype = NLTYPE_ANY;
- }
-else
- {
- cd->nltype = NLTYPE_FIXED;
- if (newline > 255)
- {
- cd->nllen = 2;
- cd->nl[0] = (newline >> 8) & 255;
- cd->nl[1] = newline & 255;
- }
- else
- {
- cd->nllen = 1;
- cd->nl[0] = newline;
- }
- }
-
-/* Maximum back reference and backref bitmap. The bitmap records up to 31 back
-references to help in deciding whether (.*) can be treated as anchored or not.
-*/
-
-cd->top_backref = 0;
-cd->backref_map = 0;
-
-/* Reflect pattern for debugging output */
-
-DPRINTF(("------------------------------------------------------------------\n"));
-DPRINTF(("%s\n", pattern));
-
-/* Pretend to compile the pattern while actually just accumulating the length
-of memory required. This behaviour is triggered by passing a non-NULL final
-argument to compile_regex(). We pass a block of workspace (cworkspace) for it
-to compile parts of the pattern into; the compiled code is discarded when it is
-no longer needed, so hopefully this workspace will never overflow, though there
-is a test for its doing so. */
-
-cd->bracount = cd->final_bracount = 0;
-cd->names_found = 0;
-cd->name_entry_size = 0;
-cd->name_table = NULL;
-cd->start_workspace = cworkspace;
-cd->start_code = cworkspace;
-cd->hwm = cworkspace;
-cd->start_pattern = (const uschar *)pattern;
-cd->end_pattern = (const uschar *)(pattern + strlen(pattern));
-cd->req_varyopt = 0;
-cd->external_options = options;
-cd->external_flags = 0;
-
-/* Now do the pre-compile. On error, errorcode will be set non-zero, so we
-don't need to look at the result of the function here. The initial options have
-been put into the cd block so that they can be changed if an option setting is
-found within the regex right at the beginning. Bringing initial option settings
-outside can help speed up starting point checks. */
-
-ptr += skipatstart;
-code = cworkspace;
-*code = OP_BRA;
-(void)compile_regex(cd->external_options, cd->external_options & PCRE_IMS,
- &code, &ptr, &errorcode, FALSE, FALSE, 0, &firstbyte, &reqbyte, NULL, cd,
- &length);
-if (errorcode != 0) goto PCRE_EARLY_ERROR_RETURN;
-
-DPRINTF(("end pre-compile: length=%d workspace=%d\n", length,
- cd->hwm - cworkspace));
-
-if (length > MAX_PATTERN_SIZE)
- {
- errorcode = ERR20;
- goto PCRE_EARLY_ERROR_RETURN;
- }
-
-/* Compute the size of data block needed and get it, either from malloc or
-externally provided function. Integer overflow should no longer be possible
-because nowadays we limit the maximum value of cd->names_found and
-cd->name_entry_size. */
-
-size = length + sizeof(real_pcre) + cd->names_found * (cd->name_entry_size + 3);
-re = (real_pcre *)(pcre_malloc)(size);
-
-if (re == NULL)
- {
- errorcode = ERR21;
- goto PCRE_EARLY_ERROR_RETURN;
- }
-
-/* Put in the magic number, and save the sizes, initial options, internal
-flags, and character table pointer. NULL is used for the default character
-tables. The nullpad field is at the end; it's there to help in the case when a
-regex compiled on a system with 4-byte pointers is run on another with 8-byte
-pointers. */
-
-re->magic_number = MAGIC_NUMBER;
-re->size = size;
-re->options = cd->external_options;
-re->flags = cd->external_flags;
-re->dummy1 = 0;
-re->first_byte = 0;
-re->req_byte = 0;
-re->name_table_offset = sizeof(real_pcre);
-re->name_entry_size = cd->name_entry_size;
-re->name_count = cd->names_found;
-re->ref_count = 0;
-re->tables = (tables == _pcre_default_tables)? NULL : tables;
-re->nullpad = NULL;
-
-/* The starting points of the name/number translation table and of the code are
-passed around in the compile data block. The start/end pattern and initial
-options are already set from the pre-compile phase, as is the name_entry_size
-field. Reset the bracket count and the names_found field. Also reset the hwm
-field; this time it's used for remembering forward references to subpatterns.
-*/
-
-cd->final_bracount = cd->bracount; /* Save for checking forward references */
-cd->bracount = 0;
-cd->names_found = 0;
-cd->name_table = (uschar *)re + re->name_table_offset;
-codestart = cd->name_table + re->name_entry_size * re->name_count;
-cd->start_code = codestart;
-cd->hwm = cworkspace;
-cd->req_varyopt = 0;
-cd->had_accept = FALSE;
-
-/* Set up a starting, non-extracting bracket, then compile the expression. On
-error, errorcode will be set non-zero, so we don't need to look at the result
-of the function here. */
-
-ptr = (const uschar *)pattern + skipatstart;
-code = (uschar *)codestart;
-*code = OP_BRA;
-(void)compile_regex(re->options, re->options & PCRE_IMS, &code, &ptr,
- &errorcode, FALSE, FALSE, 0, &firstbyte, &reqbyte, NULL, cd, NULL);
-re->top_bracket = cd->bracount;
-re->top_backref = cd->top_backref;
-re->flags = cd->external_flags;
-
-if (cd->had_accept) reqbyte = -1; /* Must disable after (*ACCEPT) */
-
-/* If not reached end of pattern on success, there's an excess bracket. */
-
-if (errorcode == 0 && *ptr != 0) errorcode = ERR22;
-
-/* Fill in the terminating state and check for disastrous overflow, but
-if debugging, leave the test till after things are printed out. */
-
-*code++ = OP_END;
-
-#ifndef DEBUG
-if (code - codestart > length) errorcode = ERR23;
-#endif
-
-/* Fill in any forward references that are required. */
-
-while (errorcode == 0 && cd->hwm > cworkspace)
- {
- int offset, recno;
- const uschar *groupptr;
- cd->hwm -= LINK_SIZE;
- offset = GET(cd->hwm, 0);
- recno = GET(codestart, offset);
- groupptr = find_bracket(codestart, (re->options & PCRE_UTF8) != 0, recno);
- if (groupptr == NULL) errorcode = ERR53;
- else PUT(((uschar *)codestart), offset, groupptr - codestart);
- }
-
-/* Give an error if there's back reference to a non-existent capturing
-subpattern. */
-
-if (errorcode == 0 && re->top_backref > re->top_bracket) errorcode = ERR15;
-
-/* Failed to compile, or error while post-processing */
-
-if (errorcode != 0)
- {
- (pcre_free)(re);
- PCRE_EARLY_ERROR_RETURN:
- *erroroffset = ptr - (const uschar *)pattern;
- PCRE_EARLY_ERROR_RETURN2:
- *errorptr = find_error_text(errorcode);
- if (errorcodeptr != NULL) *errorcodeptr = errorcode;
- return NULL;
- }
-
-/* If the anchored option was not passed, set the flag if we can determine that
-the pattern is anchored by virtue of ^ characters or \A or anything else (such
-as starting with .* when DOTALL is set).
-
-Otherwise, if we know what the first byte has to be, save it, because that
-speeds up unanchored matches no end. If not, see if we can set the
-PCRE_STARTLINE flag. This is helpful for multiline matches when all branches
-start with ^. and also when all branches start with .* for non-DOTALL matches.
-*/
-
-if ((re->options & PCRE_ANCHORED) == 0)
- {
- int temp_options = re->options; /* May get changed during these scans */
- if (is_anchored(codestart, &temp_options, 0, cd->backref_map))
- re->options |= PCRE_ANCHORED;
- else
- {
- if (firstbyte < 0)
- firstbyte = find_firstassertedchar(codestart, &temp_options, FALSE);
- if (firstbyte >= 0) /* Remove caseless flag for non-caseable chars */
- {
- int ch = firstbyte & 255;
- re->first_byte = ((firstbyte & REQ_CASELESS) != 0 &&
- cd->fcc[ch] == ch)? ch : firstbyte;
- re->flags |= PCRE_FIRSTSET;
- }
- else if (is_startline(codestart, 0, cd->backref_map))
- re->flags |= PCRE_STARTLINE;
- }
- }
-
-/* For an anchored pattern, we use the "required byte" only if it follows a
-variable length item in the regex. Remove the caseless flag for non-caseable
-bytes. */
-
-if (reqbyte >= 0 &&
- ((re->options & PCRE_ANCHORED) == 0 || (reqbyte & REQ_VARY) != 0))
- {
- int ch = reqbyte & 255;
- re->req_byte = ((reqbyte & REQ_CASELESS) != 0 &&
- cd->fcc[ch] == ch)? (reqbyte & ~REQ_CASELESS) : reqbyte;
- re->flags |= PCRE_REQCHSET;
- }
-
-/* Print out the compiled data if debugging is enabled. This is never the
-case when building a production library. */
-
-#ifdef DEBUG
-
-printf("Length = %d top_bracket = %d top_backref = %d\n",
- length, re->top_bracket, re->top_backref);
-
-printf("Options=%08x\n", re->options);
-
-if ((re->flags & PCRE_FIRSTSET) != 0)
- {
- int ch = re->first_byte & 255;
- const char *caseless = ((re->first_byte & REQ_CASELESS) == 0)?
- "" : " (caseless)";
- if (isprint(ch)) printf("First char = %c%s\n", ch, caseless);
- else printf("First char = \\x%02x%s\n", ch, caseless);
- }
-
-if ((re->flags & PCRE_REQCHSET) != 0)
- {
- int ch = re->req_byte & 255;
- const char *caseless = ((re->req_byte & REQ_CASELESS) == 0)?
- "" : " (caseless)";
- if (isprint(ch)) printf("Req char = %c%s\n", ch, caseless);
- else printf("Req char = \\x%02x%s\n", ch, caseless);
- }
-
-pcre_printint(re, stdout, TRUE);
-
-/* This check is done here in the debugging case so that the code that
-was compiled can be seen. */
-
-if (code - codestart > length)
- {
- (pcre_free)(re);
- *errorptr = find_error_text(ERR23);
- *erroroffset = ptr - (uschar *)pattern;
- if (errorcodeptr != NULL) *errorcodeptr = ERR23;
- return NULL;
- }
-#endif /* DEBUG */
-
-return (pcre *)re;
-}
-
-/* End of pcre_compile.c */
diff --git a/crawl-ref/source/util/pcre/pcre_config.c b/crawl-ref/source/util/pcre/pcre_config.c
deleted file mode 100644
index 454fed98df..0000000000
--- a/crawl-ref/source/util/pcre/pcre_config.c
+++ /dev/null
@@ -1,128 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
- Written by Philip Hazel
- Copyright (c) 1997-2008 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-
-/* This module contains the external function pcre_config(). */
-
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "pcre_internal.h"
-
-
-/*************************************************
-* Return info about what features are configured *
-*************************************************/
-
-/* This function has an extensible interface so that additional items can be
-added compatibly.
-
-Arguments:
- what what information is required
- where where to put the information
-
-Returns: 0 if data returned, negative on error
-*/
-
-PCRE_EXP_DEFN int
-pcre_config(int what, void *where)
-{
-switch (what)
- {
- case PCRE_CONFIG_UTF8:
-#ifdef SUPPORT_UTF8
- *((int *)where) = 1;
-#else
- *((int *)where) = 0;
-#endif
- break;
-
- case PCRE_CONFIG_UNICODE_PROPERTIES:
-#ifdef SUPPORT_UCP
- *((int *)where) = 1;
-#else
- *((int *)where) = 0;
-#endif
- break;
-
- case PCRE_CONFIG_NEWLINE:
- *((int *)where) = NEWLINE;
- break;
-
- case PCRE_CONFIG_BSR:
-#ifdef BSR_ANYCRLF
- *((int *)where) = 1;
-#else
- *((int *)where) = 0;
-#endif
- break;
-
- case PCRE_CONFIG_LINK_SIZE:
- *((int *)where) = LINK_SIZE;
- break;
-
- case PCRE_CONFIG_POSIX_MALLOC_THRESHOLD:
- *((int *)where) = POSIX_MALLOC_THRESHOLD;
- break;
-
- case PCRE_CONFIG_MATCH_LIMIT:
- *((unsigned int *)where) = MATCH_LIMIT;
- break;
-
- case PCRE_CONFIG_MATCH_LIMIT_RECURSION:
- *((unsigned int *)where) = MATCH_LIMIT_RECURSION;
- break;
-
- case PCRE_CONFIG_STACKRECURSE:
-#ifdef NO_RECURSE
- *((int *)where) = 0;
-#else
- *((int *)where) = 1;
-#endif
- break;
-
- default: return PCRE_ERROR_BADOPTION;
- }
-
-return 0;
-}
-
-/* End of pcre_config.c */
diff --git a/crawl-ref/source/util/pcre/pcre_dfa_exec.c b/crawl-ref/source/util/pcre/pcre_dfa_exec.c
deleted file mode 100644
index 01aad5df44..0000000000
--- a/crawl-ref/source/util/pcre/pcre_dfa_exec.c
+++ /dev/null
@@ -1,2899 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
- Written by Philip Hazel
- Copyright (c) 1997-2008 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-
-/* This module contains the external function pcre_dfa_exec(), which is an
-alternative matching function that uses a sort of DFA algorithm (not a true
-FSM). This is NOT Perl- compatible, but it has advantages in certain
-applications. */
-
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#define NLBLOCK md /* Block containing newline information */
-#define PSSTART start_subject /* Field containing processed string start */
-#define PSEND end_subject /* Field containing processed string end */
-
-#include "pcre_internal.h"
-
-
-/* For use to indent debugging output */
-
-#define SP " "
-
-
-
-/*************************************************
-* Code parameters and static tables *
-*************************************************/
-
-/* These are offsets that are used to turn the OP_TYPESTAR and friends opcodes
-into others, under special conditions. A gap of 20 between the blocks should be
-enough. The resulting opcodes don't have to be less than 256 because they are
-never stored, so we push them well clear of the normal opcodes. */
-
-#define OP_PROP_EXTRA 300
-#define OP_EXTUNI_EXTRA 320
-#define OP_ANYNL_EXTRA 340
-#define OP_HSPACE_EXTRA 360
-#define OP_VSPACE_EXTRA 380
-
-
-/* This table identifies those opcodes that are followed immediately by a
-character that is to be tested in some way. This makes is possible to
-centralize the loading of these characters. In the case of Type * etc, the
-"character" is the opcode for \D, \d, \S, \s, \W, or \w, which will always be a
-small value. ***NOTE*** If the start of this table is modified, the two tables
-that follow must also be modified. */
-
-static const uschar coptable[] = {
- 0, /* End */
- 0, 0, 0, 0, 0, /* \A, \G, \K, \B, \b */
- 0, 0, 0, 0, 0, 0, /* \D, \d, \S, \s, \W, \w */
- 0, 0, 0, /* Any, AllAny, Anybyte */
- 0, 0, 0, /* NOTPROP, PROP, EXTUNI */
- 0, 0, 0, 0, 0, /* \R, \H, \h, \V, \v */
- 0, 0, 0, 0, 0, /* \Z, \z, Opt, ^, $ */
- 1, /* Char */
- 1, /* Charnc */
- 1, /* not */
- /* Positive single-char repeats */
- 1, 1, 1, 1, 1, 1, /* *, *?, +, +?, ?, ?? */
- 3, 3, 3, /* upto, minupto, exact */
- 1, 1, 1, 3, /* *+, ++, ?+, upto+ */
- /* Negative single-char repeats - only for chars < 256 */
- 1, 1, 1, 1, 1, 1, /* NOT *, *?, +, +?, ?, ?? */
- 3, 3, 3, /* NOT upto, minupto, exact */
- 1, 1, 1, 3, /* NOT *+, ++, ?+, updo+ */
- /* Positive type repeats */
- 1, 1, 1, 1, 1, 1, /* Type *, *?, +, +?, ?, ?? */
- 3, 3, 3, /* Type upto, minupto, exact */
- 1, 1, 1, 3, /* Type *+, ++, ?+, upto+ */
- /* Character class & ref repeats */
- 0, 0, 0, 0, 0, 0, /* *, *?, +, +?, ?, ?? */
- 0, 0, /* CRRANGE, CRMINRANGE */
- 0, /* CLASS */
- 0, /* NCLASS */
- 0, /* XCLASS - variable length */
- 0, /* REF */
- 0, /* RECURSE */
- 0, /* CALLOUT */
- 0, /* Alt */
- 0, /* Ket */
- 0, /* KetRmax */
- 0, /* KetRmin */
- 0, /* Assert */
- 0, /* Assert not */
- 0, /* Assert behind */
- 0, /* Assert behind not */
- 0, /* Reverse */
- 0, 0, 0, 0, /* ONCE, BRA, CBRA, COND */
- 0, 0, 0, /* SBRA, SCBRA, SCOND */
- 0, /* CREF */
- 0, /* RREF */
- 0, /* DEF */
- 0, 0, /* BRAZERO, BRAMINZERO */
- 0, 0, 0, 0, /* PRUNE, SKIP, THEN, COMMIT */
- 0, 0, 0 /* FAIL, ACCEPT, SKIPZERO */
-};
-
-/* These 2 tables allow for compact code for testing for \D, \d, \S, \s, \W,
-and \w */
-
-static const uschar toptable1[] = {
- 0, 0, 0, 0, 0, 0,
- ctype_digit, ctype_digit,
- ctype_space, ctype_space,
- ctype_word, ctype_word,
- 0, 0 /* OP_ANY, OP_ALLANY */
-};
-
-static const uschar toptable2[] = {
- 0, 0, 0, 0, 0, 0,
- ctype_digit, 0,
- ctype_space, 0,
- ctype_word, 0,
- 1, 1 /* OP_ANY, OP_ALLANY */
-};
-
-
-/* Structure for holding data about a particular state, which is in effect the
-current data for an active path through the match tree. It must consist
-entirely of ints because the working vector we are passed, and which we put
-these structures in, is a vector of ints. */
-
-typedef struct stateblock {
- int offset; /* Offset to opcode */
- int count; /* Count for repeats */
- int ims; /* ims flag bits */
- int data; /* Some use extra data */
-} stateblock;
-
-#define INTS_PER_STATEBLOCK (sizeof(stateblock)/sizeof(int))
-
-
-#ifdef DEBUG
-/*************************************************
-* Print character string *
-*************************************************/
-
-/* Character string printing function for debugging.
-
-Arguments:
- p points to string
- length number of bytes
- f where to print
-
-Returns: nothing
-*/
-
-static void
-pchars(unsigned char *p, int length, FILE *f)
-{
-int c;
-while (length-- > 0)
- {
- if (isprint(c = *(p++)))
- fprintf(f, "%c", c);
- else
- fprintf(f, "\\x%02x", c);
- }
-}
-#endif
-
-
-
-/*************************************************
-* Execute a Regular Expression - DFA engine *
-*************************************************/
-
-/* This internal function applies a compiled pattern to a subject string,
-starting at a given point, using a DFA engine. This function is called from the
-external one, possibly multiple times if the pattern is not anchored. The
-function calls itself recursively for some kinds of subpattern.
-
-Arguments:
- md the match_data block with fixed information
- this_start_code the opening bracket of this subexpression's code
- current_subject where we currently are in the subject string
- start_offset start offset in the subject string
- offsets vector to contain the matching string offsets
- offsetcount size of same
- workspace vector of workspace
- wscount size of same
- ims the current ims flags
- rlevel function call recursion level
- recursing regex recursive call level
-
-Returns: > 0 => number of match offset pairs placed in offsets
- = 0 => offsets overflowed; longest matches are present
- -1 => failed to match
- < -1 => some kind of unexpected problem
-
-The following macros are used for adding states to the two state vectors (one
-for the current character, one for the following character). */
-
-#define ADD_ACTIVE(x,y) \
- if (active_count++ < wscount) \
- { \
- next_active_state->offset = (x); \
- next_active_state->count = (y); \
- next_active_state->ims = ims; \
- next_active_state++; \
- DPRINTF(("%.*sADD_ACTIVE(%d,%d)\n", rlevel*2-2, SP, (x), (y))); \
- } \
- else return PCRE_ERROR_DFA_WSSIZE
-
-#define ADD_ACTIVE_DATA(x,y,z) \
- if (active_count++ < wscount) \
- { \
- next_active_state->offset = (x); \
- next_active_state->count = (y); \
- next_active_state->ims = ims; \
- next_active_state->data = (z); \
- next_active_state++; \
- DPRINTF(("%.*sADD_ACTIVE_DATA(%d,%d,%d)\n", rlevel*2-2, SP, (x), (y), (z))); \
- } \
- else return PCRE_ERROR_DFA_WSSIZE
-
-#define ADD_NEW(x,y) \
- if (new_count++ < wscount) \
- { \
- next_new_state->offset = (x); \
- next_new_state->count = (y); \
- next_new_state->ims = ims; \
- next_new_state++; \
- DPRINTF(("%.*sADD_NEW(%d,%d)\n", rlevel*2-2, SP, (x), (y))); \
- } \
- else return PCRE_ERROR_DFA_WSSIZE
-
-#define ADD_NEW_DATA(x,y,z) \
- if (new_count++ < wscount) \
- { \
- next_new_state->offset = (x); \
- next_new_state->count = (y); \
- next_new_state->ims = ims; \
- next_new_state->data = (z); \
- next_new_state++; \
- DPRINTF(("%.*sADD_NEW_DATA(%d,%d,%d)\n", rlevel*2-2, SP, (x), (y), (z))); \
- } \
- else return PCRE_ERROR_DFA_WSSIZE
-
-/* And now, here is the code */
-
-static int
-internal_dfa_exec(
- dfa_match_data *md,
- const uschar *this_start_code,
- const uschar *current_subject,
- int start_offset,
- int *offsets,
- int offsetcount,
- int *workspace,
- int wscount,
- int ims,
- int rlevel,
- int recursing)
-{
-stateblock *active_states, *new_states, *temp_states;
-stateblock *next_active_state, *next_new_state;
-
-const uschar *ctypes, *lcc, *fcc;
-const uschar *ptr;
-const uschar *end_code, *first_op;
-
-int active_count, new_count, match_count;
-
-/* Some fields in the md block are frequently referenced, so we load them into
-independent variables in the hope that this will perform better. */
-
-const uschar *start_subject = md->start_subject;
-const uschar *end_subject = md->end_subject;
-const uschar *start_code = md->start_code;
-
-#ifdef SUPPORT_UTF8
-BOOL utf8 = (md->poptions & PCRE_UTF8) != 0;
-#else
-BOOL utf8 = FALSE;
-#endif
-
-rlevel++;
-offsetcount &= (-2);
-
-wscount -= 2;
-wscount = (wscount - (wscount % (INTS_PER_STATEBLOCK * 2))) /
- (2 * INTS_PER_STATEBLOCK);
-
-DPRINTF(("\n%.*s---------------------\n"
- "%.*sCall to internal_dfa_exec f=%d r=%d\n",
- rlevel*2-2, SP, rlevel*2-2, SP, rlevel, recursing));
-
-ctypes = md->tables + ctypes_offset;
-lcc = md->tables + lcc_offset;
-fcc = md->tables + fcc_offset;
-
-match_count = PCRE_ERROR_NOMATCH; /* A negative number */
-
-active_states = (stateblock *)(workspace + 2);
-next_new_state = new_states = active_states + wscount;
-new_count = 0;
-
-first_op = this_start_code + 1 + LINK_SIZE +
- ((*this_start_code == OP_CBRA || *this_start_code == OP_SCBRA)? 2:0);
-
-/* The first thing in any (sub) pattern is a bracket of some sort. Push all
-the alternative states onto the list, and find out where the end is. This
-makes is possible to use this function recursively, when we want to stop at a
-matching internal ket rather than at the end.
-
-If the first opcode in the first alternative is OP_REVERSE, we are dealing with
-a backward assertion. In that case, we have to find out the maximum amount to
-move back, and set up each alternative appropriately. */
-
-if (*first_op == OP_REVERSE)
- {
- int max_back = 0;
- int gone_back;
-
- end_code = this_start_code;
- do
- {
- int back = GET(end_code, 2+LINK_SIZE);
- if (back > max_back) max_back = back;
- end_code += GET(end_code, 1);
- }
- while (*end_code == OP_ALT);
-
- /* If we can't go back the amount required for the longest lookbehind
- pattern, go back as far as we can; some alternatives may still be viable. */
-
-#ifdef SUPPORT_UTF8
- /* In character mode we have to step back character by character */
-
- if (utf8)
- {
- for (gone_back = 0; gone_back < max_back; gone_back++)
- {
- if (current_subject <= start_subject) break;
- current_subject--;
- while (current_subject > start_subject &&
- (*current_subject & 0xc0) == 0x80)
- current_subject--;
- }
- }
- else
-#endif
-
- /* In byte-mode we can do this quickly. */
-
- {
- gone_back = (current_subject - max_back < start_subject)?
- current_subject - start_subject : max_back;
- current_subject -= gone_back;
- }
-
- /* Now we can process the individual branches. */
-
- end_code = this_start_code;
- do
- {
- int back = GET(end_code, 2+LINK_SIZE);
- if (back <= gone_back)
- {
- int bstate = end_code - start_code + 2 + 2*LINK_SIZE;
- ADD_NEW_DATA(-bstate, 0, gone_back - back);
- }
- end_code += GET(end_code, 1);
- }
- while (*end_code == OP_ALT);
- }
-
-/* This is the code for a "normal" subpattern (not a backward assertion). The
-start of a whole pattern is always one of these. If we are at the top level,
-we may be asked to restart matching from the same point that we reached for a
-previous partial match. We still have to scan through the top-level branches to
-find the end state. */
-
-else
- {
- end_code = this_start_code;
-
- /* Restarting */
-
- if (rlevel == 1 && (md->moptions & PCRE_DFA_RESTART) != 0)
- {
- do { end_code += GET(end_code, 1); } while (*end_code == OP_ALT);
- new_count = workspace[1];
- if (!workspace[0])
- memcpy(new_states, active_states, new_count * sizeof(stateblock));
- }
-
- /* Not restarting */
-
- else
- {
- int length = 1 + LINK_SIZE +
- ((*this_start_code == OP_CBRA || *this_start_code == OP_SCBRA)? 2:0);
- do
- {
- ADD_NEW(end_code - start_code + length, 0);
- end_code += GET(end_code, 1);
- length = 1 + LINK_SIZE;
- }
- while (*end_code == OP_ALT);
- }
- }
-
-workspace[0] = 0; /* Bit indicating which vector is current */
-
-DPRINTF(("%.*sEnd state = %d\n", rlevel*2-2, SP, end_code - start_code));
-
-/* Loop for scanning the subject */
-
-ptr = current_subject;
-for (;;)
- {
- int i, j;
- int clen, dlen;
- unsigned int c, d;
-
- /* Make the new state list into the active state list and empty the
- new state list. */
-
- temp_states = active_states;
- active_states = new_states;
- new_states = temp_states;
- active_count = new_count;
- new_count = 0;
-
- workspace[0] ^= 1; /* Remember for the restarting feature */
- workspace[1] = active_count;
-
-#ifdef DEBUG
- printf("%.*sNext character: rest of subject = \"", rlevel*2-2, SP);
- pchars((uschar *)ptr, strlen((char *)ptr), stdout);
- printf("\"\n");
-
- printf("%.*sActive states: ", rlevel*2-2, SP);
- for (i = 0; i < active_count; i++)
- printf("%d/%d ", active_states[i].offset, active_states[i].count);
- printf("\n");
-#endif
-
- /* Set the pointers for adding new states */
-
- next_active_state = active_states + active_count;
- next_new_state = new_states;
-
- /* Load the current character from the subject outside the loop, as many
- different states may want to look at it, and we assume that at least one
- will. */
-
- if (ptr < end_subject)
- {
- clen = 1; /* Number of bytes in the character */
-#ifdef SUPPORT_UTF8
- if (utf8) { GETCHARLEN(c, ptr, clen); } else
-#endif /* SUPPORT_UTF8 */
- c = *ptr;
- }
- else
- {
- clen = 0; /* This indicates the end of the subject */
- c = NOTACHAR; /* This value should never actually be used */
- }
-
- /* Scan up the active states and act on each one. The result of an action
- may be to add more states to the currently active list (e.g. on hitting a
- parenthesis) or it may be to put states on the new list, for considering
- when we move the character pointer on. */
-
- for (i = 0; i < active_count; i++)
- {
- stateblock *current_state = active_states + i;
- const uschar *code;
- int state_offset = current_state->offset;
- int count, codevalue;
-#ifdef SUPPORT_UCP
- int chartype, script;
-#endif
-
-#ifdef DEBUG
- printf ("%.*sProcessing state %d c=", rlevel*2-2, SP, state_offset);
- if (clen == 0) printf("EOL\n");
- else if (c > 32 && c < 127) printf("'%c'\n", c);
- else printf("0x%02x\n", c);
-#endif
-
- /* This variable is referred to implicity in the ADD_xxx macros. */
-
- ims = current_state->ims;
-
- /* A negative offset is a special case meaning "hold off going to this
- (negated) state until the number of characters in the data field have
- been skipped". */
-
- if (state_offset < 0)
- {
- if (current_state->data > 0)
- {
- DPRINTF(("%.*sSkipping this character\n", rlevel*2-2, SP));
- ADD_NEW_DATA(state_offset, current_state->count,
- current_state->data - 1);
- continue;
- }
- else
- {
- current_state->offset = state_offset = -state_offset;
- }
- }
-
- /* Check for a duplicate state with the same count, and skip if found. */
-
- for (j = 0; j < i; j++)
- {
- if (active_states[j].offset == state_offset &&
- active_states[j].count == current_state->count)
- {
- DPRINTF(("%.*sDuplicate state: skipped\n", rlevel*2-2, SP));
- goto NEXT_ACTIVE_STATE;
- }
- }
-
- /* The state offset is the offset to the opcode */
-
- code = start_code + state_offset;
- codevalue = *code;
-
- /* If this opcode is followed by an inline character, load it. It is
- tempting to test for the presence of a subject character here, but that
- is wrong, because sometimes zero repetitions of the subject are
- permitted.
-
- We also use this mechanism for opcodes such as OP_TYPEPLUS that take an
- argument that is not a data character - but is always one byte long. We
- have to take special action to deal with \P, \p, \H, \h, \V, \v and \X in
- this case. To keep the other cases fast, convert these ones to new opcodes.
- */
-
- if (coptable[codevalue] > 0)
- {
- dlen = 1;
-#ifdef SUPPORT_UTF8
- if (utf8) { GETCHARLEN(d, (code + coptable[codevalue]), dlen); } else
-#endif /* SUPPORT_UTF8 */
- d = code[coptable[codevalue]];
- if (codevalue >= OP_TYPESTAR)
- {
- switch(d)
- {
- case OP_ANYBYTE: return PCRE_ERROR_DFA_UITEM;
- case OP_NOTPROP:
- case OP_PROP: codevalue += OP_PROP_EXTRA; break;
- case OP_ANYNL: codevalue += OP_ANYNL_EXTRA; break;
- case OP_EXTUNI: codevalue += OP_EXTUNI_EXTRA; break;
- case OP_NOT_HSPACE:
- case OP_HSPACE: codevalue += OP_HSPACE_EXTRA; break;
- case OP_NOT_VSPACE:
- case OP_VSPACE: codevalue += OP_VSPACE_EXTRA; break;
- default: break;
- }
- }
- }
- else
- {
- dlen = 0; /* Not strictly necessary, but compilers moan */
- d = NOTACHAR; /* if these variables are not set. */
- }
-
-
- /* Now process the individual opcodes */
-
- switch (codevalue)
- {
-
-/* ========================================================================== */
- /* Reached a closing bracket. If not at the end of the pattern, carry
- on with the next opcode. Otherwise, unless we have an empty string and
- PCRE_NOTEMPTY is set, save the match data, shifting up all previous
- matches so we always have the longest first. */
-
- case OP_KET:
- case OP_KETRMIN:
- case OP_KETRMAX:
- if (code != end_code)
- {
- ADD_ACTIVE(state_offset + 1 + LINK_SIZE, 0);
- if (codevalue != OP_KET)
- {
- ADD_ACTIVE(state_offset - GET(code, 1), 0);
- }
- }
- else if (ptr > current_subject || (md->moptions & PCRE_NOTEMPTY) == 0)
- {
- if (match_count < 0) match_count = (offsetcount >= 2)? 1 : 0;
- else if (match_count > 0 && ++match_count * 2 >= offsetcount)
- match_count = 0;
- count = ((match_count == 0)? offsetcount : match_count * 2) - 2;
- if (count > 0) memmove(offsets + 2, offsets, count * sizeof(int));
- if (offsetcount >= 2)
- {
- offsets[0] = current_subject - start_subject;
- offsets[1] = ptr - start_subject;
- DPRINTF(("%.*sSet matched string = \"%.*s\"\n", rlevel*2-2, SP,
- offsets[1] - offsets[0], current_subject));
- }
- if ((md->moptions & PCRE_DFA_SHORTEST) != 0)
- {
- DPRINTF(("%.*sEnd of internal_dfa_exec %d: returning %d\n"
- "%.*s---------------------\n\n", rlevel*2-2, SP, rlevel,
- match_count, rlevel*2-2, SP));
- return match_count;
- }
- }
- break;
-
-/* ========================================================================== */
- /* These opcodes add to the current list of states without looking
- at the current character. */
-
- /*-----------------------------------------------------------------*/
- case OP_ALT:
- do { code += GET(code, 1); } while (*code == OP_ALT);
- ADD_ACTIVE(code - start_code, 0);
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_BRA:
- case OP_SBRA:
- do
- {
- ADD_ACTIVE(code - start_code + 1 + LINK_SIZE, 0);
- code += GET(code, 1);
- }
- while (*code == OP_ALT);
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_CBRA:
- case OP_SCBRA:
- ADD_ACTIVE(code - start_code + 3 + LINK_SIZE, 0);
- code += GET(code, 1);
- while (*code == OP_ALT)
- {
- ADD_ACTIVE(code - start_code + 1 + LINK_SIZE, 0);
- code += GET(code, 1);
- }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_BRAZERO:
- case OP_BRAMINZERO:
- ADD_ACTIVE(state_offset + 1, 0);
- code += 1 + GET(code, 2);
- while (*code == OP_ALT) code += GET(code, 1);
- ADD_ACTIVE(code - start_code + 1 + LINK_SIZE, 0);
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_SKIPZERO:
- code += 1 + GET(code, 2);
- while (*code == OP_ALT) code += GET(code, 1);
- ADD_ACTIVE(code - start_code + 1 + LINK_SIZE, 0);
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_CIRC:
- if ((ptr == start_subject && (md->moptions & PCRE_NOTBOL) == 0) ||
- ((ims & PCRE_MULTILINE) != 0 &&
- ptr != end_subject &&
- WAS_NEWLINE(ptr)))
- { ADD_ACTIVE(state_offset + 1, 0); }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_EOD:
- if (ptr >= end_subject) { ADD_ACTIVE(state_offset + 1, 0); }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_OPT:
- ims = code[1];
- ADD_ACTIVE(state_offset + 2, 0);
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_SOD:
- if (ptr == start_subject) { ADD_ACTIVE(state_offset + 1, 0); }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_SOM:
- if (ptr == start_subject + start_offset) { ADD_ACTIVE(state_offset + 1, 0); }
- break;
-
-
-/* ========================================================================== */
- /* These opcodes inspect the next subject character, and sometimes
- the previous one as well, but do not have an argument. The variable
- clen contains the length of the current character and is zero if we are
- at the end of the subject. */
-
- /*-----------------------------------------------------------------*/
- case OP_ANY:
- if (clen > 0 && !IS_NEWLINE(ptr))
- { ADD_NEW(state_offset + 1, 0); }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_ALLANY:
- if (clen > 0)
- { ADD_NEW(state_offset + 1, 0); }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_EODN:
- if (clen == 0 || (IS_NEWLINE(ptr) && ptr == end_subject - md->nllen))
- { ADD_ACTIVE(state_offset + 1, 0); }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_DOLL:
- if ((md->moptions & PCRE_NOTEOL) == 0)
- {
- if (clen == 0 ||
- (IS_NEWLINE(ptr) &&
- ((ims & PCRE_MULTILINE) != 0 || ptr == end_subject - md->nllen)
- ))
- { ADD_ACTIVE(state_offset + 1, 0); }
- }
- else if ((ims & PCRE_MULTILINE) != 0 && IS_NEWLINE(ptr))
- { ADD_ACTIVE(state_offset + 1, 0); }
- break;
-
- /*-----------------------------------------------------------------*/
-
- case OP_DIGIT:
- case OP_WHITESPACE:
- case OP_WORDCHAR:
- if (clen > 0 && c < 256 &&
- ((ctypes[c] & toptable1[codevalue]) ^ toptable2[codevalue]) != 0)
- { ADD_NEW(state_offset + 1, 0); }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_NOT_DIGIT:
- case OP_NOT_WHITESPACE:
- case OP_NOT_WORDCHAR:
- if (clen > 0 && (c >= 256 ||
- ((ctypes[c] & toptable1[codevalue]) ^ toptable2[codevalue]) != 0))
- { ADD_NEW(state_offset + 1, 0); }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_WORD_BOUNDARY:
- case OP_NOT_WORD_BOUNDARY:
- {
- int left_word, right_word;
-
- if (ptr > start_subject)
- {
- const uschar *temp = ptr - 1;
-#ifdef SUPPORT_UTF8
- if (utf8) BACKCHAR(temp);
-#endif
- GETCHARTEST(d, temp);
- left_word = d < 256 && (ctypes[d] & ctype_word) != 0;
- }
- else left_word = 0;
-
- if (clen > 0) right_word = c < 256 && (ctypes[c] & ctype_word) != 0;
- else right_word = 0;
-
- if ((left_word == right_word) == (codevalue == OP_NOT_WORD_BOUNDARY))
- { ADD_ACTIVE(state_offset + 1, 0); }
- }
- break;
-
-
- /*-----------------------------------------------------------------*/
- /* Check the next character by Unicode property. We will get here only
- if the support is in the binary; otherwise a compile-time error occurs.
- */
-
-#ifdef SUPPORT_UCP
- case OP_PROP:
- case OP_NOTPROP:
- if (clen > 0)
- {
- BOOL OK;
- int category = _pcre_ucp_findprop(c, &chartype, &script);
- switch(code[1])
- {
- case PT_ANY:
- OK = TRUE;
- break;
-
- case PT_LAMP:
- OK = chartype == ucp_Lu || chartype == ucp_Ll || chartype == ucp_Lt;
- break;
-
- case PT_GC:
- OK = category == code[2];
- break;
-
- case PT_PC:
- OK = chartype == code[2];
- break;
-
- case PT_SC:
- OK = script == code[2];
- break;
-
- /* Should never occur, but keep compilers from grumbling. */
-
- default:
- OK = codevalue != OP_PROP;
- break;
- }
-
- if (OK == (codevalue == OP_PROP)) { ADD_NEW(state_offset + 3, 0); }
- }
- break;
-#endif
-
-
-
-/* ========================================================================== */
- /* These opcodes likewise inspect the subject character, but have an
- argument that is not a data character. It is one of these opcodes:
- OP_ANY, OP_ALLANY, OP_DIGIT, OP_NOT_DIGIT, OP_WHITESPACE, OP_NOT_SPACE,
- OP_WORDCHAR, OP_NOT_WORDCHAR. The value is loaded into d. */
-
- case OP_TYPEPLUS:
- case OP_TYPEMINPLUS:
- case OP_TYPEPOSPLUS:
- count = current_state->count; /* Already matched */
- if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); }
- if (clen > 0)
- {
- if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) ||
- (c < 256 &&
- (d != OP_ANY || !IS_NEWLINE(ptr)) &&
- ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0))
- {
- if (count > 0 && codevalue == OP_TYPEPOSPLUS)
- {
- active_count--; /* Remove non-match possibility */
- next_active_state--;
- }
- count++;
- ADD_NEW(state_offset, count);
- }
- }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_TYPEQUERY:
- case OP_TYPEMINQUERY:
- case OP_TYPEPOSQUERY:
- ADD_ACTIVE(state_offset + 2, 0);
- if (clen > 0)
- {
- if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) ||
- (c < 256 &&
- (d != OP_ANY || !IS_NEWLINE(ptr)) &&
- ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0))
- {
- if (codevalue == OP_TYPEPOSQUERY)
- {
- active_count--; /* Remove non-match possibility */
- next_active_state--;
- }
- ADD_NEW(state_offset + 2, 0);
- }
- }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_TYPESTAR:
- case OP_TYPEMINSTAR:
- case OP_TYPEPOSSTAR:
- ADD_ACTIVE(state_offset + 2, 0);
- if (clen > 0)
- {
- if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) ||
- (c < 256 &&
- (d != OP_ANY || !IS_NEWLINE(ptr)) &&
- ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0))
- {
- if (codevalue == OP_TYPEPOSSTAR)
- {
- active_count--; /* Remove non-match possibility */
- next_active_state--;
- }
- ADD_NEW(state_offset, 0);
- }
- }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_TYPEEXACT:
- count = current_state->count; /* Number already matched */
- if (clen > 0)
- {
- if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) ||
- (c < 256 &&
- (d != OP_ANY || !IS_NEWLINE(ptr)) &&
- ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0))
- {
- if (++count >= GET2(code, 1))
- { ADD_NEW(state_offset + 4, 0); }
- else
- { ADD_NEW(state_offset, count); }
- }
- }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_TYPEUPTO:
- case OP_TYPEMINUPTO:
- case OP_TYPEPOSUPTO:
- ADD_ACTIVE(state_offset + 4, 0);
- count = current_state->count; /* Number already matched */
- if (clen > 0)
- {
- if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) ||
- (c < 256 &&
- (d != OP_ANY || !IS_NEWLINE(ptr)) &&
- ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0))
- {
- if (codevalue == OP_TYPEPOSUPTO)
- {
- active_count--; /* Remove non-match possibility */
- next_active_state--;
- }
- if (++count >= GET2(code, 1))
- { ADD_NEW(state_offset + 4, 0); }
- else
- { ADD_NEW(state_offset, count); }
- }
- }
- break;
-
-/* ========================================================================== */
- /* These are virtual opcodes that are used when something like
- OP_TYPEPLUS has OP_PROP, OP_NOTPROP, OP_ANYNL, or OP_EXTUNI as its
- argument. It keeps the code above fast for the other cases. The argument
- is in the d variable. */
-
-#ifdef SUPPORT_UCP
- case OP_PROP_EXTRA + OP_TYPEPLUS:
- case OP_PROP_EXTRA + OP_TYPEMINPLUS:
- case OP_PROP_EXTRA + OP_TYPEPOSPLUS:
- count = current_state->count; /* Already matched */
- if (count > 0) { ADD_ACTIVE(state_offset + 4, 0); }
- if (clen > 0)
- {
- BOOL OK;
- int category = _pcre_ucp_findprop(c, &chartype, &script);
- switch(code[2])
- {
- case PT_ANY:
- OK = TRUE;
- break;
-
- case PT_LAMP:
- OK = chartype == ucp_Lu || chartype == ucp_Ll || chartype == ucp_Lt;
- break;
-
- case PT_GC:
- OK = category == code[3];
- break;
-
- case PT_PC:
- OK = chartype == code[3];
- break;
-
- case PT_SC:
- OK = script == code[3];
- break;
-
- /* Should never occur, but keep compilers from grumbling. */
-
- default:
- OK = codevalue != OP_PROP;
- break;
- }
-
- if (OK == (d == OP_PROP))
- {
- if (count > 0 && codevalue == OP_PROP_EXTRA + OP_TYPEPOSPLUS)
- {
- active_count--; /* Remove non-match possibility */
- next_active_state--;
- }
- count++;
- ADD_NEW(state_offset, count);
- }
- }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_EXTUNI_EXTRA + OP_TYPEPLUS:
- case OP_EXTUNI_EXTRA + OP_TYPEMINPLUS:
- case OP_EXTUNI_EXTRA + OP_TYPEPOSPLUS:
- count = current_state->count; /* Already matched */
- if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); }
- if (clen > 0 && _pcre_ucp_findprop(c, &chartype, &script) != ucp_M)
- {
- const uschar *nptr = ptr + clen;
- int ncount = 0;
- if (count > 0 && codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSPLUS)
- {
- active_count--; /* Remove non-match possibility */
- next_active_state--;
- }
- while (nptr < end_subject)
- {
- int nd;
- int ndlen = 1;
- GETCHARLEN(nd, nptr, ndlen);
- if (_pcre_ucp_findprop(nd, &chartype, &script) != ucp_M) break;
- ncount++;
- nptr += ndlen;
- }
- count++;
- ADD_NEW_DATA(-state_offset, count, ncount);
- }
- break;
-#endif
-
- /*-----------------------------------------------------------------*/
- case OP_ANYNL_EXTRA + OP_TYPEPLUS:
- case OP_ANYNL_EXTRA + OP_TYPEMINPLUS:
- case OP_ANYNL_EXTRA + OP_TYPEPOSPLUS:
- count = current_state->count; /* Already matched */
- if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); }
- if (clen > 0)
- {
- int ncount = 0;
- switch (c)
- {
- case 0x000b:
- case 0x000c:
- case 0x0085:
- case 0x2028:
- case 0x2029:
- if ((md->moptions & PCRE_BSR_ANYCRLF) != 0) break;
- goto ANYNL01;
-
- case 0x000d:
- if (ptr + 1 < end_subject && ptr[1] == 0x0a) ncount = 1;
- /* Fall through */
-
- ANYNL01:
- case 0x000a:
- if (count > 0 && codevalue == OP_ANYNL_EXTRA + OP_TYPEPOSPLUS)
- {
- active_count--; /* Remove non-match possibility */
- next_active_state--;
- }
- count++;
- ADD_NEW_DATA(-state_offset, count, ncount);
- break;
-
- default:
- break;
- }
- }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_VSPACE_EXTRA + OP_TYPEPLUS:
- case OP_VSPACE_EXTRA + OP_TYPEMINPLUS:
- case OP_VSPACE_EXTRA + OP_TYPEPOSPLUS:
- count = current_state->count; /* Already matched */
- if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); }
- if (clen > 0)
- {
- BOOL OK;
- switch (c)
- {
- case 0x000a:
- case 0x000b:
- case 0x000c:
- case 0x000d:
- case 0x0085:
- case 0x2028:
- case 0x2029:
- OK = TRUE;
- break;
-
- default:
- OK = FALSE;
- break;
- }
-
- if (OK == (d == OP_VSPACE))
- {
- if (count > 0 && codevalue == OP_VSPACE_EXTRA + OP_TYPEPOSPLUS)
- {
- active_count--; /* Remove non-match possibility */
- next_active_state--;
- }
- count++;
- ADD_NEW_DATA(-state_offset, count, 0);
- }
- }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_HSPACE_EXTRA + OP_TYPEPLUS:
- case OP_HSPACE_EXTRA + OP_TYPEMINPLUS:
- case OP_HSPACE_EXTRA + OP_TYPEPOSPLUS:
- count = current_state->count; /* Already matched */
- if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); }
- if (clen > 0)
- {
- BOOL OK;
- switch (c)
- {
- case 0x09: /* HT */
- case 0x20: /* SPACE */
- case 0xa0: /* NBSP */
- case 0x1680: /* OGHAM SPACE MARK */
- case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */
- case 0x2000: /* EN QUAD */
- case 0x2001: /* EM QUAD */
- case 0x2002: /* EN SPACE */
- case 0x2003: /* EM SPACE */
- case 0x2004: /* THREE-PER-EM SPACE */
- case 0x2005: /* FOUR-PER-EM SPACE */
- case 0x2006: /* SIX-PER-EM SPACE */
- case 0x2007: /* FIGURE SPACE */
- case 0x2008: /* PUNCTUATION SPACE */
- case 0x2009: /* THIN SPACE */
- case 0x200A: /* HAIR SPACE */
- case 0x202f: /* NARROW NO-BREAK SPACE */
- case 0x205f: /* MEDIUM MATHEMATICAL SPACE */
- case 0x3000: /* IDEOGRAPHIC SPACE */
- OK = TRUE;
- break;
-
- default:
- OK = FALSE;
- break;
- }
-
- if (OK == (d == OP_HSPACE))
- {
- if (count > 0 && codevalue == OP_HSPACE_EXTRA + OP_TYPEPOSPLUS)
- {
- active_count--; /* Remove non-match possibility */
- next_active_state--;
- }
- count++;
- ADD_NEW_DATA(-state_offset, count, 0);
- }
- }
- break;
-
- /*-----------------------------------------------------------------*/
-#ifdef SUPPORT_UCP
- case OP_PROP_EXTRA + OP_TYPEQUERY:
- case OP_PROP_EXTRA + OP_TYPEMINQUERY:
- case OP_PROP_EXTRA + OP_TYPEPOSQUERY:
- count = 4;
- goto QS1;
-
- case OP_PROP_EXTRA + OP_TYPESTAR:
- case OP_PROP_EXTRA + OP_TYPEMINSTAR:
- case OP_PROP_EXTRA + OP_TYPEPOSSTAR:
- count = 0;
-
- QS1:
-
- ADD_ACTIVE(state_offset + 4, 0);
- if (clen > 0)
- {
- BOOL OK;
- int category = _pcre_ucp_findprop(c, &chartype, &script);
- switch(code[2])
- {
- case PT_ANY:
- OK = TRUE;
- break;
-
- case PT_LAMP:
- OK = chartype == ucp_Lu || chartype == ucp_Ll || chartype == ucp_Lt;
- break;
-
- case PT_GC:
- OK = category == code[3];
- break;
-
- case PT_PC:
- OK = chartype == code[3];
- break;
-
- case PT_SC:
- OK = script == code[3];
- break;
-
- /* Should never occur, but keep compilers from grumbling. */
-
- default:
- OK = codevalue != OP_PROP;
- break;
- }
-
- if (OK == (d == OP_PROP))
- {
- if (codevalue == OP_PROP_EXTRA + OP_TYPEPOSSTAR ||
- codevalue == OP_PROP_EXTRA + OP_TYPEPOSQUERY)
- {
- active_count--; /* Remove non-match possibility */
- next_active_state--;
- }
- ADD_NEW(state_offset + count, 0);
- }
- }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_EXTUNI_EXTRA + OP_TYPEQUERY:
- case OP_EXTUNI_EXTRA + OP_TYPEMINQUERY:
- case OP_EXTUNI_EXTRA + OP_TYPEPOSQUERY:
- count = 2;
- goto QS2;
-
- case OP_EXTUNI_EXTRA + OP_TYPESTAR:
- case OP_EXTUNI_EXTRA + OP_TYPEMINSTAR:
- case OP_EXTUNI_EXTRA + OP_TYPEPOSSTAR:
- count = 0;
-
- QS2:
-
- ADD_ACTIVE(state_offset + 2, 0);
- if (clen > 0 && _pcre_ucp_findprop(c, &chartype, &script) != ucp_M)
- {
- const uschar *nptr = ptr + clen;
- int ncount = 0;
- if (codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSSTAR ||
- codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSQUERY)
- {
- active_count--; /* Remove non-match possibility */
- next_active_state--;
- }
- while (nptr < end_subject)
- {
- int nd;
- int ndlen = 1;
- GETCHARLEN(nd, nptr, ndlen);
- if (_pcre_ucp_findprop(nd, &chartype, &script) != ucp_M) break;
- ncount++;
- nptr += ndlen;
- }
- ADD_NEW_DATA(-(state_offset + count), 0, ncount);
- }
- break;
-#endif
-
- /*-----------------------------------------------------------------*/
- case OP_ANYNL_EXTRA + OP_TYPEQUERY:
- case OP_ANYNL_EXTRA + OP_TYPEMINQUERY:
- case OP_ANYNL_EXTRA + OP_TYPEPOSQUERY:
- count = 2;
- goto QS3;
-
- case OP_ANYNL_EXTRA + OP_TYPESTAR:
- case OP_ANYNL_EXTRA + OP_TYPEMINSTAR:
- case OP_ANYNL_EXTRA + OP_TYPEPOSSTAR:
- count = 0;
-
- QS3:
- ADD_ACTIVE(state_offset + 2, 0);
- if (clen > 0)
- {
- int ncount = 0;
- switch (c)
- {
- case 0x000b:
- case 0x000c:
- case 0x0085:
- case 0x2028:
- case 0x2029:
- if ((md->moptions & PCRE_BSR_ANYCRLF) != 0) break;
- goto ANYNL02;
-
- case 0x000d:
- if (ptr + 1 < end_subject && ptr[1] == 0x0a) ncount = 1;
- /* Fall through */
-
- ANYNL02:
- case 0x000a:
- if (codevalue == OP_ANYNL_EXTRA + OP_TYPEPOSSTAR ||
- codevalue == OP_ANYNL_EXTRA + OP_TYPEPOSQUERY)
- {
- active_count--; /* Remove non-match possibility */
- next_active_state--;
- }
- ADD_NEW_DATA(-(state_offset + count), 0, ncount);
- break;
-
- default:
- break;
- }
- }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_VSPACE_EXTRA + OP_TYPEQUERY:
- case OP_VSPACE_EXTRA + OP_TYPEMINQUERY:
- case OP_VSPACE_EXTRA + OP_TYPEPOSQUERY:
- count = 2;
- goto QS4;
-
- case OP_VSPACE_EXTRA + OP_TYPESTAR:
- case OP_VSPACE_EXTRA + OP_TYPEMINSTAR:
- case OP_VSPACE_EXTRA + OP_TYPEPOSSTAR:
- count = 0;
-
- QS4:
- ADD_ACTIVE(state_offset + 2, 0);
- if (clen > 0)
- {
- BOOL OK;
- switch (c)
- {
- case 0x000a:
- case 0x000b:
- case 0x000c:
- case 0x000d:
- case 0x0085:
- case 0x2028:
- case 0x2029:
- OK = TRUE;
- break;
-
- default:
- OK = FALSE;
- break;
- }
- if (OK == (d == OP_VSPACE))
- {
- if (codevalue == OP_VSPACE_EXTRA + OP_TYPEPOSSTAR ||
- codevalue == OP_VSPACE_EXTRA + OP_TYPEPOSQUERY)
- {
- active_count--; /* Remove non-match possibility */
- next_active_state--;
- }
- ADD_NEW_DATA(-(state_offset + count), 0, 0);
- }
- }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_HSPACE_EXTRA + OP_TYPEQUERY:
- case OP_HSPACE_EXTRA + OP_TYPEMINQUERY:
- case OP_HSPACE_EXTRA + OP_TYPEPOSQUERY:
- count = 2;
- goto QS5;
-
- case OP_HSPACE_EXTRA + OP_TYPESTAR:
- case OP_HSPACE_EXTRA + OP_TYPEMINSTAR:
- case OP_HSPACE_EXTRA + OP_TYPEPOSSTAR:
- count = 0;
-
- QS5:
- ADD_ACTIVE(state_offset + 2, 0);
- if (clen > 0)
- {
- BOOL OK;
- switch (c)
- {
- case 0x09: /* HT */
- case 0x20: /* SPACE */
- case 0xa0: /* NBSP */
- case 0x1680: /* OGHAM SPACE MARK */
- case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */
- case 0x2000: /* EN QUAD */
- case 0x2001: /* EM QUAD */
- case 0x2002: /* EN SPACE */
- case 0x2003: /* EM SPACE */
- case 0x2004: /* THREE-PER-EM SPACE */
- case 0x2005: /* FOUR-PER-EM SPACE */
- case 0x2006: /* SIX-PER-EM SPACE */
- case 0x2007: /* FIGURE SPACE */
- case 0x2008: /* PUNCTUATION SPACE */
- case 0x2009: /* THIN SPACE */
- case 0x200A: /* HAIR SPACE */
- case 0x202f: /* NARROW NO-BREAK SPACE */
- case 0x205f: /* MEDIUM MATHEMATICAL SPACE */
- case 0x3000: /* IDEOGRAPHIC SPACE */
- OK = TRUE;
- break;
-
- default:
- OK = FALSE;
- break;
- }
-
- if (OK == (d == OP_HSPACE))
- {
- if (codevalue == OP_HSPACE_EXTRA + OP_TYPEPOSSTAR ||
- codevalue == OP_HSPACE_EXTRA + OP_TYPEPOSQUERY)
- {
- active_count--; /* Remove non-match possibility */
- next_active_state--;
- }
- ADD_NEW_DATA(-(state_offset + count), 0, 0);
- }
- }
- break;
-
- /*-----------------------------------------------------------------*/
-#ifdef SUPPORT_UCP
- case OP_PROP_EXTRA + OP_TYPEEXACT:
- case OP_PROP_EXTRA + OP_TYPEUPTO:
- case OP_PROP_EXTRA + OP_TYPEMINUPTO:
- case OP_PROP_EXTRA + OP_TYPEPOSUPTO:
- if (codevalue != OP_PROP_EXTRA + OP_TYPEEXACT)
- { ADD_ACTIVE(state_offset + 6, 0); }
- count = current_state->count; /* Number already matched */
- if (clen > 0)
- {
- BOOL OK;
- int category = _pcre_ucp_findprop(c, &chartype, &script);
- switch(code[4])
- {
- case PT_ANY:
- OK = TRUE;
- break;
-
- case PT_LAMP:
- OK = chartype == ucp_Lu || chartype == ucp_Ll || chartype == ucp_Lt;
- break;
-
- case PT_GC:
- OK = category == code[5];
- break;
-
- case PT_PC:
- OK = chartype == code[5];
- break;
-
- case PT_SC:
- OK = script == code[5];
- break;
-
- /* Should never occur, but keep compilers from grumbling. */
-
- default:
- OK = codevalue != OP_PROP;
- break;
- }
-
- if (OK == (d == OP_PROP))
- {
- if (codevalue == OP_PROP_EXTRA + OP_TYPEPOSUPTO)
- {
- active_count--; /* Remove non-match possibility */
- next_active_state--;
- }
- if (++count >= GET2(code, 1))
- { ADD_NEW(state_offset + 6, 0); }
- else
- { ADD_NEW(state_offset, count); }
- }
- }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_EXTUNI_EXTRA + OP_TYPEEXACT:
- case OP_EXTUNI_EXTRA + OP_TYPEUPTO:
- case OP_EXTUNI_EXTRA + OP_TYPEMINUPTO:
- case OP_EXTUNI_EXTRA + OP_TYPEPOSUPTO:
- if (codevalue != OP_EXTUNI_EXTRA + OP_TYPEEXACT)
- { ADD_ACTIVE(state_offset + 4, 0); }
- count = current_state->count; /* Number already matched */
- if (clen > 0 && _pcre_ucp_findprop(c, &chartype, &script) != ucp_M)
- {
- const uschar *nptr = ptr + clen;
- int ncount = 0;
- if (codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSUPTO)
- {
- active_count--; /* Remove non-match possibility */
- next_active_state--;
- }
- while (nptr < end_subject)
- {
- int nd;
- int ndlen = 1;
- GETCHARLEN(nd, nptr, ndlen);
- if (_pcre_ucp_findprop(nd, &chartype, &script) != ucp_M) break;
- ncount++;
- nptr += ndlen;
- }
- if (++count >= GET2(code, 1))
- { ADD_NEW_DATA(-(state_offset + 4), 0, ncount); }
- else
- { ADD_NEW_DATA(-state_offset, count, ncount); }
- }
- break;
-#endif
-
- /*-----------------------------------------------------------------*/
- case OP_ANYNL_EXTRA + OP_TYPEEXACT:
- case OP_ANYNL_EXTRA + OP_TYPEUPTO:
- case OP_ANYNL_EXTRA + OP_TYPEMINUPTO:
- case OP_ANYNL_EXTRA + OP_TYPEPOSUPTO:
- if (codevalue != OP_ANYNL_EXTRA + OP_TYPEEXACT)
- { ADD_ACTIVE(state_offset + 4, 0); }
- count = current_state->count; /* Number already matched */
- if (clen > 0)
- {
- int ncount = 0;
- switch (c)
- {
- case 0x000b:
- case 0x000c:
- case 0x0085:
- case 0x2028:
- case 0x2029:
- if ((md->moptions & PCRE_BSR_ANYCRLF) != 0) break;
- goto ANYNL03;
-
- case 0x000d:
- if (ptr + 1 < end_subject && ptr[1] == 0x0a) ncount = 1;
- /* Fall through */
-
- ANYNL03:
- case 0x000a:
- if (codevalue == OP_ANYNL_EXTRA + OP_TYPEPOSUPTO)
- {
- active_count--; /* Remove non-match possibility */
- next_active_state--;
- }
- if (++count >= GET2(code, 1))
- { ADD_NEW_DATA(-(state_offset + 4), 0, ncount); }
- else
- { ADD_NEW_DATA(-state_offset, count, ncount); }
- break;
-
- default:
- break;
- }
- }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_VSPACE_EXTRA + OP_TYPEEXACT:
- case OP_VSPACE_EXTRA + OP_TYPEUPTO:
- case OP_VSPACE_EXTRA + OP_TYPEMINUPTO:
- case OP_VSPACE_EXTRA + OP_TYPEPOSUPTO:
- if (codevalue != OP_VSPACE_EXTRA + OP_TYPEEXACT)
- { ADD_ACTIVE(state_offset + 4, 0); }
- count = current_state->count; /* Number already matched */
- if (clen > 0)
- {
- BOOL OK;
- switch (c)
- {
- case 0x000a:
- case 0x000b:
- case 0x000c:
- case 0x000d:
- case 0x0085:
- case 0x2028:
- case 0x2029:
- OK = TRUE;
- break;
-
- default:
- OK = FALSE;
- }
-
- if (OK == (d == OP_VSPACE))
- {
- if (codevalue == OP_VSPACE_EXTRA + OP_TYPEPOSUPTO)
- {
- active_count--; /* Remove non-match possibility */
- next_active_state--;
- }
- if (++count >= GET2(code, 1))
- { ADD_NEW_DATA(-(state_offset + 4), 0, 0); }
- else
- { ADD_NEW_DATA(-state_offset, count, 0); }
- }
- }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_HSPACE_EXTRA + OP_TYPEEXACT:
- case OP_HSPACE_EXTRA + OP_TYPEUPTO:
- case OP_HSPACE_EXTRA + OP_TYPEMINUPTO:
- case OP_HSPACE_EXTRA + OP_TYPEPOSUPTO:
- if (codevalue != OP_HSPACE_EXTRA + OP_TYPEEXACT)
- { ADD_ACTIVE(state_offset + 4, 0); }
- count = current_state->count; /* Number already matched */
- if (clen > 0)
- {
- BOOL OK;
- switch (c)
- {
- case 0x09: /* HT */
- case 0x20: /* SPACE */
- case 0xa0: /* NBSP */
- case 0x1680: /* OGHAM SPACE MARK */
- case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */
- case 0x2000: /* EN QUAD */
- case 0x2001: /* EM QUAD */
- case 0x2002: /* EN SPACE */
- case 0x2003: /* EM SPACE */
- case 0x2004: /* THREE-PER-EM SPACE */
- case 0x2005: /* FOUR-PER-EM SPACE */
- case 0x2006: /* SIX-PER-EM SPACE */
- case 0x2007: /* FIGURE SPACE */
- case 0x2008: /* PUNCTUATION SPACE */
- case 0x2009: /* THIN SPACE */
- case 0x200A: /* HAIR SPACE */
- case 0x202f: /* NARROW NO-BREAK SPACE */
- case 0x205f: /* MEDIUM MATHEMATICAL SPACE */
- case 0x3000: /* IDEOGRAPHIC SPACE */
- OK = TRUE;
- break;
-
- default:
- OK = FALSE;
- break;
- }
-
- if (OK == (d == OP_HSPACE))
- {
- if (codevalue == OP_HSPACE_EXTRA + OP_TYPEPOSUPTO)
- {
- active_count--; /* Remove non-match possibility */
- next_active_state--;
- }
- if (++count >= GET2(code, 1))
- { ADD_NEW_DATA(-(state_offset + 4), 0, 0); }
- else
- { ADD_NEW_DATA(-state_offset, count, 0); }
- }
- }
- break;
-
-/* ========================================================================== */
- /* These opcodes are followed by a character that is usually compared
- to the current subject character; it is loaded into d. We still get
- here even if there is no subject character, because in some cases zero
- repetitions are permitted. */
-
- /*-----------------------------------------------------------------*/
- case OP_CHAR:
- if (clen > 0 && c == d) { ADD_NEW(state_offset + dlen + 1, 0); }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_CHARNC:
- if (clen == 0) break;
-
-#ifdef SUPPORT_UTF8
- if (utf8)
- {
- if (c == d) { ADD_NEW(state_offset + dlen + 1, 0); } else
- {
- unsigned int othercase;
- if (c < 128) othercase = fcc[c]; else
-
- /* If we have Unicode property support, we can use it to test the
- other case of the character. */
-
-#ifdef SUPPORT_UCP
- othercase = _pcre_ucp_othercase(c);
-#else
- othercase = NOTACHAR;
-#endif
-
- if (d == othercase) { ADD_NEW(state_offset + dlen + 1, 0); }
- }
- }
- else
-#endif /* SUPPORT_UTF8 */
-
- /* Non-UTF-8 mode */
- {
- if (lcc[c] == lcc[d]) { ADD_NEW(state_offset + 2, 0); }
- }
- break;
-
-
-#ifdef SUPPORT_UCP
- /*-----------------------------------------------------------------*/
- /* This is a tricky one because it can match more than one character.
- Find out how many characters to skip, and then set up a negative state
- to wait for them to pass before continuing. */
-
- case OP_EXTUNI:
- if (clen > 0 && _pcre_ucp_findprop(c, &chartype, &script) != ucp_M)
- {
- const uschar *nptr = ptr + clen;
- int ncount = 0;
- while (nptr < end_subject)
- {
- int nclen = 1;
- GETCHARLEN(c, nptr, nclen);
- if (_pcre_ucp_findprop(c, &chartype, &script) != ucp_M) break;
- ncount++;
- nptr += nclen;
- }
- ADD_NEW_DATA(-(state_offset + 1), 0, ncount);
- }
- break;
-#endif
-
- /*-----------------------------------------------------------------*/
- /* This is a tricky like EXTUNI because it too can match more than one
- character (when CR is followed by LF). In this case, set up a negative
- state to wait for one character to pass before continuing. */
-
- case OP_ANYNL:
- if (clen > 0) switch(c)
- {
- case 0x000b:
- case 0x000c:
- case 0x0085:
- case 0x2028:
- case 0x2029:
- if ((md->moptions & PCRE_BSR_ANYCRLF) != 0) break;
-
- case 0x000a:
- ADD_NEW(state_offset + 1, 0);
- break;
-
- case 0x000d:
- if (ptr + 1 < end_subject && ptr[1] == 0x0a)
- {
- ADD_NEW_DATA(-(state_offset + 1), 0, 1);
- }
- else
- {
- ADD_NEW(state_offset + 1, 0);
- }
- break;
- }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_NOT_VSPACE:
- if (clen > 0) switch(c)
- {
- case 0x000a:
- case 0x000b:
- case 0x000c:
- case 0x000d:
- case 0x0085:
- case 0x2028:
- case 0x2029:
- break;
-
- default:
- ADD_NEW(state_offset + 1, 0);
- break;
- }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_VSPACE:
- if (clen > 0) switch(c)
- {
- case 0x000a:
- case 0x000b:
- case 0x000c:
- case 0x000d:
- case 0x0085:
- case 0x2028:
- case 0x2029:
- ADD_NEW(state_offset + 1, 0);
- break;
-
- default: break;
- }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_NOT_HSPACE:
- if (clen > 0) switch(c)
- {
- case 0x09: /* HT */
- case 0x20: /* SPACE */
- case 0xa0: /* NBSP */
- case 0x1680: /* OGHAM SPACE MARK */
- case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */
- case 0x2000: /* EN QUAD */
- case 0x2001: /* EM QUAD */
- case 0x2002: /* EN SPACE */
- case 0x2003: /* EM SPACE */
- case 0x2004: /* THREE-PER-EM SPACE */
- case 0x2005: /* FOUR-PER-EM SPACE */
- case 0x2006: /* SIX-PER-EM SPACE */
- case 0x2007: /* FIGURE SPACE */
- case 0x2008: /* PUNCTUATION SPACE */
- case 0x2009: /* THIN SPACE */
- case 0x200A: /* HAIR SPACE */
- case 0x202f: /* NARROW NO-BREAK SPACE */
- case 0x205f: /* MEDIUM MATHEMATICAL SPACE */
- case 0x3000: /* IDEOGRAPHIC SPACE */
- break;
-
- default:
- ADD_NEW(state_offset + 1, 0);
- break;
- }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_HSPACE:
- if (clen > 0) switch(c)
- {
- case 0x09: /* HT */
- case 0x20: /* SPACE */
- case 0xa0: /* NBSP */
- case 0x1680: /* OGHAM SPACE MARK */
- case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */
- case 0x2000: /* EN QUAD */
- case 0x2001: /* EM QUAD */
- case 0x2002: /* EN SPACE */
- case 0x2003: /* EM SPACE */
- case 0x2004: /* THREE-PER-EM SPACE */
- case 0x2005: /* FOUR-PER-EM SPACE */
- case 0x2006: /* SIX-PER-EM SPACE */
- case 0x2007: /* FIGURE SPACE */
- case 0x2008: /* PUNCTUATION SPACE */
- case 0x2009: /* THIN SPACE */
- case 0x200A: /* HAIR SPACE */
- case 0x202f: /* NARROW NO-BREAK SPACE */
- case 0x205f: /* MEDIUM MATHEMATICAL SPACE */
- case 0x3000: /* IDEOGRAPHIC SPACE */
- ADD_NEW(state_offset + 1, 0);
- break;
- }
- break;
-
- /*-----------------------------------------------------------------*/
- /* Match a negated single character. This is only used for one-byte
- characters, that is, we know that d < 256. The character we are
- checking (c) can be multibyte. */
-
- case OP_NOT:
- if (clen > 0)
- {
- unsigned int otherd = ((ims & PCRE_CASELESS) != 0)? fcc[d] : d;
- if (c != d && c != otherd) { ADD_NEW(state_offset + dlen + 1, 0); }
- }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_PLUS:
- case OP_MINPLUS:
- case OP_POSPLUS:
- case OP_NOTPLUS:
- case OP_NOTMINPLUS:
- case OP_NOTPOSPLUS:
- count = current_state->count; /* Already matched */
- if (count > 0) { ADD_ACTIVE(state_offset + dlen + 1, 0); }
- if (clen > 0)
- {
- unsigned int otherd = NOTACHAR;
- if ((ims & PCRE_CASELESS) != 0)
- {
-#ifdef SUPPORT_UTF8
- if (utf8 && d >= 128)
- {
-#ifdef SUPPORT_UCP
- otherd = _pcre_ucp_othercase(d);
-#endif /* SUPPORT_UCP */
- }
- else
-#endif /* SUPPORT_UTF8 */
- otherd = fcc[d];
- }
- if ((c == d || c == otherd) == (codevalue < OP_NOTSTAR))
- {
- if (count > 0 &&
- (codevalue == OP_POSPLUS || codevalue == OP_NOTPOSPLUS))
- {
- active_count--; /* Remove non-match possibility */
- next_active_state--;
- }
- count++;
- ADD_NEW(state_offset, count);
- }
- }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_QUERY:
- case OP_MINQUERY:
- case OP_POSQUERY:
- case OP_NOTQUERY:
- case OP_NOTMINQUERY:
- case OP_NOTPOSQUERY:
- ADD_ACTIVE(state_offset + dlen + 1, 0);
- if (clen > 0)
- {
- unsigned int otherd = NOTACHAR;
- if ((ims & PCRE_CASELESS) != 0)
- {
-#ifdef SUPPORT_UTF8
- if (utf8 && d >= 128)
- {
-#ifdef SUPPORT_UCP
- otherd = _pcre_ucp_othercase(d);
-#endif /* SUPPORT_UCP */
- }
- else
-#endif /* SUPPORT_UTF8 */
- otherd = fcc[d];
- }
- if ((c == d || c == otherd) == (codevalue < OP_NOTSTAR))
- {
- if (codevalue == OP_POSQUERY || codevalue == OP_NOTPOSQUERY)
- {
- active_count--; /* Remove non-match possibility */
- next_active_state--;
- }
- ADD_NEW(state_offset + dlen + 1, 0);
- }
- }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_STAR:
- case OP_MINSTAR:
- case OP_POSSTAR:
- case OP_NOTSTAR:
- case OP_NOTMINSTAR:
- case OP_NOTPOSSTAR:
- ADD_ACTIVE(state_offset + dlen + 1, 0);
- if (clen > 0)
- {
- unsigned int otherd = NOTACHAR;
- if ((ims & PCRE_CASELESS) != 0)
- {
-#ifdef SUPPORT_UTF8
- if (utf8 && d >= 128)
- {
-#ifdef SUPPORT_UCP
- otherd = _pcre_ucp_othercase(d);
-#endif /* SUPPORT_UCP */
- }
- else
-#endif /* SUPPORT_UTF8 */
- otherd = fcc[d];
- }
- if ((c == d || c == otherd) == (codevalue < OP_NOTSTAR))
- {
- if (codevalue == OP_POSSTAR || codevalue == OP_NOTPOSSTAR)
- {
- active_count--; /* Remove non-match possibility */
- next_active_state--;
- }
- ADD_NEW(state_offset, 0);
- }
- }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_EXACT:
- case OP_NOTEXACT:
- count = current_state->count; /* Number already matched */
- if (clen > 0)
- {
- unsigned int otherd = NOTACHAR;
- if ((ims & PCRE_CASELESS) != 0)
- {
-#ifdef SUPPORT_UTF8
- if (utf8 && d >= 128)
- {
-#ifdef SUPPORT_UCP
- otherd = _pcre_ucp_othercase(d);
-#endif /* SUPPORT_UCP */
- }
- else
-#endif /* SUPPORT_UTF8 */
- otherd = fcc[d];
- }
- if ((c == d || c == otherd) == (codevalue < OP_NOTSTAR))
- {
- if (++count >= GET2(code, 1))
- { ADD_NEW(state_offset + dlen + 3, 0); }
- else
- { ADD_NEW(state_offset, count); }
- }
- }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_UPTO:
- case OP_MINUPTO:
- case OP_POSUPTO:
- case OP_NOTUPTO:
- case OP_NOTMINUPTO:
- case OP_NOTPOSUPTO:
- ADD_ACTIVE(state_offset + dlen + 3, 0);
- count = current_state->count; /* Number already matched */
- if (clen > 0)
- {
- unsigned int otherd = NOTACHAR;
- if ((ims & PCRE_CASELESS) != 0)
- {
-#ifdef SUPPORT_UTF8
- if (utf8 && d >= 128)
- {
-#ifdef SUPPORT_UCP
- otherd = _pcre_ucp_othercase(d);
-#endif /* SUPPORT_UCP */
- }
- else
-#endif /* SUPPORT_UTF8 */
- otherd = fcc[d];
- }
- if ((c == d || c == otherd) == (codevalue < OP_NOTSTAR))
- {
- if (codevalue == OP_POSUPTO || codevalue == OP_NOTPOSUPTO)
- {
- active_count--; /* Remove non-match possibility */
- next_active_state--;
- }
- if (++count >= GET2(code, 1))
- { ADD_NEW(state_offset + dlen + 3, 0); }
- else
- { ADD_NEW(state_offset, count); }
- }
- }
- break;
-
-
-/* ========================================================================== */
- /* These are the class-handling opcodes */
-
- case OP_CLASS:
- case OP_NCLASS:
- case OP_XCLASS:
- {
- BOOL isinclass = FALSE;
- int next_state_offset;
- const uschar *ecode;
-
- /* For a simple class, there is always just a 32-byte table, and we
- can set isinclass from it. */
-
- if (codevalue != OP_XCLASS)
- {
- ecode = code + 33;
- if (clen > 0)
- {
- isinclass = (c > 255)? (codevalue == OP_NCLASS) :
- ((code[1 + c/8] & (1 << (c&7))) != 0);
- }
- }
-
- /* An extended class may have a table or a list of single characters,
- ranges, or both, and it may be positive or negative. There's a
- function that sorts all this out. */
-
- else
- {
- ecode = code + GET(code, 1);
- if (clen > 0) isinclass = _pcre_xclass(c, code + 1 + LINK_SIZE);
- }
-
- /* At this point, isinclass is set for all kinds of class, and ecode
- points to the byte after the end of the class. If there is a
- quantifier, this is where it will be. */
-
- next_state_offset = ecode - start_code;
-
- switch (*ecode)
- {
- case OP_CRSTAR:
- case OP_CRMINSTAR:
- ADD_ACTIVE(next_state_offset + 1, 0);
- if (isinclass) { ADD_NEW(state_offset, 0); }
- break;
-
- case OP_CRPLUS:
- case OP_CRMINPLUS:
- count = current_state->count; /* Already matched */
- if (count > 0) { ADD_ACTIVE(next_state_offset + 1, 0); }
- if (isinclass) { count++; ADD_NEW(state_offset, count); }
- break;
-
- case OP_CRQUERY:
- case OP_CRMINQUERY:
- ADD_ACTIVE(next_state_offset + 1, 0);
- if (isinclass) { ADD_NEW(next_state_offset + 1, 0); }
- break;
-
- case OP_CRRANGE:
- case OP_CRMINRANGE:
- count = current_state->count; /* Already matched */
- if (count >= GET2(ecode, 1))
- { ADD_ACTIVE(next_state_offset + 5, 0); }
- if (isinclass)
- {
- int max = GET2(ecode, 3);
- if (++count >= max && max != 0) /* Max 0 => no limit */
- { ADD_NEW(next_state_offset + 5, 0); }
- else
- { ADD_NEW(state_offset, count); }
- }
- break;
-
- default:
- if (isinclass) { ADD_NEW(next_state_offset, 0); }
- break;
- }
- }
- break;
-
-/* ========================================================================== */
- /* These are the opcodes for fancy brackets of various kinds. We have
- to use recursion in order to handle them. The "always failing" assersion
- (?!) is optimised when compiling to OP_FAIL, so we have to support that,
- though the other "backtracking verbs" are not supported. */
-
- case OP_FAIL:
- break;
-
- case OP_ASSERT:
- case OP_ASSERT_NOT:
- case OP_ASSERTBACK:
- case OP_ASSERTBACK_NOT:
- {
- int rc;
- int local_offsets[2];
- int local_workspace[1000];
- const uschar *endasscode = code + GET(code, 1);
-
- while (*endasscode == OP_ALT) endasscode += GET(endasscode, 1);
-
- rc = internal_dfa_exec(
- md, /* static match data */
- code, /* this subexpression's code */
- ptr, /* where we currently are */
- ptr - start_subject, /* start offset */
- local_offsets, /* offset vector */
- sizeof(local_offsets)/sizeof(int), /* size of same */
- local_workspace, /* workspace vector */
- sizeof(local_workspace)/sizeof(int), /* size of same */
- ims, /* the current ims flags */
- rlevel, /* function recursion level */
- recursing); /* pass on regex recursion */
-
- if ((rc >= 0) == (codevalue == OP_ASSERT || codevalue == OP_ASSERTBACK))
- { ADD_ACTIVE(endasscode + LINK_SIZE + 1 - start_code, 0); }
- }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_COND:
- case OP_SCOND:
- {
- int local_offsets[1000];
- int local_workspace[1000];
- int condcode = code[LINK_SIZE+1];
-
- /* Back reference conditions are not supported */
-
- if (condcode == OP_CREF) return PCRE_ERROR_DFA_UCOND;
-
- /* The DEFINE condition is always false */
-
- if (condcode == OP_DEF)
- {
- ADD_ACTIVE(state_offset + GET(code, 1) + LINK_SIZE + 1, 0);
- }
-
- /* The only supported version of OP_RREF is for the value RREF_ANY,
- which means "test if in any recursion". We can't test for specifically
- recursed groups. */
-
- else if (condcode == OP_RREF)
- {
- int value = GET2(code, LINK_SIZE+2);
- if (value != RREF_ANY) return PCRE_ERROR_DFA_UCOND;
- if (recursing > 0) { ADD_ACTIVE(state_offset + LINK_SIZE + 4, 0); }
- else { ADD_ACTIVE(state_offset + GET(code, 1) + LINK_SIZE + 1, 0); }
- }
-
- /* Otherwise, the condition is an assertion */
-
- else
- {
- int rc;
- const uschar *asscode = code + LINK_SIZE + 1;
- const uschar *endasscode = asscode + GET(asscode, 1);
-
- while (*endasscode == OP_ALT) endasscode += GET(endasscode, 1);
-
- rc = internal_dfa_exec(
- md, /* fixed match data */
- asscode, /* this subexpression's code */
- ptr, /* where we currently are */
- ptr - start_subject, /* start offset */
- local_offsets, /* offset vector */
- sizeof(local_offsets)/sizeof(int), /* size of same */
- local_workspace, /* workspace vector */
- sizeof(local_workspace)/sizeof(int), /* size of same */
- ims, /* the current ims flags */
- rlevel, /* function recursion level */
- recursing); /* pass on regex recursion */
-
- if ((rc >= 0) ==
- (condcode == OP_ASSERT || condcode == OP_ASSERTBACK))
- { ADD_ACTIVE(endasscode + LINK_SIZE + 1 - start_code, 0); }
- else
- { ADD_ACTIVE(state_offset + GET(code, 1) + LINK_SIZE + 1, 0); }
- }
- }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_RECURSE:
- {
- int local_offsets[1000];
- int local_workspace[1000];
- int rc;
-
- DPRINTF(("%.*sStarting regex recursion %d\n", rlevel*2-2, SP,
- recursing + 1));
-
- rc = internal_dfa_exec(
- md, /* fixed match data */
- start_code + GET(code, 1), /* this subexpression's code */
- ptr, /* where we currently are */
- ptr - start_subject, /* start offset */
- local_offsets, /* offset vector */
- sizeof(local_offsets)/sizeof(int), /* size of same */
- local_workspace, /* workspace vector */
- sizeof(local_workspace)/sizeof(int), /* size of same */
- ims, /* the current ims flags */
- rlevel, /* function recursion level */
- recursing + 1); /* regex recurse level */
-
- DPRINTF(("%.*sReturn from regex recursion %d: rc=%d\n", rlevel*2-2, SP,
- recursing + 1, rc));
-
- /* Ran out of internal offsets */
-
- if (rc == 0) return PCRE_ERROR_DFA_RECURSE;
-
- /* For each successful matched substring, set up the next state with a
- count of characters to skip before trying it. Note that the count is in
- characters, not bytes. */
-
- if (rc > 0)
- {
- for (rc = rc*2 - 2; rc >= 0; rc -= 2)
- {
- const uschar *p = start_subject + local_offsets[rc];
- const uschar *pp = start_subject + local_offsets[rc+1];
- int charcount = local_offsets[rc+1] - local_offsets[rc];
- while (p < pp) if ((*p++ & 0xc0) == 0x80) charcount--;
- if (charcount > 0)
- {
- ADD_NEW_DATA(-(state_offset + LINK_SIZE + 1), 0, (charcount - 1));
- }
- else
- {
- ADD_ACTIVE(state_offset + LINK_SIZE + 1, 0);
- }
- }
- }
- else if (rc != PCRE_ERROR_NOMATCH) return rc;
- }
- break;
-
- /*-----------------------------------------------------------------*/
- case OP_ONCE:
- {
- int local_offsets[2];
- int local_workspace[1000];
-
- int rc = internal_dfa_exec(
- md, /* fixed match data */
- code, /* this subexpression's code */
- ptr, /* where we currently are */
- ptr - start_subject, /* start offset */
- local_offsets, /* offset vector */
- sizeof(local_offsets)/sizeof(int), /* size of same */
- local_workspace, /* workspace vector */
- sizeof(local_workspace)/sizeof(int), /* size of same */
- ims, /* the current ims flags */
- rlevel, /* function recursion level */
- recursing); /* pass on regex recursion */
-
- if (rc >= 0)
- {
- const uschar *end_subpattern = code;
- int charcount = local_offsets[1] - local_offsets[0];
- int next_state_offset, repeat_state_offset;
-
- do { end_subpattern += GET(end_subpattern, 1); }
- while (*end_subpattern == OP_ALT);
- next_state_offset = end_subpattern - start_code + LINK_SIZE + 1;
-
- /* If the end of this subpattern is KETRMAX or KETRMIN, we must
- arrange for the repeat state also to be added to the relevant list.
- Calculate the offset, or set -1 for no repeat. */
-
- repeat_state_offset = (*end_subpattern == OP_KETRMAX ||
- *end_subpattern == OP_KETRMIN)?
- end_subpattern - start_code - GET(end_subpattern, 1) : -1;
-
- /* If we have matched an empty string, add the next state at the
- current character pointer. This is important so that the duplicate
- checking kicks in, which is what breaks infinite loops that match an
- empty string. */
-
- if (charcount == 0)
- {
- ADD_ACTIVE(next_state_offset, 0);
- }
-
- /* Optimization: if there are no more active states, and there
- are no new states yet set up, then skip over the subject string
- right here, to save looping. Otherwise, set up the new state to swing
- into action when the end of the substring is reached. */
-
- else if (i + 1 >= active_count && new_count == 0)
- {
- ptr += charcount;
- clen = 0;
- ADD_NEW(next_state_offset, 0);
-
- /* If we are adding a repeat state at the new character position,
- we must fudge things so that it is the only current state.
- Otherwise, it might be a duplicate of one we processed before, and
- that would cause it to be skipped. */
-
- if (repeat_state_offset >= 0)
- {
- next_active_state = active_states;
- active_count = 0;
- i = -1;
- ADD_ACTIVE(repeat_state_offset, 0);
- }
- }
- else
- {
- const uschar *p = start_subject + local_offsets[0];
- const uschar *pp = start_subject + local_offsets[1];
- while (p < pp) if ((*p++ & 0xc0) == 0x80) charcount--;
- ADD_NEW_DATA(-next_state_offset, 0, (charcount - 1));
- if (repeat_state_offset >= 0)
- { ADD_NEW_DATA(-repeat_state_offset, 0, (charcount - 1)); }
- }
-
- }
- else if (rc != PCRE_ERROR_NOMATCH) return rc;
- }
- break;
-
-
-/* ========================================================================== */
- /* Handle callouts */
-
- case OP_CALLOUT:
- if (pcre_callout != NULL)
- {
- int rrc;
- pcre_callout_block cb;
- cb.version = 1; /* Version 1 of the callout block */
- cb.callout_number = code[1];
- cb.offset_vector = offsets;
- cb.subject = (PCRE_SPTR)start_subject;
- cb.subject_length = end_subject - start_subject;
- cb.start_match = current_subject - start_subject;
- cb.current_position = ptr - start_subject;
- cb.pattern_position = GET(code, 2);
- cb.next_item_length = GET(code, 2 + LINK_SIZE);
- cb.capture_top = 1;
- cb.capture_last = -1;
- cb.callout_data = md->callout_data;
- if ((rrc = (*pcre_callout)(&cb)) < 0) return rrc; /* Abandon */
- if (rrc == 0) { ADD_ACTIVE(state_offset + 2 + 2*LINK_SIZE, 0); }
- }
- break;
-
-
-/* ========================================================================== */
- default: /* Unsupported opcode */
- return PCRE_ERROR_DFA_UITEM;
- }
-
- NEXT_ACTIVE_STATE: continue;
-
- } /* End of loop scanning active states */
-
- /* We have finished the processing at the current subject character. If no
- new states have been set for the next character, we have found all the
- matches that we are going to find. If we are at the top level and partial
- matching has been requested, check for appropriate conditions. */
-
- if (new_count <= 0)
- {
- if (match_count < 0 && /* No matches found */
- rlevel == 1 && /* Top level match function */
- (md->moptions & PCRE_PARTIAL) != 0 && /* Want partial matching */
- ptr >= end_subject && /* Reached end of subject */
- ptr > current_subject) /* Matched non-empty string */
- {
- if (offsetcount >= 2)
- {
- offsets[0] = current_subject - start_subject;
- offsets[1] = end_subject - start_subject;
- }
- match_count = PCRE_ERROR_PARTIAL;
- }
-
- DPRINTF(("%.*sEnd of internal_dfa_exec %d: returning %d\n"
- "%.*s---------------------\n\n", rlevel*2-2, SP, rlevel, match_count,
- rlevel*2-2, SP));
- break; /* In effect, "return", but see the comment below */
- }
-
- /* One or more states are active for the next character. */
-
- ptr += clen; /* Advance to next subject character */
- } /* Loop to move along the subject string */
-
-/* Control gets here from "break" a few lines above. We do it this way because
-if we use "return" above, we have compiler trouble. Some compilers warn if
-there's nothing here because they think the function doesn't return a value. On
-the other hand, if we put a dummy statement here, some more clever compilers
-complain that it can't be reached. Sigh. */
-
-return match_count;
-}
-
-
-
-
-/*************************************************
-* Execute a Regular Expression - DFA engine *
-*************************************************/
-
-/* This external function applies a compiled re to a subject string using a DFA
-engine. This function calls the internal function multiple times if the pattern
-is not anchored.
-
-Arguments:
- argument_re points to the compiled expression
- extra_data points to extra data or is NULL
- subject points to the subject string
- length length of subject string (may contain binary zeros)
- start_offset where to start in the subject string
- options option bits
- offsets vector of match offsets
- offsetcount size of same
- workspace workspace vector
- wscount size of same
-
-Returns: > 0 => number of match offset pairs placed in offsets
- = 0 => offsets overflowed; longest matches are present
- -1 => failed to match
- < -1 => some kind of unexpected problem
-*/
-
-PCRE_EXP_DEFN int
-pcre_dfa_exec(const pcre *argument_re, const pcre_extra *extra_data,
- const char *subject, int length, int start_offset, int options, int *offsets,
- int offsetcount, int *workspace, int wscount)
-{
-real_pcre *re = (real_pcre *)argument_re;
-dfa_match_data match_block;
-dfa_match_data *md = &match_block;
-BOOL utf8, anchored, startline, firstline;
-const uschar *current_subject, *end_subject, *lcc;
-
-pcre_study_data internal_study;
-const pcre_study_data *study = NULL;
-real_pcre internal_re;
-
-const uschar *req_byte_ptr;
-const uschar *start_bits = NULL;
-BOOL first_byte_caseless = FALSE;
-BOOL req_byte_caseless = FALSE;
-int first_byte = -1;
-int req_byte = -1;
-int req_byte2 = -1;
-int newline;
-
-/* Plausibility checks */
-
-if ((options & ~PUBLIC_DFA_EXEC_OPTIONS) != 0) return PCRE_ERROR_BADOPTION;
-if (re == NULL || subject == NULL || workspace == NULL ||
- (offsets == NULL && offsetcount > 0)) return PCRE_ERROR_NULL;
-if (offsetcount < 0) return PCRE_ERROR_BADCOUNT;
-if (wscount < 20) return PCRE_ERROR_DFA_WSSIZE;
-
-/* We need to find the pointer to any study data before we test for byte
-flipping, so we scan the extra_data block first. This may set two fields in the
-match block, so we must initialize them beforehand. However, the other fields
-in the match block must not be set until after the byte flipping. */
-
-md->tables = re->tables;
-md->callout_data = NULL;
-
-if (extra_data != NULL)
- {
- unsigned int flags = extra_data->flags;
- if ((flags & PCRE_EXTRA_STUDY_DATA) != 0)
- study = (const pcre_study_data *)extra_data->study_data;
- if ((flags & PCRE_EXTRA_MATCH_LIMIT) != 0) return PCRE_ERROR_DFA_UMLIMIT;
- if ((flags & PCRE_EXTRA_MATCH_LIMIT_RECURSION) != 0)
- return PCRE_ERROR_DFA_UMLIMIT;
- if ((flags & PCRE_EXTRA_CALLOUT_DATA) != 0)
- md->callout_data = extra_data->callout_data;
- if ((flags & PCRE_EXTRA_TABLES) != 0)
- md->tables = extra_data->tables;
- }
-
-/* Check that the first field in the block is the magic number. If it is not,
-test for a regex that was compiled on a host of opposite endianness. If this is
-the case, flipped values are put in internal_re and internal_study if there was
-study data too. */
-
-if (re->magic_number != MAGIC_NUMBER)
- {
- re = _pcre_try_flipped(re, &internal_re, study, &internal_study);
- if (re == NULL) return PCRE_ERROR_BADMAGIC;
- if (study != NULL) study = &internal_study;
- }
-
-/* Set some local values */
-
-current_subject = (const unsigned char *)subject + start_offset;
-end_subject = (const unsigned char *)subject + length;
-req_byte_ptr = current_subject - 1;
-
-#ifdef SUPPORT_UTF8
-utf8 = (re->options & PCRE_UTF8) != 0;
-#else
-utf8 = FALSE;
-#endif
-
-anchored = (options & (PCRE_ANCHORED|PCRE_DFA_RESTART)) != 0 ||
- (re->options & PCRE_ANCHORED) != 0;
-
-/* The remaining fixed data for passing around. */
-
-md->start_code = (const uschar *)argument_re +
- re->name_table_offset + re->name_count * re->name_entry_size;
-md->start_subject = (const unsigned char *)subject;
-md->end_subject = end_subject;
-md->moptions = options;
-md->poptions = re->options;
-
-/* If the BSR option is not set at match time, copy what was set
-at compile time. */
-
-if ((md->moptions & (PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE)) == 0)
- {
- if ((re->options & (PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE)) != 0)
- md->moptions |= re->options & (PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE);
-#ifdef BSR_ANYCRLF
- else md->moptions |= PCRE_BSR_ANYCRLF;
-#endif
- }
-
-/* Handle different types of newline. The three bits give eight cases. If
-nothing is set at run time, whatever was used at compile time applies. */
-
-switch ((((options & PCRE_NEWLINE_BITS) == 0)? re->options : (pcre_uint32)options) &
- PCRE_NEWLINE_BITS)
- {
- case 0: newline = NEWLINE; break; /* Compile-time default */
- case PCRE_NEWLINE_CR: newline = '\r'; break;
- case PCRE_NEWLINE_LF: newline = '\n'; break;
- case PCRE_NEWLINE_CR+
- PCRE_NEWLINE_LF: newline = ('\r' << 8) | '\n'; break;
- case PCRE_NEWLINE_ANY: newline = -1; break;
- case PCRE_NEWLINE_ANYCRLF: newline = -2; break;
- default: return PCRE_ERROR_BADNEWLINE;
- }
-
-if (newline == -2)
- {
- md->nltype = NLTYPE_ANYCRLF;
- }
-else if (newline < 0)
- {
- md->nltype = NLTYPE_ANY;
- }
-else
- {
- md->nltype = NLTYPE_FIXED;
- if (newline > 255)
- {
- md->nllen = 2;
- md->nl[0] = (newline >> 8) & 255;
- md->nl[1] = newline & 255;
- }
- else
- {
- md->nllen = 1;
- md->nl[0] = newline;
- }
- }
-
-/* Check a UTF-8 string if required. Unfortunately there's no way of passing
-back the character offset. */
-
-#ifdef SUPPORT_UTF8
-if (utf8 && (options & PCRE_NO_UTF8_CHECK) == 0)
- {
- if (_pcre_valid_utf8((uschar *)subject, length) >= 0)
- return PCRE_ERROR_BADUTF8;
- if (start_offset > 0 && start_offset < length)
- {
- int tb = ((uschar *)subject)[start_offset];
- if (tb > 127)
- {
- tb &= 0xc0;
- if (tb != 0 && tb != 0xc0) return PCRE_ERROR_BADUTF8_OFFSET;
- }
- }
- }
-#endif
-
-/* If the exec call supplied NULL for tables, use the inbuilt ones. This
-is a feature that makes it possible to save compiled regex and re-use them
-in other programs later. */
-
-if (md->tables == NULL) md->tables = _pcre_default_tables;
-
-/* The lower casing table and the "must be at the start of a line" flag are
-used in a loop when finding where to start. */
-
-lcc = md->tables + lcc_offset;
-startline = (re->flags & PCRE_STARTLINE) != 0;
-firstline = (re->options & PCRE_FIRSTLINE) != 0;
-
-/* Set up the first character to match, if available. The first_byte value is
-never set for an anchored regular expression, but the anchoring may be forced
-at run time, so we have to test for anchoring. The first char may be unset for
-an unanchored pattern, of course. If there's no first char and the pattern was
-studied, there may be a bitmap of possible first characters. */
-
-if (!anchored)
- {
- if ((re->flags & PCRE_FIRSTSET) != 0)
- {
- first_byte = re->first_byte & 255;
- if ((first_byte_caseless = ((re->first_byte & REQ_CASELESS) != 0)) == TRUE)
- first_byte = lcc[first_byte];
- }
- else
- {
- if (startline && study != NULL &&
- (study->options & PCRE_STUDY_MAPPED) != 0)
- start_bits = study->start_bits;
- }
- }
-
-/* For anchored or unanchored matches, there may be a "last known required
-character" set. */
-
-if ((re->flags & PCRE_REQCHSET) != 0)
- {
- req_byte = re->req_byte & 255;
- req_byte_caseless = (re->req_byte & REQ_CASELESS) != 0;
- req_byte2 = (md->tables + fcc_offset)[req_byte]; /* case flipped */
- }
-
-/* Call the main matching function, looping for a non-anchored regex after a
-failed match. Unless restarting, optimize by moving to the first match
-character if possible, when not anchored. Then unless wanting a partial match,
-check for a required later character. */
-
-for (;;)
- {
- int rc;
-
- if ((options & PCRE_DFA_RESTART) == 0)
- {
- const uschar *save_end_subject = end_subject;
-
- /* Advance to a unique first char if possible. If firstline is TRUE, the
- start of the match is constrained to the first line of a multiline string.
- Implement this by temporarily adjusting end_subject so that we stop
- scanning at a newline. If the match fails at the newline, later code breaks
- this loop. */
-
- if (firstline)
- {
- const uschar *t = current_subject;
- while (t < md->end_subject && !IS_NEWLINE(t)) t++;
- end_subject = t;
- }
-
- if (first_byte >= 0)
- {
- if (first_byte_caseless)
- while (current_subject < end_subject &&
- lcc[*current_subject] != first_byte)
- current_subject++;
- else
- while (current_subject < end_subject && *current_subject != first_byte)
- current_subject++;
- }
-
- /* Or to just after a linebreak for a multiline match if possible */
-
- else if (startline)
- {
- if (current_subject > md->start_subject + start_offset)
- {
- while (current_subject <= end_subject && !WAS_NEWLINE(current_subject))
- current_subject++;
-
- /* If we have just passed a CR and the newline option is ANY or
- ANYCRLF, and we are now at a LF, advance the match position by one more
- character. */
-
- if (current_subject[-1] == '\r' &&
- (md->nltype == NLTYPE_ANY || md->nltype == NLTYPE_ANYCRLF) &&
- current_subject < end_subject &&
- *current_subject == '\n')
- current_subject++;
- }
- }
-
- /* Or to a non-unique first char after study */
-
- else if (start_bits != NULL)
- {
- while (current_subject < end_subject)
- {
- register unsigned int c = *current_subject;
- if ((start_bits[c/8] & (1 << (c&7))) == 0) current_subject++;
- else break;
- }
- }
-
- /* Restore fudged end_subject */
-
- end_subject = save_end_subject;
- }
-
- /* If req_byte is set, we know that that character must appear in the subject
- for the match to succeed. If the first character is set, req_byte must be
- later in the subject; otherwise the test starts at the match point. This
- optimization can save a huge amount of work in patterns with nested unlimited
- repeats that aren't going to match. Writing separate code for cased/caseless
- versions makes it go faster, as does using an autoincrement and backing off
- on a match.
-
- HOWEVER: when the subject string is very, very long, searching to its end can
- take a long time, and give bad performance on quite ordinary patterns. This
- showed up when somebody was matching /^C/ on a 32-megabyte string... so we
- don't do this when the string is sufficiently long.
-
- ALSO: this processing is disabled when partial matching is requested.
- */
-
- if (req_byte >= 0 &&
- end_subject - current_subject < REQ_BYTE_MAX &&
- (options & PCRE_PARTIAL) == 0)
- {
- register const uschar *p = current_subject + ((first_byte >= 0)? 1 : 0);
-
- /* We don't need to repeat the search if we haven't yet reached the
- place we found it at last time. */
-
- if (p > req_byte_ptr)
- {
- if (req_byte_caseless)
- {
- while (p < end_subject)
- {
- register int pp = *p++;
- if (pp == req_byte || pp == req_byte2) { p--; break; }
- }
- }
- else
- {
- while (p < end_subject)
- {
- if (*p++ == req_byte) { p--; break; }
- }
- }
-
- /* If we can't find the required character, break the matching loop,
- which will cause a return or PCRE_ERROR_NOMATCH. */
-
- if (p >= end_subject) break;
-
- /* If we have found the required character, save the point where we
- found it, so that we don't search again next time round the loop if
- the start hasn't passed this character yet. */
-
- req_byte_ptr = p;
- }
- }
-
- /* OK, now we can do the business */
-
- rc = internal_dfa_exec(
- md, /* fixed match data */
- md->start_code, /* this subexpression's code */
- current_subject, /* where we currently are */
- start_offset, /* start offset in subject */
- offsets, /* offset vector */
- offsetcount, /* size of same */
- workspace, /* workspace vector */
- wscount, /* size of same */
- re->options & (PCRE_CASELESS|PCRE_MULTILINE|PCRE_DOTALL), /* ims flags */
- 0, /* function recurse level */
- 0); /* regex recurse level */
-
- /* Anything other than "no match" means we are done, always; otherwise, carry
- on only if not anchored. */
-
- if (rc != PCRE_ERROR_NOMATCH || anchored) return rc;
-
- /* Advance to the next subject character unless we are at the end of a line
- and firstline is set. */
-
- if (firstline && IS_NEWLINE(current_subject)) break;
- current_subject++;
- if (utf8)
- {
- while (current_subject < end_subject && (*current_subject & 0xc0) == 0x80)
- current_subject++;
- }
- if (current_subject > end_subject) break;
-
- /* If we have just passed a CR and we are now at a LF, and the pattern does
- not contain any explicit matches for \r or \n, and the newline option is CRLF
- or ANY or ANYCRLF, advance the match position by one more character. */
-
- if (current_subject[-1] == '\r' &&
- current_subject < end_subject &&
- *current_subject == '\n' &&
- (re->flags & PCRE_HASCRORLF) == 0 &&
- (md->nltype == NLTYPE_ANY ||
- md->nltype == NLTYPE_ANYCRLF ||
- md->nllen == 2))
- current_subject++;
-
- } /* "Bumpalong" loop */
-
-return PCRE_ERROR_NOMATCH;
-}
-
-/* End of pcre_dfa_exec.c */
diff --git a/crawl-ref/source/util/pcre/pcre_exec.c b/crawl-ref/source/util/pcre/pcre_exec.c
deleted file mode 100644
index ed28ae7c97..0000000000
--- a/crawl-ref/source/util/pcre/pcre_exec.c
+++ /dev/null
@@ -1,4953 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
- Written by Philip Hazel
- Copyright (c) 1997-2008 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-
-/* This module contains pcre_exec(), the externally visible function that does
-pattern matching using an NFA algorithm, trying to mimic Perl as closely as
-possible. There are also some static supporting functions. */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#define NLBLOCK md /* Block containing newline information */
-#define PSSTART start_subject /* Field containing processed string start */
-#define PSEND end_subject /* Field containing processed string end */
-
-#include "pcre_internal.h"
-
-/* Undefine some potentially clashing cpp symbols */
-
-#undef min
-#undef max
-
-/* Flag bits for the match() function */
-
-#define match_condassert 0x01 /* Called to check a condition assertion */
-#define match_cbegroup 0x02 /* Could-be-empty unlimited repeat group */
-
-/* Non-error returns from the match() function. Error returns are externally
-defined PCRE_ERROR_xxx codes, which are all negative. */
-
-#define MATCH_MATCH 1
-#define MATCH_NOMATCH 0
-
-/* Special internal returns from the match() function. Make them sufficiently
-negative to avoid the external error codes. */
-
-#define MATCH_COMMIT (-999)
-#define MATCH_PRUNE (-998)
-#define MATCH_SKIP (-997)
-#define MATCH_THEN (-996)
-
-/* Maximum number of ints of offset to save on the stack for recursive calls.
-If the offset vector is bigger, malloc is used. This should be a multiple of 3,
-because the offset vector is always a multiple of 3 long. */
-
-#define REC_STACK_SAVE_MAX 30
-
-/* Min and max values for the common repeats; for the maxima, 0 => infinity */
-
-static const char rep_min[] = { 0, 0, 1, 1, 0, 0 };
-static const char rep_max[] = { 0, 0, 0, 0, 1, 1 };
-
-
-
-#ifdef DEBUG
-/*************************************************
-* Debugging function to print chars *
-*************************************************/
-
-/* Print a sequence of chars in printable format, stopping at the end of the
-subject if the requested.
-
-Arguments:
- p points to characters
- length number to print
- is_subject TRUE if printing from within md->start_subject
- md pointer to matching data block, if is_subject is TRUE
-
-Returns: nothing
-*/
-
-static void
-pchars(const uschar *p, int length, BOOL is_subject, match_data *md)
-{
-unsigned int c;
-if (is_subject && length > md->end_subject - p) length = md->end_subject - p;
-while (length-- > 0)
- if (isprint(c = *(p++))) printf("%c", c); else printf("\\x%02x", c);
-}
-#endif
-
-
-
-/*************************************************
-* Match a back-reference *
-*************************************************/
-
-/* If a back reference hasn't been set, the length that is passed is greater
-than the number of characters left in the string, so the match fails.
-
-Arguments:
- offset index into the offset vector
- eptr points into the subject
- length length to be matched
- md points to match data block
- ims the ims flags
-
-Returns: TRUE if matched
-*/
-
-static BOOL
-match_ref(int offset, register USPTR eptr, int length, match_data *md,
- unsigned long int ims)
-{
-USPTR p = md->start_subject + md->offset_vector[offset];
-
-#ifdef DEBUG
-if (eptr >= md->end_subject)
- printf("matching subject <null>");
-else
- {
- printf("matching subject ");
- pchars(eptr, length, TRUE, md);
- }
-printf(" against backref ");
-pchars(p, length, FALSE, md);
-printf("\n");
-#endif
-
-/* Always fail if not enough characters left */
-
-if (length > md->end_subject - eptr) return FALSE;
-
-/* Separate the caselesss case for speed */
-
-if ((ims & PCRE_CASELESS) != 0)
- {
- while (length-- > 0)
- if (md->lcc[*p++] != md->lcc[*eptr++]) return FALSE;
- }
-else
- { while (length-- > 0) if (*p++ != *eptr++) return FALSE; }
-
-return TRUE;
-}
-
-
-
-/***************************************************************************
-****************************************************************************
- RECURSION IN THE match() FUNCTION
-
-The match() function is highly recursive, though not every recursive call
-increases the recursive depth. Nevertheless, some regular expressions can cause
-it to recurse to a great depth. I was writing for Unix, so I just let it call
-itself recursively. This uses the stack for saving everything that has to be
-saved for a recursive call. On Unix, the stack can be large, and this works
-fine.
-
-It turns out that on some non-Unix-like systems there are problems with
-programs that use a lot of stack. (This despite the fact that every last chip
-has oodles of memory these days, and techniques for extending the stack have
-been known for decades.) So....
-
-There is a fudge, triggered by defining NO_RECURSE, which avoids recursive
-calls by keeping local variables that need to be preserved in blocks of memory
-obtained from malloc() instead instead of on the stack. Macros are used to
-achieve this so that the actual code doesn't look very different to what it
-always used to.
-
-The original heap-recursive code used longjmp(). However, it seems that this
-can be very slow on some operating systems. Following a suggestion from Stan
-Switzer, the use of longjmp() has been abolished, at the cost of having to
-provide a unique number for each call to RMATCH. There is no way of generating
-a sequence of numbers at compile time in C. I have given them names, to make
-them stand out more clearly.
-
-Crude tests on x86 Linux show a small speedup of around 5-8%. However, on
-FreeBSD, avoiding longjmp() more than halves the time taken to run the standard
-tests. Furthermore, not using longjmp() means that local dynamic variables
-don't have indeterminate values; this has meant that the frame size can be
-reduced because the result can be "passed back" by straight setting of the
-variable instead of being passed in the frame.
-****************************************************************************
-***************************************************************************/
-
-/* Numbers for RMATCH calls. When this list is changed, the code at HEAP_RETURN
-below must be updated in sync. */
-
-enum { RM1=1, RM2, RM3, RM4, RM5, RM6, RM7, RM8, RM9, RM10,
- RM11, RM12, RM13, RM14, RM15, RM16, RM17, RM18, RM19, RM20,
- RM21, RM22, RM23, RM24, RM25, RM26, RM27, RM28, RM29, RM30,
- RM31, RM32, RM33, RM34, RM35, RM36, RM37, RM38, RM39, RM40,
- RM41, RM42, RM43, RM44, RM45, RM46, RM47, RM48, RM49, RM50,
- RM51, RM52, RM53, RM54 };
-
-/* These versions of the macros use the stack, as normal. There are debugging
-versions and production versions. Note that the "rw" argument of RMATCH isn't
-actuall used in this definition. */
-
-#ifndef NO_RECURSE
-#define REGISTER register
-
-#ifdef DEBUG
-#define RMATCH(ra,rb,rc,rd,re,rf,rg,rw) \
- { \
- printf("match() called in line %d\n", __LINE__); \
- rrc = match(ra,rb,mstart,rc,rd,re,rf,rg,rdepth+1); \
- printf("to line %d\n", __LINE__); \
- }
-#define RRETURN(ra) \
- { \
- printf("match() returned %d from line %d ", ra, __LINE__); \
- return ra; \
- }
-#else
-#define RMATCH(ra,rb,rc,rd,re,rf,rg,rw) \
- rrc = match(ra,rb,mstart,rc,rd,re,rf,rg,rdepth+1)
-#define RRETURN(ra) return ra
-#endif
-
-#else
-
-
-/* These versions of the macros manage a private stack on the heap. Note that
-the "rd" argument of RMATCH isn't actually used in this definition. It's the md
-argument of match(), which never changes. */
-
-#define REGISTER
-
-#define RMATCH(ra,rb,rc,rd,re,rf,rg,rw)\
- {\
- heapframe *newframe = (pcre_stack_malloc)(sizeof(heapframe));\
- frame->Xwhere = rw; \
- newframe->Xeptr = ra;\
- newframe->Xecode = rb;\
- newframe->Xmstart = mstart;\
- newframe->Xoffset_top = rc;\
- newframe->Xims = re;\
- newframe->Xeptrb = rf;\
- newframe->Xflags = rg;\
- newframe->Xrdepth = frame->Xrdepth + 1;\
- newframe->Xprevframe = frame;\
- frame = newframe;\
- DPRINTF(("restarting from line %d\n", __LINE__));\
- goto HEAP_RECURSE;\
- L_##rw:\
- DPRINTF(("jumped back to line %d\n", __LINE__));\
- }
-
-#define RRETURN(ra)\
- {\
- heapframe *newframe = frame;\
- frame = newframe->Xprevframe;\
- (pcre_stack_free)(newframe);\
- if (frame != NULL)\
- {\
- rrc = ra;\
- goto HEAP_RETURN;\
- }\
- return ra;\
- }
-
-
-/* Structure for remembering the local variables in a private frame */
-
-typedef struct heapframe {
- struct heapframe *Xprevframe;
-
- /* Function arguments that may change */
-
- const uschar *Xeptr;
- const uschar *Xecode;
- const uschar *Xmstart;
- int Xoffset_top;
- long int Xims;
- eptrblock *Xeptrb;
- int Xflags;
- unsigned int Xrdepth;
-
- /* Function local variables */
-
- const uschar *Xcallpat;
- const uschar *Xcharptr;
- const uschar *Xdata;
- const uschar *Xnext;
- const uschar *Xpp;
- const uschar *Xprev;
- const uschar *Xsaved_eptr;
-
- recursion_info Xnew_recursive;
-
- BOOL Xcur_is_word;
- BOOL Xcondition;
- BOOL Xprev_is_word;
-
- unsigned long int Xoriginal_ims;
-
-#ifdef SUPPORT_UCP
- int Xprop_type;
- int Xprop_value;
- int Xprop_fail_result;
- int Xprop_category;
- int Xprop_chartype;
- int Xprop_script;
- int Xoclength;
- uschar Xocchars[8];
-#endif
-
- int Xctype;
- unsigned int Xfc;
- int Xfi;
- int Xlength;
- int Xmax;
- int Xmin;
- int Xnumber;
- int Xoffset;
- int Xop;
- int Xsave_capture_last;
- int Xsave_offset1, Xsave_offset2, Xsave_offset3;
- int Xstacksave[REC_STACK_SAVE_MAX];
-
- eptrblock Xnewptrb;
-
- /* Where to jump back to */
-
- int Xwhere;
-
-} heapframe;
-
-#endif
-
-
-/***************************************************************************
-***************************************************************************/
-
-
-
-/*************************************************
-* Match from current position *
-*************************************************/
-
-/* This function is called recursively in many circumstances. Whenever it
-returns a negative (error) response, the outer incarnation must also return the
-same response.
-
-Performance note: It might be tempting to extract commonly used fields from the
-md structure (e.g. utf8, end_subject) into individual variables to improve
-performance. Tests using gcc on a SPARC disproved this; in the first case, it
-made performance worse.
-
-Arguments:
- eptr pointer to current character in subject
- ecode pointer to current position in compiled code
- mstart pointer to the current match start position (can be modified
- by encountering \K)
- offset_top current top pointer
- md pointer to "static" info for the match
- ims current /i, /m, and /s options
- eptrb pointer to chain of blocks containing eptr at start of
- brackets - for testing for empty matches
- flags can contain
- match_condassert - this is an assertion condition
- match_cbegroup - this is the start of an unlimited repeat
- group that can match an empty string
- rdepth the recursion depth
-
-Returns: MATCH_MATCH if matched ) these values are >= 0
- MATCH_NOMATCH if failed to match )
- a negative PCRE_ERROR_xxx value if aborted by an error condition
- (e.g. stopped by repeated call or recursion limit)
-*/
-
-static int
-match(REGISTER USPTR eptr, REGISTER const uschar *ecode, const uschar *mstart,
- int offset_top, match_data *md, unsigned long int ims, eptrblock *eptrb,
- int flags, unsigned int rdepth)
-{
-/* These variables do not need to be preserved over recursion in this function,
-so they can be ordinary variables in all cases. Mark some of them with
-"register" because they are used a lot in loops. */
-
-register int rrc; /* Returns from recursive calls */
-register int i; /* Used for loops not involving calls to RMATCH() */
-register unsigned int c; /* Character values not kept over RMATCH() calls */
-register BOOL utf8; /* Local copy of UTF-8 flag for speed */
-
-BOOL minimize, possessive; /* Quantifier options */
-
-/* When recursion is not being used, all "local" variables that have to be
-preserved over calls to RMATCH() are part of a "frame" which is obtained from
-heap storage. Set up the top-level frame here; others are obtained from the
-heap whenever RMATCH() does a "recursion". See the macro definitions above. */
-
-#ifdef NO_RECURSE
-heapframe *frame = (pcre_stack_malloc)(sizeof(heapframe));
-frame->Xprevframe = NULL; /* Marks the top level */
-
-/* Copy in the original argument variables */
-
-frame->Xeptr = eptr;
-frame->Xecode = ecode;
-frame->Xmstart = mstart;
-frame->Xoffset_top = offset_top;
-frame->Xims = ims;
-frame->Xeptrb = eptrb;
-frame->Xflags = flags;
-frame->Xrdepth = rdepth;
-
-/* This is where control jumps back to to effect "recursion" */
-
-HEAP_RECURSE:
-
-/* Macros make the argument variables come from the current frame */
-
-#define eptr frame->Xeptr
-#define ecode frame->Xecode
-#define mstart frame->Xmstart
-#define offset_top frame->Xoffset_top
-#define ims frame->Xims
-#define eptrb frame->Xeptrb
-#define flags frame->Xflags
-#define rdepth frame->Xrdepth
-
-/* Ditto for the local variables */
-
-#ifdef SUPPORT_UTF8
-#define charptr frame->Xcharptr
-#endif
-#define callpat frame->Xcallpat
-#define data frame->Xdata
-#define next frame->Xnext
-#define pp frame->Xpp
-#define prev frame->Xprev
-#define saved_eptr frame->Xsaved_eptr
-
-#define new_recursive frame->Xnew_recursive
-
-#define cur_is_word frame->Xcur_is_word
-#define condition frame->Xcondition
-#define prev_is_word frame->Xprev_is_word
-
-#define original_ims frame->Xoriginal_ims
-
-#ifdef SUPPORT_UCP
-#define prop_type frame->Xprop_type
-#define prop_value frame->Xprop_value
-#define prop_fail_result frame->Xprop_fail_result
-#define prop_category frame->Xprop_category
-#define prop_chartype frame->Xprop_chartype
-#define prop_script frame->Xprop_script
-#define oclength frame->Xoclength
-#define occhars frame->Xocchars
-#endif
-
-#define ctype frame->Xctype
-#define fc frame->Xfc
-#define fi frame->Xfi
-#define length frame->Xlength
-#define max frame->Xmax
-#define min frame->Xmin
-#define number frame->Xnumber
-#define offset frame->Xoffset
-#define op frame->Xop
-#define save_capture_last frame->Xsave_capture_last
-#define save_offset1 frame->Xsave_offset1
-#define save_offset2 frame->Xsave_offset2
-#define save_offset3 frame->Xsave_offset3
-#define stacksave frame->Xstacksave
-
-#define newptrb frame->Xnewptrb
-
-/* When recursion is being used, local variables are allocated on the stack and
-get preserved during recursion in the normal way. In this environment, fi and
-i, and fc and c, can be the same variables. */
-
-#else /* NO_RECURSE not defined */
-#define fi i
-#define fc c
-
-
-#ifdef SUPPORT_UTF8 /* Many of these variables are used only */
-const uschar *charptr; /* in small blocks of the code. My normal */
-#endif /* style of coding would have declared */
-const uschar *callpat; /* them within each of those blocks. */
-const uschar *data; /* However, in order to accommodate the */
-const uschar *next; /* version of this code that uses an */
-USPTR pp; /* external "stack" implemented on the */
-const uschar *prev; /* heap, it is easier to declare them all */
-USPTR saved_eptr; /* here, so the declarations can be cut */
- /* out in a block. The only declarations */
-recursion_info new_recursive; /* within blocks below are for variables */
- /* that do not have to be preserved over */
-BOOL cur_is_word; /* a recursive call to RMATCH(). */
-BOOL condition;
-BOOL prev_is_word;
-
-unsigned long int original_ims;
-
-#ifdef SUPPORT_UCP
-int prop_type;
-int prop_value;
-int prop_fail_result;
-int prop_category;
-int prop_chartype;
-int prop_script;
-int oclength;
-uschar occhars[8];
-#endif
-
-int ctype;
-int length;
-int max;
-int min;
-int number;
-int offset;
-int op;
-int save_capture_last;
-int save_offset1, save_offset2, save_offset3;
-int stacksave[REC_STACK_SAVE_MAX];
-
-eptrblock newptrb;
-#endif /* NO_RECURSE */
-
-/* These statements are here to stop the compiler complaining about unitialized
-variables. */
-
-#ifdef SUPPORT_UCP
-prop_value = 0;
-prop_fail_result = 0;
-#endif
-
-
-/* This label is used for tail recursion, which is used in a few cases even
-when NO_RECURSE is not defined, in order to reduce the amount of stack that is
-used. Thanks to Ian Taylor for noticing this possibility and sending the
-original patch. */
-
-TAIL_RECURSE:
-
-/* OK, now we can get on with the real code of the function. Recursive calls
-are specified by the macro RMATCH and RRETURN is used to return. When
-NO_RECURSE is *not* defined, these just turn into a recursive call to match()
-and a "return", respectively (possibly with some debugging if DEBUG is
-defined). However, RMATCH isn't like a function call because it's quite a
-complicated macro. It has to be used in one particular way. This shouldn't,
-however, impact performance when true recursion is being used. */
-
-#ifdef SUPPORT_UTF8
-utf8 = md->utf8; /* Local copy of the flag */
-#else
-utf8 = FALSE;
-#endif
-
-/* First check that we haven't called match() too many times, or that we
-haven't exceeded the recursive call limit. */
-
-if (md->match_call_count++ >= md->match_limit) RRETURN(PCRE_ERROR_MATCHLIMIT);
-if (rdepth >= md->match_limit_recursion) RRETURN(PCRE_ERROR_RECURSIONLIMIT);
-
-original_ims = ims; /* Save for resetting on ')' */
-
-/* At the start of a group with an unlimited repeat that may match an empty
-string, the match_cbegroup flag is set. When this is the case, add the current
-subject pointer to the chain of such remembered pointers, to be checked when we
-hit the closing ket, in order to break infinite loops that match no characters.
-When match() is called in other circumstances, don't add to the chain. The
-match_cbegroup flag must NOT be used with tail recursion, because the memory
-block that is used is on the stack, so a new one may be required for each
-match(). */
-
-if ((flags & match_cbegroup) != 0)
- {
- newptrb.epb_saved_eptr = eptr;
- newptrb.epb_prev = eptrb;
- eptrb = &newptrb;
- }
-
-/* Now start processing the opcodes. */
-
-for (;;)
- {
- minimize = possessive = FALSE;
- op = *ecode;
-
- /* For partial matching, remember if we ever hit the end of the subject after
- matching at least one subject character. */
-
- if (md->partial &&
- eptr >= md->end_subject &&
- eptr > mstart)
- md->hitend = TRUE;
-
- switch(op)
- {
- case OP_FAIL:
- RRETURN(MATCH_NOMATCH);
-
- case OP_PRUNE:
- RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,
- ims, eptrb, flags, RM51);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- RRETURN(MATCH_PRUNE);
-
- case OP_COMMIT:
- RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,
- ims, eptrb, flags, RM52);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- RRETURN(MATCH_COMMIT);
-
- case OP_SKIP:
- RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,
- ims, eptrb, flags, RM53);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- md->start_match_ptr = eptr; /* Pass back current position */
- RRETURN(MATCH_SKIP);
-
- case OP_THEN:
- RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,
- ims, eptrb, flags, RM54);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- RRETURN(MATCH_THEN);
-
- /* Handle a capturing bracket. If there is space in the offset vector, save
- the current subject position in the working slot at the top of the vector.
- We mustn't change the current values of the data slot, because they may be
- set from a previous iteration of this group, and be referred to by a
- reference inside the group.
-
- If the bracket fails to match, we need to restore this value and also the
- values of the final offsets, in case they were set by a previous iteration
- of the same bracket.
-
- If there isn't enough space in the offset vector, treat this as if it were
- a non-capturing bracket. Don't worry about setting the flag for the error
- case here; that is handled in the code for KET. */
-
- case OP_CBRA:
- case OP_SCBRA:
- number = GET2(ecode, 1+LINK_SIZE);
- offset = number << 1;
-
-#ifdef DEBUG
- printf("start bracket %d\n", number);
- printf("subject=");
- pchars(eptr, 16, TRUE, md);
- printf("\n");
-#endif
-
- if (offset < md->offset_max)
- {
- save_offset1 = md->offset_vector[offset];
- save_offset2 = md->offset_vector[offset+1];
- save_offset3 = md->offset_vector[md->offset_end - number];
- save_capture_last = md->capture_last;
-
- DPRINTF(("saving %d %d %d\n", save_offset1, save_offset2, save_offset3));
- md->offset_vector[md->offset_end - number] = eptr - md->start_subject;
-
- flags = (op == OP_SCBRA)? match_cbegroup : 0;
- do
- {
- RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,
- ims, eptrb, flags, RM1);
- if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
- md->capture_last = save_capture_last;
- ecode += GET(ecode, 1);
- }
- while (*ecode == OP_ALT);
-
- DPRINTF(("bracket %d failed\n", number));
-
- md->offset_vector[offset] = save_offset1;
- md->offset_vector[offset+1] = save_offset2;
- md->offset_vector[md->offset_end - number] = save_offset3;
-
- RRETURN(MATCH_NOMATCH);
- }
-
- /* FALL THROUGH ... Insufficient room for saving captured contents. Treat
- as a non-capturing bracket. */
-
- /* VVVVVVVVVVVVVVVVVVVVVVVVV */
- /* VVVVVVVVVVVVVVVVVVVVVVVVV */
-
- DPRINTF(("insufficient capture room: treat as non-capturing\n"));
-
- /* VVVVVVVVVVVVVVVVVVVVVVVVV */
- /* VVVVVVVVVVVVVVVVVVVVVVVVV */
-
- /* Non-capturing bracket. Loop for all the alternatives. When we get to the
- final alternative within the brackets, we would return the result of a
- recursive call to match() whatever happened. We can reduce stack usage by
- turning this into a tail recursion, except in the case when match_cbegroup
- is set.*/
-
- case OP_BRA:
- case OP_SBRA:
- DPRINTF(("start non-capturing bracket\n"));
- flags = (op >= OP_SBRA)? match_cbegroup : 0;
- for (;;)
- {
- if (ecode[GET(ecode, 1)] != OP_ALT) /* Final alternative */
- {
- if (flags == 0) /* Not a possibly empty group */
- {
- ecode += _pcre_OP_lengths[*ecode];
- DPRINTF(("bracket 0 tail recursion\n"));
- goto TAIL_RECURSE;
- }
-
- /* Possibly empty group; can't use tail recursion. */
-
- RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md, ims,
- eptrb, flags, RM48);
- RRETURN(rrc);
- }
-
- /* For non-final alternatives, continue the loop for a NOMATCH result;
- otherwise return. */
-
- RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md, ims,
- eptrb, flags, RM2);
- if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
- ecode += GET(ecode, 1);
- }
- /* Control never reaches here. */
-
- /* Conditional group: compilation checked that there are no more than
- two branches. If the condition is false, skipping the first branch takes us
- past the end if there is only one branch, but that's OK because that is
- exactly what going to the ket would do. As there is only one branch to be
- obeyed, we can use tail recursion to avoid using another stack frame. */
-
- case OP_COND:
- case OP_SCOND:
- if (ecode[LINK_SIZE+1] == OP_RREF) /* Recursion test */
- {
- offset = GET2(ecode, LINK_SIZE + 2); /* Recursion group number*/
- condition = md->recursive != NULL &&
- (offset == RREF_ANY || offset == md->recursive->group_num);
- ecode += condition? 3 : GET(ecode, 1);
- }
-
- else if (ecode[LINK_SIZE+1] == OP_CREF) /* Group used test */
- {
- offset = GET2(ecode, LINK_SIZE+2) << 1; /* Doubled ref number */
- condition = offset < offset_top && md->offset_vector[offset] >= 0;
- ecode += condition? 3 : GET(ecode, 1);
- }
-
- else if (ecode[LINK_SIZE+1] == OP_DEF) /* DEFINE - always false */
- {
- condition = FALSE;
- ecode += GET(ecode, 1);
- }
-
- /* The condition is an assertion. Call match() to evaluate it - setting
- the final argument match_condassert causes it to stop at the end of an
- assertion. */
-
- else
- {
- RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, NULL,
- match_condassert, RM3);
- if (rrc == MATCH_MATCH)
- {
- condition = TRUE;
- ecode += 1 + LINK_SIZE + GET(ecode, LINK_SIZE + 2);
- while (*ecode == OP_ALT) ecode += GET(ecode, 1);
- }
- else if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN)
- {
- RRETURN(rrc); /* Need braces because of following else */
- }
- else
- {
- condition = FALSE;
- ecode += GET(ecode, 1);
- }
- }
-
- /* We are now at the branch that is to be obeyed. As there is only one,
- we can use tail recursion to avoid using another stack frame, except when
- match_cbegroup is required for an unlimited repeat of a possibly empty
- group. If the second alternative doesn't exist, we can just plough on. */
-
- if (condition || *ecode == OP_ALT)
- {
- ecode += 1 + LINK_SIZE;
- if (op == OP_SCOND) /* Possibly empty group */
- {
- RMATCH(eptr, ecode, offset_top, md, ims, eptrb, match_cbegroup, RM49);
- RRETURN(rrc);
- }
- else /* Group must match something */
- {
- flags = 0;
- goto TAIL_RECURSE;
- }
- }
- else /* Condition false & no 2nd alternative */
- {
- ecode += 1 + LINK_SIZE;
- }
- break;
-
-
- /* End of the pattern, either real or forced. If we are in a top-level
- recursion, we should restore the offsets appropriately and continue from
- after the call. */
-
- case OP_ACCEPT:
- case OP_END:
- if (md->recursive != NULL && md->recursive->group_num == 0)
- {
- recursion_info *rec = md->recursive;
- DPRINTF(("End of pattern in a (?0) recursion\n"));
- md->recursive = rec->prevrec;
- memmove(md->offset_vector, rec->offset_save,
- rec->saved_max * sizeof(int));
- mstart = rec->save_start;
- ims = original_ims;
- ecode = rec->after_call;
- break;
- }
-
- /* Otherwise, if PCRE_NOTEMPTY is set, fail if we have matched an empty
- string - backtracking will then try other alternatives, if any. */
-
- if (md->notempty && eptr == mstart) RRETURN(MATCH_NOMATCH);
- md->end_match_ptr = eptr; /* Record where we ended */
- md->end_offset_top = offset_top; /* and how many extracts were taken */
- md->start_match_ptr = mstart; /* and the start (\K can modify) */
- RRETURN(MATCH_MATCH);
-
- /* Change option settings */
-
- case OP_OPT:
- ims = ecode[1];
- ecode += 2;
- DPRINTF(("ims set to %02lx\n", ims));
- break;
-
- /* Assertion brackets. Check the alternative branches in turn - the
- matching won't pass the KET for an assertion. If any one branch matches,
- the assertion is true. Lookbehind assertions have an OP_REVERSE item at the
- start of each branch to move the current point backwards, so the code at
- this level is identical to the lookahead case. */
-
- case OP_ASSERT:
- case OP_ASSERTBACK:
- do
- {
- RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, NULL, 0,
- RM4);
- if (rrc == MATCH_MATCH) break;
- if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
- ecode += GET(ecode, 1);
- }
- while (*ecode == OP_ALT);
- if (*ecode == OP_KET) RRETURN(MATCH_NOMATCH);
-
- /* If checking an assertion for a condition, return MATCH_MATCH. */
-
- if ((flags & match_condassert) != 0) RRETURN(MATCH_MATCH);
-
- /* Continue from after the assertion, updating the offsets high water
- mark, since extracts may have been taken during the assertion. */
-
- do ecode += GET(ecode,1); while (*ecode == OP_ALT);
- ecode += 1 + LINK_SIZE;
- offset_top = md->end_offset_top;
- continue;
-
- /* Negative assertion: all branches must fail to match */
-
- case OP_ASSERT_NOT:
- case OP_ASSERTBACK_NOT:
- do
- {
- RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, NULL, 0,
- RM5);
- if (rrc == MATCH_MATCH) RRETURN(MATCH_NOMATCH);
- if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
- ecode += GET(ecode,1);
- }
- while (*ecode == OP_ALT);
-
- if ((flags & match_condassert) != 0) RRETURN(MATCH_MATCH);
-
- ecode += 1 + LINK_SIZE;
- continue;
-
- /* Move the subject pointer back. This occurs only at the start of
- each branch of a lookbehind assertion. If we are too close to the start to
- move back, this match function fails. When working with UTF-8 we move
- back a number of characters, not bytes. */
-
- case OP_REVERSE:
-#ifdef SUPPORT_UTF8
- if (utf8)
- {
- i = GET(ecode, 1);
- while (i-- > 0)
- {
- eptr--;
- if (eptr < md->start_subject) RRETURN(MATCH_NOMATCH);
- BACKCHAR(eptr);
- }
- }
- else
-#endif
-
- /* No UTF-8 support, or not in UTF-8 mode: count is byte count */
-
- {
- eptr -= GET(ecode, 1);
- if (eptr < md->start_subject) RRETURN(MATCH_NOMATCH);
- }
-
- /* Skip to next op code */
-
- ecode += 1 + LINK_SIZE;
- break;
-
- /* The callout item calls an external function, if one is provided, passing
- details of the match so far. This is mainly for debugging, though the
- function is able to force a failure. */
-
- case OP_CALLOUT:
- if (pcre_callout != NULL)
- {
- pcre_callout_block cb;
- cb.version = 1; /* Version 1 of the callout block */
- cb.callout_number = ecode[1];
- cb.offset_vector = md->offset_vector;
- cb.subject = (PCRE_SPTR)md->start_subject;
- cb.subject_length = md->end_subject - md->start_subject;
- cb.start_match = mstart - md->start_subject;
- cb.current_position = eptr - md->start_subject;
- cb.pattern_position = GET(ecode, 2);
- cb.next_item_length = GET(ecode, 2 + LINK_SIZE);
- cb.capture_top = offset_top/2;
- cb.capture_last = md->capture_last;
- cb.callout_data = md->callout_data;
- if ((rrc = (*pcre_callout)(&cb)) > 0) RRETURN(MATCH_NOMATCH);
- if (rrc < 0) RRETURN(rrc);
- }
- ecode += 2 + 2*LINK_SIZE;
- break;
-
- /* Recursion either matches the current regex, or some subexpression. The
- offset data is the offset to the starting bracket from the start of the
- whole pattern. (This is so that it works from duplicated subpatterns.)
-
- If there are any capturing brackets started but not finished, we have to
- save their starting points and reinstate them after the recursion. However,
- we don't know how many such there are (offset_top records the completed
- total) so we just have to save all the potential data. There may be up to
- 65535 such values, which is too large to put on the stack, but using malloc
- for small numbers seems expensive. As a compromise, the stack is used when
- there are no more than REC_STACK_SAVE_MAX values to store; otherwise malloc
- is used. A problem is what to do if the malloc fails ... there is no way of
- returning to the top level with an error. Save the top REC_STACK_SAVE_MAX
- values on the stack, and accept that the rest may be wrong.
-
- There are also other values that have to be saved. We use a chained
- sequence of blocks that actually live on the stack. Thanks to Robin Houston
- for the original version of this logic. */
-
- case OP_RECURSE:
- {
- callpat = md->start_code + GET(ecode, 1);
- new_recursive.group_num = (callpat == md->start_code)? 0 :
- GET2(callpat, 1 + LINK_SIZE);
-
- /* Add to "recursing stack" */
-
- new_recursive.prevrec = md->recursive;
- md->recursive = &new_recursive;
-
- /* Find where to continue from afterwards */
-
- ecode += 1 + LINK_SIZE;
- new_recursive.after_call = ecode;
-
- /* Now save the offset data. */
-
- new_recursive.saved_max = md->offset_end;
- if (new_recursive.saved_max <= REC_STACK_SAVE_MAX)
- new_recursive.offset_save = stacksave;
- else
- {
- new_recursive.offset_save =
- (int *)(pcre_malloc)(new_recursive.saved_max * sizeof(int));
- if (new_recursive.offset_save == NULL) RRETURN(PCRE_ERROR_NOMEMORY);
- }
-
- memcpy(new_recursive.offset_save, md->offset_vector,
- new_recursive.saved_max * sizeof(int));
- new_recursive.save_start = mstart;
- mstart = eptr;
-
- /* OK, now we can do the recursion. For each top-level alternative we
- restore the offset and recursion data. */
-
- DPRINTF(("Recursing into group %d\n", new_recursive.group_num));
- flags = (*callpat >= OP_SBRA)? match_cbegroup : 0;
- do
- {
- RMATCH(eptr, callpat + _pcre_OP_lengths[*callpat], offset_top,
- md, ims, eptrb, flags, RM6);
- if (rrc == MATCH_MATCH)
- {
- DPRINTF(("Recursion matched\n"));
- md->recursive = new_recursive.prevrec;
- if (new_recursive.offset_save != stacksave)
- (pcre_free)(new_recursive.offset_save);
- RRETURN(MATCH_MATCH);
- }
- else if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN)
- {
- DPRINTF(("Recursion gave error %d\n", rrc));
- RRETURN(rrc);
- }
-
- md->recursive = &new_recursive;
- memcpy(md->offset_vector, new_recursive.offset_save,
- new_recursive.saved_max * sizeof(int));
- callpat += GET(callpat, 1);
- }
- while (*callpat == OP_ALT);
-
- DPRINTF(("Recursion didn't match\n"));
- md->recursive = new_recursive.prevrec;
- if (new_recursive.offset_save != stacksave)
- (pcre_free)(new_recursive.offset_save);
- RRETURN(MATCH_NOMATCH);
- }
- /* Control never reaches here */
-
- /* "Once" brackets are like assertion brackets except that after a match,
- the point in the subject string is not moved back. Thus there can never be
- a move back into the brackets. Friedl calls these "atomic" subpatterns.
- Check the alternative branches in turn - the matching won't pass the KET
- for this kind of subpattern. If any one branch matches, we carry on as at
- the end of a normal bracket, leaving the subject pointer. */
-
- case OP_ONCE:
- prev = ecode;
- saved_eptr = eptr;
-
- do
- {
- RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, eptrb, 0, RM7);
- if (rrc == MATCH_MATCH) break;
- if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
- ecode += GET(ecode,1);
- }
- while (*ecode == OP_ALT);
-
- /* If hit the end of the group (which could be repeated), fail */
-
- if (*ecode != OP_ONCE && *ecode != OP_ALT) RRETURN(MATCH_NOMATCH);
-
- /* Continue as from after the assertion, updating the offsets high water
- mark, since extracts may have been taken. */
-
- do ecode += GET(ecode, 1); while (*ecode == OP_ALT);
-
- offset_top = md->end_offset_top;
- eptr = md->end_match_ptr;
-
- /* For a non-repeating ket, just continue at this level. This also
- happens for a repeating ket if no characters were matched in the group.
- This is the forcible breaking of infinite loops as implemented in Perl
- 5.005. If there is an options reset, it will get obeyed in the normal
- course of events. */
-
- if (*ecode == OP_KET || eptr == saved_eptr)
- {
- ecode += 1+LINK_SIZE;
- break;
- }
-
- /* The repeating kets try the rest of the pattern or restart from the
- preceding bracket, in the appropriate order. The second "call" of match()
- uses tail recursion, to avoid using another stack frame. We need to reset
- any options that changed within the bracket before re-running it, so
- check the next opcode. */
-
- if (ecode[1+LINK_SIZE] == OP_OPT)
- {
- ims = (ims & ~PCRE_IMS) | ecode[4];
- DPRINTF(("ims set to %02lx at group repeat\n", ims));
- }
-
- if (*ecode == OP_KETRMIN)
- {
- RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, eptrb, 0, RM8);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- ecode = prev;
- flags = 0;
- goto TAIL_RECURSE;
- }
- else /* OP_KETRMAX */
- {
- RMATCH(eptr, prev, offset_top, md, ims, eptrb, match_cbegroup, RM9);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- ecode += 1 + LINK_SIZE;
- flags = 0;
- goto TAIL_RECURSE;
- }
- /* Control never gets here */
-
- /* An alternation is the end of a branch; scan along to find the end of the
- bracketed group and go to there. */
-
- case OP_ALT:
- do ecode += GET(ecode,1); while (*ecode == OP_ALT);
- break;
-
- /* BRAZERO, BRAMINZERO and SKIPZERO occur just before a bracket group,
- indicating that it may occur zero times. It may repeat infinitely, or not
- at all - i.e. it could be ()* or ()? or even (){0} in the pattern. Brackets
- with fixed upper repeat limits are compiled as a number of copies, with the
- optional ones preceded by BRAZERO or BRAMINZERO. */
-
- case OP_BRAZERO:
- {
- next = ecode+1;
- RMATCH(eptr, next, offset_top, md, ims, eptrb, 0, RM10);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- do next += GET(next,1); while (*next == OP_ALT);
- ecode = next + 1 + LINK_SIZE;
- }
- break;
-
- case OP_BRAMINZERO:
- {
- next = ecode+1;
- do next += GET(next, 1); while (*next == OP_ALT);
- RMATCH(eptr, next + 1+LINK_SIZE, offset_top, md, ims, eptrb, 0, RM11);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- ecode++;
- }
- break;
-
- case OP_SKIPZERO:
- {
- next = ecode+1;
- do next += GET(next,1); while (*next == OP_ALT);
- ecode = next + 1 + LINK_SIZE;
- }
- break;
-
- /* End of a group, repeated or non-repeating. */
-
- case OP_KET:
- case OP_KETRMIN:
- case OP_KETRMAX:
- prev = ecode - GET(ecode, 1);
-
- /* If this was a group that remembered the subject start, in order to break
- infinite repeats of empty string matches, retrieve the subject start from
- the chain. Otherwise, set it NULL. */
-
- if (*prev >= OP_SBRA)
- {
- saved_eptr = eptrb->epb_saved_eptr; /* Value at start of group */
- eptrb = eptrb->epb_prev; /* Backup to previous group */
- }
- else saved_eptr = NULL;
-
- /* If we are at the end of an assertion group, stop matching and return
- MATCH_MATCH, but record the current high water mark for use by positive
- assertions. Do this also for the "once" (atomic) groups. */
-
- if (*prev == OP_ASSERT || *prev == OP_ASSERT_NOT ||
- *prev == OP_ASSERTBACK || *prev == OP_ASSERTBACK_NOT ||
- *prev == OP_ONCE)
- {
- md->end_match_ptr = eptr; /* For ONCE */
- md->end_offset_top = offset_top;
- RRETURN(MATCH_MATCH);
- }
-
- /* For capturing groups we have to check the group number back at the start
- and if necessary complete handling an extraction by setting the offsets and
- bumping the high water mark. Note that whole-pattern recursion is coded as
- a recurse into group 0, so it won't be picked up here. Instead, we catch it
- when the OP_END is reached. Other recursion is handled here. */
-
- if (*prev == OP_CBRA || *prev == OP_SCBRA)
- {
- number = GET2(prev, 1+LINK_SIZE);
- offset = number << 1;
-
-#ifdef DEBUG
- printf("end bracket %d", number);
- printf("\n");
-#endif
-
- md->capture_last = number;
- if (offset >= md->offset_max) md->offset_overflow = TRUE; else
- {
- md->offset_vector[offset] =
- md->offset_vector[md->offset_end - number];
- md->offset_vector[offset+1] = eptr - md->start_subject;
- if (offset_top <= offset) offset_top = offset + 2;
- }
-
- /* Handle a recursively called group. Restore the offsets
- appropriately and continue from after the call. */
-
- if (md->recursive != NULL && md->recursive->group_num == number)
- {
- recursion_info *rec = md->recursive;
- DPRINTF(("Recursion (%d) succeeded - continuing\n", number));
- md->recursive = rec->prevrec;
- mstart = rec->save_start;
- memcpy(md->offset_vector, rec->offset_save,
- rec->saved_max * sizeof(int));
- ecode = rec->after_call;
- ims = original_ims;
- break;
- }
- }
-
- /* For both capturing and non-capturing groups, reset the value of the ims
- flags, in case they got changed during the group. */
-
- ims = original_ims;
- DPRINTF(("ims reset to %02lx\n", ims));
-
- /* For a non-repeating ket, just continue at this level. This also
- happens for a repeating ket if no characters were matched in the group.
- This is the forcible breaking of infinite loops as implemented in Perl
- 5.005. If there is an options reset, it will get obeyed in the normal
- course of events. */
-
- if (*ecode == OP_KET || eptr == saved_eptr)
- {
- ecode += 1 + LINK_SIZE;
- break;
- }
-
- /* The repeating kets try the rest of the pattern or restart from the
- preceding bracket, in the appropriate order. In the second case, we can use
- tail recursion to avoid using another stack frame, unless we have an
- unlimited repeat of a group that can match an empty string. */
-
- flags = (*prev >= OP_SBRA)? match_cbegroup : 0;
-
- if (*ecode == OP_KETRMIN)
- {
- RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, eptrb, 0, RM12);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (flags != 0) /* Could match an empty string */
- {
- RMATCH(eptr, prev, offset_top, md, ims, eptrb, flags, RM50);
- RRETURN(rrc);
- }
- ecode = prev;
- goto TAIL_RECURSE;
- }
- else /* OP_KETRMAX */
- {
- RMATCH(eptr, prev, offset_top, md, ims, eptrb, flags, RM13);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- ecode += 1 + LINK_SIZE;
- flags = 0;
- goto TAIL_RECURSE;
- }
- /* Control never gets here */
-
- /* Start of subject unless notbol, or after internal newline if multiline */
-
- case OP_CIRC:
- if (md->notbol && eptr == md->start_subject) RRETURN(MATCH_NOMATCH);
- if ((ims & PCRE_MULTILINE) != 0)
- {
- if (eptr != md->start_subject &&
- (eptr == md->end_subject || !WAS_NEWLINE(eptr)))
- RRETURN(MATCH_NOMATCH);
- ecode++;
- break;
- }
- /* ... else fall through */
-
- /* Start of subject assertion */
-
- case OP_SOD:
- if (eptr != md->start_subject) RRETURN(MATCH_NOMATCH);
- ecode++;
- break;
-
- /* Start of match assertion */
-
- case OP_SOM:
- if (eptr != md->start_subject + md->start_offset) RRETURN(MATCH_NOMATCH);
- ecode++;
- break;
-
- /* Reset the start of match point */
-
- case OP_SET_SOM:
- mstart = eptr;
- ecode++;
- break;
-
- /* Assert before internal newline if multiline, or before a terminating
- newline unless endonly is set, else end of subject unless noteol is set. */
-
- case OP_DOLL:
- if ((ims & PCRE_MULTILINE) != 0)
- {
- if (eptr < md->end_subject)
- { if (!IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH); }
- else
- { if (md->noteol) RRETURN(MATCH_NOMATCH); }
- ecode++;
- break;
- }
- else
- {
- if (md->noteol) RRETURN(MATCH_NOMATCH);
- if (!md->endonly)
- {
- if (eptr != md->end_subject &&
- (!IS_NEWLINE(eptr) || eptr != md->end_subject - md->nllen))
- RRETURN(MATCH_NOMATCH);
- ecode++;
- break;
- }
- }
- /* ... else fall through for endonly */
-
- /* End of subject assertion (\z) */
-
- case OP_EOD:
- if (eptr < md->end_subject) RRETURN(MATCH_NOMATCH);
- ecode++;
- break;
-
- /* End of subject or ending \n assertion (\Z) */
-
- case OP_EODN:
- if (eptr != md->end_subject &&
- (!IS_NEWLINE(eptr) || eptr != md->end_subject - md->nllen))
- RRETURN(MATCH_NOMATCH);
- ecode++;
- break;
-
- /* Word boundary assertions */
-
- case OP_NOT_WORD_BOUNDARY:
- case OP_WORD_BOUNDARY:
- {
-
- /* Find out if the previous and current characters are "word" characters.
- It takes a bit more work in UTF-8 mode. Characters > 255 are assumed to
- be "non-word" characters. */
-
-#ifdef SUPPORT_UTF8
- if (utf8)
- {
- if (eptr == md->start_subject) prev_is_word = FALSE; else
- {
- const uschar *lastptr = eptr - 1;
- while((*lastptr & 0xc0) == 0x80) lastptr--;
- GETCHAR(c, lastptr);
- prev_is_word = c < 256 && (md->ctypes[c] & ctype_word) != 0;
- }
- if (eptr >= md->end_subject) cur_is_word = FALSE; else
- {
- GETCHAR(c, eptr);
- cur_is_word = c < 256 && (md->ctypes[c] & ctype_word) != 0;
- }
- }
- else
-#endif
-
- /* More streamlined when not in UTF-8 mode */
-
- {
- prev_is_word = (eptr != md->start_subject) &&
- ((md->ctypes[eptr[-1]] & ctype_word) != 0);
- cur_is_word = (eptr < md->end_subject) &&
- ((md->ctypes[*eptr] & ctype_word) != 0);
- }
-
- /* Now see if the situation is what we want */
-
- if ((*ecode++ == OP_WORD_BOUNDARY)?
- cur_is_word == prev_is_word : cur_is_word != prev_is_word)
- RRETURN(MATCH_NOMATCH);
- }
- break;
-
- /* Match a single character type; inline for speed */
-
- case OP_ANY:
- if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);
- /* Fall through */
-
- case OP_ALLANY:
- if (eptr++ >= md->end_subject) RRETURN(MATCH_NOMATCH);
- if (utf8) while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;
- ecode++;
- break;
-
- /* Match a single byte, even in UTF-8 mode. This opcode really does match
- any byte, even newline, independent of the setting of PCRE_DOTALL. */
-
- case OP_ANYBYTE:
- if (eptr++ >= md->end_subject) RRETURN(MATCH_NOMATCH);
- ecode++;
- break;
-
- case OP_NOT_DIGIT:
- if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
- GETCHARINCTEST(c, eptr);
- if (
-#ifdef SUPPORT_UTF8
- c < 256 &&
-#endif
- (md->ctypes[c] & ctype_digit) != 0
- )
- RRETURN(MATCH_NOMATCH);
- ecode++;
- break;
-
- case OP_DIGIT:
- if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
- GETCHARINCTEST(c, eptr);
- if (
-#ifdef SUPPORT_UTF8
- c >= 256 ||
-#endif
- (md->ctypes[c] & ctype_digit) == 0
- )
- RRETURN(MATCH_NOMATCH);
- ecode++;
- break;
-
- case OP_NOT_WHITESPACE:
- if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
- GETCHARINCTEST(c, eptr);
- if (
-#ifdef SUPPORT_UTF8
- c < 256 &&
-#endif
- (md->ctypes[c] & ctype_space) != 0
- )
- RRETURN(MATCH_NOMATCH);
- ecode++;
- break;
-
- case OP_WHITESPACE:
- if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
- GETCHARINCTEST(c, eptr);
- if (
-#ifdef SUPPORT_UTF8
- c >= 256 ||
-#endif
- (md->ctypes[c] & ctype_space) == 0
- )
- RRETURN(MATCH_NOMATCH);
- ecode++;
- break;
-
- case OP_NOT_WORDCHAR:
- if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
- GETCHARINCTEST(c, eptr);
- if (
-#ifdef SUPPORT_UTF8
- c < 256 &&
-#endif
- (md->ctypes[c] & ctype_word) != 0
- )
- RRETURN(MATCH_NOMATCH);
- ecode++;
- break;
-
- case OP_WORDCHAR:
- if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
- GETCHARINCTEST(c, eptr);
- if (
-#ifdef SUPPORT_UTF8
- c >= 256 ||
-#endif
- (md->ctypes[c] & ctype_word) == 0
- )
- RRETURN(MATCH_NOMATCH);
- ecode++;
- break;
-
- case OP_ANYNL:
- if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
- GETCHARINCTEST(c, eptr);
- switch(c)
- {
- default: RRETURN(MATCH_NOMATCH);
- case 0x000d:
- if (eptr < md->end_subject && *eptr == 0x0a) eptr++;
- break;
-
- case 0x000a:
- break;
-
- case 0x000b:
- case 0x000c:
- case 0x0085:
- case 0x2028:
- case 0x2029:
- if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
- break;
- }
- ecode++;
- break;
-
- case OP_NOT_HSPACE:
- if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
- GETCHARINCTEST(c, eptr);
- switch(c)
- {
- default: break;
- case 0x09: /* HT */
- case 0x20: /* SPACE */
- case 0xa0: /* NBSP */
- case 0x1680: /* OGHAM SPACE MARK */
- case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */
- case 0x2000: /* EN QUAD */
- case 0x2001: /* EM QUAD */
- case 0x2002: /* EN SPACE */
- case 0x2003: /* EM SPACE */
- case 0x2004: /* THREE-PER-EM SPACE */
- case 0x2005: /* FOUR-PER-EM SPACE */
- case 0x2006: /* SIX-PER-EM SPACE */
- case 0x2007: /* FIGURE SPACE */
- case 0x2008: /* PUNCTUATION SPACE */
- case 0x2009: /* THIN SPACE */
- case 0x200A: /* HAIR SPACE */
- case 0x202f: /* NARROW NO-BREAK SPACE */
- case 0x205f: /* MEDIUM MATHEMATICAL SPACE */
- case 0x3000: /* IDEOGRAPHIC SPACE */
- RRETURN(MATCH_NOMATCH);
- }
- ecode++;
- break;
-
- case OP_HSPACE:
- if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
- GETCHARINCTEST(c, eptr);
- switch(c)
- {
- default: RRETURN(MATCH_NOMATCH);
- case 0x09: /* HT */
- case 0x20: /* SPACE */
- case 0xa0: /* NBSP */
- case 0x1680: /* OGHAM SPACE MARK */
- case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */
- case 0x2000: /* EN QUAD */
- case 0x2001: /* EM QUAD */
- case 0x2002: /* EN SPACE */
- case 0x2003: /* EM SPACE */
- case 0x2004: /* THREE-PER-EM SPACE */
- case 0x2005: /* FOUR-PER-EM SPACE */
- case 0x2006: /* SIX-PER-EM SPACE */
- case 0x2007: /* FIGURE SPACE */
- case 0x2008: /* PUNCTUATION SPACE */
- case 0x2009: /* THIN SPACE */
- case 0x200A: /* HAIR SPACE */
- case 0x202f: /* NARROW NO-BREAK SPACE */
- case 0x205f: /* MEDIUM MATHEMATICAL SPACE */
- case 0x3000: /* IDEOGRAPHIC SPACE */
- break;
- }
- ecode++;
- break;
-
- case OP_NOT_VSPACE:
- if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
- GETCHARINCTEST(c, eptr);
- switch(c)
- {
- default: break;
- case 0x0a: /* LF */
- case 0x0b: /* VT */
- case 0x0c: /* FF */
- case 0x0d: /* CR */
- case 0x85: /* NEL */
- case 0x2028: /* LINE SEPARATOR */
- case 0x2029: /* PARAGRAPH SEPARATOR */
- RRETURN(MATCH_NOMATCH);
- }
- ecode++;
- break;
-
- case OP_VSPACE:
- if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
- GETCHARINCTEST(c, eptr);
- switch(c)
- {
- default: RRETURN(MATCH_NOMATCH);
- case 0x0a: /* LF */
- case 0x0b: /* VT */
- case 0x0c: /* FF */
- case 0x0d: /* CR */
- case 0x85: /* NEL */
- case 0x2028: /* LINE SEPARATOR */
- case 0x2029: /* PARAGRAPH SEPARATOR */
- break;
- }
- ecode++;
- break;
-
-#ifdef SUPPORT_UCP
- /* Check the next character by Unicode property. We will get here only
- if the support is in the binary; otherwise a compile-time error occurs. */
-
- case OP_PROP:
- case OP_NOTPROP:
- if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
- GETCHARINCTEST(c, eptr);
- {
- int chartype, script;
- int category = _pcre_ucp_findprop(c, &chartype, &script);
-
- switch(ecode[1])
- {
- case PT_ANY:
- if (op == OP_NOTPROP) RRETURN(MATCH_NOMATCH);
- break;
-
- case PT_LAMP:
- if ((chartype == ucp_Lu ||
- chartype == ucp_Ll ||
- chartype == ucp_Lt) == (op == OP_NOTPROP))
- RRETURN(MATCH_NOMATCH);
- break;
-
- case PT_GC:
- if ((ecode[2] != category) == (op == OP_PROP))
- RRETURN(MATCH_NOMATCH);
- break;
-
- case PT_PC:
- if ((ecode[2] != chartype) == (op == OP_PROP))
- RRETURN(MATCH_NOMATCH);
- break;
-
- case PT_SC:
- if ((ecode[2] != script) == (op == OP_PROP))
- RRETURN(MATCH_NOMATCH);
- break;
-
- default:
- RRETURN(PCRE_ERROR_INTERNAL);
- }
-
- ecode += 3;
- }
- break;
-
- /* Match an extended Unicode sequence. We will get here only if the support
- is in the binary; otherwise a compile-time error occurs. */
-
- case OP_EXTUNI:
- if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
- GETCHARINCTEST(c, eptr);
- {
- int chartype, script;
- int category = _pcre_ucp_findprop(c, &chartype, &script);
- if (category == ucp_M) RRETURN(MATCH_NOMATCH);
- while (eptr < md->end_subject)
- {
- int len = 1;
- if (!utf8) c = *eptr; else
- {
- GETCHARLEN(c, eptr, len);
- }
- category = _pcre_ucp_findprop(c, &chartype, &script);
- if (category != ucp_M) break;
- eptr += len;
- }
- }
- ecode++;
- break;
-#endif
-
-
- /* Match a back reference, possibly repeatedly. Look past the end of the
- item to see if there is repeat information following. The code is similar
- to that for character classes, but repeated for efficiency. Then obey
- similar code to character type repeats - written out again for speed.
- However, if the referenced string is the empty string, always treat
- it as matched, any number of times (otherwise there could be infinite
- loops). */
-
- case OP_REF:
- {
- offset = GET2(ecode, 1) << 1; /* Doubled ref number */
- ecode += 3;
-
- /* If the reference is unset, there are two possibilities:
-
- (a) In the default, Perl-compatible state, set the length to be longer
- than the amount of subject left; this ensures that every attempt at a
- match fails. We can't just fail here, because of the possibility of
- quantifiers with zero minima.
-
- (b) If the JavaScript compatibility flag is set, set the length to zero
- so that the back reference matches an empty string.
-
- Otherwise, set the length to the length of what was matched by the
- referenced subpattern. */
-
- if (offset >= offset_top || md->offset_vector[offset] < 0)
- length = (md->jscript_compat)? 0 : md->end_subject - eptr + 1;
- else
- length = md->offset_vector[offset+1] - md->offset_vector[offset];
-
- /* Set up for repetition, or handle the non-repeated case */
-
- switch (*ecode)
- {
- case OP_CRSTAR:
- case OP_CRMINSTAR:
- case OP_CRPLUS:
- case OP_CRMINPLUS:
- case OP_CRQUERY:
- case OP_CRMINQUERY:
- c = *ecode++ - OP_CRSTAR;
- minimize = (c & 1) != 0;
- min = rep_min[c]; /* Pick up values from tables; */
- max = rep_max[c]; /* zero for max => infinity */
- if (max == 0) max = INT_MAX;
- break;
-
- case OP_CRRANGE:
- case OP_CRMINRANGE:
- minimize = (*ecode == OP_CRMINRANGE);
- min = GET2(ecode, 1);
- max = GET2(ecode, 3);
- if (max == 0) max = INT_MAX;
- ecode += 5;
- break;
-
- default: /* No repeat follows */
- if (!match_ref(offset, eptr, length, md, ims)) RRETURN(MATCH_NOMATCH);
- eptr += length;
- continue; /* With the main loop */
- }
-
- /* If the length of the reference is zero, just continue with the
- main loop. */
-
- if (length == 0) continue;
-
- /* First, ensure the minimum number of matches are present. We get back
- the length of the reference string explicitly rather than passing the
- address of eptr, so that eptr can be a register variable. */
-
- for (i = 1; i <= min; i++)
- {
- if (!match_ref(offset, eptr, length, md, ims)) RRETURN(MATCH_NOMATCH);
- eptr += length;
- }
-
- /* If min = max, continue at the same level without recursion.
- They are not both allowed to be zero. */
-
- if (min == max) continue;
-
- /* If minimizing, keep trying and advancing the pointer */
-
- if (minimize)
- {
- for (fi = min;; fi++)
- {
- RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM14);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max || !match_ref(offset, eptr, length, md, ims))
- RRETURN(MATCH_NOMATCH);
- eptr += length;
- }
- /* Control never gets here */
- }
-
- /* If maximizing, find the longest string and work backwards */
-
- else
- {
- pp = eptr;
- for (i = min; i < max; i++)
- {
- if (!match_ref(offset, eptr, length, md, ims)) break;
- eptr += length;
- }
- while (eptr >= pp)
- {
- RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM15);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- eptr -= length;
- }
- RRETURN(MATCH_NOMATCH);
- }
- }
- /* Control never gets here */
-
-
-
- /* Match a bit-mapped character class, possibly repeatedly. This op code is
- used when all the characters in the class have values in the range 0-255,
- and either the matching is caseful, or the characters are in the range
- 0-127 when UTF-8 processing is enabled. The only difference between
- OP_CLASS and OP_NCLASS occurs when a data character outside the range is
- encountered.
-
- First, look past the end of the item to see if there is repeat information
- following. Then obey similar code to character type repeats - written out
- again for speed. */
-
- case OP_NCLASS:
- case OP_CLASS:
- {
- data = ecode + 1; /* Save for matching */
- ecode += 33; /* Advance past the item */
-
- switch (*ecode)
- {
- case OP_CRSTAR:
- case OP_CRMINSTAR:
- case OP_CRPLUS:
- case OP_CRMINPLUS:
- case OP_CRQUERY:
- case OP_CRMINQUERY:
- c = *ecode++ - OP_CRSTAR;
- minimize = (c & 1) != 0;
- min = rep_min[c]; /* Pick up values from tables; */
- max = rep_max[c]; /* zero for max => infinity */
- if (max == 0) max = INT_MAX;
- break;
-
- case OP_CRRANGE:
- case OP_CRMINRANGE:
- minimize = (*ecode == OP_CRMINRANGE);
- min = GET2(ecode, 1);
- max = GET2(ecode, 3);
- if (max == 0) max = INT_MAX;
- ecode += 5;
- break;
-
- default: /* No repeat follows */
- min = max = 1;
- break;
- }
-
- /* First, ensure the minimum number of matches are present. */
-
-#ifdef SUPPORT_UTF8
- /* UTF-8 mode */
- if (utf8)
- {
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
- GETCHARINC(c, eptr);
- if (c > 255)
- {
- if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);
- }
- else
- {
- if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
- }
- }
- }
- else
-#endif
- /* Not UTF-8 mode */
- {
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
- c = *eptr++;
- if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
- }
- }
-
- /* If max == min we can continue with the main loop without the
- need to recurse. */
-
- if (min == max) continue;
-
- /* If minimizing, keep testing the rest of the expression and advancing
- the pointer while it matches the class. */
-
- if (minimize)
- {
-#ifdef SUPPORT_UTF8
- /* UTF-8 mode */
- if (utf8)
- {
- for (fi = min;; fi++)
- {
- RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM16);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
- GETCHARINC(c, eptr);
- if (c > 255)
- {
- if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);
- }
- else
- {
- if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
- }
- }
- }
- else
-#endif
- /* Not UTF-8 mode */
- {
- for (fi = min;; fi++)
- {
- RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM17);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
- c = *eptr++;
- if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
- }
- }
- /* Control never gets here */
- }
-
- /* If maximizing, find the longest possible run, then work backwards. */
-
- else
- {
- pp = eptr;
-
-#ifdef SUPPORT_UTF8
- /* UTF-8 mode */
- if (utf8)
- {
- for (i = min; i < max; i++)
- {
- int len = 1;
- if (eptr >= md->end_subject) break;
- GETCHARLEN(c, eptr, len);
- if (c > 255)
- {
- if (op == OP_CLASS) break;
- }
- else
- {
- if ((data[c/8] & (1 << (c&7))) == 0) break;
- }
- eptr += len;
- }
- for (;;)
- {
- RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM18);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (eptr-- == pp) break; /* Stop if tried at original pos */
- BACKCHAR(eptr);
- }
- }
- else
-#endif
- /* Not UTF-8 mode */
- {
- for (i = min; i < max; i++)
- {
- if (eptr >= md->end_subject) break;
- c = *eptr;
- if ((data[c/8] & (1 << (c&7))) == 0) break;
- eptr++;
- }
- while (eptr >= pp)
- {
- RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM19);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- eptr--;
- }
- }
-
- RRETURN(MATCH_NOMATCH);
- }
- }
- /* Control never gets here */
-
-
- /* Match an extended character class. This opcode is encountered only
- in UTF-8 mode, because that's the only time it is compiled. */
-
-#ifdef SUPPORT_UTF8
- case OP_XCLASS:
- {
- data = ecode + 1 + LINK_SIZE; /* Save for matching */
- ecode += GET(ecode, 1); /* Advance past the item */
-
- switch (*ecode)
- {
- case OP_CRSTAR:
- case OP_CRMINSTAR:
- case OP_CRPLUS:
- case OP_CRMINPLUS:
- case OP_CRQUERY:
- case OP_CRMINQUERY:
- c = *ecode++ - OP_CRSTAR;
- minimize = (c & 1) != 0;
- min = rep_min[c]; /* Pick up values from tables; */
- max = rep_max[c]; /* zero for max => infinity */
- if (max == 0) max = INT_MAX;
- break;
-
- case OP_CRRANGE:
- case OP_CRMINRANGE:
- minimize = (*ecode == OP_CRMINRANGE);
- min = GET2(ecode, 1);
- max = GET2(ecode, 3);
- if (max == 0) max = INT_MAX;
- ecode += 5;
- break;
-
- default: /* No repeat follows */
- min = max = 1;
- break;
- }
-
- /* First, ensure the minimum number of matches are present. */
-
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
- GETCHARINC(c, eptr);
- if (!_pcre_xclass(c, data)) RRETURN(MATCH_NOMATCH);
- }
-
- /* If max == min we can continue with the main loop without the
- need to recurse. */
-
- if (min == max) continue;
-
- /* If minimizing, keep testing the rest of the expression and advancing
- the pointer while it matches the class. */
-
- if (minimize)
- {
- for (fi = min;; fi++)
- {
- RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM20);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
- GETCHARINC(c, eptr);
- if (!_pcre_xclass(c, data)) RRETURN(MATCH_NOMATCH);
- }
- /* Control never gets here */
- }
-
- /* If maximizing, find the longest possible run, then work backwards. */
-
- else
- {
- pp = eptr;
- for (i = min; i < max; i++)
- {
- int len = 1;
- if (eptr >= md->end_subject) break;
- GETCHARLEN(c, eptr, len);
- if (!_pcre_xclass(c, data)) break;
- eptr += len;
- }
- for(;;)
- {
- RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM21);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (eptr-- == pp) break; /* Stop if tried at original pos */
- if (utf8) BACKCHAR(eptr);
- }
- RRETURN(MATCH_NOMATCH);
- }
-
- /* Control never gets here */
- }
-#endif /* End of XCLASS */
-
- /* Match a single character, casefully */
-
- case OP_CHAR:
-#ifdef SUPPORT_UTF8
- if (utf8)
- {
- length = 1;
- ecode++;
- GETCHARLEN(fc, ecode, length);
- if (length > md->end_subject - eptr) RRETURN(MATCH_NOMATCH);
- while (length-- > 0) if (*ecode++ != *eptr++) RRETURN(MATCH_NOMATCH);
- }
- else
-#endif
-
- /* Non-UTF-8 mode */
- {
- if (md->end_subject - eptr < 1) RRETURN(MATCH_NOMATCH);
- if (ecode[1] != *eptr++) RRETURN(MATCH_NOMATCH);
- ecode += 2;
- }
- break;
-
- /* Match a single character, caselessly */
-
- case OP_CHARNC:
-#ifdef SUPPORT_UTF8
- if (utf8)
- {
- length = 1;
- ecode++;
- GETCHARLEN(fc, ecode, length);
-
- if (length > md->end_subject - eptr) RRETURN(MATCH_NOMATCH);
-
- /* If the pattern character's value is < 128, we have only one byte, and
- can use the fast lookup table. */
-
- if (fc < 128)
- {
- if (md->lcc[*ecode++] != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);
- }
-
- /* Otherwise we must pick up the subject character */
-
- else
- {
- unsigned int dc;
- GETCHARINC(dc, eptr);
- ecode += length;
-
- /* If we have Unicode property support, we can use it to test the other
- case of the character, if there is one. */
-
- if (fc != dc)
- {
-#ifdef SUPPORT_UCP
- if (dc != _pcre_ucp_othercase(fc))
-#endif
- RRETURN(MATCH_NOMATCH);
- }
- }
- }
- else
-#endif /* SUPPORT_UTF8 */
-
- /* Non-UTF-8 mode */
- {
- if (md->end_subject - eptr < 1) RRETURN(MATCH_NOMATCH);
- if (md->lcc[ecode[1]] != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);
- ecode += 2;
- }
- break;
-
- /* Match a single character repeatedly. */
-
- case OP_EXACT:
- min = max = GET2(ecode, 1);
- ecode += 3;
- goto REPEATCHAR;
-
- case OP_POSUPTO:
- possessive = TRUE;
- /* Fall through */
-
- case OP_UPTO:
- case OP_MINUPTO:
- min = 0;
- max = GET2(ecode, 1);
- minimize = *ecode == OP_MINUPTO;
- ecode += 3;
- goto REPEATCHAR;
-
- case OP_POSSTAR:
- possessive = TRUE;
- min = 0;
- max = INT_MAX;
- ecode++;
- goto REPEATCHAR;
-
- case OP_POSPLUS:
- possessive = TRUE;
- min = 1;
- max = INT_MAX;
- ecode++;
- goto REPEATCHAR;
-
- case OP_POSQUERY:
- possessive = TRUE;
- min = 0;
- max = 1;
- ecode++;
- goto REPEATCHAR;
-
- case OP_STAR:
- case OP_MINSTAR:
- case OP_PLUS:
- case OP_MINPLUS:
- case OP_QUERY:
- case OP_MINQUERY:
- c = *ecode++ - OP_STAR;
- minimize = (c & 1) != 0;
- min = rep_min[c]; /* Pick up values from tables; */
- max = rep_max[c]; /* zero for max => infinity */
- if (max == 0) max = INT_MAX;
-
- /* Common code for all repeated single-character matches. We can give
- up quickly if there are fewer than the minimum number of characters left in
- the subject. */
-
- REPEATCHAR:
-#ifdef SUPPORT_UTF8
- if (utf8)
- {
- length = 1;
- charptr = ecode;
- GETCHARLEN(fc, ecode, length);
- if (min * length > md->end_subject - eptr) RRETURN(MATCH_NOMATCH);
- ecode += length;
-
- /* Handle multibyte character matching specially here. There is
- support for caseless matching if UCP support is present. */
-
- if (length > 1)
- {
-#ifdef SUPPORT_UCP
- unsigned int othercase;
- if ((ims & PCRE_CASELESS) != 0 &&
- (othercase = _pcre_ucp_othercase(fc)) != NOTACHAR)
- oclength = _pcre_ord2utf8(othercase, occhars);
- else oclength = 0;
-#endif /* SUPPORT_UCP */
-
- for (i = 1; i <= min; i++)
- {
- if (memcmp(eptr, charptr, length) == 0) eptr += length;
-#ifdef SUPPORT_UCP
- /* Need braces because of following else */
- else if (oclength == 0) { RRETURN(MATCH_NOMATCH); }
- else
- {
- if (memcmp(eptr, occhars, oclength) != 0) RRETURN(MATCH_NOMATCH);
- eptr += oclength;
- }
-#else /* without SUPPORT_UCP */
- else { RRETURN(MATCH_NOMATCH); }
-#endif /* SUPPORT_UCP */
- }
-
- if (min == max) continue;
-
- if (minimize)
- {
- for (fi = min;; fi++)
- {
- RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM22);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
- if (memcmp(eptr, charptr, length) == 0) eptr += length;
-#ifdef SUPPORT_UCP
- /* Need braces because of following else */
- else if (oclength == 0) { RRETURN(MATCH_NOMATCH); }
- else
- {
- if (memcmp(eptr, occhars, oclength) != 0) RRETURN(MATCH_NOMATCH);
- eptr += oclength;
- }
-#else /* without SUPPORT_UCP */
- else { RRETURN (MATCH_NOMATCH); }
-#endif /* SUPPORT_UCP */
- }
- /* Control never gets here */
- }
-
- else /* Maximize */
- {
- pp = eptr;
- for (i = min; i < max; i++)
- {
- if (eptr > md->end_subject - length) break;
- if (memcmp(eptr, charptr, length) == 0) eptr += length;
-#ifdef SUPPORT_UCP
- else if (oclength == 0) break;
- else
- {
- if (memcmp(eptr, occhars, oclength) != 0) break;
- eptr += oclength;
- }
-#else /* without SUPPORT_UCP */
- else break;
-#endif /* SUPPORT_UCP */
- }
-
- if (possessive) continue;
- for(;;)
- {
- RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM23);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (eptr == pp) RRETURN(MATCH_NOMATCH);
-#ifdef SUPPORT_UCP
- eptr--;
- BACKCHAR(eptr);
-#else /* without SUPPORT_UCP */
- eptr -= length;
-#endif /* SUPPORT_UCP */
- }
- }
- /* Control never gets here */
- }
-
- /* If the length of a UTF-8 character is 1, we fall through here, and
- obey the code as for non-UTF-8 characters below, though in this case the
- value of fc will always be < 128. */
- }
- else
-#endif /* SUPPORT_UTF8 */
-
- /* When not in UTF-8 mode, load a single-byte character. */
- {
- if (min > md->end_subject - eptr) RRETURN(MATCH_NOMATCH);
- fc = *ecode++;
- }
-
- /* The value of fc at this point is always less than 256, though we may or
- may not be in UTF-8 mode. The code is duplicated for the caseless and
- caseful cases, for speed, since matching characters is likely to be quite
- common. First, ensure the minimum number of matches are present. If min =
- max, continue at the same level without recursing. Otherwise, if
- minimizing, keep trying the rest of the expression and advancing one
- matching character if failing, up to the maximum. Alternatively, if
- maximizing, find the maximum number of characters and work backwards. */
-
- DPRINTF(("matching %c{%d,%d} against subject %.*s\n", fc, min, max,
- max, eptr));
-
- if ((ims & PCRE_CASELESS) != 0)
- {
- fc = md->lcc[fc];
- for (i = 1; i <= min; i++)
- if (fc != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);
- if (min == max) continue;
- if (minimize)
- {
- for (fi = min;; fi++)
- {
- RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM24);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max || eptr >= md->end_subject ||
- fc != md->lcc[*eptr++])
- RRETURN(MATCH_NOMATCH);
- }
- /* Control never gets here */
- }
- else /* Maximize */
- {
- pp = eptr;
- for (i = min; i < max; i++)
- {
- if (eptr >= md->end_subject || fc != md->lcc[*eptr]) break;
- eptr++;
- }
- if (possessive) continue;
- while (eptr >= pp)
- {
- RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM25);
- eptr--;
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- }
- RRETURN(MATCH_NOMATCH);
- }
- /* Control never gets here */
- }
-
- /* Caseful comparisons (includes all multi-byte characters) */
-
- else
- {
- for (i = 1; i <= min; i++) if (fc != *eptr++) RRETURN(MATCH_NOMATCH);
- if (min == max) continue;
- if (minimize)
- {
- for (fi = min;; fi++)
- {
- RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM26);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max || eptr >= md->end_subject || fc != *eptr++)
- RRETURN(MATCH_NOMATCH);
- }
- /* Control never gets here */
- }
- else /* Maximize */
- {
- pp = eptr;
- for (i = min; i < max; i++)
- {
- if (eptr >= md->end_subject || fc != *eptr) break;
- eptr++;
- }
- if (possessive) continue;
- while (eptr >= pp)
- {
- RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM27);
- eptr--;
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- }
- RRETURN(MATCH_NOMATCH);
- }
- }
- /* Control never gets here */
-
- /* Match a negated single one-byte character. The character we are
- checking can be multibyte. */
-
- case OP_NOT:
- if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
- ecode++;
- GETCHARINCTEST(c, eptr);
- if ((ims & PCRE_CASELESS) != 0)
- {
-#ifdef SUPPORT_UTF8
- if (c < 256)
-#endif
- c = md->lcc[c];
- if (md->lcc[*ecode++] == c) RRETURN(MATCH_NOMATCH);
- }
- else
- {
- if (*ecode++ == c) RRETURN(MATCH_NOMATCH);
- }
- break;
-
- /* Match a negated single one-byte character repeatedly. This is almost a
- repeat of the code for a repeated single character, but I haven't found a
- nice way of commoning these up that doesn't require a test of the
- positive/negative option for each character match. Maybe that wouldn't add
- very much to the time taken, but character matching *is* what this is all
- about... */
-
- case OP_NOTEXACT:
- min = max = GET2(ecode, 1);
- ecode += 3;
- goto REPEATNOTCHAR;
-
- case OP_NOTUPTO:
- case OP_NOTMINUPTO:
- min = 0;
- max = GET2(ecode, 1);
- minimize = *ecode == OP_NOTMINUPTO;
- ecode += 3;
- goto REPEATNOTCHAR;
-
- case OP_NOTPOSSTAR:
- possessive = TRUE;
- min = 0;
- max = INT_MAX;
- ecode++;
- goto REPEATNOTCHAR;
-
- case OP_NOTPOSPLUS:
- possessive = TRUE;
- min = 1;
- max = INT_MAX;
- ecode++;
- goto REPEATNOTCHAR;
-
- case OP_NOTPOSQUERY:
- possessive = TRUE;
- min = 0;
- max = 1;
- ecode++;
- goto REPEATNOTCHAR;
-
- case OP_NOTPOSUPTO:
- possessive = TRUE;
- min = 0;
- max = GET2(ecode, 1);
- ecode += 3;
- goto REPEATNOTCHAR;
-
- case OP_NOTSTAR:
- case OP_NOTMINSTAR:
- case OP_NOTPLUS:
- case OP_NOTMINPLUS:
- case OP_NOTQUERY:
- case OP_NOTMINQUERY:
- c = *ecode++ - OP_NOTSTAR;
- minimize = (c & 1) != 0;
- min = rep_min[c]; /* Pick up values from tables; */
- max = rep_max[c]; /* zero for max => infinity */
- if (max == 0) max = INT_MAX;
-
- /* Common code for all repeated single-byte matches. We can give up quickly
- if there are fewer than the minimum number of bytes left in the
- subject. */
-
- REPEATNOTCHAR:
- if (min > md->end_subject - eptr) RRETURN(MATCH_NOMATCH);
- fc = *ecode++;
-
- /* The code is duplicated for the caseless and caseful cases, for speed,
- since matching characters is likely to be quite common. First, ensure the
- minimum number of matches are present. If min = max, continue at the same
- level without recursing. Otherwise, if minimizing, keep trying the rest of
- the expression and advancing one matching character if failing, up to the
- maximum. Alternatively, if maximizing, find the maximum number of
- characters and work backwards. */
-
- DPRINTF(("negative matching %c{%d,%d} against subject %.*s\n", fc, min, max,
- max, eptr));
-
- if ((ims & PCRE_CASELESS) != 0)
- {
- fc = md->lcc[fc];
-
-#ifdef SUPPORT_UTF8
- /* UTF-8 mode */
- if (utf8)
- {
- register unsigned int d;
- for (i = 1; i <= min; i++)
- {
- GETCHARINC(d, eptr);
- if (d < 256) d = md->lcc[d];
- if (fc == d) RRETURN(MATCH_NOMATCH);
- }
- }
- else
-#endif
-
- /* Not UTF-8 mode */
- {
- for (i = 1; i <= min; i++)
- if (fc == md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);
- }
-
- if (min == max) continue;
-
- if (minimize)
- {
-#ifdef SUPPORT_UTF8
- /* UTF-8 mode */
- if (utf8)
- {
- register unsigned int d;
- for (fi = min;; fi++)
- {
- RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM28);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- GETCHARINC(d, eptr);
- if (d < 256) d = md->lcc[d];
- if (fi >= max || eptr >= md->end_subject || fc == d)
- RRETURN(MATCH_NOMATCH);
- }
- }
- else
-#endif
- /* Not UTF-8 mode */
- {
- for (fi = min;; fi++)
- {
- RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM29);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max || eptr >= md->end_subject || fc == md->lcc[*eptr++])
- RRETURN(MATCH_NOMATCH);
- }
- }
- /* Control never gets here */
- }
-
- /* Maximize case */
-
- else
- {
- pp = eptr;
-
-#ifdef SUPPORT_UTF8
- /* UTF-8 mode */
- if (utf8)
- {
- register unsigned int d;
- for (i = min; i < max; i++)
- {
- int len = 1;
- if (eptr >= md->end_subject) break;
- GETCHARLEN(d, eptr, len);
- if (d < 256) d = md->lcc[d];
- if (fc == d) break;
- eptr += len;
- }
- if (possessive) continue;
- for(;;)
- {
- RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM30);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (eptr-- == pp) break; /* Stop if tried at original pos */
- BACKCHAR(eptr);
- }
- }
- else
-#endif
- /* Not UTF-8 mode */
- {
- for (i = min; i < max; i++)
- {
- if (eptr >= md->end_subject || fc == md->lcc[*eptr]) break;
- eptr++;
- }
- if (possessive) continue;
- while (eptr >= pp)
- {
- RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM31);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- eptr--;
- }
- }
-
- RRETURN(MATCH_NOMATCH);
- }
- /* Control never gets here */
- }
-
- /* Caseful comparisons */
-
- else
- {
-#ifdef SUPPORT_UTF8
- /* UTF-8 mode */
- if (utf8)
- {
- register unsigned int d;
- for (i = 1; i <= min; i++)
- {
- GETCHARINC(d, eptr);
- if (fc == d) RRETURN(MATCH_NOMATCH);
- }
- }
- else
-#endif
- /* Not UTF-8 mode */
- {
- for (i = 1; i <= min; i++)
- if (fc == *eptr++) RRETURN(MATCH_NOMATCH);
- }
-
- if (min == max) continue;
-
- if (minimize)
- {
-#ifdef SUPPORT_UTF8
- /* UTF-8 mode */
- if (utf8)
- {
- register unsigned int d;
- for (fi = min;; fi++)
- {
- RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM32);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- GETCHARINC(d, eptr);
- if (fi >= max || eptr >= md->end_subject || fc == d)
- RRETURN(MATCH_NOMATCH);
- }
- }
- else
-#endif
- /* Not UTF-8 mode */
- {
- for (fi = min;; fi++)
- {
- RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM33);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max || eptr >= md->end_subject || fc == *eptr++)
- RRETURN(MATCH_NOMATCH);
- }
- }
- /* Control never gets here */
- }
-
- /* Maximize case */
-
- else
- {
- pp = eptr;
-
-#ifdef SUPPORT_UTF8
- /* UTF-8 mode */
- if (utf8)
- {
- register unsigned int d;
- for (i = min; i < max; i++)
- {
- int len = 1;
- if (eptr >= md->end_subject) break;
- GETCHARLEN(d, eptr, len);
- if (fc == d) break;
- eptr += len;
- }
- if (possessive) continue;
- for(;;)
- {
- RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM34);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (eptr-- == pp) break; /* Stop if tried at original pos */
- BACKCHAR(eptr);
- }
- }
- else
-#endif
- /* Not UTF-8 mode */
- {
- for (i = min; i < max; i++)
- {
- if (eptr >= md->end_subject || fc == *eptr) break;
- eptr++;
- }
- if (possessive) continue;
- while (eptr >= pp)
- {
- RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM35);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- eptr--;
- }
- }
-
- RRETURN(MATCH_NOMATCH);
- }
- }
- /* Control never gets here */
-
- /* Match a single character type repeatedly; several different opcodes
- share code. This is very similar to the code for single characters, but we
- repeat it in the interests of efficiency. */
-
- case OP_TYPEEXACT:
- min = max = GET2(ecode, 1);
- minimize = TRUE;
- ecode += 3;
- goto REPEATTYPE;
-
- case OP_TYPEUPTO:
- case OP_TYPEMINUPTO:
- min = 0;
- max = GET2(ecode, 1);
- minimize = *ecode == OP_TYPEMINUPTO;
- ecode += 3;
- goto REPEATTYPE;
-
- case OP_TYPEPOSSTAR:
- possessive = TRUE;
- min = 0;
- max = INT_MAX;
- ecode++;
- goto REPEATTYPE;
-
- case OP_TYPEPOSPLUS:
- possessive = TRUE;
- min = 1;
- max = INT_MAX;
- ecode++;
- goto REPEATTYPE;
-
- case OP_TYPEPOSQUERY:
- possessive = TRUE;
- min = 0;
- max = 1;
- ecode++;
- goto REPEATTYPE;
-
- case OP_TYPEPOSUPTO:
- possessive = TRUE;
- min = 0;
- max = GET2(ecode, 1);
- ecode += 3;
- goto REPEATTYPE;
-
- case OP_TYPESTAR:
- case OP_TYPEMINSTAR:
- case OP_TYPEPLUS:
- case OP_TYPEMINPLUS:
- case OP_TYPEQUERY:
- case OP_TYPEMINQUERY:
- c = *ecode++ - OP_TYPESTAR;
- minimize = (c & 1) != 0;
- min = rep_min[c]; /* Pick up values from tables; */
- max = rep_max[c]; /* zero for max => infinity */
- if (max == 0) max = INT_MAX;
-
- /* Common code for all repeated single character type matches. Note that
- in UTF-8 mode, '.' matches a character of any length, but for the other
- character types, the valid characters are all one-byte long. */
-
- REPEATTYPE:
- ctype = *ecode++; /* Code for the character type */
-
-#ifdef SUPPORT_UCP
- if (ctype == OP_PROP || ctype == OP_NOTPROP)
- {
- prop_fail_result = ctype == OP_NOTPROP;
- prop_type = *ecode++;
- prop_value = *ecode++;
- }
- else prop_type = -1;
-#endif
-
- /* First, ensure the minimum number of matches are present. Use inline
- code for maximizing the speed, and do the type test once at the start
- (i.e. keep it out of the loop). Also we can test that there are at least
- the minimum number of bytes before we start. This isn't as effective in
- UTF-8 mode, but it does no harm. Separate the UTF-8 code completely as that
- is tidier. Also separate the UCP code, which can be the same for both UTF-8
- and single-bytes. */
-
- if (min > md->end_subject - eptr) RRETURN(MATCH_NOMATCH);
- if (min > 0)
- {
-#ifdef SUPPORT_UCP
- if (prop_type >= 0)
- {
- switch(prop_type)
- {
- case PT_ANY:
- if (prop_fail_result) RRETURN(MATCH_NOMATCH);
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
- GETCHARINCTEST(c, eptr);
- }
- break;
-
- case PT_LAMP:
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
- GETCHARINCTEST(c, eptr);
- prop_category = _pcre_ucp_findprop(c, &prop_chartype, &prop_script);
- if ((prop_chartype == ucp_Lu ||
- prop_chartype == ucp_Ll ||
- prop_chartype == ucp_Lt) == prop_fail_result)
- RRETURN(MATCH_NOMATCH);
- }
- break;
-
- case PT_GC:
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
- GETCHARINCTEST(c, eptr);
- prop_category = _pcre_ucp_findprop(c, &prop_chartype, &prop_script);
- if ((prop_category == prop_value) == prop_fail_result)
- RRETURN(MATCH_NOMATCH);
- }
- break;
-
- case PT_PC:
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
- GETCHARINCTEST(c, eptr);
- prop_category = _pcre_ucp_findprop(c, &prop_chartype, &prop_script);
- if ((prop_chartype == prop_value) == prop_fail_result)
- RRETURN(MATCH_NOMATCH);
- }
- break;
-
- case PT_SC:
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
- GETCHARINCTEST(c, eptr);
- prop_category = _pcre_ucp_findprop(c, &prop_chartype, &prop_script);
- if ((prop_script == prop_value) == prop_fail_result)
- RRETURN(MATCH_NOMATCH);
- }
- break;
-
- default:
- RRETURN(PCRE_ERROR_INTERNAL);
- }
- }
-
- /* Match extended Unicode sequences. We will get here only if the
- support is in the binary; otherwise a compile-time error occurs. */
-
- else if (ctype == OP_EXTUNI)
- {
- for (i = 1; i <= min; i++)
- {
- GETCHARINCTEST(c, eptr);
- prop_category = _pcre_ucp_findprop(c, &prop_chartype, &prop_script);
- if (prop_category == ucp_M) RRETURN(MATCH_NOMATCH);
- while (eptr < md->end_subject)
- {
- int len = 1;
- if (!utf8) c = *eptr; else
- {
- GETCHARLEN(c, eptr, len);
- }
- prop_category = _pcre_ucp_findprop(c, &prop_chartype, &prop_script);
- if (prop_category != ucp_M) break;
- eptr += len;
- }
- }
- }
-
- else
-#endif /* SUPPORT_UCP */
-
-/* Handle all other cases when the coding is UTF-8 */
-
-#ifdef SUPPORT_UTF8
- if (utf8) switch(ctype)
- {
- case OP_ANY:
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject || IS_NEWLINE(eptr))
- RRETURN(MATCH_NOMATCH);
- eptr++;
- while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;
- }
- break;
-
- case OP_ALLANY:
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
- eptr++;
- while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;
- }
- break;
-
- case OP_ANYBYTE:
- eptr += min;
- break;
-
- case OP_ANYNL:
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
- GETCHARINC(c, eptr);
- switch(c)
- {
- default: RRETURN(MATCH_NOMATCH);
- case 0x000d:
- if (eptr < md->end_subject && *eptr == 0x0a) eptr++;
- break;
-
- case 0x000a:
- break;
-
- case 0x000b:
- case 0x000c:
- case 0x0085:
- case 0x2028:
- case 0x2029:
- if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
- break;
- }
- }
- break;
-
- case OP_NOT_HSPACE:
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
- GETCHARINC(c, eptr);
- switch(c)
- {
- default: break;
- case 0x09: /* HT */
- case 0x20: /* SPACE */
- case 0xa0: /* NBSP */
- case 0x1680: /* OGHAM SPACE MARK */
- case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */
- case 0x2000: /* EN QUAD */
- case 0x2001: /* EM QUAD */
- case 0x2002: /* EN SPACE */
- case 0x2003: /* EM SPACE */
- case 0x2004: /* THREE-PER-EM SPACE */
- case 0x2005: /* FOUR-PER-EM SPACE */
- case 0x2006: /* SIX-PER-EM SPACE */
- case 0x2007: /* FIGURE SPACE */
- case 0x2008: /* PUNCTUATION SPACE */
- case 0x2009: /* THIN SPACE */
- case 0x200A: /* HAIR SPACE */
- case 0x202f: /* NARROW NO-BREAK SPACE */
- case 0x205f: /* MEDIUM MATHEMATICAL SPACE */
- case 0x3000: /* IDEOGRAPHIC SPACE */
- RRETURN(MATCH_NOMATCH);
- }
- }
- break;
-
- case OP_HSPACE:
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
- GETCHARINC(c, eptr);
- switch(c)
- {
- default: RRETURN(MATCH_NOMATCH);
- case 0x09: /* HT */
- case 0x20: /* SPACE */
- case 0xa0: /* NBSP */
- case 0x1680: /* OGHAM SPACE MARK */
- case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */
- case 0x2000: /* EN QUAD */
- case 0x2001: /* EM QUAD */
- case 0x2002: /* EN SPACE */
- case 0x2003: /* EM SPACE */
- case 0x2004: /* THREE-PER-EM SPACE */
- case 0x2005: /* FOUR-PER-EM SPACE */
- case 0x2006: /* SIX-PER-EM SPACE */
- case 0x2007: /* FIGURE SPACE */
- case 0x2008: /* PUNCTUATION SPACE */
- case 0x2009: /* THIN SPACE */
- case 0x200A: /* HAIR SPACE */
- case 0x202f: /* NARROW NO-BREAK SPACE */
- case 0x205f: /* MEDIUM MATHEMATICAL SPACE */
- case 0x3000: /* IDEOGRAPHIC SPACE */
- break;
- }
- }
- break;
-
- case OP_NOT_VSPACE:
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
- GETCHARINC(c, eptr);
- switch(c)
- {
- default: break;
- case 0x0a: /* LF */
- case 0x0b: /* VT */
- case 0x0c: /* FF */
- case 0x0d: /* CR */
- case 0x85: /* NEL */
- case 0x2028: /* LINE SEPARATOR */
- case 0x2029: /* PARAGRAPH SEPARATOR */
- RRETURN(MATCH_NOMATCH);
- }
- }
- break;
-
- case OP_VSPACE:
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
- GETCHARINC(c, eptr);
- switch(c)
- {
- default: RRETURN(MATCH_NOMATCH);
- case 0x0a: /* LF */
- case 0x0b: /* VT */
- case 0x0c: /* FF */
- case 0x0d: /* CR */
- case 0x85: /* NEL */
- case 0x2028: /* LINE SEPARATOR */
- case 0x2029: /* PARAGRAPH SEPARATOR */
- break;
- }
- }
- break;
-
- case OP_NOT_DIGIT:
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
- GETCHARINC(c, eptr);
- if (c < 128 && (md->ctypes[c] & ctype_digit) != 0)
- RRETURN(MATCH_NOMATCH);
- }
- break;
-
- case OP_DIGIT:
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject ||
- *eptr >= 128 || (md->ctypes[*eptr++] & ctype_digit) == 0)
- RRETURN(MATCH_NOMATCH);
- /* No need to skip more bytes - we know it's a 1-byte character */
- }
- break;
-
- case OP_NOT_WHITESPACE:
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject ||
- (*eptr < 128 && (md->ctypes[*eptr] & ctype_space) != 0))
- RRETURN(MATCH_NOMATCH);
- while (++eptr < md->end_subject && (*eptr & 0xc0) == 0x80);
- }
- break;
-
- case OP_WHITESPACE:
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject ||
- *eptr >= 128 || (md->ctypes[*eptr++] & ctype_space) == 0)
- RRETURN(MATCH_NOMATCH);
- /* No need to skip more bytes - we know it's a 1-byte character */
- }
- break;
-
- case OP_NOT_WORDCHAR:
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject ||
- (*eptr < 128 && (md->ctypes[*eptr] & ctype_word) != 0))
- RRETURN(MATCH_NOMATCH);
- while (++eptr < md->end_subject && (*eptr & 0xc0) == 0x80);
- }
- break;
-
- case OP_WORDCHAR:
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject ||
- *eptr >= 128 || (md->ctypes[*eptr++] & ctype_word) == 0)
- RRETURN(MATCH_NOMATCH);
- /* No need to skip more bytes - we know it's a 1-byte character */
- }
- break;
-
- default:
- RRETURN(PCRE_ERROR_INTERNAL);
- } /* End switch(ctype) */
-
- else
-#endif /* SUPPORT_UTF8 */
-
- /* Code for the non-UTF-8 case for minimum matching of operators other
- than OP_PROP and OP_NOTPROP. We can assume that there are the minimum
- number of bytes present, as this was tested above. */
-
- switch(ctype)
- {
- case OP_ANY:
- for (i = 1; i <= min; i++)
- {
- if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);
- eptr++;
- }
- break;
-
- case OP_ALLANY:
- eptr += min;
- break;
-
- case OP_ANYBYTE:
- eptr += min;
- break;
-
- /* Because of the CRLF case, we can't assume the minimum number of
- bytes are present in this case. */
-
- case OP_ANYNL:
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
- switch(*eptr++)
- {
- default: RRETURN(MATCH_NOMATCH);
- case 0x000d:
- if (eptr < md->end_subject && *eptr == 0x0a) eptr++;
- break;
- case 0x000a:
- break;
-
- case 0x000b:
- case 0x000c:
- case 0x0085:
- if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
- break;
- }
- }
- break;
-
- case OP_NOT_HSPACE:
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
- switch(*eptr++)
- {
- default: break;
- case 0x09: /* HT */
- case 0x20: /* SPACE */
- case 0xa0: /* NBSP */
- RRETURN(MATCH_NOMATCH);
- }
- }
- break;
-
- case OP_HSPACE:
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
- switch(*eptr++)
- {
- default: RRETURN(MATCH_NOMATCH);
- case 0x09: /* HT */
- case 0x20: /* SPACE */
- case 0xa0: /* NBSP */
- break;
- }
- }
- break;
-
- case OP_NOT_VSPACE:
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
- switch(*eptr++)
- {
- default: break;
- case 0x0a: /* LF */
- case 0x0b: /* VT */
- case 0x0c: /* FF */
- case 0x0d: /* CR */
- case 0x85: /* NEL */
- RRETURN(MATCH_NOMATCH);
- }
- }
- break;
-
- case OP_VSPACE:
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
- switch(*eptr++)
- {
- default: RRETURN(MATCH_NOMATCH);
- case 0x0a: /* LF */
- case 0x0b: /* VT */
- case 0x0c: /* FF */
- case 0x0d: /* CR */
- case 0x85: /* NEL */
- break;
- }
- }
- break;
-
- case OP_NOT_DIGIT:
- for (i = 1; i <= min; i++)
- if ((md->ctypes[*eptr++] & ctype_digit) != 0) RRETURN(MATCH_NOMATCH);
- break;
-
- case OP_DIGIT:
- for (i = 1; i <= min; i++)
- if ((md->ctypes[*eptr++] & ctype_digit) == 0) RRETURN(MATCH_NOMATCH);
- break;
-
- case OP_NOT_WHITESPACE:
- for (i = 1; i <= min; i++)
- if ((md->ctypes[*eptr++] & ctype_space) != 0) RRETURN(MATCH_NOMATCH);
- break;
-
- case OP_WHITESPACE:
- for (i = 1; i <= min; i++)
- if ((md->ctypes[*eptr++] & ctype_space) == 0) RRETURN(MATCH_NOMATCH);
- break;
-
- case OP_NOT_WORDCHAR:
- for (i = 1; i <= min; i++)
- if ((md->ctypes[*eptr++] & ctype_word) != 0)
- RRETURN(MATCH_NOMATCH);
- break;
-
- case OP_WORDCHAR:
- for (i = 1; i <= min; i++)
- if ((md->ctypes[*eptr++] & ctype_word) == 0)
- RRETURN(MATCH_NOMATCH);
- break;
-
- default:
- RRETURN(PCRE_ERROR_INTERNAL);
- }
- }
-
- /* If min = max, continue at the same level without recursing */
-
- if (min == max) continue;
-
- /* If minimizing, we have to test the rest of the pattern before each
- subsequent match. Again, separate the UTF-8 case for speed, and also
- separate the UCP cases. */
-
- if (minimize)
- {
-#ifdef SUPPORT_UCP
- if (prop_type >= 0)
- {
- switch(prop_type)
- {
- case PT_ANY:
- for (fi = min;; fi++)
- {
- RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM36);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
- GETCHARINC(c, eptr);
- if (prop_fail_result) RRETURN(MATCH_NOMATCH);
- }
- /* Control never gets here */
-
- case PT_LAMP:
- for (fi = min;; fi++)
- {
- RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM37);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
- GETCHARINC(c, eptr);
- prop_category = _pcre_ucp_findprop(c, &prop_chartype, &prop_script);
- if ((prop_chartype == ucp_Lu ||
- prop_chartype == ucp_Ll ||
- prop_chartype == ucp_Lt) == prop_fail_result)
- RRETURN(MATCH_NOMATCH);
- }
- /* Control never gets here */
-
- case PT_GC:
- for (fi = min;; fi++)
- {
- RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM38);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
- GETCHARINC(c, eptr);
- prop_category = _pcre_ucp_findprop(c, &prop_chartype, &prop_script);
- if ((prop_category == prop_value) == prop_fail_result)
- RRETURN(MATCH_NOMATCH);
- }
- /* Control never gets here */
-
- case PT_PC:
- for (fi = min;; fi++)
- {
- RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM39);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
- GETCHARINC(c, eptr);
- prop_category = _pcre_ucp_findprop(c, &prop_chartype, &prop_script);
- if ((prop_chartype == prop_value) == prop_fail_result)
- RRETURN(MATCH_NOMATCH);
- }
- /* Control never gets here */
-
- case PT_SC:
- for (fi = min;; fi++)
- {
- RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM40);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
- GETCHARINC(c, eptr);
- prop_category = _pcre_ucp_findprop(c, &prop_chartype, &prop_script);
- if ((prop_script == prop_value) == prop_fail_result)
- RRETURN(MATCH_NOMATCH);
- }
- /* Control never gets here */
-
- default:
- RRETURN(PCRE_ERROR_INTERNAL);
- }
- }
-
- /* Match extended Unicode sequences. We will get here only if the
- support is in the binary; otherwise a compile-time error occurs. */
-
- else if (ctype == OP_EXTUNI)
- {
- for (fi = min;; fi++)
- {
- RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM41);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
- GETCHARINCTEST(c, eptr);
- prop_category = _pcre_ucp_findprop(c, &prop_chartype, &prop_script);
- if (prop_category == ucp_M) RRETURN(MATCH_NOMATCH);
- while (eptr < md->end_subject)
- {
- int len = 1;
- if (!utf8) c = *eptr; else
- {
- GETCHARLEN(c, eptr, len);
- }
- prop_category = _pcre_ucp_findprop(c, &prop_chartype, &prop_script);
- if (prop_category != ucp_M) break;
- eptr += len;
- }
- }
- }
-
- else
-#endif /* SUPPORT_UCP */
-
-#ifdef SUPPORT_UTF8
- /* UTF-8 mode */
- if (utf8)
- {
- for (fi = min;; fi++)
- {
- RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM42);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max || eptr >= md->end_subject ||
- (ctype == OP_ANY && IS_NEWLINE(eptr)))
- RRETURN(MATCH_NOMATCH);
-
- GETCHARINC(c, eptr);
- switch(ctype)
- {
- case OP_ANY: /* This is the non-NL case */
- case OP_ALLANY:
- case OP_ANYBYTE:
- break;
-
- case OP_ANYNL:
- switch(c)
- {
- default: RRETURN(MATCH_NOMATCH);
- case 0x000d:
- if (eptr < md->end_subject && *eptr == 0x0a) eptr++;
- break;
- case 0x000a:
- break;
-
- case 0x000b:
- case 0x000c:
- case 0x0085:
- case 0x2028:
- case 0x2029:
- if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
- break;
- }
- break;
-
- case OP_NOT_HSPACE:
- switch(c)
- {
- default: break;
- case 0x09: /* HT */
- case 0x20: /* SPACE */
- case 0xa0: /* NBSP */
- case 0x1680: /* OGHAM SPACE MARK */
- case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */
- case 0x2000: /* EN QUAD */
- case 0x2001: /* EM QUAD */
- case 0x2002: /* EN SPACE */
- case 0x2003: /* EM SPACE */
- case 0x2004: /* THREE-PER-EM SPACE */
- case 0x2005: /* FOUR-PER-EM SPACE */
- case 0x2006: /* SIX-PER-EM SPACE */
- case 0x2007: /* FIGURE SPACE */
- case 0x2008: /* PUNCTUATION SPACE */
- case 0x2009: /* THIN SPACE */
- case 0x200A: /* HAIR SPACE */
- case 0x202f: /* NARROW NO-BREAK SPACE */
- case 0x205f: /* MEDIUM MATHEMATICAL SPACE */
- case 0x3000: /* IDEOGRAPHIC SPACE */
- RRETURN(MATCH_NOMATCH);
- }
- break;
-
- case OP_HSPACE:
- switch(c)
- {
- default: RRETURN(MATCH_NOMATCH);
- case 0x09: /* HT */
- case 0x20: /* SPACE */
- case 0xa0: /* NBSP */
- case 0x1680: /* OGHAM SPACE MARK */
- case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */
- case 0x2000: /* EN QUAD */
- case 0x2001: /* EM QUAD */
- case 0x2002: /* EN SPACE */
- case 0x2003: /* EM SPACE */
- case 0x2004: /* THREE-PER-EM SPACE */
- case 0x2005: /* FOUR-PER-EM SPACE */
- case 0x2006: /* SIX-PER-EM SPACE */
- case 0x2007: /* FIGURE SPACE */
- case 0x2008: /* PUNCTUATION SPACE */
- case 0x2009: /* THIN SPACE */
- case 0x200A: /* HAIR SPACE */
- case 0x202f: /* NARROW NO-BREAK SPACE */
- case 0x205f: /* MEDIUM MATHEMATICAL SPACE */
- case 0x3000: /* IDEOGRAPHIC SPACE */
- break;
- }
- break;
-
- case OP_NOT_VSPACE:
- switch(c)
- {
- default: break;
- case 0x0a: /* LF */
- case 0x0b: /* VT */
- case 0x0c: /* FF */
- case 0x0d: /* CR */
- case 0x85: /* NEL */
- case 0x2028: /* LINE SEPARATOR */
- case 0x2029: /* PARAGRAPH SEPARATOR */
- RRETURN(MATCH_NOMATCH);
- }
- break;
-
- case OP_VSPACE:
- switch(c)
- {
- default: RRETURN(MATCH_NOMATCH);
- case 0x0a: /* LF */
- case 0x0b: /* VT */
- case 0x0c: /* FF */
- case 0x0d: /* CR */
- case 0x85: /* NEL */
- case 0x2028: /* LINE SEPARATOR */
- case 0x2029: /* PARAGRAPH SEPARATOR */
- break;
- }
- break;
-
- case OP_NOT_DIGIT:
- if (c < 256 && (md->ctypes[c] & ctype_digit) != 0)
- RRETURN(MATCH_NOMATCH);
- break;
-
- case OP_DIGIT:
- if (c >= 256 || (md->ctypes[c] & ctype_digit) == 0)
- RRETURN(MATCH_NOMATCH);
- break;
-
- case OP_NOT_WHITESPACE:
- if (c < 256 && (md->ctypes[c] & ctype_space) != 0)
- RRETURN(MATCH_NOMATCH);
- break;
-
- case OP_WHITESPACE:
- if (c >= 256 || (md->ctypes[c] & ctype_space) == 0)
- RRETURN(MATCH_NOMATCH);
- break;
-
- case OP_NOT_WORDCHAR:
- if (c < 256 && (md->ctypes[c] & ctype_word) != 0)
- RRETURN(MATCH_NOMATCH);
- break;
-
- case OP_WORDCHAR:
- if (c >= 256 || (md->ctypes[c] & ctype_word) == 0)
- RRETURN(MATCH_NOMATCH);
- break;
-
- default:
- RRETURN(PCRE_ERROR_INTERNAL);
- }
- }
- }
- else
-#endif
- /* Not UTF-8 mode */
- {
- for (fi = min;; fi++)
- {
- RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM43);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max || eptr >= md->end_subject ||
- (ctype == OP_ANY && IS_NEWLINE(eptr)))
- RRETURN(MATCH_NOMATCH);
-
- c = *eptr++;
- switch(ctype)
- {
- case OP_ANY: /* This is the non-NL case */
- case OP_ALLANY:
- case OP_ANYBYTE:
- break;
-
- case OP_ANYNL:
- switch(c)
- {
- default: RRETURN(MATCH_NOMATCH);
- case 0x000d:
- if (eptr < md->end_subject && *eptr == 0x0a) eptr++;
- break;
-
- case 0x000a:
- break;
-
- case 0x000b:
- case 0x000c:
- case 0x0085:
- if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
- break;
- }
- break;
-
- case OP_NOT_HSPACE:
- switch(c)
- {
- default: break;
- case 0x09: /* HT */
- case 0x20: /* SPACE */
- case 0xa0: /* NBSP */
- RRETURN(MATCH_NOMATCH);
- }
- break;
-
- case OP_HSPACE:
- switch(c)
- {
- default: RRETURN(MATCH_NOMATCH);
- case 0x09: /* HT */
- case 0x20: /* SPACE */
- case 0xa0: /* NBSP */
- break;
- }
- break;
-
- case OP_NOT_VSPACE:
- switch(c)
- {
- default: break;
- case 0x0a: /* LF */
- case 0x0b: /* VT */
- case 0x0c: /* FF */
- case 0x0d: /* CR */
- case 0x85: /* NEL */
- RRETURN(MATCH_NOMATCH);
- }
- break;
-
- case OP_VSPACE:
- switch(c)
- {
- default: RRETURN(MATCH_NOMATCH);
- case 0x0a: /* LF */
- case 0x0b: /* VT */
- case 0x0c: /* FF */
- case 0x0d: /* CR */
- case 0x85: /* NEL */
- break;
- }
- break;
-
- case OP_NOT_DIGIT:
- if ((md->ctypes[c] & ctype_digit) != 0) RRETURN(MATCH_NOMATCH);
- break;
-
- case OP_DIGIT:
- if ((md->ctypes[c] & ctype_digit) == 0) RRETURN(MATCH_NOMATCH);
- break;
-
- case OP_NOT_WHITESPACE:
- if ((md->ctypes[c] & ctype_space) != 0) RRETURN(MATCH_NOMATCH);
- break;
-
- case OP_WHITESPACE:
- if ((md->ctypes[c] & ctype_space) == 0) RRETURN(MATCH_NOMATCH);
- break;
-
- case OP_NOT_WORDCHAR:
- if ((md->ctypes[c] & ctype_word) != 0) RRETURN(MATCH_NOMATCH);
- break;
-
- case OP_WORDCHAR:
- if ((md->ctypes[c] & ctype_word) == 0) RRETURN(MATCH_NOMATCH);
- break;
-
- default:
- RRETURN(PCRE_ERROR_INTERNAL);
- }
- }
- }
- /* Control never gets here */
- }
-
- /* If maximizing, it is worth using inline code for speed, doing the type
- test once at the start (i.e. keep it out of the loop). Again, keep the
- UTF-8 and UCP stuff separate. */
-
- else
- {
- pp = eptr; /* Remember where we started */
-
-#ifdef SUPPORT_UCP
- if (prop_type >= 0)
- {
- switch(prop_type)
- {
- case PT_ANY:
- for (i = min; i < max; i++)
- {
- int len = 1;
- if (eptr >= md->end_subject) break;
- GETCHARLEN(c, eptr, len);
- if (prop_fail_result) break;
- eptr+= len;
- }
- break;
-
- case PT_LAMP:
- for (i = min; i < max; i++)
- {
- int len = 1;
- if (eptr >= md->end_subject) break;
- GETCHARLEN(c, eptr, len);
- prop_category = _pcre_ucp_findprop(c, &prop_chartype, &prop_script);
- if ((prop_chartype == ucp_Lu ||
- prop_chartype == ucp_Ll ||
- prop_chartype == ucp_Lt) == prop_fail_result)
- break;
- eptr+= len;
- }
- break;
-
- case PT_GC:
- for (i = min; i < max; i++)
- {
- int len = 1;
- if (eptr >= md->end_subject) break;
- GETCHARLEN(c, eptr, len);
- prop_category = _pcre_ucp_findprop(c, &prop_chartype, &prop_script);
- if ((prop_category == prop_value) == prop_fail_result)
- break;
- eptr+= len;
- }
- break;
-
- case PT_PC:
- for (i = min; i < max; i++)
- {
- int len = 1;
- if (eptr >= md->end_subject) break;
- GETCHARLEN(c, eptr, len);
- prop_category = _pcre_ucp_findprop(c, &prop_chartype, &prop_script);
- if ((prop_chartype == prop_value) == prop_fail_result)
- break;
- eptr+= len;
- }
- break;
-
- case PT_SC:
- for (i = min; i < max; i++)
- {
- int len = 1;
- if (eptr >= md->end_subject) break;
- GETCHARLEN(c, eptr, len);
- prop_category = _pcre_ucp_findprop(c, &prop_chartype, &prop_script);
- if ((prop_script == prop_value) == prop_fail_result)
- break;
- eptr+= len;
- }
- break;
- }
-
- /* eptr is now past the end of the maximum run */
-
- if (possessive) continue;
- for(;;)
- {
- RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM44);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (eptr-- == pp) break; /* Stop if tried at original pos */
- if (utf8) BACKCHAR(eptr);
- }
- }
-
- /* Match extended Unicode sequences. We will get here only if the
- support is in the binary; otherwise a compile-time error occurs. */
-
- else if (ctype == OP_EXTUNI)
- {
- for (i = min; i < max; i++)
- {
- if (eptr >= md->end_subject) break;
- GETCHARINCTEST(c, eptr);
- prop_category = _pcre_ucp_findprop(c, &prop_chartype, &prop_script);
- if (prop_category == ucp_M) break;
- while (eptr < md->end_subject)
- {
- int len = 1;
- if (!utf8) c = *eptr; else
- {
- GETCHARLEN(c, eptr, len);
- }
- prop_category = _pcre_ucp_findprop(c, &prop_chartype, &prop_script);
- if (prop_category != ucp_M) break;
- eptr += len;
- }
- }
-
- /* eptr is now past the end of the maximum run */
-
- if (possessive) continue;
- for(;;)
- {
- RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM45);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (eptr-- == pp) break; /* Stop if tried at original pos */
- for (;;) /* Move back over one extended */
- {
- int len = 1;
- if (!utf8) c = *eptr; else
- {
- BACKCHAR(eptr);
- GETCHARLEN(c, eptr, len);
- }
- prop_category = _pcre_ucp_findprop(c, &prop_chartype, &prop_script);
- if (prop_category != ucp_M) break;
- eptr--;
- }
- }
- }
-
- else
-#endif /* SUPPORT_UCP */
-
-#ifdef SUPPORT_UTF8
- /* UTF-8 mode */
-
- if (utf8)
- {
- switch(ctype)
- {
- case OP_ANY:
- if (max < INT_MAX)
- {
- for (i = min; i < max; i++)
- {
- if (eptr >= md->end_subject || IS_NEWLINE(eptr)) break;
- eptr++;
- while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;
- }
- }
-
- /* Handle unlimited UTF-8 repeat */
-
- else
- {
- for (i = min; i < max; i++)
- {
- if (eptr >= md->end_subject || IS_NEWLINE(eptr)) break;
- eptr++;
- while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;
- }
- }
- break;
-
- case OP_ALLANY:
- if (max < INT_MAX)
- {
- for (i = min; i < max; i++)
- {
- if (eptr >= md->end_subject) break;
- eptr++;
- while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;
- }
- }
- else eptr = md->end_subject; /* Unlimited UTF-8 repeat */
- break;
-
- /* The byte case is the same as non-UTF8 */
-
- case OP_ANYBYTE:
- c = max - min;
- if (c > (unsigned int)(md->end_subject - eptr))
- c = md->end_subject - eptr;
- eptr += c;
- break;
-
- case OP_ANYNL:
- for (i = min; i < max; i++)
- {
- int len = 1;
- if (eptr >= md->end_subject) break;
- GETCHARLEN(c, eptr, len);
- if (c == 0x000d)
- {
- if (++eptr >= md->end_subject) break;
- if (*eptr == 0x000a) eptr++;
- }
- else
- {
- if (c != 0x000a &&
- (md->bsr_anycrlf ||
- (c != 0x000b && c != 0x000c &&
- c != 0x0085 && c != 0x2028 && c != 0x2029)))
- break;
- eptr += len;
- }
- }
- break;
-
- case OP_NOT_HSPACE:
- case OP_HSPACE:
- for (i = min; i < max; i++)
- {
- BOOL gotspace;
- int len = 1;
- if (eptr >= md->end_subject) break;
- GETCHARLEN(c, eptr, len);
- switch(c)
- {
- default: gotspace = FALSE; break;
- case 0x09: /* HT */
- case 0x20: /* SPACE */
- case 0xa0: /* NBSP */
- case 0x1680: /* OGHAM SPACE MARK */
- case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */
- case 0x2000: /* EN QUAD */
- case 0x2001: /* EM QUAD */
- case 0x2002: /* EN SPACE */
- case 0x2003: /* EM SPACE */
- case 0x2004: /* THREE-PER-EM SPACE */
- case 0x2005: /* FOUR-PER-EM SPACE */
- case 0x2006: /* SIX-PER-EM SPACE */
- case 0x2007: /* FIGURE SPACE */
- case 0x2008: /* PUNCTUATION SPACE */
- case 0x2009: /* THIN SPACE */
- case 0x200A: /* HAIR SPACE */
- case 0x202f: /* NARROW NO-BREAK SPACE */
- case 0x205f: /* MEDIUM MATHEMATICAL SPACE */
- case 0x3000: /* IDEOGRAPHIC SPACE */
- gotspace = TRUE;
- break;
- }
- if (gotspace == (ctype == OP_NOT_HSPACE)) break;
- eptr += len;
- }
- break;
-
- case OP_NOT_VSPACE:
- case OP_VSPACE:
- for (i = min; i < max; i++)
- {
- BOOL gotspace;
- int len = 1;
- if (eptr >= md->end_subject) break;
- GETCHARLEN(c, eptr, len);
- switch(c)
- {
- default: gotspace = FALSE; break;
- case 0x0a: /* LF */
- case 0x0b: /* VT */
- case 0x0c: /* FF */
- case 0x0d: /* CR */
- case 0x85: /* NEL */
- case 0x2028: /* LINE SEPARATOR */
- case 0x2029: /* PARAGRAPH SEPARATOR */
- gotspace = TRUE;
- break;
- }
- if (gotspace == (ctype == OP_NOT_VSPACE)) break;
- eptr += len;
- }
- break;
-
- case OP_NOT_DIGIT:
- for (i = min; i < max; i++)
- {
- int len = 1;
- if (eptr >= md->end_subject) break;
- GETCHARLEN(c, eptr, len);
- if (c < 256 && (md->ctypes[c] & ctype_digit) != 0) break;
- eptr+= len;
- }
- break;
-
- case OP_DIGIT:
- for (i = min; i < max; i++)
- {
- int len = 1;
- if (eptr >= md->end_subject) break;
- GETCHARLEN(c, eptr, len);
- if (c >= 256 ||(md->ctypes[c] & ctype_digit) == 0) break;
- eptr+= len;
- }
- break;
-
- case OP_NOT_WHITESPACE:
- for (i = min; i < max; i++)
- {
- int len = 1;
- if (eptr >= md->end_subject) break;
- GETCHARLEN(c, eptr, len);
- if (c < 256 && (md->ctypes[c] & ctype_space) != 0) break;
- eptr+= len;
- }
- break;
-
- case OP_WHITESPACE:
- for (i = min; i < max; i++)
- {
- int len = 1;
- if (eptr >= md->end_subject) break;
- GETCHARLEN(c, eptr, len);
- if (c >= 256 ||(md->ctypes[c] & ctype_space) == 0) break;
- eptr+= len;
- }
- break;
-
- case OP_NOT_WORDCHAR:
- for (i = min; i < max; i++)
- {
- int len = 1;
- if (eptr >= md->end_subject) break;
- GETCHARLEN(c, eptr, len);
- if (c < 256 && (md->ctypes[c] & ctype_word) != 0) break;
- eptr+= len;
- }
- break;
-
- case OP_WORDCHAR:
- for (i = min; i < max; i++)
- {
- int len = 1;
- if (eptr >= md->end_subject) break;
- GETCHARLEN(c, eptr, len);
- if (c >= 256 || (md->ctypes[c] & ctype_word) == 0) break;
- eptr+= len;
- }
- break;
-
- default:
- RRETURN(PCRE_ERROR_INTERNAL);
- }
-
- /* eptr is now past the end of the maximum run */
-
- if (possessive) continue;
- for(;;)
- {
- RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM46);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (eptr-- == pp) break; /* Stop if tried at original pos */
- BACKCHAR(eptr);
- }
- }
- else
-#endif /* SUPPORT_UTF8 */
-
- /* Not UTF-8 mode */
- {
- switch(ctype)
- {
- case OP_ANY:
- for (i = min; i < max; i++)
- {
- if (eptr >= md->end_subject || IS_NEWLINE(eptr)) break;
- eptr++;
- }
- break;
-
- case OP_ALLANY:
- case OP_ANYBYTE:
- c = max - min;
- if (c > (unsigned int)(md->end_subject - eptr))
- c = md->end_subject - eptr;
- eptr += c;
- break;
-
- case OP_ANYNL:
- for (i = min; i < max; i++)
- {
- if (eptr >= md->end_subject) break;
- c = *eptr;
- if (c == 0x000d)
- {
- if (++eptr >= md->end_subject) break;
- if (*eptr == 0x000a) eptr++;
- }
- else
- {
- if (c != 0x000a &&
- (md->bsr_anycrlf ||
- (c != 0x000b && c != 0x000c && c != 0x0085)))
- break;
- eptr++;
- }
- }
- break;
-
- case OP_NOT_HSPACE:
- for (i = min; i < max; i++)
- {
- if (eptr >= md->end_subject) break;
- c = *eptr;
- if (c == 0x09 || c == 0x20 || c == 0xa0) break;
- eptr++;
- }
- break;
-
- case OP_HSPACE:
- for (i = min; i < max; i++)
- {
- if (eptr >= md->end_subject) break;
- c = *eptr;
- if (c != 0x09 && c != 0x20 && c != 0xa0) break;
- eptr++;
- }
- break;
-
- case OP_NOT_VSPACE:
- for (i = min; i < max; i++)
- {
- if (eptr >= md->end_subject) break;
- c = *eptr;
- if (c == 0x0a || c == 0x0b || c == 0x0c || c == 0x0d || c == 0x85)
- break;
- eptr++;
- }
- break;
-
- case OP_VSPACE:
- for (i = min; i < max; i++)
- {
- if (eptr >= md->end_subject) break;
- c = *eptr;
- if (c != 0x0a && c != 0x0b && c != 0x0c && c != 0x0d && c != 0x85)
- break;
- eptr++;
- }
- break;
-
- case OP_NOT_DIGIT:
- for (i = min; i < max; i++)
- {
- if (eptr >= md->end_subject || (md->ctypes[*eptr] & ctype_digit) != 0)
- break;
- eptr++;
- }
- break;
-
- case OP_DIGIT:
- for (i = min; i < max; i++)
- {
- if (eptr >= md->end_subject || (md->ctypes[*eptr] & ctype_digit) == 0)
- break;
- eptr++;
- }
- break;
-
- case OP_NOT_WHITESPACE:
- for (i = min; i < max; i++)
- {
- if (eptr >= md->end_subject || (md->ctypes[*eptr] & ctype_space) != 0)
- break;
- eptr++;
- }
- break;
-
- case OP_WHITESPACE:
- for (i = min; i < max; i++)
- {
- if (eptr >= md->end_subject || (md->ctypes[*eptr] & ctype_space) == 0)
- break;
- eptr++;
- }
- break;
-
- case OP_NOT_WORDCHAR:
- for (i = min; i < max; i++)
- {
- if (eptr >= md->end_subject || (md->ctypes[*eptr] & ctype_word) != 0)
- break;
- eptr++;
- }
- break;
-
- case OP_WORDCHAR:
- for (i = min; i < max; i++)
- {
- if (eptr >= md->end_subject || (md->ctypes[*eptr] & ctype_word) == 0)
- break;
- eptr++;
- }
- break;
-
- default:
- RRETURN(PCRE_ERROR_INTERNAL);
- }
-
- /* eptr is now past the end of the maximum run */
-
- if (possessive) continue;
- while (eptr >= pp)
- {
- RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM47);
- eptr--;
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- }
- }
-
- /* Get here if we can't make it match with any permitted repetitions */
-
- RRETURN(MATCH_NOMATCH);
- }
- /* Control never gets here */
-
- /* There's been some horrible disaster. Arrival here can only mean there is
- something seriously wrong in the code above or the OP_xxx definitions. */
-
- default:
- DPRINTF(("Unknown opcode %d\n", *ecode));
- RRETURN(PCRE_ERROR_UNKNOWN_OPCODE);
- }
-
- /* Do not stick any code in here without much thought; it is assumed
- that "continue" in the code above comes out to here to repeat the main
- loop. */
-
- } /* End of main loop */
-/* Control never reaches here */
-
-
-/* When compiling to use the heap rather than the stack for recursive calls to
-match(), the RRETURN() macro jumps here. The number that is saved in
-frame->Xwhere indicates which label we actually want to return to. */
-
-#ifdef NO_RECURSE
-#define LBL(val) case val: goto L_RM##val;
-HEAP_RETURN:
-switch (frame->Xwhere)
- {
- LBL( 1) LBL( 2) LBL( 3) LBL( 4) LBL( 5) LBL( 6) LBL( 7) LBL( 8)
- LBL( 9) LBL(10) LBL(11) LBL(12) LBL(13) LBL(14) LBL(15) LBL(17)
- LBL(19) LBL(24) LBL(25) LBL(26) LBL(27) LBL(29) LBL(31) LBL(33)
- LBL(35) LBL(43) LBL(47) LBL(48) LBL(49) LBL(50) LBL(51) LBL(52)
- LBL(53) LBL(54)
-#ifdef SUPPORT_UTF8
- LBL(16) LBL(18) LBL(20) LBL(21) LBL(22) LBL(23) LBL(28) LBL(30)
- LBL(32) LBL(34) LBL(42) LBL(46)
-#ifdef SUPPORT_UCP
- LBL(36) LBL(37) LBL(38) LBL(39) LBL(40) LBL(41) LBL(44) LBL(45)
-#endif /* SUPPORT_UCP */
-#endif /* SUPPORT_UTF8 */
- default:
- DPRINTF(("jump error in pcre match: label %d non-existent\n", frame->Xwhere));
- return PCRE_ERROR_INTERNAL;
- }
-#undef LBL
-#endif /* NO_RECURSE */
-}
-
-
-/***************************************************************************
-****************************************************************************
- RECURSION IN THE match() FUNCTION
-
-Undefine all the macros that were defined above to handle this. */
-
-#ifdef NO_RECURSE
-#undef eptr
-#undef ecode
-#undef mstart
-#undef offset_top
-#undef ims
-#undef eptrb
-#undef flags
-
-#undef callpat
-#undef charptr
-#undef data
-#undef next
-#undef pp
-#undef prev
-#undef saved_eptr
-
-#undef new_recursive
-
-#undef cur_is_word
-#undef condition
-#undef prev_is_word
-
-#undef original_ims
-
-#undef ctype
-#undef length
-#undef max
-#undef min
-#undef number
-#undef offset
-#undef op
-#undef save_capture_last
-#undef save_offset1
-#undef save_offset2
-#undef save_offset3
-#undef stacksave
-
-#undef newptrb
-
-#endif
-
-/* These two are defined as macros in both cases */
-
-#undef fc
-#undef fi
-
-/***************************************************************************
-***************************************************************************/
-
-
-
-/*************************************************
-* Execute a Regular Expression *
-*************************************************/
-
-/* This function applies a compiled re to a subject string and picks out
-portions of the string if it matches. Two elements in the vector are set for
-each substring: the offsets to the start and end of the substring.
-
-Arguments:
- argument_re points to the compiled expression
- extra_data points to extra data or is NULL
- subject points to the subject string
- length length of subject string (may contain binary zeros)
- start_offset where to start in the subject string
- options option bits
- offsets points to a vector of ints to be filled in with offsets
- offsetcount the number of elements in the vector
-
-Returns: > 0 => success; value is the number of elements filled in
- = 0 => success, but offsets is not big enough
- -1 => failed to match
- < -1 => some kind of unexpected problem
-*/
-
-PCRE_EXP_DEFN int
-pcre_exec(const pcre *argument_re, const pcre_extra *extra_data,
- PCRE_SPTR subject, int length, int start_offset, int options, int *offsets,
- int offsetcount)
-{
-int rc, resetcount, ocount;
-int first_byte = -1;
-int req_byte = -1;
-int req_byte2 = -1;
-int newline;
-unsigned long int ims;
-BOOL using_temporary_offsets = FALSE;
-BOOL anchored;
-BOOL startline;
-BOOL firstline;
-BOOL first_byte_caseless = FALSE;
-BOOL req_byte_caseless = FALSE;
-BOOL utf8;
-match_data match_block;
-match_data *md = &match_block;
-const uschar *tables;
-const uschar *start_bits = NULL;
-USPTR start_match = (USPTR)subject + start_offset;
-USPTR end_subject;
-USPTR req_byte_ptr = start_match - 1;
-
-pcre_study_data internal_study;
-const pcre_study_data *study;
-
-real_pcre internal_re;
-const real_pcre *external_re = (const real_pcre *)argument_re;
-const real_pcre *re = external_re;
-
-/* Plausibility checks */
-
-if ((options & ~PUBLIC_EXEC_OPTIONS) != 0) return PCRE_ERROR_BADOPTION;
-if (re == NULL || subject == NULL ||
- (offsets == NULL && offsetcount > 0)) return PCRE_ERROR_NULL;
-if (offsetcount < 0) return PCRE_ERROR_BADCOUNT;
-
-/* Fish out the optional data from the extra_data structure, first setting
-the default values. */
-
-study = NULL;
-md->match_limit = MATCH_LIMIT;
-md->match_limit_recursion = MATCH_LIMIT_RECURSION;
-md->callout_data = NULL;
-
-/* The table pointer is always in native byte order. */
-
-tables = external_re->tables;
-
-if (extra_data != NULL)
- {
- register unsigned int flags = extra_data->flags;
- if ((flags & PCRE_EXTRA_STUDY_DATA) != 0)
- study = (const pcre_study_data *)extra_data->study_data;
- if ((flags & PCRE_EXTRA_MATCH_LIMIT) != 0)
- md->match_limit = extra_data->match_limit;
- if ((flags & PCRE_EXTRA_MATCH_LIMIT_RECURSION) != 0)
- md->match_limit_recursion = extra_data->match_limit_recursion;
- if ((flags & PCRE_EXTRA_CALLOUT_DATA) != 0)
- md->callout_data = extra_data->callout_data;
- if ((flags & PCRE_EXTRA_TABLES) != 0) tables = extra_data->tables;
- }
-
-/* If the exec call supplied NULL for tables, use the inbuilt ones. This
-is a feature that makes it possible to save compiled regex and re-use them
-in other programs later. */
-
-if (tables == NULL) tables = _pcre_default_tables;
-
-/* Check that the first field in the block is the magic number. If it is not,
-test for a regex that was compiled on a host of opposite endianness. If this is
-the case, flipped values are put in internal_re and internal_study if there was
-study data too. */
-
-if (re->magic_number != MAGIC_NUMBER)
- {
- re = _pcre_try_flipped(re, &internal_re, study, &internal_study);
- if (re == NULL) return PCRE_ERROR_BADMAGIC;
- if (study != NULL) study = &internal_study;
- }
-
-/* Set up other data */
-
-anchored = ((re->options | options) & PCRE_ANCHORED) != 0;
-startline = (re->flags & PCRE_STARTLINE) != 0;
-firstline = (re->options & PCRE_FIRSTLINE) != 0;
-
-/* The code starts after the real_pcre block and the capture name table. */
-
-md->start_code = (const uschar *)external_re + re->name_table_offset +
- re->name_count * re->name_entry_size;
-
-md->start_subject = (USPTR)subject;
-md->start_offset = start_offset;
-md->end_subject = md->start_subject + length;
-end_subject = md->end_subject;
-
-md->endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0;
-utf8 = md->utf8 = (re->options & PCRE_UTF8) != 0;
-md->jscript_compat = (re->options & PCRE_JAVASCRIPT_COMPAT) != 0;
-
-md->notbol = (options & PCRE_NOTBOL) != 0;
-md->noteol = (options & PCRE_NOTEOL) != 0;
-md->notempty = (options & PCRE_NOTEMPTY) != 0;
-md->partial = (options & PCRE_PARTIAL) != 0;
-md->hitend = FALSE;
-
-md->recursive = NULL; /* No recursion at top level */
-
-md->lcc = tables + lcc_offset;
-md->ctypes = tables + ctypes_offset;
-
-/* Handle different \R options. */
-
-switch (options & (PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE))
- {
- case 0:
- if ((re->options & (PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE)) != 0)
- md->bsr_anycrlf = (re->options & PCRE_BSR_ANYCRLF) != 0;
- else
-#ifdef BSR_ANYCRLF
- md->bsr_anycrlf = TRUE;
-#else
- md->bsr_anycrlf = FALSE;
-#endif
- break;
-
- case PCRE_BSR_ANYCRLF:
- md->bsr_anycrlf = TRUE;
- break;
-
- case PCRE_BSR_UNICODE:
- md->bsr_anycrlf = FALSE;
- break;
-
- default: return PCRE_ERROR_BADNEWLINE;
- }
-
-/* Handle different types of newline. The three bits give eight cases. If
-nothing is set at run time, whatever was used at compile time applies. */
-
-switch ((((options & PCRE_NEWLINE_BITS) == 0)? re->options :
- (pcre_uint32)options) & PCRE_NEWLINE_BITS)
- {
- case 0: newline = NEWLINE; break; /* Compile-time default */
- case PCRE_NEWLINE_CR: newline = '\r'; break;
- case PCRE_NEWLINE_LF: newline = '\n'; break;
- case PCRE_NEWLINE_CR+
- PCRE_NEWLINE_LF: newline = ('\r' << 8) | '\n'; break;
- case PCRE_NEWLINE_ANY: newline = -1; break;
- case PCRE_NEWLINE_ANYCRLF: newline = -2; break;
- default: return PCRE_ERROR_BADNEWLINE;
- }
-
-if (newline == -2)
- {
- md->nltype = NLTYPE_ANYCRLF;
- }
-else if (newline < 0)
- {
- md->nltype = NLTYPE_ANY;
- }
-else
- {
- md->nltype = NLTYPE_FIXED;
- if (newline > 255)
- {
- md->nllen = 2;
- md->nl[0] = (newline >> 8) & 255;
- md->nl[1] = newline & 255;
- }
- else
- {
- md->nllen = 1;
- md->nl[0] = newline;
- }
- }
-
-/* Partial matching is supported only for a restricted set of regexes at the
-moment. */
-
-if (md->partial && (re->flags & PCRE_NOPARTIAL) != 0)
- return PCRE_ERROR_BADPARTIAL;
-
-/* Check a UTF-8 string if required. Unfortunately there's no way of passing
-back the character offset. */
-
-#ifdef SUPPORT_UTF8
-if (utf8 && (options & PCRE_NO_UTF8_CHECK) == 0)
- {
- if (_pcre_valid_utf8((uschar *)subject, length) >= 0)
- return PCRE_ERROR_BADUTF8;
- if (start_offset > 0 && start_offset < length)
- {
- int tb = ((uschar *)subject)[start_offset];
- if (tb > 127)
- {
- tb &= 0xc0;
- if (tb != 0 && tb != 0xc0) return PCRE_ERROR_BADUTF8_OFFSET;
- }
- }
- }
-#endif
-
-/* The ims options can vary during the matching as a result of the presence
-of (?ims) items in the pattern. They are kept in a local variable so that
-restoring at the exit of a group is easy. */
-
-ims = re->options & (PCRE_CASELESS|PCRE_MULTILINE|PCRE_DOTALL);
-
-/* If the expression has got more back references than the offsets supplied can
-hold, we get a temporary chunk of working store to use during the matching.
-Otherwise, we can use the vector supplied, rounding down its size to a multiple
-of 3. */
-
-ocount = offsetcount - (offsetcount % 3);
-
-if (re->top_backref > 0 && re->top_backref >= ocount/3)
- {
- ocount = re->top_backref * 3 + 3;
- md->offset_vector = (int *)(pcre_malloc)(ocount * sizeof(int));
- if (md->offset_vector == NULL) return PCRE_ERROR_NOMEMORY;
- using_temporary_offsets = TRUE;
- DPRINTF(("Got memory to hold back references\n"));
- }
-else md->offset_vector = offsets;
-
-md->offset_end = ocount;
-md->offset_max = (2*ocount)/3;
-md->offset_overflow = FALSE;
-md->capture_last = -1;
-
-/* Compute the minimum number of offsets that we need to reset each time. Doing
-this makes a huge difference to execution time when there aren't many brackets
-in the pattern. */
-
-resetcount = 2 + re->top_bracket * 2;
-if (resetcount > offsetcount) resetcount = ocount;
-
-/* Reset the working variable associated with each extraction. These should
-never be used unless previously set, but they get saved and restored, and so we
-initialize them to avoid reading uninitialized locations. */
-
-if (md->offset_vector != NULL)
- {
- register int *iptr = md->offset_vector + ocount;
- register int *iend = iptr - resetcount/2 + 1;
- while (--iptr >= iend) *iptr = -1;
- }
-
-/* Set up the first character to match, if available. The first_byte value is
-never set for an anchored regular expression, but the anchoring may be forced
-at run time, so we have to test for anchoring. The first char may be unset for
-an unanchored pattern, of course. If there's no first char and the pattern was
-studied, there may be a bitmap of possible first characters. */
-
-if (!anchored)
- {
- if ((re->flags & PCRE_FIRSTSET) != 0)
- {
- first_byte = re->first_byte & 255;
- if ((first_byte_caseless = ((re->first_byte & REQ_CASELESS) != 0)) == TRUE)
- first_byte = md->lcc[first_byte];
- }
- else
- if (!startline && study != NULL &&
- (study->options & PCRE_STUDY_MAPPED) != 0)
- start_bits = study->start_bits;
- }
-
-/* For anchored or unanchored matches, there may be a "last known required
-character" set. */
-
-if ((re->flags & PCRE_REQCHSET) != 0)
- {
- req_byte = re->req_byte & 255;
- req_byte_caseless = (re->req_byte & REQ_CASELESS) != 0;
- req_byte2 = (tables + fcc_offset)[req_byte]; /* case flipped */
- }
-
-
-/* ==========================================================================*/
-
-/* Loop for handling unanchored repeated matching attempts; for anchored regexs
-the loop runs just once. */
-
-for(;;)
- {
- USPTR save_end_subject = end_subject;
- USPTR new_start_match;
-
- /* Reset the maximum number of extractions we might see. */
-
- if (md->offset_vector != NULL)
- {
- register int *iptr = md->offset_vector;
- register int *iend = iptr + resetcount;
- while (iptr < iend) *iptr++ = -1;
- }
-
- /* Advance to a unique first char if possible. If firstline is TRUE, the
- start of the match is constrained to the first line of a multiline string.
- That is, the match must be before or at the first newline. Implement this by
- temporarily adjusting end_subject so that we stop scanning at a newline. If
- the match fails at the newline, later code breaks this loop. */
-
- if (firstline)
- {
- USPTR t = start_match;
- while (t < md->end_subject && !IS_NEWLINE(t)) t++;
- end_subject = t;
- }
-
- /* Now test for a unique first byte */
-
- if (first_byte >= 0)
- {
- if (first_byte_caseless)
- while (start_match < end_subject &&
- md->lcc[*start_match] != first_byte)
- { NEXTCHAR(start_match); }
- else
- while (start_match < end_subject && *start_match != first_byte)
- { NEXTCHAR(start_match); }
- }
-
- /* Or to just after a linebreak for a multiline match if possible */
-
- else if (startline)
- {
- if (start_match > md->start_subject + start_offset)
- {
- while (start_match <= end_subject && !WAS_NEWLINE(start_match))
- { NEXTCHAR(start_match); }
-
- /* If we have just passed a CR and the newline option is ANY or ANYCRLF,
- and we are now at a LF, advance the match position by one more character.
- */
-
- if (start_match[-1] == '\r' &&
- (md->nltype == NLTYPE_ANY || md->nltype == NLTYPE_ANYCRLF) &&
- start_match < end_subject &&
- *start_match == '\n')
- start_match++;
- }
- }
-
- /* Or to a non-unique first char after study */
-
- else if (start_bits != NULL)
- {
- while (start_match < end_subject)
- {
- register unsigned int c = *start_match;
- if ((start_bits[c/8] & (1 << (c&7))) == 0)
- { NEXTCHAR(start_match); }
- else break;
- }
- }
-
- /* Restore fudged end_subject */
-
- end_subject = save_end_subject;
-
-#ifdef DEBUG /* Sigh. Some compilers never learn. */
- printf(">>>> Match against: ");
- pchars(start_match, end_subject - start_match, TRUE, md);
- printf("\n");
-#endif
-
- /* If req_byte is set, we know that that character must appear in the subject
- for the match to succeed. If the first character is set, req_byte must be
- later in the subject; otherwise the test starts at the match point. This
- optimization can save a huge amount of backtracking in patterns with nested
- unlimited repeats that aren't going to match. Writing separate code for
- cased/caseless versions makes it go faster, as does using an autoincrement
- and backing off on a match.
-
- HOWEVER: when the subject string is very, very long, searching to its end can
- take a long time, and give bad performance on quite ordinary patterns. This
- showed up when somebody was matching something like /^\d+C/ on a 32-megabyte
- string... so we don't do this when the string is sufficiently long.
-
- ALSO: this processing is disabled when partial matching is requested.
- */
-
- if (req_byte >= 0 &&
- end_subject - start_match < REQ_BYTE_MAX &&
- !md->partial)
- {
- register USPTR p = start_match + ((first_byte >= 0)? 1 : 0);
-
- /* We don't need to repeat the search if we haven't yet reached the
- place we found it at last time. */
-
- if (p > req_byte_ptr)
- {
- if (req_byte_caseless)
- {
- while (p < end_subject)
- {
- register int pp = *p++;
- if (pp == req_byte || pp == req_byte2) { p--; break; }
- }
- }
- else
- {
- while (p < end_subject)
- {
- if (*p++ == req_byte) { p--; break; }
- }
- }
-
- /* If we can't find the required character, break the matching loop,
- forcing a match failure. */
-
- if (p >= end_subject)
- {
- rc = MATCH_NOMATCH;
- break;
- }
-
- /* If we have found the required character, save the point where we
- found it, so that we don't search again next time round the loop if
- the start hasn't passed this character yet. */
-
- req_byte_ptr = p;
- }
- }
-
- /* OK, we can now run the match. */
-
- md->start_match_ptr = start_match;
- md->match_call_count = 0;
- rc = match(start_match, md->start_code, start_match, 2, md, ims, NULL, 0, 0);
-
- switch(rc)
- {
- /* NOMATCH and PRUNE advance by one character. THEN at this level acts
- exactly like PRUNE. */
-
- case MATCH_NOMATCH:
- case MATCH_PRUNE:
- case MATCH_THEN:
- new_start_match = start_match + 1;
-#ifdef SUPPORT_UTF8
- if (utf8)
- while(new_start_match < end_subject && (*new_start_match & 0xc0) == 0x80)
- new_start_match++;
-#endif
- break;
-
- /* SKIP passes back the next starting point explicitly. */
-
- case MATCH_SKIP:
- new_start_match = md->start_match_ptr;
- break;
-
- /* COMMIT disables the bumpalong, but otherwise behaves as NOMATCH. */
-
- case MATCH_COMMIT:
- rc = MATCH_NOMATCH;
- goto ENDLOOP;
-
- /* Any other return is some kind of error. */
-
- default:
- goto ENDLOOP;
- }
-
- /* Control reaches here for the various types of "no match at this point"
- result. Reset the code to MATCH_NOMATCH for subsequent checking. */
-
- rc = MATCH_NOMATCH;
-
- /* If PCRE_FIRSTLINE is set, the match must happen before or at the first
- newline in the subject (though it may continue over the newline). Therefore,
- if we have just failed to match, starting at a newline, do not continue. */
-
- if (firstline && IS_NEWLINE(start_match)) break;
-
- /* Advance to new matching position */
-
- start_match = new_start_match;
-
- /* Break the loop if the pattern is anchored or if we have passed the end of
- the subject. */
-
- if (anchored || start_match > end_subject) break;
-
- /* If we have just passed a CR and we are now at a LF, and the pattern does
- not contain any explicit matches for \r or \n, and the newline option is CRLF
- or ANY or ANYCRLF, advance the match position by one more character. */
-
- if (start_match[-1] == '\r' &&
- start_match < end_subject &&
- *start_match == '\n' &&
- (re->flags & PCRE_HASCRORLF) == 0 &&
- (md->nltype == NLTYPE_ANY ||
- md->nltype == NLTYPE_ANYCRLF ||
- md->nllen == 2))
- start_match++;
-
- } /* End of for(;;) "bumpalong" loop */
-
-/* ==========================================================================*/
-
-/* We reach here when rc is not MATCH_NOMATCH, or if one of the stopping
-conditions is true:
-
-(1) The pattern is anchored or the match was failed by (*COMMIT);
-
-(2) We are past the end of the subject;
-
-(3) PCRE_FIRSTLINE is set and we have failed to match at a newline, because
- this option requests that a match occur at or before the first newline in
- the subject.
-
-When we have a match and the offset vector is big enough to deal with any
-backreferences, captured substring offsets will already be set up. In the case
-where we had to get some local store to hold offsets for backreference
-processing, copy those that we can. In this case there need not be overflow if
-certain parts of the pattern were not used, even though there are more
-capturing parentheses than vector slots. */
-
-ENDLOOP:
-
-if (rc == MATCH_MATCH)
- {
- if (using_temporary_offsets)
- {
- if (offsetcount >= 4)
- {
- memcpy(offsets + 2, md->offset_vector + 2,
- (offsetcount - 2) * sizeof(int));
- DPRINTF(("Copied offsets from temporary memory\n"));
- }
- if (md->end_offset_top > offsetcount) md->offset_overflow = TRUE;
- DPRINTF(("Freeing temporary memory\n"));
- (pcre_free)(md->offset_vector);
- }
-
- /* Set the return code to the number of captured strings, or 0 if there are
- too many to fit into the vector. */
-
- rc = md->offset_overflow? 0 : md->end_offset_top/2;
-
- /* If there is space, set up the whole thing as substring 0. The value of
- md->start_match_ptr might be modified if \K was encountered on the success
- matching path. */
-
- if (offsetcount < 2) rc = 0; else
- {
- offsets[0] = md->start_match_ptr - md->start_subject;
- offsets[1] = md->end_match_ptr - md->start_subject;
- }
-
- DPRINTF((">>>> returning %d\n", rc));
- return rc;
- }
-
-/* Control gets here if there has been an error, or if the overall match
-attempt has failed at all permitted starting positions. */
-
-if (using_temporary_offsets)
- {
- DPRINTF(("Freeing temporary memory\n"));
- (pcre_free)(md->offset_vector);
- }
-
-if (rc != MATCH_NOMATCH)
- {
- DPRINTF((">>>> error: returning %d\n", rc));
- return rc;
- }
-else if (md->partial && md->hitend)
- {
- DPRINTF((">>>> returning PCRE_ERROR_PARTIAL\n"));
- return PCRE_ERROR_PARTIAL;
- }
-else
- {
- DPRINTF((">>>> returning PCRE_ERROR_NOMATCH\n"));
- return PCRE_ERROR_NOMATCH;
- }
-}
-
-/* End of pcre_exec.c */
diff --git a/crawl-ref/source/util/pcre/pcre_fullinfo.c b/crawl-ref/source/util/pcre/pcre_fullinfo.c
deleted file mode 100644
index 7b001c60b2..0000000000
--- a/crawl-ref/source/util/pcre/pcre_fullinfo.c
+++ /dev/null
@@ -1,165 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
- Written by Philip Hazel
- Copyright (c) 1997-2008 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-
-/* This module contains the external function pcre_fullinfo(), which returns
-information about a compiled pattern. */
-
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "pcre_internal.h"
-
-
-/*************************************************
-* Return info about compiled pattern *
-*************************************************/
-
-/* This is a newer "info" function which has an extensible interface so
-that additional items can be added compatibly.
-
-Arguments:
- argument_re points to compiled code
- extra_data points extra data, or NULL
- what what information is required
- where where to put the information
-
-Returns: 0 if data returned, negative on error
-*/
-
-PCRE_EXP_DEFN int
-pcre_fullinfo(const pcre *argument_re, const pcre_extra *extra_data, int what,
- void *where)
-{
-real_pcre internal_re;
-pcre_study_data internal_study;
-const real_pcre *re = (const real_pcre *)argument_re;
-const pcre_study_data *study = NULL;
-
-if (re == NULL || where == NULL) return PCRE_ERROR_NULL;
-
-if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_STUDY_DATA) != 0)
- study = (const pcre_study_data *)extra_data->study_data;
-
-if (re->magic_number != MAGIC_NUMBER)
- {
- re = _pcre_try_flipped(re, &internal_re, study, &internal_study);
- if (re == NULL) return PCRE_ERROR_BADMAGIC;
- if (study != NULL) study = &internal_study;
- }
-
-switch (what)
- {
- case PCRE_INFO_OPTIONS:
- *((unsigned long int *)where) = re->options & PUBLIC_OPTIONS;
- break;
-
- case PCRE_INFO_SIZE:
- *((size_t *)where) = re->size;
- break;
-
- case PCRE_INFO_STUDYSIZE:
- *((size_t *)where) = (study == NULL)? 0 : study->size;
- break;
-
- case PCRE_INFO_CAPTURECOUNT:
- *((int *)where) = re->top_bracket;
- break;
-
- case PCRE_INFO_BACKREFMAX:
- *((int *)where) = re->top_backref;
- break;
-
- case PCRE_INFO_FIRSTBYTE:
- *((int *)where) =
- ((re->flags & PCRE_FIRSTSET) != 0)? re->first_byte :
- ((re->flags & PCRE_STARTLINE) != 0)? -1 : -2;
- break;
-
- /* Make sure we pass back the pointer to the bit vector in the external
- block, not the internal copy (with flipped integer fields). */
-
- case PCRE_INFO_FIRSTTABLE:
- *((const uschar **)where) =
- (study != NULL && (study->options & PCRE_STUDY_MAPPED) != 0)?
- ((const pcre_study_data *)extra_data->study_data)->start_bits : NULL;
- break;
-
- case PCRE_INFO_LASTLITERAL:
- *((int *)where) =
- ((re->flags & PCRE_REQCHSET) != 0)? re->req_byte : -1;
- break;
-
- case PCRE_INFO_NAMEENTRYSIZE:
- *((int *)where) = re->name_entry_size;
- break;
-
- case PCRE_INFO_NAMECOUNT:
- *((int *)where) = re->name_count;
- break;
-
- case PCRE_INFO_NAMETABLE:
- *((const uschar **)where) = (const uschar *)re + re->name_table_offset;
- break;
-
- case PCRE_INFO_DEFAULT_TABLES:
- *((const uschar **)where) = (const uschar *)(_pcre_default_tables);
- break;
-
- case PCRE_INFO_OKPARTIAL:
- *((int *)where) = (re->flags & PCRE_NOPARTIAL) == 0;
- break;
-
- case PCRE_INFO_JCHANGED:
- *((int *)where) = (re->flags & PCRE_JCHANGED) != 0;
- break;
-
- case PCRE_INFO_HASCRORLF:
- *((int *)where) = (re->flags & PCRE_HASCRORLF) != 0;
- break;
-
- default: return PCRE_ERROR_BADOPTION;
- }
-
-return 0;
-}
-
-/* End of pcre_fullinfo.c */
diff --git a/crawl-ref/source/util/pcre/pcre_get.c b/crawl-ref/source/util/pcre/pcre_get.c
deleted file mode 100644
index 68b8de47b6..0000000000
--- a/crawl-ref/source/util/pcre/pcre_get.c
+++ /dev/null
@@ -1,465 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
- Written by Philip Hazel
- Copyright (c) 1997-2008 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-
-/* This module contains some convenience functions for extracting substrings
-from the subject string after a regex match has succeeded. The original idea
-for these functions came from Scott Wimer. */
-
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "pcre_internal.h"
-
-
-/*************************************************
-* Find number for named string *
-*************************************************/
-
-/* This function is used by the get_first_set() function below, as well
-as being generally available. It assumes that names are unique.
-
-Arguments:
- code the compiled regex
- stringname the name whose number is required
-
-Returns: the number of the named parentheses, or a negative number
- (PCRE_ERROR_NOSUBSTRING) if not found
-*/
-
-int
-pcre_get_stringnumber(const pcre *code, const char *stringname)
-{
-int rc;
-int entrysize;
-int top, bot;
-uschar *nametable;
-
-if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMECOUNT, &top)) != 0)
- return rc;
-if (top <= 0) return PCRE_ERROR_NOSUBSTRING;
-
-if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMEENTRYSIZE, &entrysize)) != 0)
- return rc;
-if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMETABLE, &nametable)) != 0)
- return rc;
-
-bot = 0;
-while (top > bot)
- {
- int mid = (top + bot) / 2;
- uschar *entry = nametable + entrysize*mid;
- int c = strcmp(stringname, (char *)(entry + 2));
- if (c == 0) return (entry[0] << 8) + entry[1];
- if (c > 0) bot = mid + 1; else top = mid;
- }
-
-return PCRE_ERROR_NOSUBSTRING;
-}
-
-
-
-/*************************************************
-* Find (multiple) entries for named string *
-*************************************************/
-
-/* This is used by the get_first_set() function below, as well as being
-generally available. It is used when duplicated names are permitted.
-
-Arguments:
- code the compiled regex
- stringname the name whose entries required
- firstptr where to put the pointer to the first entry
- lastptr where to put the pointer to the last entry
-
-Returns: the length of each entry, or a negative number
- (PCRE_ERROR_NOSUBSTRING) if not found
-*/
-
-int
-pcre_get_stringtable_entries(const pcre *code, const char *stringname,
- char **firstptr, char **lastptr)
-{
-int rc;
-int entrysize;
-int top, bot;
-uschar *nametable, *lastentry;
-
-if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMECOUNT, &top)) != 0)
- return rc;
-if (top <= 0) return PCRE_ERROR_NOSUBSTRING;
-
-if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMEENTRYSIZE, &entrysize)) != 0)
- return rc;
-if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMETABLE, &nametable)) != 0)
- return rc;
-
-lastentry = nametable + entrysize * (top - 1);
-bot = 0;
-while (top > bot)
- {
- int mid = (top + bot) / 2;
- uschar *entry = nametable + entrysize*mid;
- int c = strcmp(stringname, (char *)(entry + 2));
- if (c == 0)
- {
- uschar *first = entry;
- uschar *last = entry;
- while (first > nametable)
- {
- if (strcmp(stringname, (char *)(first - entrysize + 2)) != 0) break;
- first -= entrysize;
- }
- while (last < lastentry)
- {
- if (strcmp(stringname, (char *)(last + entrysize + 2)) != 0) break;
- last += entrysize;
- }
- *firstptr = (char *)first;
- *lastptr = (char *)last;
- return entrysize;
- }
- if (c > 0) bot = mid + 1; else top = mid;
- }
-
-return PCRE_ERROR_NOSUBSTRING;
-}
-
-
-
-/*************************************************
-* Find first set of multiple named strings *
-*************************************************/
-
-/* This function allows for duplicate names in the table of named substrings.
-It returns the number of the first one that was set in a pattern match.
-
-Arguments:
- code the compiled regex
- stringname the name of the capturing substring
- ovector the vector of matched substrings
-
-Returns: the number of the first that is set,
- or the number of the last one if none are set,
- or a negative number on error
-*/
-
-static int
-get_first_set(const pcre *code, const char *stringname, int *ovector)
-{
-const real_pcre *re = (const real_pcre *)code;
-int entrysize;
-char *first, *last;
-uschar *entry;
-if ((re->options & PCRE_DUPNAMES) == 0 && (re->flags & PCRE_JCHANGED) == 0)
- return pcre_get_stringnumber(code, stringname);
-entrysize = pcre_get_stringtable_entries(code, stringname, &first, &last);
-if (entrysize <= 0) return entrysize;
-for (entry = (uschar *)first; entry <= (uschar *)last; entry += entrysize)
- {
- int n = (entry[0] << 8) + entry[1];
- if (ovector[n*2] >= 0) return n;
- }
-return (first[0] << 8) + first[1];
-}
-
-
-
-
-/*************************************************
-* Copy captured string to given buffer *
-*************************************************/
-
-/* This function copies a single captured substring into a given buffer.
-Note that we use memcpy() rather than strncpy() in case there are binary zeros
-in the string.
-
-Arguments:
- subject the subject string that was matched
- ovector pointer to the offsets table
- stringcount the number of substrings that were captured
- (i.e. the yield of the pcre_exec call, unless
- that was zero, in which case it should be 1/3
- of the offset table size)
- stringnumber the number of the required substring
- buffer where to put the substring
- size the size of the buffer
-
-Returns: if successful:
- the length of the copied string, not including the zero
- that is put on the end; can be zero
- if not successful:
- PCRE_ERROR_NOMEMORY (-6) buffer too small
- PCRE_ERROR_NOSUBSTRING (-7) no such captured substring
-*/
-
-int
-pcre_copy_substring(const char *subject, int *ovector, int stringcount,
- int stringnumber, char *buffer, int size)
-{
-int yield;
-if (stringnumber < 0 || stringnumber >= stringcount)
- return PCRE_ERROR_NOSUBSTRING;
-stringnumber *= 2;
-yield = ovector[stringnumber+1] - ovector[stringnumber];
-if (size < yield + 1) return PCRE_ERROR_NOMEMORY;
-memcpy(buffer, subject + ovector[stringnumber], yield);
-buffer[yield] = 0;
-return yield;
-}
-
-
-
-/*************************************************
-* Copy named captured string to given buffer *
-*************************************************/
-
-/* This function copies a single captured substring into a given buffer,
-identifying it by name. If the regex permits duplicate names, the first
-substring that is set is chosen.
-
-Arguments:
- code the compiled regex
- subject the subject string that was matched
- ovector pointer to the offsets table
- stringcount the number of substrings that were captured
- (i.e. the yield of the pcre_exec call, unless
- that was zero, in which case it should be 1/3
- of the offset table size)
- stringname the name of the required substring
- buffer where to put the substring
- size the size of the buffer
-
-Returns: if successful:
- the length of the copied string, not including the zero
- that is put on the end; can be zero
- if not successful:
- PCRE_ERROR_NOMEMORY (-6) buffer too small
- PCRE_ERROR_NOSUBSTRING (-7) no such captured substring
-*/
-
-int
-pcre_copy_named_substring(const pcre *code, const char *subject, int *ovector,
- int stringcount, const char *stringname, char *buffer, int size)
-{
-int n = get_first_set(code, stringname, ovector);
-if (n <= 0) return n;
-return pcre_copy_substring(subject, ovector, stringcount, n, buffer, size);
-}
-
-
-
-/*************************************************
-* Copy all captured strings to new store *
-*************************************************/
-
-/* This function gets one chunk of store and builds a list of pointers and all
-of the captured substrings in it. A NULL pointer is put on the end of the list.
-
-Arguments:
- subject the subject string that was matched
- ovector pointer to the offsets table
- stringcount the number of substrings that were captured
- (i.e. the yield of the pcre_exec call, unless
- that was zero, in which case it should be 1/3
- of the offset table size)
- listptr set to point to the list of pointers
-
-Returns: if successful: 0
- if not successful:
- PCRE_ERROR_NOMEMORY (-6) failed to get store
-*/
-
-int
-pcre_get_substring_list(const char *subject, int *ovector, int stringcount,
- const char ***listptr)
-{
-int i;
-int size = sizeof(char *);
-int double_count = stringcount * 2;
-char **stringlist;
-char *p;
-
-for (i = 0; i < double_count; i += 2)
- size += sizeof(char *) + ovector[i+1] - ovector[i] + 1;
-
-stringlist = (char **)(pcre_malloc)(size);
-if (stringlist == NULL) return PCRE_ERROR_NOMEMORY;
-
-*listptr = (const char **)stringlist;
-p = (char *)(stringlist + stringcount + 1);
-
-for (i = 0; i < double_count; i += 2)
- {
- int len = ovector[i+1] - ovector[i];
- memcpy(p, subject + ovector[i], len);
- *stringlist++ = p;
- p += len;
- *p++ = 0;
- }
-
-*stringlist = NULL;
-return 0;
-}
-
-
-
-/*************************************************
-* Free store obtained by get_substring_list *
-*************************************************/
-
-/* This function exists for the benefit of people calling PCRE from non-C
-programs that can call its functions, but not free() or (pcre_free)() directly.
-
-Argument: the result of a previous pcre_get_substring_list()
-Returns: nothing
-*/
-
-void
-pcre_free_substring_list(const char **pointer)
-{
-(pcre_free)((void *)pointer);
-}
-
-
-
-/*************************************************
-* Copy captured string to new store *
-*************************************************/
-
-/* This function copies a single captured substring into a piece of new
-store
-
-Arguments:
- subject the subject string that was matched
- ovector pointer to the offsets table
- stringcount the number of substrings that were captured
- (i.e. the yield of the pcre_exec call, unless
- that was zero, in which case it should be 1/3
- of the offset table size)
- stringnumber the number of the required substring
- stringptr where to put a pointer to the substring
-
-Returns: if successful:
- the length of the string, not including the zero that
- is put on the end; can be zero
- if not successful:
- PCRE_ERROR_NOMEMORY (-6) failed to get store
- PCRE_ERROR_NOSUBSTRING (-7) substring not present
-*/
-
-int
-pcre_get_substring(const char *subject, int *ovector, int stringcount,
- int stringnumber, const char **stringptr)
-{
-int yield;
-char *substring;
-if (stringnumber < 0 || stringnumber >= stringcount)
- return PCRE_ERROR_NOSUBSTRING;
-stringnumber *= 2;
-yield = ovector[stringnumber+1] - ovector[stringnumber];
-substring = (char *)(pcre_malloc)(yield + 1);
-if (substring == NULL) return PCRE_ERROR_NOMEMORY;
-memcpy(substring, subject + ovector[stringnumber], yield);
-substring[yield] = 0;
-*stringptr = substring;
-return yield;
-}
-
-
-
-/*************************************************
-* Copy named captured string to new store *
-*************************************************/
-
-/* This function copies a single captured substring, identified by name, into
-new store. If the regex permits duplicate names, the first substring that is
-set is chosen.
-
-Arguments:
- code the compiled regex
- subject the subject string that was matched
- ovector pointer to the offsets table
- stringcount the number of substrings that were captured
- (i.e. the yield of the pcre_exec call, unless
- that was zero, in which case it should be 1/3
- of the offset table size)
- stringname the name of the required substring
- stringptr where to put the pointer
-
-Returns: if successful:
- the length of the copied string, not including the zero
- that is put on the end; can be zero
- if not successful:
- PCRE_ERROR_NOMEMORY (-6) couldn't get memory
- PCRE_ERROR_NOSUBSTRING (-7) no such captured substring
-*/
-
-int
-pcre_get_named_substring(const pcre *code, const char *subject, int *ovector,
- int stringcount, const char *stringname, const char **stringptr)
-{
-int n = get_first_set(code, stringname, ovector);
-if (n <= 0) return n;
-return pcre_get_substring(subject, ovector, stringcount, n, stringptr);
-}
-
-
-
-
-/*************************************************
-* Free store obtained by get_substring *
-*************************************************/
-
-/* This function exists for the benefit of people calling PCRE from non-C
-programs that can call its functions, but not free() or (pcre_free)() directly.
-
-Argument: the result of a previous pcre_get_substring()
-Returns: nothing
-*/
-
-void
-pcre_free_substring(const char *pointer)
-{
-(pcre_free)((void *)pointer);
-}
-
-/* End of pcre_get.c */
diff --git a/crawl-ref/source/util/pcre/pcre_globals.c b/crawl-ref/source/util/pcre/pcre_globals.c
deleted file mode 100644
index 24ed03d396..0000000000
--- a/crawl-ref/source/util/pcre/pcre_globals.c
+++ /dev/null
@@ -1,63 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
- Written by Philip Hazel
- Copyright (c) 1997-2008 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-
-/* This module contains global variables that are exported by the PCRE library.
-PCRE is thread-clean and doesn't use any global variables in the normal sense.
-However, it calls memory allocation and freeing functions via the four
-indirections below, and it can optionally do callouts, using the fifth
-indirection. These values can be changed by the caller, but are shared between
-all threads. However, when compiling for Virtual Pascal, things are done
-differently, and global variables are not used (see pcre.in). */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "pcre_internal.h"
-
-#ifndef VPCOMPAT
-PCRE_EXP_DATA_DEFN void *(*pcre_malloc)(size_t) = malloc;
-PCRE_EXP_DATA_DEFN void (*pcre_free)(void *) = free;
-PCRE_EXP_DATA_DEFN void *(*pcre_stack_malloc)(size_t) = malloc;
-PCRE_EXP_DATA_DEFN void (*pcre_stack_free)(void *) = free;
-PCRE_EXP_DATA_DEFN int (*pcre_callout)(pcre_callout_block *) = NULL;
-#endif
-
-/* End of pcre_globals.c */
diff --git a/crawl-ref/source/util/pcre/pcre_info.c b/crawl-ref/source/util/pcre/pcre_info.c
deleted file mode 100644
index 638a475316..0000000000
--- a/crawl-ref/source/util/pcre/pcre_info.c
+++ /dev/null
@@ -1,93 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
- Written by Philip Hazel
- Copyright (c) 1997-2008 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-
-/* This module contains the external function pcre_info(), which gives some
-information about a compiled pattern. However, use of this function is now
-deprecated, as it has been superseded by pcre_fullinfo(). */
-
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "pcre_internal.h"
-
-
-/*************************************************
-* (Obsolete) Return info about compiled pattern *
-*************************************************/
-
-/* This is the original "info" function. It picks potentially useful data out
-of the private structure, but its interface was too rigid. It remains for
-backwards compatibility. The public options are passed back in an int - though
-the re->options field has been expanded to a long int, all the public options
-at the low end of it, and so even on 16-bit systems this will still be OK.
-Therefore, I haven't changed the API for pcre_info().
-
-Arguments:
- argument_re points to compiled code
- optptr where to pass back the options
- first_byte where to pass back the first character,
- or -1 if multiline and all branches start ^,
- or -2 otherwise
-
-Returns: number of capturing subpatterns
- or negative values on error
-*/
-
-PCRE_EXP_DEFN int
-pcre_info(const pcre *argument_re, int *optptr, int *first_byte)
-{
-real_pcre internal_re;
-const real_pcre *re = (const real_pcre *)argument_re;
-if (re == NULL) return PCRE_ERROR_NULL;
-if (re->magic_number != MAGIC_NUMBER)
- {
- re = _pcre_try_flipped(re, &internal_re, NULL, NULL);
- if (re == NULL) return PCRE_ERROR_BADMAGIC;
- }
-if (optptr != NULL) *optptr = (int)(re->options & PUBLIC_OPTIONS);
-if (first_byte != NULL)
- *first_byte = ((re->flags & PCRE_FIRSTSET) != 0)? re->first_byte :
- ((re->flags & PCRE_STARTLINE) != 0)? -1 : -2;
-return re->top_bracket;
-}
-
-/* End of pcre_info.c */
diff --git a/crawl-ref/source/util/pcre/pcre_internal.h b/crawl-ref/source/util/pcre/pcre_internal.h
deleted file mode 100644
index 102e2d01e2..0000000000
--- a/crawl-ref/source/util/pcre/pcre_internal.h
+++ /dev/null
@@ -1,1138 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-
-/* PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
- Written by Philip Hazel
- Copyright (c) 1997-2008 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-/* This header contains definitions that are shared between the different
-modules, but which are not relevant to the exported API. This includes some
-functions whose names all begin with "_pcre_". */
-
-#ifndef PCRE_INTERNAL_H
-#define PCRE_INTERNAL_H
-
-/* Define DEBUG to get debugging output on stdout. */
-
-#if 0
-#define DEBUG
-#endif
-
-/* Use a macro for debugging printing, 'cause that eliminates the use of #ifdef
-inline, and there are *still* stupid compilers about that don't like indented
-pre-processor statements, or at least there were when I first wrote this. After
-all, it had only been about 10 years then...
-
-It turns out that the Mac Debugging.h header also defines the macro DPRINTF, so
-be absolutely sure we get our version. */
-
-#undef DPRINTF
-#ifdef DEBUG
-#define DPRINTF(p) printf p
-#else
-#define DPRINTF(p) /* Nothing */
-#endif
-
-
-/* Standard C headers plus the external interface definition. The only time
-setjmp and stdarg are used is when NO_RECURSE is set. */
-
-#include <ctype.h>
-#include <limits.h>
-#include <setjmp.h>
-#include <stdarg.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-/* When compiling a DLL for Windows, the exported symbols have to be declared
-using some MS magic. I found some useful information on this web page:
-http://msdn2.microsoft.com/en-us/library/y4h7bcy6(VS.80).aspx. According to the
-information there, using __declspec(dllexport) without "extern" we have a
-definition; with "extern" we have a declaration. The settings here override the
-setting in pcre.h (which is included below); it defines only PCRE_EXP_DECL,
-which is all that is needed for applications (they just import the symbols). We
-use:
-
- PCRE_EXP_DECL for declarations
- PCRE_EXP_DEFN for definitions of exported functions
- PCRE_EXP_DATA_DEFN for definitions of exported variables
-
-The reason for the two DEFN macros is that in non-Windows environments, one
-does not want to have "extern" before variable definitions because it leads to
-compiler warnings. So we distinguish between functions and variables. In
-Windows, the two should always be the same.
-
-The reason for wrapping this in #ifndef PCRE_EXP_DECL is so that pcretest,
-which is an application, but needs to import this file in order to "peek" at
-internals, can #include pcre.h first to get an application's-eye view.
-
-In principle, people compiling for non-Windows, non-Unix-like (i.e. uncommon,
-special-purpose environments) might want to stick other stuff in front of
-exported symbols. That's why, in the non-Windows case, we set PCRE_EXP_DEFN and
-PCRE_EXP_DATA_DEFN only if they are not already set. */
-
-#ifndef PCRE_EXP_DECL
-# ifdef _WIN32
-# ifndef PCRE_STATIC
-# define PCRE_EXP_DECL extern __declspec(dllexport)
-# define PCRE_EXP_DEFN __declspec(dllexport)
-# define PCRE_EXP_DATA_DEFN __declspec(dllexport)
-# else
-# define PCRE_EXP_DECL extern
-# define PCRE_EXP_DEFN
-# define PCRE_EXP_DATA_DEFN
-# endif
-# else
-# ifdef __cplusplus
-# define PCRE_EXP_DECL extern "C"
-# else
-# define PCRE_EXP_DECL extern
-# endif
-# ifndef PCRE_EXP_DEFN
-# define PCRE_EXP_DEFN PCRE_EXP_DECL
-# endif
-# ifndef PCRE_EXP_DATA_DEFN
-# define PCRE_EXP_DATA_DEFN
-# endif
-# endif
-#endif
-
-/* We need to have types that specify unsigned 16-bit and 32-bit integers. We
-cannot determine these outside the compilation (e.g. by running a program as
-part of "configure") because PCRE is often cross-compiled for use on other
-systems. Instead we make use of the maximum sizes that are available at
-preprocessor time in standard C environments. */
-
-#if USHRT_MAX == 65535
- typedef unsigned short pcre_uint16;
-#elif UINT_MAX == 65535
- typedef unsigned int pcre_uint16;
-#else
- #error Cannot determine a type for 16-bit unsigned integers
-#endif
-
-#if UINT_MAX == 4294967295
- typedef unsigned int pcre_uint32;
-#elif ULONG_MAX == 4294967295
- typedef unsigned long int pcre_uint32;
-#else
- #error Cannot determine a type for 32-bit unsigned integers
-#endif
-
-/* All character handling must be done as unsigned characters. Otherwise there
-are problems with top-bit-set characters and functions such as isspace().
-However, we leave the interface to the outside world as char *, because that
-should make things easier for callers. We define a short type for unsigned char
-to save lots of typing. I tried "uchar", but it causes problems on Digital
-Unix, where it is defined in sys/types, so use "uschar" instead. */
-
-typedef unsigned char uschar;
-
-/* This is an unsigned int value that no character can ever have. UTF-8
-characters only go up to 0x7fffffff (though Unicode doesn't go beyond
-0x0010ffff). */
-
-#define NOTACHAR 0xffffffff
-
-/* PCRE is able to support several different kinds of newline (CR, LF, CRLF,
-"any" and "anycrlf" at present). The following macros are used to package up
-testing for newlines. NLBLOCK, PSSTART, and PSEND are defined in the various
-modules to indicate in which datablock the parameters exist, and what the
-start/end of string field names are. */
-
-#define NLTYPE_FIXED 0 /* Newline is a fixed length string */
-#define NLTYPE_ANY 1 /* Newline is any Unicode line ending */
-#define NLTYPE_ANYCRLF 2 /* Newline is CR, LF, or CRLF */
-
-/* This macro checks for a newline at the given position */
-
-#define IS_NEWLINE(p) \
- ((NLBLOCK->nltype != NLTYPE_FIXED)? \
- ((p) < NLBLOCK->PSEND && \
- _pcre_is_newline((p), NLBLOCK->nltype, NLBLOCK->PSEND, &(NLBLOCK->nllen),\
- utf8)) \
- : \
- ((p) <= NLBLOCK->PSEND - NLBLOCK->nllen && \
- (p)[0] == NLBLOCK->nl[0] && \
- (NLBLOCK->nllen == 1 || (p)[1] == NLBLOCK->nl[1]) \
- ) \
- )
-
-/* This macro checks for a newline immediately preceding the given position */
-
-#define WAS_NEWLINE(p) \
- ((NLBLOCK->nltype != NLTYPE_FIXED)? \
- ((p) > NLBLOCK->PSSTART && \
- _pcre_was_newline((p), NLBLOCK->nltype, NLBLOCK->PSSTART, \
- &(NLBLOCK->nllen), utf8)) \
- : \
- ((p) >= NLBLOCK->PSSTART + NLBLOCK->nllen && \
- (p)[-NLBLOCK->nllen] == NLBLOCK->nl[0] && \
- (NLBLOCK->nllen == 1 || (p)[-NLBLOCK->nllen+1] == NLBLOCK->nl[1]) \
- ) \
- )
-
-/* When PCRE is compiled as a C++ library, the subject pointer can be replaced
-with a custom type. This makes it possible, for example, to allow pcre_exec()
-to process subject strings that are discontinuous by using a smart pointer
-class. It must always be possible to inspect all of the subject string in
-pcre_exec() because of the way it backtracks. Two macros are required in the
-normal case, for sign-unspecified and unsigned char pointers. The former is
-used for the external interface and appears in pcre.h, which is why its name
-must begin with PCRE_. */
-
-#ifdef CUSTOM_SUBJECT_PTR
-#define PCRE_SPTR CUSTOM_SUBJECT_PTR
-#define USPTR CUSTOM_SUBJECT_PTR
-#else
-#define PCRE_SPTR const char *
-#define USPTR const unsigned char *
-#endif
-
-
-
-/* Include the public PCRE header and the definitions of UCP character property
-values. */
-
-#include "pcre.h"
-#include "ucp.h"
-
-/* When compiling for use with the Virtual Pascal compiler, these functions
-need to have their names changed. PCRE must be compiled with the -DVPCOMPAT
-option on the command line. */
-
-#ifdef VPCOMPAT
-#define strlen(s) _strlen(s)
-#define strncmp(s1,s2,m) _strncmp(s1,s2,m)
-#define memcmp(s,c,n) _memcmp(s,c,n)
-#define memcpy(d,s,n) _memcpy(d,s,n)
-#define memmove(d,s,n) _memmove(d,s,n)
-#define memset(s,c,n) _memset(s,c,n)
-#else /* VPCOMPAT */
-
-/* To cope with SunOS4 and other systems that lack memmove() but have bcopy(),
-define a macro for memmove() if HAVE_MEMMOVE is false, provided that HAVE_BCOPY
-is set. Otherwise, include an emulating function for those systems that have
-neither (there some non-Unix environments where this is the case). */
-
-#ifndef HAVE_MEMMOVE
-#undef memmove /* some systems may have a macro */
-#ifdef HAVE_BCOPY
-#define memmove(a, b, c) bcopy(b, a, c)
-#else /* HAVE_BCOPY */
-static void *
-pcre_memmove(void *d, const void *s, size_t n)
-{
-size_t i;
-unsigned char *dest = (unsigned char *)d;
-const unsigned char *src = (const unsigned char *)s;
-if (dest > src)
- {
- dest += n;
- src += n;
- for (i = 0; i < n; ++i) *(--dest) = *(--src);
- return (void *)dest;
- }
-else
- {
- for (i = 0; i < n; ++i) *dest++ = *src++;
- return (void *)(dest - n);
- }
-}
-#define memmove(a, b, c) pcre_memmove(a, b, c)
-#endif /* not HAVE_BCOPY */
-#endif /* not HAVE_MEMMOVE */
-#endif /* not VPCOMPAT */
-
-
-/* PCRE keeps offsets in its compiled code as 2-byte quantities (always stored
-in big-endian order) by default. These are used, for example, to link from the
-start of a subpattern to its alternatives and its end. The use of 2 bytes per
-offset limits the size of the compiled regex to around 64K, which is big enough
-for almost everybody. However, I received a request for an even bigger limit.
-For this reason, and also to make the code easier to maintain, the storing and
-loading of offsets from the byte string is now handled by the macros that are
-defined here.
-
-The macros are controlled by the value of LINK_SIZE. This defaults to 2 in
-the config.h file, but can be overridden by using -D on the command line. This
-is automated on Unix systems via the "configure" command. */
-
-#if LINK_SIZE == 2
-
-#define PUT(a,n,d) \
- (a[n] = (d) >> 8), \
- (a[(n)+1] = (d) & 255)
-
-#define GET(a,n) \
- (((a)[n] << 8) | (a)[(n)+1])
-
-#define MAX_PATTERN_SIZE (1 << 16)
-
-
-#elif LINK_SIZE == 3
-
-#define PUT(a,n,d) \
- (a[n] = (d) >> 16), \
- (a[(n)+1] = (d) >> 8), \
- (a[(n)+2] = (d) & 255)
-
-#define GET(a,n) \
- (((a)[n] << 16) | ((a)[(n)+1] << 8) | (a)[(n)+2])
-
-#define MAX_PATTERN_SIZE (1 << 24)
-
-
-#elif LINK_SIZE == 4
-
-#define PUT(a,n,d) \
- (a[n] = (d) >> 24), \
- (a[(n)+1] = (d) >> 16), \
- (a[(n)+2] = (d) >> 8), \
- (a[(n)+3] = (d) & 255)
-
-#define GET(a,n) \
- (((a)[n] << 24) | ((a)[(n)+1] << 16) | ((a)[(n)+2] << 8) | (a)[(n)+3])
-
-#define MAX_PATTERN_SIZE (1 << 30) /* Keep it positive */
-
-
-#else
-#error LINK_SIZE must be either 2, 3, or 4
-#endif
-
-
-/* Convenience macro defined in terms of the others */
-
-#define PUTINC(a,n,d) PUT(a,n,d), a += LINK_SIZE
-
-
-/* PCRE uses some other 2-byte quantities that do not change when the size of
-offsets changes. There are used for repeat counts and for other things such as
-capturing parenthesis numbers in back references. */
-
-#define PUT2(a,n,d) \
- a[n] = (d) >> 8; \
- a[(n)+1] = (d) & 255
-
-#define GET2(a,n) \
- (((a)[n] << 8) | (a)[(n)+1])
-
-#define PUT2INC(a,n,d) PUT2(a,n,d), a += 2
-
-
-/* When UTF-8 encoding is being used, a character is no longer just a single
-byte. The macros for character handling generate simple sequences when used in
-byte-mode, and more complicated ones for UTF-8 characters. BACKCHAR should
-never be called in byte mode. To make sure it can never even appear when UTF-8
-support is omitted, we don't even define it. */
-
-#ifndef SUPPORT_UTF8
-#define NEXTCHAR(p) p++;
-#define GETCHAR(c, eptr) c = *eptr;
-#define GETCHARTEST(c, eptr) c = *eptr;
-#define GETCHARINC(c, eptr) c = *eptr++;
-#define GETCHARINCTEST(c, eptr) c = *eptr++;
-#define GETCHARLEN(c, eptr, len) c = *eptr;
-/* #define BACKCHAR(eptr) */
-
-#else /* SUPPORT_UTF8 */
-
-/* Advance a character pointer one byte in non-UTF-8 mode and by one character
-in UTF-8 mode. */
-
-#define NEXTCHAR(p) \
- p++; \
- if (utf8) { while((*p & 0xc0) == 0x80) p++; }
-
-/* Get the next UTF-8 character, not advancing the pointer. This is called when
-we know we are in UTF-8 mode. */
-
-#define GETCHAR(c, eptr) \
- c = *eptr; \
- if (c >= 0xc0) \
- { \
- int gcii; \
- int gcaa = _pcre_utf8_table4[c & 0x3f]; /* Number of additional bytes */ \
- int gcss = 6*gcaa; \
- c = (c & _pcre_utf8_table3[gcaa]) << gcss; \
- for (gcii = 1; gcii <= gcaa; gcii++) \
- { \
- gcss -= 6; \
- c |= (eptr[gcii] & 0x3f) << gcss; \
- } \
- }
-
-/* Get the next UTF-8 character, testing for UTF-8 mode, and not advancing the
-pointer. */
-
-#define GETCHARTEST(c, eptr) \
- c = *eptr; \
- if (utf8 && c >= 0xc0) \
- { \
- int gcii; \
- int gcaa = _pcre_utf8_table4[c & 0x3f]; /* Number of additional bytes */ \
- int gcss = 6*gcaa; \
- c = (c & _pcre_utf8_table3[gcaa]) << gcss; \
- for (gcii = 1; gcii <= gcaa; gcii++) \
- { \
- gcss -= 6; \
- c |= (eptr[gcii] & 0x3f) << gcss; \
- } \
- }
-
-/* Get the next UTF-8 character, advancing the pointer. This is called when we
-know we are in UTF-8 mode. */
-
-#define GETCHARINC(c, eptr) \
- c = *eptr++; \
- if (c >= 0xc0) \
- { \
- int gcaa = _pcre_utf8_table4[c & 0x3f]; /* Number of additional bytes */ \
- int gcss = 6*gcaa; \
- c = (c & _pcre_utf8_table3[gcaa]) << gcss; \
- while (gcaa-- > 0) \
- { \
- gcss -= 6; \
- c |= (*eptr++ & 0x3f) << gcss; \
- } \
- }
-
-/* Get the next character, testing for UTF-8 mode, and advancing the pointer */
-
-#define GETCHARINCTEST(c, eptr) \
- c = *eptr++; \
- if (utf8 && c >= 0xc0) \
- { \
- int gcaa = _pcre_utf8_table4[c & 0x3f]; /* Number of additional bytes */ \
- int gcss = 6*gcaa; \
- c = (c & _pcre_utf8_table3[gcaa]) << gcss; \
- while (gcaa-- > 0) \
- { \
- gcss -= 6; \
- c |= (*eptr++ & 0x3f) << gcss; \
- } \
- }
-
-/* Get the next UTF-8 character, not advancing the pointer, incrementing length
-if there are extra bytes. This is called when we know we are in UTF-8 mode. */
-
-#define GETCHARLEN(c, eptr, len) \
- c = *eptr; \
- if (c >= 0xc0) \
- { \
- int gcii; \
- int gcaa = _pcre_utf8_table4[c & 0x3f]; /* Number of additional bytes */ \
- int gcss = 6*gcaa; \
- c = (c & _pcre_utf8_table3[gcaa]) << gcss; \
- for (gcii = 1; gcii <= gcaa; gcii++) \
- { \
- gcss -= 6; \
- c |= (eptr[gcii] & 0x3f) << gcss; \
- } \
- len += gcaa; \
- }
-
-/* If the pointer is not at the start of a character, move it back until
-it is. This is called only in UTF-8 mode - we don't put a test within the macro
-because almost all calls are already within a block of UTF-8 only code. */
-
-#define BACKCHAR(eptr) while((*eptr & 0xc0) == 0x80) eptr--
-
-#endif
-
-
-/* In case there is no definition of offsetof() provided - though any proper
-Standard C system should have one. */
-
-#ifndef offsetof
-#define offsetof(p_type,field) ((size_t)&(((p_type *)0)->field))
-#endif
-
-
-/* These are the public options that can change during matching. */
-
-#define PCRE_IMS (PCRE_CASELESS|PCRE_MULTILINE|PCRE_DOTALL)
-
-/* Private flags containing information about the compiled regex. They used to
-live at the top end of the options word, but that got almost full, so now they
-are in a 16-bit flags word. */
-
-#define PCRE_NOPARTIAL 0x0001 /* can't use partial with this regex */
-#define PCRE_FIRSTSET 0x0002 /* first_byte is set */
-#define PCRE_REQCHSET 0x0004 /* req_byte is set */
-#define PCRE_STARTLINE 0x0008 /* start after \n for multiline */
-#define PCRE_JCHANGED 0x0010 /* j option used in regex */
-#define PCRE_HASCRORLF 0x0020 /* explicit \r or \n in pattern */
-
-/* Options for the "extra" block produced by pcre_study(). */
-
-#define PCRE_STUDY_MAPPED 0x01 /* a map of starting chars exists */
-
-/* Masks for identifying the public options that are permitted at compile
-time, run time, or study time, respectively. */
-
-#define PCRE_NEWLINE_BITS (PCRE_NEWLINE_CR|PCRE_NEWLINE_LF|PCRE_NEWLINE_ANY| \
- PCRE_NEWLINE_ANYCRLF)
-
-#define PUBLIC_OPTIONS \
- (PCRE_CASELESS|PCRE_EXTENDED|PCRE_ANCHORED|PCRE_MULTILINE| \
- PCRE_DOTALL|PCRE_DOLLAR_ENDONLY|PCRE_EXTRA|PCRE_UNGREEDY|PCRE_UTF8| \
- PCRE_NO_AUTO_CAPTURE|PCRE_NO_UTF8_CHECK|PCRE_AUTO_CALLOUT|PCRE_FIRSTLINE| \
- PCRE_DUPNAMES|PCRE_NEWLINE_BITS|PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE| \
- PCRE_JAVASCRIPT_COMPAT)
-
-#define PUBLIC_EXEC_OPTIONS \
- (PCRE_ANCHORED|PCRE_NOTBOL|PCRE_NOTEOL|PCRE_NOTEMPTY|PCRE_NO_UTF8_CHECK| \
- PCRE_PARTIAL|PCRE_NEWLINE_BITS|PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE)
-
-#define PUBLIC_DFA_EXEC_OPTIONS \
- (PCRE_ANCHORED|PCRE_NOTBOL|PCRE_NOTEOL|PCRE_NOTEMPTY|PCRE_NO_UTF8_CHECK| \
- PCRE_PARTIAL|PCRE_DFA_SHORTEST|PCRE_DFA_RESTART|PCRE_NEWLINE_BITS| \
- PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE)
-
-#define PUBLIC_STUDY_OPTIONS 0 /* None defined */
-
-/* Magic number to provide a small check against being handed junk. Also used
-to detect whether a pattern was compiled on a host of different endianness. */
-
-#define MAGIC_NUMBER 0x50435245UL /* 'PCRE' */
-
-/* Negative values for the firstchar and reqchar variables */
-
-#define REQ_UNSET (-2)
-#define REQ_NONE (-1)
-
-/* The maximum remaining length of subject we are prepared to search for a
-req_byte match. */
-
-#define REQ_BYTE_MAX 1000
-
-/* Flags added to firstbyte or reqbyte; a "non-literal" item is either a
-variable-length repeat, or a anything other than literal characters. */
-
-#define REQ_CASELESS 0x0100 /* indicates caselessness */
-#define REQ_VARY 0x0200 /* reqbyte followed non-literal item */
-
-/* Miscellaneous definitions */
-
-typedef int BOOL;
-
-#define FALSE 0
-#define TRUE 1
-
-/* Escape items that are just an encoding of a particular data value. */
-
-#ifndef ESC_e
-#define ESC_e 27
-#endif
-
-#ifndef ESC_f
-#define ESC_f '\f'
-#endif
-
-#ifndef ESC_n
-#define ESC_n '\n'
-#endif
-
-#ifndef ESC_r
-#define ESC_r '\r'
-#endif
-
-/* We can't officially use ESC_t because it is a POSIX reserved identifier
-(presumably because of all the others like size_t). */
-
-#ifndef ESC_tee
-#define ESC_tee '\t'
-#endif
-
-/* Codes for different types of Unicode property */
-
-#define PT_ANY 0 /* Any property - matches all chars */
-#define PT_LAMP 1 /* L& - the union of Lu, Ll, Lt */
-#define PT_GC 2 /* General characteristic (e.g. L) */
-#define PT_PC 3 /* Particular characteristic (e.g. Lu) */
-#define PT_SC 4 /* Script (e.g. Han) */
-
-/* Flag bits and data types for the extended class (OP_XCLASS) for classes that
-contain UTF-8 characters with values greater than 255. */
-
-#define XCL_NOT 0x01 /* Flag: this is a negative class */
-#define XCL_MAP 0x02 /* Flag: a 32-byte map is present */
-
-#define XCL_END 0 /* Marks end of individual items */
-#define XCL_SINGLE 1 /* Single item (one multibyte char) follows */
-#define XCL_RANGE 2 /* A range (two multibyte chars) follows */
-#define XCL_PROP 3 /* Unicode property (2-byte property code follows) */
-#define XCL_NOTPROP 4 /* Unicode inverted property (ditto) */
-
-/* These are escaped items that aren't just an encoding of a particular data
-value such as \n. They must have non-zero values, as check_escape() returns
-their negation. Also, they must appear in the same order as in the opcode
-definitions below, up to ESC_z. There's a dummy for OP_ANY because it
-corresponds to "." rather than an escape sequence, and another for OP_ALLANY
-(which is used for [^] in JavaScript compatibility mode).
-
-The final escape must be ESC_REF as subsequent values are used for
-backreferences (\1, \2, \3, etc). There are two tests in the code for an escape
-greater than ESC_b and less than ESC_Z to detect the types that may be
-repeated. These are the types that consume characters. If any new escapes are
-put in between that don't consume a character, that code will have to change.
-*/
-
-enum { ESC_A = 1, ESC_G, ESC_K, ESC_B, ESC_b, ESC_D, ESC_d, ESC_S, ESC_s,
- ESC_W, ESC_w, ESC_dum1, ESC_dum2, ESC_C, ESC_P, ESC_p, ESC_R, ESC_H,
- ESC_h, ESC_V, ESC_v, ESC_X, ESC_Z, ESC_z, ESC_E, ESC_Q, ESC_g, ESC_k,
- ESC_REF };
-
-
-/* Opcode table: Starting from 1 (i.e. after OP_END), the values up to
-OP_EOD must correspond in order to the list of escapes immediately above.
-
-*** NOTE NOTE NOTE *** Whenever this list is updated, the two macro definitions
-that follow must also be updated to match. There is also a table called
-"coptable" in pcre_dfa_exec.c that must be updated. */
-
-enum {
- OP_END, /* 0 End of pattern */
-
- /* Values corresponding to backslashed metacharacters */
-
- OP_SOD, /* 1 Start of data: \A */
- OP_SOM, /* 2 Start of match (subject + offset): \G */
- OP_SET_SOM, /* 3 Set start of match (\K) */
- OP_NOT_WORD_BOUNDARY, /* 4 \B */
- OP_WORD_BOUNDARY, /* 5 \b */
- OP_NOT_DIGIT, /* 6 \D */
- OP_DIGIT, /* 7 \d */
- OP_NOT_WHITESPACE, /* 8 \S */
- OP_WHITESPACE, /* 9 \s */
- OP_NOT_WORDCHAR, /* 10 \W */
- OP_WORDCHAR, /* 11 \w */
- OP_ANY, /* 12 Match any character (subject to DOTALL) */
- OP_ALLANY, /* 13 Match any character (not subject to DOTALL) */
- OP_ANYBYTE, /* 14 Match any byte (\C); different to OP_ANY for UTF-8 */
- OP_NOTPROP, /* 15 \P (not Unicode property) */
- OP_PROP, /* 16 \p (Unicode property) */
- OP_ANYNL, /* 17 \R (any newline sequence) */
- OP_NOT_HSPACE, /* 18 \H (not horizontal whitespace) */
- OP_HSPACE, /* 19 \h (horizontal whitespace) */
- OP_NOT_VSPACE, /* 20 \V (not vertical whitespace) */
- OP_VSPACE, /* 21 \v (vertical whitespace) */
- OP_EXTUNI, /* 22 \X (extended Unicode sequence */
- OP_EODN, /* 23 End of data or \n at end of data: \Z. */
- OP_EOD, /* 24 End of data: \z */
-
- OP_OPT, /* 25 Set runtime options */
- OP_CIRC, /* 26 Start of line - varies with multiline switch */
- OP_DOLL, /* 27 End of line - varies with multiline switch */
- OP_CHAR, /* 28 Match one character, casefully */
- OP_CHARNC, /* 29 Match one character, caselessly */
- OP_NOT, /* 30 Match one character, not the following one */
-
- OP_STAR, /* 31 The maximizing and minimizing versions of */
- OP_MINSTAR, /* 32 these six opcodes must come in pairs, with */
- OP_PLUS, /* 33 the minimizing one second. */
- OP_MINPLUS, /* 34 This first set applies to single characters.*/
- OP_QUERY, /* 35 */
- OP_MINQUERY, /* 36 */
-
- OP_UPTO, /* 37 From 0 to n matches */
- OP_MINUPTO, /* 38 */
- OP_EXACT, /* 39 Exactly n matches */
-
- OP_POSSTAR, /* 40 Possessified star */
- OP_POSPLUS, /* 41 Possessified plus */
- OP_POSQUERY, /* 42 Posesssified query */
- OP_POSUPTO, /* 43 Possessified upto */
-
- OP_NOTSTAR, /* 44 The maximizing and minimizing versions of */
- OP_NOTMINSTAR, /* 45 these six opcodes must come in pairs, with */
- OP_NOTPLUS, /* 46 the minimizing one second. They must be in */
- OP_NOTMINPLUS, /* 47 exactly the same order as those above. */
- OP_NOTQUERY, /* 48 This set applies to "not" single characters. */
- OP_NOTMINQUERY, /* 49 */
-
- OP_NOTUPTO, /* 50 From 0 to n matches */
- OP_NOTMINUPTO, /* 51 */
- OP_NOTEXACT, /* 52 Exactly n matches */
-
- OP_NOTPOSSTAR, /* 53 Possessified versions */
- OP_NOTPOSPLUS, /* 54 */
- OP_NOTPOSQUERY, /* 55 */
- OP_NOTPOSUPTO, /* 56 */
-
- OP_TYPESTAR, /* 57 The maximizing and minimizing versions of */
- OP_TYPEMINSTAR, /* 58 these six opcodes must come in pairs, with */
- OP_TYPEPLUS, /* 59 the minimizing one second. These codes must */
- OP_TYPEMINPLUS, /* 60 be in exactly the same order as those above. */
- OP_TYPEQUERY, /* 61 This set applies to character types such as \d */
- OP_TYPEMINQUERY, /* 62 */
-
- OP_TYPEUPTO, /* 63 From 0 to n matches */
- OP_TYPEMINUPTO, /* 64 */
- OP_TYPEEXACT, /* 65 Exactly n matches */
-
- OP_TYPEPOSSTAR, /* 66 Possessified versions */
- OP_TYPEPOSPLUS, /* 67 */
- OP_TYPEPOSQUERY, /* 68 */
- OP_TYPEPOSUPTO, /* 69 */
-
- OP_CRSTAR, /* 70 The maximizing and minimizing versions of */
- OP_CRMINSTAR, /* 71 all these opcodes must come in pairs, with */
- OP_CRPLUS, /* 72 the minimizing one second. These codes must */
- OP_CRMINPLUS, /* 73 be in exactly the same order as those above. */
- OP_CRQUERY, /* 74 These are for character classes and back refs */
- OP_CRMINQUERY, /* 75 */
- OP_CRRANGE, /* 76 These are different to the three sets above. */
- OP_CRMINRANGE, /* 77 */
-
- OP_CLASS, /* 78 Match a character class, chars < 256 only */
- OP_NCLASS, /* 79 Same, but the bitmap was created from a negative
- class - the difference is relevant only when a UTF-8
- character > 255 is encountered. */
-
- OP_XCLASS, /* 80 Extended class for handling UTF-8 chars within the
- class. This does both positive and negative. */
-
- OP_REF, /* 81 Match a back reference */
- OP_RECURSE, /* 82 Match a numbered subpattern (possibly recursive) */
- OP_CALLOUT, /* 83 Call out to external function if provided */
-
- OP_ALT, /* 84 Start of alternation */
- OP_KET, /* 85 End of group that doesn't have an unbounded repeat */
- OP_KETRMAX, /* 86 These two must remain together and in this */
- OP_KETRMIN, /* 87 order. They are for groups the repeat for ever. */
-
- /* The assertions must come before BRA, CBRA, ONCE, and COND.*/
-
- OP_ASSERT, /* 88 Positive lookahead */
- OP_ASSERT_NOT, /* 89 Negative lookahead */
- OP_ASSERTBACK, /* 90 Positive lookbehind */
- OP_ASSERTBACK_NOT, /* 91 Negative lookbehind */
- OP_REVERSE, /* 92 Move pointer back - used in lookbehind assertions */
-
- /* ONCE, BRA, CBRA, and COND must come after the assertions, with ONCE first,
- as there's a test for >= ONCE for a subpattern that isn't an assertion. */
-
- OP_ONCE, /* 93 Atomic group */
- OP_BRA, /* 94 Start of non-capturing bracket */
- OP_CBRA, /* 95 Start of capturing bracket */
- OP_COND, /* 96 Conditional group */
-
- /* These three must follow the previous three, in the same order. There's a
- check for >= SBRA to distinguish the two sets. */
-
- OP_SBRA, /* 97 Start of non-capturing bracket, check empty */
- OP_SCBRA, /* 98 Start of capturing bracket, check empty */
- OP_SCOND, /* 99 Conditional group, check empty */
-
- OP_CREF, /* 100 Used to hold a capture number as condition */
- OP_RREF, /* 101 Used to hold a recursion number as condition */
- OP_DEF, /* 102 The DEFINE condition */
-
- OP_BRAZERO, /* 103 These two must remain together and in this */
- OP_BRAMINZERO, /* 104 order. */
-
- /* These are backtracking control verbs */
-
- OP_PRUNE, /* 105 */
- OP_SKIP, /* 106 */
- OP_THEN, /* 107 */
- OP_COMMIT, /* 108 */
-
- /* These are forced failure and success verbs */
-
- OP_FAIL, /* 109 */
- OP_ACCEPT, /* 110 */
-
- /* This is used to skip a subpattern with a {0} quantifier */
-
- OP_SKIPZERO /* 111 */
-};
-
-
-/* This macro defines textual names for all the opcodes. These are used only
-for debugging. The macro is referenced only in pcre_printint.c. */
-
-#define OP_NAME_LIST \
- "End", "\\A", "\\G", "\\K", "\\B", "\\b", "\\D", "\\d", \
- "\\S", "\\s", "\\W", "\\w", "Any", "AllAny", "Anybyte", \
- "notprop", "prop", "\\R", "\\H", "\\h", "\\V", "\\v", \
- "extuni", "\\Z", "\\z", \
- "Opt", "^", "$", "char", "charnc", "not", \
- "*", "*?", "+", "+?", "?", "??", "{", "{", "{", \
- "*+","++", "?+", "{", \
- "*", "*?", "+", "+?", "?", "??", "{", "{", "{", \
- "*+","++", "?+", "{", \
- "*", "*?", "+", "+?", "?", "??", "{", "{", "{", \
- "*+","++", "?+", "{", \
- "*", "*?", "+", "+?", "?", "??", "{", "{", \
- "class", "nclass", "xclass", "Ref", "Recurse", "Callout", \
- "Alt", "Ket", "KetRmax", "KetRmin", "Assert", "Assert not", \
- "AssertB", "AssertB not", "Reverse", \
- "Once", "Bra", "CBra", "Cond", "SBra", "SCBra", "SCond", \
- "Cond ref", "Cond rec", "Cond def", "Brazero", "Braminzero", \
- "*PRUNE", "*SKIP", "*THEN", "*COMMIT", "*FAIL", "*ACCEPT", \
- "Skip zero"
-
-
-/* This macro defines the length of fixed length operations in the compiled
-regex. The lengths are used when searching for specific things, and also in the
-debugging printing of a compiled regex. We use a macro so that it can be
-defined close to the definitions of the opcodes themselves.
-
-As things have been extended, some of these are no longer fixed lenths, but are
-minima instead. For example, the length of a single-character repeat may vary
-in UTF-8 mode. The code that uses this table must know about such things. */
-
-#define OP_LENGTHS \
- 1, /* End */ \
- 1, 1, 1, 1, 1, /* \A, \G, \K, \B, \b */ \
- 1, 1, 1, 1, 1, 1, /* \D, \d, \S, \s, \W, \w */ \
- 1, 1, 1, /* Any, AllAny, Anybyte */ \
- 3, 3, 1, /* NOTPROP, PROP, EXTUNI */ \
- 1, 1, 1, 1, 1, /* \R, \H, \h, \V, \v */ \
- 1, 1, 2, 1, 1, /* \Z, \z, Opt, ^, $ */ \
- 2, /* Char - the minimum length */ \
- 2, /* Charnc - the minimum length */ \
- 2, /* not */ \
- /* Positive single-char repeats ** These are */ \
- 2, 2, 2, 2, 2, 2, /* *, *?, +, +?, ?, ?? ** minima in */ \
- 4, 4, 4, /* upto, minupto, exact ** UTF-8 mode */ \
- 2, 2, 2, 4, /* *+, ++, ?+, upto+ */ \
- /* Negative single-char repeats - only for chars < 256 */ \
- 2, 2, 2, 2, 2, 2, /* NOT *, *?, +, +?, ?, ?? */ \
- 4, 4, 4, /* NOT upto, minupto, exact */ \
- 2, 2, 2, 4, /* Possessive *, +, ?, upto */ \
- /* Positive type repeats */ \
- 2, 2, 2, 2, 2, 2, /* Type *, *?, +, +?, ?, ?? */ \
- 4, 4, 4, /* Type upto, minupto, exact */ \
- 2, 2, 2, 4, /* Possessive *+, ++, ?+, upto+ */ \
- /* Character class & ref repeats */ \
- 1, 1, 1, 1, 1, 1, /* *, *?, +, +?, ?, ?? */ \
- 5, 5, /* CRRANGE, CRMINRANGE */ \
- 33, /* CLASS */ \
- 33, /* NCLASS */ \
- 0, /* XCLASS - variable length */ \
- 3, /* REF */ \
- 1+LINK_SIZE, /* RECURSE */ \
- 2+2*LINK_SIZE, /* CALLOUT */ \
- 1+LINK_SIZE, /* Alt */ \
- 1+LINK_SIZE, /* Ket */ \
- 1+LINK_SIZE, /* KetRmax */ \
- 1+LINK_SIZE, /* KetRmin */ \
- 1+LINK_SIZE, /* Assert */ \
- 1+LINK_SIZE, /* Assert not */ \
- 1+LINK_SIZE, /* Assert behind */ \
- 1+LINK_SIZE, /* Assert behind not */ \
- 1+LINK_SIZE, /* Reverse */ \
- 1+LINK_SIZE, /* ONCE */ \
- 1+LINK_SIZE, /* BRA */ \
- 3+LINK_SIZE, /* CBRA */ \
- 1+LINK_SIZE, /* COND */ \
- 1+LINK_SIZE, /* SBRA */ \
- 3+LINK_SIZE, /* SCBRA */ \
- 1+LINK_SIZE, /* SCOND */ \
- 3, /* CREF */ \
- 3, /* RREF */ \
- 1, /* DEF */ \
- 1, 1, /* BRAZERO, BRAMINZERO */ \
- 1, 1, 1, 1, /* PRUNE, SKIP, THEN, COMMIT, */ \
- 1, 1, 1 /* FAIL, ACCEPT, SKIPZERO */
-
-
-/* A magic value for OP_RREF to indicate the "any recursion" condition. */
-
-#define RREF_ANY 0xffff
-
-/* Error code numbers. They are given names so that they can more easily be
-tracked. */
-
-enum { ERR0, ERR1, ERR2, ERR3, ERR4, ERR5, ERR6, ERR7, ERR8, ERR9,
- ERR10, ERR11, ERR12, ERR13, ERR14, ERR15, ERR16, ERR17, ERR18, ERR19,
- ERR20, ERR21, ERR22, ERR23, ERR24, ERR25, ERR26, ERR27, ERR28, ERR29,
- ERR30, ERR31, ERR32, ERR33, ERR34, ERR35, ERR36, ERR37, ERR38, ERR39,
- ERR40, ERR41, ERR42, ERR43, ERR44, ERR45, ERR46, ERR47, ERR48, ERR49,
- ERR50, ERR51, ERR52, ERR53, ERR54, ERR55, ERR56, ERR57, ERR58, ERR59,
- ERR60, ERR61, ERR62, ERR63, ERR64 };
-
-/* The real format of the start of the pcre block; the index of names and the
-code vector run on as long as necessary after the end. We store an explicit
-offset to the name table so that if a regex is compiled on one host, saved, and
-then run on another where the size of pointers is different, all might still
-be well. For the case of compiled-on-4 and run-on-8, we include an extra
-pointer that is always NULL. For future-proofing, a few dummy fields were
-originally included - even though you can never get this planning right - but
-there is only one left now.
-
-NOTE NOTE NOTE:
-Because people can now save and re-use compiled patterns, any additions to this
-structure should be made at the end, and something earlier (e.g. a new
-flag in the options or one of the dummy fields) should indicate that the new
-fields are present. Currently PCRE always sets the dummy fields to zero.
-NOTE NOTE NOTE:
-*/
-
-typedef struct real_pcre {
- pcre_uint32 magic_number;
- pcre_uint32 size; /* Total that was malloced */
- pcre_uint32 options; /* Public options */
- pcre_uint16 flags; /* Private flags */
- pcre_uint16 dummy1; /* For future use */
- pcre_uint16 top_bracket;
- pcre_uint16 top_backref;
- pcre_uint16 first_byte;
- pcre_uint16 req_byte;
- pcre_uint16 name_table_offset; /* Offset to name table that follows */
- pcre_uint16 name_entry_size; /* Size of any name items */
- pcre_uint16 name_count; /* Number of name items */
- pcre_uint16 ref_count; /* Reference count */
-
- const unsigned char *tables; /* Pointer to tables or NULL for std */
- const unsigned char *nullpad; /* NULL padding */
-} real_pcre;
-
-/* The format of the block used to store data from pcre_study(). The same
-remark (see NOTE above) about extending this structure applies. */
-
-typedef struct pcre_study_data {
- pcre_uint32 size; /* Total that was malloced */
- pcre_uint32 options;
- uschar start_bits[32];
-} pcre_study_data;
-
-/* Structure for passing "static" information around between the functions
-doing the compiling, so that they are thread-safe. */
-
-typedef struct compile_data {
- const uschar *lcc; /* Points to lower casing table */
- const uschar *fcc; /* Points to case-flipping table */
- const uschar *cbits; /* Points to character type table */
- const uschar *ctypes; /* Points to table of type maps */
- const uschar *start_workspace;/* The start of working space */
- const uschar *start_code; /* The start of the compiled code */
- const uschar *start_pattern; /* The start of the pattern */
- const uschar *end_pattern; /* The end of the pattern */
- uschar *hwm; /* High watermark of workspace */
- uschar *name_table; /* The name/number table */
- int names_found; /* Number of entries so far */
- int name_entry_size; /* Size of each entry */
- int bracount; /* Count of capturing parens as we compile */
- int final_bracount; /* Saved value after first pass */
- int top_backref; /* Maximum back reference */
- unsigned int backref_map; /* Bitmap of low back refs */
- int external_options; /* External (initial) options */
- int external_flags; /* External flag bits to be set */
- int req_varyopt; /* "After variable item" flag for reqbyte */
- BOOL had_accept; /* (*ACCEPT) encountered */
- int nltype; /* Newline type */
- int nllen; /* Newline string length */
- uschar nl[4]; /* Newline string when fixed length */
-} compile_data;
-
-/* Structure for maintaining a chain of pointers to the currently incomplete
-branches, for testing for left recursion. */
-
-typedef struct branch_chain {
- struct branch_chain *outer;
- uschar *current;
-} branch_chain;
-
-/* Structure for items in a linked list that represents an explicit recursive
-call within the pattern. */
-
-typedef struct recursion_info {
- struct recursion_info *prevrec; /* Previous recursion record (or NULL) */
- int group_num; /* Number of group that was called */
- const uschar *after_call; /* "Return value": points after the call in the expr */
- USPTR save_start; /* Old value of mstart */
- int *offset_save; /* Pointer to start of saved offsets */
- int saved_max; /* Number of saved offsets */
-} recursion_info;
-
-/* Structure for building a chain of data for holding the values of the subject
-pointer at the start of each subpattern, so as to detect when an empty string
-has been matched by a subpattern - to break infinite loops. */
-
-typedef struct eptrblock {
- struct eptrblock *epb_prev;
- USPTR epb_saved_eptr;
-} eptrblock;
-
-
-/* Structure for passing "static" information around between the functions
-doing traditional NFA matching, so that they are thread-safe. */
-
-typedef struct match_data {
- unsigned long int match_call_count; /* As it says */
- unsigned long int match_limit; /* As it says */
- unsigned long int match_limit_recursion; /* As it says */
- int *offset_vector; /* Offset vector */
- int offset_end; /* One past the end */
- int offset_max; /* The maximum usable for return data */
- int nltype; /* Newline type */
- int nllen; /* Newline string length */
- uschar nl[4]; /* Newline string when fixed */
- const uschar *lcc; /* Points to lower casing table */
- const uschar *ctypes; /* Points to table of type maps */
- BOOL offset_overflow; /* Set if too many extractions */
- BOOL notbol; /* NOTBOL flag */
- BOOL noteol; /* NOTEOL flag */
- BOOL utf8; /* UTF8 flag */
- BOOL jscript_compat; /* JAVASCRIPT_COMPAT flag */
- BOOL endonly; /* Dollar not before final \n */
- BOOL notempty; /* Empty string match not wanted */
- BOOL partial; /* PARTIAL flag */
- BOOL hitend; /* Hit the end of the subject at some point */
- BOOL bsr_anycrlf; /* \R is just any CRLF, not full Unicode */
- const uschar *start_code; /* For use when recursing */
- USPTR start_subject; /* Start of the subject string */
- USPTR end_subject; /* End of the subject string */
- USPTR start_match_ptr; /* Start of matched string */
- USPTR end_match_ptr; /* Subject position at end match */
- int end_offset_top; /* Highwater mark at end of match */
- int capture_last; /* Most recent capture number */
- int start_offset; /* The start offset value */
- eptrblock *eptrchain; /* Chain of eptrblocks for tail recursions */
- int eptrn; /* Next free eptrblock */
- recursion_info *recursive; /* Linked list of recursion data */
- void *callout_data; /* To pass back to callouts */
-} match_data;
-
-/* A similar structure is used for the same purpose by the DFA matching
-functions. */
-
-typedef struct dfa_match_data {
- const uschar *start_code; /* Start of the compiled pattern */
- const uschar *start_subject; /* Start of the subject string */
- const uschar *end_subject; /* End of subject string */
- const uschar *tables; /* Character tables */
- int moptions; /* Match options */
- int poptions; /* Pattern options */
- int nltype; /* Newline type */
- int nllen; /* Newline string length */
- uschar nl[4]; /* Newline string when fixed */
- void *callout_data; /* To pass back to callouts */
-} dfa_match_data;
-
-/* Bit definitions for entries in the pcre_ctypes table. */
-
-#define ctype_space 0x01
-#define ctype_letter 0x02
-#define ctype_digit 0x04
-#define ctype_xdigit 0x08
-#define ctype_word 0x10 /* alphanumeric or '_' */
-#define ctype_meta 0x80 /* regexp meta char or zero (end pattern) */
-
-/* Offsets for the bitmap tables in pcre_cbits. Each table contains a set
-of bits for a class map. Some classes are built by combining these tables. */
-
-#define cbit_space 0 /* [:space:] or \s */
-#define cbit_xdigit 32 /* [:xdigit:] */
-#define cbit_digit 64 /* [:digit:] or \d */
-#define cbit_upper 96 /* [:upper:] */
-#define cbit_lower 128 /* [:lower:] */
-#define cbit_word 160 /* [:word:] or \w */
-#define cbit_graph 192 /* [:graph:] */
-#define cbit_print 224 /* [:print:] */
-#define cbit_punct 256 /* [:punct:] */
-#define cbit_cntrl 288 /* [:cntrl:] */
-#define cbit_length 320 /* Length of the cbits table */
-
-/* Offsets of the various tables from the base tables pointer, and
-total length. */
-
-#define lcc_offset 0
-#define fcc_offset 256
-#define cbits_offset 512
-#define ctypes_offset (cbits_offset + cbit_length)
-#define tables_length (ctypes_offset + 256)
-
-/* Layout of the UCP type table that translates property names into types and
-codes. Each entry used to point directly to a name, but to reduce the number of
-relocations in shared libraries, it now has an offset into a single string
-instead. */
-
-typedef struct {
- pcre_uint16 name_offset;
- pcre_uint16 type;
- pcre_uint16 value;
-} ucp_type_table;
-
-
-/* Internal shared data tables. These are tables that are used by more than one
-of the exported public functions. They have to be "external" in the C sense,
-but are not part of the PCRE public API. The data for these tables is in the
-pcre_tables.c module. */
-
-extern const int _pcre_utf8_table1[];
-extern const int _pcre_utf8_table2[];
-extern const int _pcre_utf8_table3[];
-extern const uschar _pcre_utf8_table4[];
-
-extern const int _pcre_utf8_table1_size;
-
-extern const char _pcre_utt_names[];
-extern const ucp_type_table _pcre_utt[];
-extern const int _pcre_utt_size;
-
-extern const uschar _pcre_default_tables[];
-
-extern const uschar _pcre_OP_lengths[];
-
-
-/* Internal shared functions. These are functions that are used by more than
-one of the exported public functions. They have to be "external" in the C
-sense, but are not part of the PCRE public API. */
-
-extern BOOL _pcre_is_newline(const uschar *, int, const uschar *,
- int *, BOOL);
-extern int _pcre_ord2utf8(int, uschar *);
-extern real_pcre *_pcre_try_flipped(const real_pcre *, real_pcre *,
- const pcre_study_data *, pcre_study_data *);
-extern int _pcre_ucp_findprop(const unsigned int, int *, int *);
-extern unsigned int _pcre_ucp_othercase(const unsigned int);
-extern int _pcre_valid_utf8(const uschar *, int);
-extern BOOL _pcre_was_newline(const uschar *, int, const uschar *,
- int *, BOOL);
-extern BOOL _pcre_xclass(int, const uschar *);
-
-#endif
-
-/* End of pcre_internal.h */
diff --git a/crawl-ref/source/util/pcre/pcre_maketables.c b/crawl-ref/source/util/pcre/pcre_maketables.c
deleted file mode 100644
index 219973e378..0000000000
--- a/crawl-ref/source/util/pcre/pcre_maketables.c
+++ /dev/null
@@ -1,143 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
- Written by Philip Hazel
- Copyright (c) 1997-2008 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-
-/* This module contains the external function pcre_maketables(), which builds
-character tables for PCRE in the current locale. The file is compiled on its
-own as part of the PCRE library. However, it is also included in the
-compilation of dftables.c, in which case the macro DFTABLES is defined. */
-
-
-#ifndef DFTABLES
-# ifdef HAVE_CONFIG_H
-# include "config.h"
-# endif
-# include "pcre_internal.h"
-#endif
-
-
-/*************************************************
-* Create PCRE character tables *
-*************************************************/
-
-/* This function builds a set of character tables for use by PCRE and returns
-a pointer to them. They are build using the ctype functions, and consequently
-their contents will depend upon the current locale setting. When compiled as
-part of the library, the store is obtained via pcre_malloc(), but when compiled
-inside dftables, use malloc().
-
-Arguments: none
-Returns: pointer to the contiguous block of data
-*/
-
-const unsigned char *
-pcre_maketables(void)
-{
-unsigned char *yield, *p;
-int i;
-
-#ifndef DFTABLES
-yield = (unsigned char*)(pcre_malloc)(tables_length);
-#else
-yield = (unsigned char*)malloc(tables_length);
-#endif
-
-if (yield == NULL) return NULL;
-p = yield;
-
-/* First comes the lower casing table */
-
-for (i = 0; i < 256; i++) *p++ = tolower(i);
-
-/* Next the case-flipping table */
-
-for (i = 0; i < 256; i++) *p++ = islower(i)? toupper(i) : tolower(i);
-
-/* Then the character class tables. Don't try to be clever and save effort on
-exclusive ones - in some locales things may be different. Note that the table
-for "space" includes everything "isspace" gives, including VT in the default
-locale. This makes it work for the POSIX class [:space:]. Note also that it is
-possible for a character to be alnum or alpha without being lower or upper,
-such as "male and female ordinals" (\xAA and \xBA) in the fr_FR locale (at
-least under Debian Linux's locales as of 12/2005). So we must test for alnum
-specially. */
-
-memset(p, 0, cbit_length);
-for (i = 0; i < 256; i++)
- {
- if (isdigit(i)) p[cbit_digit + i/8] |= 1 << (i&7);
- if (isupper(i)) p[cbit_upper + i/8] |= 1 << (i&7);
- if (islower(i)) p[cbit_lower + i/8] |= 1 << (i&7);
- if (isalnum(i)) p[cbit_word + i/8] |= 1 << (i&7);
- if (i == '_') p[cbit_word + i/8] |= 1 << (i&7);
- if (isspace(i)) p[cbit_space + i/8] |= 1 << (i&7);
- if (isxdigit(i))p[cbit_xdigit + i/8] |= 1 << (i&7);
- if (isgraph(i)) p[cbit_graph + i/8] |= 1 << (i&7);
- if (isprint(i)) p[cbit_print + i/8] |= 1 << (i&7);
- if (ispunct(i)) p[cbit_punct + i/8] |= 1 << (i&7);
- if (iscntrl(i)) p[cbit_cntrl + i/8] |= 1 << (i&7);
- }
-p += cbit_length;
-
-/* Finally, the character type table. In this, we exclude VT from the white
-space chars, because Perl doesn't recognize it as such for \s and for comments
-within regexes. */
-
-for (i = 0; i < 256; i++)
- {
- int x = 0;
- if (i != 0x0b && isspace(i)) x += ctype_space;
- if (isalpha(i)) x += ctype_letter;
- if (isdigit(i)) x += ctype_digit;
- if (isxdigit(i)) x += ctype_xdigit;
- if (isalnum(i) || i == '_') x += ctype_word;
-
- /* Note: strchr includes the terminating zero in the characters it considers.
- In this instance, that is ok because we want binary zero to be flagged as a
- meta-character, which in this sense is any character that terminates a run
- of data characters. */
-
- if (strchr("\\*+?{^.$|()[", i) != 0) x += ctype_meta;
- *p++ = x;
- }
-
-return yield;
-}
-
-/* End of pcre_maketables.c */
diff --git a/crawl-ref/source/util/pcre/pcre_newline.c b/crawl-ref/source/util/pcre/pcre_newline.c
deleted file mode 100644
index 58885760ef..0000000000
--- a/crawl-ref/source/util/pcre/pcre_newline.c
+++ /dev/null
@@ -1,164 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
- Written by Philip Hazel
- Copyright (c) 1997-2008 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-
-/* This module contains internal functions for testing newlines when more than
-one kind of newline is to be recognized. When a newline is found, its length is
-returned. In principle, we could implement several newline "types", each
-referring to a different set of newline characters. At present, PCRE supports
-only NLTYPE_FIXED, which gets handled without these functions, NLTYPE_ANYCRLF,
-and NLTYPE_ANY. The full list of Unicode newline characters is taken from
-http://unicode.org/unicode/reports/tr18/. */
-
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "pcre_internal.h"
-
-
-
-/*************************************************
-* Check for newline at given position *
-*************************************************/
-
-/* It is guaranteed that the initial value of ptr is less than the end of the
-string that is being processed.
-
-Arguments:
- ptr pointer to possible newline
- type the newline type
- endptr pointer to the end of the string
- lenptr where to return the length
- utf8 TRUE if in utf8 mode
-
-Returns: TRUE or FALSE
-*/
-
-BOOL
-_pcre_is_newline(const uschar *ptr, int type, const uschar *endptr,
- int *lenptr, BOOL utf8)
-{
-int c;
-if (utf8) { GETCHAR(c, ptr); } else c = *ptr;
-
-if (type == NLTYPE_ANYCRLF) switch(c)
- {
- case 0x000a: *lenptr = 1; return TRUE; /* LF */
- case 0x000d: *lenptr = (ptr < endptr - 1 && ptr[1] == 0x0a)? 2 : 1;
- return TRUE; /* CR */
- default: return FALSE;
- }
-
-/* NLTYPE_ANY */
-
-else switch(c)
- {
- case 0x000a: /* LF */
- case 0x000b: /* VT */
- case 0x000c: *lenptr = 1; return TRUE; /* FF */
- case 0x000d: *lenptr = (ptr < endptr - 1 && ptr[1] == 0x0a)? 2 : 1;
- return TRUE; /* CR */
- case 0x0085: *lenptr = utf8? 2 : 1; return TRUE; /* NEL */
- case 0x2028: /* LS */
- case 0x2029: *lenptr = 3; return TRUE; /* PS */
- default: return FALSE;
- }
-}
-
-
-
-/*************************************************
-* Check for newline at previous position *
-*************************************************/
-
-/* It is guaranteed that the initial value of ptr is greater than the start of
-the string that is being processed.
-
-Arguments:
- ptr pointer to possible newline
- type the newline type
- startptr pointer to the start of the string
- lenptr where to return the length
- utf8 TRUE if in utf8 mode
-
-Returns: TRUE or FALSE
-*/
-
-BOOL
-_pcre_was_newline(const uschar *ptr, int type, const uschar *startptr,
- int *lenptr, BOOL utf8)
-{
-int c;
-ptr--;
-#ifdef SUPPORT_UTF8
-if (utf8)
- {
- BACKCHAR(ptr);
- GETCHAR(c, ptr);
- }
-else c = *ptr;
-#else /* no UTF-8 support */
-c = *ptr;
-#endif /* SUPPORT_UTF8 */
-
-if (type == NLTYPE_ANYCRLF) switch(c)
- {
- case 0x000a: *lenptr = (ptr > startptr && ptr[-1] == 0x0d)? 2 : 1;
- return TRUE; /* LF */
- case 0x000d: *lenptr = 1; return TRUE; /* CR */
- default: return FALSE;
- }
-
-else switch(c)
- {
- case 0x000a: *lenptr = (ptr > startptr && ptr[-1] == 0x0d)? 2 : 1;
- return TRUE; /* LF */
- case 0x000b: /* VT */
- case 0x000c: /* FF */
- case 0x000d: *lenptr = 1; return TRUE; /* CR */
- case 0x0085: *lenptr = utf8? 2 : 1; return TRUE; /* NEL */
- case 0x2028: /* LS */
- case 0x2029: *lenptr = 3; return TRUE; /* PS */
- default: return FALSE;
- }
-}
-
-/* End of pcre_newline.c */
diff --git a/crawl-ref/source/util/pcre/pcre_ord2utf8.c b/crawl-ref/source/util/pcre/pcre_ord2utf8.c
deleted file mode 100644
index 0fdc512a00..0000000000
--- a/crawl-ref/source/util/pcre/pcre_ord2utf8.c
+++ /dev/null
@@ -1,85 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
- Written by Philip Hazel
- Copyright (c) 1997-2008 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-
-/* This file contains a private PCRE function that converts an ordinal
-character value into a UTF8 string. */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "pcre_internal.h"
-
-
-/*************************************************
-* Convert character value to UTF-8 *
-*************************************************/
-
-/* This function takes an integer value in the range 0 - 0x7fffffff
-and encodes it as a UTF-8 character in 0 to 6 bytes.
-
-Arguments:
- cvalue the character value
- buffer pointer to buffer for result - at least 6 bytes long
-
-Returns: number of characters placed in the buffer
-*/
-
-int
-_pcre_ord2utf8(int cvalue, uschar *buffer)
-{
-#ifdef SUPPORT_UTF8
-register int i, j;
-for (i = 0; i < _pcre_utf8_table1_size; i++)
- if (cvalue <= _pcre_utf8_table1[i]) break;
-buffer += i;
-for (j = i; j > 0; j--)
- {
- *buffer-- = 0x80 | (cvalue & 0x3f);
- cvalue >>= 6;
- }
-*buffer = _pcre_utf8_table2[i] | cvalue;
-return i + 1;
-#else
-return 0; /* Keep compiler happy; this function won't ever be */
-#endif /* called when SUPPORT_UTF8 is not defined. */
-}
-
-/* End of pcre_ord2utf8.c */
diff --git a/crawl-ref/source/util/pcre/pcre_printint.src b/crawl-ref/source/util/pcre/pcre_printint.src
deleted file mode 100644
index 98b42aa804..0000000000
--- a/crawl-ref/source/util/pcre/pcre_printint.src
+++ /dev/null
@@ -1,512 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
- Written by Philip Hazel
- Copyright (c) 1997-2008 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-
-/* This module contains a PCRE private debugging function for printing out the
-internal form of a compiled regular expression, along with some supporting
-local functions. This source file is used in two places:
-
-(1) It is #included by pcre_compile.c when it is compiled in debugging mode
-(DEBUG defined in pcre_internal.h). It is not included in production compiles.
-
-(2) It is always #included by pcretest.c, which can be asked to print out a
-compiled regex for debugging purposes. */
-
-
-/* Macro that decides whether a character should be output as a literal or in
-hexadecimal. We don't use isprint() because that can vary from system to system
-(even without the use of locales) and we want the output always to be the same,
-for testing purposes. This macro is used in pcretest as well as in this file. */
-
-#define PRINTABLE(c) ((c) >= 32 && (c) < 127)
-
-/* The table of operator names. */
-
-static const char *OP_names[] = { OP_NAME_LIST };
-
-
-
-/*************************************************
-* Print single- or multi-byte character *
-*************************************************/
-
-static int
-print_char(FILE *f, uschar *ptr, BOOL utf8)
-{
-int c = *ptr;
-
-#ifndef SUPPORT_UTF8
-utf8 = utf8; /* Avoid compiler warning */
-if (PRINTABLE(c)) fprintf(f, "%c", c); else fprintf(f, "\\x%02x", c);
-return 0;
-
-#else
-if (!utf8 || (c & 0xc0) != 0xc0)
- {
- if (PRINTABLE(c)) fprintf(f, "%c", c); else fprintf(f, "\\x%02x", c);
- return 0;
- }
-else
- {
- int i;
- int a = _pcre_utf8_table4[c & 0x3f]; /* Number of additional bytes */
- int s = 6*a;
- c = (c & _pcre_utf8_table3[a]) << s;
- for (i = 1; i <= a; i++)
- {
- /* This is a check for malformed UTF-8; it should only occur if the sanity
- check has been turned off. Rather than swallow random bytes, just stop if
- we hit a bad one. Print it with \X instead of \x as an indication. */
-
- if ((ptr[i] & 0xc0) != 0x80)
- {
- fprintf(f, "\\X{%x}", c);
- return i - 1;
- }
-
- /* The byte is OK */
-
- s -= 6;
- c |= (ptr[i] & 0x3f) << s;
- }
- if (c < 128) fprintf(f, "\\x%02x", c); else fprintf(f, "\\x{%x}", c);
- return a;
- }
-#endif
-}
-
-
-
-/*************************************************
-* Find Unicode property name *
-*************************************************/
-
-static const char *
-get_ucpname(int ptype, int pvalue)
-{
-#ifdef SUPPORT_UCP
-int i;
-for (i = _pcre_utt_size - 1; i >= 0; i--)
- {
- if (ptype == _pcre_utt[i].type && pvalue == _pcre_utt[i].value) break;
- }
-return (i >= 0)? _pcre_utt_names + _pcre_utt[i].name_offset : "??";
-#else
-/* It gets harder and harder to shut off unwanted compiler warnings. */
-ptype = ptype * pvalue;
-return (ptype == pvalue)? "??" : "??";
-#endif
-}
-
-
-
-/*************************************************
-* Print compiled regex *
-*************************************************/
-
-/* Make this function work for a regex with integers either byte order.
-However, we assume that what we are passed is a compiled regex. The
-print_lengths flag controls whether offsets and lengths of items are printed.
-They can be turned off from pcretest so that automatic tests on bytecode can be
-written that do not depend on the value of LINK_SIZE. */
-
-static void
-pcre_printint(pcre *external_re, FILE *f, BOOL print_lengths)
-{
-real_pcre *re = (real_pcre *)external_re;
-uschar *codestart, *code;
-BOOL utf8;
-
-unsigned int options = re->options;
-int offset = re->name_table_offset;
-int count = re->name_count;
-int size = re->name_entry_size;
-
-if (re->magic_number != MAGIC_NUMBER)
- {
- offset = ((offset << 8) & 0xff00) | ((offset >> 8) & 0xff);
- count = ((count << 8) & 0xff00) | ((count >> 8) & 0xff);
- size = ((size << 8) & 0xff00) | ((size >> 8) & 0xff);
- options = ((options << 24) & 0xff000000) |
- ((options << 8) & 0x00ff0000) |
- ((options >> 8) & 0x0000ff00) |
- ((options >> 24) & 0x000000ff);
- }
-
-code = codestart = (uschar *)re + offset + count * size;
-utf8 = (options & PCRE_UTF8) != 0;
-
-for(;;)
- {
- uschar *ccode;
- int c;
- int extra = 0;
-
- if (print_lengths)
- fprintf(f, "%3d ", (int)(code - codestart));
- else
- fprintf(f, " ");
-
- switch(*code)
- {
- case OP_END:
- fprintf(f, " %s\n", OP_names[*code]);
- fprintf(f, "------------------------------------------------------------------\n");
- return;
-
- case OP_OPT:
- fprintf(f, " %.2x %s", code[1], OP_names[*code]);
- break;
-
- case OP_CHAR:
- fprintf(f, " ");
- do
- {
- code++;
- code += 1 + print_char(f, code, utf8);
- }
- while (*code == OP_CHAR);
- fprintf(f, "\n");
- continue;
-
- case OP_CHARNC:
- fprintf(f, " NC ");
- do
- {
- code++;
- code += 1 + print_char(f, code, utf8);
- }
- while (*code == OP_CHARNC);
- fprintf(f, "\n");
- continue;
-
- case OP_CBRA:
- case OP_SCBRA:
- if (print_lengths) fprintf(f, "%3d ", GET(code, 1));
- else fprintf(f, " ");
- fprintf(f, "%s %d", OP_names[*code], GET2(code, 1+LINK_SIZE));
- break;
-
- case OP_BRA:
- case OP_SBRA:
- case OP_KETRMAX:
- case OP_KETRMIN:
- case OP_ALT:
- case OP_KET:
- case OP_ASSERT:
- case OP_ASSERT_NOT:
- case OP_ASSERTBACK:
- case OP_ASSERTBACK_NOT:
- case OP_ONCE:
- case OP_COND:
- case OP_SCOND:
- case OP_REVERSE:
- if (print_lengths) fprintf(f, "%3d ", GET(code, 1));
- else fprintf(f, " ");
- fprintf(f, "%s", OP_names[*code]);
- break;
-
- case OP_CREF:
- fprintf(f, "%3d %s", GET2(code,1), OP_names[*code]);
- break;
-
- case OP_RREF:
- c = GET2(code, 1);
- if (c == RREF_ANY)
- fprintf(f, " Cond recurse any");
- else
- fprintf(f, " Cond recurse %d", c);
- break;
-
- case OP_DEF:
- fprintf(f, " Cond def");
- break;
-
- case OP_STAR:
- case OP_MINSTAR:
- case OP_POSSTAR:
- case OP_PLUS:
- case OP_MINPLUS:
- case OP_POSPLUS:
- case OP_QUERY:
- case OP_MINQUERY:
- case OP_POSQUERY:
- case OP_TYPESTAR:
- case OP_TYPEMINSTAR:
- case OP_TYPEPOSSTAR:
- case OP_TYPEPLUS:
- case OP_TYPEMINPLUS:
- case OP_TYPEPOSPLUS:
- case OP_TYPEQUERY:
- case OP_TYPEMINQUERY:
- case OP_TYPEPOSQUERY:
- fprintf(f, " ");
- if (*code >= OP_TYPESTAR)
- {
- fprintf(f, "%s", OP_names[code[1]]);
- if (code[1] == OP_PROP || code[1] == OP_NOTPROP)
- {
- fprintf(f, " %s ", get_ucpname(code[2], code[3]));
- extra = 2;
- }
- }
- else extra = print_char(f, code+1, utf8);
- fprintf(f, "%s", OP_names[*code]);
- break;
-
- case OP_EXACT:
- case OP_UPTO:
- case OP_MINUPTO:
- case OP_POSUPTO:
- fprintf(f, " ");
- extra = print_char(f, code+3, utf8);
- fprintf(f, "{");
- if (*code != OP_EXACT) fprintf(f, "0,");
- fprintf(f, "%d}", GET2(code,1));
- if (*code == OP_MINUPTO) fprintf(f, "?");
- else if (*code == OP_POSUPTO) fprintf(f, "+");
- break;
-
- case OP_TYPEEXACT:
- case OP_TYPEUPTO:
- case OP_TYPEMINUPTO:
- case OP_TYPEPOSUPTO:
- fprintf(f, " %s", OP_names[code[3]]);
- if (code[3] == OP_PROP || code[3] == OP_NOTPROP)
- {
- fprintf(f, " %s ", get_ucpname(code[4], code[5]));
- extra = 2;
- }
- fprintf(f, "{");
- if (*code != OP_TYPEEXACT) fprintf(f, "0,");
- fprintf(f, "%d}", GET2(code,1));
- if (*code == OP_TYPEMINUPTO) fprintf(f, "?");
- else if (*code == OP_TYPEPOSUPTO) fprintf(f, "+");
- break;
-
- case OP_NOT:
- c = code[1];
- if (PRINTABLE(c)) fprintf(f, " [^%c]", c);
- else fprintf(f, " [^\\x%02x]", c);
- break;
-
- case OP_NOTSTAR:
- case OP_NOTMINSTAR:
- case OP_NOTPOSSTAR:
- case OP_NOTPLUS:
- case OP_NOTMINPLUS:
- case OP_NOTPOSPLUS:
- case OP_NOTQUERY:
- case OP_NOTMINQUERY:
- case OP_NOTPOSQUERY:
- c = code[1];
- if (PRINTABLE(c)) fprintf(f, " [^%c]", c);
- else fprintf(f, " [^\\x%02x]", c);
- fprintf(f, "%s", OP_names[*code]);
- break;
-
- case OP_NOTEXACT:
- case OP_NOTUPTO:
- case OP_NOTMINUPTO:
- case OP_NOTPOSUPTO:
- c = code[3];
- if (PRINTABLE(c)) fprintf(f, " [^%c]{", c);
- else fprintf(f, " [^\\x%02x]{", c);
- if (*code != OP_NOTEXACT) fprintf(f, "0,");
- fprintf(f, "%d}", GET2(code,1));
- if (*code == OP_NOTMINUPTO) fprintf(f, "?");
- else if (*code == OP_NOTPOSUPTO) fprintf(f, "+");
- break;
-
- case OP_RECURSE:
- if (print_lengths) fprintf(f, "%3d ", GET(code, 1));
- else fprintf(f, " ");
- fprintf(f, "%s", OP_names[*code]);
- break;
-
- case OP_REF:
- fprintf(f, " \\%d", GET2(code,1));
- ccode = code + _pcre_OP_lengths[*code];
- goto CLASS_REF_REPEAT;
-
- case OP_CALLOUT:
- fprintf(f, " %s %d %d %d", OP_names[*code], code[1], GET(code,2),
- GET(code, 2 + LINK_SIZE));
- break;
-
- case OP_PROP:
- case OP_NOTPROP:
- fprintf(f, " %s %s", OP_names[*code], get_ucpname(code[1], code[2]));
- break;
-
- /* OP_XCLASS can only occur in UTF-8 mode. However, there's no harm in
- having this code always here, and it makes it less messy without all those
- #ifdefs. */
-
- case OP_CLASS:
- case OP_NCLASS:
- case OP_XCLASS:
- {
- int i, min, max;
- BOOL printmap;
-
- fprintf(f, " [");
-
- if (*code == OP_XCLASS)
- {
- extra = GET(code, 1);
- ccode = code + LINK_SIZE + 1;
- printmap = (*ccode & XCL_MAP) != 0;
- if ((*ccode++ & XCL_NOT) != 0) fprintf(f, "^");
- }
- else
- {
- printmap = TRUE;
- ccode = code + 1;
- }
-
- /* Print a bit map */
-
- if (printmap)
- {
- for (i = 0; i < 256; i++)
- {
- if ((ccode[i/8] & (1 << (i&7))) != 0)
- {
- int j;
- for (j = i+1; j < 256; j++)
- if ((ccode[j/8] & (1 << (j&7))) == 0) break;
- if (i == '-' || i == ']') fprintf(f, "\\");
- if (PRINTABLE(i)) fprintf(f, "%c", i);
- else fprintf(f, "\\x%02x", i);
- if (--j > i)
- {
- if (j != i + 1) fprintf(f, "-");
- if (j == '-' || j == ']') fprintf(f, "\\");
- if (PRINTABLE(j)) fprintf(f, "%c", j);
- else fprintf(f, "\\x%02x", j);
- }
- i = j;
- }
- }
- ccode += 32;
- }
-
- /* For an XCLASS there is always some additional data */
-
- if (*code == OP_XCLASS)
- {
- int ch;
- while ((ch = *ccode++) != XCL_END)
- {
- if (ch == XCL_PROP)
- {
- int ptype = *ccode++;
- int pvalue = *ccode++;
- fprintf(f, "\\p{%s}", get_ucpname(ptype, pvalue));
- }
- else if (ch == XCL_NOTPROP)
- {
- int ptype = *ccode++;
- int pvalue = *ccode++;
- fprintf(f, "\\P{%s}", get_ucpname(ptype, pvalue));
- }
- else
- {
- ccode += 1 + print_char(f, ccode, TRUE);
- if (ch == XCL_RANGE)
- {
- fprintf(f, "-");
- ccode += 1 + print_char(f, ccode, TRUE);
- }
- }
- }
- }
-
- /* Indicate a non-UTF8 class which was created by negation */
-
- fprintf(f, "]%s", (*code == OP_NCLASS)? " (neg)" : "");
-
- /* Handle repeats after a class or a back reference */
-
- CLASS_REF_REPEAT:
- switch(*ccode)
- {
- case OP_CRSTAR:
- case OP_CRMINSTAR:
- case OP_CRPLUS:
- case OP_CRMINPLUS:
- case OP_CRQUERY:
- case OP_CRMINQUERY:
- fprintf(f, "%s", OP_names[*ccode]);
- extra += _pcre_OP_lengths[*ccode];
- break;
-
- case OP_CRRANGE:
- case OP_CRMINRANGE:
- min = GET2(ccode,1);
- max = GET2(ccode,3);
- if (max == 0) fprintf(f, "{%d,}", min);
- else fprintf(f, "{%d,%d}", min, max);
- if (*ccode == OP_CRMINRANGE) fprintf(f, "?");
- extra += _pcre_OP_lengths[*ccode];
- break;
-
- /* Do nothing if it's not a repeat; this code stops picky compilers
- warning about the lack of a default code path. */
-
- default:
- break;
- }
- }
- break;
-
- /* Anything else is just an item with no data*/
-
- default:
- fprintf(f, " %s", OP_names[*code]);
- break;
- }
-
- code += _pcre_OP_lengths[*code] + extra;
- fprintf(f, "\n");
- }
-}
-
-/* End of pcre_printint.src */
diff --git a/crawl-ref/source/util/pcre/pcre_refcount.c b/crawl-ref/source/util/pcre/pcre_refcount.c
deleted file mode 100644
index eeb2897c82..0000000000
--- a/crawl-ref/source/util/pcre/pcre_refcount.c
+++ /dev/null
@@ -1,82 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
- Written by Philip Hazel
- Copyright (c) 1997-2008 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-
-/* This module contains the external function pcre_refcount(), which is an
-auxiliary function that can be used to maintain a reference count in a compiled
-pattern data block. This might be helpful in applications where the block is
-shared by different users. */
-
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "pcre_internal.h"
-
-
-/*************************************************
-* Maintain reference count *
-*************************************************/
-
-/* The reference count is a 16-bit field, initialized to zero. It is not
-possible to transfer a non-zero count from one host to a different host that
-has a different byte order - though I can't see why anyone in their right mind
-would ever want to do that!
-
-Arguments:
- argument_re points to compiled code
- adjust value to add to the count
-
-Returns: the (possibly updated) count value (a non-negative number), or
- a negative error number
-*/
-
-PCRE_EXP_DEFN int
-pcre_refcount(pcre *argument_re, int adjust)
-{
-real_pcre *re = (real_pcre *)argument_re;
-if (re == NULL) return PCRE_ERROR_NULL;
-re->ref_count = (-adjust > re->ref_count)? 0 :
- (adjust + re->ref_count > 65535)? 65535 :
- re->ref_count + adjust;
-return re->ref_count;
-}
-
-/* End of pcre_refcount.c */
diff --git a/crawl-ref/source/util/pcre/pcre_scanner.cc b/crawl-ref/source/util/pcre/pcre_scanner.cc
deleted file mode 100644
index a817a684e2..0000000000
--- a/crawl-ref/source/util/pcre/pcre_scanner.cc
+++ /dev/null
@@ -1,199 +0,0 @@
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// Author: Sanjay Ghemawat
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <vector>
-#include <assert.h>
-
-#include "pcrecpp_internal.h"
-#include "pcre_scanner.h"
-
-using std::vector;
-
-namespace pcrecpp {
-
-Scanner::Scanner()
- : data_(),
- input_(data_),
- skip_(NULL),
- should_skip_(false),
- skip_repeat_(false),
- save_comments_(false),
- comments_(NULL),
- comments_offset_(0) {
-}
-
-Scanner::Scanner(const string& in)
- : data_(in),
- input_(data_),
- skip_(NULL),
- should_skip_(false),
- skip_repeat_(false),
- save_comments_(false),
- comments_(NULL),
- comments_offset_(0) {
-}
-
-Scanner::~Scanner() {
- delete skip_;
- delete comments_;
-}
-
-void Scanner::SetSkipExpression(const char* re) {
- delete skip_;
- if (re != NULL) {
- skip_ = new RE(re);
- should_skip_ = true;
- skip_repeat_ = true;
- ConsumeSkip();
- } else {
- skip_ = NULL;
- should_skip_ = false;
- skip_repeat_ = false;
- }
-}
-
-void Scanner::Skip(const char* re) {
- delete skip_;
- if (re != NULL) {
- skip_ = new RE(re);
- should_skip_ = true;
- skip_repeat_ = false;
- ConsumeSkip();
- } else {
- skip_ = NULL;
- should_skip_ = false;
- skip_repeat_ = false;
- }
-}
-
-void Scanner::DisableSkip() {
- assert(skip_ != NULL);
- should_skip_ = false;
-}
-
-void Scanner::EnableSkip() {
- assert(skip_ != NULL);
- should_skip_ = true;
- ConsumeSkip();
-}
-
-int Scanner::LineNumber() const {
- // TODO: Make it more efficient by keeping track of the last point
- // where we computed line numbers and counting newlines since then.
- // We could use std:count, but not all systems have it. :-(
- int count = 1;
- for (const char* p = data_.data(); p < input_.data(); ++p)
- if (*p == '\n')
- ++count;
- return count;
-}
-
-int Scanner::Offset() const {
- return input_.data() - data_.c_str();
-}
-
-bool Scanner::LookingAt(const RE& re) const {
- int consumed;
- return re.DoMatch(input_, RE::ANCHOR_START, &consumed, 0, 0);
-}
-
-
-bool Scanner::Consume(const RE& re,
- const Arg& arg0,
- const Arg& arg1,
- const Arg& arg2) {
- const bool result = re.Consume(&input_, arg0, arg1, arg2);
- if (result && should_skip_) ConsumeSkip();
- return result;
-}
-
-// helper function to consume *skip_ and honour save_comments_
-void Scanner::ConsumeSkip() {
- const char* start_data = input_.data();
- while (skip_->Consume(&input_)) {
- if (!skip_repeat_) {
- // Only one skip allowed.
- break;
- }
- }
- if (save_comments_) {
- if (comments_ == NULL) {
- comments_ = new vector<StringPiece>;
- }
- // already pointing one past end, so no need to +1
- int length = input_.data() - start_data;
- if (length > 0) {
- comments_->push_back(StringPiece(start_data, length));
- }
- }
-}
-
-
-void Scanner::GetComments(int start, int end, vector<StringPiece> *ranges) {
- // short circuit out if we've not yet initialized comments_
- // (e.g., when save_comments is false)
- if (!comments_) {
- return;
- }
- // TODO: if we guarantee that comments_ will contain StringPieces
- // that are ordered by their start, then we can do a binary search
- // for the first StringPiece at or past start and then scan for the
- // ones contained in the range, quit early (use equal_range or
- // lower_bound)
- for (vector<StringPiece>::const_iterator it = comments_->begin();
- it != comments_->end(); ++it) {
- if ((it->data() >= data_.c_str() + start &&
- it->data() + it->size() <= data_.c_str() + end)) {
- ranges->push_back(*it);
- }
- }
-}
-
-
-void Scanner::GetNextComments(vector<StringPiece> *ranges) {
- // short circuit out if we've not yet initialized comments_
- // (e.g., when save_comments is false)
- if (!comments_) {
- return;
- }
- for (vector<StringPiece>::const_iterator it =
- comments_->begin() + comments_offset_;
- it != comments_->end(); ++it) {
- ranges->push_back(*it);
- ++comments_offset_;
- }
-}
-
-} // namespace pcrecpp
diff --git a/crawl-ref/source/util/pcre/pcre_scanner.h b/crawl-ref/source/util/pcre/pcre_scanner.h
deleted file mode 100644
index 5617e4515c..0000000000
--- a/crawl-ref/source/util/pcre/pcre_scanner.h
+++ /dev/null
@@ -1,172 +0,0 @@
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// Author: Sanjay Ghemawat
-//
-// Regular-expression based scanner for parsing an input stream.
-//
-// Example 1: parse a sequence of "var = number" entries from input:
-//
-// Scanner scanner(input);
-// string var;
-// int number;
-// scanner.SetSkipExpression("\\s+"); // Skip any white space we encounter
-// while (scanner.Consume("(\\w+) = (\\d+)", &var, &number)) {
-// ...;
-// }
-
-#ifndef _PCRE_SCANNER_H
-#define _PCRE_SCANNER_H
-
-#include <assert.h>
-#include <string>
-#include <vector>
-
-#include <pcrecpp.h>
-#include <pcre_stringpiece.h>
-
-namespace pcrecpp {
-
-class PCRECPP_EXP_DEFN Scanner {
- public:
- Scanner();
- explicit Scanner(const std::string& input);
- ~Scanner();
-
- // Return current line number. The returned line-number is
- // one-based. I.e. it returns 1 + the number of consumed newlines.
- //
- // Note: this method may be slow. It may take time proportional to
- // the size of the input.
- int LineNumber() const;
-
- // Return the byte-offset that the scanner is looking in the
- // input data;
- int Offset() const;
-
- // Return true iff the start of the remaining input matches "re"
- bool LookingAt(const RE& re) const;
-
- // Return true iff all of the following are true
- // a. the start of the remaining input matches "re",
- // b. if any arguments are supplied, matched sub-patterns can be
- // parsed and stored into the arguments.
- // If it returns true, it skips over the matched input and any
- // following input that matches the "skip" regular expression.
- bool Consume(const RE& re,
- const Arg& arg0 = RE::no_arg,
- const Arg& arg1 = RE::no_arg,
- const Arg& arg2 = RE::no_arg
- // TODO: Allow more arguments?
- );
-
- // Set the "skip" regular expression. If after consuming some data,
- // a prefix of the input matches this RE, it is automatically
- // skipped. For example, a programming language scanner would use
- // a skip RE that matches white space and comments.
- //
- // scanner.SetSkipExpression("\\s+|//.*|/[*](.|\n)*?[*]/");
- //
- // Skipping repeats as long as it succeeds. We used to let people do
- // this by writing "(...)*" in the regular expression, but that added
- // up to lots of recursive calls within the pcre library, so now we
- // control repetition explicitly via the function call API.
- //
- // You can pass NULL for "re" if you do not want any data to be skipped.
- void Skip(const char* re); // DEPRECATED; does *not* repeat
- void SetSkipExpression(const char* re);
-
- // Temporarily pause "skip"ing. This
- // Skip("Foo"); code ; DisableSkip(); code; EnableSkip()
- // is similar to
- // Skip("Foo"); code ; Skip(NULL); code ; Skip("Foo");
- // but avoids creating/deleting new RE objects.
- void DisableSkip();
-
- // Reenable previously paused skipping. Any prefix of the input
- // that matches the skip pattern is immediately dropped.
- void EnableSkip();
-
- /***** Special wrappers around SetSkip() for some common idioms *****/
-
- // Arranges to skip whitespace, C comments, C++ comments.
- // The overall RE is a disjunction of the following REs:
- // \\s whitespace
- // //.*\n C++ comment
- // /[*](.|\n)*?[*]/ C comment (x*? means minimal repetitions of x)
- // We get repetition via the semantics of SetSkipExpression, not by using *
- void SkipCXXComments() {
- SetSkipExpression("\\s|//.*\n|/[*](?:\n|.)*?[*]/");
- }
-
- void set_save_comments(bool comments) {
- save_comments_ = comments;
- }
-
- bool save_comments() {
- return save_comments_;
- }
-
- // Append to vector ranges the comments found in the
- // byte range [start,end] (inclusive) of the input data.
- // Only comments that were extracted entirely within that
- // range are returned: no range splitting of atomically-extracted
- // comments is performed.
- void GetComments(int start, int end, std::vector<StringPiece> *ranges);
-
- // Append to vector ranges the comments added
- // since the last time this was called. This
- // functionality is provided for efficiency when
- // interleaving scanning with parsing.
- void GetNextComments(std::vector<StringPiece> *ranges);
-
- private:
- std::string data_; // All the input data
- StringPiece input_; // Unprocessed input
- RE* skip_; // If non-NULL, RE for skipping input
- bool should_skip_; // If true, use skip_
- bool skip_repeat_; // If true, repeat skip_ as long as it works
- bool save_comments_; // If true, aggregate the skip expression
-
- // the skipped comments
- // TODO: later consider requiring that the StringPieces be added
- // in order by their start position
- std::vector<StringPiece> *comments_;
-
- // the offset into comments_ that has been returned by GetNextComments
- int comments_offset_;
-
- // helper function to consume *skip_ and honour
- // save_comments_
- void ConsumeSkip();
-};
-
-} // namespace pcrecpp
-
-#endif /* _PCRE_SCANNER_H */
diff --git a/crawl-ref/source/util/pcre/pcre_scanner_unittest.cc b/crawl-ref/source/util/pcre/pcre_scanner_unittest.cc
deleted file mode 100644
index 284c8ea99e..0000000000
--- a/crawl-ref/source/util/pcre/pcre_scanner_unittest.cc
+++ /dev/null
@@ -1,158 +0,0 @@
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// Author: Greg J. Badros
-//
-// Unittest for scanner, especially GetNextComments and GetComments()
-// functionality.
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <stdio.h>
-#include <string>
-#include <vector>
-
-#include "pcrecpp.h"
-#include "pcre_stringpiece.h"
-#include "pcre_scanner.h"
-
-#define FLAGS_unittest_stack_size 49152
-
-// Dies with a fatal error if the two values are not equal.
-#define CHECK_EQ(a, b) do { \
- if ( (a) != (b) ) { \
- fprintf(stderr, "%s:%d: Check failed because %s != %s\n", \
- __FILE__, __LINE__, #a, #b); \
- exit(1); \
- } \
-} while (0)
-
-using std::vector;
-using pcrecpp::StringPiece;
-using pcrecpp::Scanner;
-
-static void TestScanner() {
- const char input[] = "\n"
- "alpha = 1; // this sets alpha\n"
- "bravo = 2; // bravo is set here\n"
- "gamma = 33; /* and here is gamma */\n";
-
- const char *re = "(\\w+) = (\\d+);";
-
- Scanner s(input);
- string var;
- int number;
- s.SkipCXXComments();
- s.set_save_comments(true);
- vector<StringPiece> comments;
-
- s.Consume(re, &var, &number);
- CHECK_EQ(var, "alpha");
- CHECK_EQ(number, 1);
- CHECK_EQ(s.LineNumber(), 3);
- s.GetNextComments(&comments);
- CHECK_EQ(comments.size(), 1);
- CHECK_EQ(comments[0].as_string(), " // this sets alpha\n");
- comments.resize(0);
-
- s.Consume(re, &var, &number);
- CHECK_EQ(var, "bravo");
- CHECK_EQ(number, 2);
- s.GetNextComments(&comments);
- CHECK_EQ(comments.size(), 1);
- CHECK_EQ(comments[0].as_string(), " // bravo is set here\n");
- comments.resize(0);
-
- s.Consume(re, &var, &number);
- CHECK_EQ(var, "gamma");
- CHECK_EQ(number, 33);
- s.GetNextComments(&comments);
- CHECK_EQ(comments.size(), 1);
- CHECK_EQ(comments[0].as_string(), " /* and here is gamma */\n");
- comments.resize(0);
-
- s.GetComments(0, sizeof(input), &comments);
- CHECK_EQ(comments.size(), 3);
- CHECK_EQ(comments[0].as_string(), " // this sets alpha\n");
- CHECK_EQ(comments[1].as_string(), " // bravo is set here\n");
- CHECK_EQ(comments[2].as_string(), " /* and here is gamma */\n");
- comments.resize(0);
-
- s.GetComments(0, strchr(input, '/') - input, &comments);
- CHECK_EQ(comments.size(), 0);
- comments.resize(0);
-
- s.GetComments(strchr(input, '/') - input - 1, sizeof(input),
- &comments);
- CHECK_EQ(comments.size(), 3);
- CHECK_EQ(comments[0].as_string(), " // this sets alpha\n");
- CHECK_EQ(comments[1].as_string(), " // bravo is set here\n");
- CHECK_EQ(comments[2].as_string(), " /* and here is gamma */\n");
- comments.resize(0);
-
- s.GetComments(strchr(input, '/') - input - 1,
- strchr(input + 1, '\n') - input + 1, &comments);
- CHECK_EQ(comments.size(), 1);
- CHECK_EQ(comments[0].as_string(), " // this sets alpha\n");
- comments.resize(0);
-}
-
-static void TestBigComment() {
- string input;
- for (int i = 0; i < 1024; ++i) {
- char buf[1024]; // definitely big enough
- sprintf(buf, " # Comment %d\n", i);
- input += buf;
- }
- input += "name = value;\n";
-
- Scanner s(input.c_str());
- s.SetSkipExpression("\\s+|#.*\n");
-
- string name;
- string value;
- s.Consume("(\\w+) = (\\w+);", &name, &value);
- CHECK_EQ(name, "name");
- CHECK_EQ(value, "value");
-}
-
-// TODO: also test scanner and big-comment in a thread with a
-// small stack size
-
-int main(int argc, char** argv) {
- TestScanner();
- TestBigComment();
-
- // Done
- printf("OK\n");
-
- return 0;
-}
diff --git a/crawl-ref/source/util/pcre/pcre_stringpiece.cc b/crawl-ref/source/util/pcre/pcre_stringpiece.cc
deleted file mode 100644
index 67c0f1fc0e..0000000000
--- a/crawl-ref/source/util/pcre/pcre_stringpiece.cc
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// Author: wilsonh@google.com (Wilson Hsieh)
-//
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <iostream>
-#include "pcrecpp_internal.h"
-#include "pcre_stringpiece.h"
-
-std::ostream& operator<<(std::ostream& o, const pcrecpp::StringPiece& piece) {
- return (o << piece.as_string());
-}
diff --git a/crawl-ref/source/util/pcre/pcre_stringpiece.h.in b/crawl-ref/source/util/pcre/pcre_stringpiece.h.in
deleted file mode 100644
index b017661eb4..0000000000
--- a/crawl-ref/source/util/pcre/pcre_stringpiece.h.in
+++ /dev/null
@@ -1,177 +0,0 @@
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// Author: Sanjay Ghemawat
-//
-// A string like object that points into another piece of memory.
-// Useful for providing an interface that allows clients to easily
-// pass in either a "const char*" or a "string".
-//
-// Arghh! I wish C++ literals were automatically of type "string".
-
-#ifndef _PCRE_STRINGPIECE_H
-#define _PCRE_STRINGPIECE_H
-
-#include <string.h>
-#include <string>
-#include <iosfwd> // for ostream forward-declaration
-
-#if @pcre_have_type_traits@
-#define HAVE_TYPE_TRAITS
-#include <type_traits.h>
-#elif @pcre_have_bits_type_traits@
-#define HAVE_TYPE_TRAITS
-#include <bits/type_traits.h>
-#endif
-
-#include <pcre.h>
-
-using std::string;
-
-namespace pcrecpp {
-
-class PCRECPP_EXP_DEFN StringPiece {
- private:
- const char* ptr_;
- int length_;
-
- public:
- // We provide non-explicit singleton constructors so users can pass
- // in a "const char*" or a "string" wherever a "StringPiece" is
- // expected.
- StringPiece()
- : ptr_(NULL), length_(0) { }
- StringPiece(const char* str)
- : ptr_(str), length_(static_cast<int>(strlen(ptr_))) { }
- StringPiece(const unsigned char* str)
- : ptr_(reinterpret_cast<const char*>(str)),
- length_(static_cast<int>(strlen(ptr_))) { }
- StringPiece(const string& str)
- : ptr_(str.data()), length_(static_cast<int>(str.size())) { }
- StringPiece(const char* offset, int len)
- : ptr_(offset), length_(len) { }
-
- // data() may return a pointer to a buffer with embedded NULs, and the
- // returned buffer may or may not be null terminated. Therefore it is
- // typically a mistake to pass data() to a routine that expects a NUL
- // terminated string. Use "as_string().c_str()" if you really need to do
- // this. Or better yet, change your routine so it does not rely on NUL
- // termination.
- const char* data() const { return ptr_; }
- int size() const { return length_; }
- bool empty() const { return length_ == 0; }
-
- void clear() { ptr_ = NULL; length_ = 0; }
- void set(const char* buffer, int len) { ptr_ = buffer; length_ = len; }
- void set(const char* str) {
- ptr_ = str;
- length_ = static_cast<int>(strlen(str));
- }
- void set(const void* buffer, int len) {
- ptr_ = reinterpret_cast<const char*>(buffer);
- length_ = len;
- }
-
- char operator[](int i) const { return ptr_[i]; }
-
- void remove_prefix(int n) {
- ptr_ += n;
- length_ -= n;
- }
-
- void remove_suffix(int n) {
- length_ -= n;
- }
-
- bool operator==(const StringPiece& x) const {
- return ((length_ == x.length_) &&
- (memcmp(ptr_, x.ptr_, length_) == 0));
- }
- bool operator!=(const StringPiece& x) const {
- return !(*this == x);
- }
-
-#define STRINGPIECE_BINARY_PREDICATE(cmp,auxcmp) \
- bool operator cmp (const StringPiece& x) const { \
- int r = memcmp(ptr_, x.ptr_, length_ < x.length_ ? length_ : x.length_); \
- return ((r auxcmp 0) || ((r == 0) && (length_ cmp x.length_))); \
- }
- STRINGPIECE_BINARY_PREDICATE(<, <);
- STRINGPIECE_BINARY_PREDICATE(<=, <);
- STRINGPIECE_BINARY_PREDICATE(>=, >);
- STRINGPIECE_BINARY_PREDICATE(>, >);
-#undef STRINGPIECE_BINARY_PREDICATE
-
- int compare(const StringPiece& x) const {
- int r = memcmp(ptr_, x.ptr_, length_ < x.length_ ? length_ : x.length_);
- if (r == 0) {
- if (length_ < x.length_) r = -1;
- else if (length_ > x.length_) r = +1;
- }
- return r;
- }
-
- string as_string() const {
- return string(data(), size());
- }
-
- void CopyToString(string* target) const {
- target->assign(ptr_, length_);
- }
-
- // Does "this" start with "x"
- bool starts_with(const StringPiece& x) const {
- return ((length_ >= x.length_) && (memcmp(ptr_, x.ptr_, x.length_) == 0));
- }
-};
-
-} // namespace pcrecpp
-
-// ------------------------------------------------------------------
-// Functions used to create STL containers that use StringPiece
-// Remember that a StringPiece's lifetime had better be less than
-// that of the underlying string or char*. If it is not, then you
-// cannot safely store a StringPiece into an STL container
-// ------------------------------------------------------------------
-
-#ifdef HAVE_TYPE_TRAITS
-// This makes vector<StringPiece> really fast for some STL implementations
-template<> struct __type_traits<pcrecpp::StringPiece> {
- typedef __true_type has_trivial_default_constructor;
- typedef __true_type has_trivial_copy_constructor;
- typedef __true_type has_trivial_assignment_operator;
- typedef __true_type has_trivial_destructor;
- typedef __true_type is_POD_type;
-};
-#endif
-
-// allow StringPiece to be logged
-std::ostream& operator<<(std::ostream& o, const pcrecpp::StringPiece& piece);
-
-#endif /* _PCRE_STRINGPIECE_H */
diff --git a/crawl-ref/source/util/pcre/pcre_stringpiece_unittest.cc b/crawl-ref/source/util/pcre/pcre_stringpiece_unittest.cc
deleted file mode 100644
index 1e821ab6e4..0000000000
--- a/crawl-ref/source/util/pcre/pcre_stringpiece_unittest.cc
+++ /dev/null
@@ -1,151 +0,0 @@
-// Copyright 2003 and onwards Google Inc.
-// Author: Sanjay Ghemawat
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <stdio.h>
-#include <map>
-#include <algorithm> // for make_pair
-
-#include "pcrecpp.h"
-#include "pcre_stringpiece.h"
-
-// CHECK dies with a fatal error if condition is not true. It is *not*
-// controlled by NDEBUG, so the check will be executed regardless of
-// compilation mode. Therefore, it is safe to do things like:
-// CHECK(fp->Write(x) == 4)
-#define CHECK(condition) do { \
- if (!(condition)) { \
- fprintf(stderr, "%s:%d: Check failed: %s\n", \
- __FILE__, __LINE__, #condition); \
- exit(1); \
- } \
-} while (0)
-
-using std::map;
-using std::make_pair;
-using pcrecpp::StringPiece;
-
-static void CheckSTLComparator() {
- string s1("foo");
- string s2("bar");
- string s3("baz");
-
- StringPiece p1(s1);
- StringPiece p2(s2);
- StringPiece p3(s3);
-
- typedef map<StringPiece, int> TestMap;
- TestMap map;
-
- map.insert(make_pair(p1, 0));
- map.insert(make_pair(p2, 1));
- map.insert(make_pair(p3, 2));
- CHECK(map.size() == 3);
-
- TestMap::const_iterator iter = map.begin();
- CHECK(iter->second == 1);
- ++iter;
- CHECK(iter->second == 2);
- ++iter;
- CHECK(iter->second == 0);
- ++iter;
- CHECK(iter == map.end());
-
- TestMap::iterator new_iter = map.find("zot");
- CHECK(new_iter == map.end());
-
- new_iter = map.find("bar");
- CHECK(new_iter != map.end());
-
- map.erase(new_iter);
- CHECK(map.size() == 2);
-
- iter = map.begin();
- CHECK(iter->second == 2);
- ++iter;
- CHECK(iter->second == 0);
- ++iter;
- CHECK(iter == map.end());
-}
-
-static void CheckComparisonOperators() {
-#define CMP_Y(op, x, y) \
- CHECK( (StringPiece((x)) op StringPiece((y)))); \
- CHECK( (StringPiece((x)).compare(StringPiece((y))) op 0))
-
-#define CMP_N(op, x, y) \
- CHECK(!(StringPiece((x)) op StringPiece((y)))); \
- CHECK(!(StringPiece((x)).compare(StringPiece((y))) op 0))
-
- CMP_Y(==, "", "");
- CMP_Y(==, "a", "a");
- CMP_Y(==, "aa", "aa");
- CMP_N(==, "a", "");
- CMP_N(==, "", "a");
- CMP_N(==, "a", "b");
- CMP_N(==, "a", "aa");
- CMP_N(==, "aa", "a");
-
- CMP_N(!=, "", "");
- CMP_N(!=, "a", "a");
- CMP_N(!=, "aa", "aa");
- CMP_Y(!=, "a", "");
- CMP_Y(!=, "", "a");
- CMP_Y(!=, "a", "b");
- CMP_Y(!=, "a", "aa");
- CMP_Y(!=, "aa", "a");
-
- CMP_Y(<, "a", "b");
- CMP_Y(<, "a", "aa");
- CMP_Y(<, "aa", "b");
- CMP_Y(<, "aa", "bb");
- CMP_N(<, "a", "a");
- CMP_N(<, "b", "a");
- CMP_N(<, "aa", "a");
- CMP_N(<, "b", "aa");
- CMP_N(<, "bb", "aa");
-
- CMP_Y(<=, "a", "a");
- CMP_Y(<=, "a", "b");
- CMP_Y(<=, "a", "aa");
- CMP_Y(<=, "aa", "b");
- CMP_Y(<=, "aa", "bb");
- CMP_N(<=, "b", "a");
- CMP_N(<=, "aa", "a");
- CMP_N(<=, "b", "aa");
- CMP_N(<=, "bb", "aa");
-
- CMP_N(>=, "a", "b");
- CMP_N(>=, "a", "aa");
- CMP_N(>=, "aa", "b");
- CMP_N(>=, "aa", "bb");
- CMP_Y(>=, "a", "a");
- CMP_Y(>=, "b", "a");
- CMP_Y(>=, "aa", "a");
- CMP_Y(>=, "b", "aa");
- CMP_Y(>=, "bb", "aa");
-
- CMP_N(>, "a", "a");
- CMP_N(>, "a", "b");
- CMP_N(>, "a", "aa");
- CMP_N(>, "aa", "b");
- CMP_N(>, "aa", "bb");
- CMP_Y(>, "b", "a");
- CMP_Y(>, "aa", "a");
- CMP_Y(>, "b", "aa");
- CMP_Y(>, "bb", "aa");
-
-#undef CMP_Y
-#undef CMP_N
-}
-
-int main(int argc, char** argv) {
- CheckComparisonOperators();
- CheckSTLComparator();
-
- printf("OK\n");
- return 0;
-}
diff --git a/crawl-ref/source/util/pcre/pcre_study.c b/crawl-ref/source/util/pcre/pcre_study.c
deleted file mode 100644
index e4e24b61e7..0000000000
--- a/crawl-ref/source/util/pcre/pcre_study.c
+++ /dev/null
@@ -1,587 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
- Written by Philip Hazel
- Copyright (c) 1997-2008 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-
-/* This module contains the external function pcre_study(), along with local
-supporting functions. */
-
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "pcre_internal.h"
-
-
-/* Returns from set_start_bits() */
-
-enum { SSB_FAIL, SSB_DONE, SSB_CONTINUE };
-
-
-/*************************************************
-* Set a bit and maybe its alternate case *
-*************************************************/
-
-/* Given a character, set its bit in the table, and also the bit for the other
-version of a letter if we are caseless.
-
-Arguments:
- start_bits points to the bit map
- c is the character
- caseless the caseless flag
- cd the block with char table pointers
-
-Returns: nothing
-*/
-
-static void
-set_bit(uschar *start_bits, unsigned int c, BOOL caseless, compile_data *cd)
-{
-start_bits[c/8] |= (1 << (c&7));
-if (caseless && (cd->ctypes[c] & ctype_letter) != 0)
- start_bits[cd->fcc[c]/8] |= (1 << (cd->fcc[c]&7));
-}
-
-
-
-/*************************************************
-* Create bitmap of starting bytes *
-*************************************************/
-
-/* This function scans a compiled unanchored expression recursively and
-attempts to build a bitmap of the set of possible starting bytes. As time goes
-by, we may be able to get more clever at doing this. The SSB_CONTINUE return is
-useful for parenthesized groups in patterns such as (a*)b where the group
-provides some optional starting bytes but scanning must continue at the outer
-level to find at least one mandatory byte. At the outermost level, this
-function fails unless the result is SSB_DONE.
-
-Arguments:
- code points to an expression
- start_bits points to a 32-byte table, initialized to 0
- caseless the current state of the caseless flag
- utf8 TRUE if in UTF-8 mode
- cd the block with char table pointers
-
-Returns: SSB_FAIL => Failed to find any starting bytes
- SSB_DONE => Found mandatory starting bytes
- SSB_CONTINUE => Found optional starting bytes
-*/
-
-static int
-set_start_bits(const uschar *code, uschar *start_bits, BOOL caseless,
- BOOL utf8, compile_data *cd)
-{
-register int c;
-int yield = SSB_DONE;
-
-#if 0
-/* ========================================================================= */
-/* The following comment and code was inserted in January 1999. In May 2006,
-when it was observed to cause compiler warnings about unused values, I took it
-out again. If anybody is still using OS/2, they will have to put it back
-manually. */
-
-/* This next statement and the later reference to dummy are here in order to
-trick the optimizer of the IBM C compiler for OS/2 into generating correct
-code. Apparently IBM isn't going to fix the problem, and we would rather not
-disable optimization (in this module it actually makes a big difference, and
-the pcre module can use all the optimization it can get). */
-
-volatile int dummy;
-/* ========================================================================= */
-#endif
-
-do
- {
- const uschar *tcode = code + (((int)*code == OP_CBRA)? 3:1) + LINK_SIZE;
- BOOL try_next = TRUE;
-
- while (try_next) /* Loop for items in this branch */
- {
- int rc;
- switch(*tcode)
- {
- /* Fail if we reach something we don't understand */
-
- default:
- return SSB_FAIL;
-
- /* If we hit a bracket or a positive lookahead assertion, recurse to set
- bits from within the subpattern. If it can't find anything, we have to
- give up. If it finds some mandatory character(s), we are done for this
- branch. Otherwise, carry on scanning after the subpattern. */
-
- case OP_BRA:
- case OP_SBRA:
- case OP_CBRA:
- case OP_SCBRA:
- case OP_ONCE:
- case OP_ASSERT:
- rc = set_start_bits(tcode, start_bits, caseless, utf8, cd);
- if (rc == SSB_FAIL) return SSB_FAIL;
- if (rc == SSB_DONE) try_next = FALSE; else
- {
- do tcode += GET(tcode, 1); while (*tcode == OP_ALT);
- tcode += 1 + LINK_SIZE;
- }
- break;
-
- /* If we hit ALT or KET, it means we haven't found anything mandatory in
- this branch, though we might have found something optional. For ALT, we
- continue with the next alternative, but we have to arrange that the final
- result from subpattern is SSB_CONTINUE rather than SSB_DONE. For KET,
- return SSB_CONTINUE: if this is the top level, that indicates failure,
- but after a nested subpattern, it causes scanning to continue. */
-
- case OP_ALT:
- yield = SSB_CONTINUE;
- try_next = FALSE;
- break;
-
- case OP_KET:
- case OP_KETRMAX:
- case OP_KETRMIN:
- return SSB_CONTINUE;
-
- /* Skip over callout */
-
- case OP_CALLOUT:
- tcode += 2 + 2*LINK_SIZE;
- break;
-
- /* Skip over lookbehind and negative lookahead assertions */
-
- case OP_ASSERT_NOT:
- case OP_ASSERTBACK:
- case OP_ASSERTBACK_NOT:
- do tcode += GET(tcode, 1); while (*tcode == OP_ALT);
- tcode += 1 + LINK_SIZE;
- break;
-
- /* Skip over an option setting, changing the caseless flag */
-
- case OP_OPT:
- caseless = (tcode[1] & PCRE_CASELESS) != 0;
- tcode += 2;
- break;
-
- /* BRAZERO does the bracket, but carries on. */
-
- case OP_BRAZERO:
- case OP_BRAMINZERO:
- if (set_start_bits(++tcode, start_bits, caseless, utf8, cd) == SSB_FAIL)
- return SSB_FAIL;
-/* =========================================================================
- See the comment at the head of this function concerning the next line,
- which was an old fudge for the benefit of OS/2.
- dummy = 1;
- ========================================================================= */
- do tcode += GET(tcode,1); while (*tcode == OP_ALT);
- tcode += 1 + LINK_SIZE;
- break;
-
- /* SKIPZERO skips the bracket. */
-
- case OP_SKIPZERO:
- do tcode += GET(tcode,1); while (*tcode == OP_ALT);
- tcode += 1 + LINK_SIZE;
- break;
-
- /* Single-char * or ? sets the bit and tries the next item */
-
- case OP_STAR:
- case OP_MINSTAR:
- case OP_POSSTAR:
- case OP_QUERY:
- case OP_MINQUERY:
- case OP_POSQUERY:
- set_bit(start_bits, tcode[1], caseless, cd);
- tcode += 2;
-#ifdef SUPPORT_UTF8
- if (utf8 && tcode[-1] >= 0xc0)
- tcode += _pcre_utf8_table4[tcode[-1] & 0x3f];
-#endif
- break;
-
- /* Single-char upto sets the bit and tries the next */
-
- case OP_UPTO:
- case OP_MINUPTO:
- case OP_POSUPTO:
- set_bit(start_bits, tcode[3], caseless, cd);
- tcode += 4;
-#ifdef SUPPORT_UTF8
- if (utf8 && tcode[-1] >= 0xc0)
- tcode += _pcre_utf8_table4[tcode[-1] & 0x3f];
-#endif
- break;
-
- /* At least one single char sets the bit and stops */
-
- case OP_EXACT: /* Fall through */
- tcode += 2;
-
- case OP_CHAR:
- case OP_CHARNC:
- case OP_PLUS:
- case OP_MINPLUS:
- case OP_POSPLUS:
- set_bit(start_bits, tcode[1], caseless, cd);
- try_next = FALSE;
- break;
-
- /* Single character type sets the bits and stops */
-
- case OP_NOT_DIGIT:
- for (c = 0; c < 32; c++)
- start_bits[c] |= ~cd->cbits[c+cbit_digit];
- try_next = FALSE;
- break;
-
- case OP_DIGIT:
- for (c = 0; c < 32; c++)
- start_bits[c] |= cd->cbits[c+cbit_digit];
- try_next = FALSE;
- break;
-
- /* The cbit_space table has vertical tab as whitespace; we have to
- discard it. */
-
- case OP_NOT_WHITESPACE:
- for (c = 0; c < 32; c++)
- {
- int d = cd->cbits[c+cbit_space];
- if (c == 1) d &= ~0x08;
- start_bits[c] |= ~d;
- }
- try_next = FALSE;
- break;
-
- /* The cbit_space table has vertical tab as whitespace; we have to
- discard it. */
-
- case OP_WHITESPACE:
- for (c = 0; c < 32; c++)
- {
- int d = cd->cbits[c+cbit_space];
- if (c == 1) d &= ~0x08;
- start_bits[c] |= d;
- }
- try_next = FALSE;
- break;
-
- case OP_NOT_WORDCHAR:
- for (c = 0; c < 32; c++)
- start_bits[c] |= ~cd->cbits[c+cbit_word];
- try_next = FALSE;
- break;
-
- case OP_WORDCHAR:
- for (c = 0; c < 32; c++)
- start_bits[c] |= cd->cbits[c+cbit_word];
- try_next = FALSE;
- break;
-
- /* One or more character type fudges the pointer and restarts, knowing
- it will hit a single character type and stop there. */
-
- case OP_TYPEPLUS:
- case OP_TYPEMINPLUS:
- tcode++;
- break;
-
- case OP_TYPEEXACT:
- tcode += 3;
- break;
-
- /* Zero or more repeats of character types set the bits and then
- try again. */
-
- case OP_TYPEUPTO:
- case OP_TYPEMINUPTO:
- case OP_TYPEPOSUPTO:
- tcode += 2; /* Fall through */
-
- case OP_TYPESTAR:
- case OP_TYPEMINSTAR:
- case OP_TYPEPOSSTAR:
- case OP_TYPEQUERY:
- case OP_TYPEMINQUERY:
- case OP_TYPEPOSQUERY:
- switch(tcode[1])
- {
- case OP_ANY:
- case OP_ALLANY:
- return SSB_FAIL;
-
- case OP_NOT_DIGIT:
- for (c = 0; c < 32; c++)
- start_bits[c] |= ~cd->cbits[c+cbit_digit];
- break;
-
- case OP_DIGIT:
- for (c = 0; c < 32; c++)
- start_bits[c] |= cd->cbits[c+cbit_digit];
- break;
-
- /* The cbit_space table has vertical tab as whitespace; we have to
- discard it. */
-
- case OP_NOT_WHITESPACE:
- for (c = 0; c < 32; c++)
- {
- int d = cd->cbits[c+cbit_space];
- if (c == 1) d &= ~0x08;
- start_bits[c] |= ~d;
- }
- break;
-
- /* The cbit_space table has vertical tab as whitespace; we have to
- discard it. */
-
- case OP_WHITESPACE:
- for (c = 0; c < 32; c++)
- {
- int d = cd->cbits[c+cbit_space];
- if (c == 1) d &= ~0x08;
- start_bits[c] |= d;
- }
- break;
-
- case OP_NOT_WORDCHAR:
- for (c = 0; c < 32; c++)
- start_bits[c] |= ~cd->cbits[c+cbit_word];
- break;
-
- case OP_WORDCHAR:
- for (c = 0; c < 32; c++)
- start_bits[c] |= cd->cbits[c+cbit_word];
- break;
- }
-
- tcode += 2;
- break;
-
- /* Character class where all the information is in a bit map: set the
- bits and either carry on or not, according to the repeat count. If it was
- a negative class, and we are operating with UTF-8 characters, any byte
- with a value >= 0xc4 is a potentially valid starter because it starts a
- character with a value > 255. */
-
- case OP_NCLASS:
-#ifdef SUPPORT_UTF8
- if (utf8)
- {
- start_bits[24] |= 0xf0; /* Bits for 0xc4 - 0xc8 */
- memset(start_bits+25, 0xff, 7); /* Bits for 0xc9 - 0xff */
- }
-#endif
- /* Fall through */
-
- case OP_CLASS:
- {
- tcode++;
-
- /* In UTF-8 mode, the bits in a bit map correspond to character
- values, not to byte values. However, the bit map we are constructing is
- for byte values. So we have to do a conversion for characters whose
- value is > 127. In fact, there are only two possible starting bytes for
- characters in the range 128 - 255. */
-
-#ifdef SUPPORT_UTF8
- if (utf8)
- {
- for (c = 0; c < 16; c++) start_bits[c] |= tcode[c];
- for (c = 128; c < 256; c++)
- {
- if ((tcode[c/8] && (1 << (c&7))) != 0)
- {
- int d = (c >> 6) | 0xc0; /* Set bit for this starter */
- start_bits[d/8] |= (1 << (d&7)); /* and then skip on to the */
- c = (c & 0xc0) + 0x40 - 1; /* next relevant character. */
- }
- }
- }
-
- /* In non-UTF-8 mode, the two bit maps are completely compatible. */
-
- else
-#endif
- {
- for (c = 0; c < 32; c++) start_bits[c] |= tcode[c];
- }
-
- /* Advance past the bit map, and act on what follows */
-
- tcode += 32;
- switch (*tcode)
- {
- case OP_CRSTAR:
- case OP_CRMINSTAR:
- case OP_CRQUERY:
- case OP_CRMINQUERY:
- tcode++;
- break;
-
- case OP_CRRANGE:
- case OP_CRMINRANGE:
- if (((tcode[1] << 8) + tcode[2]) == 0) tcode += 5;
- else try_next = FALSE;
- break;
-
- default:
- try_next = FALSE;
- break;
- }
- }
- break; /* End of bitmap class handling */
-
- } /* End of switch */
- } /* End of try_next loop */
-
- code += GET(code, 1); /* Advance to next branch */
- }
-while (*code == OP_ALT);
-return yield;
-}
-
-
-
-/*************************************************
-* Study a compiled expression *
-*************************************************/
-
-/* This function is handed a compiled expression that it must study to produce
-information that will speed up the matching. It returns a pcre_extra block
-which then gets handed back to pcre_exec().
-
-Arguments:
- re points to the compiled expression
- options contains option bits
- errorptr points to where to place error messages;
- set NULL unless error
-
-Returns: pointer to a pcre_extra block, with study_data filled in and the
- appropriate flag set;
- NULL on error or if no optimization possible
-*/
-
-PCRE_EXP_DEFN pcre_extra *
-pcre_study(const pcre *external_re, int options, const char **errorptr)
-{
-uschar start_bits[32];
-pcre_extra *extra;
-pcre_study_data *study;
-const uschar *tables;
-uschar *code;
-compile_data compile_block;
-const real_pcre *re = (const real_pcre *)external_re;
-
-*errorptr = NULL;
-
-if (re == NULL || re->magic_number != MAGIC_NUMBER)
- {
- *errorptr = "argument is not a compiled regular expression";
- return NULL;
- }
-
-if ((options & ~PUBLIC_STUDY_OPTIONS) != 0)
- {
- *errorptr = "unknown or incorrect option bit(s) set";
- return NULL;
- }
-
-code = (uschar *)re + re->name_table_offset +
- (re->name_count * re->name_entry_size);
-
-/* For an anchored pattern, or an unanchored pattern that has a first char, or
-a multiline pattern that matches only at "line starts", no further processing
-at present. */
-
-if ((re->options & PCRE_ANCHORED) != 0 ||
- (re->flags & (PCRE_FIRSTSET|PCRE_STARTLINE)) != 0)
- return NULL;
-
-/* Set the character tables in the block that is passed around */
-
-tables = re->tables;
-if (tables == NULL)
- (void)pcre_fullinfo(external_re, NULL, PCRE_INFO_DEFAULT_TABLES,
- (void *)(&tables));
-
-compile_block.lcc = tables + lcc_offset;
-compile_block.fcc = tables + fcc_offset;
-compile_block.cbits = tables + cbits_offset;
-compile_block.ctypes = tables + ctypes_offset;
-
-/* See if we can find a fixed set of initial characters for the pattern. */
-
-memset(start_bits, 0, 32 * sizeof(uschar));
-if (set_start_bits(code, start_bits, (re->options & PCRE_CASELESS) != 0,
- (re->options & PCRE_UTF8) != 0, &compile_block) != SSB_DONE) return NULL;
-
-/* Get a pcre_extra block and a pcre_study_data block. The study data is put in
-the latter, which is pointed to by the former, which may also get additional
-data set later by the calling program. At the moment, the size of
-pcre_study_data is fixed. We nevertheless save it in a field for returning via
-the pcre_fullinfo() function so that if it becomes variable in the future, we
-don't have to change that code. */
-
-extra = (pcre_extra *)(pcre_malloc)
- (sizeof(pcre_extra) + sizeof(pcre_study_data));
-
-if (extra == NULL)
- {
- *errorptr = "failed to get memory";
- return NULL;
- }
-
-study = (pcre_study_data *)((char *)extra + sizeof(pcre_extra));
-extra->flags = PCRE_EXTRA_STUDY_DATA;
-extra->study_data = study;
-
-study->size = sizeof(pcre_study_data);
-study->options = PCRE_STUDY_MAPPED;
-memcpy(study->start_bits, start_bits, sizeof(start_bits));
-
-return extra;
-}
-
-/* End of pcre_study.c */
diff --git a/crawl-ref/source/util/pcre/pcre_tables.c b/crawl-ref/source/util/pcre/pcre_tables.c
deleted file mode 100644
index e37dcb629b..0000000000
--- a/crawl-ref/source/util/pcre/pcre_tables.c
+++ /dev/null
@@ -1,318 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
- Written by Philip Hazel
- Copyright (c) 1997-2008 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-
-/* This module contains some fixed tables that are used by more than one of the
-PCRE code modules. The tables are also #included by the pcretest program, which
-uses macros to change their names from _pcre_xxx to xxxx, thereby avoiding name
-clashes with the library. */
-
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "pcre_internal.h"
-
-
-/* Table of sizes for the fixed-length opcodes. It's defined in a macro so that
-the definition is next to the definition of the opcodes in pcre_internal.h. */
-
-const uschar _pcre_OP_lengths[] = { OP_LENGTHS };
-
-
-
-/*************************************************
-* Tables for UTF-8 support *
-*************************************************/
-
-/* These are the breakpoints for different numbers of bytes in a UTF-8
-character. */
-
-#ifdef SUPPORT_UTF8
-
-const int _pcre_utf8_table1[] =
- { 0x7f, 0x7ff, 0xffff, 0x1fffff, 0x3ffffff, 0x7fffffff};
-
-const int _pcre_utf8_table1_size = sizeof(_pcre_utf8_table1)/sizeof(int);
-
-/* These are the indicator bits and the mask for the data bits to set in the
-first byte of a character, indexed by the number of additional bytes. */
-
-const int _pcre_utf8_table2[] = { 0, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc};
-const int _pcre_utf8_table3[] = { 0xff, 0x1f, 0x0f, 0x07, 0x03, 0x01};
-
-/* Table of the number of extra bytes, indexed by the first byte masked with
-0x3f. The highest number for a valid UTF-8 first byte is in fact 0x3d. */
-
-const uschar _pcre_utf8_table4[] = {
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
- 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
- 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5 };
-
-/* The pcre_utt[] table below translates Unicode property names into type and
-code values. It is searched by binary chop, so must be in collating sequence of
-name. Originally, the table contained pointers to the name strings in the first
-field of each entry. However, that leads to a large number of relocations when
-a shared library is dynamically loaded. A significant reduction is made by
-putting all the names into a single, large string and then using offsets in the
-table itself. Maintenance is more error-prone, but frequent changes to this
-data is unlikely. */
-
-const char _pcre_utt_names[] =
- "Any\0"
- "Arabic\0"
- "Armenian\0"
- "Balinese\0"
- "Bengali\0"
- "Bopomofo\0"
- "Braille\0"
- "Buginese\0"
- "Buhid\0"
- "C\0"
- "Canadian_Aboriginal\0"
- "Cc\0"
- "Cf\0"
- "Cherokee\0"
- "Cn\0"
- "Co\0"
- "Common\0"
- "Coptic\0"
- "Cs\0"
- "Cuneiform\0"
- "Cypriot\0"
- "Cyrillic\0"
- "Deseret\0"
- "Devanagari\0"
- "Ethiopic\0"
- "Georgian\0"
- "Glagolitic\0"
- "Gothic\0"
- "Greek\0"
- "Gujarati\0"
- "Gurmukhi\0"
- "Han\0"
- "Hangul\0"
- "Hanunoo\0"
- "Hebrew\0"
- "Hiragana\0"
- "Inherited\0"
- "Kannada\0"
- "Katakana\0"
- "Kharoshthi\0"
- "Khmer\0"
- "L\0"
- "L&\0"
- "Lao\0"
- "Latin\0"
- "Limbu\0"
- "Linear_B\0"
- "Ll\0"
- "Lm\0"
- "Lo\0"
- "Lt\0"
- "Lu\0"
- "M\0"
- "Malayalam\0"
- "Mc\0"
- "Me\0"
- "Mn\0"
- "Mongolian\0"
- "Myanmar\0"
- "N\0"
- "Nd\0"
- "New_Tai_Lue\0"
- "Nko\0"
- "Nl\0"
- "No\0"
- "Ogham\0"
- "Old_Italic\0"
- "Old_Persian\0"
- "Oriya\0"
- "Osmanya\0"
- "P\0"
- "Pc\0"
- "Pd\0"
- "Pe\0"
- "Pf\0"
- "Phags_Pa\0"
- "Phoenician\0"
- "Pi\0"
- "Po\0"
- "Ps\0"
- "Runic\0"
- "S\0"
- "Sc\0"
- "Shavian\0"
- "Sinhala\0"
- "Sk\0"
- "Sm\0"
- "So\0"
- "Syloti_Nagri\0"
- "Syriac\0"
- "Tagalog\0"
- "Tagbanwa\0"
- "Tai_Le\0"
- "Tamil\0"
- "Telugu\0"
- "Thaana\0"
- "Thai\0"
- "Tibetan\0"
- "Tifinagh\0"
- "Ugaritic\0"
- "Yi\0"
- "Z\0"
- "Zl\0"
- "Zp\0"
- "Zs\0";
-
-const ucp_type_table _pcre_utt[] = {
- { 0, PT_ANY, 0 },
- { 4, PT_SC, ucp_Arabic },
- { 11, PT_SC, ucp_Armenian },
- { 20, PT_SC, ucp_Balinese },
- { 29, PT_SC, ucp_Bengali },
- { 37, PT_SC, ucp_Bopomofo },
- { 46, PT_SC, ucp_Braille },
- { 54, PT_SC, ucp_Buginese },
- { 63, PT_SC, ucp_Buhid },
- { 69, PT_GC, ucp_C },
- { 71, PT_SC, ucp_Canadian_Aboriginal },
- { 91, PT_PC, ucp_Cc },
- { 94, PT_PC, ucp_Cf },
- { 97, PT_SC, ucp_Cherokee },
- { 106, PT_PC, ucp_Cn },
- { 109, PT_PC, ucp_Co },
- { 112, PT_SC, ucp_Common },
- { 119, PT_SC, ucp_Coptic },
- { 126, PT_PC, ucp_Cs },
- { 129, PT_SC, ucp_Cuneiform },
- { 139, PT_SC, ucp_Cypriot },
- { 147, PT_SC, ucp_Cyrillic },
- { 156, PT_SC, ucp_Deseret },
- { 164, PT_SC, ucp_Devanagari },
- { 175, PT_SC, ucp_Ethiopic },
- { 184, PT_SC, ucp_Georgian },
- { 193, PT_SC, ucp_Glagolitic },
- { 204, PT_SC, ucp_Gothic },
- { 211, PT_SC, ucp_Greek },
- { 217, PT_SC, ucp_Gujarati },
- { 226, PT_SC, ucp_Gurmukhi },
- { 235, PT_SC, ucp_Han },
- { 239, PT_SC, ucp_Hangul },
- { 246, PT_SC, ucp_Hanunoo },
- { 254, PT_SC, ucp_Hebrew },
- { 261, PT_SC, ucp_Hiragana },
- { 270, PT_SC, ucp_Inherited },
- { 280, PT_SC, ucp_Kannada },
- { 288, PT_SC, ucp_Katakana },
- { 297, PT_SC, ucp_Kharoshthi },
- { 308, PT_SC, ucp_Khmer },
- { 314, PT_GC, ucp_L },
- { 316, PT_LAMP, 0 },
- { 319, PT_SC, ucp_Lao },
- { 323, PT_SC, ucp_Latin },
- { 329, PT_SC, ucp_Limbu },
- { 335, PT_SC, ucp_Linear_B },
- { 344, PT_PC, ucp_Ll },
- { 347, PT_PC, ucp_Lm },
- { 350, PT_PC, ucp_Lo },
- { 353, PT_PC, ucp_Lt },
- { 356, PT_PC, ucp_Lu },
- { 359, PT_GC, ucp_M },
- { 361, PT_SC, ucp_Malayalam },
- { 371, PT_PC, ucp_Mc },
- { 374, PT_PC, ucp_Me },
- { 377, PT_PC, ucp_Mn },
- { 380, PT_SC, ucp_Mongolian },
- { 390, PT_SC, ucp_Myanmar },
- { 398, PT_GC, ucp_N },
- { 400, PT_PC, ucp_Nd },
- { 403, PT_SC, ucp_New_Tai_Lue },
- { 415, PT_SC, ucp_Nko },
- { 419, PT_PC, ucp_Nl },
- { 422, PT_PC, ucp_No },
- { 425, PT_SC, ucp_Ogham },
- { 431, PT_SC, ucp_Old_Italic },
- { 442, PT_SC, ucp_Old_Persian },
- { 454, PT_SC, ucp_Oriya },
- { 460, PT_SC, ucp_Osmanya },
- { 468, PT_GC, ucp_P },
- { 470, PT_PC, ucp_Pc },
- { 473, PT_PC, ucp_Pd },
- { 476, PT_PC, ucp_Pe },
- { 479, PT_PC, ucp_Pf },
- { 482, PT_SC, ucp_Phags_Pa },
- { 491, PT_SC, ucp_Phoenician },
- { 502, PT_PC, ucp_Pi },
- { 505, PT_PC, ucp_Po },
- { 508, PT_PC, ucp_Ps },
- { 511, PT_SC, ucp_Runic },
- { 517, PT_GC, ucp_S },
- { 519, PT_PC, ucp_Sc },
- { 522, PT_SC, ucp_Shavian },
- { 530, PT_SC, ucp_Sinhala },
- { 538, PT_PC, ucp_Sk },
- { 541, PT_PC, ucp_Sm },
- { 544, PT_PC, ucp_So },
- { 547, PT_SC, ucp_Syloti_Nagri },
- { 560, PT_SC, ucp_Syriac },
- { 567, PT_SC, ucp_Tagalog },
- { 575, PT_SC, ucp_Tagbanwa },
- { 584, PT_SC, ucp_Tai_Le },
- { 591, PT_SC, ucp_Tamil },
- { 597, PT_SC, ucp_Telugu },
- { 604, PT_SC, ucp_Thaana },
- { 611, PT_SC, ucp_Thai },
- { 616, PT_SC, ucp_Tibetan },
- { 624, PT_SC, ucp_Tifinagh },
- { 633, PT_SC, ucp_Ugaritic },
- { 642, PT_SC, ucp_Yi },
- { 645, PT_GC, ucp_Z },
- { 647, PT_PC, ucp_Zl },
- { 650, PT_PC, ucp_Zp },
- { 653, PT_PC, ucp_Zs }
-};
-
-const int _pcre_utt_size = sizeof(_pcre_utt)/sizeof(ucp_type_table);
-
-#endif /* SUPPORT_UTF8 */
-
-/* End of pcre_tables.c */
diff --git a/crawl-ref/source/util/pcre/pcre_try_flipped.c b/crawl-ref/source/util/pcre/pcre_try_flipped.c
deleted file mode 100644
index 0d2f3a2d38..0000000000
--- a/crawl-ref/source/util/pcre/pcre_try_flipped.c
+++ /dev/null
@@ -1,137 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
- Written by Philip Hazel
- Copyright (c) 1997-2008 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-
-/* This module contains an internal function that tests a compiled pattern to
-see if it was compiled with the opposite endianness. If so, it uses an
-auxiliary local function to flip the appropriate bytes. */
-
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "pcre_internal.h"
-
-
-/*************************************************
-* Flip bytes in an integer *
-*************************************************/
-
-/* This function is called when the magic number in a regex doesn't match, in
-order to flip its bytes to see if we are dealing with a pattern that was
-compiled on a host of different endianness. If so, this function is used to
-flip other byte values.
-
-Arguments:
- value the number to flip
- n the number of bytes to flip (assumed to be 2 or 4)
-
-Returns: the flipped value
-*/
-
-static unsigned long int
-byteflip(unsigned long int value, int n)
-{
-if (n == 2) return ((value & 0x00ff) << 8) | ((value & 0xff00) >> 8);
-return ((value & 0x000000ff) << 24) |
- ((value & 0x0000ff00) << 8) |
- ((value & 0x00ff0000) >> 8) |
- ((value & 0xff000000) >> 24);
-}
-
-
-
-/*************************************************
-* Test for a byte-flipped compiled regex *
-*************************************************/
-
-/* This function is called from pcre_exec(), pcre_dfa_exec(), and also from
-pcre_fullinfo(). Its job is to test whether the regex is byte-flipped - that
-is, it was compiled on a system of opposite endianness. The function is called
-only when the native MAGIC_NUMBER test fails. If the regex is indeed flipped,
-we flip all the relevant values into a different data block, and return it.
-
-Arguments:
- re points to the regex
- study points to study data, or NULL
- internal_re points to a new regex block
- internal_study points to a new study block
-
-Returns: the new block if is is indeed a byte-flipped regex
- NULL if it is not
-*/
-
-real_pcre *
-_pcre_try_flipped(const real_pcre *re, real_pcre *internal_re,
- const pcre_study_data *study, pcre_study_data *internal_study)
-{
-if (byteflip(re->magic_number, sizeof(re->magic_number)) != MAGIC_NUMBER)
- return NULL;
-
-*internal_re = *re; /* To copy other fields */
-internal_re->size = byteflip(re->size, sizeof(re->size));
-internal_re->options = byteflip(re->options, sizeof(re->options));
-internal_re->flags = (pcre_uint16)byteflip(re->flags, sizeof(re->flags));
-internal_re->top_bracket =
- (pcre_uint16)byteflip(re->top_bracket, sizeof(re->top_bracket));
-internal_re->top_backref =
- (pcre_uint16)byteflip(re->top_backref, sizeof(re->top_backref));
-internal_re->first_byte =
- (pcre_uint16)byteflip(re->first_byte, sizeof(re->first_byte));
-internal_re->req_byte =
- (pcre_uint16)byteflip(re->req_byte, sizeof(re->req_byte));
-internal_re->name_table_offset =
- (pcre_uint16)byteflip(re->name_table_offset, sizeof(re->name_table_offset));
-internal_re->name_entry_size =
- (pcre_uint16)byteflip(re->name_entry_size, sizeof(re->name_entry_size));
-internal_re->name_count =
- (pcre_uint16)byteflip(re->name_count, sizeof(re->name_count));
-
-if (study != NULL)
- {
- *internal_study = *study; /* To copy other fields */
- internal_study->size = byteflip(study->size, sizeof(study->size));
- internal_study->options = byteflip(study->options, sizeof(study->options));
- }
-
-return internal_re;
-}
-
-/* End of pcre_tryflipped.c */
diff --git a/crawl-ref/source/util/pcre/pcre_ucp_searchfuncs.c b/crawl-ref/source/util/pcre/pcre_ucp_searchfuncs.c
deleted file mode 100644
index 461ca4377d..0000000000
--- a/crawl-ref/source/util/pcre/pcre_ucp_searchfuncs.c
+++ /dev/null
@@ -1,179 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
- Written by Philip Hazel
- Copyright (c) 1997-2008 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-
-/* This module contains code for searching the table of Unicode character
-properties. */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "pcre_internal.h"
-
-#include "ucp.h" /* Category definitions */
-#include "ucpinternal.h" /* Internal table details */
-#include "ucptable.h" /* The table itself */
-
-
-/* Table to translate from particular type value to the general value. */
-
-static const int ucp_gentype[] = {
- ucp_C, ucp_C, ucp_C, ucp_C, ucp_C, /* Cc, Cf, Cn, Co, Cs */
- ucp_L, ucp_L, ucp_L, ucp_L, ucp_L, /* Ll, Lu, Lm, Lo, Lt */
- ucp_M, ucp_M, ucp_M, /* Mc, Me, Mn */
- ucp_N, ucp_N, ucp_N, /* Nd, Nl, No */
- ucp_P, ucp_P, ucp_P, ucp_P, ucp_P, /* Pc, Pd, Pe, Pf, Pi */
- ucp_P, ucp_P, /* Ps, Po */
- ucp_S, ucp_S, ucp_S, ucp_S, /* Sc, Sk, Sm, So */
- ucp_Z, ucp_Z, ucp_Z /* Zl, Zp, Zs */
-};
-
-
-
-/*************************************************
-* Search table and return type *
-*************************************************/
-
-/* Three values are returned: the category is ucp_C, ucp_L, etc. The detailed
-character type is ucp_Lu, ucp_Nd, etc. The script is ucp_Latin, etc.
-
-Arguments:
- c the character value
- type_ptr the detailed character type is returned here
- script_ptr the script is returned here
-
-Returns: the character type category
-*/
-
-int
-_pcre_ucp_findprop(const unsigned int c, int *type_ptr, int *script_ptr)
-{
-int bot = 0;
-int top = sizeof(ucp_table)/sizeof(cnode);
-int mid;
-
-/* The table is searched using a binary chop. You might think that using
-intermediate variables to hold some of the common expressions would speed
-things up, but tests with gcc 3.4.4 on Linux showed that, on the contrary, it
-makes things a lot slower. */
-
-for (;;)
- {
- if (top <= bot)
- {
- *type_ptr = ucp_Cn;
- *script_ptr = ucp_Common;
- return ucp_C;
- }
- mid = (bot + top) >> 1;
- if (c == (ucp_table[mid].f0 & f0_charmask)) break;
- if (c < (ucp_table[mid].f0 & f0_charmask)) top = mid;
- else
- {
- if ((ucp_table[mid].f0 & f0_rangeflag) != 0 &&
- c <= (ucp_table[mid].f0 & f0_charmask) +
- (ucp_table[mid].f1 & f1_rangemask)) break;
- bot = mid + 1;
- }
- }
-
-/* Found an entry in the table. Set the script and detailed type values, and
-return the general type. */
-
-*script_ptr = (ucp_table[mid].f0 & f0_scriptmask) >> f0_scriptshift;
-*type_ptr = (ucp_table[mid].f1 & f1_typemask) >> f1_typeshift;
-
-return ucp_gentype[*type_ptr];
-}
-
-
-
-/*************************************************
-* Search table and return other case *
-*************************************************/
-
-/* If the given character is a letter, and there is another case for the
-letter, return the other case. Otherwise, return -1.
-
-Arguments:
- c the character value
-
-Returns: the other case or NOTACHAR if none
-*/
-
-unsigned int
-_pcre_ucp_othercase(const unsigned int c)
-{
-int bot = 0;
-int top = sizeof(ucp_table)/sizeof(cnode);
-int mid, offset;
-
-/* The table is searched using a binary chop. You might think that using
-intermediate variables to hold some of the common expressions would speed
-things up, but tests with gcc 3.4.4 on Linux showed that, on the contrary, it
-makes things a lot slower. */
-
-for (;;)
- {
- if (top <= bot) return -1;
- mid = (bot + top) >> 1;
- if (c == (ucp_table[mid].f0 & f0_charmask)) break;
- if (c < (ucp_table[mid].f0 & f0_charmask)) top = mid;
- else
- {
- if ((ucp_table[mid].f0 & f0_rangeflag) != 0 &&
- c <= (ucp_table[mid].f0 & f0_charmask) +
- (ucp_table[mid].f1 & f1_rangemask)) break;
- bot = mid + 1;
- }
- }
-
-/* Found an entry in the table. Return NOTACHAR for a range entry. Otherwise
-return the other case if there is one, else NOTACHAR. */
-
-if ((ucp_table[mid].f0 & f0_rangeflag) != 0) return NOTACHAR;
-
-offset = ucp_table[mid].f1 & f1_casemask;
-if ((offset & f1_caseneg) != 0) offset |= f1_caseneg;
-return (offset == 0)? NOTACHAR : c + offset;
-}
-
-
-/* End of pcre_ucp_searchfuncs.c */
diff --git a/crawl-ref/source/util/pcre/pcre_valid_utf8.c b/crawl-ref/source/util/pcre/pcre_valid_utf8.c
deleted file mode 100644
index bc3bc8f3d4..0000000000
--- a/crawl-ref/source/util/pcre/pcre_valid_utf8.c
+++ /dev/null
@@ -1,162 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
- Written by Philip Hazel
- Copyright (c) 1997-2008 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-
-/* This module contains an internal function for validating UTF-8 character
-strings. */
-
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "pcre_internal.h"
-
-
-/*************************************************
-* Validate a UTF-8 string *
-*************************************************/
-
-/* This function is called (optionally) at the start of compile or match, to
-validate that a supposed UTF-8 string is actually valid. The early check means
-that subsequent code can assume it is dealing with a valid string. The check
-can be turned off for maximum performance, but the consequences of supplying
-an invalid string are then undefined.
-
-Originally, this function checked according to RFC 2279, allowing for values in
-the range 0 to 0x7fffffff, up to 6 bytes long, but ensuring that they were in
-the canonical format. Once somebody had pointed out RFC 3629 to me (it
-obsoletes 2279), additional restrictions were applied. The values are now
-limited to be between 0 and 0x0010ffff, no more than 4 bytes long, and the
-subrange 0xd000 to 0xdfff is excluded.
-
-Arguments:
- string points to the string
- length length of string, or -1 if the string is zero-terminated
-
-Returns: < 0 if the string is a valid UTF-8 string
- >= 0 otherwise; the value is the offset of the bad byte
-*/
-
-int
-_pcre_valid_utf8(const uschar *string, int length)
-{
-#ifdef SUPPORT_UTF8
-register const uschar *p;
-
-if (length < 0)
- {
- for (p = string; *p != 0; p++);
- length = p - string;
- }
-
-for (p = string; length-- > 0; p++)
- {
- register int ab;
- register int c = *p;
- if (c < 128) continue;
- if (c < 0xc0) return p - string;
- ab = _pcre_utf8_table4[c & 0x3f]; /* Number of additional bytes */
- if (length < ab || ab > 3) return p - string;
- length -= ab;
-
- /* Check top bits in the second byte */
- if ((*(++p) & 0xc0) != 0x80) return p - string;
-
- /* Check for overlong sequences for each different length, and for the
- excluded range 0xd000 to 0xdfff. */
-
- switch (ab)
- {
- /* Check for xx00 000x (overlong sequence) */
-
- case 1:
- if ((c & 0x3e) == 0) return p - string;
- continue; /* We know there aren't any more bytes to check */
-
- /* Check for 1110 0000, xx0x xxxx (overlong sequence) or
- 1110 1101, 1010 xxxx (0xd000 - 0xdfff) */
-
- case 2:
- if ((c == 0xe0 && (*p & 0x20) == 0) ||
- (c == 0xed && *p >= 0xa0))
- return p - string;
- break;
-
- /* Check for 1111 0000, xx00 xxxx (overlong sequence) or
- greater than 0x0010ffff (f4 8f bf bf) */
-
- case 3:
- if ((c == 0xf0 && (*p & 0x30) == 0) ||
- (c > 0xf4 ) ||
- (c == 0xf4 && *p > 0x8f))
- return p - string;
- break;
-
-#if 0
- /* These cases can no longer occur, as we restrict to a maximum of four
- bytes nowadays. Leave the code here in case we ever want to add an option
- for longer sequences. */
-
- /* Check for 1111 1000, xx00 0xxx */
- case 4:
- if (c == 0xf8 && (*p & 0x38) == 0) return p - string;
- break;
-
- /* Check for leading 0xfe or 0xff, and then for 1111 1100, xx00 00xx */
- case 5:
- if (c == 0xfe || c == 0xff ||
- (c == 0xfc && (*p & 0x3c) == 0)) return p - string;
- break;
-#endif
-
- }
-
- /* Check for valid bytes after the 2nd, if any; all must start 10 */
- while (--ab > 0)
- {
- if ((*(++p) & 0xc0) != 0x80) return p - string;
- }
- }
-#endif
-
-return -1;
-}
-
-/* End of pcre_valid_utf8.c */
diff --git a/crawl-ref/source/util/pcre/pcre_version.c b/crawl-ref/source/util/pcre/pcre_version.c
deleted file mode 100644
index 697b44b391..0000000000
--- a/crawl-ref/source/util/pcre/pcre_version.c
+++ /dev/null
@@ -1,90 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
- Written by Philip Hazel
- Copyright (c) 1997-2008 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-
-/* This module contains the external function pcre_version(), which returns a
-string that identifies the PCRE version that is in use. */
-
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "pcre_internal.h"
-
-
-/*************************************************
-* Return version string *
-*************************************************/
-
-/* These macros are the standard way of turning unquoted text into C strings.
-They allow macros like PCRE_MAJOR to be defined without quotes, which is
-convenient for user programs that want to test its value. */
-
-#define STRING(a) # a
-#define XSTRING(s) STRING(s)
-
-/* A problem turned up with PCRE_PRERELEASE, which is defined empty for
-production releases. Originally, it was used naively in this code:
-
- return XSTRING(PCRE_MAJOR)
- "." XSTRING(PCRE_MINOR)
- XSTRING(PCRE_PRERELEASE)
- " " XSTRING(PCRE_DATE);
-
-However, when PCRE_PRERELEASE is empty, this leads to an attempted expansion of
-STRING(). The C standard states: "If (before argument substitution) any
-argument consists of no preprocessing tokens, the behavior is undefined." It
-turns out the gcc treats this case as a single empty string - which is what we
-really want - but Visual C grumbles about the lack of an argument for the
-macro. Unfortunately, both are within their rights. To cope with both ways of
-handling this, I had resort to some messy hackery that does a test at run time.
-I could find no way of detecting that a macro is defined as an empty string at
-pre-processor time. This hack uses a standard trick for avoiding calling
-the STRING macro with an empty argument when doing the test. */
-
-PCRE_EXP_DEFN const char *
-pcre_version(void)
-{
-return (XSTRING(Z PCRE_PRERELEASE)[1] == 0)?
- XSTRING(PCRE_MAJOR.PCRE_MINOR PCRE_DATE) :
- XSTRING(PCRE_MAJOR.PCRE_MINOR) XSTRING(PCRE_PRERELEASE PCRE_DATE);
-}
-
-/* End of pcre_version.c */
diff --git a/crawl-ref/source/util/pcre/pcre_xclass.c b/crawl-ref/source/util/pcre/pcre_xclass.c
deleted file mode 100644
index cfb5a77b50..0000000000
--- a/crawl-ref/source/util/pcre/pcre_xclass.c
+++ /dev/null
@@ -1,148 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
- Written by Philip Hazel
- Copyright (c) 1997-2008 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-
-/* This module contains an internal function that is used to match an extended
-class (one that contains characters whose values are > 255). It is used by both
-pcre_exec() and pcre_def_exec(). */
-
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "pcre_internal.h"
-
-
-/*************************************************
-* Match character against an XCLASS *
-*************************************************/
-
-/* This function is called to match a character against an extended class that
-might contain values > 255.
-
-Arguments:
- c the character
- data points to the flag byte of the XCLASS data
-
-Returns: TRUE if character matches, else FALSE
-*/
-
-BOOL
-_pcre_xclass(int c, const uschar *data)
-{
-int t;
-BOOL negated = (*data & XCL_NOT) != 0;
-
-/* Character values < 256 are matched against a bitmap, if one is present. If
-not, we still carry on, because there may be ranges that start below 256 in the
-additional data. */
-
-if (c < 256)
- {
- if ((*data & XCL_MAP) != 0 && (data[1 + c/8] & (1 << (c&7))) != 0)
- return !negated; /* char found */
- }
-
-/* First skip the bit map if present. Then match against the list of Unicode
-properties or large chars or ranges that end with a large char. We won't ever
-encounter XCL_PROP or XCL_NOTPROP when UCP support is not compiled. */
-
-if ((*data++ & XCL_MAP) != 0) data += 32;
-
-while ((t = *data++) != XCL_END)
- {
- int x, y;
- if (t == XCL_SINGLE)
- {
- GETCHARINC(x, data);
- if (c == x) return !negated;
- }
- else if (t == XCL_RANGE)
- {
- GETCHARINC(x, data);
- GETCHARINC(y, data);
- if (c >= x && c <= y) return !negated;
- }
-
-#ifdef SUPPORT_UCP
- else /* XCL_PROP & XCL_NOTPROP */
- {
- int chartype, script;
- int category = _pcre_ucp_findprop(c, &chartype, &script);
-
- switch(*data)
- {
- case PT_ANY:
- if (t == XCL_PROP) return !negated;
- break;
-
- case PT_LAMP:
- if ((chartype == ucp_Lu || chartype == ucp_Ll || chartype == ucp_Lt) ==
- (t == XCL_PROP)) return !negated;
- break;
-
- case PT_GC:
- if ((data[1] == category) == (t == XCL_PROP)) return !negated;
- break;
-
- case PT_PC:
- if ((data[1] == chartype) == (t == XCL_PROP)) return !negated;
- break;
-
- case PT_SC:
- if ((data[1] == script) == (t == XCL_PROP)) return !negated;
- break;
-
- /* This should never occur, but compilers may mutter if there is no
- default. */
-
- default:
- return FALSE;
- }
-
- data += 2;
- }
-#endif /* SUPPORT_UCP */
- }
-
-return negated; /* char did not match */
-}
-
-/* End of pcre_xclass.c */
diff --git a/crawl-ref/source/util/pcre/pcrecpp.cc b/crawl-ref/source/util/pcre/pcrecpp.cc
deleted file mode 100644
index ba0ff6eda7..0000000000
--- a/crawl-ref/source/util/pcre/pcrecpp.cc
+++ /dev/null
@@ -1,893 +0,0 @@
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// Author: Sanjay Ghemawat
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <ctype.h>
-#include <limits.h> /* for SHRT_MIN, USHRT_MAX, etc */
-#include <assert.h>
-#include <errno.h>
-#include <string>
-#include <algorithm>
-
-#include "pcrecpp_internal.h"
-#include "pcre.h"
-#include "pcrecpp.h"
-#include "pcre_stringpiece.h"
-
-
-namespace pcrecpp {
-
-// Maximum number of args we can set
-static const int kMaxArgs = 16;
-static const int kVecSize = (1 + kMaxArgs) * 3; // results + PCRE workspace
-
-// Special object that stands-in for no argument
-Arg RE::no_arg((void*)NULL);
-
-// This is for ABI compatibility with old versions of pcre (pre-7.6),
-// which defined a global no_arg variable instead of putting it in the
-// RE class. This works on GCC >= 3, at least. It definitely works
-// for ELF, but may not for other object formats (Mach-O, for
-// instance, does not support aliases.) We could probably have a more
-// inclusive test if we ever needed it. (Note that not only the
-// __attribute__ syntax, but also __USER_LABEL_PREFIX__, are
-// gnu-specific.)
-#if defined(__GNUC__) && __GNUC__ >= 3 && defined(__ELF__)
-# define ULP_AS_STRING(x) ULP_AS_STRING_INTERNAL(x)
-# define ULP_AS_STRING_INTERNAL(x) #x
-# define USER_LABEL_PREFIX_STR ULP_AS_STRING(__USER_LABEL_PREFIX__)
-extern Arg no_arg
- __attribute__((alias(USER_LABEL_PREFIX_STR "_ZN7pcrecpp2RE6no_argE")));
-#endif
-
-// If a regular expression has no error, its error_ field points here
-static const string empty_string;
-
-// If the user doesn't ask for any options, we just use this one
-static RE_Options default_options;
-
-void RE::Init(const string& pat, const RE_Options* options) {
- pattern_ = pat;
- if (options == NULL) {
- options_ = default_options;
- } else {
- options_ = *options;
- }
- error_ = &empty_string;
- re_full_ = NULL;
- re_partial_ = NULL;
-
- re_partial_ = Compile(UNANCHORED);
- if (re_partial_ != NULL) {
- re_full_ = Compile(ANCHOR_BOTH);
- }
-}
-
-void RE::Cleanup() {
- if (re_full_ != NULL) (*pcre_free)(re_full_);
- if (re_partial_ != NULL) (*pcre_free)(re_partial_);
- if (error_ != &empty_string) delete error_;
-}
-
-
-RE::~RE() {
- Cleanup();
-}
-
-
-pcre* RE::Compile(Anchor anchor) {
- // First, convert RE_Options into pcre options
- int pcre_options = 0;
- pcre_options = options_.all_options();
-
- // Special treatment for anchoring. This is needed because at
- // runtime pcre only provides an option for anchoring at the
- // beginning of a string (unless you use offset).
- //
- // There are three types of anchoring we want:
- // UNANCHORED Compile the original pattern, and use
- // a pcre unanchored match.
- // ANCHOR_START Compile the original pattern, and use
- // a pcre anchored match.
- // ANCHOR_BOTH Tack a "\z" to the end of the original pattern
- // and use a pcre anchored match.
-
- const char* compile_error;
- int eoffset;
- pcre* re;
- if (anchor != ANCHOR_BOTH) {
- re = pcre_compile(pattern_.c_str(), pcre_options,
- &compile_error, &eoffset, NULL);
- } else {
- // Tack a '\z' at the end of RE. Parenthesize it first so that
- // the '\z' applies to all top-level alternatives in the regexp.
- string wrapped = "(?:"; // A non-counting grouping operator
- wrapped += pattern_;
- wrapped += ")\\z";
- re = pcre_compile(wrapped.c_str(), pcre_options,
- &compile_error, &eoffset, NULL);
- }
- if (re == NULL) {
- if (error_ == &empty_string) error_ = new string(compile_error);
- }
- return re;
-}
-
-/***** Matching interfaces *****/
-
-bool RE::FullMatch(const StringPiece& text,
- const Arg& ptr1,
- const Arg& ptr2,
- const Arg& ptr3,
- const Arg& ptr4,
- const Arg& ptr5,
- const Arg& ptr6,
- const Arg& ptr7,
- const Arg& ptr8,
- const Arg& ptr9,
- const Arg& ptr10,
- const Arg& ptr11,
- const Arg& ptr12,
- const Arg& ptr13,
- const Arg& ptr14,
- const Arg& ptr15,
- const Arg& ptr16) const {
- const Arg* args[kMaxArgs];
- int n = 0;
- if (&ptr1 == &no_arg) goto done; args[n++] = &ptr1;
- if (&ptr2 == &no_arg) goto done; args[n++] = &ptr2;
- if (&ptr3 == &no_arg) goto done; args[n++] = &ptr3;
- if (&ptr4 == &no_arg) goto done; args[n++] = &ptr4;
- if (&ptr5 == &no_arg) goto done; args[n++] = &ptr5;
- if (&ptr6 == &no_arg) goto done; args[n++] = &ptr6;
- if (&ptr7 == &no_arg) goto done; args[n++] = &ptr7;
- if (&ptr8 == &no_arg) goto done; args[n++] = &ptr8;
- if (&ptr9 == &no_arg) goto done; args[n++] = &ptr9;
- if (&ptr10 == &no_arg) goto done; args[n++] = &ptr10;
- if (&ptr11 == &no_arg) goto done; args[n++] = &ptr11;
- if (&ptr12 == &no_arg) goto done; args[n++] = &ptr12;
- if (&ptr13 == &no_arg) goto done; args[n++] = &ptr13;
- if (&ptr14 == &no_arg) goto done; args[n++] = &ptr14;
- if (&ptr15 == &no_arg) goto done; args[n++] = &ptr15;
- if (&ptr16 == &no_arg) goto done; args[n++] = &ptr16;
- done:
-
- int consumed;
- int vec[kVecSize];
- return DoMatchImpl(text, ANCHOR_BOTH, &consumed, args, n, vec, kVecSize);
-}
-
-bool RE::PartialMatch(const StringPiece& text,
- const Arg& ptr1,
- const Arg& ptr2,
- const Arg& ptr3,
- const Arg& ptr4,
- const Arg& ptr5,
- const Arg& ptr6,
- const Arg& ptr7,
- const Arg& ptr8,
- const Arg& ptr9,
- const Arg& ptr10,
- const Arg& ptr11,
- const Arg& ptr12,
- const Arg& ptr13,
- const Arg& ptr14,
- const Arg& ptr15,
- const Arg& ptr16) const {
- const Arg* args[kMaxArgs];
- int n = 0;
- if (&ptr1 == &no_arg) goto done; args[n++] = &ptr1;
- if (&ptr2 == &no_arg) goto done; args[n++] = &ptr2;
- if (&ptr3 == &no_arg) goto done; args[n++] = &ptr3;
- if (&ptr4 == &no_arg) goto done; args[n++] = &ptr4;
- if (&ptr5 == &no_arg) goto done; args[n++] = &ptr5;
- if (&ptr6 == &no_arg) goto done; args[n++] = &ptr6;
- if (&ptr7 == &no_arg) goto done; args[n++] = &ptr7;
- if (&ptr8 == &no_arg) goto done; args[n++] = &ptr8;
- if (&ptr9 == &no_arg) goto done; args[n++] = &ptr9;
- if (&ptr10 == &no_arg) goto done; args[n++] = &ptr10;
- if (&ptr11 == &no_arg) goto done; args[n++] = &ptr11;
- if (&ptr12 == &no_arg) goto done; args[n++] = &ptr12;
- if (&ptr13 == &no_arg) goto done; args[n++] = &ptr13;
- if (&ptr14 == &no_arg) goto done; args[n++] = &ptr14;
- if (&ptr15 == &no_arg) goto done; args[n++] = &ptr15;
- if (&ptr16 == &no_arg) goto done; args[n++] = &ptr16;
- done:
-
- int consumed;
- int vec[kVecSize];
- return DoMatchImpl(text, UNANCHORED, &consumed, args, n, vec, kVecSize);
-}
-
-bool RE::Consume(StringPiece* input,
- const Arg& ptr1,
- const Arg& ptr2,
- const Arg& ptr3,
- const Arg& ptr4,
- const Arg& ptr5,
- const Arg& ptr6,
- const Arg& ptr7,
- const Arg& ptr8,
- const Arg& ptr9,
- const Arg& ptr10,
- const Arg& ptr11,
- const Arg& ptr12,
- const Arg& ptr13,
- const Arg& ptr14,
- const Arg& ptr15,
- const Arg& ptr16) const {
- const Arg* args[kMaxArgs];
- int n = 0;
- if (&ptr1 == &no_arg) goto done; args[n++] = &ptr1;
- if (&ptr2 == &no_arg) goto done; args[n++] = &ptr2;
- if (&ptr3 == &no_arg) goto done; args[n++] = &ptr3;
- if (&ptr4 == &no_arg) goto done; args[n++] = &ptr4;
- if (&ptr5 == &no_arg) goto done; args[n++] = &ptr5;
- if (&ptr6 == &no_arg) goto done; args[n++] = &ptr6;
- if (&ptr7 == &no_arg) goto done; args[n++] = &ptr7;
- if (&ptr8 == &no_arg) goto done; args[n++] = &ptr8;
- if (&ptr9 == &no_arg) goto done; args[n++] = &ptr9;
- if (&ptr10 == &no_arg) goto done; args[n++] = &ptr10;
- if (&ptr11 == &no_arg) goto done; args[n++] = &ptr11;
- if (&ptr12 == &no_arg) goto done; args[n++] = &ptr12;
- if (&ptr13 == &no_arg) goto done; args[n++] = &ptr13;
- if (&ptr14 == &no_arg) goto done; args[n++] = &ptr14;
- if (&ptr15 == &no_arg) goto done; args[n++] = &ptr15;
- if (&ptr16 == &no_arg) goto done; args[n++] = &ptr16;
- done:
-
- int consumed;
- int vec[kVecSize];
- if (DoMatchImpl(*input, ANCHOR_START, &consumed,
- args, n, vec, kVecSize)) {
- input->remove_prefix(consumed);
- return true;
- } else {
- return false;
- }
-}
-
-bool RE::FindAndConsume(StringPiece* input,
- const Arg& ptr1,
- const Arg& ptr2,
- const Arg& ptr3,
- const Arg& ptr4,
- const Arg& ptr5,
- const Arg& ptr6,
- const Arg& ptr7,
- const Arg& ptr8,
- const Arg& ptr9,
- const Arg& ptr10,
- const Arg& ptr11,
- const Arg& ptr12,
- const Arg& ptr13,
- const Arg& ptr14,
- const Arg& ptr15,
- const Arg& ptr16) const {
- const Arg* args[kMaxArgs];
- int n = 0;
- if (&ptr1 == &no_arg) goto done; args[n++] = &ptr1;
- if (&ptr2 == &no_arg) goto done; args[n++] = &ptr2;
- if (&ptr3 == &no_arg) goto done; args[n++] = &ptr3;
- if (&ptr4 == &no_arg) goto done; args[n++] = &ptr4;
- if (&ptr5 == &no_arg) goto done; args[n++] = &ptr5;
- if (&ptr6 == &no_arg) goto done; args[n++] = &ptr6;
- if (&ptr7 == &no_arg) goto done; args[n++] = &ptr7;
- if (&ptr8 == &no_arg) goto done; args[n++] = &ptr8;
- if (&ptr9 == &no_arg) goto done; args[n++] = &ptr9;
- if (&ptr10 == &no_arg) goto done; args[n++] = &ptr10;
- if (&ptr11 == &no_arg) goto done; args[n++] = &ptr11;
- if (&ptr12 == &no_arg) goto done; args[n++] = &ptr12;
- if (&ptr13 == &no_arg) goto done; args[n++] = &ptr13;
- if (&ptr14 == &no_arg) goto done; args[n++] = &ptr14;
- if (&ptr15 == &no_arg) goto done; args[n++] = &ptr15;
- if (&ptr16 == &no_arg) goto done; args[n++] = &ptr16;
- done:
-
- int consumed;
- int vec[kVecSize];
- if (DoMatchImpl(*input, UNANCHORED, &consumed,
- args, n, vec, kVecSize)) {
- input->remove_prefix(consumed);
- return true;
- } else {
- return false;
- }
-}
-
-bool RE::Replace(const StringPiece& rewrite,
- string *str) const {
- int vec[kVecSize];
- int matches = TryMatch(*str, 0, UNANCHORED, vec, kVecSize);
- if (matches == 0)
- return false;
-
- string s;
- if (!Rewrite(&s, rewrite, *str, vec, matches))
- return false;
-
- assert(vec[0] >= 0);
- assert(vec[1] >= 0);
- str->replace(vec[0], vec[1] - vec[0], s);
- return true;
-}
-
-// Returns PCRE_NEWLINE_CRLF, PCRE_NEWLINE_CR, or PCRE_NEWLINE_LF.
-// Note that PCRE_NEWLINE_CRLF is defined to be P_N_CR | P_N_LF.
-// Modified by PH to add PCRE_NEWLINE_ANY and PCRE_NEWLINE_ANYCRLF.
-
-static int NewlineMode(int pcre_options) {
- // TODO: if we can make it threadsafe, cache this var
- int newline_mode = 0;
- /* if (newline_mode) return newline_mode; */ // do this once it's cached
- if (pcre_options & (PCRE_NEWLINE_CRLF|PCRE_NEWLINE_CR|PCRE_NEWLINE_LF|
- PCRE_NEWLINE_ANY|PCRE_NEWLINE_ANYCRLF)) {
- newline_mode = (pcre_options &
- (PCRE_NEWLINE_CRLF|PCRE_NEWLINE_CR|PCRE_NEWLINE_LF|
- PCRE_NEWLINE_ANY|PCRE_NEWLINE_ANYCRLF));
- } else {
- int newline;
- pcre_config(PCRE_CONFIG_NEWLINE, &newline);
- if (newline == 10)
- newline_mode = PCRE_NEWLINE_LF;
- else if (newline == 13)
- newline_mode = PCRE_NEWLINE_CR;
- else if (newline == 3338)
- newline_mode = PCRE_NEWLINE_CRLF;
- else if (newline == -1)
- newline_mode = PCRE_NEWLINE_ANY;
- else if (newline == -2)
- newline_mode = PCRE_NEWLINE_ANYCRLF;
- else
- assert("" == "Unexpected return value from pcre_config(NEWLINE)");
- }
- return newline_mode;
-}
-
-int RE::GlobalReplace(const StringPiece& rewrite,
- string *str) const {
- int count = 0;
- int vec[kVecSize];
- string out;
- int start = 0;
- int lastend = -1;
-
- while (start <= static_cast<int>(str->length())) {
- int matches = TryMatch(*str, start, UNANCHORED, vec, kVecSize);
- if (matches <= 0)
- break;
- int matchstart = vec[0], matchend = vec[1];
- assert(matchstart >= start);
- assert(matchend >= matchstart);
- if (matchstart == matchend && matchstart == lastend) {
- // advance one character if we matched an empty string at the same
- // place as the last match occurred
- matchend = start + 1;
- // If the current char is CR and we're in CRLF mode, skip LF too.
- // Note it's better to call pcre_fullinfo() than to examine
- // all_options(), since options_ could have changed bewteen
- // compile-time and now, but this is simpler and safe enough.
- // Modified by PH to add ANY and ANYCRLF.
- if (start+1 < static_cast<int>(str->length()) &&
- (*str)[start] == '\r' && (*str)[start+1] == '\n' &&
- (NewlineMode(options_.all_options()) == PCRE_NEWLINE_CRLF ||
- NewlineMode(options_.all_options()) == PCRE_NEWLINE_ANY ||
- NewlineMode(options_.all_options()) == PCRE_NEWLINE_ANYCRLF)
- ) {
- matchend++;
- }
- // We also need to advance more than one char if we're in utf8 mode.
-#ifdef SUPPORT_UTF8
- if (options_.utf8()) {
- while (matchend < static_cast<int>(str->length()) &&
- ((*str)[matchend] & 0xc0) == 0x80)
- matchend++;
- }
-#endif
- if (matchend <= static_cast<int>(str->length()))
- out.append(*str, start, matchend - start);
- start = matchend;
- } else {
- out.append(*str, start, matchstart - start);
- Rewrite(&out, rewrite, *str, vec, matches);
- start = matchend;
- lastend = matchend;
- count++;
- }
- }
-
- if (count == 0)
- return 0;
-
- if (start < static_cast<int>(str->length()))
- out.append(*str, start, str->length() - start);
- swap(out, *str);
- return count;
-}
-
-bool RE::Extract(const StringPiece& rewrite,
- const StringPiece& text,
- string *out) const {
- int vec[kVecSize];
- int matches = TryMatch(text, 0, UNANCHORED, vec, kVecSize);
- if (matches == 0)
- return false;
- out->erase();
- return Rewrite(out, rewrite, text, vec, matches);
-}
-
-/*static*/ string RE::QuoteMeta(const StringPiece& unquoted) {
- string result;
-
- // Escape any ascii character not in [A-Za-z_0-9].
- //
- // Note that it's legal to escape a character even if it has no
- // special meaning in a regular expression -- so this function does
- // that. (This also makes it identical to the perl function of the
- // same name; see `perldoc -f quotemeta`.) The one exception is
- // escaping NUL: rather than doing backslash + NUL, like perl does,
- // we do '\0', because pcre itself doesn't take embedded NUL chars.
- for (int ii = 0; ii < unquoted.size(); ++ii) {
- // Note that using 'isalnum' here raises the benchmark time from
- // 32ns to 58ns:
- if (unquoted[ii] == '\0') {
- result += "\\0";
- } else if ((unquoted[ii] < 'a' || unquoted[ii] > 'z') &&
- (unquoted[ii] < 'A' || unquoted[ii] > 'Z') &&
- (unquoted[ii] < '0' || unquoted[ii] > '9') &&
- unquoted[ii] != '_' &&
- // If this is the part of a UTF8 or Latin1 character, we need
- // to copy this byte without escaping. Experimentally this is
- // what works correctly with the regexp library.
- !(unquoted[ii] & 128)) {
- result += '\\';
- result += unquoted[ii];
- } else {
- result += unquoted[ii];
- }
- }
-
- return result;
-}
-
-/***** Actual matching and rewriting code *****/
-
-int RE::TryMatch(const StringPiece& text,
- int startpos,
- Anchor anchor,
- int *vec,
- int vecsize) const {
- pcre* re = (anchor == ANCHOR_BOTH) ? re_full_ : re_partial_;
- if (re == NULL) {
- //fprintf(stderr, "Matching against invalid re: %s\n", error_->c_str());
- return 0;
- }
-
- pcre_extra extra = { 0, 0, 0, 0, 0, 0 };
- if (options_.match_limit() > 0) {
- extra.flags |= PCRE_EXTRA_MATCH_LIMIT;
- extra.match_limit = options_.match_limit();
- }
- if (options_.match_limit_recursion() > 0) {
- extra.flags |= PCRE_EXTRA_MATCH_LIMIT_RECURSION;
- extra.match_limit_recursion = options_.match_limit_recursion();
- }
- int rc = pcre_exec(re, // The regular expression object
- &extra,
- (text.data() == NULL) ? "" : text.data(),
- text.size(),
- startpos,
- (anchor == UNANCHORED) ? 0 : PCRE_ANCHORED,
- vec,
- vecsize);
-
- // Handle errors
- if (rc == PCRE_ERROR_NOMATCH) {
- return 0;
- } else if (rc < 0) {
- //fprintf(stderr, "Unexpected return code: %d when matching '%s'\n",
- // re, pattern_.c_str());
- return 0;
- } else if (rc == 0) {
- // pcre_exec() returns 0 as a special case when the number of
- // capturing subpatterns exceeds the size of the vector.
- // When this happens, there is a match and the output vector
- // is filled, but we miss out on the positions of the extra subpatterns.
- rc = vecsize / 2;
- }
-
- return rc;
-}
-
-bool RE::DoMatchImpl(const StringPiece& text,
- Anchor anchor,
- int* consumed,
- const Arg* const* args,
- int n,
- int* vec,
- int vecsize) const {
- assert((1 + n) * 3 <= vecsize); // results + PCRE workspace
- int matches = TryMatch(text, 0, anchor, vec, vecsize);
- assert(matches >= 0); // TryMatch never returns negatives
- if (matches == 0)
- return false;
-
- *consumed = vec[1];
-
- if (n == 0 || args == NULL) {
- // We are not interested in results
- return true;
- }
-
- if (NumberOfCapturingGroups() < n) {
- // RE has fewer capturing groups than number of arg pointers passed in
- return false;
- }
-
- // If we got here, we must have matched the whole pattern.
- // We do not need (can not do) any more checks on the value of 'matches' here
- // -- see the comment for TryMatch.
- for (int i = 0; i < n; i++) {
- const int start = vec[2*(i+1)];
- const int limit = vec[2*(i+1)+1];
- if (!args[i]->Parse(text.data() + start, limit-start)) {
- // TODO: Should we indicate what the error was?
- return false;
- }
- }
-
- return true;
-}
-
-bool RE::DoMatch(const StringPiece& text,
- Anchor anchor,
- int* consumed,
- const Arg* const args[],
- int n) const {
- assert(n >= 0);
- size_t const vecsize = (1 + n) * 3; // results + PCRE workspace
- // (as for kVecSize)
- int space[21]; // use stack allocation for small vecsize (common case)
- int* vec = vecsize <= 21 ? space : new int[vecsize];
- bool retval = DoMatchImpl(text, anchor, consumed, args, n, vec, vecsize);
- if (vec != space) delete [] vec;
- return retval;
-}
-
-bool RE::Rewrite(string *out, const StringPiece &rewrite,
- const StringPiece &text, int *vec, int veclen) const {
- for (const char *s = rewrite.data(), *end = s + rewrite.size();
- s < end; s++) {
- int c = *s;
- if (c == '\\') {
- c = *++s;
- if (isdigit(c)) {
- int n = (c - '0');
- if (n >= veclen) {
- //fprintf(stderr, requested group %d in regexp %.*s\n",
- // n, rewrite.size(), rewrite.data());
- return false;
- }
- int start = vec[2 * n];
- if (start >= 0)
- out->append(text.data() + start, vec[2 * n + 1] - start);
- } else if (c == '\\') {
- *out += '\\';
- } else {
- //fprintf(stderr, "invalid rewrite pattern: %.*s\n",
- // rewrite.size(), rewrite.data());
- return false;
- }
- } else {
- *out += c;
- }
- }
- return true;
-}
-
-// Return the number of capturing subpatterns, or -1 if the
-// regexp wasn't valid on construction.
-int RE::NumberOfCapturingGroups() const {
- if (re_partial_ == NULL) return -1;
-
- int result;
- int pcre_retval = pcre_fullinfo(re_partial_, // The regular expression object
- NULL, // We did not study the pattern
- PCRE_INFO_CAPTURECOUNT,
- &result);
- assert(pcre_retval == 0);
- return result;
-}
-
-/***** Parsers for various types *****/
-
-bool Arg::parse_null(const char* str, int n, void* dest) {
- // We fail if somebody asked us to store into a non-NULL void* pointer
- return (dest == NULL);
-}
-
-bool Arg::parse_string(const char* str, int n, void* dest) {
- if (dest == NULL) return true;
- reinterpret_cast<string*>(dest)->assign(str, n);
- return true;
-}
-
-bool Arg::parse_stringpiece(const char* str, int n, void* dest) {
- if (dest == NULL) return true;
- reinterpret_cast<StringPiece*>(dest)->set(str, n);
- return true;
-}
-
-bool Arg::parse_char(const char* str, int n, void* dest) {
- if (n != 1) return false;
- if (dest == NULL) return true;
- *(reinterpret_cast<char*>(dest)) = str[0];
- return true;
-}
-
-bool Arg::parse_uchar(const char* str, int n, void* dest) {
- if (n != 1) return false;
- if (dest == NULL) return true;
- *(reinterpret_cast<unsigned char*>(dest)) = str[0];
- return true;
-}
-
-// Largest number spec that we are willing to parse
-static const int kMaxNumberLength = 32;
-
-// REQUIRES "buf" must have length at least kMaxNumberLength+1
-// REQUIRES "n > 0"
-// Copies "str" into "buf" and null-terminates if necessary.
-// Returns one of:
-// a. "str" if no termination is needed
-// b. "buf" if the string was copied and null-terminated
-// c. "" if the input was invalid and has no hope of being parsed
-static const char* TerminateNumber(char* buf, const char* str, int n) {
- if ((n > 0) && isspace(*str)) {
- // We are less forgiving than the strtoxxx() routines and do not
- // allow leading spaces.
- return "";
- }
-
- // See if the character right after the input text may potentially
- // look like a digit.
- if (isdigit(str[n]) ||
- ((str[n] >= 'a') && (str[n] <= 'f')) ||
- ((str[n] >= 'A') && (str[n] <= 'F'))) {
- if (n > kMaxNumberLength) return ""; // Input too big to be a valid number
- memcpy(buf, str, n);
- buf[n] = '\0';
- return buf;
- } else {
- // We can parse right out of the supplied string, so return it.
- return str;
- }
-}
-
-bool Arg::parse_long_radix(const char* str,
- int n,
- void* dest,
- int radix) {
- if (n == 0) return false;
- char buf[kMaxNumberLength+1];
- str = TerminateNumber(buf, str, n);
- char* end;
- errno = 0;
- long r = strtol(str, &end, radix);
- if (end != str + n) return false; // Leftover junk
- if (errno) return false;
- if (dest == NULL) return true;
- *(reinterpret_cast<long*>(dest)) = r;
- return true;
-}
-
-bool Arg::parse_ulong_radix(const char* str,
- int n,
- void* dest,
- int radix) {
- if (n == 0) return false;
- char buf[kMaxNumberLength+1];
- str = TerminateNumber(buf, str, n);
- if (str[0] == '-') return false; // strtoul() on a negative number?!
- char* end;
- errno = 0;
- unsigned long r = strtoul(str, &end, radix);
- if (end != str + n) return false; // Leftover junk
- if (errno) return false;
- if (dest == NULL) return true;
- *(reinterpret_cast<unsigned long*>(dest)) = r;
- return true;
-}
-
-bool Arg::parse_short_radix(const char* str,
- int n,
- void* dest,
- int radix) {
- long r;
- if (!parse_long_radix(str, n, &r, radix)) return false; // Could not parse
- if (r < SHRT_MIN || r > SHRT_MAX) return false; // Out of range
- if (dest == NULL) return true;
- *(reinterpret_cast<short*>(dest)) = static_cast<short>(r);
- return true;
-}
-
-bool Arg::parse_ushort_radix(const char* str,
- int n,
- void* dest,
- int radix) {
- unsigned long r;
- if (!parse_ulong_radix(str, n, &r, radix)) return false; // Could not parse
- if (r > USHRT_MAX) return false; // Out of range
- if (dest == NULL) return true;
- *(reinterpret_cast<unsigned short*>(dest)) = static_cast<unsigned short>(r);
- return true;
-}
-
-bool Arg::parse_int_radix(const char* str,
- int n,
- void* dest,
- int radix) {
- long r;
- if (!parse_long_radix(str, n, &r, radix)) return false; // Could not parse
- if (r < INT_MIN || r > INT_MAX) return false; // Out of range
- if (dest == NULL) return true;
- *(reinterpret_cast<int*>(dest)) = r;
- return true;
-}
-
-bool Arg::parse_uint_radix(const char* str,
- int n,
- void* dest,
- int radix) {
- unsigned long r;
- if (!parse_ulong_radix(str, n, &r, radix)) return false; // Could not parse
- if (r > UINT_MAX) return false; // Out of range
- if (dest == NULL) return true;
- *(reinterpret_cast<unsigned int*>(dest)) = r;
- return true;
-}
-
-bool Arg::parse_longlong_radix(const char* str,
- int n,
- void* dest,
- int radix) {
-#ifndef HAVE_LONG_LONG
- return false;
-#else
- if (n == 0) return false;
- char buf[kMaxNumberLength+1];
- str = TerminateNumber(buf, str, n);
- char* end;
- errno = 0;
-#if defined HAVE_STRTOQ
- long long r = strtoq(str, &end, radix);
-#elif defined HAVE_STRTOLL
- long long r = strtoll(str, &end, radix);
-#elif defined HAVE__STRTOI64
- long long r = _strtoi64(str, &end, radix);
-#else
-#error parse_longlong_radix: cannot convert input to a long-long
-#endif
- if (end != str + n) return false; // Leftover junk
- if (errno) return false;
- if (dest == NULL) return true;
- *(reinterpret_cast<long long*>(dest)) = r;
- return true;
-#endif /* HAVE_LONG_LONG */
-}
-
-bool Arg::parse_ulonglong_radix(const char* str,
- int n,
- void* dest,
- int radix) {
-#ifndef HAVE_UNSIGNED_LONG_LONG
- return false;
-#else
- if (n == 0) return false;
- char buf[kMaxNumberLength+1];
- str = TerminateNumber(buf, str, n);
- if (str[0] == '-') return false; // strtoull() on a negative number?!
- char* end;
- errno = 0;
-#if defined HAVE_STRTOQ
- unsigned long long r = strtouq(str, &end, radix);
-#elif defined HAVE_STRTOLL
- unsigned long long r = strtoull(str, &end, radix);
-#elif defined HAVE__STRTOI64
- unsigned long long r = _strtoui64(str, &end, radix);
-#else
-#error parse_ulonglong_radix: cannot convert input to a long-long
-#endif
- if (end != str + n) return false; // Leftover junk
- if (errno) return false;
- if (dest == NULL) return true;
- *(reinterpret_cast<unsigned long long*>(dest)) = r;
- return true;
-#endif /* HAVE_UNSIGNED_LONG_LONG */
-}
-
-bool Arg::parse_double(const char* str, int n, void* dest) {
- if (n == 0) return false;
- static const int kMaxLength = 200;
- char buf[kMaxLength];
- if (n >= kMaxLength) return false;
- memcpy(buf, str, n);
- buf[n] = '\0';
- errno = 0;
- char* end;
- double r = strtod(buf, &end);
- if (end != buf + n) return false; // Leftover junk
- if (errno) return false;
- if (dest == NULL) return true;
- *(reinterpret_cast<double*>(dest)) = r;
- return true;
-}
-
-bool Arg::parse_float(const char* str, int n, void* dest) {
- double r;
- if (!parse_double(str, n, &r)) return false;
- if (dest == NULL) return true;
- *(reinterpret_cast<float*>(dest)) = static_cast<float>(r);
- return true;
-}
-
-
-#define DEFINE_INTEGER_PARSERS(name) \
- bool Arg::parse_##name(const char* str, int n, void* dest) { \
- return parse_##name##_radix(str, n, dest, 10); \
- } \
- bool Arg::parse_##name##_hex(const char* str, int n, void* dest) { \
- return parse_##name##_radix(str, n, dest, 16); \
- } \
- bool Arg::parse_##name##_octal(const char* str, int n, void* dest) { \
- return parse_##name##_radix(str, n, dest, 8); \
- } \
- bool Arg::parse_##name##_cradix(const char* str, int n, void* dest) { \
- return parse_##name##_radix(str, n, dest, 0); \
- }
-
-DEFINE_INTEGER_PARSERS(short) /* */
-DEFINE_INTEGER_PARSERS(ushort) /* */
-DEFINE_INTEGER_PARSERS(int) /* Don't use semicolons after these */
-DEFINE_INTEGER_PARSERS(uint) /* statements because they can cause */
-DEFINE_INTEGER_PARSERS(long) /* compiler warnings if the checking */
-DEFINE_INTEGER_PARSERS(ulong) /* level is turned up high enough. */
-DEFINE_INTEGER_PARSERS(longlong) /* */
-DEFINE_INTEGER_PARSERS(ulonglong) /* */
-
-#undef DEFINE_INTEGER_PARSERS
-
-} // namespace pcrecpp
diff --git a/crawl-ref/source/util/pcre/pcrecpp.h b/crawl-ref/source/util/pcre/pcrecpp.h
deleted file mode 100644
index a87a816442..0000000000
--- a/crawl-ref/source/util/pcre/pcrecpp.h
+++ /dev/null
@@ -1,703 +0,0 @@
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// Author: Sanjay Ghemawat
-// Support for PCRE_XXX modifiers added by Giuseppe Maxia, July 2005
-
-#ifndef _PCRECPP_H
-#define _PCRECPP_H
-
-// C++ interface to the pcre regular-expression library. RE supports
-// Perl-style regular expressions (with extensions like \d, \w, \s,
-// ...).
-//
-// -----------------------------------------------------------------------
-// REGEXP SYNTAX:
-//
-// This module is part of the pcre library and hence supports its syntax
-// for regular expressions.
-//
-// The syntax is pretty similar to Perl's. For those not familiar
-// with Perl's regular expressions, here are some examples of the most
-// commonly used extensions:
-//
-// "hello (\\w+) world" -- \w matches a "word" character
-// "version (\\d+)" -- \d matches a digit
-// "hello\\s+world" -- \s matches any whitespace character
-// "\\b(\\w+)\\b" -- \b matches empty string at a word boundary
-// "(?i)hello" -- (?i) turns on case-insensitive matching
-// "/\\*(.*?)\\*/" -- .*? matches . minimum no. of times possible
-//
-// -----------------------------------------------------------------------
-// MATCHING INTERFACE:
-//
-// The "FullMatch" operation checks that supplied text matches a
-// supplied pattern exactly.
-//
-// Example: successful match
-// pcrecpp::RE re("h.*o");
-// re.FullMatch("hello");
-//
-// Example: unsuccessful match (requires full match):
-// pcrecpp::RE re("e");
-// !re.FullMatch("hello");
-//
-// Example: creating a temporary RE object:
-// pcrecpp::RE("h.*o").FullMatch("hello");
-//
-// You can pass in a "const char*" or a "string" for "text". The
-// examples below tend to use a const char*.
-//
-// You can, as in the different examples above, store the RE object
-// explicitly in a variable or use a temporary RE object. The
-// examples below use one mode or the other arbitrarily. Either
-// could correctly be used for any of these examples.
-//
-// -----------------------------------------------------------------------
-// MATCHING WITH SUB-STRING EXTRACTION:
-//
-// You can supply extra pointer arguments to extract matched subpieces.
-//
-// Example: extracts "ruby" into "s" and 1234 into "i"
-// int i;
-// string s;
-// pcrecpp::RE re("(\\w+):(\\d+)");
-// re.FullMatch("ruby:1234", &s, &i);
-//
-// Example: does not try to extract any extra sub-patterns
-// re.FullMatch("ruby:1234", &s);
-//
-// Example: does not try to extract into NULL
-// re.FullMatch("ruby:1234", NULL, &i);
-//
-// Example: integer overflow causes failure
-// !re.FullMatch("ruby:1234567891234", NULL, &i);
-//
-// Example: fails because there aren't enough sub-patterns:
-// !pcrecpp::RE("\\w+:\\d+").FullMatch("ruby:1234", &s);
-//
-// Example: fails because string cannot be stored in integer
-// !pcrecpp::RE("(.*)").FullMatch("ruby", &i);
-//
-// The provided pointer arguments can be pointers to any scalar numeric
-// type, or one of
-// string (matched piece is copied to string)
-// StringPiece (StringPiece is mutated to point to matched piece)
-// T (where "bool T::ParseFrom(const char*, int)" exists)
-// NULL (the corresponding matched sub-pattern is not copied)
-//
-// CAVEAT: An optional sub-pattern that does not exist in the matched
-// string is assigned the empty string. Therefore, the following will
-// return false (because the empty string is not a valid number):
-// int number;
-// pcrecpp::RE::FullMatch("abc", "[a-z]+(\\d+)?", &number);
-//
-// -----------------------------------------------------------------------
-// DO_MATCH
-//
-// The matching interface supports at most 16 arguments per call.
-// If you need more, consider using the more general interface
-// pcrecpp::RE::DoMatch(). See pcrecpp.h for the signature for DoMatch.
-//
-// -----------------------------------------------------------------------
-// PARTIAL MATCHES
-//
-// You can use the "PartialMatch" operation when you want the pattern
-// to match any substring of the text.
-//
-// Example: simple search for a string:
-// pcrecpp::RE("ell").PartialMatch("hello");
-//
-// Example: find first number in a string:
-// int number;
-// pcrecpp::RE re("(\\d+)");
-// re.PartialMatch("x*100 + 20", &number);
-// assert(number == 100);
-//
-// -----------------------------------------------------------------------
-// UTF-8 AND THE MATCHING INTERFACE:
-//
-// By default, pattern and text are plain text, one byte per character.
-// The UTF8 flag, passed to the constructor, causes both pattern
-// and string to be treated as UTF-8 text, still a byte stream but
-// potentially multiple bytes per character. In practice, the text
-// is likelier to be UTF-8 than the pattern, but the match returned
-// may depend on the UTF8 flag, so always use it when matching
-// UTF8 text. E.g., "." will match one byte normally but with UTF8
-// set may match up to three bytes of a multi-byte character.
-//
-// Example:
-// pcrecpp::RE_Options options;
-// options.set_utf8();
-// pcrecpp::RE re(utf8_pattern, options);
-// re.FullMatch(utf8_string);
-//
-// Example: using the convenience function UTF8():
-// pcrecpp::RE re(utf8_pattern, pcrecpp::UTF8());
-// re.FullMatch(utf8_string);
-//
-// NOTE: The UTF8 option is ignored if pcre was not configured with the
-// --enable-utf8 flag.
-//
-// -----------------------------------------------------------------------
-// PASSING MODIFIERS TO THE REGULAR EXPRESSION ENGINE
-//
-// PCRE defines some modifiers to change the behavior of the regular
-// expression engine.
-// The C++ wrapper defines an auxiliary class, RE_Options, as a vehicle
-// to pass such modifiers to a RE class.
-//
-// Currently, the following modifiers are supported
-//
-// modifier description Perl corresponding
-//
-// PCRE_CASELESS case insensitive match /i
-// PCRE_MULTILINE multiple lines match /m
-// PCRE_DOTALL dot matches newlines /s
-// PCRE_DOLLAR_ENDONLY $ matches only at end N/A
-// PCRE_EXTRA strict escape parsing N/A
-// PCRE_EXTENDED ignore whitespaces /x
-// PCRE_UTF8 handles UTF8 chars built-in
-// PCRE_UNGREEDY reverses * and *? N/A
-// PCRE_NO_AUTO_CAPTURE disables matching parens N/A (*)
-//
-// (For a full account on how each modifier works, please check the
-// PCRE API reference manual).
-//
-// (*) Both Perl and PCRE allow non matching parentheses by means of the
-// "?:" modifier within the pattern itself. e.g. (?:ab|cd) does not
-// capture, while (ab|cd) does.
-//
-// For each modifier, there are two member functions whose name is made
-// out of the modifier in lowercase, without the "PCRE_" prefix. For
-// instance, PCRE_CASELESS is handled by
-// bool caseless(),
-// which returns true if the modifier is set, and
-// RE_Options & set_caseless(bool),
-// which sets or unsets the modifier.
-//
-// Moreover, PCRE_EXTRA_MATCH_LIMIT can be accessed through the
-// set_match_limit() and match_limit() member functions.
-// Setting match_limit to a non-zero value will limit the executation of
-// pcre to keep it from doing bad things like blowing the stack or taking
-// an eternity to return a result. A value of 5000 is good enough to stop
-// stack blowup in a 2MB thread stack. Setting match_limit to zero will
-// disable match limiting. Alternately, you can set match_limit_recursion()
-// which uses PCRE_EXTRA_MATCH_LIMIT_RECURSION to limit how much pcre
-// recurses. match_limit() caps the number of matches pcre does;
-// match_limit_recrusion() caps the depth of recursion.
-//
-// Normally, to pass one or more modifiers to a RE class, you declare
-// a RE_Options object, set the appropriate options, and pass this
-// object to a RE constructor. Example:
-//
-// RE_options opt;
-// opt.set_caseless(true);
-//
-// if (RE("HELLO", opt).PartialMatch("hello world")) ...
-//
-// RE_options has two constructors. The default constructor takes no
-// arguments and creates a set of flags that are off by default.
-//
-// The optional parameter 'option_flags' is to facilitate transfer
-// of legacy code from C programs. This lets you do
-// RE(pattern, RE_Options(PCRE_CASELESS|PCRE_MULTILINE)).PartialMatch(str);
-//
-// But new code is better off doing
-// RE(pattern,
-// RE_Options().set_caseless(true).set_multiline(true)).PartialMatch(str);
-// (See below)
-//
-// If you are going to pass one of the most used modifiers, there are some
-// convenience functions that return a RE_Options class with the
-// appropriate modifier already set:
-// CASELESS(), UTF8(), MULTILINE(), DOTALL(), EXTENDED()
-//
-// If you need to set several options at once, and you don't want to go
-// through the pains of declaring a RE_Options object and setting several
-// options, there is a parallel method that give you such ability on the
-// fly. You can concatenate several set_xxxxx member functions, since each
-// of them returns a reference to its class object. e.g.: to pass
-// PCRE_CASELESS, PCRE_EXTENDED, and PCRE_MULTILINE to a RE with one
-// statement, you may write
-//
-// RE(" ^ xyz \\s+ .* blah$", RE_Options()
-// .set_caseless(true)
-// .set_extended(true)
-// .set_multiline(true)).PartialMatch(sometext);
-//
-// -----------------------------------------------------------------------
-// SCANNING TEXT INCREMENTALLY
-//
-// The "Consume" operation may be useful if you want to repeatedly
-// match regular expressions at the front of a string and skip over
-// them as they match. This requires use of the "StringPiece" type,
-// which represents a sub-range of a real string. Like RE, StringPiece
-// is defined in the pcrecpp namespace.
-//
-// Example: read lines of the form "var = value" from a string.
-// string contents = ...; // Fill string somehow
-// pcrecpp::StringPiece input(contents); // Wrap in a StringPiece
-//
-// string var;
-// int value;
-// pcrecpp::RE re("(\\w+) = (\\d+)\n");
-// while (re.Consume(&input, &var, &value)) {
-// ...;
-// }
-//
-// Each successful call to "Consume" will set "var/value", and also
-// advance "input" so it points past the matched text.
-//
-// The "FindAndConsume" operation is similar to "Consume" but does not
-// anchor your match at the beginning of the string. For example, you
-// could extract all words from a string by repeatedly calling
-// pcrecpp::RE("(\\w+)").FindAndConsume(&input, &word)
-//
-// -----------------------------------------------------------------------
-// PARSING HEX/OCTAL/C-RADIX NUMBERS
-//
-// By default, if you pass a pointer to a numeric value, the
-// corresponding text is interpreted as a base-10 number. You can
-// instead wrap the pointer with a call to one of the operators Hex(),
-// Octal(), or CRadix() to interpret the text in another base. The
-// CRadix operator interprets C-style "0" (base-8) and "0x" (base-16)
-// prefixes, but defaults to base-10.
-//
-// Example:
-// int a, b, c, d;
-// pcrecpp::RE re("(.*) (.*) (.*) (.*)");
-// re.FullMatch("100 40 0100 0x40",
-// pcrecpp::Octal(&a), pcrecpp::Hex(&b),
-// pcrecpp::CRadix(&c), pcrecpp::CRadix(&d));
-// will leave 64 in a, b, c, and d.
-//
-// -----------------------------------------------------------------------
-// REPLACING PARTS OF STRINGS
-//
-// You can replace the first match of "pattern" in "str" with
-// "rewrite". Within "rewrite", backslash-escaped digits (\1 to \9)
-// can be used to insert text matching corresponding parenthesized
-// group from the pattern. \0 in "rewrite" refers to the entire
-// matching text. E.g.,
-//
-// string s = "yabba dabba doo";
-// pcrecpp::RE("b+").Replace("d", &s);
-//
-// will leave "s" containing "yada dabba doo". The result is true if
-// the pattern matches and a replacement occurs, or false otherwise.
-//
-// GlobalReplace() is like Replace(), except that it replaces all
-// occurrences of the pattern in the string with the rewrite.
-// Replacements are not subject to re-matching. E.g.,
-//
-// string s = "yabba dabba doo";
-// pcrecpp::RE("b+").GlobalReplace("d", &s);
-//
-// will leave "s" containing "yada dada doo". It returns the number
-// of replacements made.
-//
-// Extract() is like Replace(), except that if the pattern matches,
-// "rewrite" is copied into "out" (an additional argument) with
-// substitutions. The non-matching portions of "text" are ignored.
-// Returns true iff a match occurred and the extraction happened
-// successfully. If no match occurs, the string is left unaffected.
-
-
-#include <string>
-#include <pcre.h>
-#include <pcrecpparg.h> // defines the Arg class
-// This isn't technically needed here, but we include it
-// anyway so folks who include pcrecpp.h don't have to.
-#include <pcre_stringpiece.h>
-
-namespace pcrecpp {
-
-#define PCRE_SET_OR_CLEAR(b, o) \
- if (b) all_options_ |= (o); else all_options_ &= ~(o); \
- return *this
-
-#define PCRE_IS_SET(o) \
- (all_options_ & o) == o
-
-/***** Compiling regular expressions: the RE class *****/
-
-// RE_Options allow you to set options to be passed along to pcre,
-// along with other options we put on top of pcre.
-// Only 9 modifiers, plus match_limit and match_limit_recursion,
-// are supported now.
-class PCRECPP_EXP_DEFN RE_Options {
- public:
- // constructor
- RE_Options() : match_limit_(0), match_limit_recursion_(0), all_options_(0) {}
-
- // alternative constructor.
- // To facilitate transfer of legacy code from C programs
- //
- // This lets you do
- // RE(pattern, RE_Options(PCRE_CASELESS|PCRE_MULTILINE)).PartialMatch(str);
- // But new code is better off doing
- // RE(pattern,
- // RE_Options().set_caseless(true).set_multiline(true)).PartialMatch(str);
- RE_Options(int option_flags) : match_limit_(0), match_limit_recursion_(0),
- all_options_(option_flags) {}
- // we're fine with the default destructor, copy constructor, etc.
-
- // accessors and mutators
- int match_limit() const { return match_limit_; };
- RE_Options &set_match_limit(int limit) {
- match_limit_ = limit;
- return *this;
- }
-
- int match_limit_recursion() const { return match_limit_recursion_; };
- RE_Options &set_match_limit_recursion(int limit) {
- match_limit_recursion_ = limit;
- return *this;
- }
-
- bool caseless() const {
- return PCRE_IS_SET(PCRE_CASELESS);
- }
- RE_Options &set_caseless(bool x) {
- PCRE_SET_OR_CLEAR(x, PCRE_CASELESS);
- }
-
- bool multiline() const {
- return PCRE_IS_SET(PCRE_MULTILINE);
- }
- RE_Options &set_multiline(bool x) {
- PCRE_SET_OR_CLEAR(x, PCRE_MULTILINE);
- }
-
- bool dotall() const {
- return PCRE_IS_SET(PCRE_DOTALL);
- }
- RE_Options &set_dotall(bool x) {
- PCRE_SET_OR_CLEAR(x, PCRE_DOTALL);
- }
-
- bool extended() const {
- return PCRE_IS_SET(PCRE_EXTENDED);
- }
- RE_Options &set_extended(bool x) {
- PCRE_SET_OR_CLEAR(x, PCRE_EXTENDED);
- }
-
- bool dollar_endonly() const {
- return PCRE_IS_SET(PCRE_DOLLAR_ENDONLY);
- }
- RE_Options &set_dollar_endonly(bool x) {
- PCRE_SET_OR_CLEAR(x, PCRE_DOLLAR_ENDONLY);
- }
-
- bool extra() const {
- return PCRE_IS_SET(PCRE_EXTRA);
- }
- RE_Options &set_extra(bool x) {
- PCRE_SET_OR_CLEAR(x, PCRE_EXTRA);
- }
-
- bool ungreedy() const {
- return PCRE_IS_SET(PCRE_UNGREEDY);
- }
- RE_Options &set_ungreedy(bool x) {
- PCRE_SET_OR_CLEAR(x, PCRE_UNGREEDY);
- }
-
- bool utf8() const {
- return PCRE_IS_SET(PCRE_UTF8);
- }
- RE_Options &set_utf8(bool x) {
- PCRE_SET_OR_CLEAR(x, PCRE_UTF8);
- }
-
- bool no_auto_capture() const {
- return PCRE_IS_SET(PCRE_NO_AUTO_CAPTURE);
- }
- RE_Options &set_no_auto_capture(bool x) {
- PCRE_SET_OR_CLEAR(x, PCRE_NO_AUTO_CAPTURE);
- }
-
- RE_Options &set_all_options(int opt) {
- all_options_ = opt;
- return *this;
- }
- int all_options() const {
- return all_options_ ;
- }
-
- // TODO: add other pcre flags
-
- private:
- int match_limit_;
- int match_limit_recursion_;
- int all_options_;
-};
-
-// These functions return some common RE_Options
-static inline RE_Options UTF8() {
- return RE_Options().set_utf8(true);
-}
-
-static inline RE_Options CASELESS() {
- return RE_Options().set_caseless(true);
-}
-static inline RE_Options MULTILINE() {
- return RE_Options().set_multiline(true);
-}
-
-static inline RE_Options DOTALL() {
- return RE_Options().set_dotall(true);
-}
-
-static inline RE_Options EXTENDED() {
- return RE_Options().set_extended(true);
-}
-
-// Interface for regular expression matching. Also corresponds to a
-// pre-compiled regular expression. An "RE" object is safe for
-// concurrent use by multiple threads.
-class PCRECPP_EXP_DEFN RE {
- public:
- // We provide implicit conversions from strings so that users can
- // pass in a string or a "const char*" wherever an "RE" is expected.
- RE(const string& pat) { Init(pat, NULL); }
- RE(const string& pat, const RE_Options& option) { Init(pat, &option); }
- RE(const char* pat) { Init(pat, NULL); }
- RE(const char* pat, const RE_Options& option) { Init(pat, &option); }
- RE(const unsigned char* pat) {
- Init(reinterpret_cast<const char*>(pat), NULL);
- }
- RE(const unsigned char* pat, const RE_Options& option) {
- Init(reinterpret_cast<const char*>(pat), &option);
- }
-
- // Copy constructor & assignment - note that these are expensive
- // because they recompile the expression.
- RE(const RE& re) { Init(re.pattern_, &re.options_); }
- const RE& operator=(const RE& re) {
- if (this != &re) {
- Cleanup();
-
- // This is the code that originally came from Google
- // Init(re.pattern_.c_str(), &re.options_);
-
- // This is the replacement from Ari Pollak
- Init(re.pattern_, &re.options_);
- }
- return *this;
- }
-
-
- ~RE();
-
- // The string specification for this RE. E.g.
- // RE re("ab*c?d+");
- // re.pattern(); // "ab*c?d+"
- const string& pattern() const { return pattern_; }
-
- // If RE could not be created properly, returns an error string.
- // Else returns the empty string.
- const string& error() const { return *error_; }
-
- /***** The useful part: the matching interface *****/
-
- // This is provided so one can do pattern.ReplaceAll() just as
- // easily as ReplaceAll(pattern-text, ....)
-
- bool FullMatch(const StringPiece& text,
- const Arg& ptr1 = no_arg,
- const Arg& ptr2 = no_arg,
- const Arg& ptr3 = no_arg,
- const Arg& ptr4 = no_arg,
- const Arg& ptr5 = no_arg,
- const Arg& ptr6 = no_arg,
- const Arg& ptr7 = no_arg,
- const Arg& ptr8 = no_arg,
- const Arg& ptr9 = no_arg,
- const Arg& ptr10 = no_arg,
- const Arg& ptr11 = no_arg,
- const Arg& ptr12 = no_arg,
- const Arg& ptr13 = no_arg,
- const Arg& ptr14 = no_arg,
- const Arg& ptr15 = no_arg,
- const Arg& ptr16 = no_arg) const;
-
- bool PartialMatch(const StringPiece& text,
- const Arg& ptr1 = no_arg,
- const Arg& ptr2 = no_arg,
- const Arg& ptr3 = no_arg,
- const Arg& ptr4 = no_arg,
- const Arg& ptr5 = no_arg,
- const Arg& ptr6 = no_arg,
- const Arg& ptr7 = no_arg,
- const Arg& ptr8 = no_arg,
- const Arg& ptr9 = no_arg,
- const Arg& ptr10 = no_arg,
- const Arg& ptr11 = no_arg,
- const Arg& ptr12 = no_arg,
- const Arg& ptr13 = no_arg,
- const Arg& ptr14 = no_arg,
- const Arg& ptr15 = no_arg,
- const Arg& ptr16 = no_arg) const;
-
- bool Consume(StringPiece* input,
- const Arg& ptr1 = no_arg,
- const Arg& ptr2 = no_arg,
- const Arg& ptr3 = no_arg,
- const Arg& ptr4 = no_arg,
- const Arg& ptr5 = no_arg,
- const Arg& ptr6 = no_arg,
- const Arg& ptr7 = no_arg,
- const Arg& ptr8 = no_arg,
- const Arg& ptr9 = no_arg,
- const Arg& ptr10 = no_arg,
- const Arg& ptr11 = no_arg,
- const Arg& ptr12 = no_arg,
- const Arg& ptr13 = no_arg,
- const Arg& ptr14 = no_arg,
- const Arg& ptr15 = no_arg,
- const Arg& ptr16 = no_arg) const;
-
- bool FindAndConsume(StringPiece* input,
- const Arg& ptr1 = no_arg,
- const Arg& ptr2 = no_arg,
- const Arg& ptr3 = no_arg,
- const Arg& ptr4 = no_arg,
- const Arg& ptr5 = no_arg,
- const Arg& ptr6 = no_arg,
- const Arg& ptr7 = no_arg,
- const Arg& ptr8 = no_arg,
- const Arg& ptr9 = no_arg,
- const Arg& ptr10 = no_arg,
- const Arg& ptr11 = no_arg,
- const Arg& ptr12 = no_arg,
- const Arg& ptr13 = no_arg,
- const Arg& ptr14 = no_arg,
- const Arg& ptr15 = no_arg,
- const Arg& ptr16 = no_arg) const;
-
- bool Replace(const StringPiece& rewrite,
- string *str) const;
-
- int GlobalReplace(const StringPiece& rewrite,
- string *str) const;
-
- bool Extract(const StringPiece &rewrite,
- const StringPiece &text,
- string *out) const;
-
- // Escapes all potentially meaningful regexp characters in
- // 'unquoted'. The returned string, used as a regular expression,
- // will exactly match the original string. For example,
- // 1.5-2.0?
- // may become:
- // 1\.5\-2\.0\?
- // Note QuoteMeta behaves the same as perl's QuoteMeta function,
- // *except* that it escapes the NUL character (\0) as backslash + 0,
- // rather than backslash + NUL.
- static string QuoteMeta(const StringPiece& unquoted);
-
-
- /***** Generic matching interface *****/
-
- // Type of match (TODO: Should be restructured as part of RE_Options)
- enum Anchor {
- UNANCHORED, // No anchoring
- ANCHOR_START, // Anchor at start only
- ANCHOR_BOTH // Anchor at start and end
- };
-
- // General matching routine. Stores the length of the match in
- // "*consumed" if successful.
- bool DoMatch(const StringPiece& text,
- Anchor anchor,
- int* consumed,
- const Arg* const* args, int n) const;
-
- // Return the number of capturing subpatterns, or -1 if the
- // regexp wasn't valid on construction.
- int NumberOfCapturingGroups() const;
-
- // The default value for an argument, to indicate no arg was passed in
- static Arg no_arg;
-
- private:
-
- void Init(const string& pattern, const RE_Options* options);
- void Cleanup();
-
- // Match against "text", filling in "vec" (up to "vecsize" * 2/3) with
- // pairs of integers for the beginning and end positions of matched
- // text. The first pair corresponds to the entire matched text;
- // subsequent pairs correspond, in order, to parentheses-captured
- // matches. Returns the number of pairs (one more than the number of
- // the last subpattern with a match) if matching was successful
- // and zero if the match failed.
- // I.e. for RE("(foo)|(bar)|(baz)") it will return 2, 3, and 4 when matching
- // against "foo", "bar", and "baz" respectively.
- // When matching RE("(foo)|hello") against "hello", it will return 1.
- // But the values for all subpattern are filled in into "vec".
- int TryMatch(const StringPiece& text,
- int startpos,
- Anchor anchor,
- int *vec,
- int vecsize) const;
-
- // Append the "rewrite" string, with backslash subsitutions from "text"
- // and "vec", to string "out".
- bool Rewrite(string *out,
- const StringPiece& rewrite,
- const StringPiece& text,
- int *vec,
- int veclen) const;
-
- // internal implementation for DoMatch
- bool DoMatchImpl(const StringPiece& text,
- Anchor anchor,
- int* consumed,
- const Arg* const args[],
- int n,
- int* vec,
- int vecsize) const;
-
- // Compile the regexp for the specified anchoring mode
- pcre* Compile(Anchor anchor);
-
- string pattern_;
- RE_Options options_;
- pcre* re_full_; // For full matches
- pcre* re_partial_; // For partial matches
- const string* error_; // Error indicator (or points to empty string)
-};
-
-} // namespace pcrecpp
-
-#endif /* _PCRECPP_H */
diff --git a/crawl-ref/source/util/pcre/pcrecpp_internal.h b/crawl-ref/source/util/pcre/pcrecpp_internal.h
deleted file mode 100644
index 88fdf9c246..0000000000
--- a/crawl-ref/source/util/pcre/pcrecpp_internal.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/*
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-
-#ifndef PCRECPP_INTERNAL_H
-#define PCRECPP_INTERNAL_H
-
-/* When compiling a DLL for Windows, the exported symbols have to be declared
-using some MS magic. I found some useful information on this web page:
-http://msdn2.microsoft.com/en-us/library/y4h7bcy6(VS.80).aspx. According to the
-information there, using __declspec(dllexport) without "extern" we have a
-definition; with "extern" we have a declaration. The settings here override the
-setting in pcre.h. We use:
-
- PCRECPP_EXP_DECL for declarations
- PCRECPP_EXP_DEFN for definitions of exported functions
-
-*/
-
-#ifndef PCRECPP_EXP_DECL
-# ifdef _WIN32
-# ifndef PCRE_STATIC
-# define PCRECPP_EXP_DECL extern __declspec(dllexport)
-# define PCRECPP_EXP_DEFN __declspec(dllexport)
-# else
-# define PCRECPP_EXP_DECL extern
-# define PCRECPP_EXP_DEFN
-# endif
-# else
-# define PCRECPP_EXP_DECL extern
-# define PCRECPP_EXP_DEFN
-# endif
-#endif
-
-#endif /* PCRECPP_INTERNAL_H */
-
-/* End of pcrecpp_internal.h */
diff --git a/crawl-ref/source/util/pcre/pcrecpp_unittest.cc b/crawl-ref/source/util/pcre/pcrecpp_unittest.cc
deleted file mode 100644
index 44e0cc9558..0000000000
--- a/crawl-ref/source/util/pcre/pcrecpp_unittest.cc
+++ /dev/null
@@ -1,1276 +0,0 @@
-// -*- coding: utf-8 -*-
-//
-// Copyright (c) 2005 - 2006, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// Author: Sanjay Ghemawat
-//
-// TODO: Test extractions for PartialMatch/Consume
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <stdio.h>
-#include <cassert>
-#include <vector>
-#include "pcrecpp.h"
-
-using pcrecpp::StringPiece;
-using pcrecpp::RE;
-using pcrecpp::RE_Options;
-using pcrecpp::Hex;
-using pcrecpp::Octal;
-using pcrecpp::CRadix;
-
-static bool VERBOSE_TEST = false;
-
-// CHECK dies with a fatal error if condition is not true. It is *not*
-// controlled by NDEBUG, so the check will be executed regardless of
-// compilation mode. Therefore, it is safe to do things like:
-// CHECK_EQ(fp->Write(x), 4)
-#define CHECK(condition) do { \
- if (!(condition)) { \
- fprintf(stderr, "%s:%d: Check failed: %s\n", \
- __FILE__, __LINE__, #condition); \
- exit(1); \
- } \
-} while (0)
-
-#define CHECK_EQ(a, b) CHECK(a == b)
-
-static void Timing1(int num_iters) {
- // Same pattern lots of times
- RE pattern("ruby:\\d+");
- StringPiece p("ruby:1234");
- for (int j = num_iters; j > 0; j--) {
- CHECK(pattern.FullMatch(p));
- }
-}
-
-static void Timing2(int num_iters) {
- // Same pattern lots of times
- RE pattern("ruby:(\\d+)");
- int i;
- for (int j = num_iters; j > 0; j--) {
- CHECK(pattern.FullMatch("ruby:1234", &i));
- CHECK_EQ(i, 1234);
- }
-}
-
-static void Timing3(int num_iters) {
- string text_string;
- for (int j = num_iters; j > 0; j--) {
- text_string += "this is another line\n";
- }
-
- RE line_matcher(".*\n");
- string line;
- StringPiece text(text_string);
- int counter = 0;
- while (line_matcher.Consume(&text)) {
- counter++;
- }
- printf("Matched %d lines\n", counter);
-}
-
-#if 0 // uncomment this if you have a way of defining VirtualProcessSize()
-
-static void LeakTest() {
- // Check for memory leaks
- unsigned long long initial_size = 0;
- for (int i = 0; i < 100000; i++) {
- if (i == 50000) {
- initial_size = VirtualProcessSize();
- printf("Size after 50000: %llu\n", initial_size);
- }
- char buf[100]; // definitely big enough
- sprintf(buf, "pat%09d", i);
- RE newre(buf);
- }
- uint64 final_size = VirtualProcessSize();
- printf("Size after 100000: %llu\n", final_size);
- const double growth = double(final_size - initial_size) / final_size;
- printf("Growth: %0.2f%%", growth * 100);
- CHECK(growth < 0.02); // Allow < 2% growth
-}
-
-#endif
-
-static void RadixTests() {
- printf("Testing hex\n");
-
-#define CHECK_HEX(type, value) \
- do { \
- type v; \
- CHECK(RE("([0-9a-fA-F]+)[uUlL]*").FullMatch(#value, Hex(&v))); \
- CHECK_EQ(v, 0x ## value); \
- CHECK(RE("([0-9a-fA-FxX]+)[uUlL]*").FullMatch("0x" #value, CRadix(&v))); \
- CHECK_EQ(v, 0x ## value); \
- } while(0)
-
- CHECK_HEX(short, 2bad);
- CHECK_HEX(unsigned short, 2badU);
- CHECK_HEX(int, dead);
- CHECK_HEX(unsigned int, deadU);
- CHECK_HEX(long, 7eadbeefL);
- CHECK_HEX(unsigned long, deadbeefUL);
-#ifdef HAVE_LONG_LONG
- CHECK_HEX(long long, 12345678deadbeefLL);
-#endif
-#ifdef HAVE_UNSIGNED_LONG_LONG
- CHECK_HEX(unsigned long long, cafebabedeadbeefULL);
-#endif
-
-#undef CHECK_HEX
-
- printf("Testing octal\n");
-
-#define CHECK_OCTAL(type, value) \
- do { \
- type v; \
- CHECK(RE("([0-7]+)[uUlL]*").FullMatch(#value, Octal(&v))); \
- CHECK_EQ(v, 0 ## value); \
- CHECK(RE("([0-9a-fA-FxX]+)[uUlL]*").FullMatch("0" #value, CRadix(&v))); \
- CHECK_EQ(v, 0 ## value); \
- } while(0)
-
- CHECK_OCTAL(short, 77777);
- CHECK_OCTAL(unsigned short, 177777U);
- CHECK_OCTAL(int, 17777777777);
- CHECK_OCTAL(unsigned int, 37777777777U);
- CHECK_OCTAL(long, 17777777777L);
- CHECK_OCTAL(unsigned long, 37777777777UL);
-#ifdef HAVE_LONG_LONG
- CHECK_OCTAL(long long, 777777777777777777777LL);
-#endif
-#ifdef HAVE_UNSIGNED_LONG_LONG
- CHECK_OCTAL(unsigned long long, 1777777777777777777777ULL);
-#endif
-
-#undef CHECK_OCTAL
-
- printf("Testing decimal\n");
-
-#define CHECK_DECIMAL(type, value) \
- do { \
- type v; \
- CHECK(RE("(-?[0-9]+)[uUlL]*").FullMatch(#value, &v)); \
- CHECK_EQ(v, value); \
- CHECK(RE("(-?[0-9a-fA-FxX]+)[uUlL]*").FullMatch(#value, CRadix(&v))); \
- CHECK_EQ(v, value); \
- } while(0)
-
- CHECK_DECIMAL(short, -1);
- CHECK_DECIMAL(unsigned short, 9999);
- CHECK_DECIMAL(int, -1000);
- CHECK_DECIMAL(unsigned int, 12345U);
- CHECK_DECIMAL(long, -10000000L);
- CHECK_DECIMAL(unsigned long, 3083324652U);
-#ifdef HAVE_LONG_LONG
- CHECK_DECIMAL(long long, -100000000000000LL);
-#endif
-#ifdef HAVE_UNSIGNED_LONG_LONG
- CHECK_DECIMAL(unsigned long long, 1234567890987654321ULL);
-#endif
-
-#undef CHECK_DECIMAL
-
-}
-
-static void TestReplace() {
- printf("Testing Replace\n");
-
- struct ReplaceTest {
- const char *regexp;
- const char *rewrite;
- const char *original;
- const char *single;
- const char *global;
- int global_count; // the expected return value from ReplaceAll
- };
- static const ReplaceTest tests[] = {
- { "(qu|[b-df-hj-np-tv-z]*)([a-z]+)",
- "\\2\\1ay",
- "the quick brown fox jumps over the lazy dogs.",
- "ethay quick brown fox jumps over the lazy dogs.",
- "ethay ickquay ownbray oxfay umpsjay overay ethay azylay ogsday.",
- 9 },
- { "\\w+",
- "\\0-NOSPAM",
- "paul.haahr@google.com",
- "paul-NOSPAM.haahr@google.com",
- "paul-NOSPAM.haahr-NOSPAM@google-NOSPAM.com-NOSPAM",
- 4 },
- { "^",
- "(START)",
- "foo",
- "(START)foo",
- "(START)foo",
- 1 },
- { "^",
- "(START)",
- "",
- "(START)",
- "(START)",
- 1 },
- { "$",
- "(END)",
- "",
- "(END)",
- "(END)",
- 1 },
- { "b",
- "bb",
- "ababababab",
- "abbabababab",
- "abbabbabbabbabb",
- 5 },
- { "b",
- "bb",
- "bbbbbb",
- "bbbbbbb",
- "bbbbbbbbbbbb",
- 6 },
- { "b+",
- "bb",
- "bbbbbb",
- "bb",
- "bb",
- 1 },
- { "b*",
- "bb",
- "bbbbbb",
- "bb",
- "bb",
- 1 },
- { "b*",
- "bb",
- "aaaaa",
- "bbaaaaa",
- "bbabbabbabbabbabb",
- 6 },
- { "b*",
- "bb",
- "aa\naa\n",
- "bbaa\naa\n",
- "bbabbabb\nbbabbabb\nbb",
- 7 },
- { "b*",
- "bb",
- "aa\raa\r",
- "bbaa\raa\r",
- "bbabbabb\rbbabbabb\rbb",
- 7 },
- { "b*",
- "bb",
- "aa\r\naa\r\n",
- "bbaa\r\naa\r\n",
- "bbabbabb\r\nbbabbabb\r\nbb",
- 7 },
-#ifdef SUPPORT_UTF8
- { "b*",
- "bb",
- "\xE3\x83\x9B\xE3\x83\xBC\xE3\x83\xA0\xE3\x81\xB8", // utf8
- "bb\xE3\x83\x9B\xE3\x83\xBC\xE3\x83\xA0\xE3\x81\xB8",
- "bb\xE3\x83\x9B""bb""\xE3\x83\xBC""bb""\xE3\x83\xA0""bb""\xE3\x81\xB8""bb",
- 5 },
- { "b*",
- "bb",
- "\xE3\x83\x9B\r\n\xE3\x83\xBC\r\xE3\x83\xA0\n\xE3\x81\xB8\r\n", // utf8
- "bb\xE3\x83\x9B\r\n\xE3\x83\xBC\r\xE3\x83\xA0\n\xE3\x81\xB8\r\n",
- ("bb\xE3\x83\x9B""bb\r\nbb""\xE3\x83\xBC""bb\rbb""\xE3\x83\xA0"
- "bb\nbb""\xE3\x81\xB8""bb\r\nbb"),
- 9 },
-#endif
- { "", NULL, NULL, NULL, NULL, 0 }
- };
-
-#ifdef SUPPORT_UTF8
- const bool support_utf8 = true;
-#else
- const bool support_utf8 = false;
-#endif
-
- for (const ReplaceTest *t = tests; t->original != NULL; ++t) {
- RE re(t->regexp, RE_Options(PCRE_NEWLINE_CRLF).set_utf8(support_utf8));
- assert(re.error().empty());
- string one(t->original);
- CHECK(re.Replace(t->rewrite, &one));
- CHECK_EQ(one, t->single);
- string all(t->original);
- const int replace_count = re.GlobalReplace(t->rewrite, &all);
- CHECK_EQ(all, t->global);
- CHECK_EQ(replace_count, t->global_count);
- }
-
- // One final test: test \r\n replacement when we're not in CRLF mode
- {
- RE re("b*", RE_Options(PCRE_NEWLINE_CR).set_utf8(support_utf8));
- assert(re.error().empty());
- string all("aa\r\naa\r\n");
- CHECK_EQ(re.GlobalReplace("bb", &all), 9);
- CHECK_EQ(all, string("bbabbabb\rbb\nbbabbabb\rbb\nbb"));
- }
- {
- RE re("b*", RE_Options(PCRE_NEWLINE_LF).set_utf8(support_utf8));
- assert(re.error().empty());
- string all("aa\r\naa\r\n");
- CHECK_EQ(re.GlobalReplace("bb", &all), 9);
- CHECK_EQ(all, string("bbabbabb\rbb\nbbabbabb\rbb\nbb"));
- }
- // TODO: test what happens when no PCRE_NEWLINE_* flag is set.
- // Alas, the answer depends on how pcre was compiled.
-}
-
-static void TestExtract() {
- printf("Testing Extract\n");
-
- string s;
-
- CHECK(RE("(.*)@([^.]*)").Extract("\\2!\\1", "boris@kremvax.ru", &s));
- CHECK_EQ(s, "kremvax!boris");
-
- // check the RE interface as well
- CHECK(RE(".*").Extract("'\\0'", "foo", &s));
- CHECK_EQ(s, "'foo'");
- CHECK(!RE("bar").Extract("'\\0'", "baz", &s));
- CHECK_EQ(s, "'foo'");
-}
-
-static void TestConsume() {
- printf("Testing Consume\n");
-
- string word;
-
- string s(" aaa b!@#$@#$cccc");
- StringPiece input(s);
-
- RE r("\\s*(\\w+)"); // matches a word, possibly proceeded by whitespace
- CHECK(r.Consume(&input, &word));
- CHECK_EQ(word, "aaa");
- CHECK(r.Consume(&input, &word));
- CHECK_EQ(word, "b");
- CHECK(! r.Consume(&input, &word));
-}
-
-static void TestFindAndConsume() {
- printf("Testing FindAndConsume\n");
-
- string word;
-
- string s(" aaa b!@#$@#$cccc");
- StringPiece input(s);
-
- RE r("(\\w+)"); // matches a word
- CHECK(r.FindAndConsume(&input, &word));
- CHECK_EQ(word, "aaa");
- CHECK(r.FindAndConsume(&input, &word));
- CHECK_EQ(word, "b");
- CHECK(r.FindAndConsume(&input, &word));
- CHECK_EQ(word, "cccc");
- CHECK(! r.FindAndConsume(&input, &word));
-}
-
-static void TestMatchNumberPeculiarity() {
- printf("Testing match-number peculiaraity\n");
-
- string word1;
- string word2;
- string word3;
-
- RE r("(foo)|(bar)|(baz)");
- CHECK(r.PartialMatch("foo", &word1, &word2, &word3));
- CHECK_EQ(word1, "foo");
- CHECK_EQ(word2, "");
- CHECK_EQ(word3, "");
- CHECK(r.PartialMatch("bar", &word1, &word2, &word3));
- CHECK_EQ(word1, "");
- CHECK_EQ(word2, "bar");
- CHECK_EQ(word3, "");
- CHECK(r.PartialMatch("baz", &word1, &word2, &word3));
- CHECK_EQ(word1, "");
- CHECK_EQ(word2, "");
- CHECK_EQ(word3, "baz");
- CHECK(!r.PartialMatch("f", &word1, &word2, &word3));
-
- string a;
- CHECK(RE("(foo)|hello").FullMatch("hello", &a));
- CHECK_EQ(a, "");
-}
-
-static void TestRecursion() {
- printf("Testing recursion\n");
-
- // Get one string that passes (sometimes), one that never does.
- string text_good("abcdefghijk");
- string text_bad("acdefghijkl");
-
- // According to pcretest, matching text_good against (\w+)*b
- // requires match_limit of at least 8192, and match_recursion_limit
- // of at least 37.
-
- RE_Options options_ml;
- options_ml.set_match_limit(8192);
- RE re("(\\w+)*b", options_ml);
- CHECK(re.PartialMatch(text_good) == true);
- CHECK(re.PartialMatch(text_bad) == false);
- CHECK(re.FullMatch(text_good) == false);
- CHECK(re.FullMatch(text_bad) == false);
-
- options_ml.set_match_limit(1024);
- RE re2("(\\w+)*b", options_ml);
- CHECK(re2.PartialMatch(text_good) == false); // because of match_limit
- CHECK(re2.PartialMatch(text_bad) == false);
- CHECK(re2.FullMatch(text_good) == false);
- CHECK(re2.FullMatch(text_bad) == false);
-
- RE_Options options_mlr;
- options_mlr.set_match_limit_recursion(50);
- RE re3("(\\w+)*b", options_mlr);
- CHECK(re3.PartialMatch(text_good) == true);
- CHECK(re3.PartialMatch(text_bad) == false);
- CHECK(re3.FullMatch(text_good) == false);
- CHECK(re3.FullMatch(text_bad) == false);
-
- options_mlr.set_match_limit_recursion(10);
- RE re4("(\\w+)*b", options_mlr);
- CHECK(re4.PartialMatch(text_good) == false);
- CHECK(re4.PartialMatch(text_bad) == false);
- CHECK(re4.FullMatch(text_good) == false);
- CHECK(re4.FullMatch(text_bad) == false);
-}
-
-// A meta-quoted string, interpreted as a pattern, should always match
-// the original unquoted string.
-static void TestQuoteMeta(string unquoted, RE_Options options = RE_Options()) {
- string quoted = RE::QuoteMeta(unquoted);
- RE re(quoted, options);
- CHECK(re.FullMatch(unquoted));
-}
-
-// A string containing meaningful regexp characters, which is then meta-
-// quoted, should not generally match a string the unquoted string does.
-static void NegativeTestQuoteMeta(string unquoted, string should_not_match,
- RE_Options options = RE_Options()) {
- string quoted = RE::QuoteMeta(unquoted);
- RE re(quoted, options);
- CHECK(!re.FullMatch(should_not_match));
-}
-
-// Tests that quoted meta characters match their original strings,
-// and that a few things that shouldn't match indeed do not.
-static void TestQuotaMetaSimple() {
- TestQuoteMeta("foo");
- TestQuoteMeta("foo.bar");
- TestQuoteMeta("foo\\.bar");
- TestQuoteMeta("[1-9]");
- TestQuoteMeta("1.5-2.0?");
- TestQuoteMeta("\\d");
- TestQuoteMeta("Who doesn't like ice cream?");
- TestQuoteMeta("((a|b)c?d*e+[f-h]i)");
- TestQuoteMeta("((?!)xxx).*yyy");
- TestQuoteMeta("([");
- TestQuoteMeta(string("foo\0bar", 7));
-}
-
-static void TestQuoteMetaSimpleNegative() {
- NegativeTestQuoteMeta("foo", "bar");
- NegativeTestQuoteMeta("...", "bar");
- NegativeTestQuoteMeta("\\.", ".");
- NegativeTestQuoteMeta("\\.", "..");
- NegativeTestQuoteMeta("(a)", "a");
- NegativeTestQuoteMeta("(a|b)", "a");
- NegativeTestQuoteMeta("(a|b)", "(a)");
- NegativeTestQuoteMeta("(a|b)", "a|b");
- NegativeTestQuoteMeta("[0-9]", "0");
- NegativeTestQuoteMeta("[0-9]", "0-9");
- NegativeTestQuoteMeta("[0-9]", "[9]");
- NegativeTestQuoteMeta("((?!)xxx)", "xxx");
-}
-
-static void TestQuoteMetaLatin1() {
- TestQuoteMeta("3\xb2 = 9");
-}
-
-static void TestQuoteMetaUtf8() {
-#ifdef SUPPORT_UTF8
- TestQuoteMeta("Pl\xc3\xa1\x63ido Domingo", pcrecpp::UTF8());
- TestQuoteMeta("xyz", pcrecpp::UTF8()); // No fancy utf8
- TestQuoteMeta("\xc2\xb0", pcrecpp::UTF8()); // 2-byte utf8 (degree symbol)
- TestQuoteMeta("27\xc2\xb0 degrees", pcrecpp::UTF8()); // As a middle character
- TestQuoteMeta("\xe2\x80\xb3", pcrecpp::UTF8()); // 3-byte utf8 (double prime)
- TestQuoteMeta("\xf0\x9d\x85\x9f", pcrecpp::UTF8()); // 4-byte utf8 (music note)
- TestQuoteMeta("27\xc2\xb0"); // Interpreted as Latin-1, but should still work
- NegativeTestQuoteMeta("27\xc2\xb0", // 2-byte utf (degree symbol)
- "27\\\xc2\\\xb0",
- pcrecpp::UTF8());
-#endif
-}
-
-static void TestQuoteMetaAll() {
- printf("Testing QuoteMeta\n");
- TestQuotaMetaSimple();
- TestQuoteMetaSimpleNegative();
- TestQuoteMetaLatin1();
- TestQuoteMetaUtf8();
-}
-
-//
-// Options tests contributed by
-// Giuseppe Maxia, CTO, Stardata s.r.l.
-// July 2005
-//
-static void GetOneOptionResult(
- const char *option_name,
- const char *regex,
- const char *str,
- RE_Options options,
- bool full,
- string expected) {
-
- printf("Testing Option <%s>\n", option_name);
- if(VERBOSE_TEST)
- printf("/%s/ finds \"%s\" within \"%s\" \n",
- regex,
- expected.c_str(),
- str);
- string captured("");
- if (full)
- RE(regex,options).FullMatch(str, &captured);
- else
- RE(regex,options).PartialMatch(str, &captured);
- CHECK_EQ(captured, expected);
-}
-
-static void TestOneOption(
- const char *option_name,
- const char *regex,
- const char *str,
- RE_Options options,
- bool full,
- bool assertive = true) {
-
- printf("Testing Option <%s>\n", option_name);
- if (VERBOSE_TEST)
- printf("'%s' %s /%s/ \n",
- str,
- (assertive? "matches" : "doesn't match"),
- regex);
- if (assertive) {
- if (full)
- CHECK(RE(regex,options).FullMatch(str));
- else
- CHECK(RE(regex,options).PartialMatch(str));
- } else {
- if (full)
- CHECK(!RE(regex,options).FullMatch(str));
- else
- CHECK(!RE(regex,options).PartialMatch(str));
- }
-}
-
-static void Test_CASELESS() {
- RE_Options options;
- RE_Options options2;
-
- options.set_caseless(true);
- TestOneOption("CASELESS (class)", "HELLO", "hello", options, false);
- TestOneOption("CASELESS (class2)", "HELLO", "hello", options2.set_caseless(true), false);
- TestOneOption("CASELESS (class)", "^[A-Z]+$", "Hello", options, false);
-
- TestOneOption("CASELESS (function)", "HELLO", "hello", pcrecpp::CASELESS(), false);
- TestOneOption("CASELESS (function)", "^[A-Z]+$", "Hello", pcrecpp::CASELESS(), false);
- options.set_caseless(false);
- TestOneOption("no CASELESS", "HELLO", "hello", options, false, false);
-}
-
-static void Test_MULTILINE() {
- RE_Options options;
- RE_Options options2;
- const char *str = "HELLO\n" "cruel\n" "world\n";
-
- options.set_multiline(true);
- TestOneOption("MULTILINE (class)", "^cruel$", str, options, false);
- TestOneOption("MULTILINE (class2)", "^cruel$", str, options2.set_multiline(true), false);
- TestOneOption("MULTILINE (function)", "^cruel$", str, pcrecpp::MULTILINE(), false);
- options.set_multiline(false);
- TestOneOption("no MULTILINE", "^cruel$", str, options, false, false);
-}
-
-static void Test_DOTALL() {
- RE_Options options;
- RE_Options options2;
- const char *str = "HELLO\n" "cruel\n" "world";
-
- options.set_dotall(true);
- TestOneOption("DOTALL (class)", "HELLO.*world", str, options, true);
- TestOneOption("DOTALL (class2)", "HELLO.*world", str, options2.set_dotall(true), true);
- TestOneOption("DOTALL (function)", "HELLO.*world", str, pcrecpp::DOTALL(), true);
- options.set_dotall(false);
- TestOneOption("no DOTALL", "HELLO.*world", str, options, true, false);
-}
-
-static void Test_DOLLAR_ENDONLY() {
- RE_Options options;
- RE_Options options2;
- const char *str = "HELLO world\n";
-
- TestOneOption("no DOLLAR_ENDONLY", "world$", str, options, false);
- options.set_dollar_endonly(true);
- TestOneOption("DOLLAR_ENDONLY 1", "world$", str, options, false, false);
- TestOneOption("DOLLAR_ENDONLY 2", "world$", str, options2.set_dollar_endonly(true), false, false);
-}
-
-static void Test_EXTRA() {
- RE_Options options;
- const char *str = "HELLO";
-
- options.set_extra(true);
- TestOneOption("EXTRA 1", "\\HELL\\O", str, options, true, false );
- TestOneOption("EXTRA 2", "\\HELL\\O", str, RE_Options().set_extra(true), true, false );
- options.set_extra(false);
- TestOneOption("no EXTRA", "\\HELL\\O", str, options, true );
-}
-
-static void Test_EXTENDED() {
- RE_Options options;
- RE_Options options2;
- const char *str = "HELLO world";
-
- options.set_extended(true);
- TestOneOption("EXTENDED (class)", "HELLO world", str, options, false, false);
- TestOneOption("EXTENDED (class2)", "HELLO world", str, options2.set_extended(true), false, false);
- TestOneOption("EXTENDED (class)",
- "^ HE L{2} O "
- "\\s+ "
- "\\w+ $ ",
- str,
- options,
- false);
-
- TestOneOption("EXTENDED (function)", "HELLO world", str, pcrecpp::EXTENDED(), false, false);
- TestOneOption("EXTENDED (function)",
- "^ HE L{2} O "
- "\\s+ "
- "\\w+ $ ",
- str,
- pcrecpp::EXTENDED(),
- false);
-
- options.set_extended(false);
- TestOneOption("no EXTENDED", "HELLO world", str, options, false);
-}
-
-static void Test_NO_AUTO_CAPTURE() {
- RE_Options options;
- const char *str = "HELLO world";
- string captured;
-
- printf("Testing Option <no NO_AUTO_CAPTURE>\n");
- if (VERBOSE_TEST)
- printf("parentheses capture text\n");
- RE re("(world|universe)$", options);
- CHECK(re.Extract("\\1", str , &captured));
- CHECK_EQ(captured, "world");
- options.set_no_auto_capture(true);
- printf("testing Option <NO_AUTO_CAPTURE>\n");
- if (VERBOSE_TEST)
- printf("parentheses do not capture text\n");
- re.Extract("\\1",str, &captured );
- CHECK_EQ(captured, "world");
-}
-
-static void Test_UNGREEDY() {
- RE_Options options;
- const char *str = "HELLO, 'this' is the 'world'";
-
- options.set_ungreedy(true);
- GetOneOptionResult("UNGREEDY 1", "('.*')", str, options, false, "'this'" );
- GetOneOptionResult("UNGREEDY 2", "('.*')", str, RE_Options().set_ungreedy(true), false, "'this'" );
- GetOneOptionResult("UNGREEDY", "('.*?')", str, options, false, "'this' is the 'world'" );
-
- options.set_ungreedy(false);
- GetOneOptionResult("no UNGREEDY", "('.*')", str, options, false, "'this' is the 'world'" );
- GetOneOptionResult("no UNGREEDY", "('.*?')", str, options, false, "'this'" );
-}
-
-static void Test_all_options() {
- const char *str = "HELLO\n" "cruel\n" "world";
- RE_Options options;
- options.set_all_options(PCRE_CASELESS | PCRE_DOTALL);
-
- TestOneOption("all_options (CASELESS|DOTALL)", "^hello.*WORLD", str , options, false);
- options.set_all_options(0);
- TestOneOption("all_options (0)", "^hello.*WORLD", str , options, false, false);
- options.set_all_options(PCRE_MULTILINE | PCRE_EXTENDED);
-
- TestOneOption("all_options (MULTILINE|EXTENDED)", " ^ c r u e l $ ", str, options, false);
- TestOneOption("all_options (MULTILINE|EXTENDED) with constructor",
- " ^ c r u e l $ ",
- str,
- RE_Options(PCRE_MULTILINE | PCRE_EXTENDED),
- false);
-
- TestOneOption("all_options (MULTILINE|EXTENDED) with concatenation",
- " ^ c r u e l $ ",
- str,
- RE_Options()
- .set_multiline(true)
- .set_extended(true),
- false);
-
- options.set_all_options(0);
- TestOneOption("all_options (0)", "^ c r u e l $", str, options, false, false);
-
-}
-
-static void TestOptions() {
- printf("Testing Options\n");
- Test_CASELESS();
- Test_MULTILINE();
- Test_DOTALL();
- Test_DOLLAR_ENDONLY();
- Test_EXTENDED();
- Test_NO_AUTO_CAPTURE();
- Test_UNGREEDY();
- Test_EXTRA();
- Test_all_options();
-}
-
-static void TestConstructors() {
- printf("Testing constructors\n");
-
- RE_Options options;
- options.set_dotall(true);
- const char *str = "HELLO\n" "cruel\n" "world";
-
- RE orig("HELLO.*world", options);
- CHECK(orig.FullMatch(str));
-
- RE copy1(orig);
- CHECK(copy1.FullMatch(str));
-
- RE copy2("not a match");
- CHECK(!copy2.FullMatch(str));
- copy2 = copy1;
- CHECK(copy2.FullMatch(str));
- copy2 = orig;
- CHECK(copy2.FullMatch(str));
-
- // Make sure when we assign to ourselves, nothing bad happens
- orig = orig;
- copy1 = copy1;
- copy2 = copy2;
- CHECK(orig.FullMatch(str));
- CHECK(copy1.FullMatch(str));
- CHECK(copy2.FullMatch(str));
-}
-
-int main(int argc, char** argv) {
- // Treat any flag as --help
- if (argc > 1 && argv[1][0] == '-') {
- printf("Usage: %s [timing1|timing2|timing3 num-iters]\n"
- " If 'timingX ###' is specified, run the given timing test\n"
- " with the given number of iterations, rather than running\n"
- " the default corectness test.\n", argv[0]);
- return 0;
- }
-
- if (argc > 1) {
- if ( argc == 2 || atoi(argv[2]) == 0) {
- printf("timing mode needs a num-iters argument\n");
- return 1;
- }
- if (!strcmp(argv[1], "timing1"))
- Timing1(atoi(argv[2]));
- else if (!strcmp(argv[1], "timing2"))
- Timing2(atoi(argv[2]));
- else if (!strcmp(argv[1], "timing3"))
- Timing3(atoi(argv[2]));
- else
- printf("Unknown argument '%s'\n", argv[1]);
- return 0;
- }
-
- printf("Testing FullMatch\n");
-
- int i;
- string s;
-
- /***** FullMatch with no args *****/
-
- CHECK(RE("h.*o").FullMatch("hello"));
- CHECK(!RE("h.*o").FullMatch("othello")); // Must be anchored at front
- CHECK(!RE("h.*o").FullMatch("hello!")); // Must be anchored at end
- CHECK(RE("a*").FullMatch("aaaa")); // Fullmatch with normal op
- CHECK(RE("a*?").FullMatch("aaaa")); // Fullmatch with nongreedy op
- CHECK(RE("a*?\\z").FullMatch("aaaa")); // Two unusual ops
-
- /***** FullMatch with args *****/
-
- // Zero-arg
- CHECK(RE("\\d+").FullMatch("1001"));
-
- // Single-arg
- CHECK(RE("(\\d+)").FullMatch("1001", &i));
- CHECK_EQ(i, 1001);
- CHECK(RE("(-?\\d+)").FullMatch("-123", &i));
- CHECK_EQ(i, -123);
- CHECK(!RE("()\\d+").FullMatch("10", &i));
- CHECK(!RE("(\\d+)").FullMatch("1234567890123456789012345678901234567890",
- &i));
-
- // Digits surrounding integer-arg
- CHECK(RE("1(\\d*)4").FullMatch("1234", &i));
- CHECK_EQ(i, 23);
- CHECK(RE("(\\d)\\d+").FullMatch("1234", &i));
- CHECK_EQ(i, 1);
- CHECK(RE("(-\\d)\\d+").FullMatch("-1234", &i));
- CHECK_EQ(i, -1);
- CHECK(RE("(\\d)").PartialMatch("1234", &i));
- CHECK_EQ(i, 1);
- CHECK(RE("(-\\d)").PartialMatch("-1234", &i));
- CHECK_EQ(i, -1);
-
- // String-arg
- CHECK(RE("h(.*)o").FullMatch("hello", &s));
- CHECK_EQ(s, string("ell"));
-
- // StringPiece-arg
- StringPiece sp;
- CHECK(RE("(\\w+):(\\d+)").FullMatch("ruby:1234", &sp, &i));
- CHECK_EQ(sp.size(), 4);
- CHECK(memcmp(sp.data(), "ruby", 4) == 0);
- CHECK_EQ(i, 1234);
-
- // Multi-arg
- CHECK(RE("(\\w+):(\\d+)").FullMatch("ruby:1234", &s, &i));
- CHECK_EQ(s, string("ruby"));
- CHECK_EQ(i, 1234);
-
- // Ignore non-void* NULL arg
- CHECK(RE("he(.*)lo").FullMatch("hello", (char*)NULL));
- CHECK(RE("h(.*)o").FullMatch("hello", (string*)NULL));
- CHECK(RE("h(.*)o").FullMatch("hello", (StringPiece*)NULL));
- CHECK(RE("(.*)").FullMatch("1234", (int*)NULL));
-#ifdef HAVE_LONG_LONG
- CHECK(RE("(.*)").FullMatch("1234567890123456", (long long*)NULL));
-#endif
- CHECK(RE("(.*)").FullMatch("123.4567890123456", (double*)NULL));
- CHECK(RE("(.*)").FullMatch("123.4567890123456", (float*)NULL));
-
- // Fail on non-void* NULL arg if the match doesn't parse for the given type.
- CHECK(!RE("h(.*)lo").FullMatch("hello", &s, (char*)NULL));
- CHECK(!RE("(.*)").FullMatch("hello", (int*)NULL));
- CHECK(!RE("(.*)").FullMatch("1234567890123456", (int*)NULL));
- CHECK(!RE("(.*)").FullMatch("hello", (double*)NULL));
- CHECK(!RE("(.*)").FullMatch("hello", (float*)NULL));
-
- // Ignored arg
- CHECK(RE("(\\w+)(:)(\\d+)").FullMatch("ruby:1234", &s, (void*)NULL, &i));
- CHECK_EQ(s, string("ruby"));
- CHECK_EQ(i, 1234);
-
- // Type tests
- {
- char c;
- CHECK(RE("(H)ello").FullMatch("Hello", &c));
- CHECK_EQ(c, 'H');
- }
- {
- unsigned char c;
- CHECK(RE("(H)ello").FullMatch("Hello", &c));
- CHECK_EQ(c, static_cast<unsigned char>('H'));
- }
- {
- short v;
- CHECK(RE("(-?\\d+)").FullMatch("100", &v)); CHECK_EQ(v, 100);
- CHECK(RE("(-?\\d+)").FullMatch("-100", &v)); CHECK_EQ(v, -100);
- CHECK(RE("(-?\\d+)").FullMatch("32767", &v)); CHECK_EQ(v, 32767);
- CHECK(RE("(-?\\d+)").FullMatch("-32768", &v)); CHECK_EQ(v, -32768);
- CHECK(!RE("(-?\\d+)").FullMatch("-32769", &v));
- CHECK(!RE("(-?\\d+)").FullMatch("32768", &v));
- }
- {
- unsigned short v;
- CHECK(RE("(\\d+)").FullMatch("100", &v)); CHECK_EQ(v, 100);
- CHECK(RE("(\\d+)").FullMatch("32767", &v)); CHECK_EQ(v, 32767);
- CHECK(RE("(\\d+)").FullMatch("65535", &v)); CHECK_EQ(v, 65535);
- CHECK(!RE("(\\d+)").FullMatch("65536", &v));
- }
- {
- int v;
- static const int max_value = 0x7fffffff;
- static const int min_value = -max_value - 1;
- CHECK(RE("(-?\\d+)").FullMatch("100", &v)); CHECK_EQ(v, 100);
- CHECK(RE("(-?\\d+)").FullMatch("-100", &v)); CHECK_EQ(v, -100);
- CHECK(RE("(-?\\d+)").FullMatch("2147483647", &v)); CHECK_EQ(v, max_value);
- CHECK(RE("(-?\\d+)").FullMatch("-2147483648", &v)); CHECK_EQ(v, min_value);
- CHECK(!RE("(-?\\d+)").FullMatch("-2147483649", &v));
- CHECK(!RE("(-?\\d+)").FullMatch("2147483648", &v));
- }
- {
- unsigned int v;
- static const unsigned int max_value = 0xfffffffful;
- CHECK(RE("(\\d+)").FullMatch("100", &v)); CHECK_EQ(v, 100);
- CHECK(RE("(\\d+)").FullMatch("4294967295", &v)); CHECK_EQ(v, max_value);
- CHECK(!RE("(\\d+)").FullMatch("4294967296", &v));
- }
-#ifdef HAVE_LONG_LONG
-# if defined(__MINGW__) || defined(__MINGW32__)
-# define LLD "%I64d"
-# define LLU "%I64u"
-# else
-# define LLD "%lld"
-# define LLU "%llu"
-# endif
- {
- long long v;
- static const long long max_value = 0x7fffffffffffffffLL;
- static const long long min_value = -max_value - 1;
- char buf[32]; // definitely big enough for a long long
-
- CHECK(RE("(-?\\d+)").FullMatch("100", &v)); CHECK_EQ(v, 100);
- CHECK(RE("(-?\\d+)").FullMatch("-100",&v)); CHECK_EQ(v, -100);
-
- sprintf(buf, LLD, max_value);
- CHECK(RE("(-?\\d+)").FullMatch(buf,&v)); CHECK_EQ(v, max_value);
-
- sprintf(buf, LLD, min_value);
- CHECK(RE("(-?\\d+)").FullMatch(buf,&v)); CHECK_EQ(v, min_value);
-
- sprintf(buf, LLD, max_value);
- assert(buf[strlen(buf)-1] != '9');
- buf[strlen(buf)-1]++;
- CHECK(!RE("(-?\\d+)").FullMatch(buf, &v));
-
- sprintf(buf, LLD, min_value);
- assert(buf[strlen(buf)-1] != '9');
- buf[strlen(buf)-1]++;
- CHECK(!RE("(-?\\d+)").FullMatch(buf, &v));
- }
-#endif
-#if defined HAVE_UNSIGNED_LONG_LONG && defined HAVE_LONG_LONG
- {
- unsigned long long v;
- long long v2;
- static const unsigned long long max_value = 0xffffffffffffffffULL;
- char buf[32]; // definitely big enough for a unsigned long long
-
- CHECK(RE("(-?\\d+)").FullMatch("100",&v)); CHECK_EQ(v, 100);
- CHECK(RE("(-?\\d+)").FullMatch("-100",&v2)); CHECK_EQ(v2, -100);
-
- sprintf(buf, LLU, max_value);
- CHECK(RE("(-?\\d+)").FullMatch(buf,&v)); CHECK_EQ(v, max_value);
-
- assert(buf[strlen(buf)-1] != '9');
- buf[strlen(buf)-1]++;
- CHECK(!RE("(-?\\d+)").FullMatch(buf, &v));
- }
-#endif
- {
- float v;
- CHECK(RE("(.*)").FullMatch("100", &v));
- CHECK(RE("(.*)").FullMatch("-100.", &v));
- CHECK(RE("(.*)").FullMatch("1e23", &v));
- }
- {
- double v;
- CHECK(RE("(.*)").FullMatch("100", &v));
- CHECK(RE("(.*)").FullMatch("-100.", &v));
- CHECK(RE("(.*)").FullMatch("1e23", &v));
- }
-
- // Check that matching is fully anchored
- CHECK(!RE("(\\d+)").FullMatch("x1001", &i));
- CHECK(!RE("(\\d+)").FullMatch("1001x", &i));
- CHECK(RE("x(\\d+)").FullMatch("x1001", &i)); CHECK_EQ(i, 1001);
- CHECK(RE("(\\d+)x").FullMatch("1001x", &i)); CHECK_EQ(i, 1001);
-
- // Braces
- CHECK(RE("[0-9a-f+.-]{5,}").FullMatch("0abcd"));
- CHECK(RE("[0-9a-f+.-]{5,}").FullMatch("0abcde"));
- CHECK(!RE("[0-9a-f+.-]{5,}").FullMatch("0abc"));
-
- // Complicated RE
- CHECK(RE("foo|bar|[A-Z]").FullMatch("foo"));
- CHECK(RE("foo|bar|[A-Z]").FullMatch("bar"));
- CHECK(RE("foo|bar|[A-Z]").FullMatch("X"));
- CHECK(!RE("foo|bar|[A-Z]").FullMatch("XY"));
-
- // Check full-match handling (needs '$' tacked on internally)
- CHECK(RE("fo|foo").FullMatch("fo"));
- CHECK(RE("fo|foo").FullMatch("foo"));
- CHECK(RE("fo|foo$").FullMatch("fo"));
- CHECK(RE("fo|foo$").FullMatch("foo"));
- CHECK(RE("foo$").FullMatch("foo"));
- CHECK(!RE("foo\\$").FullMatch("foo$bar"));
- CHECK(!RE("fo|bar").FullMatch("fox"));
-
- // Uncomment the following if we change the handling of '$' to
- // prevent it from matching a trailing newline
- if (false) {
- // Check that we don't get bitten by pcre's special handling of a
- // '\n' at the end of the string matching '$'
- CHECK(!RE("foo$").PartialMatch("foo\n"));
- }
-
- // Number of args
- int a[16];
- CHECK(RE("").FullMatch(""));
-
- memset(a, 0, sizeof(0));
- CHECK(RE("(\\d){1}").FullMatch("1",
- &a[0]));
- CHECK_EQ(a[0], 1);
-
- memset(a, 0, sizeof(0));
- CHECK(RE("(\\d)(\\d)").FullMatch("12",
- &a[0], &a[1]));
- CHECK_EQ(a[0], 1);
- CHECK_EQ(a[1], 2);
-
- memset(a, 0, sizeof(0));
- CHECK(RE("(\\d)(\\d)(\\d)").FullMatch("123",
- &a[0], &a[1], &a[2]));
- CHECK_EQ(a[0], 1);
- CHECK_EQ(a[1], 2);
- CHECK_EQ(a[2], 3);
-
- memset(a, 0, sizeof(0));
- CHECK(RE("(\\d)(\\d)(\\d)(\\d)").FullMatch("1234",
- &a[0], &a[1], &a[2], &a[3]));
- CHECK_EQ(a[0], 1);
- CHECK_EQ(a[1], 2);
- CHECK_EQ(a[2], 3);
- CHECK_EQ(a[3], 4);
-
- memset(a, 0, sizeof(0));
- CHECK(RE("(\\d)(\\d)(\\d)(\\d)(\\d)").FullMatch("12345",
- &a[0], &a[1], &a[2],
- &a[3], &a[4]));
- CHECK_EQ(a[0], 1);
- CHECK_EQ(a[1], 2);
- CHECK_EQ(a[2], 3);
- CHECK_EQ(a[3], 4);
- CHECK_EQ(a[4], 5);
-
- memset(a, 0, sizeof(0));
- CHECK(RE("(\\d)(\\d)(\\d)(\\d)(\\d)(\\d)").FullMatch("123456",
- &a[0], &a[1], &a[2],
- &a[3], &a[4], &a[5]));
- CHECK_EQ(a[0], 1);
- CHECK_EQ(a[1], 2);
- CHECK_EQ(a[2], 3);
- CHECK_EQ(a[3], 4);
- CHECK_EQ(a[4], 5);
- CHECK_EQ(a[5], 6);
-
- memset(a, 0, sizeof(0));
- CHECK(RE("(\\d)(\\d)(\\d)(\\d)(\\d)(\\d)(\\d)").FullMatch("1234567",
- &a[0], &a[1], &a[2], &a[3],
- &a[4], &a[5], &a[6]));
- CHECK_EQ(a[0], 1);
- CHECK_EQ(a[1], 2);
- CHECK_EQ(a[2], 3);
- CHECK_EQ(a[3], 4);
- CHECK_EQ(a[4], 5);
- CHECK_EQ(a[5], 6);
- CHECK_EQ(a[6], 7);
-
- memset(a, 0, sizeof(0));
- CHECK(RE("(\\d)(\\d)(\\d)(\\d)(\\d)(\\d)(\\d)(\\d)"
- "(\\d)(\\d)(\\d)(\\d)(\\d)(\\d)(\\d)(\\d)").FullMatch(
- "1234567890123456",
- &a[0], &a[1], &a[2], &a[3],
- &a[4], &a[5], &a[6], &a[7],
- &a[8], &a[9], &a[10], &a[11],
- &a[12], &a[13], &a[14], &a[15]));
- CHECK_EQ(a[0], 1);
- CHECK_EQ(a[1], 2);
- CHECK_EQ(a[2], 3);
- CHECK_EQ(a[3], 4);
- CHECK_EQ(a[4], 5);
- CHECK_EQ(a[5], 6);
- CHECK_EQ(a[6], 7);
- CHECK_EQ(a[7], 8);
- CHECK_EQ(a[8], 9);
- CHECK_EQ(a[9], 0);
- CHECK_EQ(a[10], 1);
- CHECK_EQ(a[11], 2);
- CHECK_EQ(a[12], 3);
- CHECK_EQ(a[13], 4);
- CHECK_EQ(a[14], 5);
- CHECK_EQ(a[15], 6);
-
- /***** PartialMatch *****/
-
- printf("Testing PartialMatch\n");
-
- CHECK(RE("h.*o").PartialMatch("hello"));
- CHECK(RE("h.*o").PartialMatch("othello"));
- CHECK(RE("h.*o").PartialMatch("hello!"));
- CHECK(RE("((((((((((((((((((((x))))))))))))))))))))").PartialMatch("x"));
-
- /***** other tests *****/
-
- RadixTests();
- TestReplace();
- TestExtract();
- TestConsume();
- TestFindAndConsume();
- TestQuoteMetaAll();
- TestMatchNumberPeculiarity();
-
- // Check the pattern() accessor
- {
- const string kPattern = "http://([^/]+)/.*";
- const RE re(kPattern);
- CHECK_EQ(kPattern, re.pattern());
- }
-
- // Check RE error field.
- {
- RE re("foo");
- CHECK(re.error().empty()); // Must have no error
- }
-
-#ifdef SUPPORT_UTF8
- // Check UTF-8 handling
- {
- printf("Testing UTF-8 handling\n");
-
- // Three Japanese characters (nihongo)
- const unsigned char utf8_string[] = {
- 0xe6, 0x97, 0xa5, // 65e5
- 0xe6, 0x9c, 0xac, // 627c
- 0xe8, 0xaa, 0x9e, // 8a9e
- 0
- };
- const unsigned char utf8_pattern[] = {
- '.',
- 0xe6, 0x9c, 0xac, // 627c
- '.',
- 0
- };
-
- // Both should match in either mode, bytes or UTF-8
- RE re_test1(".........");
- CHECK(re_test1.FullMatch(utf8_string));
- RE re_test2("...", pcrecpp::UTF8());
- CHECK(re_test2.FullMatch(utf8_string));
-
- // Check that '.' matches one byte or UTF-8 character
- // according to the mode.
- string ss;
- RE re_test3("(.)");
- CHECK(re_test3.PartialMatch(utf8_string, &ss));
- CHECK_EQ(ss, string("\xe6"));
- RE re_test4("(.)", pcrecpp::UTF8());
- CHECK(re_test4.PartialMatch(utf8_string, &ss));
- CHECK_EQ(ss, string("\xe6\x97\xa5"));
-
- // Check that string matches itself in either mode
- RE re_test5(utf8_string);
- CHECK(re_test5.FullMatch(utf8_string));
- RE re_test6(utf8_string, pcrecpp::UTF8());
- CHECK(re_test6.FullMatch(utf8_string));
-
- // Check that pattern matches string only in UTF8 mode
- RE re_test7(utf8_pattern);
- CHECK(!re_test7.FullMatch(utf8_string));
- RE re_test8(utf8_pattern, pcrecpp::UTF8());
- CHECK(re_test8.FullMatch(utf8_string));
- }
-
- // Check that ungreedy, UTF8 regular expressions don't match when they
- // oughtn't -- see bug 82246.
- {
- // This code always worked.
- const char* pattern = "\\w+X";
- const string target = "a aX";
- RE match_sentence(pattern);
- RE match_sentence_re(pattern, pcrecpp::UTF8());
-
- CHECK(!match_sentence.FullMatch(target));
- CHECK(!match_sentence_re.FullMatch(target));
- }
-
- {
- const char* pattern = "(?U)\\w+X";
- const string target = "a aX";
- RE match_sentence(pattern);
- RE match_sentence_re(pattern, pcrecpp::UTF8());
-
- CHECK(!match_sentence.FullMatch(target));
- CHECK(!match_sentence_re.FullMatch(target));
- }
-#endif /* def SUPPORT_UTF8 */
-
- printf("Testing error reporting\n");
-
- { RE re("a\\1"); CHECK(!re.error().empty()); }
- {
- RE re("a[x");
- CHECK(!re.error().empty());
- }
- {
- RE re("a[z-a]");
- CHECK(!re.error().empty());
- }
- {
- RE re("a[[:foobar:]]");
- CHECK(!re.error().empty());
- }
- {
- RE re("a(b");
- CHECK(!re.error().empty());
- }
- {
- RE re("a\\");
- CHECK(!re.error().empty());
- }
-
- // Test that recursion is stopped
- TestRecursion();
-
- // Test Options
- if (getenv("VERBOSE_TEST") != NULL)
- VERBOSE_TEST = true;
- TestOptions();
-
- // Test the constructors
- TestConstructors();
-
- // Done
- printf("OK\n");
-
- return 0;
-}
diff --git a/crawl-ref/source/util/pcre/pcrecpparg.h.in b/crawl-ref/source/util/pcre/pcrecpparg.h.in
deleted file mode 100644
index 61bcab5402..0000000000
--- a/crawl-ref/source/util/pcre/pcrecpparg.h.in
+++ /dev/null
@@ -1,174 +0,0 @@
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// Author: Sanjay Ghemawat
-
-#ifndef _PCRECPPARG_H
-#define _PCRECPPARG_H
-
-#include <stdlib.h> // for NULL
-#include <string>
-
-#include <pcre.h>
-
-namespace pcrecpp {
-
-class StringPiece;
-
-// Hex/Octal/Binary?
-
-// Special class for parsing into objects that define a ParseFrom() method
-template <class T>
-class _RE_MatchObject {
- public:
- static inline bool Parse(const char* str, int n, void* dest) {
- if (dest == NULL) return true;
- T* object = reinterpret_cast<T*>(dest);
- return object->ParseFrom(str, n);
- }
-};
-
-class PCRECPP_EXP_DEFN Arg {
- public:
- // Empty constructor so we can declare arrays of Arg
- Arg();
-
- // Constructor specially designed for NULL arguments
- Arg(void*);
-
- typedef bool (*Parser)(const char* str, int n, void* dest);
-
-// Type-specific parsers
-#define PCRE_MAKE_PARSER(type,name) \
- Arg(type* p) : arg_(p), parser_(name) { } \
- Arg(type* p, Parser parser) : arg_(p), parser_(parser) { }
-
-
- PCRE_MAKE_PARSER(char, parse_char);
- PCRE_MAKE_PARSER(unsigned char, parse_uchar);
- PCRE_MAKE_PARSER(short, parse_short);
- PCRE_MAKE_PARSER(unsigned short, parse_ushort);
- PCRE_MAKE_PARSER(int, parse_int);
- PCRE_MAKE_PARSER(unsigned int, parse_uint);
- PCRE_MAKE_PARSER(long, parse_long);
- PCRE_MAKE_PARSER(unsigned long, parse_ulong);
-#if @pcre_have_long_long@
- PCRE_MAKE_PARSER(long long, parse_longlong);
-#endif
-#if @pcre_have_ulong_long@
- PCRE_MAKE_PARSER(unsigned long long, parse_ulonglong);
-#endif
- PCRE_MAKE_PARSER(float, parse_float);
- PCRE_MAKE_PARSER(double, parse_double);
- PCRE_MAKE_PARSER(std::string, parse_string);
- PCRE_MAKE_PARSER(StringPiece, parse_stringpiece);
-
-#undef PCRE_MAKE_PARSER
-
- // Generic constructor
- template <class T> Arg(T*, Parser parser);
- // Generic constructor template
- template <class T> Arg(T* p)
- : arg_(p), parser_(_RE_MatchObject<T>::Parse) {
- }
-
- // Parse the data
- bool Parse(const char* str, int n) const;
-
- private:
- void* arg_;
- Parser parser_;
-
- static bool parse_null (const char* str, int n, void* dest);
- static bool parse_char (const char* str, int n, void* dest);
- static bool parse_uchar (const char* str, int n, void* dest);
- static bool parse_float (const char* str, int n, void* dest);
- static bool parse_double (const char* str, int n, void* dest);
- static bool parse_string (const char* str, int n, void* dest);
- static bool parse_stringpiece (const char* str, int n, void* dest);
-
-#define PCRE_DECLARE_INTEGER_PARSER(name) \
- private: \
- static bool parse_ ## name(const char* str, int n, void* dest); \
- static bool parse_ ## name ## _radix( \
- const char* str, int n, void* dest, int radix); \
- public: \
- static bool parse_ ## name ## _hex(const char* str, int n, void* dest); \
- static bool parse_ ## name ## _octal(const char* str, int n, void* dest); \
- static bool parse_ ## name ## _cradix(const char* str, int n, void* dest)
-
- PCRE_DECLARE_INTEGER_PARSER(short);
- PCRE_DECLARE_INTEGER_PARSER(ushort);
- PCRE_DECLARE_INTEGER_PARSER(int);
- PCRE_DECLARE_INTEGER_PARSER(uint);
- PCRE_DECLARE_INTEGER_PARSER(long);
- PCRE_DECLARE_INTEGER_PARSER(ulong);
- PCRE_DECLARE_INTEGER_PARSER(longlong);
- PCRE_DECLARE_INTEGER_PARSER(ulonglong);
-
-#undef PCRE_DECLARE_INTEGER_PARSER
-};
-
-inline Arg::Arg() : arg_(NULL), parser_(parse_null) { }
-inline Arg::Arg(void* p) : arg_(p), parser_(parse_null) { }
-
-inline bool Arg::Parse(const char* str, int n) const {
- return (*parser_)(str, n, arg_);
-}
-
-// This part of the parser, appropriate only for ints, deals with bases
-#define MAKE_INTEGER_PARSER(type, name) \
- inline Arg Hex(type* ptr) { \
- return Arg(ptr, Arg::parse_ ## name ## _hex); } \
- inline Arg Octal(type* ptr) { \
- return Arg(ptr, Arg::parse_ ## name ## _octal); } \
- inline Arg CRadix(type* ptr) { \
- return Arg(ptr, Arg::parse_ ## name ## _cradix); }
-
-MAKE_INTEGER_PARSER(short, short) /* */
-MAKE_INTEGER_PARSER(unsigned short, ushort) /* */
-MAKE_INTEGER_PARSER(int, int) /* Don't use semicolons */
-MAKE_INTEGER_PARSER(unsigned int, uint) /* after these statement */
-MAKE_INTEGER_PARSER(long, long) /* because they can cause */
-MAKE_INTEGER_PARSER(unsigned long, ulong) /* compiler warnings if */
-#if @pcre_have_long_long@ /* the checking level is */
-MAKE_INTEGER_PARSER(long long, longlong) /* turned up high enough. */
-#endif /* */
-#if @pcre_have_ulong_long@ /* */
-MAKE_INTEGER_PARSER(unsigned long long, ulonglong) /* */
-#endif
-
-#undef PCRE_IS_SET
-#undef PCRE_SET_OR_CLEAR
-#undef MAKE_INTEGER_PARSER
-
-} // namespace pcrecpp
-
-
-#endif /* _PCRECPPARG_H */
diff --git a/crawl-ref/source/util/pcre/pcredemo.c b/crawl-ref/source/util/pcre/pcredemo.c
deleted file mode 100644
index 3647568766..0000000000
--- a/crawl-ref/source/util/pcre/pcredemo.c
+++ /dev/null
@@ -1,334 +0,0 @@
-/*************************************************
-* PCRE DEMONSTRATION PROGRAM *
-*************************************************/
-
-/* This is a demonstration program to illustrate the most straightforward ways
-of calling the PCRE regular expression library from a C program. See the
-pcresample documentation for a short discussion ("man pcresample" if you have
-the PCRE man pages installed).
-
-In Unix-like environments, compile this program thuswise:
-
- gcc -Wall pcredemo.c -I/usr/local/include -L/usr/local/lib \
- -R/usr/local/lib -lpcre
-
-Replace "/usr/local/include" and "/usr/local/lib" with wherever the include and
-library files for PCRE are installed on your system. You don't need -I and -L
-if PCRE is installed in the standard system libraries. Only some operating
-systems (e.g. Solaris) use the -R option.
-
-Building under Windows:
-
-If you want to statically link this program against a non-dll .a file, you must
-define PCRE_STATIC before including pcre.h, otherwise the pcre_malloc() and
-pcre_free() exported functions will be declared __declspec(dllimport), with
-unwanted results. So in this environment, uncomment the following line. */
-
-/* #define PCRE_STATIC */
-
-#include <stdio.h>
-#include <string.h>
-#include <pcre.h>
-
-#define OVECCOUNT 30 /* should be a multiple of 3 */
-
-
-int main(int argc, char **argv)
-{
-pcre *re;
-const char *error;
-char *pattern;
-char *subject;
-unsigned char *name_table;
-int erroffset;
-int find_all;
-int namecount;
-int name_entry_size;
-int ovector[OVECCOUNT];
-int subject_length;
-int rc, i;
-
-
-/**************************************************************************
-* First, sort out the command line. There is only one possible option at *
-* the moment, "-g" to request repeated matching to find all occurrences, *
-* like Perl's /g option. We set the variable find_all to a non-zero value *
-* if the -g option is present. Apart from that, there must be exactly two *
-* arguments. *
-**************************************************************************/
-
-find_all = 0;
-for (i = 1; i < argc; i++)
- {
- if (strcmp(argv[i], "-g") == 0) find_all = 1;
- else break;
- }
-
-/* After the options, we require exactly two arguments, which are the pattern,
-and the subject string. */
-
-if (argc - i != 2)
- {
- printf("Two arguments required: a regex and a subject string\n");
- return 1;
- }
-
-pattern = argv[i];
-subject = argv[i+1];
-subject_length = (int)strlen(subject);
-
-
-/*************************************************************************
-* Now we are going to compile the regular expression pattern, and handle *
-* and errors that are detected. *
-*************************************************************************/
-
-re = pcre_compile(
- pattern, /* the pattern */
- 0, /* default options */
- &error, /* for error message */
- &erroffset, /* for error offset */
- NULL); /* use default character tables */
-
-/* Compilation failed: print the error message and exit */
-
-if (re == NULL)
- {
- printf("PCRE compilation failed at offset %d: %s\n", erroffset, error);
- return 1;
- }
-
-
-/*************************************************************************
-* If the compilation succeeded, we call PCRE again, in order to do a *
-* pattern match against the subject string. This does just ONE match. If *
-* further matching is needed, it will be done below. *
-*************************************************************************/
-
-rc = pcre_exec(
- re, /* the compiled pattern */
- NULL, /* no extra data - we didn't study the pattern */
- subject, /* the subject string */
- subject_length, /* the length of the subject */
- 0, /* start at offset 0 in the subject */
- 0, /* default options */
- ovector, /* output vector for substring information */
- OVECCOUNT); /* number of elements in the output vector */
-
-/* Matching failed: handle error cases */
-
-if (rc < 0)
- {
- switch(rc)
- {
- case PCRE_ERROR_NOMATCH: printf("No match\n"); break;
- /*
- Handle other special cases if you like
- */
- default: printf("Matching error %d\n", rc); break;
- }
- pcre_free(re); /* Release memory used for the compiled pattern */
- return 1;
- }
-
-/* Match succeded */
-
-printf("\nMatch succeeded at offset %d\n", ovector[0]);
-
-
-/*************************************************************************
-* We have found the first match within the subject string. If the output *
-* vector wasn't big enough, say so. Then output any substrings that were *
-* captured. *
-*************************************************************************/
-
-/* The output vector wasn't big enough */
-
-if (rc == 0)
- {
- rc = OVECCOUNT/3;
- printf("ovector only has room for %d captured substrings\n", rc - 1);
- }
-
-/* Show substrings stored in the output vector by number. Obviously, in a real
-application you might want to do things other than print them. */
-
-for (i = 0; i < rc; i++)
- {
- char *substring_start = subject + ovector[2*i];
- int substring_length = ovector[2*i+1] - ovector[2*i];
- printf("%2d: %.*s\n", i, substring_length, substring_start);
- }
-
-
-/**************************************************************************
-* That concludes the basic part of this demonstration program. We have *
-* compiled a pattern, and performed a single match. The code that follows *
-* shows first how to access named substrings, and then how to code for *
-* repeated matches on the same subject. *
-**************************************************************************/
-
-/* See if there are any named substrings, and if so, show them by name. First
-we have to extract the count of named parentheses from the pattern. */
-
-(void)pcre_fullinfo(
- re, /* the compiled pattern */
- NULL, /* no extra data - we didn't study the pattern */
- PCRE_INFO_NAMECOUNT, /* number of named substrings */
- &namecount); /* where to put the answer */
-
-if (namecount <= 0) printf("No named substrings\n"); else
- {
- unsigned char *tabptr;
- printf("Named substrings\n");
-
- /* Before we can access the substrings, we must extract the table for
- translating names to numbers, and the size of each entry in the table. */
-
- (void)pcre_fullinfo(
- re, /* the compiled pattern */
- NULL, /* no extra data - we didn't study the pattern */
- PCRE_INFO_NAMETABLE, /* address of the table */
- &name_table); /* where to put the answer */
-
- (void)pcre_fullinfo(
- re, /* the compiled pattern */
- NULL, /* no extra data - we didn't study the pattern */
- PCRE_INFO_NAMEENTRYSIZE, /* size of each entry in the table */
- &name_entry_size); /* where to put the answer */
-
- /* Now we can scan the table and, for each entry, print the number, the name,
- and the substring itself. */
-
- tabptr = name_table;
- for (i = 0; i < namecount; i++)
- {
- int n = (tabptr[0] << 8) | tabptr[1];
- printf("(%d) %*s: %.*s\n", n, name_entry_size - 3, tabptr + 2,
- ovector[2*n+1] - ovector[2*n], subject + ovector[2*n]);
- tabptr += name_entry_size;
- }
- }
-
-
-/*************************************************************************
-* If the "-g" option was given on the command line, we want to continue *
-* to search for additional matches in the subject string, in a similar *
-* way to the /g option in Perl. This turns out to be trickier than you *
-* might think because of the possibility of matching an empty string. *
-* What happens is as follows: *
-* *
-* If the previous match was NOT for an empty string, we can just start *
-* the next match at the end of the previous one. *
-* *
-* If the previous match WAS for an empty string, we can't do that, as it *
-* would lead to an infinite loop. Instead, a special call of pcre_exec() *
-* is made with the PCRE_NOTEMPTY and PCRE_ANCHORED flags set. The first *
-* of these tells PCRE that an empty string is not a valid match; other *
-* possibilities must be tried. The second flag restricts PCRE to one *
-* match attempt at the initial string position. If this match succeeds, *
-* an alternative to the empty string match has been found, and we can *
-* proceed round the loop. *
-*************************************************************************/
-
-if (!find_all)
- {
- pcre_free(re); /* Release the memory used for the compiled pattern */
- return 0; /* Finish unless -g was given */
- }
-
-/* Loop for second and subsequent matches */
-
-for (;;)
- {
- int options = 0; /* Normally no options */
- int start_offset = ovector[1]; /* Start at end of previous match */
-
- /* If the previous match was for an empty string, we are finished if we are
- at the end of the subject. Otherwise, arrange to run another match at the
- same point to see if a non-empty match can be found. */
-
- if (ovector[0] == ovector[1])
- {
- if (ovector[0] == subject_length) break;
- options = PCRE_NOTEMPTY | PCRE_ANCHORED;
- }
-
- /* Run the next matching operation */
-
- rc = pcre_exec(
- re, /* the compiled pattern */
- NULL, /* no extra data - we didn't study the pattern */
- subject, /* the subject string */
- subject_length, /* the length of the subject */
- start_offset, /* starting offset in the subject */
- options, /* options */
- ovector, /* output vector for substring information */
- OVECCOUNT); /* number of elements in the output vector */
-
- /* This time, a result of NOMATCH isn't an error. If the value in "options"
- is zero, it just means we have found all possible matches, so the loop ends.
- Otherwise, it means we have failed to find a non-empty-string match at a
- point where there was a previous empty-string match. In this case, we do what
- Perl does: advance the matching position by one, and continue. We do this by
- setting the "end of previous match" offset, because that is picked up at the
- top of the loop as the point at which to start again. */
-
- if (rc == PCRE_ERROR_NOMATCH)
- {
- if (options == 0) break;
- ovector[1] = start_offset + 1;
- continue; /* Go round the loop again */
- }
-
- /* Other matching errors are not recoverable. */
-
- if (rc < 0)
- {
- printf("Matching error %d\n", rc);
- pcre_free(re); /* Release memory used for the compiled pattern */
- return 1;
- }
-
- /* Match succeded */
-
- printf("\nMatch succeeded again at offset %d\n", ovector[0]);
-
- /* The match succeeded, but the output vector wasn't big enough. */
-
- if (rc == 0)
- {
- rc = OVECCOUNT/3;
- printf("ovector only has room for %d captured substrings\n", rc - 1);
- }
-
- /* As before, show substrings stored in the output vector by number, and then
- also any named substrings. */
-
- for (i = 0; i < rc; i++)
- {
- char *substring_start = subject + ovector[2*i];
- int substring_length = ovector[2*i+1] - ovector[2*i];
- printf("%2d: %.*s\n", i, substring_length, substring_start);
- }
-
- if (namecount <= 0) printf("No named substrings\n"); else
- {
- unsigned char *tabptr = name_table;
- printf("Named substrings\n");
- for (i = 0; i < namecount; i++)
- {
- int n = (tabptr[0] << 8) | tabptr[1];
- printf("(%d) %*s: %.*s\n", n, name_entry_size - 3, tabptr + 2,
- ovector[2*n+1] - ovector[2*n], subject + ovector[2*n]);
- tabptr += name_entry_size;
- }
- }
- } /* End of loop to find second and subsequent matches */
-
-printf("\n");
-pcre_free(re); /* Release memory used for the compiled pattern */
-return 0;
-}
-
-/* End of pcredemo.c */
diff --git a/crawl-ref/source/util/pcre/pcregexp.pas b/crawl-ref/source/util/pcre/pcregexp.pas
deleted file mode 100644
index 4f4d4449f0..0000000000
--- a/crawl-ref/source/util/pcre/pcregexp.pas
+++ /dev/null
@@ -1,783 +0,0 @@
-{
- pcRegExp - Perl compatible regular expressions for Virtual Pascal
- (c) 2001 Peter S. Voronov aka Chem O'Dun <petervrn@yahoo.com>
-
- Based on PCRE library interface unit for Virtual Pascal.
- (c) 2001 Alexander Tokarev <dwalin@dwalin.ru>
-
- The current PCRE version is: 3.7
-
- This software must be distributed as Freeware.
-
- The PCRE library is written by: Philip Hazel <ph10@cam.ac.uk>
- Copyright (c) 1997-2004 University of Cambridge
-
- AngelsHolocaust 4-11-04 updated to use version v5.0
- (INFO: this is regex-directed, NFA)
- AH: 9-11-04 - pcre_free: removed var, pcre already gives the ptr, now
- everything works as it should (no more crashes)
- -> removed CheckRegExp because pcre handles errors perfectly
- 10-11-04 - added pcError (errorhandling), pcInit
- 13-11-04 - removed the ErrorPos = 0 check -> always print erroroffset
- 17-10-05 - support for \1-\9 backreferences in TpcRegExp.GetReplStr
- 17-02-06 - added RunTimeOptions: caller can set options while searching
- 19-02-06 - added SearchOfs(): let PCRE use the complete string and offset
- into the string itself
- 20-12-06 - support for version 7.0
-}
-
-{$H+} {$DEFINE PCRE_3_7} {$DEFINE PCRE_5_0} {$DEFINE PCRE_7_0}
-
-Unit pcregexp;
-
-Interface
-
-uses objects;
-
-Type
- PpcRegExp = ^TpcRegExp;
-// TpcRegExp = object
- TpcRegExp = object(TObject)
- MatchesCount: integer;
- RegExpC, RegExpExt : Pointer;
- Matches:Pointer;
- RegExp: shortstring;
- SourceLen: integer;
- PartialMatch : boolean;
- Error : boolean;
- ErrorMsg : Pchar;
- ErrorPos : integer;
- RunTimeOptions: Integer; // options which can be set by the caller
- constructor Init(const ARegExp : shortstring; AOptions : integer; ALocale : Pointer);
- function Search(AStr: Pchar; ALen : longint) : boolean; virtual;
- function SearchNext( AStr: Pchar; ALen : longint) : boolean; virtual;
- function SearchOfs ( AStr: Pchar; ALen, AOfs : longint) : boolean; virtual;
- function MatchSub(ANom: integer; var Pos, Len : longint) : boolean; virtual;
- function MatchFull(var Pos, Len : longint) : boolean; virtual;
- function GetSubStr(ANom: integer; AStr: Pchar) : string; virtual;
- function GetFullStr(AStr: Pchar) : string; virtual;
- function GetReplStr(AStr: Pchar; const ARepl: string) : string; virtual;
- function GetPreSubStr(AStr: Pchar) : string; virtual;
- function GetPostSubStr(AStr: Pchar) : string; virtual;
- function ErrorStr : string; virtual;
- destructor Done; virtual;
- end;
-
- function pcGrepMatch(WildCard, aStr: string; AOptions:integer; ALocale : Pointer): Boolean;
- function pcGrepSub(WildCard, aStr, aRepl: string; AOptions:integer; ALocale : Pointer): string;
-
- function pcFastGrepMatch(WildCard, aStr: string): Boolean;
- function pcFastGrepSub(WildCard, aStr, aRepl: string): string;
-
-{$IFDEF PCRE_5_0}
- function pcGetVersion : pchar;
-{$ENDIF}
-
- function pcError (var pRegExp : Pointer) : Boolean;
- function pcInit (const Pattern: Shortstring; CaseSens: Boolean) : Pointer;
-
-Const { Options }
- PCRE_CASELESS = $0001;
- PCRE_MULTILINE = $0002;
- PCRE_DOTALL = $0004;
- PCRE_EXTENDED = $0008;
- PCRE_ANCHORED = $0010;
- PCRE_DOLLAR_ENDONLY = $0020;
- PCRE_EXTRA = $0040;
- PCRE_NOTBOL = $0080;
- PCRE_NOTEOL = $0100;
- PCRE_UNGREEDY = $0200;
- PCRE_NOTEMPTY = $0400;
-{$IFDEF PCRE_5_0}
- PCRE_UTF8 = $0800;
- PCRE_NO_AUTO_CAPTURE = $1000;
- PCRE_NO_UTF8_CHECK = $2000;
- PCRE_AUTO_CALLOUT = $4000;
- PCRE_PARTIAL = $8000;
-{$ENDIF}
-{$IFDEF PCRE_7_0}
- PCRE_DFA_SHORTEST = $00010000;
- PCRE_DFA_RESTART = $00020000;
- PCRE_FIRSTLINE = $00040000;
- PCRE_DUPNAMES = $00080000;
- PCRE_NEWLINE_CR = $00100000;
- PCRE_NEWLINE_LF = $00200000;
- PCRE_NEWLINE_CRLF = $00300000;
- PCRE_NEWLINE_ANY = $00400000;
- PCRE_NEWLINE_ANYCRLF = $00500000;
-{$ENDIF}
-
- PCRE_COMPILE_ALLOWED_OPTIONS = PCRE_ANCHORED + PCRE_AUTO_CALLOUT + PCRE_CASELESS +
- PCRE_DOLLAR_ENDONLY + PCRE_DOTALL + PCRE_EXTENDED +
- PCRE_EXTRA + PCRE_MULTILINE + PCRE_NO_AUTO_CAPTURE +
- PCRE_UNGREEDY + PCRE_UTF8 + PCRE_NO_UTF8_CHECK
- {$IFDEF PCRE_7_0}
- + PCRE_DUPNAMES + PCRE_FIRSTLINE + PCRE_NEWLINE_CRLF
- + PCRE_NEWLINE_ANY + PCRE_NEWLINE_CRLF
- {$ENDIF}
- ;
-
- PCRE_EXEC_ALLOWED_OPTIONS = PCRE_ANCHORED + PCRE_NOTBOL + PCRE_NOTEOL +
- PCRE_NOTEMPTY + PCRE_NO_UTF8_CHECK + PCRE_PARTIAL
- {$IFDEF PCRE_7_0}
- + PCRE_NEWLINE_CRLF + PCRE_NEWLINE_ANY +PCRE_NEWLINE_ANYCRLF
- {$ENDIF}
- ;
-
-{$IFDEF PCRE_7_0}
- PCRE_DFA_EXEC_ALLOWED_OPTIONS = PCRE_ANCHORED + PCRE_NOTBOL + PCRE_NOTEOL +
- PCRE_NOTEMPTY + PCRE_NO_UTF8_CHECK + PCRE_PARTIAL +
- PCRE_DFA_SHORTEST + PCRE_DFA_RESTART +
- PCRE_NEWLINE_CR + PCRE_NEWLINE_LF + PCRE_NEWLINE_CRLF +
- PCRE_NEWLINE_ANY + PCRE_NEWLINE_ANYCRLF
-{$ENDIF}
-
-{ Exec-time and get/set-time error codes }
- PCRE_ERROR_NOMATCH = -1;
- PCRE_ERROR_NULL = -2;
- PCRE_ERROR_BADOPTION = -3;
- PCRE_ERROR_BADMAGIC = -4;
- PCRE_ERROR_UNKNOWN_MODE = -5;
- PCRE_ERROR_NOMEMORY = -6;
- PCRE_ERROR_NOSUBSTRING = -7;
-{$IFDEF PCRE_5_0}
- PCRE_ERROR_MATCHLIMIT = -8;
- PCRE_ERROR_CALLOUT = -9; { Never used by PCRE itself }
- PCRE_ERROR_BADUTF8 = -10;
- PCRE_ERROR_BADUTF8_OFFSET = -11;
- PCRE_ERROR_PARTIAL = -12;
- PCRE_ERROR_BADPARTIAL = -13;
- PCRE_ERROR_INTERNAL = -14;
- PCRE_ERROR_BADCOUNT = -15;
-{$ENDIF}
-{$IFDEF PCRE_7_0}
- PCRE_ERROR_DFA_UITEM = -16;
- PCRE_ERROR_DFA_UCOND = -17;
- PCRE_ERROR_DFA_UMLIMIT = -18;
- PCRE_ERROR_DFA_WSSIZE = -19;
- PCRE_ERROR_DFA_RECURSE = -20;
- PCRE_ERROR_RECURSIONLIMIT = -21;
- PCRE_ERROR_NULLWSLIMIT = -22;
- PCRE_ERROR_BADNEWLINE = -23;
-{$ENDIF}
-
-{ Request types for pcre_fullinfo() }
-
- PCRE_INFO_OPTIONS = 0;
- PCRE_INFO_SIZE = 1;
- PCRE_INFO_CAPTURECOUNT = 2;
- PCRE_INFO_BACKREFMAX = 3;
- PCRE_INFO_FIRSTBYTE = 4;
- PCRE_INFO_FIRSTCHAR = 4; { For backwards compatibility }
- PCRE_INFO_FIRSTTABLE = 5;
-{$IFDEF PCRE_5_0}
- PCRE_INFO_LASTLITERAL = 6;
- PCRE_INFO_NAMEENTRYSIZE = 7;
- PCRE_INFO_NAMECOUNT = 8;
- PCRE_INFO_NAMETABLE = 9;
- PCRE_INFO_STUDYSIZE = 10;
- PCRE_INFO_DEFAULT_TABLES = 11;
-{$ENDIF PCRE_5_0}
-
-{ Request types for pcre_config() }
-{$IFDEF PCRE_5_0}
- PCRE_CONFIG_UTF8 = 0;
- PCRE_CONFIG_NEWLINE = 1;
- PCRE_CONFIG_LINK_SIZE = 2;
- PCRE_CONFIG_POSIX_MALLOC_THRESHOLD = 3;
- PCRE_CONFIG_MATCH_LIMIT = 4;
- PCRE_CONFIG_STACKRECURSE = 5;
- PCRE_CONFIG_UNICODE_PROPERTIES = 6;
-{$ENDIF PCRE_5_0}
-{$IFDEF PCRE_7_0}
- PCRE_CONFIG_MATCH_LIMIT_RECURSION = 7;
-{$ENDIF}
-
-{ Bit flags for the pcre_extra structure }
-{$IFDEF PCRE_5_0}
- PCRE_EXTRA_STUDY_DATA = $0001;
- PCRE_EXTRA_MATCH_LIMIT = $0002;
- PCRE_EXTRA_CALLOUT_DATA = $0004;
- PCRE_EXTRA_TABLES = $0008;
-{$ENDIF PCRE_5_0}
-{$IFDEF PCRE_7_0}
- PCRE_EXTRA_MATCH_LIMIT_RECURSION = $0010;
-{$ENDIF}
-
-Const
-// DefaultOptions : integer = 0;
- DefaultLocaleTable : pointer = nil;
-
-{$IFDEF PCRE_5_0}
-{ The structure for passing additional data to pcre_exec(). This is defined in
-such as way as to be extensible. Always add new fields at the end, in order to
-remain compatible. }
-
-type ppcre_extra = ^tpcre_extra;
- tpcre_extra = record
- flags : longint; { Bits for which fields are set }
- study_data : pointer; { Opaque data from pcre_study() }
- match_limit : longint; { Maximum number of calls to match() }
- callout_data : pointer; { Data passed back in callouts }
- tables : pointer; { Pointer to character tables }
- match_limit_recursion: longint; { Max recursive calls to match() }
- end;
-
-type ppcre_callout_block = ^pcre_callout_block;
- pcre_callout_block = record
- version,
- (* ------------------------ Version 0 ------------------------------- *)
- callout_number : integer;
- offset_vector : pointer;
- subject : pchar;
- subject_length, start_match, current_position, capture_top,
- capture_last : integer;
- callout_data : pointer;
- (* ------------------- Added for Version 1 -------------------------- *)
- pattern_position, next_item_length : integer;
- end;
-{$ENDIF PCRE_5_0}
-
-{$OrgName+}
-{$IFDEF VIRTUALPASCAL} {&Cdecl+} {$ENDIF VIRTUALPASCAL}
-
- { local replacement of external pcre memory management functions }
- function pcre_malloc( size : integer ) : pointer;
- procedure pcre_free( {var} p : pointer );
-{$IFDEF PCRE_5_0}
- const pcre_stack_malloc: function ( size : integer ): pointer = pcre_malloc;
- pcre_stack_free: procedure ( {var} p : pointer ) = pcre_free;
- function pcre_callout(var p : ppcre_callout_block) : integer;
-{$ENDIF PCRE_5_0}
-{$IFDEF VIRTUALPASCAL} {&Cdecl-} {$ENDIF VIRTUALPASCAL}
-
-Implementation
-
-Uses strings, collect, messages, dnapp, commands, advance0, stringsx
- {$IFDEF VIRTUALPASCAL} ,vpsyslow {$ENDIF VIRTUALPASCAL};
-
-Const
- MAGIC_NUMBER = $50435245; { 'PCRE' }
- MAX_MATCHES = 90; { changed in 3.5 version; should be divisible by 3, was 64}
-
-Type
- PMatchArray = ^TMatchArray;
- TMatchArray = array[0..( MAX_MATCHES * 3 )] of integer;
-
- PRegExpCollection = ^TRegExpCollection;
- TRegExpCollection = object(TSortedCollection)
- MaxRegExp : integer;
- SearchRegExp : shortstring;
- CompareModeInsert : boolean;
- constructor Init(AMaxRegExp:integer);
- procedure FreeItem(P: Pointer); virtual;
- function Compare(P1, P2: Pointer): Integer; virtual;
- function Find(ARegExp:shortstring;var P: PpcRegExp):boolean; virtual;
- function CheckNew(ARegExp:shortstring):PpcRegExp;virtual;
- end;
-
-Var
- PRegExpCache : PRegExpCollection;
-
-
-{$IFDEF VIRTUALPASCAL} {&Cdecl+} {$ENDIF VIRTUALPASCAL}
-
- { imported original pcre functions }
-
- function pcre_compile( const pattern : PChar; options : integer;
- var errorptr : PChar; var erroroffset : integer;
- const tables : PChar ) : pointer {pcre}; external;
-{$IFDEF PCRE_7_0}
- function pcre_compile2( const pattern : PChar; options : integer;
- var errorcodeptr : Integer;
- var errorptr : PChar; var erroroffset : integer;
- const tables : PChar ) : pointer {pcre}; external;
-{$ENDIF}
-{$IFDEF PCRE_5_0}
- function pcre_config( what : integer; where : pointer) : integer; external;
- function pcre_copy_named_substring( const code : pointer {pcre};
- const subject : pchar;
- var ovector : integer;
- stringcount : integer;
- const stringname : pchar;
- var buffer : pchar;
- size : integer) : integer; external;
- function pcre_copy_substring( const subject : pchar; var ovector : integer;
- stringcount, stringnumber : integer;
- var buffer : pchar; size : integer )
- : integer; external;
- function pcre_exec( const argument_re : pointer {pcre};
- const extra_data : pointer {pcre_extra};
-{$ELSE}
- function pcre_exec( const external_re : pointer;
- const external_extra : pointer;
-{$ENDIF}
- const subject : PChar;
- length, start_offset, options : integer;
- offsets : pointer;
- offsetcount : integer ) : integer; external;
-{$IFDEF PCRE_7_0}
- function pcre_dfa_exec( const argument_re : pointer {pcre};
- const extra_data : pointer {pcre_extra};
- const subject : pchar;
- length, start_offset, options : integer;
- offsets : pointer;
- offsetcount : integer;
- workspace : pointer;
- wscount : integer ) : integer; external;
-{$ENDIF}
-{$IFDEF PCRE_5_0}
- procedure pcre_free_substring( const p : pchar ); external;
- procedure pcre_free_substring_list( var p : pchar ); external;
- function pcre_fullinfo( const argument_re : pointer {pcre};
- const extra_data : pointer {pcre_extra};
- what : integer;
- where : pointer ) : integer; external;
- function pcre_get_named_substring( const code : pointer {pcre};
- const subject : pchar;
- var ovector : integer;
- stringcount : integer;
- const stringname : pchar;
- var stringptr : pchar ) : integer; external;
- function pcre_get_stringnumber( const code : pointer {pcre};
- const stringname : pchar ) : integer; external;
- function pcre_get_stringtable_entries( const code : pointer {pcre};
- const stringname : pchar;
- var firstptr,
- lastptr : pchar ) : integer; external;
- function pcre_get_substring( const subject : pchar; var ovector : integer;
- stringcount, stringnumber : integer;
- var stringptr : pchar ) : integer; external;
- function pcre_get_substring_list( const subject : pchar; var ovector : integer;
- stringcount : integer;
- listptr : pointer {const char ***listptr}) : integer; external;
- function pcre_info( const argument_re : pointer {pcre};
- var optptr : integer;
- var first_byte : integer ) : integer; external;
- function pcre_maketables : pchar; external;
-{$ENDIF}
-{$IFDEF PCRE_7_0}
- function pcre_refcount( const argument_re : pointer {pcre};
- adjust : integer ) : pchar; external;
-{$ENDIF}
- function pcre_study( const external_re : pointer {pcre};
- options : integer;
- var errorptr : PChar ) : pointer {pcre_extra}; external;
-{$IFDEF PCRE_5_0}
- function pcre_version : pchar; external;
-{$ENDIF}
-
- function pcre_malloc( size : integer ) : pointer;
- begin
- GetMem( result, size );
- end;
-
- procedure pcre_free( {var} p : pointer );
- begin
- if (p <> nil) then
- FreeMem( p, 0 );
- {@p := nil;}
- end;
-
-{$IFDEF PCRE_5_0}
-(* Called from PCRE as a result of the (?C) item. We print out where we are in
-the match. Yield zero unless more callouts than the fail count, or the callout
-data is not zero. *)
-
- function pcre_callout;
- begin
- end;
-{$ENDIF}
-
-{$IFDEF VIRTUALPASCAL} {&Cdecl-} {$ENDIF VIRTUALPASCAL}
-
-// Always include the newest version of the library
-{$IFDEF PCRE_3_7} {$IFNDEF PCRE_5_0} {$IFNDEF PCRE_7_0} {$L pcre37.lib} {$ENDIF PCRE_7_0} {$ENDIF PCRE_5_0} {$ENDIF PCRE_3_7}
-{$IFDEF PCRE_5_0} {$IFNDEF PCRE_7_0} {$L pcre50.lib} {$ENDIF PCRE_7_0} {$ENDIF PCRE_5_0}
-{$IFDEF PCRE_7_0} {$L pcre70.lib} {$ENDIF PCRE_7_0}
-
-{TpcRegExp}
-
- constructor TpcRegExp.Init(const ARegExp:shortstring; AOptions:integer; ALocale : Pointer);
- var
- pRegExp : PChar;
- begin
- RegExp:=ARegExp;
- RegExpC:=nil;
- RegExpExt:=nil;
- Matches:=nil;
- MatchesCount:=0;
- Error:=true;
- ErrorMsg:=nil;
- ErrorPos:=0;
- RunTimeOptions := 0;
- if length(RegExp) < 255 then
- begin
- RegExp[length(RegExp)+1]:=#0;
- pRegExp:=@RegExp[1];
- end
- else
- begin
- GetMem(pRegExp,length(RegExp)+1);
- pRegExp:=strpcopy(pRegExp,RegExp);
- end;
- RegExpC := pcre_compile( pRegExp,
- AOptions and PCRE_COMPILE_ALLOWED_OPTIONS,
- ErrorMsg, ErrorPos, ALocale);
- if length(RegExp) = 255 then
- StrDispose(pRegExp);
- if RegExpC = nil then
- exit;
- ErrorMsg:=nil;
- RegExpExt := pcre_study( RegExpC, 0, ErrorMsg );
- if (RegExpExt = nil) and (ErrorMsg <> nil) then
- begin
- pcre_free(RegExpC);
- exit;
- end;
- GetMem(Matches,SizeOf(TMatchArray));
- Error:=false;
- end;
-
- destructor TpcRegExp.Done;
- begin
- if RegExpC <> nil then
- pcre_free(RegExpC);
- if RegExpExt <> nil then
- pcre_free(RegExpExt);
- if Matches <> nil then
- FreeMem(Matches,SizeOf(TMatchArray));
- end;
-
- function TpcRegExp.SearchNext( AStr: Pchar; ALen : longint ) : boolean;
- var Options: Integer;
- begin // must handle PCRE_ERROR_PARTIAL here
- Options := (RunTimeOptions or startup.MiscMultiData.cfgRegEx.DefaultOptions) and
- PCRE_EXEC_ALLOWED_OPTIONS;
- if MatchesCount > 0 then
- MatchesCount:=pcre_exec( RegExpC, RegExpExt, AStr, ALen, PMatchArray(Matches)^[1],
- Options, Matches, MAX_MATCHES ) else
- MatchesCount:=pcre_exec( RegExpC, RegExpExt, AStr, ALen, 0,
- Options, Matches, MAX_MATCHES );
-{ if MatchesCount = 0 then
- MatchesCount := MatchesCount div 3;}
- PartialMatch := MatchesCount = PCRE_ERROR_PARTIAL;
- SearchNext := MatchesCount > 0;
- end;
-
- function TpcRegExp.Search( AStr: Pchar; ALen : longint):boolean;
- begin
- MatchesCount:=0;
- Search:=SearchNext(AStr,ALen);
- SourceLen:=ALen;
- end;
-
- function TpcRegExp.SearchOfs( AStr: Pchar; ALen, AOfs: longint ) : boolean;
- var Options: Integer;
- begin
- MatchesCount:=0;
- Options := (RunTimeOptions or startup.MiscMultiData.cfgRegEx.DefaultOptions) and
- PCRE_EXEC_ALLOWED_OPTIONS;
- MatchesCount:=pcre_exec( RegExpC, RegExpExt, AStr, ALen, AOfs,
- Options, Matches, MAX_MATCHES );
- PartialMatch := MatchesCount = PCRE_ERROR_PARTIAL;
- SearchOfs := MatchesCount > 0;
- SourceLen := ALen-AOfs;
- end;
-
- function TpcRegExp.MatchSub(ANom:integer; var Pos,Len:longint):boolean;
- begin
- if (MatchesCount > 0) and (ANom <= (MatchesCount-1)) then
- begin
- ANom:=ANom*2;
- Pos:=PMatchArray(Matches)^[ANom];
- Len:=PMatchArray(Matches)^[ANom+1]-Pos;
- MatchSub:=true;
- end
- else
- MatchSub:=false;
- end;
-
- function TpcRegExp.MatchFull(var Pos,Len:longint):boolean;
- begin
- MatchFull:=MatchSub(0,Pos,Len);
- end;
-
- function TpcRegExp.GetSubStr(ANom: integer; AStr: Pchar):string;
- var
- s: ansistring;
- pos,len: longint;
- begin
- s:='';
- if MatchSub(ANom, pos, len) then
- begin
- setlength(s, len);
- Move(AStr[pos], s[1], len);
- end;
- GetSubStr:=s;
- end;
-
- function TpcRegExp.GetPreSubStr(AStr: Pchar):string;
- var
- s: ansistring;
- l: longint;
- begin
- s:='';
- if (MatchesCount > 0) then
- begin
- l:=PMatchArray(Matches)^[0]-1;
- if l > 0 then
- begin
- setlength(s,l);
- Move(AStr[1],s[1],l);
- end;
- end;
- GetPreSubStr:=s;
- end;
-
- function TpcRegExp.GetPostSubStr(AStr: Pchar):string;
- var
- s: ansistring;
- l: longint;
- ANom: integer;
- begin
- s:='';
- if (MatchesCount > 0) then
- begin
- ANom:=(MatchesCount-1){*2} shl 1;
- l:=SourceLen-PMatchArray(Matches)^[ANom+1]+1;
- if l > 0 then
- begin
- setlength(s,l);
- Move(AStr[PMatchArray(Matches)^[ANom+1]],s[1],l);
- end;
- end;
- GetPostSubStr:=s;
- end;
-
-
- function TpcRegExp.GetFullStr(AStr: Pchar):string;
- var
- s: ansistring;
- l: longint;
- begin
- GetFullStr:=GetSubStr(0,AStr);
- end;
-
- function TpcRegExp.GetReplStr(AStr: Pchar; const ARepl: string):string;
- var
- s: ansistring;
- l,i,lasti: longint;
- begin
- l:=length(ARepl);
- i:=1;
- lasti:=1;
- s:='';
- while i <= l do
- begin
- case ARepl[i] of
- '\' :
- begin
- if i < l then
- begin
- s:=s+copy(ARepl,lasti,i-lasti){+ARepl[i+1]};
- {AH 17-10-05 support for POSIX \1-\9 backreferences}
- case ARepl[i+1] of
- '0' : s:=s+GetFullStr(AStr);
- '1'..'9' : s:=s+GetSubStr(ord(ARepl[i+1])-ord('0'),AStr);
- else s:=s+ARepl[i+1]; // copy the escaped character
- end;
- end;
- inc(i);
- lasti:=i+1;
- end;
- '$' :
- begin
- if i < l then
- begin
- s:=s+copy(ARepl,lasti,i-lasti);
- case ARepl[i+1] of
- '&' : s:=s+GetFullStr(AStr);
- '1'..'9' : s:=s+GetSubStr(ord(ARepl[i+1])-ord('0'),AStr);
- '`' : s:=s+GetPreSubStr(AStr);
- #39 : s:=s+GetPostSubStr(AStr);
- end;
- end;
- inc(i);
- lasti:=i+1;
- end;
- end;
- inc(i);
- end;
- if lasti <= {AH 25-10-2004 added =, else l==1 won't work} l then
- s:=s+copy(ARepl,lasti,l-lasti+1);
- GetReplStr:=s;
- end;
-
- function TpcRegExp.ErrorStr:string;
- begin
- ErrorStr:=StrPas(ErrorMsg);
- end;
-
-{TRegExpCollection}
-
-constructor TRegExpCollection.Init(AMaxRegExp: integer);
-begin
- Inherited Init(1,1);
- MaxRegExp:=AMaxRegExp;
- CompareModeInsert:=true;
-end;
-
-procedure TRegExpCollection.FreeItem(P: Pointer);
-begin
- if P <> nil then
- begin
- Dispose(PpcRegExp(P),Done);
- end;
-end;
-
-function TRegExpCollection.Compare(P1, P2: Pointer): Integer;
-//var
-// l,l1,l2,i : byte;
-//// wPos: pchar;
-begin
- if CompareModeInsert then
- begin
-// l1:=length(PpcRegExp(P1)^.RegExp);
-// l2:=length(PpcRegExp(P2)^.RegExp);
-// if l1 > l2 then l:=l2 else
-// l:=l1;
-// for i:=1 to l do
-// if PpcRegExp(P1).RegExp[i] <> PpcRegExp(P2).RegExp[i] then break;
-// if i <=l then
-// Compare:=ord(PpcRegExp(P1).RegExp[i])-ord(PpcRegExp(P2).RegExp[i]) else
-// Compare:=l1-l2;
- Compare := stringsx.PasStrCmp(PpcRegExp(P1).RegExp, PpcRegExp(P2).RegExp, False);
- end
- else
- begin
-// l1:=length(PpcRegExp(P1)^.RegExp);
-// l2:=length(SearchRegExp);
-// if l1 > l2 then l:=l2 else
-// l:=l1;
-// for i:=1 to l do
-// if PpcRegExp(P1).RegExp[i] <> SearchRegExp[i] then
-// begin
-// Compare:=ord(PpcRegExp(P1).RegExp[i])-ord(SearchRegExp[i]);
-// break;
-// end;
-// if i > l then Compare:=l1-l2;
- Compare := stringsx.PasStrCmp(PpcRegExp(P1).RegExp, SearchRegExp, False);
- end;
-end;
-
-function TRegExpCollection.Find(ARegExp:shortstring;var P: PpcRegExp):boolean;
-var I : integer;
-begin
- CompareModeInsert:=false;
- SearchRegExp:=ARegExp;
- if Search(nil,I) then
- begin
- P:=PpcRegExp(At(I));
- Find:=true;
- end
- else
- begin
- P:=nil;
- Find:=false;
- end;
- CompareModeInsert:=true;
-end;
-
-function TRegExpCollection.CheckNew(ARegExp:shortstring):PpcRegExp;
-var
- P : PpcRegExp;
-begin
- if not Find(ARegExp,P) then
- begin
- if Count = MaxRegExp then
- AtFree(0);
- P:=New(ppcRegExp,Init(ARegExp,PCRE_CASELESS,nil));
- Insert(P);
- end;
- CheckNew:=P;
-end;
-
-function pcGrepMatch(WildCard, aStr: string; AOptions:integer; ALocale : Pointer): Boolean;
-var
- PpcRE:PpcRegExp;
-begin
- PpcRE:=New(ppcRegExp,Init(WildCard,AOptions,Alocale));
- pcGrepMatch:=PpcRE^.Search(pchar(AStr),Length(AStr));
- Dispose(PpcRE,Done);
-end;
-
-function pcGrepSub(WildCard, aStr, aRepl: string; AOptions:integer; ALocale : Pointer): string;
-var
- PpcRE:PpcRegExp;
-begin
- PpcRE:=New(ppcRegExp,Init(WildCard,AOptions,Alocale));
- if PpcRE^.Search(pchar(AStr),Length(AStr)) then
- pcGrepSub:=PpcRE^.GetReplStr(pchar(AStr),ARepl)
- else
- pcGrepSub:='';
- Dispose(PpcRE,Done);
-end;
-
-function pcFastGrepMatch(WildCard, aStr: string): Boolean;
-var
- PpcRE:PpcRegExp;
-begin
- PpcRE:=PRegExpCache^.CheckNew(WildCard);
- pcFastGrepMatch:=PpcRE^.Search(pchar(AStr),Length(AStr));
-end;
-
-function pcFastGrepSub(WildCard, aStr, aRepl: string): string;
-var
- PpcRE:PpcRegExp;
-begin
- PpcRE:=PRegExpCache^.CheckNew(WildCard);
- if PpcRE^.Search(pchar(AStr),Length(AStr)) then
- pcFastGrepSub:=PpcRE^.GetReplStr(pchar(AStr),ARepl)
- else
- pcFastGrepSub:='';
-end;
-
-{$IFDEF PCRE_5_0}
-function pcGetVersion : pchar; assembler; {$FRAME-}{$USES none}
-asm
- call pcre_version
-end;
-{$ENDIF PCRE_5_0}
-
-function pcError;
-var P: ppcRegExp absolute pRegExp;
-begin
- Result := (P = nil) or P^.Error;
- If Result and (P <> nil) then
- begin
-{ if P^.ErrorPos = 0 then
- MessageBox(GetString(erRegExpCompile)+'"'+P^.ErrorStr+'"', nil,mfConfirmation+mfOkButton)
- else}
- MessageBox(GetString(erRegExpCompile)+'"'+P^.ErrorStr+'"'+GetString(erRegExpCompPos),
- @P^.ErrorPos,mfConfirmation+mfOkButton);
- Dispose(P, Done);
- P:=nil;
- end;
-end;
-
-function pcInit;
-var Options : Integer;
-begin
- If CaseSens then Options := 0 else Options := PCRE_CASELESS;
- Result := New( PpcRegExp, Init( Pattern,
- {DefaultOptions}
- startup.MiscMultiData.cfgRegEx.DefaultOptions or Options,
- DefaultLocaleTable) );
-end;
-
-Initialization
- PRegExpCache:=New(PRegExpCollection,Init(64));
-Finalization
- Dispose(PRegExpCache,Done);
-End.
diff --git a/crawl-ref/source/util/pcre/pcregrep.c b/crawl-ref/source/util/pcre/pcregrep.c
deleted file mode 100644
index 87cbd4b415..0000000000
--- a/crawl-ref/source/util/pcre/pcregrep.c
+++ /dev/null
@@ -1,2379 +0,0 @@
-/*************************************************
-* pcregrep program *
-*************************************************/
-
-/* This is a grep program that uses the PCRE regular expression library to do
-its pattern matching. On a Unix or Win32 system it can recurse into
-directories.
-
- Copyright (c) 1997-2008 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <ctype.h>
-#include <locale.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <errno.h>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-#ifdef SUPPORT_LIBZ
-#include <zlib.h>
-#endif
-
-#ifdef SUPPORT_LIBBZ2
-#include <bzlib.h>
-#endif
-
-#include "pcre.h"
-
-#define FALSE 0
-#define TRUE 1
-
-typedef int BOOL;
-
-#define MAX_PATTERN_COUNT 100
-
-#if BUFSIZ > 8192
-#define MBUFTHIRD BUFSIZ
-#else
-#define MBUFTHIRD 8192
-#endif
-
-/* Values for the "filenames" variable, which specifies options for file name
-output. The order is important; it is assumed that a file name is wanted for
-all values greater than FN_DEFAULT. */
-
-enum { FN_NONE, FN_DEFAULT, FN_ONLY, FN_NOMATCH_ONLY, FN_FORCE };
-
-/* File reading styles */
-
-enum { FR_PLAIN, FR_LIBZ, FR_LIBBZ2 };
-
-/* Actions for the -d and -D options */
-
-enum { dee_READ, dee_SKIP, dee_RECURSE };
-enum { DEE_READ, DEE_SKIP };
-
-/* Actions for special processing options (flag bits) */
-
-#define PO_WORD_MATCH 0x0001
-#define PO_LINE_MATCH 0x0002
-#define PO_FIXED_STRINGS 0x0004
-
-/* Line ending types */
-
-enum { EL_LF, EL_CR, EL_CRLF, EL_ANY, EL_ANYCRLF };
-
-
-
-/*************************************************
-* Global variables *
-*************************************************/
-
-/* Jeffrey Friedl has some debugging requirements that are not part of the
-regular code. */
-
-#ifdef JFRIEDL_DEBUG
-static int S_arg = -1;
-static unsigned int jfriedl_XR = 0; /* repeat regex attempt this many times */
-static unsigned int jfriedl_XT = 0; /* replicate text this many times */
-static const char *jfriedl_prefix = "";
-static const char *jfriedl_postfix = "";
-#endif
-
-static int endlinetype;
-
-static char *colour_string = (char *)"1;31";
-static char *colour_option = NULL;
-static char *dee_option = NULL;
-static char *DEE_option = NULL;
-static char *newline = NULL;
-static char *pattern_filename = NULL;
-static char *stdin_name = (char *)"(standard input)";
-static char *locale = NULL;
-
-static const unsigned char *pcretables = NULL;
-
-static int pattern_count = 0;
-static pcre **pattern_list = NULL;
-static pcre_extra **hints_list = NULL;
-
-static char *include_pattern = NULL;
-static char *exclude_pattern = NULL;
-static char *include_dir_pattern = NULL;
-static char *exclude_dir_pattern = NULL;
-
-static pcre *include_compiled = NULL;
-static pcre *exclude_compiled = NULL;
-static pcre *include_dir_compiled = NULL;
-static pcre *exclude_dir_compiled = NULL;
-
-static int after_context = 0;
-static int before_context = 0;
-static int both_context = 0;
-static int dee_action = dee_READ;
-static int DEE_action = DEE_READ;
-static int error_count = 0;
-static int filenames = FN_DEFAULT;
-static int process_options = 0;
-
-static BOOL count_only = FALSE;
-static BOOL do_colour = FALSE;
-static BOOL file_offsets = FALSE;
-static BOOL hyphenpending = FALSE;
-static BOOL invert = FALSE;
-static BOOL line_offsets = FALSE;
-static BOOL multiline = FALSE;
-static BOOL number = FALSE;
-static BOOL only_matching = FALSE;
-static BOOL quiet = FALSE;
-static BOOL silent = FALSE;
-static BOOL utf8 = FALSE;
-
-/* Structure for options and list of them */
-
-enum { OP_NODATA, OP_STRING, OP_OP_STRING, OP_NUMBER, OP_OP_NUMBER,
- OP_PATLIST };
-
-typedef struct option_item {
- int type;
- int one_char;
- void *dataptr;
- const char *long_name;
- const char *help_text;
-} option_item;
-
-/* Options without a single-letter equivalent get a negative value. This can be
-used to identify them. */
-
-#define N_COLOUR (-1)
-#define N_EXCLUDE (-2)
-#define N_EXCLUDE_DIR (-3)
-#define N_HELP (-4)
-#define N_INCLUDE (-5)
-#define N_INCLUDE_DIR (-6)
-#define N_LABEL (-7)
-#define N_LOCALE (-8)
-#define N_NULL (-9)
-#define N_LOFFSETS (-10)
-#define N_FOFFSETS (-11)
-
-static option_item optionlist[] = {
- { OP_NODATA, N_NULL, NULL, "", " terminate options" },
- { OP_NODATA, N_HELP, NULL, "help", "display this help and exit" },
- { OP_NUMBER, 'A', &after_context, "after-context=number", "set number of following context lines" },
- { OP_NUMBER, 'B', &before_context, "before-context=number", "set number of prior context lines" },
- { OP_OP_STRING, N_COLOUR, &colour_option, "color=option", "matched text color option" },
- { OP_NUMBER, 'C', &both_context, "context=number", "set number of context lines, before & after" },
- { OP_NODATA, 'c', NULL, "count", "print only a count of matching lines per FILE" },
- { OP_OP_STRING, N_COLOUR, &colour_option, "colour=option", "matched text colour option" },
- { OP_STRING, 'D', &DEE_option, "devices=action","how to handle devices, FIFOs, and sockets" },
- { OP_STRING, 'd', &dee_option, "directories=action", "how to handle directories" },
- { OP_PATLIST, 'e', NULL, "regex(p)", "specify pattern (may be used more than once)" },
- { OP_NODATA, 'F', NULL, "fixed_strings", "patterns are sets of newline-separated strings" },
- { OP_STRING, 'f', &pattern_filename, "file=path", "read patterns from file" },
- { OP_NODATA, N_FOFFSETS, NULL, "file-offsets", "output file offsets, not text" },
- { OP_NODATA, 'H', NULL, "with-filename", "force the prefixing filename on output" },
- { OP_NODATA, 'h', NULL, "no-filename", "suppress the prefixing filename on output" },
- { OP_NODATA, 'i', NULL, "ignore-case", "ignore case distinctions" },
- { OP_NODATA, 'l', NULL, "files-with-matches", "print only FILE names containing matches" },
- { OP_NODATA, 'L', NULL, "files-without-match","print only FILE names not containing matches" },
- { OP_STRING, N_LABEL, &stdin_name, "label=name", "set name for standard input" },
- { OP_NODATA, N_LOFFSETS, NULL, "line-offsets", "output line numbers and offsets, not text" },
- { OP_STRING, N_LOCALE, &locale, "locale=locale", "use the named locale" },
- { OP_NODATA, 'M', NULL, "multiline", "run in multiline mode" },
- { OP_STRING, 'N', &newline, "newline=type", "set newline type (CR, LF, CRLF, ANYCRLF or ANY)" },
- { OP_NODATA, 'n', NULL, "line-number", "print line number with output lines" },
- { OP_NODATA, 'o', NULL, "only-matching", "show only the part of the line that matched" },
- { OP_NODATA, 'q', NULL, "quiet", "suppress output, just set return code" },
- { OP_NODATA, 'r', NULL, "recursive", "recursively scan sub-directories" },
- { OP_STRING, N_EXCLUDE,&exclude_pattern, "exclude=pattern","exclude matching files when recursing" },
- { OP_STRING, N_INCLUDE,&include_pattern, "include=pattern","include matching files when recursing" },
- { OP_STRING, N_EXCLUDE_DIR,&exclude_dir_pattern, "exclude_dir=pattern","exclude matching directories when recursing" },
- { OP_STRING, N_INCLUDE_DIR,&include_dir_pattern, "include_dir=pattern","include matching directories when recursing" },
-#ifdef JFRIEDL_DEBUG
- { OP_OP_NUMBER, 'S', &S_arg, "jeffS", "replace matched (sub)string with X" },
-#endif
- { OP_NODATA, 's', NULL, "no-messages", "suppress error messages" },
- { OP_NODATA, 'u', NULL, "utf-8", "use UTF-8 mode" },
- { OP_NODATA, 'V', NULL, "version", "print version information and exit" },
- { OP_NODATA, 'v', NULL, "invert-match", "select non-matching lines" },
- { OP_NODATA, 'w', NULL, "word-regex(p)", "force patterns to match only as words" },
- { OP_NODATA, 'x', NULL, "line-regex(p)", "force patterns to match only whole lines" },
- { OP_NODATA, 0, NULL, NULL, NULL }
-};
-
-/* Tables for prefixing and suffixing patterns, according to the -w, -x, and -F
-options. These set the 1, 2, and 4 bits in process_options, respectively. Note
-that the combination of -w and -x has the same effect as -x on its own, so we
-can treat them as the same. */
-
-static const char *prefix[] = {
- "", "\\b", "^(?:", "^(?:", "\\Q", "\\b\\Q", "^(?:\\Q", "^(?:\\Q" };
-
-static const char *suffix[] = {
- "", "\\b", ")$", ")$", "\\E", "\\E\\b", "\\E)$", "\\E)$" };
-
-/* UTF-8 tables - used only when the newline setting is "any". */
-
-const int utf8_table3[] = { 0xff, 0x1f, 0x0f, 0x07, 0x03, 0x01};
-
-const char utf8_table4[] = {
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
- 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
- 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5 };
-
-
-
-/*************************************************
-* OS-specific functions *
-*************************************************/
-
-/* These functions are defined so that they can be made system specific,
-although at present the only ones are for Unix, Win32, and for "no support". */
-
-
-/************* Directory scanning in Unix ***********/
-
-#if defined HAVE_SYS_STAT_H && defined HAVE_DIRENT_H && defined HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <dirent.h>
-
-typedef DIR directory_type;
-
-static int
-isdirectory(char *filename)
-{
-struct stat statbuf;
-if (stat(filename, &statbuf) < 0)
- return 0; /* In the expectation that opening as a file will fail */
-return ((statbuf.st_mode & S_IFMT) == S_IFDIR)? '/' : 0;
-}
-
-static directory_type *
-opendirectory(char *filename)
-{
-return opendir(filename);
-}
-
-static char *
-readdirectory(directory_type *dir)
-{
-for (;;)
- {
- struct dirent *dent = readdir(dir);
- if (dent == NULL) return NULL;
- if (strcmp(dent->d_name, ".") != 0 && strcmp(dent->d_name, "..") != 0)
- return dent->d_name;
- }
-/* Control never reaches here */
-}
-
-static void
-closedirectory(directory_type *dir)
-{
-closedir(dir);
-}
-
-
-/************* Test for regular file in Unix **********/
-
-static int
-isregfile(char *filename)
-{
-struct stat statbuf;
-if (stat(filename, &statbuf) < 0)
- return 1; /* In the expectation that opening as a file will fail */
-return (statbuf.st_mode & S_IFMT) == S_IFREG;
-}
-
-
-/************* Test stdout for being a terminal in Unix **********/
-
-static BOOL
-is_stdout_tty(void)
-{
-return isatty(fileno(stdout));
-}
-
-
-/************* Directory scanning in Win32 ***********/
-
-/* I (Philip Hazel) have no means of testing this code. It was contributed by
-Lionel Fourquaux. David Burgess added a patch to define INVALID_FILE_ATTRIBUTES
-when it did not exist. David Byron added a patch that moved the #include of
-<windows.h> to before the INVALID_FILE_ATTRIBUTES definition rather than after.
-*/
-
-#elif HAVE_WINDOWS_H
-
-#ifndef STRICT
-# define STRICT
-#endif
-#ifndef WIN32_LEAN_AND_MEAN
-# define WIN32_LEAN_AND_MEAN
-#endif
-
-#include <windows.h>
-
-#ifndef INVALID_FILE_ATTRIBUTES
-#define INVALID_FILE_ATTRIBUTES 0xFFFFFFFF
-#endif
-
-typedef struct directory_type
-{
-HANDLE handle;
-BOOL first;
-WIN32_FIND_DATA data;
-} directory_type;
-
-int
-isdirectory(char *filename)
-{
-DWORD attr = GetFileAttributes(filename);
-if (attr == INVALID_FILE_ATTRIBUTES)
- return 0;
-return ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) ? '/' : 0;
-}
-
-directory_type *
-opendirectory(char *filename)
-{
-size_t len;
-char *pattern;
-directory_type *dir;
-DWORD err;
-len = strlen(filename);
-pattern = (char *) malloc(len + 3);
-dir = (directory_type *) malloc(sizeof(*dir));
-if ((pattern == NULL) || (dir == NULL))
- {
- fprintf(stderr, "pcregrep: malloc failed\n");
- exit(2);
- }
-memcpy(pattern, filename, len);
-memcpy(&(pattern[len]), "\\*", 3);
-dir->handle = FindFirstFile(pattern, &(dir->data));
-if (dir->handle != INVALID_HANDLE_VALUE)
- {
- free(pattern);
- dir->first = TRUE;
- return dir;
- }
-err = GetLastError();
-free(pattern);
-free(dir);
-errno = (err == ERROR_ACCESS_DENIED) ? EACCES : ENOENT;
-return NULL;
-}
-
-char *
-readdirectory(directory_type *dir)
-{
-for (;;)
- {
- if (!dir->first)
- {
- if (!FindNextFile(dir->handle, &(dir->data)))
- return NULL;
- }
- else
- {
- dir->first = FALSE;
- }
- if (strcmp(dir->data.cFileName, ".") != 0 && strcmp(dir->data.cFileName, "..") != 0)
- return dir->data.cFileName;
- }
-#ifndef _MSC_VER
-return NULL; /* Keep compiler happy; never executed */
-#endif
-}
-
-void
-closedirectory(directory_type *dir)
-{
-FindClose(dir->handle);
-free(dir);
-}
-
-
-/************* Test for regular file in Win32 **********/
-
-/* I don't know how to do this, or if it can be done; assume all paths are
-regular if they are not directories. */
-
-int isregfile(char *filename)
-{
-return !isdirectory(filename);
-}
-
-
-/************* Test stdout for being a terminal in Win32 **********/
-
-/* I don't know how to do this; assume never */
-
-static BOOL
-is_stdout_tty(void)
-{
-return FALSE;
-}
-
-
-/************* Directory scanning when we can't do it ***********/
-
-/* The type is void, and apart from isdirectory(), the functions do nothing. */
-
-#else
-
-typedef void directory_type;
-
-int isdirectory(char *filename) { return 0; }
-directory_type * opendirectory(char *filename) { return (directory_type*)0;}
-char *readdirectory(directory_type *dir) { return (char*)0;}
-void closedirectory(directory_type *dir) {}
-
-
-/************* Test for regular when we can't do it **********/
-
-/* Assume all files are regular. */
-
-int isregfile(char *filename) { return 1; }
-
-
-/************* Test stdout for being a terminal when we can't do it **********/
-
-static BOOL
-is_stdout_tty(void)
-{
-return FALSE;
-}
-
-
-#endif
-
-
-
-#ifndef HAVE_STRERROR
-/*************************************************
-* Provide strerror() for non-ANSI libraries *
-*************************************************/
-
-/* Some old-fashioned systems still around (e.g. SunOS4) don't have strerror()
-in their libraries, but can provide the same facility by this simple
-alternative function. */
-
-extern int sys_nerr;
-extern char *sys_errlist[];
-
-char *
-strerror(int n)
-{
-if (n < 0 || n >= sys_nerr) return "unknown error number";
-return sys_errlist[n];
-}
-#endif /* HAVE_STRERROR */
-
-
-
-/*************************************************
-* Find end of line *
-*************************************************/
-
-/* The length of the endline sequence that is found is set via lenptr. This may
-be zero at the very end of the file if there is no line-ending sequence there.
-
-Arguments:
- p current position in line
- endptr end of available data
- lenptr where to put the length of the eol sequence
-
-Returns: pointer to the last byte of the line
-*/
-
-static char *
-end_of_line(char *p, char *endptr, int *lenptr)
-{
-switch(endlinetype)
- {
- default: /* Just in case */
- case EL_LF:
- while (p < endptr && *p != '\n') p++;
- if (p < endptr)
- {
- *lenptr = 1;
- return p + 1;
- }
- *lenptr = 0;
- return endptr;
-
- case EL_CR:
- while (p < endptr && *p != '\r') p++;
- if (p < endptr)
- {
- *lenptr = 1;
- return p + 1;
- }
- *lenptr = 0;
- return endptr;
-
- case EL_CRLF:
- for (;;)
- {
- while (p < endptr && *p != '\r') p++;
- if (++p >= endptr)
- {
- *lenptr = 0;
- return endptr;
- }
- if (*p == '\n')
- {
- *lenptr = 2;
- return p + 1;
- }
- }
- break;
-
- case EL_ANYCRLF:
- while (p < endptr)
- {
- int extra = 0;
- register int c = *((unsigned char *)p);
-
- if (utf8 && c >= 0xc0)
- {
- int gcii, gcss;
- extra = utf8_table4[c & 0x3f]; /* Number of additional bytes */
- gcss = 6*extra;
- c = (c & utf8_table3[extra]) << gcss;
- for (gcii = 1; gcii <= extra; gcii++)
- {
- gcss -= 6;
- c |= (p[gcii] & 0x3f) << gcss;
- }
- }
-
- p += 1 + extra;
-
- switch (c)
- {
- case 0x0a: /* LF */
- *lenptr = 1;
- return p;
-
- case 0x0d: /* CR */
- if (p < endptr && *p == 0x0a)
- {
- *lenptr = 2;
- p++;
- }
- else *lenptr = 1;
- return p;
-
- default:
- break;
- }
- } /* End of loop for ANYCRLF case */
-
- *lenptr = 0; /* Must have hit the end */
- return endptr;
-
- case EL_ANY:
- while (p < endptr)
- {
- int extra = 0;
- register int c = *((unsigned char *)p);
-
- if (utf8 && c >= 0xc0)
- {
- int gcii, gcss;
- extra = utf8_table4[c & 0x3f]; /* Number of additional bytes */
- gcss = 6*extra;
- c = (c & utf8_table3[extra]) << gcss;
- for (gcii = 1; gcii <= extra; gcii++)
- {
- gcss -= 6;
- c |= (p[gcii] & 0x3f) << gcss;
- }
- }
-
- p += 1 + extra;
-
- switch (c)
- {
- case 0x0a: /* LF */
- case 0x0b: /* VT */
- case 0x0c: /* FF */
- *lenptr = 1;
- return p;
-
- case 0x0d: /* CR */
- if (p < endptr && *p == 0x0a)
- {
- *lenptr = 2;
- p++;
- }
- else *lenptr = 1;
- return p;
-
- case 0x85: /* NEL */
- *lenptr = utf8? 2 : 1;
- return p;
-
- case 0x2028: /* LS */
- case 0x2029: /* PS */
- *lenptr = 3;
- return p;
-
- default:
- break;
- }
- } /* End of loop for ANY case */
-
- *lenptr = 0; /* Must have hit the end */
- return endptr;
- } /* End of overall switch */
-}
-
-
-
-/*************************************************
-* Find start of previous line *
-*************************************************/
-
-/* This is called when looking back for before lines to print.
-
-Arguments:
- p start of the subsequent line
- startptr start of available data
-
-Returns: pointer to the start of the previous line
-*/
-
-static char *
-previous_line(char *p, char *startptr)
-{
-switch(endlinetype)
- {
- default: /* Just in case */
- case EL_LF:
- p--;
- while (p > startptr && p[-1] != '\n') p--;
- return p;
-
- case EL_CR:
- p--;
- while (p > startptr && p[-1] != '\n') p--;
- return p;
-
- case EL_CRLF:
- for (;;)
- {
- p -= 2;
- while (p > startptr && p[-1] != '\n') p--;
- if (p <= startptr + 1 || p[-2] == '\r') return p;
- }
- return p; /* But control should never get here */
-
- case EL_ANY:
- case EL_ANYCRLF:
- if (*(--p) == '\n' && p > startptr && p[-1] == '\r') p--;
- if (utf8) while ((*p & 0xc0) == 0x80) p--;
-
- while (p > startptr)
- {
- register int c;
- char *pp = p - 1;
-
- if (utf8)
- {
- int extra = 0;
- while ((*pp & 0xc0) == 0x80) pp--;
- c = *((unsigned char *)pp);
- if (c >= 0xc0)
- {
- int gcii, gcss;
- extra = utf8_table4[c & 0x3f]; /* Number of additional bytes */
- gcss = 6*extra;
- c = (c & utf8_table3[extra]) << gcss;
- for (gcii = 1; gcii <= extra; gcii++)
- {
- gcss -= 6;
- c |= (pp[gcii] & 0x3f) << gcss;
- }
- }
- }
- else c = *((unsigned char *)pp);
-
- if (endlinetype == EL_ANYCRLF) switch (c)
- {
- case 0x0a: /* LF */
- case 0x0d: /* CR */
- return p;
-
- default:
- break;
- }
-
- else switch (c)
- {
- case 0x0a: /* LF */
- case 0x0b: /* VT */
- case 0x0c: /* FF */
- case 0x0d: /* CR */
- case 0x85: /* NEL */
- case 0x2028: /* LS */
- case 0x2029: /* PS */
- return p;
-
- default:
- break;
- }
-
- p = pp; /* Back one character */
- } /* End of loop for ANY case */
-
- return startptr; /* Hit start of data */
- } /* End of overall switch */
-}
-
-
-
-
-
-/*************************************************
-* Print the previous "after" lines *
-*************************************************/
-
-/* This is called if we are about to lose said lines because of buffer filling,
-and at the end of the file. The data in the line is written using fwrite() so
-that a binary zero does not terminate it.
-
-Arguments:
- lastmatchnumber the number of the last matching line, plus one
- lastmatchrestart where we restarted after the last match
- endptr end of available data
- printname filename for printing
-
-Returns: nothing
-*/
-
-static void do_after_lines(int lastmatchnumber, char *lastmatchrestart,
- char *endptr, char *printname)
-{
-if (after_context > 0 && lastmatchnumber > 0)
- {
- int count = 0;
- while (lastmatchrestart < endptr && count++ < after_context)
- {
- int ellength;
- char *pp = lastmatchrestart;
- if (printname != NULL) fprintf(stdout, "%s-", printname);
- if (number) fprintf(stdout, "%d-", lastmatchnumber++);
- pp = end_of_line(pp, endptr, &ellength);
- fwrite(lastmatchrestart, 1, pp - lastmatchrestart, stdout);
- lastmatchrestart = pp;
- }
- hyphenpending = TRUE;
- }
-}
-
-
-
-/*************************************************
-* Grep an individual file *
-*************************************************/
-
-/* This is called from grep_or_recurse() below. It uses a buffer that is three
-times the value of MBUFTHIRD. The matching point is never allowed to stray into
-the top third of the buffer, thus keeping more of the file available for
-context printing or for multiline scanning. For large files, the pointer will
-be in the middle third most of the time, so the bottom third is available for
-"before" context printing.
-
-Arguments:
- handle the fopened FILE stream for a normal file
- the gzFile pointer when reading is via libz
- the BZFILE pointer when reading is via libbz2
- frtype FR_PLAIN, FR_LIBZ, or FR_LIBBZ2
- printname the file name if it is to be printed for each match
- or NULL if the file name is not to be printed
- it cannot be NULL if filenames[_nomatch]_only is set
-
-Returns: 0 if there was at least one match
- 1 otherwise (no matches)
- 2 if there is a read error on a .bz2 file
-*/
-
-static int
-pcregrep(void *handle, int frtype, char *printname)
-{
-int rc = 1;
-int linenumber = 1;
-int lastmatchnumber = 0;
-int count = 0;
-int filepos = 0;
-int offsets[99];
-char *lastmatchrestart = NULL;
-char buffer[3*MBUFTHIRD];
-char *ptr = buffer;
-char *endptr;
-size_t bufflength;
-BOOL endhyphenpending = FALSE;
-FILE *in = NULL; /* Ensure initialized */
-
-#ifdef SUPPORT_LIBZ
-gzFile ingz = NULL;
-#endif
-
-#ifdef SUPPORT_LIBBZ2
-BZFILE *inbz2 = NULL;
-#endif
-
-
-/* Do the first read into the start of the buffer and set up the pointer to end
-of what we have. In the case of libz, a non-zipped .gz file will be read as a
-plain file. However, if a .bz2 file isn't actually bzipped, the first read will
-fail. */
-
-#ifdef SUPPORT_LIBZ
-if (frtype == FR_LIBZ)
- {
- ingz = (gzFile)handle;
- bufflength = gzread (ingz, buffer, 3*MBUFTHIRD);
- }
-else
-#endif
-
-#ifdef SUPPORT_LIBBZ2
-if (frtype == FR_LIBBZ2)
- {
- inbz2 = (BZFILE *)handle;
- bufflength = BZ2_bzread(inbz2, buffer, 3*MBUFTHIRD);
- if ((int)bufflength < 0) return 2; /* Gotcha: bufflength is size_t; */
- } /* without the cast it is unsigned. */
-else
-#endif
-
- {
- in = (FILE *)handle;
- bufflength = fread(buffer, 1, 3*MBUFTHIRD, in);
- }
-
-endptr = buffer + bufflength;
-
-/* Loop while the current pointer is not at the end of the file. For large
-files, endptr will be at the end of the buffer when we are in the middle of the
-file, but ptr will never get there, because as soon as it gets over 2/3 of the
-way, the buffer is shifted left and re-filled. */
-
-while (ptr < endptr)
- {
- int i, endlinelength;
- int mrc = 0;
- BOOL match = FALSE;
- char *matchptr = ptr;
- char *t = ptr;
- size_t length, linelength;
-
- /* At this point, ptr is at the start of a line. We need to find the length
- of the subject string to pass to pcre_exec(). In multiline mode, it is the
- length remainder of the data in the buffer. Otherwise, it is the length of
- the next line. After matching, we always advance by the length of the next
- line. In multiline mode the PCRE_FIRSTLINE option is used for compiling, so
- that any match is constrained to be in the first line. */
-
- t = end_of_line(t, endptr, &endlinelength);
- linelength = t - ptr - endlinelength;
- length = multiline? (size_t)(endptr - ptr) : linelength;
-
- /* Extra processing for Jeffrey Friedl's debugging. */
-
-#ifdef JFRIEDL_DEBUG
- if (jfriedl_XT || jfriedl_XR)
- {
- #include <sys/time.h>
- #include <time.h>
- struct timeval start_time, end_time;
- struct timezone dummy;
-
- if (jfriedl_XT)
- {
- unsigned long newlen = length * jfriedl_XT + strlen(jfriedl_prefix) + strlen(jfriedl_postfix);
- const char *orig = ptr;
- ptr = malloc(newlen + 1);
- if (!ptr) {
- printf("out of memory");
- exit(2);
- }
- endptr = ptr;
- strcpy(endptr, jfriedl_prefix); endptr += strlen(jfriedl_prefix);
- for (i = 0; i < jfriedl_XT; i++) {
- strncpy(endptr, orig, length);
- endptr += length;
- }
- strcpy(endptr, jfriedl_postfix); endptr += strlen(jfriedl_postfix);
- length = newlen;
- }
-
- if (gettimeofday(&start_time, &dummy) != 0)
- perror("bad gettimeofday");
-
-
- for (i = 0; i < jfriedl_XR; i++)
- match = (pcre_exec(pattern_list[0], hints_list[0], ptr, length, 0, 0, offsets, 99) >= 0);
-
- if (gettimeofday(&end_time, &dummy) != 0)
- perror("bad gettimeofday");
-
- double delta = ((end_time.tv_sec + (end_time.tv_usec / 1000000.0))
- -
- (start_time.tv_sec + (start_time.tv_usec / 1000000.0)));
-
- printf("%s TIMER[%.4f]\n", match ? "MATCH" : "FAIL", delta);
- return 0;
- }
-#endif
-
- /* We come back here after a match when the -o option (only_matching) is set,
- in order to find any further matches in the same line. */
-
- ONLY_MATCHING_RESTART:
-
- /* Run through all the patterns until one matches. Note that we don't include
- the final newline in the subject string. */
-
- for (i = 0; i < pattern_count; i++)
- {
- mrc = pcre_exec(pattern_list[i], hints_list[i], matchptr, length, 0, 0,
- offsets, 99);
- if (mrc >= 0) { match = TRUE; break; }
- if (mrc != PCRE_ERROR_NOMATCH)
- {
- fprintf(stderr, "pcregrep: pcre_exec() error %d while matching ", mrc);
- if (pattern_count > 1) fprintf(stderr, "pattern number %d to ", i+1);
- fprintf(stderr, "this line:\n");
- fwrite(matchptr, 1, linelength, stderr); /* In case binary zero included */
- fprintf(stderr, "\n");
- if (error_count == 0 &&
- (mrc == PCRE_ERROR_MATCHLIMIT || mrc == PCRE_ERROR_RECURSIONLIMIT))
- {
- fprintf(stderr, "pcregrep: error %d means that a resource limit "
- "was exceeded\n", mrc);
- fprintf(stderr, "pcregrep: check your regex for nested unlimited loops\n");
- }
- if (error_count++ > 20)
- {
- fprintf(stderr, "pcregrep: too many errors - abandoned\n");
- exit(2);
- }
- match = invert; /* No more matching; don't show the line again */
- break;
- }
- }
-
- /* If it's a match or a not-match (as required), do what's wanted. */
-
- if (match != invert)
- {
- BOOL hyphenprinted = FALSE;
-
- /* We've failed if we want a file that doesn't have any matches. */
-
- if (filenames == FN_NOMATCH_ONLY) return 1;
-
- /* Just count if just counting is wanted. */
-
- if (count_only) count++;
-
- /* If all we want is a file name, there is no need to scan any more lines
- in the file. */
-
- else if (filenames == FN_ONLY)
- {
- fprintf(stdout, "%s\n", printname);
- return 0;
- }
-
- /* Likewise, if all we want is a yes/no answer. */
-
- else if (quiet) return 0;
-
- /* The --only-matching option prints just the substring that matched, and
- the --file-offsets and --line-offsets options output offsets for the
- matching substring (they both force --only-matching). None of these options
- prints any context. Afterwards, adjust the start and length, and then jump
- back to look for further matches in the same line. If we are in invert
- mode, however, nothing is printed - this could be still useful because the
- return code is set. */
-
- else if (only_matching)
- {
- if (!invert)
- {
- if (printname != NULL) fprintf(stdout, "%s:", printname);
- if (number) fprintf(stdout, "%d:", linenumber);
- if (line_offsets)
- fprintf(stdout, "%d,%d", matchptr + offsets[0] - ptr,
- offsets[1] - offsets[0]);
- else if (file_offsets)
- fprintf(stdout, "%d,%d", filepos + matchptr + offsets[0] - ptr,
- offsets[1] - offsets[0]);
- else
- fwrite(matchptr + offsets[0], 1, offsets[1] - offsets[0], stdout);
- fprintf(stdout, "\n");
- matchptr += offsets[1];
- length -= offsets[1];
- match = FALSE;
- goto ONLY_MATCHING_RESTART;
- }
- }
-
- /* This is the default case when none of the above options is set. We print
- the matching lines(s), possibly preceded and/or followed by other lines of
- context. */
-
- else
- {
- /* See if there is a requirement to print some "after" lines from a
- previous match. We never print any overlaps. */
-
- if (after_context > 0 && lastmatchnumber > 0)
- {
- int ellength;
- int linecount = 0;
- char *p = lastmatchrestart;
-
- while (p < ptr && linecount < after_context)
- {
- p = end_of_line(p, ptr, &ellength);
- linecount++;
- }
-
- /* It is important to advance lastmatchrestart during this printing so
- that it interacts correctly with any "before" printing below. Print
- each line's data using fwrite() in case there are binary zeroes. */
-
- while (lastmatchrestart < p)
- {
- char *pp = lastmatchrestart;
- if (printname != NULL) fprintf(stdout, "%s-", printname);
- if (number) fprintf(stdout, "%d-", lastmatchnumber++);
- pp = end_of_line(pp, endptr, &ellength);
- fwrite(lastmatchrestart, 1, pp - lastmatchrestart, stdout);
- lastmatchrestart = pp;
- }
- if (lastmatchrestart != ptr) hyphenpending = TRUE;
- }
-
- /* If there were non-contiguous lines printed above, insert hyphens. */
-
- if (hyphenpending)
- {
- fprintf(stdout, "--\n");
- hyphenpending = FALSE;
- hyphenprinted = TRUE;
- }
-
- /* See if there is a requirement to print some "before" lines for this
- match. Again, don't print overlaps. */
-
- if (before_context > 0)
- {
- int linecount = 0;
- char *p = ptr;
-
- while (p > buffer && (lastmatchnumber == 0 || p > lastmatchrestart) &&
- linecount < before_context)
- {
- linecount++;
- p = previous_line(p, buffer);
- }
-
- if (lastmatchnumber > 0 && p > lastmatchrestart && !hyphenprinted)
- fprintf(stdout, "--\n");
-
- while (p < ptr)
- {
- int ellength;
- char *pp = p;
- if (printname != NULL) fprintf(stdout, "%s-", printname);
- if (number) fprintf(stdout, "%d-", linenumber - linecount--);
- pp = end_of_line(pp, endptr, &ellength);
- fwrite(p, 1, pp - p, stdout);
- p = pp;
- }
- }
-
- /* Now print the matching line(s); ensure we set hyphenpending at the end
- of the file if any context lines are being output. */
-
- if (after_context > 0 || before_context > 0)
- endhyphenpending = TRUE;
-
- if (printname != NULL) fprintf(stdout, "%s:", printname);
- if (number) fprintf(stdout, "%d:", linenumber);
-
- /* In multiline mode, we want to print to the end of the line in which
- the end of the matched string is found, so we adjust linelength and the
- line number appropriately, but only when there actually was a match
- (invert not set). Because the PCRE_FIRSTLINE option is set, the start of
- the match will always be before the first newline sequence. */
-
- if (multiline)
- {
- int ellength;
- char *endmatch = ptr;
- if (!invert)
- {
- endmatch += offsets[1];
- t = ptr;
- while (t < endmatch)
- {
- t = end_of_line(t, endptr, &ellength);
- if (t <= endmatch) linenumber++; else break;
- }
- }
- endmatch = end_of_line(endmatch, endptr, &ellength);
- linelength = endmatch - ptr - ellength;
- }
-
- /*** NOTE: Use only fwrite() to output the data line, so that binary
- zeroes are treated as just another data character. */
-
- /* This extra option, for Jeffrey Friedl's debugging requirements,
- replaces the matched string, or a specific captured string if it exists,
- with X. When this happens, colouring is ignored. */
-
-#ifdef JFRIEDL_DEBUG
- if (S_arg >= 0 && S_arg < mrc)
- {
- int first = S_arg * 2;
- int last = first + 1;
- fwrite(ptr, 1, offsets[first], stdout);
- fprintf(stdout, "X");
- fwrite(ptr + offsets[last], 1, linelength - offsets[last], stdout);
- }
- else
-#endif
-
- /* We have to split the line(s) up if colouring. */
-
- if (do_colour)
- {
- fwrite(ptr, 1, offsets[0], stdout);
- fprintf(stdout, "%c[%sm", 0x1b, colour_string);
- fwrite(ptr + offsets[0], 1, offsets[1] - offsets[0], stdout);
- fprintf(stdout, "%c[00m", 0x1b);
- fwrite(ptr + offsets[1], 1, (linelength + endlinelength) - offsets[1],
- stdout);
- }
- else fwrite(ptr, 1, linelength + endlinelength, stdout);
- }
-
- /* End of doing what has to be done for a match */
-
- rc = 0; /* Had some success */
-
- /* Remember where the last match happened for after_context. We remember
- where we are about to restart, and that line's number. */
-
- lastmatchrestart = ptr + linelength + endlinelength;
- lastmatchnumber = linenumber + 1;
- }
-
- /* For a match in multiline inverted mode (which of course did not cause
- anything to be printed), we have to move on to the end of the match before
- proceeding. */
-
- if (multiline && invert && match)
- {
- int ellength;
- char *endmatch = ptr + offsets[1];
- t = ptr;
- while (t < endmatch)
- {
- t = end_of_line(t, endptr, &ellength);
- if (t <= endmatch) linenumber++; else break;
- }
- endmatch = end_of_line(endmatch, endptr, &ellength);
- linelength = endmatch - ptr - ellength;
- }
-
- /* Advance to after the newline and increment the line number. The file
- offset to the current line is maintained in filepos. */
-
- ptr += linelength + endlinelength;
- filepos += linelength + endlinelength;
- linenumber++;
-
- /* If we haven't yet reached the end of the file (the buffer is full), and
- the current point is in the top 1/3 of the buffer, slide the buffer down by
- 1/3 and refill it. Before we do this, if some unprinted "after" lines are
- about to be lost, print them. */
-
- if (bufflength >= sizeof(buffer) && ptr > buffer + 2*MBUFTHIRD)
- {
- if (after_context > 0 &&
- lastmatchnumber > 0 &&
- lastmatchrestart < buffer + MBUFTHIRD)
- {
- do_after_lines(lastmatchnumber, lastmatchrestart, endptr, printname);
- lastmatchnumber = 0;
- }
-
- /* Now do the shuffle */
-
- memmove(buffer, buffer + MBUFTHIRD, 2*MBUFTHIRD);
- ptr -= MBUFTHIRD;
-
-#ifdef SUPPORT_LIBZ
- if (frtype == FR_LIBZ)
- bufflength = 2*MBUFTHIRD +
- gzread (ingz, buffer + 2*MBUFTHIRD, MBUFTHIRD);
- else
-#endif
-
-#ifdef SUPPORT_LIBBZ2
- if (frtype == FR_LIBBZ2)
- bufflength = 2*MBUFTHIRD +
- BZ2_bzread(inbz2, buffer + 2*MBUFTHIRD, MBUFTHIRD);
- else
-#endif
-
- bufflength = 2*MBUFTHIRD + fread(buffer + 2*MBUFTHIRD, 1, MBUFTHIRD, in);
-
- endptr = buffer + bufflength;
-
- /* Adjust any last match point */
-
- if (lastmatchnumber > 0) lastmatchrestart -= MBUFTHIRD;
- }
- } /* Loop through the whole file */
-
-/* End of file; print final "after" lines if wanted; do_after_lines sets
-hyphenpending if it prints something. */
-
-if (!only_matching && !count_only)
- {
- do_after_lines(lastmatchnumber, lastmatchrestart, endptr, printname);
- hyphenpending |= endhyphenpending;
- }
-
-/* Print the file name if we are looking for those without matches and there
-were none. If we found a match, we won't have got this far. */
-
-if (filenames == FN_NOMATCH_ONLY)
- {
- fprintf(stdout, "%s\n", printname);
- return 0;
- }
-
-/* Print the match count if wanted */
-
-if (count_only)
- {
- if (printname != NULL) fprintf(stdout, "%s:", printname);
- fprintf(stdout, "%d\n", count);
- }
-
-return rc;
-}
-
-
-
-/*************************************************
-* Grep a file or recurse into a directory *
-*************************************************/
-
-/* Given a path name, if it's a directory, scan all the files if we are
-recursing; if it's a file, grep it.
-
-Arguments:
- pathname the path to investigate
- dir_recurse TRUE if recursing is wanted (-r or -drecurse)
- only_one_at_top TRUE if the path is the only one at toplevel
-
-Returns: 0 if there was at least one match
- 1 if there were no matches
- 2 there was some kind of error
-
-However, file opening failures are suppressed if "silent" is set.
-*/
-
-static int
-grep_or_recurse(char *pathname, BOOL dir_recurse, BOOL only_one_at_top)
-{
-int rc = 1;
-int sep;
-int frtype;
-int pathlen;
-void *handle;
-FILE *in = NULL; /* Ensure initialized */
-
-#ifdef SUPPORT_LIBZ
-gzFile ingz = NULL;
-#endif
-
-#ifdef SUPPORT_LIBBZ2
-BZFILE *inbz2 = NULL;
-#endif
-
-/* If the file name is "-" we scan stdin */
-
-if (strcmp(pathname, "-") == 0)
- {
- return pcregrep(stdin, FR_PLAIN,
- (filenames > FN_DEFAULT || (filenames == FN_DEFAULT && !only_one_at_top))?
- stdin_name : NULL);
- }
-
-/* If the file is a directory, skip if skipping or if we are recursing, scan
-each file and directory within it, subject to any include or exclude patterns
-that were set. The scanning code is localized so it can be made
-system-specific. */
-
-if ((sep = isdirectory(pathname)) != 0)
- {
- if (dee_action == dee_SKIP) return 1;
- if (dee_action == dee_RECURSE)
- {
- char buffer[1024];
- char *nextfile;
- directory_type *dir = opendirectory(pathname);
-
- if (dir == NULL)
- {
- if (!silent)
- fprintf(stderr, "pcregrep: Failed to open directory %s: %s\n", pathname,
- strerror(errno));
- return 2;
- }
-
- while ((nextfile = readdirectory(dir)) != NULL)
- {
- int frc, nflen;
- sprintf(buffer, "%.512s%c%.128s", pathname, sep, nextfile);
- nflen = strlen(nextfile);
-
- if (isdirectory(buffer))
- {
- if (exclude_dir_compiled != NULL &&
- pcre_exec(exclude_dir_compiled, NULL, nextfile, nflen, 0, 0, NULL, 0) >= 0)
- continue;
-
- if (include_dir_compiled != NULL &&
- pcre_exec(include_dir_compiled, NULL, nextfile, nflen, 0, 0, NULL, 0) < 0)
- continue;
- }
- else
- {
- if (exclude_compiled != NULL &&
- pcre_exec(exclude_compiled, NULL, nextfile, nflen, 0, 0, NULL, 0) >= 0)
- continue;
-
- if (include_compiled != NULL &&
- pcre_exec(include_compiled, NULL, nextfile, nflen, 0, 0, NULL, 0) < 0)
- continue;
- }
-
- frc = grep_or_recurse(buffer, dir_recurse, FALSE);
- if (frc > 1) rc = frc;
- else if (frc == 0 && rc == 1) rc = 0;
- }
-
- closedirectory(dir);
- return rc;
- }
- }
-
-/* If the file is not a directory and not a regular file, skip it if that's
-been requested. */
-
-else if (!isregfile(pathname) && DEE_action == DEE_SKIP) return 1;
-
-/* Control reaches here if we have a regular file, or if we have a directory
-and recursion or skipping was not requested, or if we have anything else and
-skipping was not requested. The scan proceeds. If this is the first and only
-argument at top level, we don't show the file name, unless we are only showing
-the file name, or the filename was forced (-H). */
-
-pathlen = strlen(pathname);
-
-/* Open using zlib if it is supported and the file name ends with .gz. */
-
-#ifdef SUPPORT_LIBZ
-if (pathlen > 3 && strcmp(pathname + pathlen - 3, ".gz") == 0)
- {
- ingz = gzopen(pathname, "rb");
- if (ingz == NULL)
- {
- if (!silent)
- fprintf(stderr, "pcregrep: Failed to open %s: %s\n", pathname,
- strerror(errno));
- return 2;
- }
- handle = (void *)ingz;
- frtype = FR_LIBZ;
- }
-else
-#endif
-
-/* Otherwise open with bz2lib if it is supported and the name ends with .bz2. */
-
-#ifdef SUPPORT_LIBBZ2
-if (pathlen > 4 && strcmp(pathname + pathlen - 4, ".bz2") == 0)
- {
- inbz2 = BZ2_bzopen(pathname, "rb");
- handle = (void *)inbz2;
- frtype = FR_LIBBZ2;
- }
-else
-#endif
-
-/* Otherwise use plain fopen(). The label is so that we can come back here if
-an attempt to read a .bz2 file indicates that it really is a plain file. */
-
-#ifdef SUPPORT_LIBBZ2
-PLAIN_FILE:
-#endif
- {
- in = fopen(pathname, "r");
- handle = (void *)in;
- frtype = FR_PLAIN;
- }
-
-/* All the opening methods return errno when they fail. */
-
-if (handle == NULL)
- {
- if (!silent)
- fprintf(stderr, "pcregrep: Failed to open %s: %s\n", pathname,
- strerror(errno));
- return 2;
- }
-
-/* Now grep the file */
-
-rc = pcregrep(handle, frtype, (filenames > FN_DEFAULT ||
- (filenames == FN_DEFAULT && !only_one_at_top))? pathname : NULL);
-
-/* Close in an appropriate manner. */
-
-#ifdef SUPPORT_LIBZ
-if (frtype == FR_LIBZ)
- gzclose(ingz);
-else
-#endif
-
-/* If it is a .bz2 file and the result is 2, it means that the first attempt to
-read failed. If the error indicates that the file isn't in fact bzipped, try
-again as a normal file. */
-
-#ifdef SUPPORT_LIBBZ2
-if (frtype == FR_LIBBZ2)
- {
- if (rc == 2)
- {
- int errnum;
- const char *err = BZ2_bzerror(inbz2, &errnum);
- if (errnum == BZ_DATA_ERROR_MAGIC)
- {
- BZ2_bzclose(inbz2);
- goto PLAIN_FILE;
- }
- else if (!silent)
- fprintf(stderr, "pcregrep: Failed to read %s using bzlib: %s\n",
- pathname, err);
- }
- BZ2_bzclose(inbz2);
- }
-else
-#endif
-
-/* Normal file close */
-
-fclose(in);
-
-/* Pass back the yield from pcregrep(). */
-
-return rc;
-}
-
-
-
-
-/*************************************************
-* Usage function *
-*************************************************/
-
-static int
-usage(int rc)
-{
-option_item *op;
-fprintf(stderr, "Usage: pcregrep [-");
-for (op = optionlist; op->one_char != 0; op++)
- {
- if (op->one_char > 0) fprintf(stderr, "%c", op->one_char);
- }
-fprintf(stderr, "] [long options] [pattern] [files]\n");
-fprintf(stderr, "Type `pcregrep --help' for more information and the long "
- "options.\n");
-return rc;
-}
-
-
-
-
-/*************************************************
-* Help function *
-*************************************************/
-
-static void
-help(void)
-{
-option_item *op;
-
-printf("Usage: pcregrep [OPTION]... [PATTERN] [FILE1 FILE2 ...]\n");
-printf("Search for PATTERN in each FILE or standard input.\n");
-printf("PATTERN must be present if neither -e nor -f is used.\n");
-printf("\"-\" can be used as a file name to mean STDIN.\n");
-
-#ifdef SUPPORT_LIBZ
-printf("Files whose names end in .gz are read using zlib.\n");
-#endif
-
-#ifdef SUPPORT_LIBBZ2
-printf("Files whose names end in .bz2 are read using bzlib2.\n");
-#endif
-
-#if defined SUPPORT_LIBZ || defined SUPPORT_LIBBZ2
-printf("Other files and the standard input are read as plain files.\n\n");
-#else
-printf("All files are read as plain files, without any interpretation.\n\n");
-#endif
-
-printf("Example: pcregrep -i 'hello.*world' menu.h main.c\n\n");
-printf("Options:\n");
-
-for (op = optionlist; op->one_char != 0; op++)
- {
- int n;
- char s[4];
- if (op->one_char > 0) sprintf(s, "-%c,", op->one_char); else strcpy(s, " ");
- n = 30 - printf(" %s --%s", s, op->long_name);
- if (n < 1) n = 1;
- printf("%.*s%s\n", n, " ", op->help_text);
- }
-
-printf("\nWhen reading patterns from a file instead of using a command line option,\n");
-printf("trailing white space is removed and blank lines are ignored.\n");
-printf("There is a maximum of %d patterns.\n", MAX_PATTERN_COUNT);
-
-printf("\nWith no FILEs, read standard input. If fewer than two FILEs given, assume -h.\n");
-printf("Exit status is 0 if any matches, 1 if no matches, and 2 if trouble.\n");
-}
-
-
-
-
-/*************************************************
-* Handle a single-letter, no data option *
-*************************************************/
-
-static int
-handle_option(int letter, int options)
-{
-switch(letter)
- {
- case N_FOFFSETS: file_offsets = TRUE; break;
- case N_HELP: help(); exit(0);
- case N_LOFFSETS: line_offsets = number = TRUE; break;
- case 'c': count_only = TRUE; break;
- case 'F': process_options |= PO_FIXED_STRINGS; break;
- case 'H': filenames = FN_FORCE; break;
- case 'h': filenames = FN_NONE; break;
- case 'i': options |= PCRE_CASELESS; break;
- case 'l': filenames = FN_ONLY; break;
- case 'L': filenames = FN_NOMATCH_ONLY; break;
- case 'M': multiline = TRUE; options |= PCRE_MULTILINE|PCRE_FIRSTLINE; break;
- case 'n': number = TRUE; break;
- case 'o': only_matching = TRUE; break;
- case 'q': quiet = TRUE; break;
- case 'r': dee_action = dee_RECURSE; break;
- case 's': silent = TRUE; break;
- case 'u': options |= PCRE_UTF8; utf8 = TRUE; break;
- case 'v': invert = TRUE; break;
- case 'w': process_options |= PO_WORD_MATCH; break;
- case 'x': process_options |= PO_LINE_MATCH; break;
-
- case 'V':
- fprintf(stderr, "pcregrep version %s\n", pcre_version());
- exit(0);
- break;
-
- default:
- fprintf(stderr, "pcregrep: Unknown option -%c\n", letter);
- exit(usage(2));
- }
-
-return options;
-}
-
-
-
-
-/*************************************************
-* Construct printed ordinal *
-*************************************************/
-
-/* This turns a number into "1st", "3rd", etc. */
-
-static char *
-ordin(int n)
-{
-static char buffer[8];
-char *p = buffer;
-sprintf(p, "%d", n);
-while (*p != 0) p++;
-switch (n%10)
- {
- case 1: strcpy(p, "st"); break;
- case 2: strcpy(p, "nd"); break;
- case 3: strcpy(p, "rd"); break;
- default: strcpy(p, "th"); break;
- }
-return buffer;
-}
-
-
-
-/*************************************************
-* Compile a single pattern *
-*************************************************/
-
-/* When the -F option has been used, this is called for each substring.
-Otherwise it's called for each supplied pattern.
-
-Arguments:
- pattern the pattern string
- options the PCRE options
- filename the file name, or NULL for a command-line pattern
- count 0 if this is the only command line pattern, or
- number of the command line pattern, or
- linenumber for a pattern from a file
-
-Returns: TRUE on success, FALSE after an error
-*/
-
-static BOOL
-compile_single_pattern(char *pattern, int options, char *filename, int count)
-{
-char buffer[MBUFTHIRD + 16];
-const char *error;
-int errptr;
-
-if (pattern_count >= MAX_PATTERN_COUNT)
- {
- fprintf(stderr, "pcregrep: Too many %spatterns (max %d)\n",
- (filename == NULL)? "command-line " : "", MAX_PATTERN_COUNT);
- return FALSE;
- }
-
-sprintf(buffer, "%s%.*s%s", prefix[process_options], MBUFTHIRD, pattern,
- suffix[process_options]);
-pattern_list[pattern_count] =
- pcre_compile(buffer, options, &error, &errptr, pcretables);
-if (pattern_list[pattern_count] != NULL)
- {
- pattern_count++;
- return TRUE;
- }
-
-/* Handle compile errors */
-
-errptr -= (int)strlen(prefix[process_options]);
-if (errptr > (int)strlen(pattern)) errptr = (int)strlen(pattern);
-
-if (filename == NULL)
- {
- if (count == 0)
- fprintf(stderr, "pcregrep: Error in command-line regex "
- "at offset %d: %s\n", errptr, error);
- else
- fprintf(stderr, "pcregrep: Error in %s command-line regex "
- "at offset %d: %s\n", ordin(count), errptr, error);
- }
-else
- {
- fprintf(stderr, "pcregrep: Error in regex in line %d of %s "
- "at offset %d: %s\n", count, filename, errptr, error);
- }
-
-return FALSE;
-}
-
-
-
-/*************************************************
-* Compile one supplied pattern *
-*************************************************/
-
-/* When the -F option has been used, each string may be a list of strings,
-separated by line breaks. They will be matched literally.
-
-Arguments:
- pattern the pattern string
- options the PCRE options
- filename the file name, or NULL for a command-line pattern
- count 0 if this is the only command line pattern, or
- number of the command line pattern, or
- linenumber for a pattern from a file
-
-Returns: TRUE on success, FALSE after an error
-*/
-
-static BOOL
-compile_pattern(char *pattern, int options, char *filename, int count)
-{
-if ((process_options & PO_FIXED_STRINGS) != 0)
- {
- char *eop = pattern + strlen(pattern);
- char buffer[MBUFTHIRD];
- for(;;)
- {
- int ellength;
- char *p = end_of_line(pattern, eop, &ellength);
- if (ellength == 0)
- return compile_single_pattern(pattern, options, filename, count);
- sprintf(buffer, "%.*s", (int)(p - pattern - ellength), pattern);
- pattern = p;
- if (!compile_single_pattern(buffer, options, filename, count))
- return FALSE;
- }
- }
-else return compile_single_pattern(pattern, options, filename, count);
-}
-
-
-
-/*************************************************
-* Main program *
-*************************************************/
-
-/* Returns 0 if something matched, 1 if nothing matched, 2 after an error. */
-
-int
-main(int argc, char **argv)
-{
-int i, j;
-int rc = 1;
-int pcre_options = 0;
-int cmd_pattern_count = 0;
-int hint_count = 0;
-int errptr;
-BOOL only_one_at_top;
-char *patterns[MAX_PATTERN_COUNT];
-const char *locale_from = "--locale";
-const char *error;
-
-/* Set the default line ending value from the default in the PCRE library;
-"lf", "cr", "crlf", and "any" are supported. Anything else is treated as "lf".
-*/
-
-(void)pcre_config(PCRE_CONFIG_NEWLINE, &i);
-switch(i)
- {
- default: newline = (char *)"lf"; break;
- case '\r': newline = (char *)"cr"; break;
- case ('\r' << 8) | '\n': newline = (char *)"crlf"; break;
- case -1: newline = (char *)"any"; break;
- case -2: newline = (char *)"anycrlf"; break;
- }
-
-/* Process the options */
-
-for (i = 1; i < argc; i++)
- {
- option_item *op = NULL;
- char *option_data = (char *)""; /* default to keep compiler happy */
- BOOL longop;
- BOOL longopwasequals = FALSE;
-
- if (argv[i][0] != '-') break;
-
- /* If we hit an argument that is just "-", it may be a reference to STDIN,
- but only if we have previously had -e or -f to define the patterns. */
-
- if (argv[i][1] == 0)
- {
- if (pattern_filename != NULL || pattern_count > 0) break;
- else exit(usage(2));
- }
-
- /* Handle a long name option, or -- to terminate the options */
-
- if (argv[i][1] == '-')
- {
- char *arg = argv[i] + 2;
- char *argequals = strchr(arg, '=');
-
- if (*arg == 0) /* -- terminates options */
- {
- i++;
- break; /* out of the options-handling loop */
- }
-
- longop = TRUE;
-
- /* Some long options have data that follows after =, for example file=name.
- Some options have variations in the long name spelling: specifically, we
- allow "regexp" because GNU grep allows it, though I personally go along
- with Jeffrey Friedl and Larry Wall in preferring "regex" without the "p".
- These options are entered in the table as "regex(p)". No option is in both
- these categories, fortunately. */
-
- for (op = optionlist; op->one_char != 0; op++)
- {
- char *opbra = strchr(op->long_name, '(');
- char *equals = strchr(op->long_name, '=');
- if (opbra == NULL) /* Not a (p) case */
- {
- if (equals == NULL) /* Not thing=data case */
- {
- if (strcmp(arg, op->long_name) == 0) break;
- }
- else /* Special case xxx=data */
- {
- int oplen = equals - op->long_name;
- int arglen = (argequals == NULL)? (int)strlen(arg) : argequals - arg;
- if (oplen == arglen && strncmp(arg, op->long_name, oplen) == 0)
- {
- option_data = arg + arglen;
- if (*option_data == '=')
- {
- option_data++;
- longopwasequals = TRUE;
- }
- break;
- }
- }
- }
- else /* Special case xxxx(p) */
- {
- char buff1[24];
- char buff2[24];
- int baselen = opbra - op->long_name;
- sprintf(buff1, "%.*s", baselen, op->long_name);
- sprintf(buff2, "%s%.*s", buff1,
- (int)strlen(op->long_name) - baselen - 2, opbra + 1);
- if (strcmp(arg, buff1) == 0 || strcmp(arg, buff2) == 0)
- break;
- }
- }
-
- if (op->one_char == 0)
- {
- fprintf(stderr, "pcregrep: Unknown option %s\n", argv[i]);
- exit(usage(2));
- }
- }
-
-
- /* Jeffrey Friedl's debugging harness uses these additional options which
- are not in the right form for putting in the option table because they use
- only one hyphen, yet are more than one character long. By putting them
- separately here, they will not get displayed as part of the help() output,
- but I don't think Jeffrey will care about that. */
-
-#ifdef JFRIEDL_DEBUG
- else if (strcmp(argv[i], "-pre") == 0) {
- jfriedl_prefix = argv[++i];
- continue;
- } else if (strcmp(argv[i], "-post") == 0) {
- jfriedl_postfix = argv[++i];
- continue;
- } else if (strcmp(argv[i], "-XT") == 0) {
- sscanf(argv[++i], "%d", &jfriedl_XT);
- continue;
- } else if (strcmp(argv[i], "-XR") == 0) {
- sscanf(argv[++i], "%d", &jfriedl_XR);
- continue;
- }
-#endif
-
-
- /* One-char options; many that have no data may be in a single argument; we
- continue till we hit the last one or one that needs data. */
-
- else
- {
- char *s = argv[i] + 1;
- longop = FALSE;
- while (*s != 0)
- {
- for (op = optionlist; op->one_char != 0; op++)
- { if (*s == op->one_char) break; }
- if (op->one_char == 0)
- {
- fprintf(stderr, "pcregrep: Unknown option letter '%c' in \"%s\"\n",
- *s, argv[i]);
- exit(usage(2));
- }
- if (op->type != OP_NODATA || s[1] == 0)
- {
- option_data = s+1;
- break;
- }
- pcre_options = handle_option(*s++, pcre_options);
- }
- }
-
- /* At this point we should have op pointing to a matched option. If the type
- is NO_DATA, it means that there is no data, and the option might set
- something in the PCRE options. */
-
- if (op->type == OP_NODATA)
- {
- pcre_options = handle_option(op->one_char, pcre_options);
- continue;
- }
-
- /* If the option type is OP_OP_STRING or OP_OP_NUMBER, it's an option that
- either has a value or defaults to something. It cannot have data in a
- separate item. At the moment, the only such options are "colo(u)r" and
- Jeffrey Friedl's special -S debugging option. */
-
- if (*option_data == 0 &&
- (op->type == OP_OP_STRING || op->type == OP_OP_NUMBER))
- {
- switch (op->one_char)
- {
- case N_COLOUR:
- colour_option = (char *)"auto";
- break;
-#ifdef JFRIEDL_DEBUG
- case 'S':
- S_arg = 0;
- break;
-#endif
- }
- continue;
- }
-
- /* Otherwise, find the data string for the option. */
-
- if (*option_data == 0)
- {
- if (i >= argc - 1 || longopwasequals)
- {
- fprintf(stderr, "pcregrep: Data missing after %s\n", argv[i]);
- exit(usage(2));
- }
- option_data = argv[++i];
- }
-
- /* If the option type is OP_PATLIST, it's the -e option, which can be called
- multiple times to create a list of patterns. */
-
- if (op->type == OP_PATLIST)
- {
- if (cmd_pattern_count >= MAX_PATTERN_COUNT)
- {
- fprintf(stderr, "pcregrep: Too many command-line patterns (max %d)\n",
- MAX_PATTERN_COUNT);
- return 2;
- }
- patterns[cmd_pattern_count++] = option_data;
- }
-
- /* Otherwise, deal with single string or numeric data values. */
-
- else if (op->type != OP_NUMBER && op->type != OP_OP_NUMBER)
- {
- *((char **)op->dataptr) = option_data;
- }
- else
- {
- char *endptr;
- int n = strtoul(option_data, &endptr, 10);
- if (*endptr != 0)
- {
- if (longop)
- {
- char *equals = strchr(op->long_name, '=');
- int nlen = (equals == NULL)? (int)strlen(op->long_name) :
- equals - op->long_name;
- fprintf(stderr, "pcregrep: Malformed number \"%s\" after --%.*s\n",
- option_data, nlen, op->long_name);
- }
- else
- fprintf(stderr, "pcregrep: Malformed number \"%s\" after -%c\n",
- option_data, op->one_char);
- exit(usage(2));
- }
- *((int *)op->dataptr) = n;
- }
- }
-
-/* Options have been decoded. If -C was used, its value is used as a default
-for -A and -B. */
-
-if (both_context > 0)
- {
- if (after_context == 0) after_context = both_context;
- if (before_context == 0) before_context = both_context;
- }
-
-/* Only one of --only-matching, --file-offsets, or --line-offsets is permitted.
-However, the latter two set the only_matching flag. */
-
-if ((only_matching && (file_offsets || line_offsets)) ||
- (file_offsets && line_offsets))
- {
- fprintf(stderr, "pcregrep: Cannot mix --only-matching, --file-offsets "
- "and/or --line-offsets\n");
- exit(usage(2));
- }
-
-if (file_offsets || line_offsets) only_matching = TRUE;
-
-/* If a locale has not been provided as an option, see if the LC_CTYPE or
-LC_ALL environment variable is set, and if so, use it. */
-
-if (locale == NULL)
- {
- locale = getenv("LC_ALL");
- locale_from = "LCC_ALL";
- }
-
-if (locale == NULL)
- {
- locale = getenv("LC_CTYPE");
- locale_from = "LC_CTYPE";
- }
-
-/* If a locale has been provided, set it, and generate the tables the PCRE
-needs. Otherwise, pcretables==NULL, which causes the use of default tables. */
-
-if (locale != NULL)
- {
- if (setlocale(LC_CTYPE, locale) == NULL)
- {
- fprintf(stderr, "pcregrep: Failed to set locale %s (obtained from %s)\n",
- locale, locale_from);
- return 2;
- }
- pcretables = pcre_maketables();
- }
-
-/* Sort out colouring */
-
-if (colour_option != NULL && strcmp(colour_option, "never") != 0)
- {
- if (strcmp(colour_option, "always") == 0) do_colour = TRUE;
- else if (strcmp(colour_option, "auto") == 0) do_colour = is_stdout_tty();
- else
- {
- fprintf(stderr, "pcregrep: Unknown colour setting \"%s\"\n",
- colour_option);
- return 2;
- }
- if (do_colour)
- {
- char *cs = getenv("PCREGREP_COLOUR");
- if (cs == NULL) cs = getenv("PCREGREP_COLOR");
- if (cs != NULL) colour_string = cs;
- }
- }
-
-/* Interpret the newline type; the default settings are Unix-like. */
-
-if (strcmp(newline, "cr") == 0 || strcmp(newline, "CR") == 0)
- {
- pcre_options |= PCRE_NEWLINE_CR;
- endlinetype = EL_CR;
- }
-else if (strcmp(newline, "lf") == 0 || strcmp(newline, "LF") == 0)
- {
- pcre_options |= PCRE_NEWLINE_LF;
- endlinetype = EL_LF;
- }
-else if (strcmp(newline, "crlf") == 0 || strcmp(newline, "CRLF") == 0)
- {
- pcre_options |= PCRE_NEWLINE_CRLF;
- endlinetype = EL_CRLF;
- }
-else if (strcmp(newline, "any") == 0 || strcmp(newline, "ANY") == 0)
- {
- pcre_options |= PCRE_NEWLINE_ANY;
- endlinetype = EL_ANY;
- }
-else if (strcmp(newline, "anycrlf") == 0 || strcmp(newline, "ANYCRLF") == 0)
- {
- pcre_options |= PCRE_NEWLINE_ANYCRLF;
- endlinetype = EL_ANYCRLF;
- }
-else
- {
- fprintf(stderr, "pcregrep: Invalid newline specifier \"%s\"\n", newline);
- return 2;
- }
-
-/* Interpret the text values for -d and -D */
-
-if (dee_option != NULL)
- {
- if (strcmp(dee_option, "read") == 0) dee_action = dee_READ;
- else if (strcmp(dee_option, "recurse") == 0) dee_action = dee_RECURSE;
- else if (strcmp(dee_option, "skip") == 0) dee_action = dee_SKIP;
- else
- {
- fprintf(stderr, "pcregrep: Invalid value \"%s\" for -d\n", dee_option);
- return 2;
- }
- }
-
-if (DEE_option != NULL)
- {
- if (strcmp(DEE_option, "read") == 0) DEE_action = DEE_READ;
- else if (strcmp(DEE_option, "skip") == 0) DEE_action = DEE_SKIP;
- else
- {
- fprintf(stderr, "pcregrep: Invalid value \"%s\" for -D\n", DEE_option);
- return 2;
- }
- }
-
-/* Check the values for Jeffrey Friedl's debugging options. */
-
-#ifdef JFRIEDL_DEBUG
-if (S_arg > 9)
- {
- fprintf(stderr, "pcregrep: bad value for -S option\n");
- return 2;
- }
-if (jfriedl_XT != 0 || jfriedl_XR != 0)
- {
- if (jfriedl_XT == 0) jfriedl_XT = 1;
- if (jfriedl_XR == 0) jfriedl_XR = 1;
- }
-#endif
-
-/* Get memory to store the pattern and hints lists. */
-
-pattern_list = (pcre **)malloc(MAX_PATTERN_COUNT * sizeof(pcre *));
-hints_list = (pcre_extra **)malloc(MAX_PATTERN_COUNT * sizeof(pcre_extra *));
-
-if (pattern_list == NULL || hints_list == NULL)
- {
- fprintf(stderr, "pcregrep: malloc failed\n");
- goto EXIT2;
- }
-
-/* If no patterns were provided by -e, and there is no file provided by -f,
-the first argument is the one and only pattern, and it must exist. */
-
-if (cmd_pattern_count == 0 && pattern_filename == NULL)
- {
- if (i >= argc) return usage(2);
- patterns[cmd_pattern_count++] = argv[i++];
- }
-
-/* Compile the patterns that were provided on the command line, either by
-multiple uses of -e or as a single unkeyed pattern. */
-
-for (j = 0; j < cmd_pattern_count; j++)
- {
- if (!compile_pattern(patterns[j], pcre_options, NULL,
- (j == 0 && cmd_pattern_count == 1)? 0 : j + 1))
- goto EXIT2;
- }
-
-/* Compile the regular expressions that are provided in a file. */
-
-if (pattern_filename != NULL)
- {
- int linenumber = 0;
- FILE *f;
- char *filename;
- char buffer[MBUFTHIRD];
-
- if (strcmp(pattern_filename, "-") == 0)
- {
- f = stdin;
- filename = stdin_name;
- }
- else
- {
- f = fopen(pattern_filename, "r");
- if (f == NULL)
- {
- fprintf(stderr, "pcregrep: Failed to open %s: %s\n", pattern_filename,
- strerror(errno));
- goto EXIT2;
- }
- filename = pattern_filename;
- }
-
- while (fgets(buffer, MBUFTHIRD, f) != NULL)
- {
- char *s = buffer + (int)strlen(buffer);
- while (s > buffer && isspace((unsigned char)(s[-1]))) s--;
- *s = 0;
- linenumber++;
- if (buffer[0] == 0) continue; /* Skip blank lines */
- if (!compile_pattern(buffer, pcre_options, filename, linenumber))
- goto EXIT2;
- }
-
- if (f != stdin) fclose(f);
- }
-
-/* Study the regular expressions, as we will be running them many times */
-
-for (j = 0; j < pattern_count; j++)
- {
- hints_list[j] = pcre_study(pattern_list[j], 0, &error);
- if (error != NULL)
- {
- char s[16];
- if (pattern_count == 1) s[0] = 0; else sprintf(s, " number %d", j);
- fprintf(stderr, "pcregrep: Error while studying regex%s: %s\n", s, error);
- goto EXIT2;
- }
- hint_count++;
- }
-
-/* If there are include or exclude patterns, compile them. */
-
-if (exclude_pattern != NULL)
- {
- exclude_compiled = pcre_compile(exclude_pattern, 0, &error, &errptr,
- pcretables);
- if (exclude_compiled == NULL)
- {
- fprintf(stderr, "pcregrep: Error in 'exclude' regex at offset %d: %s\n",
- errptr, error);
- goto EXIT2;
- }
- }
-
-if (include_pattern != NULL)
- {
- include_compiled = pcre_compile(include_pattern, 0, &error, &errptr,
- pcretables);
- if (include_compiled == NULL)
- {
- fprintf(stderr, "pcregrep: Error in 'include' regex at offset %d: %s\n",
- errptr, error);
- goto EXIT2;
- }
- }
-
-if (exclude_dir_pattern != NULL)
- {
- exclude_dir_compiled = pcre_compile(exclude_dir_pattern, 0, &error, &errptr,
- pcretables);
- if (exclude_dir_compiled == NULL)
- {
- fprintf(stderr, "pcregrep: Error in 'exclude_dir' regex at offset %d: %s\n",
- errptr, error);
- goto EXIT2;
- }
- }
-
-if (include_dir_pattern != NULL)
- {
- include_dir_compiled = pcre_compile(include_dir_pattern, 0, &error, &errptr,
- pcretables);
- if (include_dir_compiled == NULL)
- {
- fprintf(stderr, "pcregrep: Error in 'include_dir' regex at offset %d: %s\n",
- errptr, error);
- goto EXIT2;
- }
- }
-
-/* If there are no further arguments, do the business on stdin and exit. */
-
-if (i >= argc)
- {
- rc = pcregrep(stdin, FR_PLAIN, (filenames > FN_DEFAULT)? stdin_name : NULL);
- goto EXIT;
- }
-
-/* Otherwise, work through the remaining arguments as files or directories.
-Pass in the fact that there is only one argument at top level - this suppresses
-the file name if the argument is not a directory and filenames are not
-otherwise forced. */
-
-only_one_at_top = i == argc - 1; /* Catch initial value of i */
-
-for (; i < argc; i++)
- {
- int frc = grep_or_recurse(argv[i], dee_action == dee_RECURSE,
- only_one_at_top);
- if (frc > 1) rc = frc;
- else if (frc == 0 && rc == 1) rc = 0;
- }
-
-EXIT:
-if (pattern_list != NULL)
- {
- for (i = 0; i < pattern_count; i++) free(pattern_list[i]);
- free(pattern_list);
- }
-if (hints_list != NULL)
- {
- for (i = 0; i < hint_count; i++) free(hints_list[i]);
- free(hints_list);
- }
-return rc;
-
-EXIT2:
-rc = 2;
-goto EXIT;
-}
-
-/* End of pcregrep */
diff --git a/crawl-ref/source/util/pcre/pcreposix.c b/crawl-ref/source/util/pcre/pcreposix.c
deleted file mode 100644
index 9782d46603..0000000000
--- a/crawl-ref/source/util/pcre/pcreposix.c
+++ /dev/null
@@ -1,356 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
- Written by Philip Hazel
- Copyright (c) 1997-2008 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-
-/* This module is a wrapper that provides a POSIX API to the underlying PCRE
-functions. */
-
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-
-/* Ensure that the PCREPOSIX_EXP_xxx macros are set appropriately for
-compiling these functions. This must come before including pcreposix.h, where
-they are set for an application (using these functions) if they have not
-previously been set. */
-
-#if defined(_WIN32) && !defined(PCRE_STATIC)
-# define PCREPOSIX_EXP_DECL extern __declspec(dllexport)
-# define PCREPOSIX_EXP_DEFN __declspec(dllexport)
-#endif
-
-#include "pcre.h"
-#include "pcre_internal.h"
-#include "pcreposix.h"
-
-
-/* Table to translate PCRE compile time error codes into POSIX error codes. */
-
-static const int eint[] = {
- 0, /* no error */
- REG_EESCAPE, /* \ at end of pattern */
- REG_EESCAPE, /* \c at end of pattern */
- REG_EESCAPE, /* unrecognized character follows \ */
- REG_BADBR, /* numbers out of order in {} quantifier */
- REG_BADBR, /* number too big in {} quantifier */
- REG_EBRACK, /* missing terminating ] for character class */
- REG_ECTYPE, /* invalid escape sequence in character class */
- REG_ERANGE, /* range out of order in character class */
- REG_BADRPT, /* nothing to repeat */
- REG_BADRPT, /* operand of unlimited repeat could match the empty string */
- REG_ASSERT, /* internal error: unexpected repeat */
- REG_BADPAT, /* unrecognized character after (? */
- REG_BADPAT, /* POSIX named classes are supported only within a class */
- REG_EPAREN, /* missing ) */
- REG_ESUBREG, /* reference to non-existent subpattern */
- REG_INVARG, /* erroffset passed as NULL */
- REG_INVARG, /* unknown option bit(s) set */
- REG_EPAREN, /* missing ) after comment */
- REG_ESIZE, /* parentheses nested too deeply */
- REG_ESIZE, /* regular expression too large */
- REG_ESPACE, /* failed to get memory */
- REG_EPAREN, /* unmatched brackets */
- REG_ASSERT, /* internal error: code overflow */
- REG_BADPAT, /* unrecognized character after (?< */
- REG_BADPAT, /* lookbehind assertion is not fixed length */
- REG_BADPAT, /* malformed number or name after (?( */
- REG_BADPAT, /* conditional group contains more than two branches */
- REG_BADPAT, /* assertion expected after (?( */
- REG_BADPAT, /* (?R or (?[+-]digits must be followed by ) */
- REG_ECTYPE, /* unknown POSIX class name */
- REG_BADPAT, /* POSIX collating elements are not supported */
- REG_INVARG, /* this version of PCRE is not compiled with PCRE_UTF8 support */
- REG_BADPAT, /* spare error */
- REG_BADPAT, /* character value in \x{...} sequence is too large */
- REG_BADPAT, /* invalid condition (?(0) */
- REG_BADPAT, /* \C not allowed in lookbehind assertion */
- REG_EESCAPE, /* PCRE does not support \L, \l, \N, \U, or \u */
- REG_BADPAT, /* number after (?C is > 255 */
- REG_BADPAT, /* closing ) for (?C expected */
- REG_BADPAT, /* recursive call could loop indefinitely */
- REG_BADPAT, /* unrecognized character after (?P */
- REG_BADPAT, /* syntax error in subpattern name (missing terminator) */
- REG_BADPAT, /* two named subpatterns have the same name */
- REG_BADPAT, /* invalid UTF-8 string */
- REG_BADPAT, /* support for \P, \p, and \X has not been compiled */
- REG_BADPAT, /* malformed \P or \p sequence */
- REG_BADPAT, /* unknown property name after \P or \p */
- REG_BADPAT, /* subpattern name is too long (maximum 32 characters) */
- REG_BADPAT, /* too many named subpatterns (maximum 10,000) */
- REG_BADPAT, /* repeated subpattern is too long */
- REG_BADPAT, /* octal value is greater than \377 (not in UTF-8 mode) */
- REG_BADPAT, /* internal error: overran compiling workspace */
- REG_BADPAT, /* internal error: previously-checked referenced subpattern not found */
- REG_BADPAT, /* DEFINE group contains more than one branch */
- REG_BADPAT, /* repeating a DEFINE group is not allowed */
- REG_INVARG, /* inconsistent NEWLINE options */
- REG_BADPAT, /* \g is not followed followed by an (optionally braced) non-zero number */
- REG_BADPAT, /* (?+ or (?- must be followed by a non-zero number */
- REG_BADPAT, /* number is too big */
- REG_BADPAT, /* subpattern name expected */
- REG_BADPAT, /* digit expected after (?+ */
- REG_BADPAT /* ] is an invalid data character in JavaScript compatibility mode */
-};
-
-/* Table of texts corresponding to POSIX error codes */
-
-static const char *const pstring[] = {
- "", /* Dummy for value 0 */
- "internal error", /* REG_ASSERT */
- "invalid repeat counts in {}", /* BADBR */
- "pattern error", /* BADPAT */
- "? * + invalid", /* BADRPT */
- "unbalanced {}", /* EBRACE */
- "unbalanced []", /* EBRACK */
- "collation error - not relevant", /* ECOLLATE */
- "bad class", /* ECTYPE */
- "bad escape sequence", /* EESCAPE */
- "empty expression", /* EMPTY */
- "unbalanced ()", /* EPAREN */
- "bad range inside []", /* ERANGE */
- "expression too big", /* ESIZE */
- "failed to get memory", /* ESPACE */
- "bad back reference", /* ESUBREG */
- "bad argument", /* INVARG */
- "match failed" /* NOMATCH */
-};
-
-
-
-
-/*************************************************
-* Translate error code to string *
-*************************************************/
-
-PCREPOSIX_EXP_DEFN size_t
-regerror(int errcode, const regex_t *preg, char *errbuf, size_t errbuf_size)
-{
-const char *message, *addmessage;
-size_t length, addlength;
-
-message = (errcode >= (int)(sizeof(pstring)/sizeof(char *)))?
- "unknown error code" : pstring[errcode];
-length = strlen(message) + 1;
-
-addmessage = " at offset ";
-addlength = (preg != NULL && (int)preg->re_erroffset != -1)?
- strlen(addmessage) + 6 : 0;
-
-if (errbuf_size > 0)
- {
- if (addlength > 0 && errbuf_size >= length + addlength)
- sprintf(errbuf, "%s%s%-6d", message, addmessage, (int)preg->re_erroffset);
- else
- {
- strncpy(errbuf, message, errbuf_size - 1);
- errbuf[errbuf_size-1] = 0;
- }
- }
-
-return length + addlength;
-}
-
-
-
-
-/*************************************************
-* Free store held by a regex *
-*************************************************/
-
-PCREPOSIX_EXP_DEFN void
-regfree(regex_t *preg)
-{
-(pcre_free)(preg->re_pcre);
-}
-
-
-
-
-/*************************************************
-* Compile a regular expression *
-*************************************************/
-
-/*
-Arguments:
- preg points to a structure for recording the compiled expression
- pattern the pattern to compile
- cflags compilation flags
-
-Returns: 0 on success
- various non-zero codes on failure
-*/
-
-PCREPOSIX_EXP_DEFN int
-regcomp(regex_t *preg, const char *pattern, int cflags)
-{
-const char *errorptr;
-int erroffset;
-int errorcode;
-int options = 0;
-
-if ((cflags & REG_ICASE) != 0) options |= PCRE_CASELESS;
-if ((cflags & REG_NEWLINE) != 0) options |= PCRE_MULTILINE;
-if ((cflags & REG_DOTALL) != 0) options |= PCRE_DOTALL;
-if ((cflags & REG_NOSUB) != 0) options |= PCRE_NO_AUTO_CAPTURE;
-if ((cflags & REG_UTF8) != 0) options |= PCRE_UTF8;
-
-preg->re_pcre = pcre_compile2(pattern, options, &errorcode, &errorptr,
- &erroffset, NULL);
-preg->re_erroffset = erroffset;
-
-if (preg->re_pcre == NULL) return eint[errorcode];
-
-preg->re_nsub = pcre_info((const pcre *)preg->re_pcre, NULL, NULL);
-return 0;
-}
-
-
-
-
-/*************************************************
-* Match a regular expression *
-*************************************************/
-
-/* Unfortunately, PCRE requires 3 ints of working space for each captured
-substring, so we have to get and release working store instead of just using
-the POSIX structures as was done in earlier releases when PCRE needed only 2
-ints. However, if the number of possible capturing brackets is small, use a
-block of store on the stack, to reduce the use of malloc/free. The threshold is
-in a macro that can be changed at configure time.
-
-If REG_NOSUB was specified at compile time, the PCRE_NO_AUTO_CAPTURE flag will
-be set. When this is the case, the nmatch and pmatch arguments are ignored, and
-the only result is yes/no/error. */
-
-PCREPOSIX_EXP_DEFN int
-regexec(const regex_t *preg, const char *string, size_t nmatch,
- regmatch_t pmatch[], int eflags)
-{
-int rc, so, eo;
-int options = 0;
-int *ovector = NULL;
-int small_ovector[POSIX_MALLOC_THRESHOLD * 3];
-BOOL allocated_ovector = FALSE;
-BOOL nosub =
- (((const pcre *)preg->re_pcre)->options & PCRE_NO_AUTO_CAPTURE) != 0;
-
-if ((eflags & REG_NOTBOL) != 0) options |= PCRE_NOTBOL;
-if ((eflags & REG_NOTEOL) != 0) options |= PCRE_NOTEOL;
-
-((regex_t *)preg)->re_erroffset = (size_t)(-1); /* Only has meaning after compile */
-
-/* When no string data is being returned, ensure that nmatch is zero.
-Otherwise, ensure the vector for holding the return data is large enough. */
-
-if (nosub) nmatch = 0;
-
-else if (nmatch > 0)
- {
- if (nmatch <= POSIX_MALLOC_THRESHOLD)
- {
- ovector = &(small_ovector[0]);
- }
- else
- {
- if (nmatch > INT_MAX/(sizeof(int) * 3)) return REG_ESPACE;
- ovector = (int *)malloc(sizeof(int) * nmatch * 3);
- if (ovector == NULL) return REG_ESPACE;
- allocated_ovector = TRUE;
- }
- }
-
-/* REG_STARTEND is a BSD extension, to allow for non-NUL-terminated strings.
-The man page from OS X says "REG_STARTEND affects only the location of the
-string, not how it is matched". That is why the "so" value is used to bump the
-start location rather than being passed as a PCRE "starting offset". */
-
-if ((eflags & REG_STARTEND) != 0)
- {
- so = pmatch[0].rm_so;
- eo = pmatch[0].rm_eo;
- }
-else
- {
- so = 0;
- eo = strlen(string);
- }
-
-rc = pcre_exec((const pcre *)preg->re_pcre, NULL, string + so, (eo - so),
- 0, options, ovector, nmatch * 3);
-
-if (rc == 0) rc = nmatch; /* All captured slots were filled in */
-
-if (rc >= 0)
- {
- size_t i;
- if (!nosub)
- {
- for (i = 0; i < (size_t)rc; i++)
- {
- pmatch[i].rm_so = ovector[i*2];
- pmatch[i].rm_eo = ovector[i*2+1];
- }
- if (allocated_ovector) free(ovector);
- for (; i < nmatch; i++) pmatch[i].rm_so = pmatch[i].rm_eo = -1;
- }
- return 0;
- }
-
-else
- {
- if (allocated_ovector) free(ovector);
- switch(rc)
- {
- case PCRE_ERROR_NOMATCH: return REG_NOMATCH;
- case PCRE_ERROR_NULL: return REG_INVARG;
- case PCRE_ERROR_BADOPTION: return REG_INVARG;
- case PCRE_ERROR_BADMAGIC: return REG_INVARG;
- case PCRE_ERROR_UNKNOWN_NODE: return REG_ASSERT;
- case PCRE_ERROR_NOMEMORY: return REG_ESPACE;
- case PCRE_ERROR_MATCHLIMIT: return REG_ESPACE;
- case PCRE_ERROR_BADUTF8: return REG_INVARG;
- case PCRE_ERROR_BADUTF8_OFFSET: return REG_INVARG;
- default: return REG_ASSERT;
- }
- }
-}
-
-/* End of pcreposix.c */
diff --git a/crawl-ref/source/util/pcre/pcreposix.h b/crawl-ref/source/util/pcre/pcreposix.h
deleted file mode 100644
index a73ad261de..0000000000
--- a/crawl-ref/source/util/pcre/pcreposix.h
+++ /dev/null
@@ -1,143 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-#ifndef _PCREPOSIX_H
-#define _PCREPOSIX_H
-
-/* This is the header for the POSIX wrapper interface to the PCRE Perl-
-Compatible Regular Expression library. It defines the things POSIX says should
-be there. I hope.
-
- Copyright (c) 1997-2008 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-/* Have to include stdlib.h in order to ensure that size_t is defined. */
-
-#include <stdlib.h>
-
-/* Allow for C++ users */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Options, mostly defined by POSIX, but with a couple of extras. */
-
-#define REG_ICASE 0x0001
-#define REG_NEWLINE 0x0002
-#define REG_NOTBOL 0x0004
-#define REG_NOTEOL 0x0008
-#define REG_DOTALL 0x0010 /* NOT defined by POSIX. */
-#define REG_NOSUB 0x0020
-#define REG_UTF8 0x0040 /* NOT defined by POSIX. */
-#define REG_STARTEND 0x0080 /* BSD feature: pass subject string by so,eo */
-
-/* This is not used by PCRE, but by defining it we make it easier
-to slot PCRE into existing programs that make POSIX calls. */
-
-#define REG_EXTENDED 0
-
-/* Error values. Not all these are relevant or used by the wrapper. */
-
-enum {
- REG_ASSERT = 1, /* internal error ? */
- REG_BADBR, /* invalid repeat counts in {} */
- REG_BADPAT, /* pattern error */
- REG_BADRPT, /* ? * + invalid */
- REG_EBRACE, /* unbalanced {} */
- REG_EBRACK, /* unbalanced [] */
- REG_ECOLLATE, /* collation error - not relevant */
- REG_ECTYPE, /* bad class */
- REG_EESCAPE, /* bad escape sequence */
- REG_EMPTY, /* empty expression */
- REG_EPAREN, /* unbalanced () */
- REG_ERANGE, /* bad range inside [] */
- REG_ESIZE, /* expression too big */
- REG_ESPACE, /* failed to get memory */
- REG_ESUBREG, /* bad back reference */
- REG_INVARG, /* bad argument */
- REG_NOMATCH /* match failed */
-};
-
-
-/* The structure representing a compiled regular expression. */
-
-typedef struct {
- void *re_pcre;
- size_t re_nsub;
- size_t re_erroffset;
-} regex_t;
-
-/* The structure in which a captured offset is returned. */
-
-typedef int regoff_t;
-
-typedef struct {
- regoff_t rm_so;
- regoff_t rm_eo;
-} regmatch_t;
-
-/* When an application links to a PCRE DLL in Windows, the symbols that are
-imported have to be identified as such. When building PCRE, the appropriate
-export settings are needed, and are set in pcreposix.c before including this
-file. */
-
-#if defined(_WIN32) && !defined(PCRE_STATIC) && !defined(PCREPOSIX_EXP_DECL)
-# define PCREPOSIX_EXP_DECL extern __declspec(dllimport)
-# define PCREPOSIX_EXP_DEFN __declspec(dllimport)
-#endif
-
-/* By default, we use the standard "extern" declarations. */
-
-#ifndef PCREPOSIX_EXP_DECL
-# ifdef __cplusplus
-# define PCREPOSIX_EXP_DECL extern "C"
-# define PCREPOSIX_EXP_DEFN extern "C"
-# else
-# define PCREPOSIX_EXP_DECL extern
-# define PCREPOSIX_EXP_DEFN extern
-# endif
-#endif
-
-/* The functions */
-
-PCREPOSIX_EXP_DECL int regcomp(regex_t *, const char *, int);
-PCREPOSIX_EXP_DECL int regexec(const regex_t *, const char *, size_t,
- regmatch_t *, int);
-PCREPOSIX_EXP_DECL size_t regerror(int, const regex_t *, char *, size_t);
-PCREPOSIX_EXP_DECL void regfree(regex_t *);
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif /* End of pcreposix.h */
diff --git a/crawl-ref/source/util/pcre/pcretest.c b/crawl-ref/source/util/pcre/pcretest.c
deleted file mode 100644
index b2998a5891..0000000000
--- a/crawl-ref/source/util/pcre/pcretest.c
+++ /dev/null
@@ -1,2448 +0,0 @@
-/*************************************************
-* PCRE testing program *
-*************************************************/
-
-/* This program was hacked up as a tester for PCRE. I really should have
-written it more tidily in the first place. Will I ever learn? It has grown and
-been extended and consequently is now rather, er, *very* untidy in places.
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <ctype.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <time.h>
-#include <locale.h>
-#include <errno.h>
-
-#ifdef SUPPORT_LIBREADLINE
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#include <readline/readline.h>
-#include <readline/history.h>
-#endif
-
-
-/* A number of things vary for Windows builds. Originally, pcretest opened its
-input and output without "b"; then I was told that "b" was needed in some
-environments, so it was added for release 5.0 to both the input and output. (It
-makes no difference on Unix-like systems.) Later I was told that it is wrong
-for the input on Windows. I've now abstracted the modes into two macros that
-are set here, to make it easier to fiddle with them, and removed "b" from the
-input mode under Windows. */
-
-#if defined(_WIN32) || defined(WIN32)
-#include <io.h> /* For _setmode() */
-#include <fcntl.h> /* For _O_BINARY */
-#define INPUT_MODE "r"
-#define OUTPUT_MODE "wb"
-
-#define isatty _isatty /* This is what Windows calls them, I'm told */
-#define fileno _fileno
-
-#else
-#include <sys/time.h> /* These two includes are needed */
-#include <sys/resource.h> /* for setrlimit(). */
-#define INPUT_MODE "rb"
-#define OUTPUT_MODE "wb"
-#endif
-
-
-/* We have to include pcre_internal.h because we need the internal info for
-displaying the results of pcre_study() and we also need to know about the
-internal macros, structures, and other internal data values; pcretest has
-"inside information" compared to a program that strictly follows the PCRE API.
-
-Although pcre_internal.h does itself include pcre.h, we explicitly include it
-here before pcre_internal.h so that the PCRE_EXP_xxx macros get set
-appropriately for an application, not for building PCRE. */
-
-#include "pcre.h"
-#include "pcre_internal.h"
-
-/* We need access to the data tables that PCRE uses. So as not to have to keep
-two copies, we include the source file here, changing the names of the external
-symbols to prevent clashes. */
-
-#define _pcre_utf8_table1 utf8_table1
-#define _pcre_utf8_table1_size utf8_table1_size
-#define _pcre_utf8_table2 utf8_table2
-#define _pcre_utf8_table3 utf8_table3
-#define _pcre_utf8_table4 utf8_table4
-#define _pcre_utt utt
-#define _pcre_utt_size utt_size
-#define _pcre_utt_names utt_names
-#define _pcre_OP_lengths OP_lengths
-
-#include "pcre_tables.c"
-
-/* We also need the pcre_printint() function for printing out compiled
-patterns. This function is in a separate file so that it can be included in
-pcre_compile.c when that module is compiled with debugging enabled.
-
-The definition of the macro PRINTABLE, which determines whether to print an
-output character as-is or as a hex value when showing compiled patterns, is
-contained in this file. We uses it here also, in cases when the locale has not
-been explicitly changed, so as to get consistent output from systems that
-differ in their output from isprint() even in the "C" locale. */
-
-#include "pcre_printint.src"
-
-#define PRINTHEX(c) (locale_set? isprint(c) : PRINTABLE(c))
-
-
-/* It is possible to compile this test program without including support for
-testing the POSIX interface, though this is not available via the standard
-Makefile. */
-
-#if !defined NOPOSIX
-#include "pcreposix.h"
-#endif
-
-/* It is also possible, for the benefit of the version currently imported into
-Exim, to build pcretest without support for UTF8 (define NOUTF8), without the
-interface to the DFA matcher (NODFA), and without the doublecheck of the old
-"info" function (define NOINFOCHECK). In fact, we automatically cut out the
-UTF8 support if PCRE is built without it. */
-
-#ifndef SUPPORT_UTF8
-#ifndef NOUTF8
-#define NOUTF8
-#endif
-#endif
-
-
-/* Other parameters */
-
-#ifndef CLOCKS_PER_SEC
-#ifdef CLK_TCK
-#define CLOCKS_PER_SEC CLK_TCK
-#else
-#define CLOCKS_PER_SEC 100
-#endif
-#endif
-
-/* This is the default loop count for timing. */
-
-#define LOOPREPEAT 500000
-
-/* Static variables */
-
-static FILE *outfile;
-static int log_store = 0;
-static int callout_count;
-static int callout_extra;
-static int callout_fail_count;
-static int callout_fail_id;
-static int debug_lengths;
-static int first_callout;
-static int locale_set = 0;
-static int show_malloc;
-static int use_utf8;
-static size_t gotten_store;
-
-/* The buffers grow automatically if very long input lines are encountered. */
-
-static int buffer_size = 50000;
-static uschar *buffer = NULL;
-static uschar *dbuffer = NULL;
-static uschar *pbuffer = NULL;
-
-
-
-/*************************************************
-* Read or extend an input line *
-*************************************************/
-
-/* Input lines are read into buffer, but both patterns and data lines can be
-continued over multiple input lines. In addition, if the buffer fills up, we
-want to automatically expand it so as to be able to handle extremely large
-lines that are needed for certain stress tests. When the input buffer is
-expanded, the other two buffers must also be expanded likewise, and the
-contents of pbuffer, which are a copy of the input for callouts, must be
-preserved (for when expansion happens for a data line). This is not the most
-optimal way of handling this, but hey, this is just a test program!
-
-Arguments:
- f the file to read
- start where in buffer to start (this *must* be within buffer)
- prompt for stdin or readline()
-
-Returns: pointer to the start of new data
- could be a copy of start, or could be moved
- NULL if no data read and EOF reached
-*/
-
-static uschar *
-extend_inputline(FILE *f, uschar *start, const char *prompt)
-{
-uschar *here = start;
-
-for (;;)
- {
- int rlen = buffer_size - (here - buffer);
-
- if (rlen > 1000)
- {
- int dlen;
-
- /* If libreadline support is required, use readline() to read a line if the
- input is a terminal. Note that readline() removes the trailing newline, so
- we must put it back again, to be compatible with fgets(). */
-
-#ifdef SUPPORT_LIBREADLINE
- if (isatty(fileno(f)))
- {
- size_t len;
- char *s = readline(prompt);
- if (s == NULL) return (here == start)? NULL : start;
- len = strlen(s);
- if (len > 0) add_history(s);
- if (len > rlen - 1) len = rlen - 1;
- memcpy(here, s, len);
- here[len] = '\n';
- here[len+1] = 0;
- free(s);
- }
- else
-#endif
-
- /* Read the next line by normal means, prompting if the file is stdin. */
-
- {
- if (f == stdin) printf(prompt);
- if (fgets((char *)here, rlen, f) == NULL)
- return (here == start)? NULL : start;
- }
-
- dlen = (int)strlen((char *)here);
- if (dlen > 0 && here[dlen - 1] == '\n') return start;
- here += dlen;
- }
-
- else
- {
- int new_buffer_size = 2*buffer_size;
- uschar *new_buffer = (unsigned char *)malloc(new_buffer_size);
- uschar *new_dbuffer = (unsigned char *)malloc(new_buffer_size);
- uschar *new_pbuffer = (unsigned char *)malloc(new_buffer_size);
-
- if (new_buffer == NULL || new_dbuffer == NULL || new_pbuffer == NULL)
- {
- fprintf(stderr, "pcretest: malloc(%d) failed\n", new_buffer_size);
- exit(1);
- }
-
- memcpy(new_buffer, buffer, buffer_size);
- memcpy(new_pbuffer, pbuffer, buffer_size);
-
- buffer_size = new_buffer_size;
-
- start = new_buffer + (start - buffer);
- here = new_buffer + (here - buffer);
-
- free(buffer);
- free(dbuffer);
- free(pbuffer);
-
- buffer = new_buffer;
- dbuffer = new_dbuffer;
- pbuffer = new_pbuffer;
- }
- }
-
-return NULL; /* Control never gets here */
-}
-
-
-
-
-
-
-
-/*************************************************
-* Read number from string *
-*************************************************/
-
-/* We don't use strtoul() because SunOS4 doesn't have it. Rather than mess
-around with conditional compilation, just do the job by hand. It is only used
-for unpicking arguments, so just keep it simple.
-
-Arguments:
- str string to be converted
- endptr where to put the end pointer
-
-Returns: the unsigned long
-*/
-
-static int
-get_value(unsigned char *str, unsigned char **endptr)
-{
-int result = 0;
-while(*str != 0 && isspace(*str)) str++;
-while (isdigit(*str)) result = result * 10 + (int)(*str++ - '0');
-*endptr = str;
-return(result);
-}
-
-
-
-
-/*************************************************
-* Convert UTF-8 string to value *
-*************************************************/
-
-/* This function takes one or more bytes that represents a UTF-8 character,
-and returns the value of the character.
-
-Argument:
- utf8bytes a pointer to the byte vector
- vptr a pointer to an int to receive the value
-
-Returns: > 0 => the number of bytes consumed
- -6 to 0 => malformed UTF-8 character at offset = (-return)
-*/
-
-#if !defined NOUTF8
-
-static int
-utf82ord(unsigned char *utf8bytes, int *vptr)
-{
-int c = *utf8bytes++;
-int d = c;
-int i, j, s;
-
-for (i = -1; i < 6; i++) /* i is number of additional bytes */
- {
- if ((d & 0x80) == 0) break;
- d <<= 1;
- }
-
-if (i == -1) { *vptr = c; return 1; } /* ascii character */
-if (i == 0 || i == 6) return 0; /* invalid UTF-8 */
-
-/* i now has a value in the range 1-5 */
-
-s = 6*i;
-d = (c & utf8_table3[i]) << s;
-
-for (j = 0; j < i; j++)
- {
- c = *utf8bytes++;
- if ((c & 0xc0) != 0x80) return -(j+1);
- s -= 6;
- d |= (c & 0x3f) << s;
- }
-
-/* Check that encoding was the correct unique one */
-
-for (j = 0; j < utf8_table1_size; j++)
- if (d <= utf8_table1[j]) break;
-if (j != i) return -(i+1);
-
-/* Valid value */
-
-*vptr = d;
-return i+1;
-}
-
-#endif
-
-
-
-/*************************************************
-* Convert character value to UTF-8 *
-*************************************************/
-
-/* This function takes an integer value in the range 0 - 0x7fffffff
-and encodes it as a UTF-8 character in 0 to 6 bytes.
-
-Arguments:
- cvalue the character value
- utf8bytes pointer to buffer for result - at least 6 bytes long
-
-Returns: number of characters placed in the buffer
-*/
-
-#if !defined NOUTF8
-
-static int
-ord2utf8(int cvalue, uschar *utf8bytes)
-{
-register int i, j;
-for (i = 0; i < utf8_table1_size; i++)
- if (cvalue <= utf8_table1[i]) break;
-utf8bytes += i;
-for (j = i; j > 0; j--)
- {
- *utf8bytes-- = 0x80 | (cvalue & 0x3f);
- cvalue >>= 6;
- }
-*utf8bytes = utf8_table2[i] | cvalue;
-return i + 1;
-}
-
-#endif
-
-
-
-/*************************************************
-* Print character string *
-*************************************************/
-
-/* Character string printing function. Must handle UTF-8 strings in utf8
-mode. Yields number of characters printed. If handed a NULL file, just counts
-chars without printing. */
-
-static int pchars(unsigned char *p, int length, FILE *f)
-{
-int c = 0;
-int yield = 0;
-
-while (length-- > 0)
- {
-#if !defined NOUTF8
- if (use_utf8)
- {
- int rc = utf82ord(p, &c);
-
- if (rc > 0 && rc <= length + 1) /* Mustn't run over the end */
- {
- length -= rc - 1;
- p += rc;
- if (PRINTHEX(c))
- {
- if (f != NULL) fprintf(f, "%c", c);
- yield++;
- }
- else
- {
- int n = 4;
- if (f != NULL) fprintf(f, "\\x{%02x}", c);
- yield += (n <= 0x000000ff)? 2 :
- (n <= 0x00000fff)? 3 :
- (n <= 0x0000ffff)? 4 :
- (n <= 0x000fffff)? 5 : 6;
- }
- continue;
- }
- }
-#endif
-
- /* Not UTF-8, or malformed UTF-8 */
-
- c = *p++;
- if (PRINTHEX(c))
- {
- if (f != NULL) fprintf(f, "%c", c);
- yield++;
- }
- else
- {
- if (f != NULL) fprintf(f, "\\x%02x", c);
- yield += 4;
- }
- }
-
-return yield;
-}
-
-
-
-/*************************************************
-* Callout function *
-*************************************************/
-
-/* Called from PCRE as a result of the (?C) item. We print out where we are in
-the match. Yield zero unless more callouts than the fail count, or the callout
-data is not zero. */
-
-static int callout(pcre_callout_block *cb)
-{
-FILE *f = (first_callout | callout_extra)? outfile : NULL;
-int i, pre_start, post_start, subject_length;
-
-if (callout_extra)
- {
- fprintf(f, "Callout %d: last capture = %d\n",
- cb->callout_number, cb->capture_last);
-
- for (i = 0; i < cb->capture_top * 2; i += 2)
- {
- if (cb->offset_vector[i] < 0)
- fprintf(f, "%2d: <unset>\n", i/2);
- else
- {
- fprintf(f, "%2d: ", i/2);
- (void)pchars((unsigned char *)cb->subject + cb->offset_vector[i],
- cb->offset_vector[i+1] - cb->offset_vector[i], f);
- fprintf(f, "\n");
- }
- }
- }
-
-/* Re-print the subject in canonical form, the first time or if giving full
-datails. On subsequent calls in the same match, we use pchars just to find the
-printed lengths of the substrings. */
-
-if (f != NULL) fprintf(f, "--->");
-
-pre_start = pchars((unsigned char *)cb->subject, cb->start_match, f);
-post_start = pchars((unsigned char *)(cb->subject + cb->start_match),
- cb->current_position - cb->start_match, f);
-
-subject_length = pchars((unsigned char *)cb->subject, cb->subject_length, NULL);
-
-(void)pchars((unsigned char *)(cb->subject + cb->current_position),
- cb->subject_length - cb->current_position, f);
-
-if (f != NULL) fprintf(f, "\n");
-
-/* Always print appropriate indicators, with callout number if not already
-shown. For automatic callouts, show the pattern offset. */
-
-if (cb->callout_number == 255)
- {
- fprintf(outfile, "%+3d ", cb->pattern_position);
- if (cb->pattern_position > 99) fprintf(outfile, "\n ");
- }
-else
- {
- if (callout_extra) fprintf(outfile, " ");
- else fprintf(outfile, "%3d ", cb->callout_number);
- }
-
-for (i = 0; i < pre_start; i++) fprintf(outfile, " ");
-fprintf(outfile, "^");
-
-if (post_start > 0)
- {
- for (i = 0; i < post_start - 1; i++) fprintf(outfile, " ");
- fprintf(outfile, "^");
- }
-
-for (i = 0; i < subject_length - pre_start - post_start + 4; i++)
- fprintf(outfile, " ");
-
-fprintf(outfile, "%.*s", (cb->next_item_length == 0)? 1 : cb->next_item_length,
- pbuffer + cb->pattern_position);
-
-fprintf(outfile, "\n");
-first_callout = 0;
-
-if (cb->callout_data != NULL)
- {
- int callout_data = *((int *)(cb->callout_data));
- if (callout_data != 0)
- {
- fprintf(outfile, "Callout data = %d\n", callout_data);
- return callout_data;
- }
- }
-
-return (cb->callout_number != callout_fail_id)? 0 :
- (++callout_count >= callout_fail_count)? 1 : 0;
-}
-
-
-/*************************************************
-* Local malloc functions *
-*************************************************/
-
-/* Alternative malloc function, to test functionality and show the size of the
-compiled re. */
-
-static void *new_malloc(size_t size)
-{
-void *block = malloc(size);
-gotten_store = size;
-if (show_malloc)
- fprintf(outfile, "malloc %3d %p\n", (int)size, block);
-return block;
-}
-
-static void new_free(void *block)
-{
-if (show_malloc)
- fprintf(outfile, "free %p\n", block);
-free(block);
-}
-
-
-/* For recursion malloc/free, to test stacking calls */
-
-static void *stack_malloc(size_t size)
-{
-void *block = malloc(size);
-if (show_malloc)
- fprintf(outfile, "stack_malloc %3d %p\n", (int)size, block);
-return block;
-}
-
-static void stack_free(void *block)
-{
-if (show_malloc)
- fprintf(outfile, "stack_free %p\n", block);
-free(block);
-}
-
-
-/*************************************************
-* Call pcre_fullinfo() *
-*************************************************/
-
-/* Get one piece of information from the pcre_fullinfo() function */
-
-static void new_info(pcre *re, pcre_extra *study, int option, void *ptr)
-{
-int rc;
-if ((rc = pcre_fullinfo(re, study, option, ptr)) < 0)
- fprintf(outfile, "Error %d from pcre_fullinfo(%d)\n", rc, option);
-}
-
-
-
-/*************************************************
-* Byte flipping function *
-*************************************************/
-
-static unsigned long int
-byteflip(unsigned long int value, int n)
-{
-if (n == 2) return ((value & 0x00ff) << 8) | ((value & 0xff00) >> 8);
-return ((value & 0x000000ff) << 24) |
- ((value & 0x0000ff00) << 8) |
- ((value & 0x00ff0000) >> 8) |
- ((value & 0xff000000) >> 24);
-}
-
-
-
-
-/*************************************************
-* Check match or recursion limit *
-*************************************************/
-
-static int
-check_match_limit(pcre *re, pcre_extra *extra, uschar *bptr, int len,
- int start_offset, int options, int *use_offsets, int use_size_offsets,
- int flag, unsigned long int *limit, int errnumber, const char *msg)
-{
-int count;
-int min = 0;
-int mid = 64;
-int max = -1;
-
-extra->flags |= flag;
-
-for (;;)
- {
- *limit = mid;
-
- count = pcre_exec(re, extra, (char *)bptr, len, start_offset, options,
- use_offsets, use_size_offsets);
-
- if (count == errnumber)
- {
- /* fprintf(outfile, "Testing %s limit = %d\n", msg, mid); */
- min = mid;
- mid = (mid == max - 1)? max : (max > 0)? (min + max)/2 : mid*2;
- }
-
- else if (count >= 0 || count == PCRE_ERROR_NOMATCH ||
- count == PCRE_ERROR_PARTIAL)
- {
- if (mid == min + 1)
- {
- fprintf(outfile, "Minimum %s limit = %d\n", msg, mid);
- break;
- }
- /* fprintf(outfile, "Testing %s limit = %d\n", msg, mid); */
- max = mid;
- mid = (min + mid)/2;
- }
- else break; /* Some other error */
- }
-
-extra->flags &= ~flag;
-return count;
-}
-
-
-
-/*************************************************
-* Case-independent strncmp() function *
-*************************************************/
-
-/*
-Arguments:
- s first string
- t second string
- n number of characters to compare
-
-Returns: < 0, = 0, or > 0, according to the comparison
-*/
-
-static int
-strncmpic(uschar *s, uschar *t, int n)
-{
-while (n--)
- {
- int c = tolower(*s++) - tolower(*t++);
- if (c) return c;
- }
-return 0;
-}
-
-
-
-/*************************************************
-* Check newline indicator *
-*************************************************/
-
-/* This is used both at compile and run-time to check for <xxx> escapes, where
-xxx is LF, CR, CRLF, ANYCRLF, or ANY. Print a message and return 0 if there is
-no match.
-
-Arguments:
- p points after the leading '<'
- f file for error message
-
-Returns: appropriate PCRE_NEWLINE_xxx flags, or 0
-*/
-
-static int
-check_newline(uschar *p, FILE *f)
-{
-if (strncmpic(p, (uschar *)"cr>", 3) == 0) return PCRE_NEWLINE_CR;
-if (strncmpic(p, (uschar *)"lf>", 3) == 0) return PCRE_NEWLINE_LF;
-if (strncmpic(p, (uschar *)"crlf>", 5) == 0) return PCRE_NEWLINE_CRLF;
-if (strncmpic(p, (uschar *)"anycrlf>", 8) == 0) return PCRE_NEWLINE_ANYCRLF;
-if (strncmpic(p, (uschar *)"any>", 4) == 0) return PCRE_NEWLINE_ANY;
-if (strncmpic(p, (uschar *)"bsr_anycrlf>", 12) == 0) return PCRE_BSR_ANYCRLF;
-if (strncmpic(p, (uschar *)"bsr_unicode>", 12) == 0) return PCRE_BSR_UNICODE;
-fprintf(f, "Unknown newline type at: <%s\n", p);
-return 0;
-}
-
-
-
-/*************************************************
-* Usage function *
-*************************************************/
-
-static void
-usage(void)
-{
-printf("Usage: pcretest [options] [<input file> [<output file>]]\n\n");
-printf("Input and output default to stdin and stdout.\n");
-#ifdef SUPPORT_LIBREADLINE
-printf("If input is a terminal, readline() is used to read from it.\n");
-#else
-printf("This version of pcretest is not linked with readline().\n");
-#endif
-printf("\nOptions:\n");
-printf(" -b show compiled code (bytecode)\n");
-printf(" -C show PCRE compile-time options and exit\n");
-printf(" -d debug: show compiled code and information (-b and -i)\n");
-#if !defined NODFA
-printf(" -dfa force DFA matching for all subjects\n");
-#endif
-printf(" -help show usage information\n");
-printf(" -i show information about compiled patterns\n"
- " -m output memory used information\n"
- " -o <n> set size of offsets vector to <n>\n");
-#if !defined NOPOSIX
-printf(" -p use POSIX interface\n");
-#endif
-printf(" -q quiet: do not output PCRE version number at start\n");
-printf(" -S <n> set stack size to <n> megabytes\n");
-printf(" -s output store (memory) used information\n"
- " -t time compilation and execution\n");
-printf(" -t <n> time compilation and execution, repeating <n> times\n");
-printf(" -tm time execution (matching) only\n");
-printf(" -tm <n> time execution (matching) only, repeating <n> times\n");
-}
-
-
-
-/*************************************************
-* Main Program *
-*************************************************/
-
-/* Read lines from named file or stdin and write to named file or stdout; lines
-consist of a regular expression, in delimiters and optionally followed by
-options, followed by a set of test data, terminated by an empty line. */
-
-int main(int argc, char **argv)
-{
-FILE *infile = stdin;
-int options = 0;
-int study_options = 0;
-int op = 1;
-int timeit = 0;
-int timeitm = 0;
-int showinfo = 0;
-int showstore = 0;
-int quiet = 0;
-int size_offsets = 45;
-int size_offsets_max;
-int *offsets = NULL;
-#if !defined NOPOSIX
-int posix = 0;
-#endif
-int debug = 0;
-int done = 0;
-int all_use_dfa = 0;
-int yield = 0;
-int stack_size;
-
-/* These vectors store, end-to-end, a list of captured substring names. Assume
-that 1024 is plenty long enough for the few names we'll be testing. */
-
-uschar copynames[1024];
-uschar getnames[1024];
-
-uschar *copynamesptr;
-uschar *getnamesptr;
-
-/* Get buffers from malloc() so that Electric Fence will check their misuse
-when I am debugging. They grow automatically when very long lines are read. */
-
-buffer = (unsigned char *)malloc(buffer_size);
-dbuffer = (unsigned char *)malloc(buffer_size);
-pbuffer = (unsigned char *)malloc(buffer_size);
-
-/* The outfile variable is static so that new_malloc can use it. */
-
-outfile = stdout;
-
-/* The following _setmode() stuff is some Windows magic that tells its runtime
-library to translate CRLF into a single LF character. At least, that's what
-I've been told: never having used Windows I take this all on trust. Originally
-it set 0x8000, but then I was advised that _O_BINARY was better. */
-
-#if defined(_WIN32) || defined(WIN32)
-_setmode( _fileno( stdout ), _O_BINARY );
-#endif
-
-/* Scan options */
-
-while (argc > 1 && argv[op][0] == '-')
- {
- unsigned char *endptr;
-
- if (strcmp(argv[op], "-s") == 0 || strcmp(argv[op], "-m") == 0)
- showstore = 1;
- else if (strcmp(argv[op], "-q") == 0) quiet = 1;
- else if (strcmp(argv[op], "-b") == 0) debug = 1;
- else if (strcmp(argv[op], "-i") == 0) showinfo = 1;
- else if (strcmp(argv[op], "-d") == 0) showinfo = debug = 1;
-#if !defined NODFA
- else if (strcmp(argv[op], "-dfa") == 0) all_use_dfa = 1;
-#endif
- else if (strcmp(argv[op], "-o") == 0 && argc > 2 &&
- ((size_offsets = get_value((unsigned char *)argv[op+1], &endptr)),
- *endptr == 0))
- {
- op++;
- argc--;
- }
- else if (strcmp(argv[op], "-t") == 0 || strcmp(argv[op], "-tm") == 0)
- {
- int both = argv[op][2] == 0;
- int temp;
- if (argc > 2 && (temp = get_value((unsigned char *)argv[op+1], &endptr),
- *endptr == 0))
- {
- timeitm = temp;
- op++;
- argc--;
- }
- else timeitm = LOOPREPEAT;
- if (both) timeit = timeitm;
- }
- else if (strcmp(argv[op], "-S") == 0 && argc > 2 &&
- ((stack_size = get_value((unsigned char *)argv[op+1], &endptr)),
- *endptr == 0))
- {
-#if defined(_WIN32) || defined(WIN32)
- printf("PCRE: -S not supported on this OS\n");
- exit(1);
-#else
- int rc;
- struct rlimit rlim;
- getrlimit(RLIMIT_STACK, &rlim);
- rlim.rlim_cur = stack_size * 1024 * 1024;
- rc = setrlimit(RLIMIT_STACK, &rlim);
- if (rc != 0)
- {
- printf("PCRE: setrlimit() failed with error %d\n", rc);
- exit(1);
- }
- op++;
- argc--;
-#endif
- }
-#if !defined NOPOSIX
- else if (strcmp(argv[op], "-p") == 0) posix = 1;
-#endif
- else if (strcmp(argv[op], "-C") == 0)
- {
- int rc;
- printf("PCRE version %s\n", pcre_version());
- printf("Compiled with\n");
- (void)pcre_config(PCRE_CONFIG_UTF8, &rc);
- printf(" %sUTF-8 support\n", rc? "" : "No ");
- (void)pcre_config(PCRE_CONFIG_UNICODE_PROPERTIES, &rc);
- printf(" %sUnicode properties support\n", rc? "" : "No ");
- (void)pcre_config(PCRE_CONFIG_NEWLINE, &rc);
- printf(" Newline sequence is %s\n", (rc == '\r')? "CR" :
- (rc == '\n')? "LF" : (rc == ('\r'<<8 | '\n'))? "CRLF" :
- (rc == -2)? "ANYCRLF" :
- (rc == -1)? "ANY" : "???");
- (void)pcre_config(PCRE_CONFIG_BSR, &rc);
- printf(" \\R matches %s\n", rc? "CR, LF, or CRLF only" :
- "all Unicode newlines");
- (void)pcre_config(PCRE_CONFIG_LINK_SIZE, &rc);
- printf(" Internal link size = %d\n", rc);
- (void)pcre_config(PCRE_CONFIG_POSIX_MALLOC_THRESHOLD, &rc);
- printf(" POSIX malloc threshold = %d\n", rc);
- (void)pcre_config(PCRE_CONFIG_MATCH_LIMIT, &rc);
- printf(" Default match limit = %d\n", rc);
- (void)pcre_config(PCRE_CONFIG_MATCH_LIMIT_RECURSION, &rc);
- printf(" Default recursion depth limit = %d\n", rc);
- (void)pcre_config(PCRE_CONFIG_STACKRECURSE, &rc);
- printf(" Match recursion uses %s\n", rc? "stack" : "heap");
- goto EXIT;
- }
- else if (strcmp(argv[op], "-help") == 0 ||
- strcmp(argv[op], "--help") == 0)
- {
- usage();
- goto EXIT;
- }
- else
- {
- printf("** Unknown or malformed option %s\n", argv[op]);
- usage();
- yield = 1;
- goto EXIT;
- }
- op++;
- argc--;
- }
-
-/* Get the store for the offsets vector, and remember what it was */
-
-size_offsets_max = size_offsets;
-offsets = (int *)malloc(size_offsets_max * sizeof(int));
-if (offsets == NULL)
- {
- printf("** Failed to get %d bytes of memory for offsets vector\n",
- (int)(size_offsets_max * sizeof(int)));
- yield = 1;
- goto EXIT;
- }
-
-/* Sort out the input and output files */
-
-if (argc > 1)
- {
- infile = fopen(argv[op], INPUT_MODE);
- if (infile == NULL)
- {
- printf("** Failed to open %s\n", argv[op]);
- yield = 1;
- goto EXIT;
- }
- }
-
-if (argc > 2)
- {
- outfile = fopen(argv[op+1], OUTPUT_MODE);
- if (outfile == NULL)
- {
- printf("** Failed to open %s\n", argv[op+1]);
- yield = 1;
- goto EXIT;
- }
- }
-
-/* Set alternative malloc function */
-
-pcre_malloc = new_malloc;
-pcre_free = new_free;
-pcre_stack_malloc = stack_malloc;
-pcre_stack_free = stack_free;
-
-/* Heading line unless quiet, then prompt for first regex if stdin */
-
-if (!quiet) fprintf(outfile, "PCRE version %s\n\n", pcre_version());
-
-/* Main loop */
-
-while (!done)
- {
- pcre *re = NULL;
- pcre_extra *extra = NULL;
-
-#if !defined NOPOSIX /* There are still compilers that require no indent */
- regex_t preg;
- int do_posix = 0;
-#endif
-
- const char *error;
- unsigned char *p, *pp, *ppp;
- unsigned char *to_file = NULL;
- const unsigned char *tables = NULL;
- unsigned long int true_size, true_study_size = 0;
- size_t size, regex_gotten_store;
- int do_study = 0;
- int do_debug = debug;
- int do_G = 0;
- int do_g = 0;
- int do_showinfo = showinfo;
- int do_showrest = 0;
- int do_flip = 0;
- int erroroffset, len, delimiter, poffset;
-
- use_utf8 = 0;
- debug_lengths = 1;
-
- if (extend_inputline(infile, buffer, " re> ") == NULL) break;
- if (infile != stdin) fprintf(outfile, "%s", (char *)buffer);
- fflush(outfile);
-
- p = buffer;
- while (isspace(*p)) p++;
- if (*p == 0) continue;
-
- /* See if the pattern is to be loaded pre-compiled from a file. */
-
- if (*p == '<' && strchr((char *)(p+1), '<') == NULL)
- {
- unsigned long int magic, get_options;
- uschar sbuf[8];
- FILE *f;
-
- p++;
- pp = p + (int)strlen((char *)p);
- while (isspace(pp[-1])) pp--;
- *pp = 0;
-
- f = fopen((char *)p, "rb");
- if (f == NULL)
- {
- fprintf(outfile, "Failed to open %s: %s\n", p, strerror(errno));
- continue;
- }
-
- if (fread(sbuf, 1, 8, f) != 8) goto FAIL_READ;
-
- true_size =
- (sbuf[0] << 24) | (sbuf[1] << 16) | (sbuf[2] << 8) | sbuf[3];
- true_study_size =
- (sbuf[4] << 24) | (sbuf[5] << 16) | (sbuf[6] << 8) | sbuf[7];
-
- re = (real_pcre *)new_malloc(true_size);
- regex_gotten_store = gotten_store;
-
- if (fread(re, 1, true_size, f) != true_size) goto FAIL_READ;
-
- magic = ((real_pcre *)re)->magic_number;
- if (magic != MAGIC_NUMBER)
- {
- if (byteflip(magic, sizeof(magic)) == MAGIC_NUMBER)
- {
- do_flip = 1;
- }
- else
- {
- fprintf(outfile, "Data in %s is not a compiled PCRE regex\n", p);
- fclose(f);
- continue;
- }
- }
-
- fprintf(outfile, "Compiled regex%s loaded from %s\n",
- do_flip? " (byte-inverted)" : "", p);
-
- /* Need to know if UTF-8 for printing data strings */
-
- new_info(re, NULL, PCRE_INFO_OPTIONS, &get_options);
- use_utf8 = (get_options & PCRE_UTF8) != 0;
-
- /* Now see if there is any following study data */
-
- if (true_study_size != 0)
- {
- pcre_study_data *psd;
-
- extra = (pcre_extra *)new_malloc(sizeof(pcre_extra) + true_study_size);
- extra->flags = PCRE_EXTRA_STUDY_DATA;
-
- psd = (pcre_study_data *)(((char *)extra) + sizeof(pcre_extra));
- extra->study_data = psd;
-
- if (fread(psd, 1, true_study_size, f) != true_study_size)
- {
- FAIL_READ:
- fprintf(outfile, "Failed to read data from %s\n", p);
- if (extra != NULL) new_free(extra);
- if (re != NULL) new_free(re);
- fclose(f);
- continue;
- }
- fprintf(outfile, "Study data loaded from %s\n", p);
- do_study = 1; /* To get the data output if requested */
- }
- else fprintf(outfile, "No study data\n");
-
- fclose(f);
- goto SHOW_INFO;
- }
-
- /* In-line pattern (the usual case). Get the delimiter and seek the end of
- the pattern; if is isn't complete, read more. */
-
- delimiter = *p++;
-
- if (isalnum(delimiter) || delimiter == '\\')
- {
- fprintf(outfile, "** Delimiter must not be alphanumeric or \\\n");
- goto SKIP_DATA;
- }
-
- pp = p;
- poffset = p - buffer;
-
- for(;;)
- {
- while (*pp != 0)
- {
- if (*pp == '\\' && pp[1] != 0) pp++;
- else if (*pp == delimiter) break;
- pp++;
- }
- if (*pp != 0) break;
- if ((pp = extend_inputline(infile, pp, " > ")) == NULL)
- {
- fprintf(outfile, "** Unexpected EOF\n");
- done = 1;
- goto CONTINUE;
- }
- if (infile != stdin) fprintf(outfile, "%s", (char *)pp);
- }
-
- /* The buffer may have moved while being extended; reset the start of data
- pointer to the correct relative point in the buffer. */
-
- p = buffer + poffset;
-
- /* If the first character after the delimiter is backslash, make
- the pattern end with backslash. This is purely to provide a way
- of testing for the error message when a pattern ends with backslash. */
-
- if (pp[1] == '\\') *pp++ = '\\';
-
- /* Terminate the pattern at the delimiter, and save a copy of the pattern
- for callouts. */
-
- *pp++ = 0;
- strcpy((char *)pbuffer, (char *)p);
-
- /* Look for options after final delimiter */
-
- options = 0;
- study_options = 0;
- log_store = showstore; /* default from command line */
-
- while (*pp != 0)
- {
- switch (*pp++)
- {
- case 'f': options |= PCRE_FIRSTLINE; break;
- case 'g': do_g = 1; break;
- case 'i': options |= PCRE_CASELESS; break;
- case 'm': options |= PCRE_MULTILINE; break;
- case 's': options |= PCRE_DOTALL; break;
- case 'x': options |= PCRE_EXTENDED; break;
-
- case '+': do_showrest = 1; break;
- case 'A': options |= PCRE_ANCHORED; break;
- case 'B': do_debug = 1; break;
- case 'C': options |= PCRE_AUTO_CALLOUT; break;
- case 'D': do_debug = do_showinfo = 1; break;
- case 'E': options |= PCRE_DOLLAR_ENDONLY; break;
- case 'F': do_flip = 1; break;
- case 'G': do_G = 1; break;
- case 'I': do_showinfo = 1; break;
- case 'J': options |= PCRE_DUPNAMES; break;
- case 'M': log_store = 1; break;
- case 'N': options |= PCRE_NO_AUTO_CAPTURE; break;
-
-#if !defined NOPOSIX
- case 'P': do_posix = 1; break;
-#endif
-
- case 'S': do_study = 1; break;
- case 'U': options |= PCRE_UNGREEDY; break;
- case 'X': options |= PCRE_EXTRA; break;
- case 'Z': debug_lengths = 0; break;
- case '8': options |= PCRE_UTF8; use_utf8 = 1; break;
- case '?': options |= PCRE_NO_UTF8_CHECK; break;
-
- case 'L':
- ppp = pp;
- /* The '\r' test here is so that it works on Windows. */
- /* The '0' test is just in case this is an unterminated line. */
- while (*ppp != 0 && *ppp != '\n' && *ppp != '\r' && *ppp != ' ') ppp++;
- *ppp = 0;
- if (setlocale(LC_CTYPE, (const char *)pp) == NULL)
- {
- fprintf(outfile, "** Failed to set locale \"%s\"\n", pp);
- goto SKIP_DATA;
- }
- locale_set = 1;
- tables = pcre_maketables();
- pp = ppp;
- break;
-
- case '>':
- to_file = pp;
- while (*pp != 0) pp++;
- while (isspace(pp[-1])) pp--;
- *pp = 0;
- break;
-
- case '<':
- {
- if (strncmp((char *)pp, "JS>", 3) == 0)
- {
- options |= PCRE_JAVASCRIPT_COMPAT;
- pp += 3;
- }
- else
- {
- int x = check_newline(pp, outfile);
- if (x == 0) goto SKIP_DATA;
- options |= x;
- while (*pp++ != '>');
- }
- }
- break;
-
- case '\r': /* So that it works in Windows */
- case '\n':
- case ' ':
- break;
-
- default:
- fprintf(outfile, "** Unknown option '%c'\n", pp[-1]);
- goto SKIP_DATA;
- }
- }
-
- /* Handle compiling via the POSIX interface, which doesn't support the
- timing, showing, or debugging options, nor the ability to pass over
- local character tables. */
-
-#if !defined NOPOSIX
- if (posix || do_posix)
- {
- int rc;
- int cflags = 0;
-
- if ((options & PCRE_CASELESS) != 0) cflags |= REG_ICASE;
- if ((options & PCRE_MULTILINE) != 0) cflags |= REG_NEWLINE;
- if ((options & PCRE_DOTALL) != 0) cflags |= REG_DOTALL;
- if ((options & PCRE_NO_AUTO_CAPTURE) != 0) cflags |= REG_NOSUB;
- if ((options & PCRE_UTF8) != 0) cflags |= REG_UTF8;
-
- rc = regcomp(&preg, (char *)p, cflags);
-
- /* Compilation failed; go back for another re, skipping to blank line
- if non-interactive. */
-
- if (rc != 0)
- {
- (void)regerror(rc, &preg, (char *)buffer, buffer_size);
- fprintf(outfile, "Failed: POSIX code %d: %s\n", rc, buffer);
- goto SKIP_DATA;
- }
- }
-
- /* Handle compiling via the native interface */
-
- else
-#endif /* !defined NOPOSIX */
-
- {
- if (timeit > 0)
- {
- register int i;
- clock_t time_taken;
- clock_t start_time = clock();
- for (i = 0; i < timeit; i++)
- {
- re = pcre_compile((char *)p, options, &error, &erroroffset, tables);
- if (re != NULL) free(re);
- }
- time_taken = clock() - start_time;
- fprintf(outfile, "Compile time %.4f milliseconds\n",
- (((double)time_taken * 1000.0) / (double)timeit) /
- (double)CLOCKS_PER_SEC);
- }
-
- re = pcre_compile((char *)p, options, &error, &erroroffset, tables);
-
- /* Compilation failed; go back for another re, skipping to blank line
- if non-interactive. */
-
- if (re == NULL)
- {
- fprintf(outfile, "Failed: %s at offset %d\n", error, erroroffset);
- SKIP_DATA:
- if (infile != stdin)
- {
- for (;;)
- {
- if (extend_inputline(infile, buffer, NULL) == NULL)
- {
- done = 1;
- goto CONTINUE;
- }
- len = (int)strlen((char *)buffer);
- while (len > 0 && isspace(buffer[len-1])) len--;
- if (len == 0) break;
- }
- fprintf(outfile, "\n");
- }
- goto CONTINUE;
- }
-
- /* Compilation succeeded; print data if required. There are now two
- info-returning functions. The old one has a limited interface and
- returns only limited data. Check that it agrees with the newer one. */
-
- if (log_store)
- fprintf(outfile, "Memory allocation (code space): %d\n",
- (int)(gotten_store -
- sizeof(real_pcre) -
- ((real_pcre *)re)->name_count * ((real_pcre *)re)->name_entry_size));
-
- /* Extract the size for possible writing before possibly flipping it,
- and remember the store that was got. */
-
- true_size = ((real_pcre *)re)->size;
- regex_gotten_store = gotten_store;
-
- /* If /S was present, study the regexp to generate additional info to
- help with the matching. */
-
- if (do_study)
- {
- if (timeit > 0)
- {
- register int i;
- clock_t time_taken;
- clock_t start_time = clock();
- for (i = 0; i < timeit; i++)
- extra = pcre_study(re, study_options, &error);
- time_taken = clock() - start_time;
- if (extra != NULL) free(extra);
- fprintf(outfile, " Study time %.4f milliseconds\n",
- (((double)time_taken * 1000.0) / (double)timeit) /
- (double)CLOCKS_PER_SEC);
- }
- extra = pcre_study(re, study_options, &error);
- if (error != NULL)
- fprintf(outfile, "Failed to study: %s\n", error);
- else if (extra != NULL)
- true_study_size = ((pcre_study_data *)(extra->study_data))->size;
- }
-
- /* If the 'F' option was present, we flip the bytes of all the integer
- fields in the regex data block and the study block. This is to make it
- possible to test PCRE's handling of byte-flipped patterns, e.g. those
- compiled on a different architecture. */
-
- if (do_flip)
- {
- real_pcre *rre = (real_pcre *)re;
- rre->magic_number =
- byteflip(rre->magic_number, sizeof(rre->magic_number));
- rre->size = byteflip(rre->size, sizeof(rre->size));
- rre->options = byteflip(rre->options, sizeof(rre->options));
- rre->flags = (pcre_uint16)byteflip(rre->flags, sizeof(rre->flags));
- rre->top_bracket =
- (pcre_uint16)byteflip(rre->top_bracket, sizeof(rre->top_bracket));
- rre->top_backref =
- (pcre_uint16)byteflip(rre->top_backref, sizeof(rre->top_backref));
- rre->first_byte =
- (pcre_uint16)byteflip(rre->first_byte, sizeof(rre->first_byte));
- rre->req_byte =
- (pcre_uint16)byteflip(rre->req_byte, sizeof(rre->req_byte));
- rre->name_table_offset = (pcre_uint16)byteflip(rre->name_table_offset,
- sizeof(rre->name_table_offset));
- rre->name_entry_size = (pcre_uint16)byteflip(rre->name_entry_size,
- sizeof(rre->name_entry_size));
- rre->name_count = (pcre_uint16)byteflip(rre->name_count,
- sizeof(rre->name_count));
-
- if (extra != NULL)
- {
- pcre_study_data *rsd = (pcre_study_data *)(extra->study_data);
- rsd->size = byteflip(rsd->size, sizeof(rsd->size));
- rsd->options = byteflip(rsd->options, sizeof(rsd->options));
- }
- }
-
- /* Extract information from the compiled data if required */
-
- SHOW_INFO:
-
- if (do_debug)
- {
- fprintf(outfile, "------------------------------------------------------------------\n");
- pcre_printint(re, outfile, debug_lengths);
- }
-
- if (do_showinfo)
- {
- unsigned long int get_options, all_options;
-#if !defined NOINFOCHECK
- int old_first_char, old_options, old_count;
-#endif
- int count, backrefmax, first_char, need_char, okpartial, jchanged,
- hascrorlf;
- int nameentrysize, namecount;
- const uschar *nametable;
-
- new_info(re, NULL, PCRE_INFO_OPTIONS, &get_options);
- new_info(re, NULL, PCRE_INFO_SIZE, &size);
- new_info(re, NULL, PCRE_INFO_CAPTURECOUNT, &count);
- new_info(re, NULL, PCRE_INFO_BACKREFMAX, &backrefmax);
- new_info(re, NULL, PCRE_INFO_FIRSTBYTE, &first_char);
- new_info(re, NULL, PCRE_INFO_LASTLITERAL, &need_char);
- new_info(re, NULL, PCRE_INFO_NAMEENTRYSIZE, &nameentrysize);
- new_info(re, NULL, PCRE_INFO_NAMECOUNT, &namecount);
- new_info(re, NULL, PCRE_INFO_NAMETABLE, (void *)&nametable);
- new_info(re, NULL, PCRE_INFO_OKPARTIAL, &okpartial);
- new_info(re, NULL, PCRE_INFO_JCHANGED, &jchanged);
- new_info(re, NULL, PCRE_INFO_HASCRORLF, &hascrorlf);
-
-#if !defined NOINFOCHECK
- old_count = pcre_info(re, &old_options, &old_first_char);
- if (count < 0) fprintf(outfile,
- "Error %d from pcre_info()\n", count);
- else
- {
- if (old_count != count) fprintf(outfile,
- "Count disagreement: pcre_fullinfo=%d pcre_info=%d\n", count,
- old_count);
-
- if (old_first_char != first_char) fprintf(outfile,
- "First char disagreement: pcre_fullinfo=%d pcre_info=%d\n",
- first_char, old_first_char);
-
- if (old_options != (int)get_options) fprintf(outfile,
- "Options disagreement: pcre_fullinfo=%ld pcre_info=%d\n",
- get_options, old_options);
- }
-#endif
-
- if (size != regex_gotten_store) fprintf(outfile,
- "Size disagreement: pcre_fullinfo=%d call to malloc for %d\n",
- (int)size, (int)regex_gotten_store);
-
- fprintf(outfile, "Capturing subpattern count = %d\n", count);
- if (backrefmax > 0)
- fprintf(outfile, "Max back reference = %d\n", backrefmax);
-
- if (namecount > 0)
- {
- fprintf(outfile, "Named capturing subpatterns:\n");
- while (namecount-- > 0)
- {
- fprintf(outfile, " %s %*s%3d\n", nametable + 2,
- nameentrysize - 3 - (int)strlen((char *)nametable + 2), "",
- GET2(nametable, 0));
- nametable += nameentrysize;
- }
- }
-
- if (!okpartial) fprintf(outfile, "Partial matching not supported\n");
- if (hascrorlf) fprintf(outfile, "Contains explicit CR or LF match\n");
-
- all_options = ((real_pcre *)re)->options;
- if (do_flip) all_options = byteflip(all_options, sizeof(all_options));
-
- if (get_options == 0) fprintf(outfile, "No options\n");
- else fprintf(outfile, "Options:%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
- ((get_options & PCRE_ANCHORED) != 0)? " anchored" : "",
- ((get_options & PCRE_CASELESS) != 0)? " caseless" : "",
- ((get_options & PCRE_EXTENDED) != 0)? " extended" : "",
- ((get_options & PCRE_MULTILINE) != 0)? " multiline" : "",
- ((get_options & PCRE_FIRSTLINE) != 0)? " firstline" : "",
- ((get_options & PCRE_DOTALL) != 0)? " dotall" : "",
- ((get_options & PCRE_BSR_ANYCRLF) != 0)? " bsr_anycrlf" : "",
- ((get_options & PCRE_BSR_UNICODE) != 0)? " bsr_unicode" : "",
- ((get_options & PCRE_DOLLAR_ENDONLY) != 0)? " dollar_endonly" : "",
- ((get_options & PCRE_EXTRA) != 0)? " extra" : "",
- ((get_options & PCRE_UNGREEDY) != 0)? " ungreedy" : "",
- ((get_options & PCRE_NO_AUTO_CAPTURE) != 0)? " no_auto_capture" : "",
- ((get_options & PCRE_UTF8) != 0)? " utf8" : "",
- ((get_options & PCRE_NO_UTF8_CHECK) != 0)? " no_utf8_check" : "",
- ((get_options & PCRE_DUPNAMES) != 0)? " dupnames" : "");
-
- if (jchanged) fprintf(outfile, "Duplicate name status changes\n");
-
- switch (get_options & PCRE_NEWLINE_BITS)
- {
- case PCRE_NEWLINE_CR:
- fprintf(outfile, "Forced newline sequence: CR\n");
- break;
-
- case PCRE_NEWLINE_LF:
- fprintf(outfile, "Forced newline sequence: LF\n");
- break;
-
- case PCRE_NEWLINE_CRLF:
- fprintf(outfile, "Forced newline sequence: CRLF\n");
- break;
-
- case PCRE_NEWLINE_ANYCRLF:
- fprintf(outfile, "Forced newline sequence: ANYCRLF\n");
- break;
-
- case PCRE_NEWLINE_ANY:
- fprintf(outfile, "Forced newline sequence: ANY\n");
- break;
-
- default:
- break;
- }
-
- if (first_char == -1)
- {
- fprintf(outfile, "First char at start or follows newline\n");
- }
- else if (first_char < 0)
- {
- fprintf(outfile, "No first char\n");
- }
- else
- {
- int ch = first_char & 255;
- const char *caseless = ((first_char & REQ_CASELESS) == 0)?
- "" : " (caseless)";
- if (PRINTHEX(ch))
- fprintf(outfile, "First char = \'%c\'%s\n", ch, caseless);
- else
- fprintf(outfile, "First char = %d%s\n", ch, caseless);
- }
-
- if (need_char < 0)
- {
- fprintf(outfile, "No need char\n");
- }
- else
- {
- int ch = need_char & 255;
- const char *caseless = ((need_char & REQ_CASELESS) == 0)?
- "" : " (caseless)";
- if (PRINTHEX(ch))
- fprintf(outfile, "Need char = \'%c\'%s\n", ch, caseless);
- else
- fprintf(outfile, "Need char = %d%s\n", ch, caseless);
- }
-
- /* Don't output study size; at present it is in any case a fixed
- value, but it varies, depending on the computer architecture, and
- so messes up the test suite. (And with the /F option, it might be
- flipped.) */
-
- if (do_study)
- {
- if (extra == NULL)
- fprintf(outfile, "Study returned NULL\n");
- else
- {
- uschar *start_bits = NULL;
- new_info(re, extra, PCRE_INFO_FIRSTTABLE, &start_bits);
-
- if (start_bits == NULL)
- fprintf(outfile, "No starting byte set\n");
- else
- {
- int i;
- int c = 24;
- fprintf(outfile, "Starting byte set: ");
- for (i = 0; i < 256; i++)
- {
- if ((start_bits[i/8] & (1<<(i&7))) != 0)
- {
- if (c > 75)
- {
- fprintf(outfile, "\n ");
- c = 2;
- }
- if (PRINTHEX(i) && i != ' ')
- {
- fprintf(outfile, "%c ", i);
- c += 2;
- }
- else
- {
- fprintf(outfile, "\\x%02x ", i);
- c += 5;
- }
- }
- }
- fprintf(outfile, "\n");
- }
- }
- }
- }
-
- /* If the '>' option was present, we write out the regex to a file, and
- that is all. The first 8 bytes of the file are the regex length and then
- the study length, in big-endian order. */
-
- if (to_file != NULL)
- {
- FILE *f = fopen((char *)to_file, "wb");
- if (f == NULL)
- {
- fprintf(outfile, "Unable to open %s: %s\n", to_file, strerror(errno));
- }
- else
- {
- uschar sbuf[8];
- sbuf[0] = (uschar)((true_size >> 24) & 255);
- sbuf[1] = (uschar)((true_size >> 16) & 255);
- sbuf[2] = (uschar)((true_size >> 8) & 255);
- sbuf[3] = (uschar)((true_size) & 255);
-
- sbuf[4] = (uschar)((true_study_size >> 24) & 255);
- sbuf[5] = (uschar)((true_study_size >> 16) & 255);
- sbuf[6] = (uschar)((true_study_size >> 8) & 255);
- sbuf[7] = (uschar)((true_study_size) & 255);
-
- if (fwrite(sbuf, 1, 8, f) < 8 ||
- fwrite(re, 1, true_size, f) < true_size)
- {
- fprintf(outfile, "Write error on %s: %s\n", to_file, strerror(errno));
- }
- else
- {
- fprintf(outfile, "Compiled regex written to %s\n", to_file);
- if (extra != NULL)
- {
- if (fwrite(extra->study_data, 1, true_study_size, f) <
- true_study_size)
- {
- fprintf(outfile, "Write error on %s: %s\n", to_file,
- strerror(errno));
- }
- else fprintf(outfile, "Study data written to %s\n", to_file);
-
- }
- }
- fclose(f);
- }
-
- new_free(re);
- if (extra != NULL) new_free(extra);
- if (tables != NULL) new_free((void *)tables);
- continue; /* With next regex */
- }
- } /* End of non-POSIX compile */
-
- /* Read data lines and test them */
-
- for (;;)
- {
- uschar *q;
- uschar *bptr;
- int *use_offsets = offsets;
- int use_size_offsets = size_offsets;
- int callout_data = 0;
- int callout_data_set = 0;
- int count, c;
- int copystrings = 0;
- int find_match_limit = 0;
- int getstrings = 0;
- int getlist = 0;
- int gmatched = 0;
- int start_offset = 0;
- int g_notempty = 0;
- int use_dfa = 0;
-
- options = 0;
-
- *copynames = 0;
- *getnames = 0;
-
- copynamesptr = copynames;
- getnamesptr = getnames;
-
- pcre_callout = callout;
- first_callout = 1;
- callout_extra = 0;
- callout_count = 0;
- callout_fail_count = 999999;
- callout_fail_id = -1;
- show_malloc = 0;
-
- if (extra != NULL) extra->flags &=
- ~(PCRE_EXTRA_MATCH_LIMIT|PCRE_EXTRA_MATCH_LIMIT_RECURSION);
-
- len = 0;
- for (;;)
- {
- if (extend_inputline(infile, buffer + len, "data> ") == NULL)
- {
- if (len > 0) break;
- done = 1;
- goto CONTINUE;
- }
- if (infile != stdin) fprintf(outfile, "%s", (char *)buffer);
- len = (int)strlen((char *)buffer);
- if (buffer[len-1] == '\n') break;
- }
-
- while (len > 0 && isspace(buffer[len-1])) len--;
- buffer[len] = 0;
- if (len == 0) break;
-
- p = buffer;
- while (isspace(*p)) p++;
-
- bptr = q = dbuffer;
- while ((c = *p++) != 0)
- {
- int i = 0;
- int n = 0;
-
- if (c == '\\') switch ((c = *p++))
- {
- case 'a': c = 7; break;
- case 'b': c = '\b'; break;
- case 'e': c = 27; break;
- case 'f': c = '\f'; break;
- case 'n': c = '\n'; break;
- case 'r': c = '\r'; break;
- case 't': c = '\t'; break;
- case 'v': c = '\v'; break;
-
- case '0': case '1': case '2': case '3':
- case '4': case '5': case '6': case '7':
- c -= '0';
- while (i++ < 2 && isdigit(*p) && *p != '8' && *p != '9')
- c = c * 8 + *p++ - '0';
-
-#if !defined NOUTF8
- if (use_utf8 && c > 255)
- {
- unsigned char buff8[8];
- int ii, utn;
- utn = ord2utf8(c, buff8);
- for (ii = 0; ii < utn - 1; ii++) *q++ = buff8[ii];
- c = buff8[ii]; /* Last byte */
- }
-#endif
- break;
-
- case 'x':
-
- /* Handle \x{..} specially - new Perl thing for utf8 */
-
-#if !defined NOUTF8
- if (*p == '{')
- {
- unsigned char *pt = p;
- c = 0;
- while (isxdigit(*(++pt)))
- c = c * 16 + tolower(*pt) - ((isdigit(*pt))? '0' : 'W');
- if (*pt == '}')
- {
- unsigned char buff8[8];
- int ii, utn;
- utn = ord2utf8(c, buff8);
- for (ii = 0; ii < utn - 1; ii++) *q++ = buff8[ii];
- c = buff8[ii]; /* Last byte */
- p = pt + 1;
- break;
- }
- /* Not correct form; fall through */
- }
-#endif
-
- /* Ordinary \x */
-
- c = 0;
- while (i++ < 2 && isxdigit(*p))
- {
- c = c * 16 + tolower(*p) - ((isdigit(*p))? '0' : 'W');
- p++;
- }
- break;
-
- case 0: /* \ followed by EOF allows for an empty line */
- p--;
- continue;
-
- case '>':
- while(isdigit(*p)) start_offset = start_offset * 10 + *p++ - '0';
- continue;
-
- case 'A': /* Option setting */
- options |= PCRE_ANCHORED;
- continue;
-
- case 'B':
- options |= PCRE_NOTBOL;
- continue;
-
- case 'C':
- if (isdigit(*p)) /* Set copy string */
- {
- while(isdigit(*p)) n = n * 10 + *p++ - '0';
- copystrings |= 1 << n;
- }
- else if (isalnum(*p))
- {
- uschar *npp = copynamesptr;
- while (isalnum(*p)) *npp++ = *p++;
- *npp++ = 0;
- *npp = 0;
- n = pcre_get_stringnumber(re, (char *)copynamesptr);
- if (n < 0)
- fprintf(outfile, "no parentheses with name \"%s\"\n", copynamesptr);
- copynamesptr = npp;
- }
- else if (*p == '+')
- {
- callout_extra = 1;
- p++;
- }
- else if (*p == '-')
- {
- pcre_callout = NULL;
- p++;
- }
- else if (*p == '!')
- {
- callout_fail_id = 0;
- p++;
- while(isdigit(*p))
- callout_fail_id = callout_fail_id * 10 + *p++ - '0';
- callout_fail_count = 0;
- if (*p == '!')
- {
- p++;
- while(isdigit(*p))
- callout_fail_count = callout_fail_count * 10 + *p++ - '0';
- }
- }
- else if (*p == '*')
- {
- int sign = 1;
- callout_data = 0;
- if (*(++p) == '-') { sign = -1; p++; }
- while(isdigit(*p))
- callout_data = callout_data * 10 + *p++ - '0';
- callout_data *= sign;
- callout_data_set = 1;
- }
- continue;
-
-#if !defined NODFA
- case 'D':
-#if !defined NOPOSIX
- if (posix || do_posix)
- printf("** Can't use dfa matching in POSIX mode: \\D ignored\n");
- else
-#endif
- use_dfa = 1;
- continue;
-
- case 'F':
- options |= PCRE_DFA_SHORTEST;
- continue;
-#endif
-
- case 'G':
- if (isdigit(*p))
- {
- while(isdigit(*p)) n = n * 10 + *p++ - '0';
- getstrings |= 1 << n;
- }
- else if (isalnum(*p))
- {
- uschar *npp = getnamesptr;
- while (isalnum(*p)) *npp++ = *p++;
- *npp++ = 0;
- *npp = 0;
- n = pcre_get_stringnumber(re, (char *)getnamesptr);
- if (n < 0)
- fprintf(outfile, "no parentheses with name \"%s\"\n", getnamesptr);
- getnamesptr = npp;
- }
- continue;
-
- case 'L':
- getlist = 1;
- continue;
-
- case 'M':
- find_match_limit = 1;
- continue;
-
- case 'N':
- options |= PCRE_NOTEMPTY;
- continue;
-
- case 'O':
- while(isdigit(*p)) n = n * 10 + *p++ - '0';
- if (n > size_offsets_max)
- {
- size_offsets_max = n;
- free(offsets);
- use_offsets = offsets = (int *)malloc(size_offsets_max * sizeof(int));
- if (offsets == NULL)
- {
- printf("** Failed to get %d bytes of memory for offsets vector\n",
- (int)(size_offsets_max * sizeof(int)));
- yield = 1;
- goto EXIT;
- }
- }
- use_size_offsets = n;
- if (n == 0) use_offsets = NULL; /* Ensures it can't write to it */
- continue;
-
- case 'P':
- options |= PCRE_PARTIAL;
- continue;
-
- case 'Q':
- while(isdigit(*p)) n = n * 10 + *p++ - '0';
- if (extra == NULL)
- {
- extra = (pcre_extra *)malloc(sizeof(pcre_extra));
- extra->flags = 0;
- }
- extra->flags |= PCRE_EXTRA_MATCH_LIMIT_RECURSION;
- extra->match_limit_recursion = n;
- continue;
-
- case 'q':
- while(isdigit(*p)) n = n * 10 + *p++ - '0';
- if (extra == NULL)
- {
- extra = (pcre_extra *)malloc(sizeof(pcre_extra));
- extra->flags = 0;
- }
- extra->flags |= PCRE_EXTRA_MATCH_LIMIT;
- extra->match_limit = n;
- continue;
-
-#if !defined NODFA
- case 'R':
- options |= PCRE_DFA_RESTART;
- continue;
-#endif
-
- case 'S':
- show_malloc = 1;
- continue;
-
- case 'Z':
- options |= PCRE_NOTEOL;
- continue;
-
- case '?':
- options |= PCRE_NO_UTF8_CHECK;
- continue;
-
- case '<':
- {
- int x = check_newline(p, outfile);
- if (x == 0) goto NEXT_DATA;
- options |= x;
- while (*p++ != '>');
- }
- continue;
- }
- *q++ = c;
- }
- *q = 0;
- len = q - dbuffer;
-
- if ((all_use_dfa || use_dfa) && find_match_limit)
- {
- printf("**Match limit not relevant for DFA matching: ignored\n");
- find_match_limit = 0;
- }
-
- /* Handle matching via the POSIX interface, which does not
- support timing or playing with the match limit or callout data. */
-
-#if !defined NOPOSIX
- if (posix || do_posix)
- {
- int rc;
- int eflags = 0;
- regmatch_t *pmatch = NULL;
- if (use_size_offsets > 0)
- pmatch = (regmatch_t *)malloc(sizeof(regmatch_t) * use_size_offsets);
- if ((options & PCRE_NOTBOL) != 0) eflags |= REG_NOTBOL;
- if ((options & PCRE_NOTEOL) != 0) eflags |= REG_NOTEOL;
-
- rc = regexec(&preg, (const char *)bptr, use_size_offsets, pmatch, eflags);
-
- if (rc != 0)
- {
- (void)regerror(rc, &preg, (char *)buffer, buffer_size);
- fprintf(outfile, "No match: POSIX code %d: %s\n", rc, buffer);
- }
- else if ((((const pcre *)preg.re_pcre)->options & PCRE_NO_AUTO_CAPTURE)
- != 0)
- {
- fprintf(outfile, "Matched with REG_NOSUB\n");
- }
- else
- {
- size_t i;
- for (i = 0; i < (size_t)use_size_offsets; i++)
- {
- if (pmatch[i].rm_so >= 0)
- {
- fprintf(outfile, "%2d: ", (int)i);
- (void)pchars(dbuffer + pmatch[i].rm_so,
- pmatch[i].rm_eo - pmatch[i].rm_so, outfile);
- fprintf(outfile, "\n");
- if (i == 0 && do_showrest)
- {
- fprintf(outfile, " 0+ ");
- (void)pchars(dbuffer + pmatch[i].rm_eo, len - pmatch[i].rm_eo,
- outfile);
- fprintf(outfile, "\n");
- }
- }
- }
- }
- free(pmatch);
- }
-
- /* Handle matching via the native interface - repeats for /g and /G */
-
- else
-#endif /* !defined NOPOSIX */
-
- for (;; gmatched++) /* Loop for /g or /G */
- {
- if (timeitm > 0)
- {
- register int i;
- clock_t time_taken;
- clock_t start_time = clock();
-
-#if !defined NODFA
- if (all_use_dfa || use_dfa)
- {
- int workspace[1000];
- for (i = 0; i < timeitm; i++)
- count = pcre_dfa_exec(re, NULL, (char *)bptr, len, start_offset,
- options | g_notempty, use_offsets, use_size_offsets, workspace,
- sizeof(workspace)/sizeof(int));
- }
- else
-#endif
-
- for (i = 0; i < timeitm; i++)
- count = pcre_exec(re, extra, (char *)bptr, len,
- start_offset, options | g_notempty, use_offsets, use_size_offsets);
-
- time_taken = clock() - start_time;
- fprintf(outfile, "Execute time %.4f milliseconds\n",
- (((double)time_taken * 1000.0) / (double)timeitm) /
- (double)CLOCKS_PER_SEC);
- }
-
- /* If find_match_limit is set, we want to do repeated matches with
- varying limits in order to find the minimum value for the match limit and
- for the recursion limit. */
-
- if (find_match_limit)
- {
- if (extra == NULL)
- {
- extra = (pcre_extra *)malloc(sizeof(pcre_extra));
- extra->flags = 0;
- }
-
- (void)check_match_limit(re, extra, bptr, len, start_offset,
- options|g_notempty, use_offsets, use_size_offsets,
- PCRE_EXTRA_MATCH_LIMIT, &(extra->match_limit),
- PCRE_ERROR_MATCHLIMIT, "match()");
-
- count = check_match_limit(re, extra, bptr, len, start_offset,
- options|g_notempty, use_offsets, use_size_offsets,
- PCRE_EXTRA_MATCH_LIMIT_RECURSION, &(extra->match_limit_recursion),
- PCRE_ERROR_RECURSIONLIMIT, "match() recursion");
- }
-
- /* If callout_data is set, use the interface with additional data */
-
- else if (callout_data_set)
- {
- if (extra == NULL)
- {
- extra = (pcre_extra *)malloc(sizeof(pcre_extra));
- extra->flags = 0;
- }
- extra->flags |= PCRE_EXTRA_CALLOUT_DATA;
- extra->callout_data = &callout_data;
- count = pcre_exec(re, extra, (char *)bptr, len, start_offset,
- options | g_notempty, use_offsets, use_size_offsets);
- extra->flags &= ~PCRE_EXTRA_CALLOUT_DATA;
- }
-
- /* The normal case is just to do the match once, with the default
- value of match_limit. */
-
-#if !defined NODFA
- else if (all_use_dfa || use_dfa)
- {
- int workspace[1000];
- count = pcre_dfa_exec(re, NULL, (char *)bptr, len, start_offset,
- options | g_notempty, use_offsets, use_size_offsets, workspace,
- sizeof(workspace)/sizeof(int));
- if (count == 0)
- {
- fprintf(outfile, "Matched, but too many subsidiary matches\n");
- count = use_size_offsets/2;
- }
- }
-#endif
-
- else
- {
- count = pcre_exec(re, extra, (char *)bptr, len,
- start_offset, options | g_notempty, use_offsets, use_size_offsets);
- if (count == 0)
- {
- fprintf(outfile, "Matched, but too many substrings\n");
- count = use_size_offsets/3;
- }
- }
-
- /* Matched */
-
- if (count >= 0)
- {
- int i, maxcount;
-
-#if !defined NODFA
- if (all_use_dfa || use_dfa) maxcount = use_size_offsets/2; else
-#endif
- maxcount = use_size_offsets/3;
-
- /* This is a check against a lunatic return value. */
-
- if (count > maxcount)
- {
- fprintf(outfile,
- "** PCRE error: returned count %d is too big for offset size %d\n",
- count, use_size_offsets);
- count = use_size_offsets/3;
- if (do_g || do_G)
- {
- fprintf(outfile, "** /%c loop abandoned\n", do_g? 'g' : 'G');
- do_g = do_G = FALSE; /* Break g/G loop */
- }
- }
-
- for (i = 0; i < count * 2; i += 2)
- {
- if (use_offsets[i] < 0)
- fprintf(outfile, "%2d: <unset>\n", i/2);
- else
- {
- fprintf(outfile, "%2d: ", i/2);
- (void)pchars(bptr + use_offsets[i],
- use_offsets[i+1] - use_offsets[i], outfile);
- fprintf(outfile, "\n");
- if (i == 0)
- {
- if (do_showrest)
- {
- fprintf(outfile, " 0+ ");
- (void)pchars(bptr + use_offsets[i+1], len - use_offsets[i+1],
- outfile);
- fprintf(outfile, "\n");
- }
- }
- }
- }
-
- for (i = 0; i < 32; i++)
- {
- if ((copystrings & (1 << i)) != 0)
- {
- char copybuffer[256];
- int rc = pcre_copy_substring((char *)bptr, use_offsets, count,
- i, copybuffer, sizeof(copybuffer));
- if (rc < 0)
- fprintf(outfile, "copy substring %d failed %d\n", i, rc);
- else
- fprintf(outfile, "%2dC %s (%d)\n", i, copybuffer, rc);
- }
- }
-
- for (copynamesptr = copynames;
- *copynamesptr != 0;
- copynamesptr += (int)strlen((char*)copynamesptr) + 1)
- {
- char copybuffer[256];
- int rc = pcre_copy_named_substring(re, (char *)bptr, use_offsets,
- count, (char *)copynamesptr, copybuffer, sizeof(copybuffer));
- if (rc < 0)
- fprintf(outfile, "copy substring %s failed %d\n", copynamesptr, rc);
- else
- fprintf(outfile, " C %s (%d) %s\n", copybuffer, rc, copynamesptr);
- }
-
- for (i = 0; i < 32; i++)
- {
- if ((getstrings & (1 << i)) != 0)
- {
- const char *substring;
- int rc = pcre_get_substring((char *)bptr, use_offsets, count,
- i, &substring);
- if (rc < 0)
- fprintf(outfile, "get substring %d failed %d\n", i, rc);
- else
- {
- fprintf(outfile, "%2dG %s (%d)\n", i, substring, rc);
- pcre_free_substring(substring);
- }
- }
- }
-
- for (getnamesptr = getnames;
- *getnamesptr != 0;
- getnamesptr += (int)strlen((char*)getnamesptr) + 1)
- {
- const char *substring;
- int rc = pcre_get_named_substring(re, (char *)bptr, use_offsets,
- count, (char *)getnamesptr, &substring);
- if (rc < 0)
- fprintf(outfile, "copy substring %s failed %d\n", getnamesptr, rc);
- else
- {
- fprintf(outfile, " G %s (%d) %s\n", substring, rc, getnamesptr);
- pcre_free_substring(substring);
- }
- }
-
- if (getlist)
- {
- const char **stringlist;
- int rc = pcre_get_substring_list((char *)bptr, use_offsets, count,
- &stringlist);
- if (rc < 0)
- fprintf(outfile, "get substring list failed %d\n", rc);
- else
- {
- for (i = 0; i < count; i++)
- fprintf(outfile, "%2dL %s\n", i, stringlist[i]);
- if (stringlist[i] != NULL)
- fprintf(outfile, "string list not terminated by NULL\n");
- /* free((void *)stringlist); */
- pcre_free_substring_list(stringlist);
- }
- }
- }
-
- /* There was a partial match */
-
- else if (count == PCRE_ERROR_PARTIAL)
- {
- fprintf(outfile, "Partial match");
-#if !defined NODFA
- if ((all_use_dfa || use_dfa) && use_size_offsets > 2)
- fprintf(outfile, ": %.*s", use_offsets[1] - use_offsets[0],
- bptr + use_offsets[0]);
-#endif
- fprintf(outfile, "\n");
- break; /* Out of the /g loop */
- }
-
- /* Failed to match. If this is a /g or /G loop and we previously set
- g_notempty after a null match, this is not necessarily the end. We want
- to advance the start offset, and continue. We won't be at the end of the
- string - that was checked before setting g_notempty.
-
- Complication arises in the case when the newline option is "any" or
- "anycrlf". If the previous match was at the end of a line terminated by
- CRLF, an advance of one character just passes the \r, whereas we should
- prefer the longer newline sequence, as does the code in pcre_exec().
- Fudge the offset value to achieve this.
-
- Otherwise, in the case of UTF-8 matching, the advance must be one
- character, not one byte. */
-
- else
- {
- if (g_notempty != 0)
- {
- int onechar = 1;
- unsigned int obits = ((real_pcre *)re)->options;
- use_offsets[0] = start_offset;
- if ((obits & PCRE_NEWLINE_BITS) == 0)
- {
- int d;
- (void)pcre_config(PCRE_CONFIG_NEWLINE, &d);
- obits = (d == '\r')? PCRE_NEWLINE_CR :
- (d == '\n')? PCRE_NEWLINE_LF :
- (d == ('\r'<<8 | '\n'))? PCRE_NEWLINE_CRLF :
- (d == -2)? PCRE_NEWLINE_ANYCRLF :
- (d == -1)? PCRE_NEWLINE_ANY : 0;
- }
- if (((obits & PCRE_NEWLINE_BITS) == PCRE_NEWLINE_ANY ||
- (obits & PCRE_NEWLINE_BITS) == PCRE_NEWLINE_ANYCRLF)
- &&
- start_offset < len - 1 &&
- bptr[start_offset] == '\r' &&
- bptr[start_offset+1] == '\n')
- onechar++;
- else if (use_utf8)
- {
- while (start_offset + onechar < len)
- {
- int tb = bptr[start_offset+onechar];
- if (tb <= 127) break;
- tb &= 0xc0;
- if (tb != 0 && tb != 0xc0) onechar++;
- }
- }
- use_offsets[1] = start_offset + onechar;
- }
- else
- {
- if (count == PCRE_ERROR_NOMATCH)
- {
- if (gmatched == 0) fprintf(outfile, "No match\n");
- }
- else fprintf(outfile, "Error %d\n", count);
- break; /* Out of the /g loop */
- }
- }
-
- /* If not /g or /G we are done */
-
- if (!do_g && !do_G) break;
-
- /* If we have matched an empty string, first check to see if we are at
- the end of the subject. If so, the /g loop is over. Otherwise, mimic
- what Perl's /g options does. This turns out to be rather cunning. First
- we set PCRE_NOTEMPTY and PCRE_ANCHORED and try the match again at the
- same point. If this fails (picked up above) we advance to the next
- character. */
-
- g_notempty = 0;
-
- if (use_offsets[0] == use_offsets[1])
- {
- if (use_offsets[0] == len) break;
- g_notempty = PCRE_NOTEMPTY | PCRE_ANCHORED;
- }
-
- /* For /g, update the start offset, leaving the rest alone */
-
- if (do_g) start_offset = use_offsets[1];
-
- /* For /G, update the pointer and length */
-
- else
- {
- bptr += use_offsets[1];
- len -= use_offsets[1];
- }
- } /* End of loop for /g and /G */
-
- NEXT_DATA: continue;
- } /* End of loop for data lines */
-
- CONTINUE:
-
-#if !defined NOPOSIX
- if (posix || do_posix) regfree(&preg);
-#endif
-
- if (re != NULL) new_free(re);
- if (extra != NULL) new_free(extra);
- if (tables != NULL)
- {
- new_free((void *)tables);
- setlocale(LC_CTYPE, "C");
- locale_set = 0;
- }
- }
-
-if (infile == stdin) fprintf(outfile, "\n");
-
-EXIT:
-
-if (infile != NULL && infile != stdin) fclose(infile);
-if (outfile != NULL && outfile != stdout) fclose(outfile);
-
-free(buffer);
-free(dbuffer);
-free(pbuffer);
-free(offsets);
-
-return yield;
-}
-
-/* End of pcretest.c */
diff --git a/crawl-ref/source/util/pcre/perltest.pl b/crawl-ref/source/util/pcre/perltest.pl
deleted file mode 100644
index 0d290c127a..0000000000
--- a/crawl-ref/source/util/pcre/perltest.pl
+++ /dev/null
@@ -1,191 +0,0 @@
-#! /usr/bin/env perl
-
-# Program for testing regular expressions with perl to check that PCRE handles
-# them the same. This is the version that supports /8 for UTF-8 testing. As it
-# stands, it requires at least Perl 5.8 for UTF-8 support. However, it needs to
-# have "use utf8" at the start for running the UTF-8 tests, but *not* for the
-# other tests. The only way I've found for doing this is to cat this line in
-# explicitly in the RunPerlTest script.
-
-# use locale; # With this included, \x0b matches \s!
-
-# Function for turning a string into a string of printing chars. There are
-# currently problems with UTF-8 strings; this fudges round them.
-
-sub pchars {
-my($t) = "";
-
-if ($utf8)
- {
- @p = unpack('U*', $_[0]);
- foreach $c (@p)
- {
- if ($c >= 32 && $c < 127) { $t .= chr $c; }
- else { $t .= sprintf("\\x{%02x}", $c); }
- }
- }
-
-else
- {
- foreach $c (split(//, $_[0]))
- {
- if (ord $c >= 32 && ord $c < 127) { $t .= $c; }
- else { $t .= sprintf("\\x%02x", ord $c); }
- }
- }
-
-$t;
-}
-
-
-# Read lines from named file or stdin and write to named file or stdout; lines
-# consist of a regular expression, in delimiters and optionally followed by
-# options, followed by a set of test data, terminated by an empty line.
-
-# Sort out the input and output files
-
-if (@ARGV > 0)
- {
- open(INFILE, "<$ARGV[0]") || die "Failed to open $ARGV[0]\n";
- $infile = "INFILE";
- }
-else { $infile = "STDIN"; }
-
-if (@ARGV > 1)
- {
- open(OUTFILE, ">$ARGV[1]") || die "Failed to open $ARGV[1]\n";
- $outfile = "OUTFILE";
- }
-else { $outfile = "STDOUT"; }
-
-printf($outfile "Perl $] Regular Expressions\n\n");
-
-# Main loop
-
-NEXT_RE:
-for (;;)
- {
- printf " re> " if $infile eq "STDIN";
- last if ! ($_ = <$infile>);
- printf $outfile "$_" if $infile ne "STDIN";
- next if ($_ eq "");
-
- $pattern = $_;
-
- while ($pattern !~ /^\s*(.).*\1/s)
- {
- printf " > " if $infile eq "STDIN";
- last if ! ($_ = <$infile>);
- printf $outfile "$_" if $infile ne "STDIN";
- $pattern .= $_;
- }
-
- chomp($pattern);
- $pattern =~ s/\s+$//;
-
- # The private /+ modifier means "print $' afterwards".
-
- $showrest = ($pattern =~ s/\+(?=[a-z]*$)//);
-
- # Remove /8 from a UTF-8 pattern.
-
- $utf8 = $pattern =~ s/8(?=[a-z]*$)//;
-
- # Check that the pattern is valid
-
- eval "\$_ =~ ${pattern}";
- if ($@)
- {
- printf $outfile "Error: $@";
- next NEXT_RE;
- }
-
- # If the /g modifier is present, we want to put a loop round the matching;
- # otherwise just a single "if".
-
- $cmd = ($pattern =~ /g[a-z]*$/)? "while" : "if";
-
- # If the pattern is actually the null string, Perl uses the most recently
- # executed (and successfully compiled) regex is used instead. This is a
- # nasty trap for the unwary! The PCRE test suite does contain null strings
- # in places - if they are allowed through here all sorts of weird and
- # unexpected effects happen. To avoid this, we replace such patterns with
- # a non-null pattern that has the same effect.
-
- $pattern = "/(?#)/$2" if ($pattern =~ /^(.)\1(.*)$/);
-
- # Read data lines and test them
-
- for (;;)
- {
- printf "data> " if $infile eq "STDIN";
- last NEXT_RE if ! ($_ = <$infile>);
- chomp;
- printf $outfile "$_\n" if $infile ne "STDIN";
-
- s/\s+$//;
- s/^\s+//;
-
- last if ($_ eq "");
- $x = eval "\"$_\""; # To get escapes processed
-
- # Empty array for holding results, then do the matching.
-
- @subs = ();
-
- $pushes = "push \@subs,\$&;" .
- "push \@subs,\$1;" .
- "push \@subs,\$2;" .
- "push \@subs,\$3;" .
- "push \@subs,\$4;" .
- "push \@subs,\$5;" .
- "push \@subs,\$6;" .
- "push \@subs,\$7;" .
- "push \@subs,\$8;" .
- "push \@subs,\$9;" .
- "push \@subs,\$10;" .
- "push \@subs,\$11;" .
- "push \@subs,\$12;" .
- "push \@subs,\$13;" .
- "push \@subs,\$14;" .
- "push \@subs,\$15;" .
- "push \@subs,\$16;" .
- "push \@subs,\$'; }";
-
- eval "${cmd} (\$x =~ ${pattern}) {" . $pushes;
-
- if ($@)
- {
- printf $outfile "Error: $@\n";
- next NEXT_RE;
- }
- elsif (scalar(@subs) == 0)
- {
- printf $outfile "No match\n";
- }
- else
- {
- while (scalar(@subs) != 0)
- {
- printf $outfile (" 0: %s\n", &pchars($subs[0]));
- printf $outfile (" 0+ %s\n", &pchars($subs[17])) if $showrest;
- $last_printed = 0;
- for ($i = 1; $i <= 16; $i++)
- {
- if (defined $subs[$i])
- {
- while ($last_printed++ < $i-1)
- { printf $outfile ("%2d: <unset>\n", $last_printed); }
- printf $outfile ("%2d: %s\n", $i, &pchars($subs[$i]));
- $last_printed = $i;
- }
- }
- splice(@subs, 0, 18);
- }
- }
- }
- }
-
-# printf $outfile "\n";
-
-# End
diff --git a/crawl-ref/source/util/pcre/ucp.h b/crawl-ref/source/util/pcre/ucp.h
deleted file mode 100644
index 3a4179b769..0000000000
--- a/crawl-ref/source/util/pcre/ucp.h
+++ /dev/null
@@ -1,133 +0,0 @@
-/*************************************************
-* Unicode Property Table handler *
-*************************************************/
-
-#ifndef _UCP_H
-#define _UCP_H
-
-/* This file contains definitions of the property values that are returned by
-the function _pcre_ucp_findprop(). New values that are added for new releases
-of Unicode should always be at the end of each enum, for backwards
-compatibility. */
-
-/* These are the general character categories. */
-
-enum {
- ucp_C, /* Other */
- ucp_L, /* Letter */
- ucp_M, /* Mark */
- ucp_N, /* Number */
- ucp_P, /* Punctuation */
- ucp_S, /* Symbol */
- ucp_Z /* Separator */
-};
-
-/* These are the particular character types. */
-
-enum {
- ucp_Cc, /* Control */
- ucp_Cf, /* Format */
- ucp_Cn, /* Unassigned */
- ucp_Co, /* Private use */
- ucp_Cs, /* Surrogate */
- ucp_Ll, /* Lower case letter */
- ucp_Lm, /* Modifier letter */
- ucp_Lo, /* Other letter */
- ucp_Lt, /* Title case letter */
- ucp_Lu, /* Upper case letter */
- ucp_Mc, /* Spacing mark */
- ucp_Me, /* Enclosing mark */
- ucp_Mn, /* Non-spacing mark */
- ucp_Nd, /* Decimal number */
- ucp_Nl, /* Letter number */
- ucp_No, /* Other number */
- ucp_Pc, /* Connector punctuation */
- ucp_Pd, /* Dash punctuation */
- ucp_Pe, /* Close punctuation */
- ucp_Pf, /* Final punctuation */
- ucp_Pi, /* Initial punctuation */
- ucp_Po, /* Other punctuation */
- ucp_Ps, /* Open punctuation */
- ucp_Sc, /* Currency symbol */
- ucp_Sk, /* Modifier symbol */
- ucp_Sm, /* Mathematical symbol */
- ucp_So, /* Other symbol */
- ucp_Zl, /* Line separator */
- ucp_Zp, /* Paragraph separator */
- ucp_Zs /* Space separator */
-};
-
-/* These are the script identifications. */
-
-enum {
- ucp_Arabic,
- ucp_Armenian,
- ucp_Bengali,
- ucp_Bopomofo,
- ucp_Braille,
- ucp_Buginese,
- ucp_Buhid,
- ucp_Canadian_Aboriginal,
- ucp_Cherokee,
- ucp_Common,
- ucp_Coptic,
- ucp_Cypriot,
- ucp_Cyrillic,
- ucp_Deseret,
- ucp_Devanagari,
- ucp_Ethiopic,
- ucp_Georgian,
- ucp_Glagolitic,
- ucp_Gothic,
- ucp_Greek,
- ucp_Gujarati,
- ucp_Gurmukhi,
- ucp_Han,
- ucp_Hangul,
- ucp_Hanunoo,
- ucp_Hebrew,
- ucp_Hiragana,
- ucp_Inherited,
- ucp_Kannada,
- ucp_Katakana,
- ucp_Kharoshthi,
- ucp_Khmer,
- ucp_Lao,
- ucp_Latin,
- ucp_Limbu,
- ucp_Linear_B,
- ucp_Malayalam,
- ucp_Mongolian,
- ucp_Myanmar,
- ucp_New_Tai_Lue,
- ucp_Ogham,
- ucp_Old_Italic,
- ucp_Old_Persian,
- ucp_Oriya,
- ucp_Osmanya,
- ucp_Runic,
- ucp_Shavian,
- ucp_Sinhala,
- ucp_Syloti_Nagri,
- ucp_Syriac,
- ucp_Tagalog,
- ucp_Tagbanwa,
- ucp_Tai_Le,
- ucp_Tamil,
- ucp_Telugu,
- ucp_Thaana,
- ucp_Thai,
- ucp_Tibetan,
- ucp_Tifinagh,
- ucp_Ugaritic,
- ucp_Yi,
- ucp_Balinese, /* New for Unicode 5.0.0 */
- ucp_Cuneiform, /* New for Unicode 5.0.0 */
- ucp_Nko, /* New for Unicode 5.0.0 */
- ucp_Phags_Pa, /* New for Unicode 5.0.0 */
- ucp_Phoenician /* New for Unicode 5.0.0 */
-};
-
-#endif
-
-/* End of ucp.h */
diff --git a/crawl-ref/source/util/pcre/ucpinternal.h b/crawl-ref/source/util/pcre/ucpinternal.h
deleted file mode 100644
index a96667b0a8..0000000000
--- a/crawl-ref/source/util/pcre/ucpinternal.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/*************************************************
-* Unicode Property Table handler *
-*************************************************/
-
-#ifndef _UCPINTERNAL_H
-#define _UCPINTERNAL_H
-
-/* Internal header file defining the layout of the bits in each pair of 32-bit
-words that form a data item in the table. */
-
-typedef struct cnode {
- pcre_uint32 f0;
- pcre_uint32 f1;
-} cnode;
-
-/* Things for the f0 field */
-
-#define f0_scriptmask 0xff000000 /* Mask for script field */
-#define f0_scriptshift 24 /* Shift for script value */
-#define f0_rangeflag 0x00800000 /* Flag for a range item */
-#define f0_charmask 0x001fffff /* Mask for code point value */
-
-/* Things for the f1 field */
-
-#define f1_typemask 0xfc000000 /* Mask for char type field */
-#define f1_typeshift 26 /* Shift for the type field */
-#define f1_rangemask 0x0000ffff /* Mask for a range offset */
-#define f1_casemask 0x0000ffff /* Mask for a case offset */
-#define f1_caseneg 0xffff8000 /* Bits for negation */
-
-/* The data consists of a vector of structures of type cnode. The two unsigned
-32-bit integers are used as follows:
-
-(f0) (1) The most significant byte holds the script number. The numbers are
- defined by the enum in ucp.h.
-
- (2) The 0x00800000 bit is set if this entry defines a range of characters.
- It is not set if this entry defines a single character
-
- (3) The 0x00600000 bits are spare.
-
- (4) The 0x001fffff bits contain the code point. No Unicode code point will
- ever be greater than 0x0010ffff, so this should be OK for ever.
-
-(f1) (1) The 0xfc000000 bits contain the character type number. The numbers are
- defined by an enum in ucp.h.
-
- (2) The 0x03ff0000 bits are spare.
-
- (3) The 0x0000ffff bits contain EITHER the unsigned offset to the top of
- range if this entry defines a range, OR the *signed* offset to the
- character's "other case" partner if this entry defines a single
- character. There is no partner if the value is zero.
-
--------------------------------------------------------------------------------
-| script (8) |.|.|.| codepoint (21) || type (6) |.|.| spare (8) | offset (16) |
--------------------------------------------------------------------------------
- | | | | |
- | | |-> spare | |-> spare
- | | |
- | |-> spare |-> spare
- |
- |-> range flag
-
-The upper/lower casing information is set only for characters that come in
-pairs. The non-one-to-one mappings in the Unicode data are ignored.
-
-When searching the data, proceed as follows:
-
-(1) Set up for a binary chop search.
-
-(2) If the top is not greater than the bottom, the character is not in the
- table. Its type must therefore be "Cn" ("Undefined").
-
-(3) Find the middle vector element.
-
-(4) Extract the code point and compare. If equal, we are done.
-
-(5) If the test character is smaller, set the top to the current point, and
- goto (2).
-
-(6) If the current entry defines a range, compute the last character by adding
- the offset, and see if the test character is within the range. If it is,
- we are done.
-
-(7) Otherwise, set the bottom to one element past the current point and goto
- (2).
-*/
-
-#endif /* _UCPINTERNAL_H */
-
-/* End of ucpinternal.h */
diff --git a/crawl-ref/source/util/pcre/ucptable.h b/crawl-ref/source/util/pcre/ucptable.h
deleted file mode 100644
index a274d443ee..0000000000
--- a/crawl-ref/source/util/pcre/ucptable.h
+++ /dev/null
@@ -1,3088 +0,0 @@
-/* This source module is automatically generated from the Unicode
-property table. See ucpinternal.h for a description of the layout.
-This version was made from the Unicode 5.0.0 tables. */
-
-static const cnode ucp_table[] = {
- { 0x09800000, 0x0000001f },
- { 0x09000020, 0x74000000 },
- { 0x09800021, 0x54000002 },
- { 0x09000024, 0x5c000000 },
- { 0x09800025, 0x54000002 },
- { 0x09000028, 0x58000000 },
- { 0x09000029, 0x48000000 },
- { 0x0900002a, 0x54000000 },
- { 0x0900002b, 0x64000000 },
- { 0x0900002c, 0x54000000 },
- { 0x0900002d, 0x44000000 },
- { 0x0980002e, 0x54000001 },
- { 0x09800030, 0x34000009 },
- { 0x0980003a, 0x54000001 },
- { 0x0980003c, 0x64000002 },
- { 0x0980003f, 0x54000001 },
- { 0x21000041, 0x24000020 },
- { 0x21000042, 0x24000020 },
- { 0x21000043, 0x24000020 },
- { 0x21000044, 0x24000020 },
- { 0x21000045, 0x24000020 },
- { 0x21000046, 0x24000020 },
- { 0x21000047, 0x24000020 },
- { 0x21000048, 0x24000020 },
- { 0x21000049, 0x24000020 },
- { 0x2100004a, 0x24000020 },
- { 0x2100004b, 0x24000020 },
- { 0x2100004c, 0x24000020 },
- { 0x2100004d, 0x24000020 },
- { 0x2100004e, 0x24000020 },
- { 0x2100004f, 0x24000020 },
- { 0x21000050, 0x24000020 },
- { 0x21000051, 0x24000020 },
- { 0x21000052, 0x24000020 },
- { 0x21000053, 0x24000020 },
- { 0x21000054, 0x24000020 },
- { 0x21000055, 0x24000020 },
- { 0x21000056, 0x24000020 },
- { 0x21000057, 0x24000020 },
- { 0x21000058, 0x24000020 },
- { 0x21000059, 0x24000020 },
- { 0x2100005a, 0x24000020 },
- { 0x0900005b, 0x58000000 },
- { 0x0900005c, 0x54000000 },
- { 0x0900005d, 0x48000000 },
- { 0x0900005e, 0x60000000 },
- { 0x0900005f, 0x40000000 },
- { 0x09000060, 0x60000000 },
- { 0x21000061, 0x1400ffe0 },
- { 0x21000062, 0x1400ffe0 },
- { 0x21000063, 0x1400ffe0 },
- { 0x21000064, 0x1400ffe0 },
- { 0x21000065, 0x1400ffe0 },
- { 0x21000066, 0x1400ffe0 },
- { 0x21000067, 0x1400ffe0 },
- { 0x21000068, 0x1400ffe0 },
- { 0x21000069, 0x1400ffe0 },
- { 0x2100006a, 0x1400ffe0 },
- { 0x2100006b, 0x1400ffe0 },
- { 0x2100006c, 0x1400ffe0 },
- { 0x2100006d, 0x1400ffe0 },
- { 0x2100006e, 0x1400ffe0 },
- { 0x2100006f, 0x1400ffe0 },
- { 0x21000070, 0x1400ffe0 },
- { 0x21000071, 0x1400ffe0 },
- { 0x21000072, 0x1400ffe0 },
- { 0x21000073, 0x1400ffe0 },
- { 0x21000074, 0x1400ffe0 },
- { 0x21000075, 0x1400ffe0 },
- { 0x21000076, 0x1400ffe0 },
- { 0x21000077, 0x1400ffe0 },
- { 0x21000078, 0x1400ffe0 },
- { 0x21000079, 0x1400ffe0 },
- { 0x2100007a, 0x1400ffe0 },
- { 0x0900007b, 0x58000000 },
- { 0x0900007c, 0x64000000 },
- { 0x0900007d, 0x48000000 },
- { 0x0900007e, 0x64000000 },
- { 0x0980007f, 0x00000020 },
- { 0x090000a0, 0x74000000 },
- { 0x090000a1, 0x54000000 },
- { 0x098000a2, 0x5c000003 },
- { 0x098000a6, 0x68000001 },
- { 0x090000a8, 0x60000000 },
- { 0x090000a9, 0x68000000 },
- { 0x210000aa, 0x14000000 },
- { 0x090000ab, 0x50000000 },
- { 0x090000ac, 0x64000000 },
- { 0x090000ad, 0x04000000 },
- { 0x090000ae, 0x68000000 },
- { 0x090000af, 0x60000000 },
- { 0x090000b0, 0x68000000 },
- { 0x090000b1, 0x64000000 },
- { 0x098000b2, 0x3c000001 },
- { 0x090000b4, 0x60000000 },
- { 0x090000b5, 0x140002e7 },
- { 0x090000b6, 0x68000000 },
- { 0x090000b7, 0x54000000 },
- { 0x090000b8, 0x60000000 },
- { 0x090000b9, 0x3c000000 },
- { 0x210000ba, 0x14000000 },
- { 0x090000bb, 0x4c000000 },
- { 0x098000bc, 0x3c000002 },
- { 0x090000bf, 0x54000000 },
- { 0x210000c0, 0x24000020 },
- { 0x210000c1, 0x24000020 },
- { 0x210000c2, 0x24000020 },
- { 0x210000c3, 0x24000020 },
- { 0x210000c4, 0x24000020 },
- { 0x210000c5, 0x24000020 },
- { 0x210000c6, 0x24000020 },
- { 0x210000c7, 0x24000020 },
- { 0x210000c8, 0x24000020 },
- { 0x210000c9, 0x24000020 },
- { 0x210000ca, 0x24000020 },
- { 0x210000cb, 0x24000020 },
- { 0x210000cc, 0x24000020 },
- { 0x210000cd, 0x24000020 },
- { 0x210000ce, 0x24000020 },
- { 0x210000cf, 0x24000020 },
- { 0x210000d0, 0x24000020 },
- { 0x210000d1, 0x24000020 },
- { 0x210000d2, 0x24000020 },
- { 0x210000d3, 0x24000020 },
- { 0x210000d4, 0x24000020 },
- { 0x210000d5, 0x24000020 },
- { 0x210000d6, 0x24000020 },
- { 0x090000d7, 0x64000000 },
- { 0x210000d8, 0x24000020 },
- { 0x210000d9, 0x24000020 },
- { 0x210000da, 0x24000020 },
- { 0x210000db, 0x24000020 },
- { 0x210000dc, 0x24000020 },
- { 0x210000dd, 0x24000020 },
- { 0x210000de, 0x24000020 },
- { 0x210000df, 0x14000000 },
- { 0x210000e0, 0x1400ffe0 },
- { 0x210000e1, 0x1400ffe0 },
- { 0x210000e2, 0x1400ffe0 },
- { 0x210000e3, 0x1400ffe0 },
- { 0x210000e4, 0x1400ffe0 },
- { 0x210000e5, 0x1400ffe0 },
- { 0x210000e6, 0x1400ffe0 },
- { 0x210000e7, 0x1400ffe0 },
- { 0x210000e8, 0x1400ffe0 },
- { 0x210000e9, 0x1400ffe0 },
- { 0x210000ea, 0x1400ffe0 },
- { 0x210000eb, 0x1400ffe0 },
- { 0x210000ec, 0x1400ffe0 },
- { 0x210000ed, 0x1400ffe0 },
- { 0x210000ee, 0x1400ffe0 },
- { 0x210000ef, 0x1400ffe0 },
- { 0x210000f0, 0x1400ffe0 },
- { 0x210000f1, 0x1400ffe0 },
- { 0x210000f2, 0x1400ffe0 },
- { 0x210000f3, 0x1400ffe0 },
- { 0x210000f4, 0x1400ffe0 },
- { 0x210000f5, 0x1400ffe0 },
- { 0x210000f6, 0x1400ffe0 },
- { 0x090000f7, 0x64000000 },
- { 0x210000f8, 0x1400ffe0 },
- { 0x210000f9, 0x1400ffe0 },
- { 0x210000fa, 0x1400ffe0 },
- { 0x210000fb, 0x1400ffe0 },
- { 0x210000fc, 0x1400ffe0 },
- { 0x210000fd, 0x1400ffe0 },
- { 0x210000fe, 0x1400ffe0 },
- { 0x210000ff, 0x14000079 },
- { 0x21000100, 0x24000001 },
- { 0x21000101, 0x1400ffff },
- { 0x21000102, 0x24000001 },
- { 0x21000103, 0x1400ffff },
- { 0x21000104, 0x24000001 },
- { 0x21000105, 0x1400ffff },
- { 0x21000106, 0x24000001 },
- { 0x21000107, 0x1400ffff },
- { 0x21000108, 0x24000001 },
- { 0x21000109, 0x1400ffff },
- { 0x2100010a, 0x24000001 },
- { 0x2100010b, 0x1400ffff },
- { 0x2100010c, 0x24000001 },
- { 0x2100010d, 0x1400ffff },
- { 0x2100010e, 0x24000001 },
- { 0x2100010f, 0x1400ffff },
- { 0x21000110, 0x24000001 },
- { 0x21000111, 0x1400ffff },
- { 0x21000112, 0x24000001 },
- { 0x21000113, 0x1400ffff },
- { 0x21000114, 0x24000001 },
- { 0x21000115, 0x1400ffff },
- { 0x21000116, 0x24000001 },
- { 0x21000117, 0x1400ffff },
- { 0x21000118, 0x24000001 },
- { 0x21000119, 0x1400ffff },
- { 0x2100011a, 0x24000001 },
- { 0x2100011b, 0x1400ffff },
- { 0x2100011c, 0x24000001 },
- { 0x2100011d, 0x1400ffff },
- { 0x2100011e, 0x24000001 },
- { 0x2100011f, 0x1400ffff },
- { 0x21000120, 0x24000001 },
- { 0x21000121, 0x1400ffff },
- { 0x21000122, 0x24000001 },
- { 0x21000123, 0x1400ffff },
- { 0x21000124, 0x24000001 },
- { 0x21000125, 0x1400ffff },
- { 0x21000126, 0x24000001 },
- { 0x21000127, 0x1400ffff },
- { 0x21000128, 0x24000001 },
- { 0x21000129, 0x1400ffff },
- { 0x2100012a, 0x24000001 },
- { 0x2100012b, 0x1400ffff },
- { 0x2100012c, 0x24000001 },
- { 0x2100012d, 0x1400ffff },
- { 0x2100012e, 0x24000001 },
- { 0x2100012f, 0x1400ffff },
- { 0x21000130, 0x2400ff39 },
- { 0x21000131, 0x1400ff18 },
- { 0x21000132, 0x24000001 },
- { 0x21000133, 0x1400ffff },
- { 0x21000134, 0x24000001 },
- { 0x21000135, 0x1400ffff },
- { 0x21000136, 0x24000001 },
- { 0x21000137, 0x1400ffff },
- { 0x21000138, 0x14000000 },
- { 0x21000139, 0x24000001 },
- { 0x2100013a, 0x1400ffff },
- { 0x2100013b, 0x24000001 },
- { 0x2100013c, 0x1400ffff },
- { 0x2100013d, 0x24000001 },
- { 0x2100013e, 0x1400ffff },
- { 0x2100013f, 0x24000001 },
- { 0x21000140, 0x1400ffff },
- { 0x21000141, 0x24000001 },
- { 0x21000142, 0x1400ffff },
- { 0x21000143, 0x24000001 },
- { 0x21000144, 0x1400ffff },
- { 0x21000145, 0x24000001 },
- { 0x21000146, 0x1400ffff },
- { 0x21000147, 0x24000001 },
- { 0x21000148, 0x1400ffff },
- { 0x21000149, 0x14000000 },
- { 0x2100014a, 0x24000001 },
- { 0x2100014b, 0x1400ffff },
- { 0x2100014c, 0x24000001 },
- { 0x2100014d, 0x1400ffff },
- { 0x2100014e, 0x24000001 },
- { 0x2100014f, 0x1400ffff },
- { 0x21000150, 0x24000001 },
- { 0x21000151, 0x1400ffff },
- { 0x21000152, 0x24000001 },
- { 0x21000153, 0x1400ffff },
- { 0x21000154, 0x24000001 },
- { 0x21000155, 0x1400ffff },
- { 0x21000156, 0x24000001 },
- { 0x21000157, 0x1400ffff },
- { 0x21000158, 0x24000001 },
- { 0x21000159, 0x1400ffff },
- { 0x2100015a, 0x24000001 },
- { 0x2100015b, 0x1400ffff },
- { 0x2100015c, 0x24000001 },
- { 0x2100015d, 0x1400ffff },
- { 0x2100015e, 0x24000001 },
- { 0x2100015f, 0x1400ffff },
- { 0x21000160, 0x24000001 },
- { 0x21000161, 0x1400ffff },
- { 0x21000162, 0x24000001 },
- { 0x21000163, 0x1400ffff },
- { 0x21000164, 0x24000001 },
- { 0x21000165, 0x1400ffff },
- { 0x21000166, 0x24000001 },
- { 0x21000167, 0x1400ffff },
- { 0x21000168, 0x24000001 },
- { 0x21000169, 0x1400ffff },
- { 0x2100016a, 0x24000001 },
- { 0x2100016b, 0x1400ffff },
- { 0x2100016c, 0x24000001 },
- { 0x2100016d, 0x1400ffff },
- { 0x2100016e, 0x24000001 },
- { 0x2100016f, 0x1400ffff },
- { 0x21000170, 0x24000001 },
- { 0x21000171, 0x1400ffff },
- { 0x21000172, 0x24000001 },
- { 0x21000173, 0x1400ffff },
- { 0x21000174, 0x24000001 },
- { 0x21000175, 0x1400ffff },
- { 0x21000176, 0x24000001 },
- { 0x21000177, 0x1400ffff },
- { 0x21000178, 0x2400ff87 },
- { 0x21000179, 0x24000001 },
- { 0x2100017a, 0x1400ffff },
- { 0x2100017b, 0x24000001 },
- { 0x2100017c, 0x1400ffff },
- { 0x2100017d, 0x24000001 },
- { 0x2100017e, 0x1400ffff },
- { 0x2100017f, 0x1400fed4 },
- { 0x21000180, 0x140000c3 },
- { 0x21000181, 0x240000d2 },
- { 0x21000182, 0x24000001 },
- { 0x21000183, 0x1400ffff },
- { 0x21000184, 0x24000001 },
- { 0x21000185, 0x1400ffff },
- { 0x21000186, 0x240000ce },
- { 0x21000187, 0x24000001 },
- { 0x21000188, 0x1400ffff },
- { 0x21000189, 0x240000cd },
- { 0x2100018a, 0x240000cd },
- { 0x2100018b, 0x24000001 },
- { 0x2100018c, 0x1400ffff },
- { 0x2100018d, 0x14000000 },
- { 0x2100018e, 0x2400004f },
- { 0x2100018f, 0x240000ca },
- { 0x21000190, 0x240000cb },
- { 0x21000191, 0x24000001 },
- { 0x21000192, 0x1400ffff },
- { 0x21000193, 0x240000cd },
- { 0x21000194, 0x240000cf },
- { 0x21000195, 0x14000061 },
- { 0x21000196, 0x240000d3 },
- { 0x21000197, 0x240000d1 },
- { 0x21000198, 0x24000001 },
- { 0x21000199, 0x1400ffff },
- { 0x2100019a, 0x140000a3 },
- { 0x2100019b, 0x14000000 },
- { 0x2100019c, 0x240000d3 },
- { 0x2100019d, 0x240000d5 },
- { 0x2100019e, 0x14000082 },
- { 0x2100019f, 0x240000d6 },
- { 0x210001a0, 0x24000001 },
- { 0x210001a1, 0x1400ffff },
- { 0x210001a2, 0x24000001 },
- { 0x210001a3, 0x1400ffff },
- { 0x210001a4, 0x24000001 },
- { 0x210001a5, 0x1400ffff },
- { 0x210001a6, 0x240000da },
- { 0x210001a7, 0x24000001 },
- { 0x210001a8, 0x1400ffff },
- { 0x210001a9, 0x240000da },
- { 0x218001aa, 0x14000001 },
- { 0x210001ac, 0x24000001 },
- { 0x210001ad, 0x1400ffff },
- { 0x210001ae, 0x240000da },
- { 0x210001af, 0x24000001 },
- { 0x210001b0, 0x1400ffff },
- { 0x210001b1, 0x240000d9 },
- { 0x210001b2, 0x240000d9 },
- { 0x210001b3, 0x24000001 },
- { 0x210001b4, 0x1400ffff },
- { 0x210001b5, 0x24000001 },
- { 0x210001b6, 0x1400ffff },
- { 0x210001b7, 0x240000db },
- { 0x210001b8, 0x24000001 },
- { 0x210001b9, 0x1400ffff },
- { 0x210001ba, 0x14000000 },
- { 0x210001bb, 0x1c000000 },
- { 0x210001bc, 0x24000001 },
- { 0x210001bd, 0x1400ffff },
- { 0x210001be, 0x14000000 },
- { 0x210001bf, 0x14000038 },
- { 0x218001c0, 0x1c000003 },
- { 0x210001c4, 0x24000002 },
- { 0x210001c5, 0x2000ffff },
- { 0x210001c6, 0x1400fffe },
- { 0x210001c7, 0x24000002 },
- { 0x210001c8, 0x2000ffff },
- { 0x210001c9, 0x1400fffe },
- { 0x210001ca, 0x24000002 },
- { 0x210001cb, 0x2000ffff },
- { 0x210001cc, 0x1400fffe },
- { 0x210001cd, 0x24000001 },
- { 0x210001ce, 0x1400ffff },
- { 0x210001cf, 0x24000001 },
- { 0x210001d0, 0x1400ffff },
- { 0x210001d1, 0x24000001 },
- { 0x210001d2, 0x1400ffff },
- { 0x210001d3, 0x24000001 },
- { 0x210001d4, 0x1400ffff },
- { 0x210001d5, 0x24000001 },
- { 0x210001d6, 0x1400ffff },
- { 0x210001d7, 0x24000001 },
- { 0x210001d8, 0x1400ffff },
- { 0x210001d9, 0x24000001 },
- { 0x210001da, 0x1400ffff },
- { 0x210001db, 0x24000001 },
- { 0x210001dc, 0x1400ffff },
- { 0x210001dd, 0x1400ffb1 },
- { 0x210001de, 0x24000001 },
- { 0x210001df, 0x1400ffff },
- { 0x210001e0, 0x24000001 },
- { 0x210001e1, 0x1400ffff },
- { 0x210001e2, 0x24000001 },
- { 0x210001e3, 0x1400ffff },
- { 0x210001e4, 0x24000001 },
- { 0x210001e5, 0x1400ffff },
- { 0x210001e6, 0x24000001 },
- { 0x210001e7, 0x1400ffff },
- { 0x210001e8, 0x24000001 },
- { 0x210001e9, 0x1400ffff },
- { 0x210001ea, 0x24000001 },
- { 0x210001eb, 0x1400ffff },
- { 0x210001ec, 0x24000001 },
- { 0x210001ed, 0x1400ffff },
- { 0x210001ee, 0x24000001 },
- { 0x210001ef, 0x1400ffff },
- { 0x210001f0, 0x14000000 },
- { 0x210001f1, 0x24000002 },
- { 0x210001f2, 0x2000ffff },
- { 0x210001f3, 0x1400fffe },
- { 0x210001f4, 0x24000001 },
- { 0x210001f5, 0x1400ffff },
- { 0x210001f6, 0x2400ff9f },
- { 0x210001f7, 0x2400ffc8 },
- { 0x210001f8, 0x24000001 },
- { 0x210001f9, 0x1400ffff },
- { 0x210001fa, 0x24000001 },
- { 0x210001fb, 0x1400ffff },
- { 0x210001fc, 0x24000001 },
- { 0x210001fd, 0x1400ffff },
- { 0x210001fe, 0x24000001 },
- { 0x210001ff, 0x1400ffff },
- { 0x21000200, 0x24000001 },
- { 0x21000201, 0x1400ffff },
- { 0x21000202, 0x24000001 },
- { 0x21000203, 0x1400ffff },
- { 0x21000204, 0x24000001 },
- { 0x21000205, 0x1400ffff },
- { 0x21000206, 0x24000001 },
- { 0x21000207, 0x1400ffff },
- { 0x21000208, 0x24000001 },
- { 0x21000209, 0x1400ffff },
- { 0x2100020a, 0x24000001 },
- { 0x2100020b, 0x1400ffff },
- { 0x2100020c, 0x24000001 },
- { 0x2100020d, 0x1400ffff },
- { 0x2100020e, 0x24000001 },
- { 0x2100020f, 0x1400ffff },
- { 0x21000210, 0x24000001 },
- { 0x21000211, 0x1400ffff },
- { 0x21000212, 0x24000001 },
- { 0x21000213, 0x1400ffff },
- { 0x21000214, 0x24000001 },
- { 0x21000215, 0x1400ffff },
- { 0x21000216, 0x24000001 },
- { 0x21000217, 0x1400ffff },
- { 0x21000218, 0x24000001 },
- { 0x21000219, 0x1400ffff },
- { 0x2100021a, 0x24000001 },
- { 0x2100021b, 0x1400ffff },
- { 0x2100021c, 0x24000001 },
- { 0x2100021d, 0x1400ffff },
- { 0x2100021e, 0x24000001 },
- { 0x2100021f, 0x1400ffff },
- { 0x21000220, 0x2400ff7e },
- { 0x21000221, 0x14000000 },
- { 0x21000222, 0x24000001 },
- { 0x21000223, 0x1400ffff },
- { 0x21000224, 0x24000001 },
- { 0x21000225, 0x1400ffff },
- { 0x21000226, 0x24000001 },
- { 0x21000227, 0x1400ffff },
- { 0x21000228, 0x24000001 },
- { 0x21000229, 0x1400ffff },
- { 0x2100022a, 0x24000001 },
- { 0x2100022b, 0x1400ffff },
- { 0x2100022c, 0x24000001 },
- { 0x2100022d, 0x1400ffff },
- { 0x2100022e, 0x24000001 },
- { 0x2100022f, 0x1400ffff },
- { 0x21000230, 0x24000001 },
- { 0x21000231, 0x1400ffff },
- { 0x21000232, 0x24000001 },
- { 0x21000233, 0x1400ffff },
- { 0x21800234, 0x14000005 },
- { 0x2100023a, 0x24002a2b },
- { 0x2100023b, 0x24000001 },
- { 0x2100023c, 0x1400ffff },
- { 0x2100023d, 0x2400ff5d },
- { 0x2100023e, 0x24002a28 },
- { 0x2180023f, 0x14000001 },
- { 0x21000241, 0x24000001 },
- { 0x21000242, 0x1400ffff },
- { 0x21000243, 0x2400ff3d },
- { 0x21000244, 0x24000045 },
- { 0x21000245, 0x24000047 },
- { 0x21000246, 0x24000001 },
- { 0x21000247, 0x1400ffff },
- { 0x21000248, 0x24000001 },
- { 0x21000249, 0x1400ffff },
- { 0x2100024a, 0x24000001 },
- { 0x2100024b, 0x1400ffff },
- { 0x2100024c, 0x24000001 },
- { 0x2100024d, 0x1400ffff },
- { 0x2100024e, 0x24000001 },
- { 0x2100024f, 0x1400ffff },
- { 0x21800250, 0x14000002 },
- { 0x21000253, 0x1400ff2e },
- { 0x21000254, 0x1400ff32 },
- { 0x21000255, 0x14000000 },
- { 0x21000256, 0x1400ff33 },
- { 0x21000257, 0x1400ff33 },
- { 0x21000258, 0x14000000 },
- { 0x21000259, 0x1400ff36 },
- { 0x2100025a, 0x14000000 },
- { 0x2100025b, 0x1400ff35 },
- { 0x2180025c, 0x14000003 },
- { 0x21000260, 0x1400ff33 },
- { 0x21800261, 0x14000001 },
- { 0x21000263, 0x1400ff31 },
- { 0x21800264, 0x14000003 },
- { 0x21000268, 0x1400ff2f },
- { 0x21000269, 0x1400ff2d },
- { 0x2100026a, 0x14000000 },
- { 0x2100026b, 0x140029f7 },
- { 0x2180026c, 0x14000002 },
- { 0x2100026f, 0x1400ff2d },
- { 0x21800270, 0x14000001 },
- { 0x21000272, 0x1400ff2b },
- { 0x21800273, 0x14000001 },
- { 0x21000275, 0x1400ff2a },
- { 0x21800276, 0x14000006 },
- { 0x2100027d, 0x140029e7 },
- { 0x2180027e, 0x14000001 },
- { 0x21000280, 0x1400ff26 },
- { 0x21800281, 0x14000001 },
- { 0x21000283, 0x1400ff26 },
- { 0x21800284, 0x14000003 },
- { 0x21000288, 0x1400ff26 },
- { 0x21000289, 0x1400ffbb },
- { 0x2100028a, 0x1400ff27 },
- { 0x2100028b, 0x1400ff27 },
- { 0x2100028c, 0x1400ffb9 },
- { 0x2180028d, 0x14000004 },
- { 0x21000292, 0x1400ff25 },
- { 0x21000293, 0x14000000 },
- { 0x21000294, 0x1c000000 },
- { 0x21800295, 0x1400001a },
- { 0x218002b0, 0x18000008 },
- { 0x098002b9, 0x18000008 },
- { 0x098002c2, 0x60000003 },
- { 0x098002c6, 0x1800000b },
- { 0x098002d2, 0x6000000d },
- { 0x218002e0, 0x18000004 },
- { 0x098002e5, 0x60000008 },
- { 0x090002ee, 0x18000000 },
- { 0x098002ef, 0x60000010 },
- { 0x1b800300, 0x30000044 },
- { 0x1b000345, 0x30000054 },
- { 0x1b800346, 0x30000029 },
- { 0x13800374, 0x60000001 },
- { 0x1300037a, 0x18000000 },
- { 0x1300037b, 0x14000082 },
- { 0x1300037c, 0x14000082 },
- { 0x1300037d, 0x14000082 },
- { 0x0900037e, 0x54000000 },
- { 0x13800384, 0x60000001 },
- { 0x13000386, 0x24000026 },
- { 0x09000387, 0x54000000 },
- { 0x13000388, 0x24000025 },
- { 0x13000389, 0x24000025 },
- { 0x1300038a, 0x24000025 },
- { 0x1300038c, 0x24000040 },
- { 0x1300038e, 0x2400003f },
- { 0x1300038f, 0x2400003f },
- { 0x13000390, 0x14000000 },
- { 0x13000391, 0x24000020 },
- { 0x13000392, 0x24000020 },
- { 0x13000393, 0x24000020 },
- { 0x13000394, 0x24000020 },
- { 0x13000395, 0x24000020 },
- { 0x13000396, 0x24000020 },
- { 0x13000397, 0x24000020 },
- { 0x13000398, 0x24000020 },
- { 0x13000399, 0x24000020 },
- { 0x1300039a, 0x24000020 },
- { 0x1300039b, 0x24000020 },
- { 0x1300039c, 0x24000020 },
- { 0x1300039d, 0x24000020 },
- { 0x1300039e, 0x24000020 },
- { 0x1300039f, 0x24000020 },
- { 0x130003a0, 0x24000020 },
- { 0x130003a1, 0x24000020 },
- { 0x130003a3, 0x24000020 },
- { 0x130003a4, 0x24000020 },
- { 0x130003a5, 0x24000020 },
- { 0x130003a6, 0x24000020 },
- { 0x130003a7, 0x24000020 },
- { 0x130003a8, 0x24000020 },
- { 0x130003a9, 0x24000020 },
- { 0x130003aa, 0x24000020 },
- { 0x130003ab, 0x24000020 },
- { 0x130003ac, 0x1400ffda },
- { 0x130003ad, 0x1400ffdb },
- { 0x130003ae, 0x1400ffdb },
- { 0x130003af, 0x1400ffdb },
- { 0x130003b0, 0x14000000 },
- { 0x130003b1, 0x1400ffe0 },
- { 0x130003b2, 0x1400ffe0 },
- { 0x130003b3, 0x1400ffe0 },
- { 0x130003b4, 0x1400ffe0 },
- { 0x130003b5, 0x1400ffe0 },
- { 0x130003b6, 0x1400ffe0 },
- { 0x130003b7, 0x1400ffe0 },
- { 0x130003b8, 0x1400ffe0 },
- { 0x130003b9, 0x1400ffe0 },
- { 0x130003ba, 0x1400ffe0 },
- { 0x130003bb, 0x1400ffe0 },
- { 0x130003bc, 0x1400ffe0 },
- { 0x130003bd, 0x1400ffe0 },
- { 0x130003be, 0x1400ffe0 },
- { 0x130003bf, 0x1400ffe0 },
- { 0x130003c0, 0x1400ffe0 },
- { 0x130003c1, 0x1400ffe0 },
- { 0x130003c2, 0x1400ffe1 },
- { 0x130003c3, 0x1400ffe0 },
- { 0x130003c4, 0x1400ffe0 },
- { 0x130003c5, 0x1400ffe0 },
- { 0x130003c6, 0x1400ffe0 },
- { 0x130003c7, 0x1400ffe0 },
- { 0x130003c8, 0x1400ffe0 },
- { 0x130003c9, 0x1400ffe0 },
- { 0x130003ca, 0x1400ffe0 },
- { 0x130003cb, 0x1400ffe0 },
- { 0x130003cc, 0x1400ffc0 },
- { 0x130003cd, 0x1400ffc1 },
- { 0x130003ce, 0x1400ffc1 },
- { 0x130003d0, 0x1400ffc2 },
- { 0x130003d1, 0x1400ffc7 },
- { 0x138003d2, 0x24000002 },
- { 0x130003d5, 0x1400ffd1 },
- { 0x130003d6, 0x1400ffca },
- { 0x130003d7, 0x14000000 },
- { 0x130003d8, 0x24000001 },
- { 0x130003d9, 0x1400ffff },
- { 0x130003da, 0x24000001 },
- { 0x130003db, 0x1400ffff },
- { 0x130003dc, 0x24000001 },
- { 0x130003dd, 0x1400ffff },
- { 0x130003de, 0x24000001 },
- { 0x130003df, 0x1400ffff },
- { 0x130003e0, 0x24000001 },
- { 0x130003e1, 0x1400ffff },
- { 0x0a0003e2, 0x24000001 },
- { 0x0a0003e3, 0x1400ffff },
- { 0x0a0003e4, 0x24000001 },
- { 0x0a0003e5, 0x1400ffff },
- { 0x0a0003e6, 0x24000001 },
- { 0x0a0003e7, 0x1400ffff },
- { 0x0a0003e8, 0x24000001 },
- { 0x0a0003e9, 0x1400ffff },
- { 0x0a0003ea, 0x24000001 },
- { 0x0a0003eb, 0x1400ffff },
- { 0x0a0003ec, 0x24000001 },
- { 0x0a0003ed, 0x1400ffff },
- { 0x0a0003ee, 0x24000001 },
- { 0x0a0003ef, 0x1400ffff },
- { 0x130003f0, 0x1400ffaa },
- { 0x130003f1, 0x1400ffb0 },
- { 0x130003f2, 0x14000007 },
- { 0x130003f3, 0x14000000 },
- { 0x130003f4, 0x2400ffc4 },
- { 0x130003f5, 0x1400ffa0 },
- { 0x130003f6, 0x64000000 },
- { 0x130003f7, 0x24000001 },
- { 0x130003f8, 0x1400ffff },
- { 0x130003f9, 0x2400fff9 },
- { 0x130003fa, 0x24000001 },
- { 0x130003fb, 0x1400ffff },
- { 0x130003fc, 0x14000000 },
- { 0x130003fd, 0x2400ff7e },
- { 0x130003fe, 0x2400ff7e },
- { 0x130003ff, 0x2400ff7e },
- { 0x0c000400, 0x24000050 },
- { 0x0c000401, 0x24000050 },
- { 0x0c000402, 0x24000050 },
- { 0x0c000403, 0x24000050 },
- { 0x0c000404, 0x24000050 },
- { 0x0c000405, 0x24000050 },
- { 0x0c000406, 0x24000050 },
- { 0x0c000407, 0x24000050 },
- { 0x0c000408, 0x24000050 },
- { 0x0c000409, 0x24000050 },
- { 0x0c00040a, 0x24000050 },
- { 0x0c00040b, 0x24000050 },
- { 0x0c00040c, 0x24000050 },
- { 0x0c00040d, 0x24000050 },
- { 0x0c00040e, 0x24000050 },
- { 0x0c00040f, 0x24000050 },
- { 0x0c000410, 0x24000020 },
- { 0x0c000411, 0x24000020 },
- { 0x0c000412, 0x24000020 },
- { 0x0c000413, 0x24000020 },
- { 0x0c000414, 0x24000020 },
- { 0x0c000415, 0x24000020 },
- { 0x0c000416, 0x24000020 },
- { 0x0c000417, 0x24000020 },
- { 0x0c000418, 0x24000020 },
- { 0x0c000419, 0x24000020 },
- { 0x0c00041a, 0x24000020 },
- { 0x0c00041b, 0x24000020 },
- { 0x0c00041c, 0x24000020 },
- { 0x0c00041d, 0x24000020 },
- { 0x0c00041e, 0x24000020 },
- { 0x0c00041f, 0x24000020 },
- { 0x0c000420, 0x24000020 },
- { 0x0c000421, 0x24000020 },
- { 0x0c000422, 0x24000020 },
- { 0x0c000423, 0x24000020 },
- { 0x0c000424, 0x24000020 },
- { 0x0c000425, 0x24000020 },
- { 0x0c000426, 0x24000020 },
- { 0x0c000427, 0x24000020 },
- { 0x0c000428, 0x24000020 },
- { 0x0c000429, 0x24000020 },
- { 0x0c00042a, 0x24000020 },
- { 0x0c00042b, 0x24000020 },
- { 0x0c00042c, 0x24000020 },
- { 0x0c00042d, 0x24000020 },
- { 0x0c00042e, 0x24000020 },
- { 0x0c00042f, 0x24000020 },
- { 0x0c000430, 0x1400ffe0 },
- { 0x0c000431, 0x1400ffe0 },
- { 0x0c000432, 0x1400ffe0 },
- { 0x0c000433, 0x1400ffe0 },
- { 0x0c000434, 0x1400ffe0 },
- { 0x0c000435, 0x1400ffe0 },
- { 0x0c000436, 0x1400ffe0 },
- { 0x0c000437, 0x1400ffe0 },
- { 0x0c000438, 0x1400ffe0 },
- { 0x0c000439, 0x1400ffe0 },
- { 0x0c00043a, 0x1400ffe0 },
- { 0x0c00043b, 0x1400ffe0 },
- { 0x0c00043c, 0x1400ffe0 },
- { 0x0c00043d, 0x1400ffe0 },
- { 0x0c00043e, 0x1400ffe0 },
- { 0x0c00043f, 0x1400ffe0 },
- { 0x0c000440, 0x1400ffe0 },
- { 0x0c000441, 0x1400ffe0 },
- { 0x0c000442, 0x1400ffe0 },
- { 0x0c000443, 0x1400ffe0 },
- { 0x0c000444, 0x1400ffe0 },
- { 0x0c000445, 0x1400ffe0 },
- { 0x0c000446, 0x1400ffe0 },
- { 0x0c000447, 0x1400ffe0 },
- { 0x0c000448, 0x1400ffe0 },
- { 0x0c000449, 0x1400ffe0 },
- { 0x0c00044a, 0x1400ffe0 },
- { 0x0c00044b, 0x1400ffe0 },
- { 0x0c00044c, 0x1400ffe0 },
- { 0x0c00044d, 0x1400ffe0 },
- { 0x0c00044e, 0x1400ffe0 },
- { 0x0c00044f, 0x1400ffe0 },
- { 0x0c000450, 0x1400ffb0 },
- { 0x0c000451, 0x1400ffb0 },
- { 0x0c000452, 0x1400ffb0 },
- { 0x0c000453, 0x1400ffb0 },
- { 0x0c000454, 0x1400ffb0 },
- { 0x0c000455, 0x1400ffb0 },
- { 0x0c000456, 0x1400ffb0 },
- { 0x0c000457, 0x1400ffb0 },
- { 0x0c000458, 0x1400ffb0 },
- { 0x0c000459, 0x1400ffb0 },
- { 0x0c00045a, 0x1400ffb0 },
- { 0x0c00045b, 0x1400ffb0 },
- { 0x0c00045c, 0x1400ffb0 },
- { 0x0c00045d, 0x1400ffb0 },
- { 0x0c00045e, 0x1400ffb0 },
- { 0x0c00045f, 0x1400ffb0 },
- { 0x0c000460, 0x24000001 },
- { 0x0c000461, 0x1400ffff },
- { 0x0c000462, 0x24000001 },
- { 0x0c000463, 0x1400ffff },
- { 0x0c000464, 0x24000001 },
- { 0x0c000465, 0x1400ffff },
- { 0x0c000466, 0x24000001 },
- { 0x0c000467, 0x1400ffff },
- { 0x0c000468, 0x24000001 },
- { 0x0c000469, 0x1400ffff },
- { 0x0c00046a, 0x24000001 },
- { 0x0c00046b, 0x1400ffff },
- { 0x0c00046c, 0x24000001 },
- { 0x0c00046d, 0x1400ffff },
- { 0x0c00046e, 0x24000001 },
- { 0x0c00046f, 0x1400ffff },
- { 0x0c000470, 0x24000001 },
- { 0x0c000471, 0x1400ffff },
- { 0x0c000472, 0x24000001 },
- { 0x0c000473, 0x1400ffff },
- { 0x0c000474, 0x24000001 },
- { 0x0c000475, 0x1400ffff },
- { 0x0c000476, 0x24000001 },
- { 0x0c000477, 0x1400ffff },
- { 0x0c000478, 0x24000001 },
- { 0x0c000479, 0x1400ffff },
- { 0x0c00047a, 0x24000001 },
- { 0x0c00047b, 0x1400ffff },
- { 0x0c00047c, 0x24000001 },
- { 0x0c00047d, 0x1400ffff },
- { 0x0c00047e, 0x24000001 },
- { 0x0c00047f, 0x1400ffff },
- { 0x0c000480, 0x24000001 },
- { 0x0c000481, 0x1400ffff },
- { 0x0c000482, 0x68000000 },
- { 0x0c800483, 0x30000003 },
- { 0x0c800488, 0x2c000001 },
- { 0x0c00048a, 0x24000001 },
- { 0x0c00048b, 0x1400ffff },
- { 0x0c00048c, 0x24000001 },
- { 0x0c00048d, 0x1400ffff },
- { 0x0c00048e, 0x24000001 },
- { 0x0c00048f, 0x1400ffff },
- { 0x0c000490, 0x24000001 },
- { 0x0c000491, 0x1400ffff },
- { 0x0c000492, 0x24000001 },
- { 0x0c000493, 0x1400ffff },
- { 0x0c000494, 0x24000001 },
- { 0x0c000495, 0x1400ffff },
- { 0x0c000496, 0x24000001 },
- { 0x0c000497, 0x1400ffff },
- { 0x0c000498, 0x24000001 },
- { 0x0c000499, 0x1400ffff },
- { 0x0c00049a, 0x24000001 },
- { 0x0c00049b, 0x1400ffff },
- { 0x0c00049c, 0x24000001 },
- { 0x0c00049d, 0x1400ffff },
- { 0x0c00049e, 0x24000001 },
- { 0x0c00049f, 0x1400ffff },
- { 0x0c0004a0, 0x24000001 },
- { 0x0c0004a1, 0x1400ffff },
- { 0x0c0004a2, 0x24000001 },
- { 0x0c0004a3, 0x1400ffff },
- { 0x0c0004a4, 0x24000001 },
- { 0x0c0004a5, 0x1400ffff },
- { 0x0c0004a6, 0x24000001 },
- { 0x0c0004a7, 0x1400ffff },
- { 0x0c0004a8, 0x24000001 },
- { 0x0c0004a9, 0x1400ffff },
- { 0x0c0004aa, 0x24000001 },
- { 0x0c0004ab, 0x1400ffff },
- { 0x0c0004ac, 0x24000001 },
- { 0x0c0004ad, 0x1400ffff },
- { 0x0c0004ae, 0x24000001 },
- { 0x0c0004af, 0x1400ffff },
- { 0x0c0004b0, 0x24000001 },
- { 0x0c0004b1, 0x1400ffff },
- { 0x0c0004b2, 0x24000001 },
- { 0x0c0004b3, 0x1400ffff },
- { 0x0c0004b4, 0x24000001 },
- { 0x0c0004b5, 0x1400ffff },
- { 0x0c0004b6, 0x24000001 },
- { 0x0c0004b7, 0x1400ffff },
- { 0x0c0004b8, 0x24000001 },
- { 0x0c0004b9, 0x1400ffff },
- { 0x0c0004ba, 0x24000001 },
- { 0x0c0004bb, 0x1400ffff },
- { 0x0c0004bc, 0x24000001 },
- { 0x0c0004bd, 0x1400ffff },
- { 0x0c0004be, 0x24000001 },
- { 0x0c0004bf, 0x1400ffff },
- { 0x0c0004c0, 0x2400000f },
- { 0x0c0004c1, 0x24000001 },
- { 0x0c0004c2, 0x1400ffff },
- { 0x0c0004c3, 0x24000001 },
- { 0x0c0004c4, 0x1400ffff },
- { 0x0c0004c5, 0x24000001 },
- { 0x0c0004c6, 0x1400ffff },
- { 0x0c0004c7, 0x24000001 },
- { 0x0c0004c8, 0x1400ffff },
- { 0x0c0004c9, 0x24000001 },
- { 0x0c0004ca, 0x1400ffff },
- { 0x0c0004cb, 0x24000001 },
- { 0x0c0004cc, 0x1400ffff },
- { 0x0c0004cd, 0x24000001 },
- { 0x0c0004ce, 0x1400ffff },
- { 0x0c0004cf, 0x1400fff1 },
- { 0x0c0004d0, 0x24000001 },
- { 0x0c0004d1, 0x1400ffff },
- { 0x0c0004d2, 0x24000001 },
- { 0x0c0004d3, 0x1400ffff },
- { 0x0c0004d4, 0x24000001 },
- { 0x0c0004d5, 0x1400ffff },
- { 0x0c0004d6, 0x24000001 },
- { 0x0c0004d7, 0x1400ffff },
- { 0x0c0004d8, 0x24000001 },
- { 0x0c0004d9, 0x1400ffff },
- { 0x0c0004da, 0x24000001 },
- { 0x0c0004db, 0x1400ffff },
- { 0x0c0004dc, 0x24000001 },
- { 0x0c0004dd, 0x1400ffff },
- { 0x0c0004de, 0x24000001 },
- { 0x0c0004df, 0x1400ffff },
- { 0x0c0004e0, 0x24000001 },
- { 0x0c0004e1, 0x1400ffff },
- { 0x0c0004e2, 0x24000001 },
- { 0x0c0004e3, 0x1400ffff },
- { 0x0c0004e4, 0x24000001 },
- { 0x0c0004e5, 0x1400ffff },
- { 0x0c0004e6, 0x24000001 },
- { 0x0c0004e7, 0x1400ffff },
- { 0x0c0004e8, 0x24000001 },
- { 0x0c0004e9, 0x1400ffff },
- { 0x0c0004ea, 0x24000001 },
- { 0x0c0004eb, 0x1400ffff },
- { 0x0c0004ec, 0x24000001 },
- { 0x0c0004ed, 0x1400ffff },
- { 0x0c0004ee, 0x24000001 },
- { 0x0c0004ef, 0x1400ffff },
- { 0x0c0004f0, 0x24000001 },
- { 0x0c0004f1, 0x1400ffff },
- { 0x0c0004f2, 0x24000001 },
- { 0x0c0004f3, 0x1400ffff },
- { 0x0c0004f4, 0x24000001 },
- { 0x0c0004f5, 0x1400ffff },
- { 0x0c0004f6, 0x24000001 },
- { 0x0c0004f7, 0x1400ffff },
- { 0x0c0004f8, 0x24000001 },
- { 0x0c0004f9, 0x1400ffff },
- { 0x0c0004fa, 0x24000001 },
- { 0x0c0004fb, 0x1400ffff },
- { 0x0c0004fc, 0x24000001 },
- { 0x0c0004fd, 0x1400ffff },
- { 0x0c0004fe, 0x24000001 },
- { 0x0c0004ff, 0x1400ffff },
- { 0x0c000500, 0x24000001 },
- { 0x0c000501, 0x1400ffff },
- { 0x0c000502, 0x24000001 },
- { 0x0c000503, 0x1400ffff },
- { 0x0c000504, 0x24000001 },
- { 0x0c000505, 0x1400ffff },
- { 0x0c000506, 0x24000001 },
- { 0x0c000507, 0x1400ffff },
- { 0x0c000508, 0x24000001 },
- { 0x0c000509, 0x1400ffff },
- { 0x0c00050a, 0x24000001 },
- { 0x0c00050b, 0x1400ffff },
- { 0x0c00050c, 0x24000001 },
- { 0x0c00050d, 0x1400ffff },
- { 0x0c00050e, 0x24000001 },
- { 0x0c00050f, 0x1400ffff },
- { 0x0c000510, 0x24000001 },
- { 0x0c000511, 0x1400ffff },
- { 0x0c000512, 0x24000001 },
- { 0x0c000513, 0x1400ffff },
- { 0x01000531, 0x24000030 },
- { 0x01000532, 0x24000030 },
- { 0x01000533, 0x24000030 },
- { 0x01000534, 0x24000030 },
- { 0x01000535, 0x24000030 },
- { 0x01000536, 0x24000030 },
- { 0x01000537, 0x24000030 },
- { 0x01000538, 0x24000030 },
- { 0x01000539, 0x24000030 },
- { 0x0100053a, 0x24000030 },
- { 0x0100053b, 0x24000030 },
- { 0x0100053c, 0x24000030 },
- { 0x0100053d, 0x24000030 },
- { 0x0100053e, 0x24000030 },
- { 0x0100053f, 0x24000030 },
- { 0x01000540, 0x24000030 },
- { 0x01000541, 0x24000030 },
- { 0x01000542, 0x24000030 },
- { 0x01000543, 0x24000030 },
- { 0x01000544, 0x24000030 },
- { 0x01000545, 0x24000030 },
- { 0x01000546, 0x24000030 },
- { 0x01000547, 0x24000030 },
- { 0x01000548, 0x24000030 },
- { 0x01000549, 0x24000030 },
- { 0x0100054a, 0x24000030 },
- { 0x0100054b, 0x24000030 },
- { 0x0100054c, 0x24000030 },
- { 0x0100054d, 0x24000030 },
- { 0x0100054e, 0x24000030 },
- { 0x0100054f, 0x24000030 },
- { 0x01000550, 0x24000030 },
- { 0x01000551, 0x24000030 },
- { 0x01000552, 0x24000030 },
- { 0x01000553, 0x24000030 },
- { 0x01000554, 0x24000030 },
- { 0x01000555, 0x24000030 },
- { 0x01000556, 0x24000030 },
- { 0x01000559, 0x18000000 },
- { 0x0180055a, 0x54000005 },
- { 0x01000561, 0x1400ffd0 },
- { 0x01000562, 0x1400ffd0 },
- { 0x01000563, 0x1400ffd0 },
- { 0x01000564, 0x1400ffd0 },
- { 0x01000565, 0x1400ffd0 },
- { 0x01000566, 0x1400ffd0 },
- { 0x01000567, 0x1400ffd0 },
- { 0x01000568, 0x1400ffd0 },
- { 0x01000569, 0x1400ffd0 },
- { 0x0100056a, 0x1400ffd0 },
- { 0x0100056b, 0x1400ffd0 },
- { 0x0100056c, 0x1400ffd0 },
- { 0x0100056d, 0x1400ffd0 },
- { 0x0100056e, 0x1400ffd0 },
- { 0x0100056f, 0x1400ffd0 },
- { 0x01000570, 0x1400ffd0 },
- { 0x01000571, 0x1400ffd0 },
- { 0x01000572, 0x1400ffd0 },
- { 0x01000573, 0x1400ffd0 },
- { 0x01000574, 0x1400ffd0 },
- { 0x01000575, 0x1400ffd0 },
- { 0x01000576, 0x1400ffd0 },
- { 0x01000577, 0x1400ffd0 },
- { 0x01000578, 0x1400ffd0 },
- { 0x01000579, 0x1400ffd0 },
- { 0x0100057a, 0x1400ffd0 },
- { 0x0100057b, 0x1400ffd0 },
- { 0x0100057c, 0x1400ffd0 },
- { 0x0100057d, 0x1400ffd0 },
- { 0x0100057e, 0x1400ffd0 },
- { 0x0100057f, 0x1400ffd0 },
- { 0x01000580, 0x1400ffd0 },
- { 0x01000581, 0x1400ffd0 },
- { 0x01000582, 0x1400ffd0 },
- { 0x01000583, 0x1400ffd0 },
- { 0x01000584, 0x1400ffd0 },
- { 0x01000585, 0x1400ffd0 },
- { 0x01000586, 0x1400ffd0 },
- { 0x01000587, 0x14000000 },
- { 0x09000589, 0x54000000 },
- { 0x0100058a, 0x44000000 },
- { 0x19800591, 0x3000002c },
- { 0x190005be, 0x54000000 },
- { 0x190005bf, 0x30000000 },
- { 0x190005c0, 0x54000000 },
- { 0x198005c1, 0x30000001 },
- { 0x190005c3, 0x54000000 },
- { 0x198005c4, 0x30000001 },
- { 0x190005c6, 0x54000000 },
- { 0x190005c7, 0x30000000 },
- { 0x198005d0, 0x1c00001a },
- { 0x198005f0, 0x1c000002 },
- { 0x198005f3, 0x54000001 },
- { 0x09800600, 0x04000003 },
- { 0x0000060b, 0x5c000000 },
- { 0x0900060c, 0x54000000 },
- { 0x0000060d, 0x54000000 },
- { 0x0080060e, 0x68000001 },
- { 0x00800610, 0x30000005 },
- { 0x0900061b, 0x54000000 },
- { 0x0000061e, 0x54000000 },
- { 0x0900061f, 0x54000000 },
- { 0x00800621, 0x1c000019 },
- { 0x09000640, 0x18000000 },
- { 0x00800641, 0x1c000009 },
- { 0x1b80064b, 0x3000000a },
- { 0x00800656, 0x30000008 },
- { 0x09800660, 0x34000009 },
- { 0x0080066a, 0x54000003 },
- { 0x0080066e, 0x1c000001 },
- { 0x1b000670, 0x30000000 },
- { 0x00800671, 0x1c000062 },
- { 0x000006d4, 0x54000000 },
- { 0x000006d5, 0x1c000000 },
- { 0x008006d6, 0x30000006 },
- { 0x090006dd, 0x04000000 },
- { 0x000006de, 0x2c000000 },
- { 0x008006df, 0x30000005 },
- { 0x008006e5, 0x18000001 },
- { 0x008006e7, 0x30000001 },
- { 0x000006e9, 0x68000000 },
- { 0x008006ea, 0x30000003 },
- { 0x008006ee, 0x1c000001 },
- { 0x008006f0, 0x34000009 },
- { 0x008006fa, 0x1c000002 },
- { 0x008006fd, 0x68000001 },
- { 0x000006ff, 0x1c000000 },
- { 0x31800700, 0x5400000d },
- { 0x3100070f, 0x04000000 },
- { 0x31000710, 0x1c000000 },
- { 0x31000711, 0x30000000 },
- { 0x31800712, 0x1c00001d },
- { 0x31800730, 0x3000001a },
- { 0x3180074d, 0x1c000002 },
- { 0x00800750, 0x1c00001d },
- { 0x37800780, 0x1c000025 },
- { 0x378007a6, 0x3000000a },
- { 0x370007b1, 0x1c000000 },
- { 0x3f8007c0, 0x34000009 },
- { 0x3f8007ca, 0x1c000020 },
- { 0x3f8007eb, 0x30000008 },
- { 0x3f8007f4, 0x18000001 },
- { 0x3f0007f6, 0x68000000 },
- { 0x3f8007f7, 0x54000002 },
- { 0x3f0007fa, 0x18000000 },
- { 0x0e800901, 0x30000001 },
- { 0x0e000903, 0x28000000 },
- { 0x0e800904, 0x1c000035 },
- { 0x0e00093c, 0x30000000 },
- { 0x0e00093d, 0x1c000000 },
- { 0x0e80093e, 0x28000002 },
- { 0x0e800941, 0x30000007 },
- { 0x0e800949, 0x28000003 },
- { 0x0e00094d, 0x30000000 },
- { 0x0e000950, 0x1c000000 },
- { 0x0e800951, 0x30000003 },
- { 0x0e800958, 0x1c000009 },
- { 0x0e800962, 0x30000001 },
- { 0x09800964, 0x54000001 },
- { 0x0e800966, 0x34000009 },
- { 0x09000970, 0x54000000 },
- { 0x0e80097b, 0x1c000004 },
- { 0x02000981, 0x30000000 },
- { 0x02800982, 0x28000001 },
- { 0x02800985, 0x1c000007 },
- { 0x0280098f, 0x1c000001 },
- { 0x02800993, 0x1c000015 },
- { 0x028009aa, 0x1c000006 },
- { 0x020009b2, 0x1c000000 },
- { 0x028009b6, 0x1c000003 },
- { 0x020009bc, 0x30000000 },
- { 0x020009bd, 0x1c000000 },
- { 0x028009be, 0x28000002 },
- { 0x028009c1, 0x30000003 },
- { 0x028009c7, 0x28000001 },
- { 0x028009cb, 0x28000001 },
- { 0x020009cd, 0x30000000 },
- { 0x020009ce, 0x1c000000 },
- { 0x020009d7, 0x28000000 },
- { 0x028009dc, 0x1c000001 },
- { 0x028009df, 0x1c000002 },
- { 0x028009e2, 0x30000001 },
- { 0x028009e6, 0x34000009 },
- { 0x028009f0, 0x1c000001 },
- { 0x028009f2, 0x5c000001 },
- { 0x028009f4, 0x3c000005 },
- { 0x020009fa, 0x68000000 },
- { 0x15800a01, 0x30000001 },
- { 0x15000a03, 0x28000000 },
- { 0x15800a05, 0x1c000005 },
- { 0x15800a0f, 0x1c000001 },
- { 0x15800a13, 0x1c000015 },
- { 0x15800a2a, 0x1c000006 },
- { 0x15800a32, 0x1c000001 },
- { 0x15800a35, 0x1c000001 },
- { 0x15800a38, 0x1c000001 },
- { 0x15000a3c, 0x30000000 },
- { 0x15800a3e, 0x28000002 },
- { 0x15800a41, 0x30000001 },
- { 0x15800a47, 0x30000001 },
- { 0x15800a4b, 0x30000002 },
- { 0x15800a59, 0x1c000003 },
- { 0x15000a5e, 0x1c000000 },
- { 0x15800a66, 0x34000009 },
- { 0x15800a70, 0x30000001 },
- { 0x15800a72, 0x1c000002 },
- { 0x14800a81, 0x30000001 },
- { 0x14000a83, 0x28000000 },
- { 0x14800a85, 0x1c000008 },
- { 0x14800a8f, 0x1c000002 },
- { 0x14800a93, 0x1c000015 },
- { 0x14800aaa, 0x1c000006 },
- { 0x14800ab2, 0x1c000001 },
- { 0x14800ab5, 0x1c000004 },
- { 0x14000abc, 0x30000000 },
- { 0x14000abd, 0x1c000000 },
- { 0x14800abe, 0x28000002 },
- { 0x14800ac1, 0x30000004 },
- { 0x14800ac7, 0x30000001 },
- { 0x14000ac9, 0x28000000 },
- { 0x14800acb, 0x28000001 },
- { 0x14000acd, 0x30000000 },
- { 0x14000ad0, 0x1c000000 },
- { 0x14800ae0, 0x1c000001 },
- { 0x14800ae2, 0x30000001 },
- { 0x14800ae6, 0x34000009 },
- { 0x14000af1, 0x5c000000 },
- { 0x2b000b01, 0x30000000 },
- { 0x2b800b02, 0x28000001 },
- { 0x2b800b05, 0x1c000007 },
- { 0x2b800b0f, 0x1c000001 },
- { 0x2b800b13, 0x1c000015 },
- { 0x2b800b2a, 0x1c000006 },
- { 0x2b800b32, 0x1c000001 },
- { 0x2b800b35, 0x1c000004 },
- { 0x2b000b3c, 0x30000000 },
- { 0x2b000b3d, 0x1c000000 },
- { 0x2b000b3e, 0x28000000 },
- { 0x2b000b3f, 0x30000000 },
- { 0x2b000b40, 0x28000000 },
- { 0x2b800b41, 0x30000002 },
- { 0x2b800b47, 0x28000001 },
- { 0x2b800b4b, 0x28000001 },
- { 0x2b000b4d, 0x30000000 },
- { 0x2b000b56, 0x30000000 },
- { 0x2b000b57, 0x28000000 },
- { 0x2b800b5c, 0x1c000001 },
- { 0x2b800b5f, 0x1c000002 },
- { 0x2b800b66, 0x34000009 },
- { 0x2b000b70, 0x68000000 },
- { 0x2b000b71, 0x1c000000 },
- { 0x35000b82, 0x30000000 },
- { 0x35000b83, 0x1c000000 },
- { 0x35800b85, 0x1c000005 },
- { 0x35800b8e, 0x1c000002 },
- { 0x35800b92, 0x1c000003 },
- { 0x35800b99, 0x1c000001 },
- { 0x35000b9c, 0x1c000000 },
- { 0x35800b9e, 0x1c000001 },
- { 0x35800ba3, 0x1c000001 },
- { 0x35800ba8, 0x1c000002 },
- { 0x35800bae, 0x1c00000b },
- { 0x35800bbe, 0x28000001 },
- { 0x35000bc0, 0x30000000 },
- { 0x35800bc1, 0x28000001 },
- { 0x35800bc6, 0x28000002 },
- { 0x35800bca, 0x28000002 },
- { 0x35000bcd, 0x30000000 },
- { 0x35000bd7, 0x28000000 },
- { 0x35800be6, 0x34000009 },
- { 0x35800bf0, 0x3c000002 },
- { 0x35800bf3, 0x68000005 },
- { 0x35000bf9, 0x5c000000 },
- { 0x35000bfa, 0x68000000 },
- { 0x36800c01, 0x28000002 },
- { 0x36800c05, 0x1c000007 },
- { 0x36800c0e, 0x1c000002 },
- { 0x36800c12, 0x1c000016 },
- { 0x36800c2a, 0x1c000009 },
- { 0x36800c35, 0x1c000004 },
- { 0x36800c3e, 0x30000002 },
- { 0x36800c41, 0x28000003 },
- { 0x36800c46, 0x30000002 },
- { 0x36800c4a, 0x30000003 },
- { 0x36800c55, 0x30000001 },
- { 0x36800c60, 0x1c000001 },
- { 0x36800c66, 0x34000009 },
- { 0x1c800c82, 0x28000001 },
- { 0x1c800c85, 0x1c000007 },
- { 0x1c800c8e, 0x1c000002 },
- { 0x1c800c92, 0x1c000016 },
- { 0x1c800caa, 0x1c000009 },
- { 0x1c800cb5, 0x1c000004 },
- { 0x1c000cbc, 0x30000000 },
- { 0x1c000cbd, 0x1c000000 },
- { 0x1c000cbe, 0x28000000 },
- { 0x1c000cbf, 0x30000000 },
- { 0x1c800cc0, 0x28000004 },
- { 0x1c000cc6, 0x30000000 },
- { 0x1c800cc7, 0x28000001 },
- { 0x1c800cca, 0x28000001 },
- { 0x1c800ccc, 0x30000001 },
- { 0x1c800cd5, 0x28000001 },
- { 0x1c000cde, 0x1c000000 },
- { 0x1c800ce0, 0x1c000001 },
- { 0x1c800ce2, 0x30000001 },
- { 0x1c800ce6, 0x34000009 },
- { 0x1c800cf1, 0x68000001 },
- { 0x24800d02, 0x28000001 },
- { 0x24800d05, 0x1c000007 },
- { 0x24800d0e, 0x1c000002 },
- { 0x24800d12, 0x1c000016 },
- { 0x24800d2a, 0x1c00000f },
- { 0x24800d3e, 0x28000002 },
- { 0x24800d41, 0x30000002 },
- { 0x24800d46, 0x28000002 },
- { 0x24800d4a, 0x28000002 },
- { 0x24000d4d, 0x30000000 },
- { 0x24000d57, 0x28000000 },
- { 0x24800d60, 0x1c000001 },
- { 0x24800d66, 0x34000009 },
- { 0x2f800d82, 0x28000001 },
- { 0x2f800d85, 0x1c000011 },
- { 0x2f800d9a, 0x1c000017 },
- { 0x2f800db3, 0x1c000008 },
- { 0x2f000dbd, 0x1c000000 },
- { 0x2f800dc0, 0x1c000006 },
- { 0x2f000dca, 0x30000000 },
- { 0x2f800dcf, 0x28000002 },
- { 0x2f800dd2, 0x30000002 },
- { 0x2f000dd6, 0x30000000 },
- { 0x2f800dd8, 0x28000007 },
- { 0x2f800df2, 0x28000001 },
- { 0x2f000df4, 0x54000000 },
- { 0x38800e01, 0x1c00002f },
- { 0x38000e31, 0x30000000 },
- { 0x38800e32, 0x1c000001 },
- { 0x38800e34, 0x30000006 },
- { 0x09000e3f, 0x5c000000 },
- { 0x38800e40, 0x1c000005 },
- { 0x38000e46, 0x18000000 },
- { 0x38800e47, 0x30000007 },
- { 0x38000e4f, 0x54000000 },
- { 0x38800e50, 0x34000009 },
- { 0x38800e5a, 0x54000001 },
- { 0x20800e81, 0x1c000001 },
- { 0x20000e84, 0x1c000000 },
- { 0x20800e87, 0x1c000001 },
- { 0x20000e8a, 0x1c000000 },
- { 0x20000e8d, 0x1c000000 },
- { 0x20800e94, 0x1c000003 },
- { 0x20800e99, 0x1c000006 },
- { 0x20800ea1, 0x1c000002 },
- { 0x20000ea5, 0x1c000000 },
- { 0x20000ea7, 0x1c000000 },
- { 0x20800eaa, 0x1c000001 },
- { 0x20800ead, 0x1c000003 },
- { 0x20000eb1, 0x30000000 },
- { 0x20800eb2, 0x1c000001 },
- { 0x20800eb4, 0x30000005 },
- { 0x20800ebb, 0x30000001 },
- { 0x20000ebd, 0x1c000000 },
- { 0x20800ec0, 0x1c000004 },
- { 0x20000ec6, 0x18000000 },
- { 0x20800ec8, 0x30000005 },
- { 0x20800ed0, 0x34000009 },
- { 0x20800edc, 0x1c000001 },
- { 0x39000f00, 0x1c000000 },
- { 0x39800f01, 0x68000002 },
- { 0x39800f04, 0x5400000e },
- { 0x39800f13, 0x68000004 },
- { 0x39800f18, 0x30000001 },
- { 0x39800f1a, 0x68000005 },
- { 0x39800f20, 0x34000009 },
- { 0x39800f2a, 0x3c000009 },
- { 0x39000f34, 0x68000000 },
- { 0x39000f35, 0x30000000 },
- { 0x39000f36, 0x68000000 },
- { 0x39000f37, 0x30000000 },
- { 0x39000f38, 0x68000000 },
- { 0x39000f39, 0x30000000 },
- { 0x39000f3a, 0x58000000 },
- { 0x39000f3b, 0x48000000 },
- { 0x39000f3c, 0x58000000 },
- { 0x39000f3d, 0x48000000 },
- { 0x39800f3e, 0x28000001 },
- { 0x39800f40, 0x1c000007 },
- { 0x39800f49, 0x1c000021 },
- { 0x39800f71, 0x3000000d },
- { 0x39000f7f, 0x28000000 },
- { 0x39800f80, 0x30000004 },
- { 0x39000f85, 0x54000000 },
- { 0x39800f86, 0x30000001 },
- { 0x39800f88, 0x1c000003 },
- { 0x39800f90, 0x30000007 },
- { 0x39800f99, 0x30000023 },
- { 0x39800fbe, 0x68000007 },
- { 0x39000fc6, 0x30000000 },
- { 0x39800fc7, 0x68000005 },
- { 0x39000fcf, 0x68000000 },
- { 0x39800fd0, 0x54000001 },
- { 0x26801000, 0x1c000021 },
- { 0x26801023, 0x1c000004 },
- { 0x26801029, 0x1c000001 },
- { 0x2600102c, 0x28000000 },
- { 0x2680102d, 0x30000003 },
- { 0x26001031, 0x28000000 },
- { 0x26001032, 0x30000000 },
- { 0x26801036, 0x30000001 },
- { 0x26001038, 0x28000000 },
- { 0x26001039, 0x30000000 },
- { 0x26801040, 0x34000009 },
- { 0x2680104a, 0x54000005 },
- { 0x26801050, 0x1c000005 },
- { 0x26801056, 0x28000001 },
- { 0x26801058, 0x30000001 },
- { 0x100010a0, 0x24001c60 },
- { 0x100010a1, 0x24001c60 },
- { 0x100010a2, 0x24001c60 },
- { 0x100010a3, 0x24001c60 },
- { 0x100010a4, 0x24001c60 },
- { 0x100010a5, 0x24001c60 },
- { 0x100010a6, 0x24001c60 },
- { 0x100010a7, 0x24001c60 },
- { 0x100010a8, 0x24001c60 },
- { 0x100010a9, 0x24001c60 },
- { 0x100010aa, 0x24001c60 },
- { 0x100010ab, 0x24001c60 },
- { 0x100010ac, 0x24001c60 },
- { 0x100010ad, 0x24001c60 },
- { 0x100010ae, 0x24001c60 },
- { 0x100010af, 0x24001c60 },
- { 0x100010b0, 0x24001c60 },
- { 0x100010b1, 0x24001c60 },
- { 0x100010b2, 0x24001c60 },
- { 0x100010b3, 0x24001c60 },
- { 0x100010b4, 0x24001c60 },
- { 0x100010b5, 0x24001c60 },
- { 0x100010b6, 0x24001c60 },
- { 0x100010b7, 0x24001c60 },
- { 0x100010b8, 0x24001c60 },
- { 0x100010b9, 0x24001c60 },
- { 0x100010ba, 0x24001c60 },
- { 0x100010bb, 0x24001c60 },
- { 0x100010bc, 0x24001c60 },
- { 0x100010bd, 0x24001c60 },
- { 0x100010be, 0x24001c60 },
- { 0x100010bf, 0x24001c60 },
- { 0x100010c0, 0x24001c60 },
- { 0x100010c1, 0x24001c60 },
- { 0x100010c2, 0x24001c60 },
- { 0x100010c3, 0x24001c60 },
- { 0x100010c4, 0x24001c60 },
- { 0x100010c5, 0x24001c60 },
- { 0x108010d0, 0x1c00002a },
- { 0x090010fb, 0x54000000 },
- { 0x100010fc, 0x18000000 },
- { 0x17801100, 0x1c000059 },
- { 0x1780115f, 0x1c000043 },
- { 0x178011a8, 0x1c000051 },
- { 0x0f801200, 0x1c000048 },
- { 0x0f80124a, 0x1c000003 },
- { 0x0f801250, 0x1c000006 },
- { 0x0f001258, 0x1c000000 },
- { 0x0f80125a, 0x1c000003 },
- { 0x0f801260, 0x1c000028 },
- { 0x0f80128a, 0x1c000003 },
- { 0x0f801290, 0x1c000020 },
- { 0x0f8012b2, 0x1c000003 },
- { 0x0f8012b8, 0x1c000006 },
- { 0x0f0012c0, 0x1c000000 },
- { 0x0f8012c2, 0x1c000003 },
- { 0x0f8012c8, 0x1c00000e },
- { 0x0f8012d8, 0x1c000038 },
- { 0x0f801312, 0x1c000003 },
- { 0x0f801318, 0x1c000042 },
- { 0x0f00135f, 0x30000000 },
- { 0x0f001360, 0x68000000 },
- { 0x0f801361, 0x54000007 },
- { 0x0f801369, 0x3c000013 },
- { 0x0f801380, 0x1c00000f },
- { 0x0f801390, 0x68000009 },
- { 0x088013a0, 0x1c000054 },
- { 0x07801401, 0x1c00026b },
- { 0x0780166d, 0x54000001 },
- { 0x0780166f, 0x1c000007 },
- { 0x28001680, 0x74000000 },
- { 0x28801681, 0x1c000019 },
- { 0x2800169b, 0x58000000 },
- { 0x2800169c, 0x48000000 },
- { 0x2d8016a0, 0x1c00004a },
- { 0x098016eb, 0x54000002 },
- { 0x2d8016ee, 0x38000002 },
- { 0x32801700, 0x1c00000c },
- { 0x3280170e, 0x1c000003 },
- { 0x32801712, 0x30000002 },
- { 0x18801720, 0x1c000011 },
- { 0x18801732, 0x30000002 },
- { 0x09801735, 0x54000001 },
- { 0x06801740, 0x1c000011 },
- { 0x06801752, 0x30000001 },
- { 0x33801760, 0x1c00000c },
- { 0x3380176e, 0x1c000002 },
- { 0x33801772, 0x30000001 },
- { 0x1f801780, 0x1c000033 },
- { 0x1f8017b4, 0x04000001 },
- { 0x1f0017b6, 0x28000000 },
- { 0x1f8017b7, 0x30000006 },
- { 0x1f8017be, 0x28000007 },
- { 0x1f0017c6, 0x30000000 },
- { 0x1f8017c7, 0x28000001 },
- { 0x1f8017c9, 0x3000000a },
- { 0x1f8017d4, 0x54000002 },
- { 0x1f0017d7, 0x18000000 },
- { 0x1f8017d8, 0x54000002 },
- { 0x1f0017db, 0x5c000000 },
- { 0x1f0017dc, 0x1c000000 },
- { 0x1f0017dd, 0x30000000 },
- { 0x1f8017e0, 0x34000009 },
- { 0x1f8017f0, 0x3c000009 },
- { 0x25801800, 0x54000001 },
- { 0x09801802, 0x54000001 },
- { 0x25001804, 0x54000000 },
- { 0x09001805, 0x54000000 },
- { 0x25001806, 0x44000000 },
- { 0x25801807, 0x54000003 },
- { 0x2580180b, 0x30000002 },
- { 0x2500180e, 0x74000000 },
- { 0x25801810, 0x34000009 },
- { 0x25801820, 0x1c000022 },
- { 0x25001843, 0x18000000 },
- { 0x25801844, 0x1c000033 },
- { 0x25801880, 0x1c000028 },
- { 0x250018a9, 0x30000000 },
- { 0x22801900, 0x1c00001c },
- { 0x22801920, 0x30000002 },
- { 0x22801923, 0x28000003 },
- { 0x22801927, 0x30000001 },
- { 0x22801929, 0x28000002 },
- { 0x22801930, 0x28000001 },
- { 0x22001932, 0x30000000 },
- { 0x22801933, 0x28000005 },
- { 0x22801939, 0x30000002 },
- { 0x22001940, 0x68000000 },
- { 0x22801944, 0x54000001 },
- { 0x22801946, 0x34000009 },
- { 0x34801950, 0x1c00001d },
- { 0x34801970, 0x1c000004 },
- { 0x27801980, 0x1c000029 },
- { 0x278019b0, 0x28000010 },
- { 0x278019c1, 0x1c000006 },
- { 0x278019c8, 0x28000001 },
- { 0x278019d0, 0x34000009 },
- { 0x278019de, 0x54000001 },
- { 0x1f8019e0, 0x6800001f },
- { 0x05801a00, 0x1c000016 },
- { 0x05801a17, 0x30000001 },
- { 0x05801a19, 0x28000002 },
- { 0x05801a1e, 0x54000001 },
- { 0x3d801b00, 0x30000003 },
- { 0x3d001b04, 0x28000000 },
- { 0x3d801b05, 0x1c00002e },
- { 0x3d001b34, 0x30000000 },
- { 0x3d001b35, 0x28000000 },
- { 0x3d801b36, 0x30000004 },
- { 0x3d001b3b, 0x28000000 },
- { 0x3d001b3c, 0x30000000 },
- { 0x3d801b3d, 0x28000004 },
- { 0x3d001b42, 0x30000000 },
- { 0x3d801b43, 0x28000001 },
- { 0x3d801b45, 0x1c000006 },
- { 0x3d801b50, 0x34000009 },
- { 0x3d801b5a, 0x54000006 },
- { 0x3d801b61, 0x68000009 },
- { 0x3d801b6b, 0x30000008 },
- { 0x3d801b74, 0x68000008 },
- { 0x21801d00, 0x14000025 },
- { 0x13801d26, 0x14000004 },
- { 0x0c001d2b, 0x14000000 },
- { 0x21801d2c, 0x18000030 },
- { 0x13801d5d, 0x18000004 },
- { 0x21801d62, 0x14000003 },
- { 0x13801d66, 0x14000004 },
- { 0x21801d6b, 0x1400000c },
- { 0x0c001d78, 0x18000000 },
- { 0x21801d79, 0x14000003 },
- { 0x21001d7d, 0x14000ee6 },
- { 0x21801d7e, 0x1400001c },
- { 0x21801d9b, 0x18000023 },
- { 0x13001dbf, 0x18000000 },
- { 0x1b801dc0, 0x3000000a },
- { 0x1b801dfe, 0x30000001 },
- { 0x21001e00, 0x24000001 },
- { 0x21001e01, 0x1400ffff },
- { 0x21001e02, 0x24000001 },
- { 0x21001e03, 0x1400ffff },
- { 0x21001e04, 0x24000001 },
- { 0x21001e05, 0x1400ffff },
- { 0x21001e06, 0x24000001 },
- { 0x21001e07, 0x1400ffff },
- { 0x21001e08, 0x24000001 },
- { 0x21001e09, 0x1400ffff },
- { 0x21001e0a, 0x24000001 },
- { 0x21001e0b, 0x1400ffff },
- { 0x21001e0c, 0x24000001 },
- { 0x21001e0d, 0x1400ffff },
- { 0x21001e0e, 0x24000001 },
- { 0x21001e0f, 0x1400ffff },
- { 0x21001e10, 0x24000001 },
- { 0x21001e11, 0x1400ffff },
- { 0x21001e12, 0x24000001 },
- { 0x21001e13, 0x1400ffff },
- { 0x21001e14, 0x24000001 },
- { 0x21001e15, 0x1400ffff },
- { 0x21001e16, 0x24000001 },
- { 0x21001e17, 0x1400ffff },
- { 0x21001e18, 0x24000001 },
- { 0x21001e19, 0x1400ffff },
- { 0x21001e1a, 0x24000001 },
- { 0x21001e1b, 0x1400ffff },
- { 0x21001e1c, 0x24000001 },
- { 0x21001e1d, 0x1400ffff },
- { 0x21001e1e, 0x24000001 },
- { 0x21001e1f, 0x1400ffff },
- { 0x21001e20, 0x24000001 },
- { 0x21001e21, 0x1400ffff },
- { 0x21001e22, 0x24000001 },
- { 0x21001e23, 0x1400ffff },
- { 0x21001e24, 0x24000001 },
- { 0x21001e25, 0x1400ffff },
- { 0x21001e26, 0x24000001 },
- { 0x21001e27, 0x1400ffff },
- { 0x21001e28, 0x24000001 },
- { 0x21001e29, 0x1400ffff },
- { 0x21001e2a, 0x24000001 },
- { 0x21001e2b, 0x1400ffff },
- { 0x21001e2c, 0x24000001 },
- { 0x21001e2d, 0x1400ffff },
- { 0x21001e2e, 0x24000001 },
- { 0x21001e2f, 0x1400ffff },
- { 0x21001e30, 0x24000001 },
- { 0x21001e31, 0x1400ffff },
- { 0x21001e32, 0x24000001 },
- { 0x21001e33, 0x1400ffff },
- { 0x21001e34, 0x24000001 },
- { 0x21001e35, 0x1400ffff },
- { 0x21001e36, 0x24000001 },
- { 0x21001e37, 0x1400ffff },
- { 0x21001e38, 0x24000001 },
- { 0x21001e39, 0x1400ffff },
- { 0x21001e3a, 0x24000001 },
- { 0x21001e3b, 0x1400ffff },
- { 0x21001e3c, 0x24000001 },
- { 0x21001e3d, 0x1400ffff },
- { 0x21001e3e, 0x24000001 },
- { 0x21001e3f, 0x1400ffff },
- { 0x21001e40, 0x24000001 },
- { 0x21001e41, 0x1400ffff },
- { 0x21001e42, 0x24000001 },
- { 0x21001e43, 0x1400ffff },
- { 0x21001e44, 0x24000001 },
- { 0x21001e45, 0x1400ffff },
- { 0x21001e46, 0x24000001 },
- { 0x21001e47, 0x1400ffff },
- { 0x21001e48, 0x24000001 },
- { 0x21001e49, 0x1400ffff },
- { 0x21001e4a, 0x24000001 },
- { 0x21001e4b, 0x1400ffff },
- { 0x21001e4c, 0x24000001 },
- { 0x21001e4d, 0x1400ffff },
- { 0x21001e4e, 0x24000001 },
- { 0x21001e4f, 0x1400ffff },
- { 0x21001e50, 0x24000001 },
- { 0x21001e51, 0x1400ffff },
- { 0x21001e52, 0x24000001 },
- { 0x21001e53, 0x1400ffff },
- { 0x21001e54, 0x24000001 },
- { 0x21001e55, 0x1400ffff },
- { 0x21001e56, 0x24000001 },
- { 0x21001e57, 0x1400ffff },
- { 0x21001e58, 0x24000001 },
- { 0x21001e59, 0x1400ffff },
- { 0x21001e5a, 0x24000001 },
- { 0x21001e5b, 0x1400ffff },
- { 0x21001e5c, 0x24000001 },
- { 0x21001e5d, 0x1400ffff },
- { 0x21001e5e, 0x24000001 },
- { 0x21001e5f, 0x1400ffff },
- { 0x21001e60, 0x24000001 },
- { 0x21001e61, 0x1400ffff },
- { 0x21001e62, 0x24000001 },
- { 0x21001e63, 0x1400ffff },
- { 0x21001e64, 0x24000001 },
- { 0x21001e65, 0x1400ffff },
- { 0x21001e66, 0x24000001 },
- { 0x21001e67, 0x1400ffff },
- { 0x21001e68, 0x24000001 },
- { 0x21001e69, 0x1400ffff },
- { 0x21001e6a, 0x24000001 },
- { 0x21001e6b, 0x1400ffff },
- { 0x21001e6c, 0x24000001 },
- { 0x21001e6d, 0x1400ffff },
- { 0x21001e6e, 0x24000001 },
- { 0x21001e6f, 0x1400ffff },
- { 0x21001e70, 0x24000001 },
- { 0x21001e71, 0x1400ffff },
- { 0x21001e72, 0x24000001 },
- { 0x21001e73, 0x1400ffff },
- { 0x21001e74, 0x24000001 },
- { 0x21001e75, 0x1400ffff },
- { 0x21001e76, 0x24000001 },
- { 0x21001e77, 0x1400ffff },
- { 0x21001e78, 0x24000001 },
- { 0x21001e79, 0x1400ffff },
- { 0x21001e7a, 0x24000001 },
- { 0x21001e7b, 0x1400ffff },
- { 0x21001e7c, 0x24000001 },
- { 0x21001e7d, 0x1400ffff },
- { 0x21001e7e, 0x24000001 },
- { 0x21001e7f, 0x1400ffff },
- { 0x21001e80, 0x24000001 },
- { 0x21001e81, 0x1400ffff },
- { 0x21001e82, 0x24000001 },
- { 0x21001e83, 0x1400ffff },
- { 0x21001e84, 0x24000001 },
- { 0x21001e85, 0x1400ffff },
- { 0x21001e86, 0x24000001 },
- { 0x21001e87, 0x1400ffff },
- { 0x21001e88, 0x24000001 },
- { 0x21001e89, 0x1400ffff },
- { 0x21001e8a, 0x24000001 },
- { 0x21001e8b, 0x1400ffff },
- { 0x21001e8c, 0x24000001 },
- { 0x21001e8d, 0x1400ffff },
- { 0x21001e8e, 0x24000001 },
- { 0x21001e8f, 0x1400ffff },
- { 0x21001e90, 0x24000001 },
- { 0x21001e91, 0x1400ffff },
- { 0x21001e92, 0x24000001 },
- { 0x21001e93, 0x1400ffff },
- { 0x21001e94, 0x24000001 },
- { 0x21001e95, 0x1400ffff },
- { 0x21801e96, 0x14000004 },
- { 0x21001e9b, 0x1400ffc5 },
- { 0x21001ea0, 0x24000001 },
- { 0x21001ea1, 0x1400ffff },
- { 0x21001ea2, 0x24000001 },
- { 0x21001ea3, 0x1400ffff },
- { 0x21001ea4, 0x24000001 },
- { 0x21001ea5, 0x1400ffff },
- { 0x21001ea6, 0x24000001 },
- { 0x21001ea7, 0x1400ffff },
- { 0x21001ea8, 0x24000001 },
- { 0x21001ea9, 0x1400ffff },
- { 0x21001eaa, 0x24000001 },
- { 0x21001eab, 0x1400ffff },
- { 0x21001eac, 0x24000001 },
- { 0x21001ead, 0x1400ffff },
- { 0x21001eae, 0x24000001 },
- { 0x21001eaf, 0x1400ffff },
- { 0x21001eb0, 0x24000001 },
- { 0x21001eb1, 0x1400ffff },
- { 0x21001eb2, 0x24000001 },
- { 0x21001eb3, 0x1400ffff },
- { 0x21001eb4, 0x24000001 },
- { 0x21001eb5, 0x1400ffff },
- { 0x21001eb6, 0x24000001 },
- { 0x21001eb7, 0x1400ffff },
- { 0x21001eb8, 0x24000001 },
- { 0x21001eb9, 0x1400ffff },
- { 0x21001eba, 0x24000001 },
- { 0x21001ebb, 0x1400ffff },
- { 0x21001ebc, 0x24000001 },
- { 0x21001ebd, 0x1400ffff },
- { 0x21001ebe, 0x24000001 },
- { 0x21001ebf, 0x1400ffff },
- { 0x21001ec0, 0x24000001 },
- { 0x21001ec1, 0x1400ffff },
- { 0x21001ec2, 0x24000001 },
- { 0x21001ec3, 0x1400ffff },
- { 0x21001ec4, 0x24000001 },
- { 0x21001ec5, 0x1400ffff },
- { 0x21001ec6, 0x24000001 },
- { 0x21001ec7, 0x1400ffff },
- { 0x21001ec8, 0x24000001 },
- { 0x21001ec9, 0x1400ffff },
- { 0x21001eca, 0x24000001 },
- { 0x21001ecb, 0x1400ffff },
- { 0x21001ecc, 0x24000001 },
- { 0x21001ecd, 0x1400ffff },
- { 0x21001ece, 0x24000001 },
- { 0x21001ecf, 0x1400ffff },
- { 0x21001ed0, 0x24000001 },
- { 0x21001ed1, 0x1400ffff },
- { 0x21001ed2, 0x24000001 },
- { 0x21001ed3, 0x1400ffff },
- { 0x21001ed4, 0x24000001 },
- { 0x21001ed5, 0x1400ffff },
- { 0x21001ed6, 0x24000001 },
- { 0x21001ed7, 0x1400ffff },
- { 0x21001ed8, 0x24000001 },
- { 0x21001ed9, 0x1400ffff },
- { 0x21001eda, 0x24000001 },
- { 0x21001edb, 0x1400ffff },
- { 0x21001edc, 0x24000001 },
- { 0x21001edd, 0x1400ffff },
- { 0x21001ede, 0x24000001 },
- { 0x21001edf, 0x1400ffff },
- { 0x21001ee0, 0x24000001 },
- { 0x21001ee1, 0x1400ffff },
- { 0x21001ee2, 0x24000001 },
- { 0x21001ee3, 0x1400ffff },
- { 0x21001ee4, 0x24000001 },
- { 0x21001ee5, 0x1400ffff },
- { 0x21001ee6, 0x24000001 },
- { 0x21001ee7, 0x1400ffff },
- { 0x21001ee8, 0x24000001 },
- { 0x21001ee9, 0x1400ffff },
- { 0x21001eea, 0x24000001 },
- { 0x21001eeb, 0x1400ffff },
- { 0x21001eec, 0x24000001 },
- { 0x21001eed, 0x1400ffff },
- { 0x21001eee, 0x24000001 },
- { 0x21001eef, 0x1400ffff },
- { 0x21001ef0, 0x24000001 },
- { 0x21001ef1, 0x1400ffff },
- { 0x21001ef2, 0x24000001 },
- { 0x21001ef3, 0x1400ffff },
- { 0x21001ef4, 0x24000001 },
- { 0x21001ef5, 0x1400ffff },
- { 0x21001ef6, 0x24000001 },
- { 0x21001ef7, 0x1400ffff },
- { 0x21001ef8, 0x24000001 },
- { 0x21001ef9, 0x1400ffff },
- { 0x13001f00, 0x14000008 },
- { 0x13001f01, 0x14000008 },
- { 0x13001f02, 0x14000008 },
- { 0x13001f03, 0x14000008 },
- { 0x13001f04, 0x14000008 },
- { 0x13001f05, 0x14000008 },
- { 0x13001f06, 0x14000008 },
- { 0x13001f07, 0x14000008 },
- { 0x13001f08, 0x2400fff8 },
- { 0x13001f09, 0x2400fff8 },
- { 0x13001f0a, 0x2400fff8 },
- { 0x13001f0b, 0x2400fff8 },
- { 0x13001f0c, 0x2400fff8 },
- { 0x13001f0d, 0x2400fff8 },
- { 0x13001f0e, 0x2400fff8 },
- { 0x13001f0f, 0x2400fff8 },
- { 0x13001f10, 0x14000008 },
- { 0x13001f11, 0x14000008 },
- { 0x13001f12, 0x14000008 },
- { 0x13001f13, 0x14000008 },
- { 0x13001f14, 0x14000008 },
- { 0x13001f15, 0x14000008 },
- { 0x13001f18, 0x2400fff8 },
- { 0x13001f19, 0x2400fff8 },
- { 0x13001f1a, 0x2400fff8 },
- { 0x13001f1b, 0x2400fff8 },
- { 0x13001f1c, 0x2400fff8 },
- { 0x13001f1d, 0x2400fff8 },
- { 0x13001f20, 0x14000008 },
- { 0x13001f21, 0x14000008 },
- { 0x13001f22, 0x14000008 },
- { 0x13001f23, 0x14000008 },
- { 0x13001f24, 0x14000008 },
- { 0x13001f25, 0x14000008 },
- { 0x13001f26, 0x14000008 },
- { 0x13001f27, 0x14000008 },
- { 0x13001f28, 0x2400fff8 },
- { 0x13001f29, 0x2400fff8 },
- { 0x13001f2a, 0x2400fff8 },
- { 0x13001f2b, 0x2400fff8 },
- { 0x13001f2c, 0x2400fff8 },
- { 0x13001f2d, 0x2400fff8 },
- { 0x13001f2e, 0x2400fff8 },
- { 0x13001f2f, 0x2400fff8 },
- { 0x13001f30, 0x14000008 },
- { 0x13001f31, 0x14000008 },
- { 0x13001f32, 0x14000008 },
- { 0x13001f33, 0x14000008 },
- { 0x13001f34, 0x14000008 },
- { 0x13001f35, 0x14000008 },
- { 0x13001f36, 0x14000008 },
- { 0x13001f37, 0x14000008 },
- { 0x13001f38, 0x2400fff8 },
- { 0x13001f39, 0x2400fff8 },
- { 0x13001f3a, 0x2400fff8 },
- { 0x13001f3b, 0x2400fff8 },
- { 0x13001f3c, 0x2400fff8 },
- { 0x13001f3d, 0x2400fff8 },
- { 0x13001f3e, 0x2400fff8 },
- { 0x13001f3f, 0x2400fff8 },
- { 0x13001f40, 0x14000008 },
- { 0x13001f41, 0x14000008 },
- { 0x13001f42, 0x14000008 },
- { 0x13001f43, 0x14000008 },
- { 0x13001f44, 0x14000008 },
- { 0x13001f45, 0x14000008 },
- { 0x13001f48, 0x2400fff8 },
- { 0x13001f49, 0x2400fff8 },
- { 0x13001f4a, 0x2400fff8 },
- { 0x13001f4b, 0x2400fff8 },
- { 0x13001f4c, 0x2400fff8 },
- { 0x13001f4d, 0x2400fff8 },
- { 0x13001f50, 0x14000000 },
- { 0x13001f51, 0x14000008 },
- { 0x13001f52, 0x14000000 },
- { 0x13001f53, 0x14000008 },
- { 0x13001f54, 0x14000000 },
- { 0x13001f55, 0x14000008 },
- { 0x13001f56, 0x14000000 },
- { 0x13001f57, 0x14000008 },
- { 0x13001f59, 0x2400fff8 },
- { 0x13001f5b, 0x2400fff8 },
- { 0x13001f5d, 0x2400fff8 },
- { 0x13001f5f, 0x2400fff8 },
- { 0x13001f60, 0x14000008 },
- { 0x13001f61, 0x14000008 },
- { 0x13001f62, 0x14000008 },
- { 0x13001f63, 0x14000008 },
- { 0x13001f64, 0x14000008 },
- { 0x13001f65, 0x14000008 },
- { 0x13001f66, 0x14000008 },
- { 0x13001f67, 0x14000008 },
- { 0x13001f68, 0x2400fff8 },
- { 0x13001f69, 0x2400fff8 },
- { 0x13001f6a, 0x2400fff8 },
- { 0x13001f6b, 0x2400fff8 },
- { 0x13001f6c, 0x2400fff8 },
- { 0x13001f6d, 0x2400fff8 },
- { 0x13001f6e, 0x2400fff8 },
- { 0x13001f6f, 0x2400fff8 },
- { 0x13001f70, 0x1400004a },
- { 0x13001f71, 0x1400004a },
- { 0x13001f72, 0x14000056 },
- { 0x13001f73, 0x14000056 },
- { 0x13001f74, 0x14000056 },
- { 0x13001f75, 0x14000056 },
- { 0x13001f76, 0x14000064 },
- { 0x13001f77, 0x14000064 },
- { 0x13001f78, 0x14000080 },
- { 0x13001f79, 0x14000080 },
- { 0x13001f7a, 0x14000070 },
- { 0x13001f7b, 0x14000070 },
- { 0x13001f7c, 0x1400007e },
- { 0x13001f7d, 0x1400007e },
- { 0x13001f80, 0x14000008 },
- { 0x13001f81, 0x14000008 },
- { 0x13001f82, 0x14000008 },
- { 0x13001f83, 0x14000008 },
- { 0x13001f84, 0x14000008 },
- { 0x13001f85, 0x14000008 },
- { 0x13001f86, 0x14000008 },
- { 0x13001f87, 0x14000008 },
- { 0x13001f88, 0x2000fff8 },
- { 0x13001f89, 0x2000fff8 },
- { 0x13001f8a, 0x2000fff8 },
- { 0x13001f8b, 0x2000fff8 },
- { 0x13001f8c, 0x2000fff8 },
- { 0x13001f8d, 0x2000fff8 },
- { 0x13001f8e, 0x2000fff8 },
- { 0x13001f8f, 0x2000fff8 },
- { 0x13001f90, 0x14000008 },
- { 0x13001f91, 0x14000008 },
- { 0x13001f92, 0x14000008 },
- { 0x13001f93, 0x14000008 },
- { 0x13001f94, 0x14000008 },
- { 0x13001f95, 0x14000008 },
- { 0x13001f96, 0x14000008 },
- { 0x13001f97, 0x14000008 },
- { 0x13001f98, 0x2000fff8 },
- { 0x13001f99, 0x2000fff8 },
- { 0x13001f9a, 0x2000fff8 },
- { 0x13001f9b, 0x2000fff8 },
- { 0x13001f9c, 0x2000fff8 },
- { 0x13001f9d, 0x2000fff8 },
- { 0x13001f9e, 0x2000fff8 },
- { 0x13001f9f, 0x2000fff8 },
- { 0x13001fa0, 0x14000008 },
- { 0x13001fa1, 0x14000008 },
- { 0x13001fa2, 0x14000008 },
- { 0x13001fa3, 0x14000008 },
- { 0x13001fa4, 0x14000008 },
- { 0x13001fa5, 0x14000008 },
- { 0x13001fa6, 0x14000008 },
- { 0x13001fa7, 0x14000008 },
- { 0x13001fa8, 0x2000fff8 },
- { 0x13001fa9, 0x2000fff8 },
- { 0x13001faa, 0x2000fff8 },
- { 0x13001fab, 0x2000fff8 },
- { 0x13001fac, 0x2000fff8 },
- { 0x13001fad, 0x2000fff8 },
- { 0x13001fae, 0x2000fff8 },
- { 0x13001faf, 0x2000fff8 },
- { 0x13001fb0, 0x14000008 },
- { 0x13001fb1, 0x14000008 },
- { 0x13001fb2, 0x14000000 },
- { 0x13001fb3, 0x14000009 },
- { 0x13001fb4, 0x14000000 },
- { 0x13801fb6, 0x14000001 },
- { 0x13001fb8, 0x2400fff8 },
- { 0x13001fb9, 0x2400fff8 },
- { 0x13001fba, 0x2400ffb6 },
- { 0x13001fbb, 0x2400ffb6 },
- { 0x13001fbc, 0x2000fff7 },
- { 0x13001fbd, 0x60000000 },
- { 0x13001fbe, 0x1400e3db },
- { 0x13801fbf, 0x60000002 },
- { 0x13001fc2, 0x14000000 },
- { 0x13001fc3, 0x14000009 },
- { 0x13001fc4, 0x14000000 },
- { 0x13801fc6, 0x14000001 },
- { 0x13001fc8, 0x2400ffaa },
- { 0x13001fc9, 0x2400ffaa },
- { 0x13001fca, 0x2400ffaa },
- { 0x13001fcb, 0x2400ffaa },
- { 0x13001fcc, 0x2000fff7 },
- { 0x13801fcd, 0x60000002 },
- { 0x13001fd0, 0x14000008 },
- { 0x13001fd1, 0x14000008 },
- { 0x13801fd2, 0x14000001 },
- { 0x13801fd6, 0x14000001 },
- { 0x13001fd8, 0x2400fff8 },
- { 0x13001fd9, 0x2400fff8 },
- { 0x13001fda, 0x2400ff9c },
- { 0x13001fdb, 0x2400ff9c },
- { 0x13801fdd, 0x60000002 },
- { 0x13001fe0, 0x14000008 },
- { 0x13001fe1, 0x14000008 },
- { 0x13801fe2, 0x14000002 },
- { 0x13001fe5, 0x14000007 },
- { 0x13801fe6, 0x14000001 },
- { 0x13001fe8, 0x2400fff8 },
- { 0x13001fe9, 0x2400fff8 },
- { 0x13001fea, 0x2400ff90 },
- { 0x13001feb, 0x2400ff90 },
- { 0x13001fec, 0x2400fff9 },
- { 0x13801fed, 0x60000002 },
- { 0x13001ff2, 0x14000000 },
- { 0x13001ff3, 0x14000009 },
- { 0x13001ff4, 0x14000000 },
- { 0x13801ff6, 0x14000001 },
- { 0x13001ff8, 0x2400ff80 },
- { 0x13001ff9, 0x2400ff80 },
- { 0x13001ffa, 0x2400ff82 },
- { 0x13001ffb, 0x2400ff82 },
- { 0x13001ffc, 0x2000fff7 },
- { 0x13801ffd, 0x60000001 },
- { 0x09802000, 0x7400000a },
- { 0x0900200b, 0x04000000 },
- { 0x1b80200c, 0x04000001 },
- { 0x0980200e, 0x04000001 },
- { 0x09802010, 0x44000005 },
- { 0x09802016, 0x54000001 },
- { 0x09002018, 0x50000000 },
- { 0x09002019, 0x4c000000 },
- { 0x0900201a, 0x58000000 },
- { 0x0980201b, 0x50000001 },
- { 0x0900201d, 0x4c000000 },
- { 0x0900201e, 0x58000000 },
- { 0x0900201f, 0x50000000 },
- { 0x09802020, 0x54000007 },
- { 0x09002028, 0x6c000000 },
- { 0x09002029, 0x70000000 },
- { 0x0980202a, 0x04000004 },
- { 0x0900202f, 0x74000000 },
- { 0x09802030, 0x54000008 },
- { 0x09002039, 0x50000000 },
- { 0x0900203a, 0x4c000000 },
- { 0x0980203b, 0x54000003 },
- { 0x0980203f, 0x40000001 },
- { 0x09802041, 0x54000002 },
- { 0x09002044, 0x64000000 },
- { 0x09002045, 0x58000000 },
- { 0x09002046, 0x48000000 },
- { 0x09802047, 0x5400000a },
- { 0x09002052, 0x64000000 },
- { 0x09002053, 0x54000000 },
- { 0x09002054, 0x40000000 },
- { 0x09802055, 0x54000009 },
- { 0x0900205f, 0x74000000 },
- { 0x09802060, 0x04000003 },
- { 0x0980206a, 0x04000005 },
- { 0x09002070, 0x3c000000 },
- { 0x21002071, 0x14000000 },
- { 0x09802074, 0x3c000005 },
- { 0x0980207a, 0x64000002 },
- { 0x0900207d, 0x58000000 },
- { 0x0900207e, 0x48000000 },
- { 0x2100207f, 0x14000000 },
- { 0x09802080, 0x3c000009 },
- { 0x0980208a, 0x64000002 },
- { 0x0900208d, 0x58000000 },
- { 0x0900208e, 0x48000000 },
- { 0x21802090, 0x18000004 },
- { 0x098020a0, 0x5c000015 },
- { 0x1b8020d0, 0x3000000c },
- { 0x1b8020dd, 0x2c000003 },
- { 0x1b0020e1, 0x30000000 },
- { 0x1b8020e2, 0x2c000002 },
- { 0x1b8020e5, 0x3000000a },
- { 0x09802100, 0x68000001 },
- { 0x09002102, 0x24000000 },
- { 0x09802103, 0x68000003 },
- { 0x09002107, 0x24000000 },
- { 0x09802108, 0x68000001 },
- { 0x0900210a, 0x14000000 },
- { 0x0980210b, 0x24000002 },
- { 0x0980210e, 0x14000001 },
- { 0x09802110, 0x24000002 },
- { 0x09002113, 0x14000000 },
- { 0x09002114, 0x68000000 },
- { 0x09002115, 0x24000000 },
- { 0x09802116, 0x68000002 },
- { 0x09802119, 0x24000004 },
- { 0x0980211e, 0x68000005 },
- { 0x09002124, 0x24000000 },
- { 0x09002125, 0x68000000 },
- { 0x13002126, 0x2400e2a3 },
- { 0x09002127, 0x68000000 },
- { 0x09002128, 0x24000000 },
- { 0x09002129, 0x68000000 },
- { 0x2100212a, 0x2400df41 },
- { 0x2100212b, 0x2400dfba },
- { 0x0980212c, 0x24000001 },
- { 0x0900212e, 0x68000000 },
- { 0x0900212f, 0x14000000 },
- { 0x09802130, 0x24000001 },
- { 0x21002132, 0x2400001c },
- { 0x09002133, 0x24000000 },
- { 0x09002134, 0x14000000 },
- { 0x09802135, 0x1c000003 },
- { 0x09002139, 0x14000000 },
- { 0x0980213a, 0x68000001 },
- { 0x0980213c, 0x14000001 },
- { 0x0980213e, 0x24000001 },
- { 0x09802140, 0x64000004 },
- { 0x09002145, 0x24000000 },
- { 0x09802146, 0x14000003 },
- { 0x0900214a, 0x68000000 },
- { 0x0900214b, 0x64000000 },
- { 0x0980214c, 0x68000001 },
- { 0x2100214e, 0x1400ffe4 },
- { 0x09802153, 0x3c00000c },
- { 0x09002160, 0x38000010 },
- { 0x09002161, 0x38000010 },
- { 0x09002162, 0x38000010 },
- { 0x09002163, 0x38000010 },
- { 0x09002164, 0x38000010 },
- { 0x09002165, 0x38000010 },
- { 0x09002166, 0x38000010 },
- { 0x09002167, 0x38000010 },
- { 0x09002168, 0x38000010 },
- { 0x09002169, 0x38000010 },
- { 0x0900216a, 0x38000010 },
- { 0x0900216b, 0x38000010 },
- { 0x0900216c, 0x38000010 },
- { 0x0900216d, 0x38000010 },
- { 0x0900216e, 0x38000010 },
- { 0x0900216f, 0x38000010 },
- { 0x09002170, 0x3800fff0 },
- { 0x09002171, 0x3800fff0 },
- { 0x09002172, 0x3800fff0 },
- { 0x09002173, 0x3800fff0 },
- { 0x09002174, 0x3800fff0 },
- { 0x09002175, 0x3800fff0 },
- { 0x09002176, 0x3800fff0 },
- { 0x09002177, 0x3800fff0 },
- { 0x09002178, 0x3800fff0 },
- { 0x09002179, 0x3800fff0 },
- { 0x0900217a, 0x3800fff0 },
- { 0x0900217b, 0x3800fff0 },
- { 0x0900217c, 0x3800fff0 },
- { 0x0900217d, 0x3800fff0 },
- { 0x0900217e, 0x3800fff0 },
- { 0x0900217f, 0x3800fff0 },
- { 0x09802180, 0x38000002 },
- { 0x09002183, 0x24000001 },
- { 0x21002184, 0x1400ffff },
- { 0x09802190, 0x64000004 },
- { 0x09802195, 0x68000004 },
- { 0x0980219a, 0x64000001 },
- { 0x0980219c, 0x68000003 },
- { 0x090021a0, 0x64000000 },
- { 0x098021a1, 0x68000001 },
- { 0x090021a3, 0x64000000 },
- { 0x098021a4, 0x68000001 },
- { 0x090021a6, 0x64000000 },
- { 0x098021a7, 0x68000006 },
- { 0x090021ae, 0x64000000 },
- { 0x098021af, 0x6800001e },
- { 0x098021ce, 0x64000001 },
- { 0x098021d0, 0x68000001 },
- { 0x090021d2, 0x64000000 },
- { 0x090021d3, 0x68000000 },
- { 0x090021d4, 0x64000000 },
- { 0x098021d5, 0x6800001e },
- { 0x098021f4, 0x6400010b },
- { 0x09802300, 0x68000007 },
- { 0x09802308, 0x64000003 },
- { 0x0980230c, 0x68000013 },
- { 0x09802320, 0x64000001 },
- { 0x09802322, 0x68000006 },
- { 0x09002329, 0x58000000 },
- { 0x0900232a, 0x48000000 },
- { 0x0980232b, 0x68000050 },
- { 0x0900237c, 0x64000000 },
- { 0x0980237d, 0x6800001d },
- { 0x0980239b, 0x64000018 },
- { 0x098023b4, 0x68000027 },
- { 0x098023dc, 0x64000005 },
- { 0x098023e2, 0x68000005 },
- { 0x09802400, 0x68000026 },
- { 0x09802440, 0x6800000a },
- { 0x09802460, 0x3c00003b },
- { 0x0980249c, 0x68000019 },
- { 0x090024b6, 0x6800001a },
- { 0x090024b7, 0x6800001a },
- { 0x090024b8, 0x6800001a },
- { 0x090024b9, 0x6800001a },
- { 0x090024ba, 0x6800001a },
- { 0x090024bb, 0x6800001a },
- { 0x090024bc, 0x6800001a },
- { 0x090024bd, 0x6800001a },
- { 0x090024be, 0x6800001a },
- { 0x090024bf, 0x6800001a },
- { 0x090024c0, 0x6800001a },
- { 0x090024c1, 0x6800001a },
- { 0x090024c2, 0x6800001a },
- { 0x090024c3, 0x6800001a },
- { 0x090024c4, 0x6800001a },
- { 0x090024c5, 0x6800001a },
- { 0x090024c6, 0x6800001a },
- { 0x090024c7, 0x6800001a },
- { 0x090024c8, 0x6800001a },
- { 0x090024c9, 0x6800001a },
- { 0x090024ca, 0x6800001a },
- { 0x090024cb, 0x6800001a },
- { 0x090024cc, 0x6800001a },
- { 0x090024cd, 0x6800001a },
- { 0x090024ce, 0x6800001a },
- { 0x090024cf, 0x6800001a },
- { 0x090024d0, 0x6800ffe6 },
- { 0x090024d1, 0x6800ffe6 },
- { 0x090024d2, 0x6800ffe6 },
- { 0x090024d3, 0x6800ffe6 },
- { 0x090024d4, 0x6800ffe6 },
- { 0x090024d5, 0x6800ffe6 },
- { 0x090024d6, 0x6800ffe6 },
- { 0x090024d7, 0x6800ffe6 },
- { 0x090024d8, 0x6800ffe6 },
- { 0x090024d9, 0x6800ffe6 },
- { 0x090024da, 0x6800ffe6 },
- { 0x090024db, 0x6800ffe6 },
- { 0x090024dc, 0x6800ffe6 },
- { 0x090024dd, 0x6800ffe6 },
- { 0x090024de, 0x6800ffe6 },
- { 0x090024df, 0x6800ffe6 },
- { 0x090024e0, 0x6800ffe6 },
- { 0x090024e1, 0x6800ffe6 },
- { 0x090024e2, 0x6800ffe6 },
- { 0x090024e3, 0x6800ffe6 },
- { 0x090024e4, 0x6800ffe6 },
- { 0x090024e5, 0x6800ffe6 },
- { 0x090024e6, 0x6800ffe6 },
- { 0x090024e7, 0x6800ffe6 },
- { 0x090024e8, 0x6800ffe6 },
- { 0x090024e9, 0x6800ffe6 },
- { 0x098024ea, 0x3c000015 },
- { 0x09802500, 0x680000b6 },
- { 0x090025b7, 0x64000000 },
- { 0x098025b8, 0x68000008 },
- { 0x090025c1, 0x64000000 },
- { 0x098025c2, 0x68000035 },
- { 0x098025f8, 0x64000007 },
- { 0x09802600, 0x6800006e },
- { 0x0900266f, 0x64000000 },
- { 0x09802670, 0x6800002c },
- { 0x098026a0, 0x68000012 },
- { 0x09802701, 0x68000003 },
- { 0x09802706, 0x68000003 },
- { 0x0980270c, 0x6800001b },
- { 0x09802729, 0x68000022 },
- { 0x0900274d, 0x68000000 },
- { 0x0980274f, 0x68000003 },
- { 0x09002756, 0x68000000 },
- { 0x09802758, 0x68000006 },
- { 0x09802761, 0x68000006 },
- { 0x09002768, 0x58000000 },
- { 0x09002769, 0x48000000 },
- { 0x0900276a, 0x58000000 },
- { 0x0900276b, 0x48000000 },
- { 0x0900276c, 0x58000000 },
- { 0x0900276d, 0x48000000 },
- { 0x0900276e, 0x58000000 },
- { 0x0900276f, 0x48000000 },
- { 0x09002770, 0x58000000 },
- { 0x09002771, 0x48000000 },
- { 0x09002772, 0x58000000 },
- { 0x09002773, 0x48000000 },
- { 0x09002774, 0x58000000 },
- { 0x09002775, 0x48000000 },
- { 0x09802776, 0x3c00001d },
- { 0x09002794, 0x68000000 },
- { 0x09802798, 0x68000017 },
- { 0x098027b1, 0x6800000d },
- { 0x098027c0, 0x64000004 },
- { 0x090027c5, 0x58000000 },
- { 0x090027c6, 0x48000000 },
- { 0x098027c7, 0x64000003 },
- { 0x098027d0, 0x64000015 },
- { 0x090027e6, 0x58000000 },
- { 0x090027e7, 0x48000000 },
- { 0x090027e8, 0x58000000 },
- { 0x090027e9, 0x48000000 },
- { 0x090027ea, 0x58000000 },
- { 0x090027eb, 0x48000000 },
- { 0x098027f0, 0x6400000f },
- { 0x04802800, 0x680000ff },
- { 0x09802900, 0x64000082 },
- { 0x09002983, 0x58000000 },
- { 0x09002984, 0x48000000 },
- { 0x09002985, 0x58000000 },
- { 0x09002986, 0x48000000 },
- { 0x09002987, 0x58000000 },
- { 0x09002988, 0x48000000 },
- { 0x09002989, 0x58000000 },
- { 0x0900298a, 0x48000000 },
- { 0x0900298b, 0x58000000 },
- { 0x0900298c, 0x48000000 },
- { 0x0900298d, 0x58000000 },
- { 0x0900298e, 0x48000000 },
- { 0x0900298f, 0x58000000 },
- { 0x09002990, 0x48000000 },
- { 0x09002991, 0x58000000 },
- { 0x09002992, 0x48000000 },
- { 0x09002993, 0x58000000 },
- { 0x09002994, 0x48000000 },
- { 0x09002995, 0x58000000 },
- { 0x09002996, 0x48000000 },
- { 0x09002997, 0x58000000 },
- { 0x09002998, 0x48000000 },
- { 0x09802999, 0x6400003e },
- { 0x090029d8, 0x58000000 },
- { 0x090029d9, 0x48000000 },
- { 0x090029da, 0x58000000 },
- { 0x090029db, 0x48000000 },
- { 0x098029dc, 0x6400001f },
- { 0x090029fc, 0x58000000 },
- { 0x090029fd, 0x48000000 },
- { 0x098029fe, 0x64000101 },
- { 0x09802b00, 0x6800001a },
- { 0x09802b20, 0x68000003 },
- { 0x11002c00, 0x24000030 },
- { 0x11002c01, 0x24000030 },
- { 0x11002c02, 0x24000030 },
- { 0x11002c03, 0x24000030 },
- { 0x11002c04, 0x24000030 },
- { 0x11002c05, 0x24000030 },
- { 0x11002c06, 0x24000030 },
- { 0x11002c07, 0x24000030 },
- { 0x11002c08, 0x24000030 },
- { 0x11002c09, 0x24000030 },
- { 0x11002c0a, 0x24000030 },
- { 0x11002c0b, 0x24000030 },
- { 0x11002c0c, 0x24000030 },
- { 0x11002c0d, 0x24000030 },
- { 0x11002c0e, 0x24000030 },
- { 0x11002c0f, 0x24000030 },
- { 0x11002c10, 0x24000030 },
- { 0x11002c11, 0x24000030 },
- { 0x11002c12, 0x24000030 },
- { 0x11002c13, 0x24000030 },
- { 0x11002c14, 0x24000030 },
- { 0x11002c15, 0x24000030 },
- { 0x11002c16, 0x24000030 },
- { 0x11002c17, 0x24000030 },
- { 0x11002c18, 0x24000030 },
- { 0x11002c19, 0x24000030 },
- { 0x11002c1a, 0x24000030 },
- { 0x11002c1b, 0x24000030 },
- { 0x11002c1c, 0x24000030 },
- { 0x11002c1d, 0x24000030 },
- { 0x11002c1e, 0x24000030 },
- { 0x11002c1f, 0x24000030 },
- { 0x11002c20, 0x24000030 },
- { 0x11002c21, 0x24000030 },
- { 0x11002c22, 0x24000030 },
- { 0x11002c23, 0x24000030 },
- { 0x11002c24, 0x24000030 },
- { 0x11002c25, 0x24000030 },
- { 0x11002c26, 0x24000030 },
- { 0x11002c27, 0x24000030 },
- { 0x11002c28, 0x24000030 },
- { 0x11002c29, 0x24000030 },
- { 0x11002c2a, 0x24000030 },
- { 0x11002c2b, 0x24000030 },
- { 0x11002c2c, 0x24000030 },
- { 0x11002c2d, 0x24000030 },
- { 0x11002c2e, 0x24000030 },
- { 0x11002c30, 0x1400ffd0 },
- { 0x11002c31, 0x1400ffd0 },
- { 0x11002c32, 0x1400ffd0 },
- { 0x11002c33, 0x1400ffd0 },
- { 0x11002c34, 0x1400ffd0 },
- { 0x11002c35, 0x1400ffd0 },
- { 0x11002c36, 0x1400ffd0 },
- { 0x11002c37, 0x1400ffd0 },
- { 0x11002c38, 0x1400ffd0 },
- { 0x11002c39, 0x1400ffd0 },
- { 0x11002c3a, 0x1400ffd0 },
- { 0x11002c3b, 0x1400ffd0 },
- { 0x11002c3c, 0x1400ffd0 },
- { 0x11002c3d, 0x1400ffd0 },
- { 0x11002c3e, 0x1400ffd0 },
- { 0x11002c3f, 0x1400ffd0 },
- { 0x11002c40, 0x1400ffd0 },
- { 0x11002c41, 0x1400ffd0 },
- { 0x11002c42, 0x1400ffd0 },
- { 0x11002c43, 0x1400ffd0 },
- { 0x11002c44, 0x1400ffd0 },
- { 0x11002c45, 0x1400ffd0 },
- { 0x11002c46, 0x1400ffd0 },
- { 0x11002c47, 0x1400ffd0 },
- { 0x11002c48, 0x1400ffd0 },
- { 0x11002c49, 0x1400ffd0 },
- { 0x11002c4a, 0x1400ffd0 },
- { 0x11002c4b, 0x1400ffd0 },
- { 0x11002c4c, 0x1400ffd0 },
- { 0x11002c4d, 0x1400ffd0 },
- { 0x11002c4e, 0x1400ffd0 },
- { 0x11002c4f, 0x1400ffd0 },
- { 0x11002c50, 0x1400ffd0 },
- { 0x11002c51, 0x1400ffd0 },
- { 0x11002c52, 0x1400ffd0 },
- { 0x11002c53, 0x1400ffd0 },
- { 0x11002c54, 0x1400ffd0 },
- { 0x11002c55, 0x1400ffd0 },
- { 0x11002c56, 0x1400ffd0 },
- { 0x11002c57, 0x1400ffd0 },
- { 0x11002c58, 0x1400ffd0 },
- { 0x11002c59, 0x1400ffd0 },
- { 0x11002c5a, 0x1400ffd0 },
- { 0x11002c5b, 0x1400ffd0 },
- { 0x11002c5c, 0x1400ffd0 },
- { 0x11002c5d, 0x1400ffd0 },
- { 0x11002c5e, 0x1400ffd0 },
- { 0x21002c60, 0x24000001 },
- { 0x21002c61, 0x1400ffff },
- { 0x21002c62, 0x2400d609 },
- { 0x21002c63, 0x2400f11a },
- { 0x21002c64, 0x2400d619 },
- { 0x21002c65, 0x1400d5d5 },
- { 0x21002c66, 0x1400d5d8 },
- { 0x21002c67, 0x24000001 },
- { 0x21002c68, 0x1400ffff },
- { 0x21002c69, 0x24000001 },
- { 0x21002c6a, 0x1400ffff },
- { 0x21002c6b, 0x24000001 },
- { 0x21002c6c, 0x1400ffff },
- { 0x21002c74, 0x14000000 },
- { 0x21002c75, 0x24000001 },
- { 0x21002c76, 0x1400ffff },
- { 0x21002c77, 0x14000000 },
- { 0x0a002c80, 0x24000001 },
- { 0x0a002c81, 0x1400ffff },
- { 0x0a002c82, 0x24000001 },
- { 0x0a002c83, 0x1400ffff },
- { 0x0a002c84, 0x24000001 },
- { 0x0a002c85, 0x1400ffff },
- { 0x0a002c86, 0x24000001 },
- { 0x0a002c87, 0x1400ffff },
- { 0x0a002c88, 0x24000001 },
- { 0x0a002c89, 0x1400ffff },
- { 0x0a002c8a, 0x24000001 },
- { 0x0a002c8b, 0x1400ffff },
- { 0x0a002c8c, 0x24000001 },
- { 0x0a002c8d, 0x1400ffff },
- { 0x0a002c8e, 0x24000001 },
- { 0x0a002c8f, 0x1400ffff },
- { 0x0a002c90, 0x24000001 },
- { 0x0a002c91, 0x1400ffff },
- { 0x0a002c92, 0x24000001 },
- { 0x0a002c93, 0x1400ffff },
- { 0x0a002c94, 0x24000001 },
- { 0x0a002c95, 0x1400ffff },
- { 0x0a002c96, 0x24000001 },
- { 0x0a002c97, 0x1400ffff },
- { 0x0a002c98, 0x24000001 },
- { 0x0a002c99, 0x1400ffff },
- { 0x0a002c9a, 0x24000001 },
- { 0x0a002c9b, 0x1400ffff },
- { 0x0a002c9c, 0x24000001 },
- { 0x0a002c9d, 0x1400ffff },
- { 0x0a002c9e, 0x24000001 },
- { 0x0a002c9f, 0x1400ffff },
- { 0x0a002ca0, 0x24000001 },
- { 0x0a002ca1, 0x1400ffff },
- { 0x0a002ca2, 0x24000001 },
- { 0x0a002ca3, 0x1400ffff },
- { 0x0a002ca4, 0x24000001 },
- { 0x0a002ca5, 0x1400ffff },
- { 0x0a002ca6, 0x24000001 },
- { 0x0a002ca7, 0x1400ffff },
- { 0x0a002ca8, 0x24000001 },
- { 0x0a002ca9, 0x1400ffff },
- { 0x0a002caa, 0x24000001 },
- { 0x0a002cab, 0x1400ffff },
- { 0x0a002cac, 0x24000001 },
- { 0x0a002cad, 0x1400ffff },
- { 0x0a002cae, 0x24000001 },
- { 0x0a002caf, 0x1400ffff },
- { 0x0a002cb0, 0x24000001 },
- { 0x0a002cb1, 0x1400ffff },
- { 0x0a002cb2, 0x24000001 },
- { 0x0a002cb3, 0x1400ffff },
- { 0x0a002cb4, 0x24000001 },
- { 0x0a002cb5, 0x1400ffff },
- { 0x0a002cb6, 0x24000001 },
- { 0x0a002cb7, 0x1400ffff },
- { 0x0a002cb8, 0x24000001 },
- { 0x0a002cb9, 0x1400ffff },
- { 0x0a002cba, 0x24000001 },
- { 0x0a002cbb, 0x1400ffff },
- { 0x0a002cbc, 0x24000001 },
- { 0x0a002cbd, 0x1400ffff },
- { 0x0a002cbe, 0x24000001 },
- { 0x0a002cbf, 0x1400ffff },
- { 0x0a002cc0, 0x24000001 },
- { 0x0a002cc1, 0x1400ffff },
- { 0x0a002cc2, 0x24000001 },
- { 0x0a002cc3, 0x1400ffff },
- { 0x0a002cc4, 0x24000001 },
- { 0x0a002cc5, 0x1400ffff },
- { 0x0a002cc6, 0x24000001 },
- { 0x0a002cc7, 0x1400ffff },
- { 0x0a002cc8, 0x24000001 },
- { 0x0a002cc9, 0x1400ffff },
- { 0x0a002cca, 0x24000001 },
- { 0x0a002ccb, 0x1400ffff },
- { 0x0a002ccc, 0x24000001 },
- { 0x0a002ccd, 0x1400ffff },
- { 0x0a002cce, 0x24000001 },
- { 0x0a002ccf, 0x1400ffff },
- { 0x0a002cd0, 0x24000001 },
- { 0x0a002cd1, 0x1400ffff },
- { 0x0a002cd2, 0x24000001 },
- { 0x0a002cd3, 0x1400ffff },
- { 0x0a002cd4, 0x24000001 },
- { 0x0a002cd5, 0x1400ffff },
- { 0x0a002cd6, 0x24000001 },
- { 0x0a002cd7, 0x1400ffff },
- { 0x0a002cd8, 0x24000001 },
- { 0x0a002cd9, 0x1400ffff },
- { 0x0a002cda, 0x24000001 },
- { 0x0a002cdb, 0x1400ffff },
- { 0x0a002cdc, 0x24000001 },
- { 0x0a002cdd, 0x1400ffff },
- { 0x0a002cde, 0x24000001 },
- { 0x0a002cdf, 0x1400ffff },
- { 0x0a002ce0, 0x24000001 },
- { 0x0a002ce1, 0x1400ffff },
- { 0x0a002ce2, 0x24000001 },
- { 0x0a002ce3, 0x1400ffff },
- { 0x0a002ce4, 0x14000000 },
- { 0x0a802ce5, 0x68000005 },
- { 0x0a802cf9, 0x54000003 },
- { 0x0a002cfd, 0x3c000000 },
- { 0x0a802cfe, 0x54000001 },
- { 0x10002d00, 0x1400e3a0 },
- { 0x10002d01, 0x1400e3a0 },
- { 0x10002d02, 0x1400e3a0 },
- { 0x10002d03, 0x1400e3a0 },
- { 0x10002d04, 0x1400e3a0 },
- { 0x10002d05, 0x1400e3a0 },
- { 0x10002d06, 0x1400e3a0 },
- { 0x10002d07, 0x1400e3a0 },
- { 0x10002d08, 0x1400e3a0 },
- { 0x10002d09, 0x1400e3a0 },
- { 0x10002d0a, 0x1400e3a0 },
- { 0x10002d0b, 0x1400e3a0 },
- { 0x10002d0c, 0x1400e3a0 },
- { 0x10002d0d, 0x1400e3a0 },
- { 0x10002d0e, 0x1400e3a0 },
- { 0x10002d0f, 0x1400e3a0 },
- { 0x10002d10, 0x1400e3a0 },
- { 0x10002d11, 0x1400e3a0 },
- { 0x10002d12, 0x1400e3a0 },
- { 0x10002d13, 0x1400e3a0 },
- { 0x10002d14, 0x1400e3a0 },
- { 0x10002d15, 0x1400e3a0 },
- { 0x10002d16, 0x1400e3a0 },
- { 0x10002d17, 0x1400e3a0 },
- { 0x10002d18, 0x1400e3a0 },
- { 0x10002d19, 0x1400e3a0 },
- { 0x10002d1a, 0x1400e3a0 },
- { 0x10002d1b, 0x1400e3a0 },
- { 0x10002d1c, 0x1400e3a0 },
- { 0x10002d1d, 0x1400e3a0 },
- { 0x10002d1e, 0x1400e3a0 },
- { 0x10002d1f, 0x1400e3a0 },
- { 0x10002d20, 0x1400e3a0 },
- { 0x10002d21, 0x1400e3a0 },
- { 0x10002d22, 0x1400e3a0 },
- { 0x10002d23, 0x1400e3a0 },
- { 0x10002d24, 0x1400e3a0 },
- { 0x10002d25, 0x1400e3a0 },
- { 0x3a802d30, 0x1c000035 },
- { 0x3a002d6f, 0x18000000 },
- { 0x0f802d80, 0x1c000016 },
- { 0x0f802da0, 0x1c000006 },
- { 0x0f802da8, 0x1c000006 },
- { 0x0f802db0, 0x1c000006 },
- { 0x0f802db8, 0x1c000006 },
- { 0x0f802dc0, 0x1c000006 },
- { 0x0f802dc8, 0x1c000006 },
- { 0x0f802dd0, 0x1c000006 },
- { 0x0f802dd8, 0x1c000006 },
- { 0x09802e00, 0x54000001 },
- { 0x09002e02, 0x50000000 },
- { 0x09002e03, 0x4c000000 },
- { 0x09002e04, 0x50000000 },
- { 0x09002e05, 0x4c000000 },
- { 0x09802e06, 0x54000002 },
- { 0x09002e09, 0x50000000 },
- { 0x09002e0a, 0x4c000000 },
- { 0x09002e0b, 0x54000000 },
- { 0x09002e0c, 0x50000000 },
- { 0x09002e0d, 0x4c000000 },
- { 0x09802e0e, 0x54000008 },
- { 0x09002e17, 0x44000000 },
- { 0x09002e1c, 0x50000000 },
- { 0x09002e1d, 0x4c000000 },
- { 0x16802e80, 0x68000019 },
- { 0x16802e9b, 0x68000058 },
- { 0x16802f00, 0x680000d5 },
- { 0x09802ff0, 0x6800000b },
- { 0x09003000, 0x74000000 },
- { 0x09803001, 0x54000002 },
- { 0x09003004, 0x68000000 },
- { 0x16003005, 0x18000000 },
- { 0x09003006, 0x1c000000 },
- { 0x16003007, 0x38000000 },
- { 0x09003008, 0x58000000 },
- { 0x09003009, 0x48000000 },
- { 0x0900300a, 0x58000000 },
- { 0x0900300b, 0x48000000 },
- { 0x0900300c, 0x58000000 },
- { 0x0900300d, 0x48000000 },
- { 0x0900300e, 0x58000000 },
- { 0x0900300f, 0x48000000 },
- { 0x09003010, 0x58000000 },
- { 0x09003011, 0x48000000 },
- { 0x09803012, 0x68000001 },
- { 0x09003014, 0x58000000 },
- { 0x09003015, 0x48000000 },
- { 0x09003016, 0x58000000 },
- { 0x09003017, 0x48000000 },
- { 0x09003018, 0x58000000 },
- { 0x09003019, 0x48000000 },
- { 0x0900301a, 0x58000000 },
- { 0x0900301b, 0x48000000 },
- { 0x0900301c, 0x44000000 },
- { 0x0900301d, 0x58000000 },
- { 0x0980301e, 0x48000001 },
- { 0x09003020, 0x68000000 },
- { 0x16803021, 0x38000008 },
- { 0x1b80302a, 0x30000005 },
- { 0x09003030, 0x44000000 },
- { 0x09803031, 0x18000004 },
- { 0x09803036, 0x68000001 },
- { 0x16803038, 0x38000002 },
- { 0x1600303b, 0x18000000 },
- { 0x0900303c, 0x1c000000 },
- { 0x0900303d, 0x54000000 },
- { 0x0980303e, 0x68000001 },
- { 0x1a803041, 0x1c000055 },
- { 0x1b803099, 0x30000001 },
- { 0x0980309b, 0x60000001 },
- { 0x1a80309d, 0x18000001 },
- { 0x1a00309f, 0x1c000000 },
- { 0x090030a0, 0x44000000 },
- { 0x1d8030a1, 0x1c000059 },
- { 0x090030fb, 0x54000000 },
- { 0x090030fc, 0x18000000 },
- { 0x1d8030fd, 0x18000001 },
- { 0x1d0030ff, 0x1c000000 },
- { 0x03803105, 0x1c000027 },
- { 0x17803131, 0x1c00005d },
- { 0x09803190, 0x68000001 },
- { 0x09803192, 0x3c000003 },
- { 0x09803196, 0x68000009 },
- { 0x038031a0, 0x1c000017 },
- { 0x098031c0, 0x6800000f },
- { 0x1d8031f0, 0x1c00000f },
- { 0x17803200, 0x6800001e },
- { 0x09803220, 0x3c000009 },
- { 0x0980322a, 0x68000019 },
- { 0x09003250, 0x68000000 },
- { 0x09803251, 0x3c00000e },
- { 0x17803260, 0x6800001d },
- { 0x0980327e, 0x68000001 },
- { 0x09803280, 0x3c000009 },
- { 0x0980328a, 0x68000026 },
- { 0x098032b1, 0x3c00000e },
- { 0x098032c0, 0x6800003e },
- { 0x09803300, 0x680000ff },
- { 0x16803400, 0x1c0019b5 },
- { 0x09804dc0, 0x6800003f },
- { 0x16804e00, 0x1c0051bb },
- { 0x3c80a000, 0x1c000014 },
- { 0x3c00a015, 0x18000000 },
- { 0x3c80a016, 0x1c000476 },
- { 0x3c80a490, 0x68000036 },
- { 0x0980a700, 0x60000016 },
- { 0x0980a717, 0x18000003 },
- { 0x0980a720, 0x60000001 },
- { 0x3080a800, 0x1c000001 },
- { 0x3000a802, 0x28000000 },
- { 0x3080a803, 0x1c000002 },
- { 0x3000a806, 0x30000000 },
- { 0x3080a807, 0x1c000003 },
- { 0x3000a80b, 0x30000000 },
- { 0x3080a80c, 0x1c000016 },
- { 0x3080a823, 0x28000001 },
- { 0x3080a825, 0x30000001 },
- { 0x3000a827, 0x28000000 },
- { 0x3080a828, 0x68000003 },
- { 0x4080a840, 0x1c000033 },
- { 0x4080a874, 0x54000003 },
- { 0x1780ac00, 0x1c002ba3 },
- { 0x0980d800, 0x1000037f },
- { 0x0980db80, 0x1000007f },
- { 0x0980dc00, 0x100003ff },
- { 0x0980e000, 0x0c0018ff },
- { 0x1680f900, 0x1c00012d },
- { 0x1680fa30, 0x1c00003a },
- { 0x1680fa70, 0x1c000069 },
- { 0x2180fb00, 0x14000006 },
- { 0x0180fb13, 0x14000004 },
- { 0x1900fb1d, 0x1c000000 },
- { 0x1900fb1e, 0x30000000 },
- { 0x1980fb1f, 0x1c000009 },
- { 0x1900fb29, 0x64000000 },
- { 0x1980fb2a, 0x1c00000c },
- { 0x1980fb38, 0x1c000004 },
- { 0x1900fb3e, 0x1c000000 },
- { 0x1980fb40, 0x1c000001 },
- { 0x1980fb43, 0x1c000001 },
- { 0x1980fb46, 0x1c000009 },
- { 0x0080fb50, 0x1c000061 },
- { 0x0080fbd3, 0x1c00016a },
- { 0x0900fd3e, 0x58000000 },
- { 0x0900fd3f, 0x48000000 },
- { 0x0080fd50, 0x1c00003f },
- { 0x0080fd92, 0x1c000035 },
- { 0x0080fdf0, 0x1c00000b },
- { 0x0000fdfc, 0x5c000000 },
- { 0x0900fdfd, 0x68000000 },
- { 0x1b80fe00, 0x3000000f },
- { 0x0980fe10, 0x54000006 },
- { 0x0900fe17, 0x58000000 },
- { 0x0900fe18, 0x48000000 },
- { 0x0900fe19, 0x54000000 },
- { 0x1b80fe20, 0x30000003 },
- { 0x0900fe30, 0x54000000 },
- { 0x0980fe31, 0x44000001 },
- { 0x0980fe33, 0x40000001 },
- { 0x0900fe35, 0x58000000 },
- { 0x0900fe36, 0x48000000 },
- { 0x0900fe37, 0x58000000 },
- { 0x0900fe38, 0x48000000 },
- { 0x0900fe39, 0x58000000 },
- { 0x0900fe3a, 0x48000000 },
- { 0x0900fe3b, 0x58000000 },
- { 0x0900fe3c, 0x48000000 },
- { 0x0900fe3d, 0x58000000 },
- { 0x0900fe3e, 0x48000000 },
- { 0x0900fe3f, 0x58000000 },
- { 0x0900fe40, 0x48000000 },
- { 0x0900fe41, 0x58000000 },
- { 0x0900fe42, 0x48000000 },
- { 0x0900fe43, 0x58000000 },
- { 0x0900fe44, 0x48000000 },
- { 0x0980fe45, 0x54000001 },
- { 0x0900fe47, 0x58000000 },
- { 0x0900fe48, 0x48000000 },
- { 0x0980fe49, 0x54000003 },
- { 0x0980fe4d, 0x40000002 },
- { 0x0980fe50, 0x54000002 },
- { 0x0980fe54, 0x54000003 },
- { 0x0900fe58, 0x44000000 },
- { 0x0900fe59, 0x58000000 },
- { 0x0900fe5a, 0x48000000 },
- { 0x0900fe5b, 0x58000000 },
- { 0x0900fe5c, 0x48000000 },
- { 0x0900fe5d, 0x58000000 },
- { 0x0900fe5e, 0x48000000 },
- { 0x0980fe5f, 0x54000002 },
- { 0x0900fe62, 0x64000000 },
- { 0x0900fe63, 0x44000000 },
- { 0x0980fe64, 0x64000002 },
- { 0x0900fe68, 0x54000000 },
- { 0x0900fe69, 0x5c000000 },
- { 0x0980fe6a, 0x54000001 },
- { 0x0080fe70, 0x1c000004 },
- { 0x0080fe76, 0x1c000086 },
- { 0x0900feff, 0x04000000 },
- { 0x0980ff01, 0x54000002 },
- { 0x0900ff04, 0x5c000000 },
- { 0x0980ff05, 0x54000002 },
- { 0x0900ff08, 0x58000000 },
- { 0x0900ff09, 0x48000000 },
- { 0x0900ff0a, 0x54000000 },
- { 0x0900ff0b, 0x64000000 },
- { 0x0900ff0c, 0x54000000 },
- { 0x0900ff0d, 0x44000000 },
- { 0x0980ff0e, 0x54000001 },
- { 0x0980ff10, 0x34000009 },
- { 0x0980ff1a, 0x54000001 },
- { 0x0980ff1c, 0x64000002 },
- { 0x0980ff1f, 0x54000001 },
- { 0x2100ff21, 0x24000020 },
- { 0x2100ff22, 0x24000020 },
- { 0x2100ff23, 0x24000020 },
- { 0x2100ff24, 0x24000020 },
- { 0x2100ff25, 0x24000020 },
- { 0x2100ff26, 0x24000020 },
- { 0x2100ff27, 0x24000020 },
- { 0x2100ff28, 0x24000020 },
- { 0x2100ff29, 0x24000020 },
- { 0x2100ff2a, 0x24000020 },
- { 0x2100ff2b, 0x24000020 },
- { 0x2100ff2c, 0x24000020 },
- { 0x2100ff2d, 0x24000020 },
- { 0x2100ff2e, 0x24000020 },
- { 0x2100ff2f, 0x24000020 },
- { 0x2100ff30, 0x24000020 },
- { 0x2100ff31, 0x24000020 },
- { 0x2100ff32, 0x24000020 },
- { 0x2100ff33, 0x24000020 },
- { 0x2100ff34, 0x24000020 },
- { 0x2100ff35, 0x24000020 },
- { 0x2100ff36, 0x24000020 },
- { 0x2100ff37, 0x24000020 },
- { 0x2100ff38, 0x24000020 },
- { 0x2100ff39, 0x24000020 },
- { 0x2100ff3a, 0x24000020 },
- { 0x0900ff3b, 0x58000000 },
- { 0x0900ff3c, 0x54000000 },
- { 0x0900ff3d, 0x48000000 },
- { 0x0900ff3e, 0x60000000 },
- { 0x0900ff3f, 0x40000000 },
- { 0x0900ff40, 0x60000000 },
- { 0x2100ff41, 0x1400ffe0 },
- { 0x2100ff42, 0x1400ffe0 },
- { 0x2100ff43, 0x1400ffe0 },
- { 0x2100ff44, 0x1400ffe0 },
- { 0x2100ff45, 0x1400ffe0 },
- { 0x2100ff46, 0x1400ffe0 },
- { 0x2100ff47, 0x1400ffe0 },
- { 0x2100ff48, 0x1400ffe0 },
- { 0x2100ff49, 0x1400ffe0 },
- { 0x2100ff4a, 0x1400ffe0 },
- { 0x2100ff4b, 0x1400ffe0 },
- { 0x2100ff4c, 0x1400ffe0 },
- { 0x2100ff4d, 0x1400ffe0 },
- { 0x2100ff4e, 0x1400ffe0 },
- { 0x2100ff4f, 0x1400ffe0 },
- { 0x2100ff50, 0x1400ffe0 },
- { 0x2100ff51, 0x1400ffe0 },
- { 0x2100ff52, 0x1400ffe0 },
- { 0x2100ff53, 0x1400ffe0 },
- { 0x2100ff54, 0x1400ffe0 },
- { 0x2100ff55, 0x1400ffe0 },
- { 0x2100ff56, 0x1400ffe0 },
- { 0x2100ff57, 0x1400ffe0 },
- { 0x2100ff58, 0x1400ffe0 },
- { 0x2100ff59, 0x1400ffe0 },
- { 0x2100ff5a, 0x1400ffe0 },
- { 0x0900ff5b, 0x58000000 },
- { 0x0900ff5c, 0x64000000 },
- { 0x0900ff5d, 0x48000000 },
- { 0x0900ff5e, 0x64000000 },
- { 0x0900ff5f, 0x58000000 },
- { 0x0900ff60, 0x48000000 },
- { 0x0900ff61, 0x54000000 },
- { 0x0900ff62, 0x58000000 },
- { 0x0900ff63, 0x48000000 },
- { 0x0980ff64, 0x54000001 },
- { 0x1d80ff66, 0x1c000009 },
- { 0x0900ff70, 0x18000000 },
- { 0x1d80ff71, 0x1c00002c },
- { 0x0980ff9e, 0x18000001 },
- { 0x1780ffa0, 0x1c00001e },
- { 0x1780ffc2, 0x1c000005 },
- { 0x1780ffca, 0x1c000005 },
- { 0x1780ffd2, 0x1c000005 },
- { 0x1780ffda, 0x1c000002 },
- { 0x0980ffe0, 0x5c000001 },
- { 0x0900ffe2, 0x64000000 },
- { 0x0900ffe3, 0x60000000 },
- { 0x0900ffe4, 0x68000000 },
- { 0x0980ffe5, 0x5c000001 },
- { 0x0900ffe8, 0x68000000 },
- { 0x0980ffe9, 0x64000003 },
- { 0x0980ffed, 0x68000001 },
- { 0x0980fff9, 0x04000002 },
- { 0x0980fffc, 0x68000001 },
- { 0x23810000, 0x1c00000b },
- { 0x2381000d, 0x1c000019 },
- { 0x23810028, 0x1c000012 },
- { 0x2381003c, 0x1c000001 },
- { 0x2381003f, 0x1c00000e },
- { 0x23810050, 0x1c00000d },
- { 0x23810080, 0x1c00007a },
- { 0x09810100, 0x54000001 },
- { 0x09010102, 0x68000000 },
- { 0x09810107, 0x3c00002c },
- { 0x09810137, 0x68000008 },
- { 0x13810140, 0x38000034 },
- { 0x13810175, 0x3c000003 },
- { 0x13810179, 0x68000010 },
- { 0x1301018a, 0x3c000000 },
- { 0x29810300, 0x1c00001e },
- { 0x29810320, 0x3c000003 },
- { 0x12810330, 0x1c000010 },
- { 0x12010341, 0x38000000 },
- { 0x12810342, 0x1c000007 },
- { 0x1201034a, 0x38000000 },
- { 0x3b810380, 0x1c00001d },
- { 0x3b01039f, 0x54000000 },
- { 0x2a8103a0, 0x1c000023 },
- { 0x2a8103c8, 0x1c000007 },
- { 0x2a0103d0, 0x54000000 },
- { 0x2a8103d1, 0x38000004 },
- { 0x0d010400, 0x24000028 },
- { 0x0d010401, 0x24000028 },
- { 0x0d010402, 0x24000028 },
- { 0x0d010403, 0x24000028 },
- { 0x0d010404, 0x24000028 },
- { 0x0d010405, 0x24000028 },
- { 0x0d010406, 0x24000028 },
- { 0x0d010407, 0x24000028 },
- { 0x0d010408, 0x24000028 },
- { 0x0d010409, 0x24000028 },
- { 0x0d01040a, 0x24000028 },
- { 0x0d01040b, 0x24000028 },
- { 0x0d01040c, 0x24000028 },
- { 0x0d01040d, 0x24000028 },
- { 0x0d01040e, 0x24000028 },
- { 0x0d01040f, 0x24000028 },
- { 0x0d010410, 0x24000028 },
- { 0x0d010411, 0x24000028 },
- { 0x0d010412, 0x24000028 },
- { 0x0d010413, 0x24000028 },
- { 0x0d010414, 0x24000028 },
- { 0x0d010415, 0x24000028 },
- { 0x0d010416, 0x24000028 },
- { 0x0d010417, 0x24000028 },
- { 0x0d010418, 0x24000028 },
- { 0x0d010419, 0x24000028 },
- { 0x0d01041a, 0x24000028 },
- { 0x0d01041b, 0x24000028 },
- { 0x0d01041c, 0x24000028 },
- { 0x0d01041d, 0x24000028 },
- { 0x0d01041e, 0x24000028 },
- { 0x0d01041f, 0x24000028 },
- { 0x0d010420, 0x24000028 },
- { 0x0d010421, 0x24000028 },
- { 0x0d010422, 0x24000028 },
- { 0x0d010423, 0x24000028 },
- { 0x0d010424, 0x24000028 },
- { 0x0d010425, 0x24000028 },
- { 0x0d010426, 0x24000028 },
- { 0x0d010427, 0x24000028 },
- { 0x0d010428, 0x1400ffd8 },
- { 0x0d010429, 0x1400ffd8 },
- { 0x0d01042a, 0x1400ffd8 },
- { 0x0d01042b, 0x1400ffd8 },
- { 0x0d01042c, 0x1400ffd8 },
- { 0x0d01042d, 0x1400ffd8 },
- { 0x0d01042e, 0x1400ffd8 },
- { 0x0d01042f, 0x1400ffd8 },
- { 0x0d010430, 0x1400ffd8 },
- { 0x0d010431, 0x1400ffd8 },
- { 0x0d010432, 0x1400ffd8 },
- { 0x0d010433, 0x1400ffd8 },
- { 0x0d010434, 0x1400ffd8 },
- { 0x0d010435, 0x1400ffd8 },
- { 0x0d010436, 0x1400ffd8 },
- { 0x0d010437, 0x1400ffd8 },
- { 0x0d010438, 0x1400ffd8 },
- { 0x0d010439, 0x1400ffd8 },
- { 0x0d01043a, 0x1400ffd8 },
- { 0x0d01043b, 0x1400ffd8 },
- { 0x0d01043c, 0x1400ffd8 },
- { 0x0d01043d, 0x1400ffd8 },
- { 0x0d01043e, 0x1400ffd8 },
- { 0x0d01043f, 0x1400ffd8 },
- { 0x0d010440, 0x1400ffd8 },
- { 0x0d010441, 0x1400ffd8 },
- { 0x0d010442, 0x1400ffd8 },
- { 0x0d010443, 0x1400ffd8 },
- { 0x0d010444, 0x1400ffd8 },
- { 0x0d010445, 0x1400ffd8 },
- { 0x0d010446, 0x1400ffd8 },
- { 0x0d010447, 0x1400ffd8 },
- { 0x0d010448, 0x1400ffd8 },
- { 0x0d010449, 0x1400ffd8 },
- { 0x0d01044a, 0x1400ffd8 },
- { 0x0d01044b, 0x1400ffd8 },
- { 0x0d01044c, 0x1400ffd8 },
- { 0x0d01044d, 0x1400ffd8 },
- { 0x0d01044e, 0x1400ffd8 },
- { 0x0d01044f, 0x1400ffd8 },
- { 0x2e810450, 0x1c00002f },
- { 0x2c810480, 0x1c00001d },
- { 0x2c8104a0, 0x34000009 },
- { 0x0b810800, 0x1c000005 },
- { 0x0b010808, 0x1c000000 },
- { 0x0b81080a, 0x1c00002b },
- { 0x0b810837, 0x1c000001 },
- { 0x0b01083c, 0x1c000000 },
- { 0x0b01083f, 0x1c000000 },
- { 0x41810900, 0x1c000015 },
- { 0x41810916, 0x3c000003 },
- { 0x4101091f, 0x54000000 },
- { 0x1e010a00, 0x1c000000 },
- { 0x1e810a01, 0x30000002 },
- { 0x1e810a05, 0x30000001 },
- { 0x1e810a0c, 0x30000003 },
- { 0x1e810a10, 0x1c000003 },
- { 0x1e810a15, 0x1c000002 },
- { 0x1e810a19, 0x1c00001a },
- { 0x1e810a38, 0x30000002 },
- { 0x1e010a3f, 0x30000000 },
- { 0x1e810a40, 0x3c000007 },
- { 0x1e810a50, 0x54000008 },
- { 0x3e812000, 0x1c00036e },
- { 0x3e812400, 0x38000062 },
- { 0x3e812470, 0x54000003 },
- { 0x0981d000, 0x680000f5 },
- { 0x0981d100, 0x68000026 },
- { 0x0981d12a, 0x6800003a },
- { 0x0981d165, 0x28000001 },
- { 0x1b81d167, 0x30000002 },
- { 0x0981d16a, 0x68000002 },
- { 0x0981d16d, 0x28000005 },
- { 0x0981d173, 0x04000007 },
- { 0x1b81d17b, 0x30000007 },
- { 0x0981d183, 0x68000001 },
- { 0x1b81d185, 0x30000006 },
- { 0x0981d18c, 0x6800001d },
- { 0x1b81d1aa, 0x30000003 },
- { 0x0981d1ae, 0x6800002f },
- { 0x1381d200, 0x68000041 },
- { 0x1381d242, 0x30000002 },
- { 0x1301d245, 0x68000000 },
- { 0x0981d300, 0x68000056 },
- { 0x0981d360, 0x3c000011 },
- { 0x0981d400, 0x24000019 },
- { 0x0981d41a, 0x14000019 },
- { 0x0981d434, 0x24000019 },
- { 0x0981d44e, 0x14000006 },
- { 0x0981d456, 0x14000011 },
- { 0x0981d468, 0x24000019 },
- { 0x0981d482, 0x14000019 },
- { 0x0901d49c, 0x24000000 },
- { 0x0981d49e, 0x24000001 },
- { 0x0901d4a2, 0x24000000 },
- { 0x0981d4a5, 0x24000001 },
- { 0x0981d4a9, 0x24000003 },
- { 0x0981d4ae, 0x24000007 },
- { 0x0981d4b6, 0x14000003 },
- { 0x0901d4bb, 0x14000000 },
- { 0x0981d4bd, 0x14000006 },
- { 0x0981d4c5, 0x1400000a },
- { 0x0981d4d0, 0x24000019 },
- { 0x0981d4ea, 0x14000019 },
- { 0x0981d504, 0x24000001 },
- { 0x0981d507, 0x24000003 },
- { 0x0981d50d, 0x24000007 },
- { 0x0981d516, 0x24000006 },
- { 0x0981d51e, 0x14000019 },
- { 0x0981d538, 0x24000001 },
- { 0x0981d53b, 0x24000003 },
- { 0x0981d540, 0x24000004 },
- { 0x0901d546, 0x24000000 },
- { 0x0981d54a, 0x24000006 },
- { 0x0981d552, 0x14000019 },
- { 0x0981d56c, 0x24000019 },
- { 0x0981d586, 0x14000019 },
- { 0x0981d5a0, 0x24000019 },
- { 0x0981d5ba, 0x14000019 },
- { 0x0981d5d4, 0x24000019 },
- { 0x0981d5ee, 0x14000019 },
- { 0x0981d608, 0x24000019 },
- { 0x0981d622, 0x14000019 },
- { 0x0981d63c, 0x24000019 },
- { 0x0981d656, 0x14000019 },
- { 0x0981d670, 0x24000019 },
- { 0x0981d68a, 0x1400001b },
- { 0x0981d6a8, 0x24000018 },
- { 0x0901d6c1, 0x64000000 },
- { 0x0981d6c2, 0x14000018 },
- { 0x0901d6db, 0x64000000 },
- { 0x0981d6dc, 0x14000005 },
- { 0x0981d6e2, 0x24000018 },
- { 0x0901d6fb, 0x64000000 },
- { 0x0981d6fc, 0x14000018 },
- { 0x0901d715, 0x64000000 },
- { 0x0981d716, 0x14000005 },
- { 0x0981d71c, 0x24000018 },
- { 0x0901d735, 0x64000000 },
- { 0x0981d736, 0x14000018 },
- { 0x0901d74f, 0x64000000 },
- { 0x0981d750, 0x14000005 },
- { 0x0981d756, 0x24000018 },
- { 0x0901d76f, 0x64000000 },
- { 0x0981d770, 0x14000018 },
- { 0x0901d789, 0x64000000 },
- { 0x0981d78a, 0x14000005 },
- { 0x0981d790, 0x24000018 },
- { 0x0901d7a9, 0x64000000 },
- { 0x0981d7aa, 0x14000018 },
- { 0x0901d7c3, 0x64000000 },
- { 0x0981d7c4, 0x14000005 },
- { 0x0901d7ca, 0x24000000 },
- { 0x0901d7cb, 0x14000000 },
- { 0x0981d7ce, 0x34000031 },
- { 0x16820000, 0x1c00a6d6 },
- { 0x1682f800, 0x1c00021d },
- { 0x090e0001, 0x04000000 },
- { 0x098e0020, 0x0400005f },
- { 0x1b8e0100, 0x300000ef },
- { 0x098f0000, 0x0c00fffd },
- { 0x09900000, 0x0c00fffd },
-};
diff --git a/crawl-ref/source/util/sqlite/Makefile b/crawl-ref/source/util/sqlite/Makefile
deleted file mode 100644
index 6eb8c70a3a..0000000000
--- a/crawl-ref/source/util/sqlite/Makefile
+++ /dev/null
@@ -1,48 +0,0 @@
-# -*- Makefile -*- for stripped down SQLite 3 static lib.
-
-ifneq ($(findstring $(MAKEFLAGS),s),s)
-ifndef V
- QUIET_CC = @echo ' ' CC $@;
- QUIET_AR = @echo ' ' AR $@;
- export V
-endif
-endif
-
-LIBSQL = libsqlite3.a
-AR ?= ar rcu
-CC ?= gcc
-RANLIB = ranlib
-RM ?= rm -f
-
-# Omit SQLite features we don't need.
-CFLAGS ?= -O2
-CFLAGS +=-DSQLITE_OMIT_AUTHORIZATION \
- -DSQLITE_OMIT_AUTOVACUUM \
- -DSQLITE_OMIT_COMPLETE \
- -DSQLITE_OMIT_BLOB_LITERAL \
- -DSQLITE_OMIT_COMPOUND_SELECT \
- -DSQLITE_OMIT_CONFLICT_CLAUSE \
- -DSQLITE_OMIT_DATETIME_FUNCS \
- -DSQLITE_OMIT_EXPLAIN \
- -DSQLITE_OMIT_INTEGRITY_CHECK \
- -DSQLITE_OMIT_PAGER_PRAGMAS \
- -DSQLITE_OMIT_PROGRESS_CALLBACK \
- -DSQLITE_OMIT_SCHEMA_PRAGMAS \
- -DSQLITE_OMIT_SCHEMA_VERSION_PRAGMAS \
- -DSQLITE_OMIT_TCL_VARIABLE \
- -DSQLITE_OMIT_LOAD_EXTENSION \
- -DSQLITE_PREFER_PROXY_LOCKING=0 \
- -DSQLITE_THREADSAFE=0 \
- -w
-
-all: $(LIBSQL)
-
-clean:
- $(RM) *.o *.a
-
-$(LIBSQL): sqlite3.o
- $(QUIET_AR)$(AR) $@ $^
- @$(RANLIB) $@
-
-%.o: %.c
- $(QUIET_CC)$(CC) $(CFLAGS) -o $@ -c $<
diff --git a/crawl-ref/source/util/sqlite/sqlite3.c b/crawl-ref/source/util/sqlite/sqlite3.c
deleted file mode 100644
index 48d22a4ab9..0000000000
--- a/crawl-ref/source/util/sqlite/sqlite3.c
+++ /dev/null
@@ -1,108806 +0,0 @@
-/******************************************************************************
-** This file is an amalgamation of many separate C source files from SQLite
-** version 3.6.18. By combining all the individual C code files into this
-** single large file, the entire code can be compiled as a one translation
-** unit. This allows many compilers to do optimizations that would not be
-** possible if the files were compiled separately. Performance improvements
-** of 5% are more are commonly seen when SQLite is compiled as a single
-** translation unit.
-**
-** This file is all you need to compile SQLite. To use SQLite in other
-** programs, you need this file and the "sqlite3.h" header file that defines
-** the programming interface to the SQLite library. (If you do not have
-** the "sqlite3.h" header file at hand, you will find a copy embedded within
-** the text of this file. Search for "Begin file sqlite3.h" to find the start
-** of the embedded sqlite3.h header file.) Additional code files may be needed
-** if you want a wrapper to interface SQLite with your choice of programming
-** language. The code for the "sqlite3" command-line shell is also in a
-** separate file. This file contains only code for the core SQLite library.
-**
-** This amalgamation was generated on 2009-09-11 15:36:30 UTC.
-*/
-#define SQLITE_CORE 1
-#define SQLITE_AMALGAMATION 1
-#ifndef SQLITE_PRIVATE
-# define SQLITE_PRIVATE static
-#endif
-#ifndef SQLITE_API
-# define SQLITE_API
-#endif
-/************** Begin file sqliteInt.h ***************************************/
-/*
-** 2001 September 15
-**
-** 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.
-**
-*************************************************************************
-** Internal interface definitions for SQLite.
-**
-*/
-#ifndef _SQLITEINT_H_
-#define _SQLITEINT_H_
-
-/*
-** These #defines should enable >2GB file support on POSIX if the
-** underlying operating system supports it. If the OS lacks
-** large file support, or if the OS is windows, these should be no-ops.
-**
-** Ticket #2739: The _LARGEFILE_SOURCE macro must appear before any
-** system #includes. Hence, this block of code must be the very first
-** code in all source files.
-**
-** Large file support can be disabled using the -DSQLITE_DISABLE_LFS switch
-** on the compiler command line. This is necessary if you are compiling
-** on a recent machine (ex: Red Hat 7.2) but you want your code to work
-** on an older machine (ex: Red Hat 6.0). If you compile on Red Hat 7.2
-** without this option, LFS is enable. But LFS does not exist in the kernel
-** in Red Hat 6.0, so the code won't work. Hence, for maximum binary
-** portability you should omit LFS.
-**
-** Similar is true for Mac OS X. LFS is only supported on Mac OS X 9 and later.
-*/
-#ifndef SQLITE_DISABLE_LFS
-# define _LARGE_FILE 1
-# ifndef _FILE_OFFSET_BITS
-# define _FILE_OFFSET_BITS 64
-# endif
-# define _LARGEFILE_SOURCE 1
-#endif
-
-/*
-** Include the configuration header output by 'configure' if we're using the
-** autoconf-based build
-*/
-#ifdef _HAVE_SQLITE_CONFIG_H
-#include "config.h"
-#endif
-
-/************** Include sqliteLimit.h in the middle of sqliteInt.h ***********/
-/************** Begin file sqliteLimit.h *************************************/
-/*
-** 2007 May 7
-**
-** 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 defines various limits of what SQLite can process.
-**
-** @(#) $Id: sqliteLimit.h,v 1.10 2009/01/10 16:15:09 danielk1977 Exp $
-*/
-
-/*
-** The maximum length of a TEXT or BLOB in bytes. This also
-** limits the size of a row in a table or index.
-**
-** The hard limit is the ability of a 32-bit signed integer
-** to count the size: 2^31-1 or 2147483647.
-*/
-#ifndef SQLITE_MAX_LENGTH
-# define SQLITE_MAX_LENGTH 1000000000
-#endif
-
-/*
-** This is the maximum number of
-**
-** * Columns in a table
-** * Columns in an index
-** * Columns in a view
-** * Terms in the SET clause of an UPDATE statement
-** * Terms in the result set of a SELECT statement
-** * Terms in the GROUP BY or ORDER BY clauses of a SELECT statement.
-** * Terms in the VALUES clause of an INSERT statement
-**
-** The hard upper limit here is 32676. Most database people will
-** tell you that in a well-normalized database, you usually should
-** not have more than a dozen or so columns in any table. And if
-** that is the case, there is no point in having more than a few
-** dozen values in any of the other situations described above.
-*/
-#ifndef SQLITE_MAX_COLUMN
-# define SQLITE_MAX_COLUMN 2000
-#endif
-
-/*
-** The maximum length of a single SQL statement in bytes.
-**
-** It used to be the case that setting this value to zero would
-** turn the limit off. That is no longer true. It is not possible
-** to turn this limit off.
-*/
-#ifndef SQLITE_MAX_SQL_LENGTH
-# define SQLITE_MAX_SQL_LENGTH 1000000000
-#endif
-
-/*
-** The maximum depth of an expression tree. This is limited to
-** some extent by SQLITE_MAX_SQL_LENGTH. But sometime you might
-** want to place more severe limits on the complexity of an
-** expression.
-**
-** A value of 0 used to mean that the limit was not enforced.
-** But that is no longer true. The limit is now strictly enforced
-** at all times.
-*/
-#ifndef SQLITE_MAX_EXPR_DEPTH
-# define SQLITE_MAX_EXPR_DEPTH 1000
-#endif
-
-/*
-** The maximum number of terms in a compound SELECT statement.
-** The code generator for compound SELECT statements does one
-** level of recursion for each term. A stack overflow can result
-** if the number of terms is too large. In practice, most SQL
-** never has more than 3 or 4 terms. Use a value of 0 to disable
-** any limit on the number of terms in a compount SELECT.
-*/
-#ifndef SQLITE_MAX_COMPOUND_SELECT
-# define SQLITE_MAX_COMPOUND_SELECT 500
-#endif
-
-/*
-** The maximum number of opcodes in a VDBE program.
-** Not currently enforced.
-*/
-#ifndef SQLITE_MAX_VDBE_OP
-# define SQLITE_MAX_VDBE_OP 25000
-#endif
-
-/*
-** The maximum number of arguments to an SQL function.
-*/
-#ifndef SQLITE_MAX_FUNCTION_ARG
-# define SQLITE_MAX_FUNCTION_ARG 127
-#endif
-
-/*
-** The maximum number of in-memory pages to use for the main database
-** table and for temporary tables. The SQLITE_DEFAULT_CACHE_SIZE
-*/
-#ifndef SQLITE_DEFAULT_CACHE_SIZE
-# define SQLITE_DEFAULT_CACHE_SIZE 2000
-#endif
-#ifndef SQLITE_DEFAULT_TEMP_CACHE_SIZE
-# define SQLITE_DEFAULT_TEMP_CACHE_SIZE 500
-#endif
-
-/*
-** The maximum number of attached databases. This must be between 0
-** and 30. The upper bound on 30 is because a 32-bit integer bitmap
-** is used internally to track attached databases.
-*/
-#ifndef SQLITE_MAX_ATTACHED
-# define SQLITE_MAX_ATTACHED 10
-#endif
-
-
-/*
-** The maximum value of a ?nnn wildcard that the parser will accept.
-*/
-#ifndef SQLITE_MAX_VARIABLE_NUMBER
-# define SQLITE_MAX_VARIABLE_NUMBER 999
-#endif
-
-/* Maximum page size. The upper bound on this value is 32768. This a limit
-** imposed by the necessity of storing the value in a 2-byte unsigned integer
-** and the fact that the page size must be a power of 2.
-**
-** If this limit is changed, then the compiled library is technically
-** incompatible with an SQLite library compiled with a different limit. If
-** a process operating on a database with a page-size of 65536 bytes
-** crashes, then an instance of SQLite compiled with the default page-size
-** limit will not be able to rollback the aborted transaction. This could
-** lead to database corruption.
-*/
-#ifndef SQLITE_MAX_PAGE_SIZE
-# define SQLITE_MAX_PAGE_SIZE 32768
-#endif
-
-
-/*
-** The default size of a database page.
-*/
-#ifndef SQLITE_DEFAULT_PAGE_SIZE
-# define SQLITE_DEFAULT_PAGE_SIZE 1024
-#endif
-#if SQLITE_DEFAULT_PAGE_SIZE>SQLITE_MAX_PAGE_SIZE
-# undef SQLITE_DEFAULT_PAGE_SIZE
-# define SQLITE_DEFAULT_PAGE_SIZE SQLITE_MAX_PAGE_SIZE
-#endif
-
-/*
-** Ordinarily, if no value is explicitly provided, SQLite creates databases
-** with page size SQLITE_DEFAULT_PAGE_SIZE. However, based on certain
-** device characteristics (sector-size and atomic write() support),
-** SQLite may choose a larger value. This constant is the maximum value
-** SQLite will choose on its own.
-*/
-#ifndef SQLITE_MAX_DEFAULT_PAGE_SIZE
-# define SQLITE_MAX_DEFAULT_PAGE_SIZE 8192
-#endif
-#if SQLITE_MAX_DEFAULT_PAGE_SIZE>SQLITE_MAX_PAGE_SIZE
-# undef SQLITE_MAX_DEFAULT_PAGE_SIZE
-# define SQLITE_MAX_DEFAULT_PAGE_SIZE SQLITE_MAX_PAGE_SIZE
-#endif
-
-
-/*
-** Maximum number of pages in one database file.
-**
-** This is really just the default value for the max_page_count pragma.
-** This value can be lowered (or raised) at run-time using that the
-** max_page_count macro.
-*/
-#ifndef SQLITE_MAX_PAGE_COUNT
-# define SQLITE_MAX_PAGE_COUNT 1073741823
-#endif
-
-/*
-** Maximum length (in bytes) of the pattern in a LIKE or GLOB
-** operator.
-*/
-#ifndef SQLITE_MAX_LIKE_PATTERN_LENGTH
-# define SQLITE_MAX_LIKE_PATTERN_LENGTH 50000
-#endif
-
-/*
-** Maximum depth of recursion for triggers.
-*/
-#ifndef SQLITE_MAX_TRIGGER_DEPTH
-#if defined(SQLITE_SMALL_STACK)
-# define SQLITE_MAX_TRIGGER_DEPTH 10
-#else
-# define SQLITE_MAX_TRIGGER_DEPTH 1000
-#endif
-#endif
-
-/************** End of sqliteLimit.h *****************************************/
-/************** Continuing where we left off in sqliteInt.h ******************/
-
-/* Disable nuisance warnings on Borland compilers */
-#if defined(__BORLANDC__)
-#pragma warn -rch /* unreachable code */
-#pragma warn -ccc /* Condition is always true or false */
-#pragma warn -aus /* Assigned value is never used */
-#pragma warn -csu /* Comparing signed and unsigned */
-#pragma warn -spa /* Suspicious pointer arithmetic */
-#endif
-
-/* Needed for various definitions... */
-#ifndef _GNU_SOURCE
-# define _GNU_SOURCE
-#endif
-
-/*
-** Include standard header files as necessary
-*/
-#ifdef HAVE_STDINT_H
-#include <stdint.h>
-#endif
-#ifdef HAVE_INTTYPES_H
-#include <inttypes.h>
-#endif
-
-#define SQLITE_INDEX_SAMPLES 10
-
-/*
-** This macro is used to "hide" some ugliness in casting an int
-** value to a ptr value under the MSVC 64-bit compiler. Casting
-** non 64-bit values to ptr types results in a "hard" error with
-** the MSVC 64-bit compiler which this attempts to avoid.
-**
-** A simple compiler pragma or casting sequence could not be found
-** to correct this in all situations, so this macro was introduced.
-**
-** It could be argued that the intptr_t type could be used in this
-** case, but that type is not available on all compilers, or
-** requires the #include of specific headers which differs between
-** platforms.
-**
-** Ticket #3860: The llvm-gcc-4.2 compiler from Apple chokes on
-** the ((void*)&((char*)0)[X]) construct. But MSVC chokes on ((void*)(X)).
-** So we have to define the macros in different ways depending on the
-** compiler.
-*/
-#if defined(__GNUC__)
-# if defined(HAVE_STDINT_H)
-# define SQLITE_INT_TO_PTR(X) ((void*)(intptr_t)(X))
-# define SQLITE_PTR_TO_INT(X) ((int)(intptr_t)(X))
-# else
-# define SQLITE_INT_TO_PTR(X) ((void*)(X))
-# define SQLITE_PTR_TO_INT(X) ((int)(X))
-# endif
-#else
-# define SQLITE_INT_TO_PTR(X) ((void*)&((char*)0)[X])
-# define SQLITE_PTR_TO_INT(X) ((int)(((char*)X)-(char*)0))
-#endif
-
-
-/*
-** The SQLITE_THREADSAFE macro must be defined as either 0 or 1.
-** Older versions of SQLite used an optional THREADSAFE macro.
-** We support that for legacy
-*/
-#if !defined(SQLITE_THREADSAFE)
-#if defined(THREADSAFE)
-# define SQLITE_THREADSAFE THREADSAFE
-#else
-# define SQLITE_THREADSAFE 1
-#endif
-#endif
-
-/*
-** The SQLITE_DEFAULT_MEMSTATUS macro must be defined as either 0 or 1.
-** It determines whether or not the features related to
-** SQLITE_CONFIG_MEMSTATUS are available by default or not. This value can
-** be overridden at runtime using the sqlite3_config() API.
-*/
-#if !defined(SQLITE_DEFAULT_MEMSTATUS)
-# define SQLITE_DEFAULT_MEMSTATUS 1
-#endif
-
-/*
-** Exactly one of the following macros must be defined in order to
-** specify which memory allocation subsystem to use.
-**
-** SQLITE_SYSTEM_MALLOC // Use normal system malloc()
-** SQLITE_MEMDEBUG // Debugging version of system malloc()
-** SQLITE_MEMORY_SIZE // internal allocator #1
-** SQLITE_MMAP_HEAP_SIZE // internal mmap() allocator
-** SQLITE_POW2_MEMORY_SIZE // internal power-of-two allocator
-**
-** If none of the above are defined, then set SQLITE_SYSTEM_MALLOC as
-** the default.
-*/
-#if defined(SQLITE_SYSTEM_MALLOC)+defined(SQLITE_MEMDEBUG)+\
- defined(SQLITE_MEMORY_SIZE)+defined(SQLITE_MMAP_HEAP_SIZE)+\
- defined(SQLITE_POW2_MEMORY_SIZE)>1
-# error "At most one of the following compile-time configuration options\
- is allows: SQLITE_SYSTEM_MALLOC, SQLITE_MEMDEBUG, SQLITE_MEMORY_SIZE,\
- SQLITE_MMAP_HEAP_SIZE, SQLITE_POW2_MEMORY_SIZE"
-#endif
-#if defined(SQLITE_SYSTEM_MALLOC)+defined(SQLITE_MEMDEBUG)+\
- defined(SQLITE_MEMORY_SIZE)+defined(SQLITE_MMAP_HEAP_SIZE)+\
- defined(SQLITE_POW2_MEMORY_SIZE)==0
-# define SQLITE_SYSTEM_MALLOC 1
-#endif
-
-/*
-** If SQLITE_MALLOC_SOFT_LIMIT is not zero, then try to keep the
-** sizes of memory allocations below this value where possible.
-*/
-#if !defined(SQLITE_MALLOC_SOFT_LIMIT)
-# define SQLITE_MALLOC_SOFT_LIMIT 1024
-#endif
-
-/*
-** We need to define _XOPEN_SOURCE as follows in order to enable
-** recursive mutexes on most Unix systems. But Mac OS X is different.
-** The _XOPEN_SOURCE define causes problems for Mac OS X we are told,
-** so it is omitted there. See ticket #2673.
-**
-** Later we learn that _XOPEN_SOURCE is poorly or incorrectly
-** implemented on some systems. So we avoid defining it at all
-** if it is already defined or if it is unneeded because we are
-** not doing a threadsafe build. Ticket #2681.
-**
-** See also ticket #2741.
-*/
-#if !defined(_XOPEN_SOURCE) && !defined(__DARWIN__) && !defined(__APPLE__) && SQLITE_THREADSAFE
-# define _XOPEN_SOURCE 500 /* Needed to enable pthread recursive mutexes */
-#endif
-
-/*
-** The TCL headers are only needed when compiling the TCL bindings.
-*/
-#if defined(SQLITE_TCL) || defined(TCLSH)
-# include <tcl.h>
-#endif
-
-/*
-** Many people are failing to set -DNDEBUG=1 when compiling SQLite.
-** Setting NDEBUG makes the code smaller and run faster. So the following
-** lines are added to automatically set NDEBUG unless the -DSQLITE_DEBUG=1
-** option is set. Thus NDEBUG becomes an opt-in rather than an opt-out
-** feature.
-*/
-#if !defined(NDEBUG) && !defined(SQLITE_DEBUG)
-# define NDEBUG 1
-#endif
-
-/*
-** The testcase() macro is used to aid in coverage testing. When
-** doing coverage testing, the condition inside the argument to
-** testcase() must be evaluated both true and false in order to
-** get full branch coverage. The testcase() macro is inserted
-** to help ensure adequate test coverage in places where simple
-** condition/decision coverage is inadequate. For example, testcase()
-** can be used to make sure boundary values are tested. For
-** bitmask tests, testcase() can be used to make sure each bit
-** is significant and used at least once. On switch statements
-** where multiple cases go to the same block of code, testcase()
-** can insure that all cases are evaluated.
-**
-*/
-#ifdef SQLITE_COVERAGE_TEST
-SQLITE_PRIVATE void sqlite3Coverage(int);
-# define testcase(X) if( X ){ sqlite3Coverage(__LINE__); }
-#else
-# define testcase(X)
-#endif
-
-/*
-** The TESTONLY macro is used to enclose variable declarations or
-** other bits of code that are needed to support the arguments
-** within testcase() and assert() macros.
-*/
-#if !defined(NDEBUG) || defined(SQLITE_COVERAGE_TEST)
-# define TESTONLY(X) X
-#else
-# define TESTONLY(X)
-#endif
-
-/*
-** Sometimes we need a small amount of code such as a variable initialization
-** to setup for a later assert() statement. We do not want this code to
-** appear when assert() is disabled. The following macro is therefore
-** used to contain that setup code. The "VVA" acronym stands for
-** "Verification, Validation, and Accreditation". In other words, the
-** code within VVA_ONLY() will only run during verification processes.
-*/
-#ifndef NDEBUG
-# define VVA_ONLY(X) X
-#else
-# define VVA_ONLY(X)
-#endif
-
-/*
-** The ALWAYS and NEVER macros surround boolean expressions which
-** are intended to always be true or false, respectively. Such
-** expressions could be omitted from the code completely. But they
-** are included in a few cases in order to enhance the resilience
-** of SQLite to unexpected behavior - to make the code "self-healing"
-** or "ductile" rather than being "brittle" and crashing at the first
-** hint of unplanned behavior.
-**
-** In other words, ALWAYS and NEVER are added for defensive code.
-**
-** When doing coverage testing ALWAYS and NEVER are hard-coded to
-** be true and false so that the unreachable code then specify will
-** not be counted as untested code.
-*/
-#if defined(SQLITE_COVERAGE_TEST)
-# define ALWAYS(X) (1)
-# define NEVER(X) (0)
-#elif !defined(NDEBUG)
-# define ALWAYS(X) ((X)?1:(assert(0),0))
-# define NEVER(X) ((X)?(assert(0),1):0)
-#else
-# define ALWAYS(X) (X)
-# define NEVER(X) (X)
-#endif
-
-/*
-** The macro unlikely() is a hint that surrounds a boolean
-** expression that is usually false. Macro likely() surrounds
-** a boolean expression that is usually true. GCC is able to
-** use these hints to generate better code, sometimes.
-*/
-#if defined(__GNUC__) && 0
-# define likely(X) __builtin_expect((X),1)
-# define unlikely(X) __builtin_expect((X),0)
-#else
-# define likely(X) !!(X)
-# define unlikely(X) !!(X)
-#endif
-
-/************** Include sqlite3.h in the middle of sqliteInt.h ***************/
-/************** Begin file sqlite3.h *****************************************/
-/*
-** 2001 September 15
-**
-** 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 header file defines the interface that the SQLite library
-** presents to client programs. If a C-function, structure, datatype,
-** or constant definition does not appear in this file, then it is
-** not a published API of SQLite, is subject to change without
-** notice, and should not be referenced by programs that use SQLite.
-**
-** Some of the definitions that are in this file are marked as
-** "experimental". Experimental interfaces are normally new
-** features recently added to SQLite. We do not anticipate changes
-** to experimental interfaces but reserve the right to make minor changes
-** if experience from use "in the wild" suggest such changes are prudent.
-**
-** The official C-language API documentation for SQLite is derived
-** from comments in this file. This file is the authoritative source
-** on how SQLite interfaces are suppose to operate.
-**
-** The name of this file under configuration management is "sqlite.h.in".
-** The makefile makes some minor changes to this file (such as inserting
-** the version number) and changes its name to "sqlite3.h" as
-** part of the build process.
-*/
-#ifndef _SQLITE3_H_
-#define _SQLITE3_H_
-#include <stdarg.h> /* Needed for the definition of va_list */
-
-/*
-** Make sure we can call this stuff from C++.
-*/
-#if 0
-extern "C" {
-#endif
-
-
-/*
-** Add the ability to override 'extern'
-*/
-#ifndef SQLITE_EXTERN
-# define SQLITE_EXTERN extern
-#endif
-
-#ifndef SQLITE_API
-# define SQLITE_API
-#endif
-
-
-/*
-** These no-op macros are used in front of interfaces to mark those
-** interfaces as either deprecated or experimental. New applications
-** should not use deprecated interfaces - they are support for backwards
-** compatibility only. Application writers should be aware that
-** experimental interfaces are subject to change in point releases.
-**
-** These macros used to resolve to various kinds of compiler magic that
-** would generate warning messages when they were used. But that
-** compiler magic ended up generating such a flurry of bug reports
-** that we have taken it all out and gone back to using simple
-** noop macros.
-*/
-#define SQLITE_DEPRECATED
-#define SQLITE_EXPERIMENTAL
-
-/*
-** Ensure these symbols were not defined by some previous header file.
-*/
-#ifdef SQLITE_VERSION
-# undef SQLITE_VERSION
-#endif
-#ifdef SQLITE_VERSION_NUMBER
-# undef SQLITE_VERSION_NUMBER
-#endif
-
-/*
-** CAPI3REF: Compile-Time Library Version Numbers {H10010} <S60100>
-**
-** The SQLITE_VERSION and SQLITE_VERSION_NUMBER #defines in
-** the sqlite3.h file specify the version of SQLite with which
-** that header file is associated.
-**
-** The "version" of SQLite is a string of the form "W.X.Y" or "W.X.Y.Z".
-** The W value is major version number and is always 3 in SQLite3.
-** The W value only changes when backwards compatibility is
-** broken and we intend to never break backwards compatibility.
-** The X value is the minor version number and only changes when
-** there are major feature enhancements that are forwards compatible
-** but not backwards compatible.
-** The Y value is the release number and is incremented with
-** each release but resets back to 0 whenever X is incremented.
-** The Z value only appears on branch releases.
-**
-** The SQLITE_VERSION_NUMBER is an integer that is computed as
-** follows:
-**
-** <blockquote><pre>
-** SQLITE_VERSION_NUMBER = W*1000000 + X*1000 + Y
-** </pre></blockquote>
-**
-** Since version 3.6.18, SQLite source code has been stored in the
-** <a href="http://www.fossil-scm.org/">fossil configuration management
-** system</a>. The SQLITE_SOURCE_ID
-** macro is a string which identifies a particular check-in of SQLite
-** within its configuration management system. The string contains the
-** date and time of the check-in (UTC) and an SHA1 hash of the entire
-** source tree.
-**
-** See also: [sqlite3_libversion()],
-** [sqlite3_libversion_number()], [sqlite3_sourceid()],
-** [sqlite_version()] and [sqlite_source_id()].
-**
-** Requirements: [H10011] [H10014]
-*/
-#define SQLITE_VERSION "3.6.18"
-#define SQLITE_VERSION_NUMBER 3006018
-#define SQLITE_SOURCE_ID "2009-09-11 14:05:07 b084828a771ec40be85f07c590ca99de4f6c24ee"
-
-/*
-** CAPI3REF: Run-Time Library Version Numbers {H10020} <S60100>
-** KEYWORDS: sqlite3_version
-**
-** These interfaces provide the same information as the [SQLITE_VERSION],
-** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] #defines in the header,
-** but are associated with the library instead of the header file. Cautious
-** programmers might include assert() statements in their application to
-** verify that values returned by these interfaces match the macros in
-** the header, and thus insure that the application is
-** compiled with matching library and header files.
-**
-** <blockquote><pre>
-** assert( sqlite3_libversion_number()==SQLITE_VERSION_NUMBER );
-** assert( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)==0 );
-** assert( strcmp(sqlite3_libversion,SQLITE_VERSION)==0 );
-** </pre></blockquote>
-**
-** The sqlite3_libversion() function returns the same information as is
-** in the sqlite3_version[] string constant. The function is provided
-** for use in DLLs since DLL users usually do not have direct access to string
-** constants within the DLL. Similarly, the sqlite3_sourceid() function
-** returns the same information as is in the [SQLITE_SOURCE_ID] #define of
-** the header file.
-**
-** See also: [sqlite_version()] and [sqlite_source_id()].
-**
-** Requirements: [H10021] [H10022] [H10023]
-*/
-SQLITE_API const char sqlite3_version[] = SQLITE_VERSION;
-SQLITE_API const char *sqlite3_libversion(void);
-SQLITE_API const char *sqlite3_sourceid(void);
-SQLITE_API int sqlite3_libversion_number(void);
-
-/*
-** CAPI3REF: Test To See If The Library Is Threadsafe {H10100} <S60100>
-**
-** SQLite can be compiled with or without mutexes. When
-** the [SQLITE_THREADSAFE] C preprocessor macro is 1 or 2, mutexes
-** are enabled and SQLite is threadsafe. When the
-** [SQLITE_THREADSAFE] macro is 0,
-** the mutexes are omitted. Without the mutexes, it is not safe
-** to use SQLite concurrently from more than one thread.
-**
-** Enabling mutexes incurs a measurable performance penalty.
-** So if speed is of utmost importance, it makes sense to disable
-** the mutexes. But for maximum safety, mutexes should be enabled.
-** The default behavior is for mutexes to be enabled.
-**
-** This interface can be used by an application to make sure that the
-** version of SQLite that it is linking against was compiled with
-** the desired setting of the [SQLITE_THREADSAFE] macro.
-**
-** This interface only reports on the compile-time mutex setting
-** of the [SQLITE_THREADSAFE] flag. If SQLite is compiled with
-** SQLITE_THREADSAFE=1 then mutexes are enabled by default but
-** can be fully or partially disabled using a call to [sqlite3_config()]
-** with the verbs [SQLITE_CONFIG_SINGLETHREAD], [SQLITE_CONFIG_MULTITHREAD],
-** or [SQLITE_CONFIG_MUTEX]. The return value of this function shows
-** only the default compile-time setting, not any run-time changes
-** to that setting.
-**
-** See the [threading mode] documentation for additional information.
-**
-** Requirements: [H10101] [H10102]
-*/
-SQLITE_API int sqlite3_threadsafe(void);
-
-/*
-** CAPI3REF: Database Connection Handle {H12000} <S40200>
-** KEYWORDS: {database connection} {database connections}
-**
-** Each open SQLite database is represented by a pointer to an instance of
-** the opaque structure named "sqlite3". It is useful to think of an sqlite3
-** pointer as an object. The [sqlite3_open()], [sqlite3_open16()], and
-** [sqlite3_open_v2()] interfaces are its constructors, and [sqlite3_close()]
-** is its destructor. There are many other interfaces (such as
-** [sqlite3_prepare_v2()], [sqlite3_create_function()], and
-** [sqlite3_busy_timeout()] to name but three) that are methods on an
-** sqlite3 object.
-*/
-typedef struct sqlite3 sqlite3;
-
-/*
-** CAPI3REF: 64-Bit Integer Types {H10200} <S10110>
-** KEYWORDS: sqlite_int64 sqlite_uint64
-**
-** Because there is no cross-platform way to specify 64-bit integer types
-** SQLite includes typedefs for 64-bit signed and unsigned integers.
-**
-** The sqlite3_int64 and sqlite3_uint64 are the preferred type definitions.
-** The sqlite_int64 and sqlite_uint64 types are supported for backwards
-** compatibility only.
-**
-** Requirements: [H10201] [H10202]
-*/
-#ifdef SQLITE_INT64_TYPE
- typedef SQLITE_INT64_TYPE sqlite_int64;
- typedef unsigned SQLITE_INT64_TYPE sqlite_uint64;
-#elif defined(_MSC_VER) || defined(__BORLANDC__)
- typedef __int64 sqlite_int64;
- typedef unsigned __int64 sqlite_uint64;
-#else
- typedef long long int sqlite_int64;
- typedef unsigned long long int sqlite_uint64;
-#endif
-typedef sqlite_int64 sqlite3_int64;
-typedef sqlite_uint64 sqlite3_uint64;
-
-/*
-** If compiling for a processor that lacks floating point support,
-** substitute integer for floating-point.
-*/
-#ifdef SQLITE_OMIT_FLOATING_POINT
-# define double sqlite3_int64
-#endif
-
-/*
-** CAPI3REF: Closing A Database Connection {H12010} <S30100><S40200>
-**
-** This routine is the destructor for the [sqlite3] object.
-**
-** Applications should [sqlite3_finalize | finalize] all [prepared statements]
-** and [sqlite3_blob_close | close] all [BLOB handles] associated with
-** the [sqlite3] object prior to attempting to close the object.
-** The [sqlite3_next_stmt()] interface can be used to locate all
-** [prepared statements] associated with a [database connection] if desired.
-** Typical code might look like this:
-**
-** <blockquote><pre>
-** sqlite3_stmt *pStmt;
-** while( (pStmt = sqlite3_next_stmt(db, 0))!=0 ){
-** &nbsp; sqlite3_finalize(pStmt);
-** }
-** </pre></blockquote>
-**
-** If [sqlite3_close()] is invoked while a transaction is open,
-** the transaction is automatically rolled back.
-**
-** The C parameter to [sqlite3_close(C)] must be either a NULL
-** pointer or an [sqlite3] object pointer obtained
-** from [sqlite3_open()], [sqlite3_open16()], or
-** [sqlite3_open_v2()], and not previously closed.
-**
-** Requirements:
-** [H12011] [H12012] [H12013] [H12014] [H12015] [H12019]
-*/
-SQLITE_API int sqlite3_close(sqlite3 *);
-
-/*
-** The type for a callback function.
-** This is legacy and deprecated. It is included for historical
-** compatibility and is not documented.
-*/
-typedef int (*sqlite3_callback)(void*,int,char**, char**);
-
-/*
-** CAPI3REF: One-Step Query Execution Interface {H12100} <S10000>
-**
-** The sqlite3_exec() interface is a convenient way of running one or more
-** SQL statements without having to write a lot of C code. The UTF-8 encoded
-** SQL statements are passed in as the second parameter to sqlite3_exec().
-** The statements are evaluated one by one until either an error or
-** an interrupt is encountered, or until they are all done. The 3rd parameter
-** is an optional callback that is invoked once for each row of any query
-** results produced by the SQL statements. The 5th parameter tells where
-** to write any error messages.
-**
-** The error message passed back through the 5th parameter is held
-** in memory obtained from [sqlite3_malloc()]. To avoid a memory leak,
-** the calling application should call [sqlite3_free()] on any error
-** message returned through the 5th parameter when it has finished using
-** the error message.
-**
-** If the SQL statement in the 2nd parameter is NULL or an empty string
-** or a string containing only whitespace and comments, then no SQL
-** statements are evaluated and the database is not changed.
-**
-** The sqlite3_exec() interface is implemented in terms of
-** [sqlite3_prepare_v2()], [sqlite3_step()], and [sqlite3_finalize()].
-** The sqlite3_exec() routine does nothing to the database that cannot be done
-** by [sqlite3_prepare_v2()], [sqlite3_step()], and [sqlite3_finalize()].
-**
-** The first parameter to [sqlite3_exec()] must be an valid and open
-** [database connection].
-**
-** The database connection must not be closed while
-** [sqlite3_exec()] is running.
-**
-** The calling function should use [sqlite3_free()] to free
-** the memory that *errmsg is left pointing at once the error
-** message is no longer needed.
-**
-** The SQL statement text in the 2nd parameter to [sqlite3_exec()]
-** must remain unchanged while [sqlite3_exec()] is running.
-**
-** Requirements:
-** [H12101] [H12102] [H12104] [H12105] [H12107] [H12110] [H12113] [H12116]
-** [H12119] [H12122] [H12125] [H12131] [H12134] [H12137] [H12138]
-*/
-SQLITE_API int sqlite3_exec(
- sqlite3*, /* An open database */
- const char *sql, /* SQL to be evaluated */
- int (*callback)(void*,int,char**,char**), /* Callback function */
- void *, /* 1st argument to callback */
- char **errmsg /* Error msg written here */
-);
-
-/*
-** CAPI3REF: Result Codes {H10210} <S10700>
-** KEYWORDS: SQLITE_OK {error code} {error codes}
-** 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.
-**
-** New error codes may be added in future versions of SQLite.
-**
-** See also: [SQLITE_IOERR_READ | extended result codes]
-*/
-#define SQLITE_OK 0 /* Successful result */
-/* beginning-of-error-codes */
-#define SQLITE_ERROR 1 /* SQL error or missing database */
-#define SQLITE_INTERNAL 2 /* Internal logic error in SQLite */
-#define SQLITE_PERM 3 /* Access permission denied */
-#define SQLITE_ABORT 4 /* Callback routine requested an abort */
-#define SQLITE_BUSY 5 /* The database file is locked */
-#define SQLITE_LOCKED 6 /* A table in the database is locked */
-#define SQLITE_NOMEM 7 /* A malloc() failed */
-#define SQLITE_READONLY 8 /* Attempt to write a readonly database */
-#define SQLITE_INTERRUPT 9 /* Operation terminated by sqlite3_interrupt()*/
-#define SQLITE_IOERR 10 /* Some kind of disk I/O error occurred */
-#define SQLITE_CORRUPT 11 /* The database disk image is malformed */
-#define SQLITE_NOTFOUND 12 /* NOT USED. Table or record not found */
-#define SQLITE_FULL 13 /* Insertion failed because database is full */
-#define SQLITE_CANTOPEN 14 /* Unable to open the database file */
-#define SQLITE_PROTOCOL 15 /* NOT USED. Database lock protocol error */
-#define SQLITE_EMPTY 16 /* Database is empty */
-#define SQLITE_SCHEMA 17 /* The database schema changed */
-#define SQLITE_TOOBIG 18 /* String or BLOB exceeds size limit */
-#define SQLITE_CONSTRAINT 19 /* Abort due to constraint violation */
-#define SQLITE_MISMATCH 20 /* Data type mismatch */
-#define SQLITE_MISUSE 21 /* Library used incorrectly */
-#define SQLITE_NOLFS 22 /* Uses OS features not supported on host */
-#define SQLITE_AUTH 23 /* Authorization denied */
-#define SQLITE_FORMAT 24 /* Auxiliary database format error */
-#define SQLITE_RANGE 25 /* 2nd parameter to sqlite3_bind out of range */
-#define SQLITE_NOTADB 26 /* File opened that is not a database file */
-#define SQLITE_ROW 100 /* sqlite3_step() has another row ready */
-#define SQLITE_DONE 101 /* sqlite3_step() has finished executing */
-/* end-of-error-codes */
-
-/*
-** CAPI3REF: Extended Result Codes {H10220} <S10700>
-** KEYWORDS: {extended error code} {extended error codes}
-** KEYWORDS: {extended result code} {extended result codes}
-**
-** In its default configuration, SQLite API routines return one of 26 integer
-** [SQLITE_OK | result codes]. However, experience has shown that many of
-** these result codes are too coarse-grained. They do not provide as
-** much information about problems as programmers might like. In an effort to
-** address this, newer versions of SQLite (version 3.3.8 and later) include
-** support for additional result codes that provide more detailed information
-** about errors. The extended result codes are enabled or disabled
-** on a per database connection basis using the
-** [sqlite3_extended_result_codes()] API.
-**
-** Some of the available extended result codes are listed here.
-** One may expect the number of extended result codes will be expand
-** over time. Software that uses extended result codes should expect
-** to see new result codes in future releases of SQLite.
-**
-** The SQLITE_OK result code will never be extended. It will always
-** be exactly zero.
-*/
-#define SQLITE_IOERR_READ (SQLITE_IOERR | (1<<8))
-#define SQLITE_IOERR_SHORT_READ (SQLITE_IOERR | (2<<8))
-#define SQLITE_IOERR_WRITE (SQLITE_IOERR | (3<<8))
-#define SQLITE_IOERR_FSYNC (SQLITE_IOERR | (4<<8))
-#define SQLITE_IOERR_DIR_FSYNC (SQLITE_IOERR | (5<<8))
-#define SQLITE_IOERR_TRUNCATE (SQLITE_IOERR | (6<<8))
-#define SQLITE_IOERR_FSTAT (SQLITE_IOERR | (7<<8))
-#define SQLITE_IOERR_UNLOCK (SQLITE_IOERR | (8<<8))
-#define SQLITE_IOERR_RDLOCK (SQLITE_IOERR | (9<<8))
-#define SQLITE_IOERR_DELETE (SQLITE_IOERR | (10<<8))
-#define SQLITE_IOERR_BLOCKED (SQLITE_IOERR | (11<<8))
-#define SQLITE_IOERR_NOMEM (SQLITE_IOERR | (12<<8))
-#define SQLITE_IOERR_ACCESS (SQLITE_IOERR | (13<<8))
-#define SQLITE_IOERR_CHECKRESERVEDLOCK (SQLITE_IOERR | (14<<8))
-#define SQLITE_IOERR_LOCK (SQLITE_IOERR | (15<<8))
-#define SQLITE_IOERR_CLOSE (SQLITE_IOERR | (16<<8))
-#define SQLITE_IOERR_DIR_CLOSE (SQLITE_IOERR | (17<<8))
-#define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8) )
-
-/*
-** CAPI3REF: Flags For File Open Operations {H10230} <H11120> <H12700>
-**
-** These bit values are intended for use in the
-** 3rd parameter to the [sqlite3_open_v2()] interface and
-** in the 4th parameter to the xOpen method of the
-** [sqlite3_vfs] object.
-*/
-#define SQLITE_OPEN_READONLY 0x00000001 /* Ok for sqlite3_open_v2() */
-#define SQLITE_OPEN_READWRITE 0x00000002 /* Ok for sqlite3_open_v2() */
-#define SQLITE_OPEN_CREATE 0x00000004 /* Ok for sqlite3_open_v2() */
-#define SQLITE_OPEN_DELETEONCLOSE 0x00000008 /* VFS only */
-#define SQLITE_OPEN_EXCLUSIVE 0x00000010 /* VFS only */
-#define SQLITE_OPEN_MAIN_DB 0x00000100 /* VFS only */
-#define SQLITE_OPEN_TEMP_DB 0x00000200 /* VFS only */
-#define SQLITE_OPEN_TRANSIENT_DB 0x00000400 /* VFS only */
-#define SQLITE_OPEN_MAIN_JOURNAL 0x00000800 /* VFS only */
-#define SQLITE_OPEN_TEMP_JOURNAL 0x00001000 /* VFS only */
-#define SQLITE_OPEN_SUBJOURNAL 0x00002000 /* VFS only */
-#define SQLITE_OPEN_MASTER_JOURNAL 0x00004000 /* VFS only */
-#define SQLITE_OPEN_NOMUTEX 0x00008000 /* Ok for sqlite3_open_v2() */
-#define SQLITE_OPEN_FULLMUTEX 0x00010000 /* Ok for sqlite3_open_v2() */
-#define SQLITE_OPEN_SHAREDCACHE 0x00020000 /* Ok for sqlite3_open_v2() */
-#define SQLITE_OPEN_PRIVATECACHE 0x00040000 /* Ok for sqlite3_open_v2() */
-
-/*
-** CAPI3REF: Device Characteristics {H10240} <H11120>
-**
-** The xDeviceCapabilities method of the [sqlite3_io_methods]
-** object returns an integer which is a vector of the these
-** bit values expressing I/O characteristics of the mass storage
-** device that holds the file that the [sqlite3_io_methods]
-** refers to.
-**
-** The SQLITE_IOCAP_ATOMIC property means that all writes of
-** any size are atomic. The SQLITE_IOCAP_ATOMICnnn values
-** mean that writes of blocks that are nnn bytes in size and
-** are aligned to an address which is an integer multiple of
-** nnn are atomic. The SQLITE_IOCAP_SAFE_APPEND value means
-** that when data is appended to a file, the data is appended
-** 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().
-*/
-#define SQLITE_IOCAP_ATOMIC 0x00000001
-#define SQLITE_IOCAP_ATOMIC512 0x00000002
-#define SQLITE_IOCAP_ATOMIC1K 0x00000004
-#define SQLITE_IOCAP_ATOMIC2K 0x00000008
-#define SQLITE_IOCAP_ATOMIC4K 0x00000010
-#define SQLITE_IOCAP_ATOMIC8K 0x00000020
-#define SQLITE_IOCAP_ATOMIC16K 0x00000040
-#define SQLITE_IOCAP_ATOMIC32K 0x00000080
-#define SQLITE_IOCAP_ATOMIC64K 0x00000100
-#define SQLITE_IOCAP_SAFE_APPEND 0x00000200
-#define SQLITE_IOCAP_SEQUENTIAL 0x00000400
-
-/*
-** CAPI3REF: File Locking Levels {H10250} <H11120> <H11310>
-**
-** SQLite uses one of these integer values as the second
-** argument to calls it makes to the xLock() and xUnlock() methods
-** of an [sqlite3_io_methods] object.
-*/
-#define SQLITE_LOCK_NONE 0
-#define SQLITE_LOCK_SHARED 1
-#define SQLITE_LOCK_RESERVED 2
-#define SQLITE_LOCK_PENDING 3
-#define SQLITE_LOCK_EXCLUSIVE 4
-
-/*
-** CAPI3REF: Synchronization Type Flags {H10260} <H11120>
-**
-** When SQLite invokes the xSync() method of an
-** [sqlite3_io_methods] object it uses a combination of
-** these integer values as the second argument.
-**
-** When the SQLITE_SYNC_DATAONLY flag is used, it means that the
-** sync operation only needs to flush data to mass storage. Inode
-** information need not be flushed. If the lower four bits of the flag
-** equal SQLITE_SYNC_NORMAL, that means to use normal fsync() semantics.
-** If the lower four bits equal SQLITE_SYNC_FULL, that means
-** to use Mac OS X style fullsync instead of fsync().
-*/
-#define SQLITE_SYNC_NORMAL 0x00002
-#define SQLITE_SYNC_FULL 0x00003
-#define SQLITE_SYNC_DATAONLY 0x00010
-
-/*
-** CAPI3REF: OS Interface Open File Handle {H11110} <S20110>
-**
-** An [sqlite3_file] object represents an open file in the
-** [sqlite3_vfs | OS interface layer]. Individual OS interface
-** implementations will
-** want to subclass this object by appending additional fields
-** for their own use. The pMethods entry is a pointer to an
-** [sqlite3_io_methods] object that defines methods for performing
-** I/O operations on the open file.
-*/
-typedef struct sqlite3_file sqlite3_file;
-struct sqlite3_file {
- const struct sqlite3_io_methods *pMethods; /* Methods for an open file */
-};
-
-/*
-** CAPI3REF: OS Interface File Virtual Methods Object {H11120} <S20110>
-**
-** Every file opened by the [sqlite3_vfs] xOpen method populates an
-** [sqlite3_file] object (or, more commonly, a subclass of the
-** [sqlite3_file] object) with a pointer to an instance of this object.
-** This object defines the methods used to perform various operations
-** against the open file represented by the [sqlite3_file] object.
-**
-** If the xOpen method sets the sqlite3_file.pMethods element
-** to a non-NULL pointer, then the sqlite3_io_methods.xClose method
-** may be invoked even if the xOpen reported that it failed. The
-** only way to prevent a call to xClose following a failed xOpen
-** is for the xOpen to set the sqlite3_file.pMethods element to NULL.
-**
-** The flags argument to xSync may be one of [SQLITE_SYNC_NORMAL] or
-** [SQLITE_SYNC_FULL]. The first choice is the normal fsync().
-** The second choice is a Mac OS X style fullsync. The [SQLITE_SYNC_DATAONLY]
-** flag may be ORed in to indicate that only the data of the file
-** and not its inode needs to be synced.
-**
-** The integer values to xLock() and xUnlock() are one of
-** <ul>
-** <li> [SQLITE_LOCK_NONE],
-** <li> [SQLITE_LOCK_SHARED],
-** <li> [SQLITE_LOCK_RESERVED],
-** <li> [SQLITE_LOCK_PENDING], or
-** <li> [SQLITE_LOCK_EXCLUSIVE].
-** </ul>
-** xLock() increases the lock. xUnlock() decreases the lock.
-** The xCheckReservedLock() method checks whether any database connection,
-** either in this process or in some other process, is holding a RESERVED,
-** PENDING, or EXCLUSIVE lock on the file. It returns true
-** if such a lock exists and false otherwise.
-**
-** The xFileControl() method is a generic interface that allows custom
-** VFS implementations to directly control an open file using the
-** [sqlite3_file_control()] interface. The second "op" argument is an
-** integer opcode. The third argument is a generic pointer intended to
-** point to a structure that may contain arguments or space in which to
-** write return values. Potential uses for xFileControl() might be
-** functions to enable blocking locks with timeouts, to change the
-** locking strategy (for example to use dot-file locks), to inquire
-** about the status of a lock, or to break stale locks. The SQLite
-** core reserves all opcodes less than 100 for its own use.
-** A [SQLITE_FCNTL_LOCKSTATE | list of opcodes] less than 100 is available.
-** Applications that define a custom xFileControl method should use opcodes
-** greater than 100 to avoid conflicts.
-**
-** The xSectorSize() method returns the sector size of the
-** device that underlies the file. The sector size is the
-** minimum write that can be performed without disturbing
-** other bytes in the file. The xDeviceCharacteristics()
-** method returns a bit vector describing behaviors of the
-** underlying device:
-**
-** <ul>
-** <li> [SQLITE_IOCAP_ATOMIC]
-** <li> [SQLITE_IOCAP_ATOMIC512]
-** <li> [SQLITE_IOCAP_ATOMIC1K]
-** <li> [SQLITE_IOCAP_ATOMIC2K]
-** <li> [SQLITE_IOCAP_ATOMIC4K]
-** <li> [SQLITE_IOCAP_ATOMIC8K]
-** <li> [SQLITE_IOCAP_ATOMIC16K]
-** <li> [SQLITE_IOCAP_ATOMIC32K]
-** <li> [SQLITE_IOCAP_ATOMIC64K]
-** <li> [SQLITE_IOCAP_SAFE_APPEND]
-** <li> [SQLITE_IOCAP_SEQUENTIAL]
-** </ul>
-**
-** The SQLITE_IOCAP_ATOMIC property means that all writes of
-** any size are atomic. The SQLITE_IOCAP_ATOMICnnn values
-** mean that writes of blocks that are nnn bytes in size and
-** are aligned to an address which is an integer multiple of
-** nnn are atomic. The SQLITE_IOCAP_SAFE_APPEND value means
-** that when data is appended to a file, the data is appended
-** 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().
-**
-** If xRead() returns SQLITE_IOERR_SHORT_READ it must also fill
-** in the unread portions of the buffer with zeros. A VFS that
-** fails to zero-fill short reads might seem to work. However,
-** failure to zero-fill short reads will eventually lead to
-** database corruption.
-*/
-typedef struct sqlite3_io_methods sqlite3_io_methods;
-struct sqlite3_io_methods {
- int iVersion;
- int (*xClose)(sqlite3_file*);
- int (*xRead)(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst);
- int (*xWrite)(sqlite3_file*, const void*, int iAmt, sqlite3_int64 iOfst);
- int (*xTruncate)(sqlite3_file*, sqlite3_int64 size);
- int (*xSync)(sqlite3_file*, int flags);
- int (*xFileSize)(sqlite3_file*, sqlite3_int64 *pSize);
- int (*xLock)(sqlite3_file*, int);
- int (*xUnlock)(sqlite3_file*, int);
- int (*xCheckReservedLock)(sqlite3_file*, int *pResOut);
- int (*xFileControl)(sqlite3_file*, int op, void *pArg);
- int (*xSectorSize)(sqlite3_file*);
- int (*xDeviceCharacteristics)(sqlite3_file*);
- /* Additional methods may be added in future releases */
-};
-
-/*
-** CAPI3REF: Standard File Control Opcodes {H11310} <S30800>
-**
-** These integer constants are opcodes for the xFileControl method
-** of the [sqlite3_io_methods] object and for the [sqlite3_file_control()]
-** interface.
-**
-** The [SQLITE_FCNTL_LOCKSTATE] opcode is used for debugging. This
-** opcode causes the xFileControl method to write the current state of
-** the lock (one of [SQLITE_LOCK_NONE], [SQLITE_LOCK_SHARED],
-** [SQLITE_LOCK_RESERVED], [SQLITE_LOCK_PENDING], or [SQLITE_LOCK_EXCLUSIVE])
-** into an integer that the pArg argument points to. This capability
-** is used during testing and only needs to be supported when SQLITE_TEST
-** is defined.
-*/
-#define SQLITE_FCNTL_LOCKSTATE 1
-#define SQLITE_GET_LOCKPROXYFILE 2
-#define SQLITE_SET_LOCKPROXYFILE 3
-#define SQLITE_LAST_ERRNO 4
-
-/*
-** CAPI3REF: Mutex Handle {H17110} <S20130>
-**
-** The mutex module within SQLite defines [sqlite3_mutex] to be an
-** abstract type for a mutex object. The SQLite core never looks
-** at the internal representation of an [sqlite3_mutex]. It only
-** deals with pointers to the [sqlite3_mutex] object.
-**
-** Mutexes are created using [sqlite3_mutex_alloc()].
-*/
-typedef struct sqlite3_mutex sqlite3_mutex;
-
-/*
-** CAPI3REF: OS Interface Object {H11140} <S20100>
-**
-** An instance of the sqlite3_vfs object defines the interface between
-** the SQLite core and the underlying operating system. The "vfs"
-** in the name of the object stands for "virtual file system".
-**
-** The value of the iVersion field is initially 1 but may be larger in
-** future versions of SQLite. Additional fields may be appended to this
-** object when the iVersion value is increased. Note that the structure
-** of the sqlite3_vfs object changes in the transaction between
-** SQLite version 3.5.9 and 3.6.0 and yet the iVersion field was not
-** modified.
-**
-** The szOsFile field is the size of the subclassed [sqlite3_file]
-** structure used by this VFS. mxPathname is the maximum length of
-** a pathname in this VFS.
-**
-** Registered sqlite3_vfs objects are kept on a linked list formed by
-** the pNext pointer. The [sqlite3_vfs_register()]
-** and [sqlite3_vfs_unregister()] interfaces manage this list
-** in a thread-safe way. The [sqlite3_vfs_find()] interface
-** searches the list. Neither the application code nor the VFS
-** implementation should use the pNext pointer.
-**
-** The pNext field is the only field in the sqlite3_vfs
-** structure that SQLite will ever modify. SQLite will only access
-** or modify this field while holding a particular static mutex.
-** The application should never modify anything within the sqlite3_vfs
-** object once the object has been registered.
-**
-** The zName field holds the name of the VFS module. The name must
-** be unique across all VFS modules.
-**
-** SQLite will guarantee that the zFilename parameter to xOpen
-** is either a NULL pointer or string obtained
-** from xFullPathname(). SQLite further guarantees that
-** the string will be valid and unchanged until xClose() is
-** called. Because of the previous sentence,
-** the [sqlite3_file] can safely store a pointer to the
-** filename if it needs to remember the filename for some reason.
-** If the zFilename parameter is xOpen is a NULL pointer then xOpen
-** must invent its own temporary name for the file. Whenever the
-** xFilename parameter is NULL it will also be the case that the
-** flags parameter will include [SQLITE_OPEN_DELETEONCLOSE].
-**
-** The flags argument to xOpen() includes all bits set in
-** the flags argument to [sqlite3_open_v2()]. Or if [sqlite3_open()]
-** or [sqlite3_open16()] is used, then flags includes at least
-** [SQLITE_OPEN_READWRITE] | [SQLITE_OPEN_CREATE].
-** If xOpen() opens a file read-only then it sets *pOutFlags to
-** include [SQLITE_OPEN_READONLY]. Other bits in *pOutFlags may be set.
-**
-** SQLite will also add one of the following flags to the xOpen()
-** call, depending on the object being opened:
-**
-** <ul>
-** <li> [SQLITE_OPEN_MAIN_DB]
-** <li> [SQLITE_OPEN_MAIN_JOURNAL]
-** <li> [SQLITE_OPEN_TEMP_DB]
-** <li> [SQLITE_OPEN_TEMP_JOURNAL]
-** <li> [SQLITE_OPEN_TRANSIENT_DB]
-** <li> [SQLITE_OPEN_SUBJOURNAL]
-** <li> [SQLITE_OPEN_MASTER_JOURNAL]
-** </ul>
-**
-** The file I/O implementation can use the object type flags to
-** change the way it deals with files. For example, an application
-** that does not care about crash recovery or rollback might make
-** the open of a journal file a no-op. Writes to this journal would
-** also be no-ops, and any attempt to read the journal would return
-** SQLITE_IOERR. Or the implementation might recognize that a database
-** file will be doing page-aligned sector reads and writes in a random
-** order and set up its I/O subsystem accordingly.
-**
-** SQLite might also add one of the following flags to the xOpen method:
-**
-** <ul>
-** <li> [SQLITE_OPEN_DELETEONCLOSE]
-** <li> [SQLITE_OPEN_EXCLUSIVE]
-** </ul>
-**
-** The [SQLITE_OPEN_DELETEONCLOSE] flag means the file should be
-** deleted when it is closed. The [SQLITE_OPEN_DELETEONCLOSE]
-** will be set for TEMP databases, journals and for subjournals.
-**
-** The [SQLITE_OPEN_EXCLUSIVE] flag is always used in conjunction
-** with the [SQLITE_OPEN_CREATE] flag, which are both directly
-** analogous to the O_EXCL and O_CREAT flags of the POSIX open()
-** API. The SQLITE_OPEN_EXCLUSIVE flag, when paired with the
-** SQLITE_OPEN_CREATE, is used to indicate that file should always
-** be created, and that it is an error if it already exists.
-** It is <i>not</i> used to indicate the file should be opened
-** for exclusive access.
-**
-** At least szOsFile bytes of memory are allocated by SQLite
-** to hold the [sqlite3_file] structure passed as the third
-** argument to xOpen. The xOpen method does not have to
-** allocate the structure; it should just fill it in. Note that
-** the xOpen method must set the sqlite3_file.pMethods to either
-** a valid [sqlite3_io_methods] object or to NULL. xOpen must do
-** this even if the open fails. SQLite expects that the sqlite3_file.pMethods
-** element will be valid after xOpen returns regardless of the success
-** or failure of the xOpen call.
-**
-** The flags argument to xAccess() may be [SQLITE_ACCESS_EXISTS]
-** to test for the existence of a file, or [SQLITE_ACCESS_READWRITE] to
-** test whether a file is readable and writable, or [SQLITE_ACCESS_READ]
-** to test whether a file is at least readable. The file can be a
-** directory.
-**
-** SQLite will always allocate at least mxPathname+1 bytes for the
-** output buffer xFullPathname. The exact size of the output buffer
-** is also passed as a parameter to both methods. If the output buffer
-** is not large enough, [SQLITE_CANTOPEN] should be returned. Since this is
-** handled as a fatal error by SQLite, vfs implementations should endeavor
-** to prevent this by setting mxPathname to a sufficiently large value.
-**
-** The xRandomness(), xSleep(), and xCurrentTime() interfaces
-** are not strictly a part of the filesystem, but they are
-** included in the VFS structure for completeness.
-** The xRandomness() function attempts to return nBytes bytes
-** of good-quality randomness into zOut. The return value is
-** the actual number of bytes of randomness obtained.
-** The xSleep() method causes the calling thread to sleep for at
-** least the number of microseconds given. The xCurrentTime()
-** method returns a Julian Day Number for the current date and time.
-**
-*/
-typedef struct sqlite3_vfs sqlite3_vfs;
-struct sqlite3_vfs {
- int iVersion; /* Structure version number */
- int szOsFile; /* Size of subclassed sqlite3_file */
- int mxPathname; /* Maximum file pathname length */
- sqlite3_vfs *pNext; /* Next registered VFS */
- const char *zName; /* Name of this virtual file system */
- void *pAppData; /* Pointer to application-specific data */
- int (*xOpen)(sqlite3_vfs*, const char *zName, sqlite3_file*,
- int flags, int *pOutFlags);
- int (*xDelete)(sqlite3_vfs*, const char *zName, int syncDir);
- int (*xAccess)(sqlite3_vfs*, const char *zName, int flags, int *pResOut);
- int (*xFullPathname)(sqlite3_vfs*, const char *zName, int nOut, char *zOut);
- void *(*xDlOpen)(sqlite3_vfs*, const char *zFilename);
- void (*xDlError)(sqlite3_vfs*, int nByte, char *zErrMsg);
- void (*(*xDlSym)(sqlite3_vfs*,void*, const char *zSymbol))(void);
- void (*xDlClose)(sqlite3_vfs*, void*);
- int (*xRandomness)(sqlite3_vfs*, int nByte, char *zOut);
- int (*xSleep)(sqlite3_vfs*, int microseconds);
- int (*xCurrentTime)(sqlite3_vfs*, double*);
- int (*xGetLastError)(sqlite3_vfs*, int, char *);
- /* New fields may be appended in figure versions. The iVersion
- ** value will increment whenever this happens. */
-};
-
-/*
-** CAPI3REF: Flags for the xAccess VFS method {H11190} <H11140>
-**
-** These integer constants can be used as the third parameter to
-** the xAccess method of an [sqlite3_vfs] object. {END} They determine
-** what kind of permissions the xAccess method is looking for.
-** With SQLITE_ACCESS_EXISTS, the xAccess method
-** simply checks whether the file exists.
-** With SQLITE_ACCESS_READWRITE, the xAccess method
-** checks whether the file is both readable and writable.
-** With SQLITE_ACCESS_READ, the xAccess method
-** checks whether the file is readable.
-*/
-#define SQLITE_ACCESS_EXISTS 0
-#define SQLITE_ACCESS_READWRITE 1
-#define SQLITE_ACCESS_READ 2
-
-/*
-** CAPI3REF: Initialize The SQLite Library {H10130} <S20000><S30100>
-**
-** The sqlite3_initialize() routine initializes the
-** SQLite library. The sqlite3_shutdown() routine
-** deallocates any resources that were allocated by sqlite3_initialize().
-**
-** A call to sqlite3_initialize() is an "effective" call if it is
-** the first time sqlite3_initialize() is invoked during the lifetime of
-** the process, or if it is the first time sqlite3_initialize() is invoked
-** following a call to sqlite3_shutdown(). Only an effective call
-** of sqlite3_initialize() does any initialization. All other calls
-** are harmless no-ops.
-**
-** A call to sqlite3_shutdown() is an "effective" call if it is the first
-** call to sqlite3_shutdown() since the last sqlite3_initialize(). Only
-** an effective call to sqlite3_shutdown() does any deinitialization.
-** All other calls to sqlite3_shutdown() are harmless no-ops.
-**
-** Among other things, sqlite3_initialize() shall invoke
-** sqlite3_os_init(). Similarly, sqlite3_shutdown()
-** shall invoke sqlite3_os_end().
-**
-** The sqlite3_initialize() routine returns [SQLITE_OK] on success.
-** If for some reason, sqlite3_initialize() is unable to initialize
-** the library (perhaps it is unable to allocate a needed resource such
-** as a mutex) it returns an [error code] other than [SQLITE_OK].
-**
-** The sqlite3_initialize() routine is called internally by many other
-** SQLite interfaces so that an application usually does not need to
-** invoke sqlite3_initialize() directly. For example, [sqlite3_open()]
-** calls sqlite3_initialize() so the SQLite library will be automatically
-** initialized when [sqlite3_open()] is called if it has not be initialized
-** already. However, if SQLite is compiled with the [SQLITE_OMIT_AUTOINIT]
-** compile-time option, then the automatic calls to sqlite3_initialize()
-** are omitted and the application must call sqlite3_initialize() directly
-** prior to using any other SQLite interface. For maximum portability,
-** it is recommended that applications always invoke sqlite3_initialize()
-** directly prior to using any other SQLite interface. Future releases
-** of SQLite may require this. In other words, the behavior exhibited
-** when SQLite is compiled with [SQLITE_OMIT_AUTOINIT] might become the
-** default behavior in some future release of SQLite.
-**
-** The sqlite3_os_init() routine does operating-system specific
-** initialization of the SQLite library. The sqlite3_os_end()
-** routine undoes the effect of sqlite3_os_init(). Typical tasks
-** performed by these routines include allocation or deallocation
-** of static resources, initialization of global variables,
-** setting up a default [sqlite3_vfs] module, or setting up
-** a default configuration using [sqlite3_config()].
-**
-** The application should never invoke either sqlite3_os_init()
-** or sqlite3_os_end() directly. The application should only invoke
-** sqlite3_initialize() and sqlite3_shutdown(). The sqlite3_os_init()
-** interface is called automatically by sqlite3_initialize() and
-** sqlite3_os_end() is called by sqlite3_shutdown(). Appropriate
-** implementations for sqlite3_os_init() and sqlite3_os_end()
-** are built into SQLite when it is compiled for Unix, Windows, or OS/2.
-** When [custom builds | built for other platforms]
-** (using the [SQLITE_OS_OTHER=1] compile-time
-** option) the application must supply a suitable implementation for
-** sqlite3_os_init() and sqlite3_os_end(). An application-supplied
-** implementation of sqlite3_os_init() or sqlite3_os_end()
-** must return [SQLITE_OK] on success and some other [error code] upon
-** failure.
-*/
-SQLITE_API int sqlite3_initialize(void);
-SQLITE_API int sqlite3_shutdown(void);
-SQLITE_API int sqlite3_os_init(void);
-SQLITE_API int sqlite3_os_end(void);
-
-/*
-** CAPI3REF: Configuring The SQLite Library {H14100} <S20000><S30200>
-** EXPERIMENTAL
-**
-** The sqlite3_config() interface is used to make global configuration
-** changes to SQLite in order to tune SQLite to the specific needs of
-** the application. The default configuration is recommended for most
-** applications and so this routine is usually not necessary. It is
-** provided to support rare applications with unusual needs.
-**
-** The sqlite3_config() interface is not threadsafe. The application
-** must insure that no other SQLite interfaces are invoked by other
-** threads while sqlite3_config() is running. Furthermore, sqlite3_config()
-** may only be invoked prior to library initialization using
-** [sqlite3_initialize()] or after shutdown by [sqlite3_shutdown()].
-** Note, however, that sqlite3_config() can be called as part of the
-** implementation of an application-defined [sqlite3_os_init()].
-**
-** The first argument to sqlite3_config() is an integer
-** [SQLITE_CONFIG_SINGLETHREAD | configuration option] that determines
-** what property of SQLite is to be configured. Subsequent arguments
-** vary depending on the [SQLITE_CONFIG_SINGLETHREAD | configuration option]
-** in the first argument.
-**
-** When a configuration option is set, sqlite3_config() returns [SQLITE_OK].
-** If the option is unknown or SQLite is unable to set the option
-** then this routine returns a non-zero [error code].
-**
-** Requirements:
-** [H14103] [H14106] [H14120] [H14123] [H14126] [H14129] [H14132] [H14135]
-** [H14138] [H14141] [H14144] [H14147] [H14150] [H14153] [H14156] [H14159]
-** [H14162] [H14165] [H14168]
-*/
-SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_config(int, ...);
-
-/*
-** CAPI3REF: Configure database connections {H14200} <S20000>
-** EXPERIMENTAL
-**
-** The sqlite3_db_config() interface is used to make configuration
-** changes to a [database connection]. The interface is similar to
-** [sqlite3_config()] except that the changes apply to a single
-** [database connection] (specified in the first argument). The
-** sqlite3_db_config() interface can only be used immediately after
-** the database connection is created using [sqlite3_open()],
-** [sqlite3_open16()], or [sqlite3_open_v2()].
-**
-** The second argument to sqlite3_db_config(D,V,...) is the
-** configuration verb - an integer code that indicates what
-** aspect of the [database connection] is being configured.
-** The only choice for this value is [SQLITE_DBCONFIG_LOOKASIDE].
-** New verbs are likely to be added in future releases of SQLite.
-** Additional arguments depend on the verb.
-**
-** Requirements:
-** [H14203] [H14206] [H14209] [H14212] [H14215]
-*/
-SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_db_config(sqlite3*, int op, ...);
-
-/*
-** CAPI3REF: Memory Allocation Routines {H10155} <S20120>
-** EXPERIMENTAL
-**
-** An instance of this object defines the interface between SQLite
-** and low-level memory allocation routines.
-**
-** This object is used in only one place in the SQLite interface.
-** A pointer to an instance of this object is the argument to
-** [sqlite3_config()] when the configuration option is
-** [SQLITE_CONFIG_MALLOC] or [SQLITE_CONFIG_GETMALLOC].
-** By creating an instance of this object
-** and passing it to [sqlite3_config]([SQLITE_CONFIG_MALLOC])
-** during configuration, an application can specify an alternative
-** memory allocation subsystem for SQLite to use for all of its
-** dynamic memory needs.
-**
-** Note that SQLite comes with several [built-in memory allocators]
-** that are perfectly adequate for the overwhelming majority of applications
-** and that this object is only useful to a tiny minority of applications
-** with specialized memory allocation requirements. This object is
-** also used during testing of SQLite in order to specify an alternative
-** memory allocator that simulates memory out-of-memory conditions in
-** order to verify that SQLite recovers gracefully from such
-** conditions.
-**
-** The xMalloc and xFree methods must work like the
-** malloc() and free() functions from the standard C library.
-** The xRealloc method must work like realloc() from the standard C library
-** with the exception that if the second argument to xRealloc is zero,
-** xRealloc must be a no-op - it must not perform any allocation or
-** deallocation. SQLite guaranteeds that the second argument to
-** xRealloc is always a value returned by a prior call to xRoundup.
-** And so in cases where xRoundup always returns a positive number,
-** xRealloc can perform exactly as the standard library realloc() and
-** still be in compliance with this specification.
-**
-** xSize should return the allocated size of a memory allocation
-** previously obtained from xMalloc or xRealloc. The allocated size
-** is always at least as big as the requested size but may be larger.
-**
-** The xRoundup method returns what would be the allocated size of
-** a memory allocation given a particular requested size. Most memory
-** allocators round up memory allocations at least to the next multiple
-** of 8. Some allocators round up to a larger multiple or to a power of 2.
-** Every memory allocation request coming in through [sqlite3_malloc()]
-** or [sqlite3_realloc()] first calls xRoundup. If xRoundup returns 0,
-** that causes the corresponding memory allocation to fail.
-**
-** The xInit method initializes the memory allocator. (For example,
-** it might allocate any require mutexes or initialize internal data
-** structures. The xShutdown method is invoked (indirectly) by
-** [sqlite3_shutdown()] and should deallocate any resources acquired
-** by xInit. The pAppData pointer is used as the only parameter to
-** xInit and xShutdown.
-**
-** SQLite holds the [SQLITE_MUTEX_STATIC_MASTER] mutex when it invokes
-** the xInit method, so the xInit method need not be threadsafe. The
-** xShutdown method is only called from [sqlite3_shutdown()] so it does
-** not need to be threadsafe either. For all other methods, SQLite
-** holds the [SQLITE_MUTEX_STATIC_MEM] mutex as long as the
-** [SQLITE_CONFIG_MEMSTATUS] configuration option is turned on (which
-** it is by default) and so the methods are automatically serialized.
-** However, if [SQLITE_CONFIG_MEMSTATUS] is disabled, then the other
-** methods must be threadsafe or else make their own arrangements for
-** serialization.
-**
-** SQLite will never invoke xInit() more than once without an intervening
-** call to xShutdown().
-*/
-typedef struct sqlite3_mem_methods sqlite3_mem_methods;
-struct sqlite3_mem_methods {
- void *(*xMalloc)(int); /* Memory allocation function */
- void (*xFree)(void*); /* Free a prior allocation */
- void *(*xRealloc)(void*,int); /* Resize an allocation */
- int (*xSize)(void*); /* Return the size of an allocation */
- int (*xRoundup)(int); /* Round up request size to allocation size */
- int (*xInit)(void*); /* Initialize the memory allocator */
- void (*xShutdown)(void*); /* Deinitialize the memory allocator */
- void *pAppData; /* Argument to xInit() and xShutdown() */
-};
-
-/*
-** CAPI3REF: Configuration Options {H10160} <S20000>
-** EXPERIMENTAL
-**
-** These constants are the available integer configuration options that
-** can be passed as the first argument to the [sqlite3_config()] interface.
-**
-** New configuration options may be added in future releases of SQLite.
-** Existing configuration options might be discontinued. Applications
-** should check the return code from [sqlite3_config()] to make sure that
-** the call worked. The [sqlite3_config()] interface will return a
-** non-zero [error code] if a discontinued or unsupported configuration option
-** is invoked.
-**
-** <dl>
-** <dt>SQLITE_CONFIG_SINGLETHREAD</dt>
-** <dd>There are no arguments to this option. This option disables
-** all mutexing and puts SQLite into a mode where it can only be used
-** by a single thread.</dd>
-**
-** <dt>SQLITE_CONFIG_MULTITHREAD</dt>
-** <dd>There are no arguments to this option. This option disables
-** mutexing on [database connection] and [prepared statement] objects.
-** The application is responsible for serializing access to
-** [database connections] and [prepared statements]. But other mutexes
-** are enabled so that SQLite will be safe to use in a multi-threaded
-** environment as long as no two threads attempt to use the same
-** [database connection] at the same time. See the [threading mode]
-** documentation for additional information.</dd>
-**
-** <dt>SQLITE_CONFIG_SERIALIZED</dt>
-** <dd>There are no arguments to this option. This option enables
-** all mutexes including the recursive
-** mutexes on [database connection] and [prepared statement] objects.
-** In this mode (which is the default when SQLite is compiled with
-** [SQLITE_THREADSAFE=1]) the SQLite library will itself serialize access
-** to [database connections] and [prepared statements] so that the
-** application is free to use the same [database connection] or the
-** same [prepared statement] in different threads at the same time.
-** See the [threading mode] documentation for additional information.</dd>
-**
-** <dt>SQLITE_CONFIG_MALLOC</dt>
-** <dd>This option takes a single argument which is a pointer to an
-** instance of the [sqlite3_mem_methods] structure. The argument specifies
-** alternative low-level memory allocation routines to be used in place of
-** the memory allocation routines built into SQLite.</dd>
-**
-** <dt>SQLITE_CONFIG_GETMALLOC</dt>
-** <dd>This option takes a single argument which is a pointer to an
-** instance of the [sqlite3_mem_methods] structure. The [sqlite3_mem_methods]
-** structure is filled with the currently defined memory allocation routines.
-** This option can be used to overload the default memory allocation
-** routines with a wrapper that simulations memory allocation failure or
-** tracks memory usage, for example.</dd>
-**
-** <dt>SQLITE_CONFIG_MEMSTATUS</dt>
-** <dd>This option takes single argument of type int, interpreted as a
-** boolean, which enables or disables the collection of memory allocation
-** statistics. When disabled, the following SQLite interfaces become
-** non-operational:
-** <ul>
-** <li> [sqlite3_memory_used()]
-** <li> [sqlite3_memory_highwater()]
-** <li> [sqlite3_soft_heap_limit()]
-** <li> [sqlite3_status()]
-** </ul>
-** </dd>
-**
-** <dt>SQLITE_CONFIG_SCRATCH</dt>
-** <dd>This option specifies a static memory buffer that SQLite can use for
-** scratch memory. There are three arguments: A pointer an 8-byte
-** aligned memory buffer from which the scrach allocations will be
-** drawn, the size of each scratch allocation (sz),
-** and the maximum number of scratch allocations (N). The sz
-** argument must be a multiple of 16. The sz parameter should be a few bytes
-** larger than the actual scratch space required due to internal overhead.
-** The first argument should pointer to an 8-byte aligned buffer
-** of at least sz*N bytes of memory.
-** SQLite will use no more than one scratch buffer at once per thread, so
-** N should be set to the expected maximum number of threads. The sz
-** parameter should be 6 times the size of the largest database page size.
-** Scratch buffers are used as part of the btree balance operation. If
-** The btree balancer needs additional memory beyond what is provided by
-** scratch buffers or if no scratch buffer space is specified, then SQLite
-** goes to [sqlite3_malloc()] to obtain the memory it needs.</dd>
-**
-** <dt>SQLITE_CONFIG_PAGECACHE</dt>
-** <dd>This option specifies a static memory buffer that SQLite can use for
-** the database page cache with the default page cache implemenation.
-** This configuration should not be used if an application-define page
-** cache implementation is loaded using the SQLITE_CONFIG_PCACHE 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
-** (a power of two between 512 and 32768) plus a little extra for each
-** page header. The page header size is 20 to 40 bytes depending on
-** the host architecture. It is harmless, apart from the wasted memory,
-** to make sz a little too large. The first
-** argument should point to an allocation of at least sz*N bytes of memory.
-** SQLite will use the memory provided by the first argument to satisfy its
-** memory needs for the first N pages that it adds to cache. If additional
-** page cache memory is needed beyond what is provided by this option, then
-** SQLite goes to [sqlite3_malloc()] for the additional storage space.
-** The implementation might use one or more of the N buffers to hold
-** memory accounting information. The pointer in the first argument must
-** be aligned to an 8-byte boundary or subsequent behavior of SQLite
-** will be undefined.</dd>
-**
-** <dt>SQLITE_CONFIG_HEAP</dt>
-** <dd>This option specifies a static memory buffer that SQLite will use
-** for all of its dynamic memory allocation needs beyond those provided
-** for by [SQLITE_CONFIG_SCRATCH] and [SQLITE_CONFIG_PAGECACHE].
-** There are three arguments: An 8-byte aligned pointer to the memory,
-** the number of bytes in the memory buffer, and the minimum allocation size.
-** If the first pointer (the memory pointer) is NULL, then SQLite reverts
-** to using its default memory allocator (the system malloc() implementation),
-** undoing any prior invocation of [SQLITE_CONFIG_MALLOC]. If the
-** memory pointer is not NULL and either [SQLITE_ENABLE_MEMSYS3] or
-** [SQLITE_ENABLE_MEMSYS5] are defined, then the alternative memory
-** allocator is engaged to handle all of SQLites memory allocation needs.
-** The first pointer (the memory pointer) must be aligned to an 8-byte
-** boundary or subsequent behavior of SQLite will be undefined.</dd>
-**
-** <dt>SQLITE_CONFIG_MUTEX</dt>
-** <dd>This option takes a single argument which is a pointer to an
-** instance of the [sqlite3_mutex_methods] structure. The argument specifies
-** alternative low-level mutex routines to be used in place
-** the mutex routines built into SQLite.</dd>
-**
-** <dt>SQLITE_CONFIG_GETMUTEX</dt>
-** <dd>This option takes a single argument which is a pointer to an
-** instance of the [sqlite3_mutex_methods] structure. The
-** [sqlite3_mutex_methods]
-** structure is filled with the currently defined mutex routines.
-** This option can be used to overload the default mutex allocation
-** routines with a wrapper used to track mutex usage for performance
-** profiling or testing, for example.</dd>
-**
-** <dt>SQLITE_CONFIG_LOOKASIDE</dt>
-** <dd>This option takes two arguments that determine the default
-** memory allocation lookaside optimization. The first argument is the
-** size of each lookaside buffer slot and the second is the number of
-** slots allocated to each database connection. This option sets the
-** <i>default</i> lookaside size. The [SQLITE_DBCONFIG_LOOKASIDE]
-** verb to [sqlite3_db_config()] can be used to change the lookaside
-** configuration on individual connections.</dd>
-**
-** <dt>SQLITE_CONFIG_PCACHE</dt>
-** <dd>This option takes a single argument which is a pointer to
-** an [sqlite3_pcache_methods] 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.</dd>
-**
-** <dt>SQLITE_CONFIG_GETPCACHE</dt>
-** <dd>This option takes a single argument which is a pointer to an
-** [sqlite3_pcache_methods] object. SQLite copies of the current
-** page cache implementation into that object.</dd>
-**
-** </dl>
-*/
-#define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */
-#define SQLITE_CONFIG_MULTITHREAD 2 /* nil */
-#define SQLITE_CONFIG_SERIALIZED 3 /* nil */
-#define SQLITE_CONFIG_MALLOC 4 /* sqlite3_mem_methods* */
-#define SQLITE_CONFIG_GETMALLOC 5 /* sqlite3_mem_methods* */
-#define SQLITE_CONFIG_SCRATCH 6 /* void*, int sz, int N */
-#define SQLITE_CONFIG_PAGECACHE 7 /* void*, int sz, int N */
-#define SQLITE_CONFIG_HEAP 8 /* void*, int nByte, int min */
-#define SQLITE_CONFIG_MEMSTATUS 9 /* boolean */
-#define SQLITE_CONFIG_MUTEX 10 /* sqlite3_mutex_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* */
-
-/*
-** CAPI3REF: Configuration Options {H10170} <S20000>
-** EXPERIMENTAL
-**
-** These constants are the available integer configuration options that
-** can be passed as the second argument to the [sqlite3_db_config()] interface.
-**
-** New configuration options may be added in future releases of SQLite.
-** Existing configuration options might be discontinued. Applications
-** should check the return code from [sqlite3_db_config()] to make sure that
-** the call worked. The [sqlite3_db_config()] interface will return a
-** non-zero [error code] if a discontinued or unsupported configuration option
-** is invoked.
-**
-** <dl>
-** <dt>SQLITE_DBCONFIG_LOOKASIDE</dt>
-** <dd>This option takes three additional arguments that determine the
-** [lookaside memory allocator] configuration for the [database connection].
-** The first argument (the third parameter to [sqlite3_db_config()] is a
-** pointer to an memory buffer to use for lookaside memory.
-** The first argument may be NULL in which case SQLite will allocate the
-** lookaside buffer itself using [sqlite3_malloc()]. The second argument is the
-** size of each lookaside buffer slot and the third argument is the number of
-** slots. The size of the buffer in the first argument must be greater than
-** or equal to the product of the second and third arguments. The buffer
-** must be aligned to an 8-byte boundary. If the second argument is not
-** a multiple of 8, it is internally rounded down to the next smaller
-** multiple of 8. See also: [SQLITE_CONFIG_LOOKASIDE]</dd>
-**
-** </dl>
-*/
-#define SQLITE_DBCONFIG_LOOKASIDE 1001 /* void* int int */
-
-
-/*
-** CAPI3REF: Enable Or Disable Extended Result Codes {H12200} <S10700>
-**
-** The sqlite3_extended_result_codes() routine enables or disables the
-** [extended result codes] feature of SQLite. The extended result
-** codes are disabled by default for historical compatibility considerations.
-**
-** Requirements:
-** [H12201] [H12202]
-*/
-SQLITE_API int sqlite3_extended_result_codes(sqlite3*, int onoff);
-
-/*
-** CAPI3REF: Last Insert Rowid {H12220} <S10700>
-**
-** Each entry in an SQLite table has a unique 64-bit signed
-** integer key called the [ROWID | "rowid"]. The rowid is always available
-** as an undeclared column named ROWID, OID, or _ROWID_ as long as those
-** names are not also used by explicitly declared columns. If
-** the table has a column of type [INTEGER PRIMARY KEY] then that column
-** is another alias for the rowid.
-**
-** This routine returns the [rowid] of the most recent
-** successful [INSERT] into the database from the [database connection]
-** in the first argument. If no successful [INSERT]s
-** have ever occurred on that database connection, zero is returned.
-**
-** If an [INSERT] occurs within a trigger, then the [rowid] of the inserted
-** row is returned by this routine as long as the trigger is running.
-** But once the trigger terminates, the value returned by this routine
-** reverts to the last value inserted before the trigger fired.
-**
-** An [INSERT] that fails due to a constraint violation is not a
-** successful [INSERT] and does not change the value returned by this
-** routine. Thus INSERT OR FAIL, INSERT OR IGNORE, INSERT OR ROLLBACK,
-** and INSERT OR ABORT make no changes to the return value of this
-** routine when their insertion fails. When INSERT OR REPLACE
-** encounters a constraint violation, it does not fail. The
-** INSERT continues to completion after deleting rows that caused
-** the constraint problem so INSERT OR REPLACE will always change
-** the return value of this interface.
-**
-** For the purposes of this routine, an [INSERT] is considered to
-** be successful even if it is subsequently rolled back.
-**
-** Requirements:
-** [H12221] [H12223]
-**
-** If a separate thread performs a new [INSERT] on the same
-** database connection while the [sqlite3_last_insert_rowid()]
-** function is running and thus changes the last insert [rowid],
-** then the value returned by [sqlite3_last_insert_rowid()] is
-** unpredictable and might not equal either the old or the new
-** last insert [rowid].
-*/
-SQLITE_API sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*);
-
-/*
-** CAPI3REF: Count The Number Of Rows Modified {H12240} <S10600>
-**
-** This function returns the number of database rows that were changed
-** or inserted or deleted by the most recently completed SQL statement
-** on the [database connection] specified by the first parameter.
-** Only changes that are directly specified by the [INSERT], [UPDATE],
-** or [DELETE] statement are counted. Auxiliary changes caused by
-** triggers are not counted. Use the [sqlite3_total_changes()] function
-** to find the total number of changes including changes caused by triggers.
-**
-** Changes to a view that are simulated by an [INSTEAD OF trigger]
-** are not counted. Only real table changes are counted.
-**
-** A "row change" is a change to a single row of a single table
-** caused by an INSERT, DELETE, or UPDATE statement. Rows that
-** are changed as side effects of [REPLACE] constraint resolution,
-** rollback, ABORT processing, [DROP TABLE], or by any other
-** mechanisms do not count as direct row changes.
-**
-** A "trigger context" is a scope of execution that begins and
-** ends with the script of a [CREATE TRIGGER | trigger].
-** Most SQL statements are
-** evaluated outside of any trigger. This is the "top level"
-** trigger context. If a trigger fires from the top level, a
-** new trigger context is entered for the duration of that one
-** trigger. Subtriggers create subcontexts for their duration.
-**
-** Calling [sqlite3_exec()] or [sqlite3_step()] recursively does
-** not create a new trigger context.
-**
-** This function returns the number of direct row changes in the
-** most recent INSERT, UPDATE, or DELETE statement within the same
-** trigger context.
-**
-** Thus, when called from the top level, this function returns the
-** number of changes in the most recent INSERT, UPDATE, or DELETE
-** that also occurred at the top level. Within the body of a trigger,
-** the sqlite3_changes() interface can be called to find the number of
-** changes in the most recently completed INSERT, UPDATE, or DELETE
-** statement within the body of the same trigger.
-** However, the number returned does not include changes
-** caused by subtriggers since those have their own context.
-**
-** See also the [sqlite3_total_changes()] interface and the
-** [count_changes pragma].
-**
-** Requirements:
-** [H12241] [H12243]
-**
-** If a separate thread makes changes on the same database connection
-** while [sqlite3_changes()] is running then the value returned
-** is unpredictable and not meaningful.
-*/
-SQLITE_API int sqlite3_changes(sqlite3*);
-
-/*
-** CAPI3REF: Total Number Of Rows Modified {H12260} <S10600>
-**
-** This function returns the number of row changes caused by [INSERT],
-** [UPDATE] or [DELETE] statements since the [database connection] was opened.
-** The count includes all changes from all
-** [CREATE TRIGGER | trigger] contexts. However,
-** the count does not include changes used to implement [REPLACE] constraints,
-** do rollbacks or ABORT processing, or [DROP TABLE] processing. The
-** count does not include rows of views that fire an [INSTEAD OF trigger],
-** though if the INSTEAD OF trigger makes changes of its own, those changes
-** are counted.
-** The changes are counted as soon as the statement that makes them is
-** completed (when the statement handle is passed to [sqlite3_reset()] or
-** [sqlite3_finalize()]).
-**
-** See also the [sqlite3_changes()] interface and the
-** [count_changes pragma].
-**
-** Requirements:
-** [H12261] [H12263]
-**
-** If a separate thread makes changes on the same database connection
-** while [sqlite3_total_changes()] is running then the value
-** returned is unpredictable and not meaningful.
-*/
-SQLITE_API int sqlite3_total_changes(sqlite3*);
-
-/*
-** CAPI3REF: Interrupt A Long-Running Query {H12270} <S30500>
-**
-** This function causes any pending database operation to abort and
-** return at its earliest opportunity. This routine is typically
-** called in response to a user action such as pressing "Cancel"
-** or Ctrl-C where the user wants a long query operation to halt
-** immediately.
-**
-** It is safe to call this routine from a thread different from the
-** thread that is currently running the database operation. But it
-** is not safe to call this routine with a [database connection] that
-** is closed or might close before sqlite3_interrupt() returns.
-**
-** If an SQL operation is very nearly finished at the time when
-** sqlite3_interrupt() is called, then it might not have an opportunity
-** to be interrupted and might continue to completion.
-**
-** An SQL operation that is interrupted will return [SQLITE_INTERRUPT].
-** If the interrupted SQL operation is an INSERT, UPDATE, or DELETE
-** that is inside an explicit transaction, then the entire transaction
-** will be rolled back automatically.
-**
-** The sqlite3_interrupt(D) call is in effect until all currently running
-** SQL statements on [database connection] D complete. Any new SQL statements
-** that are started after the sqlite3_interrupt() call and before the
-** running statements reaches zero are interrupted as if they had been
-** running prior to the sqlite3_interrupt() call. New SQL statements
-** that are started after the running statement count reaches zero are
-** not effected by the sqlite3_interrupt().
-** A call to sqlite3_interrupt(D) that occurs when there are no running
-** SQL statements is a no-op and has no effect on SQL statements
-** that are started after the sqlite3_interrupt() call returns.
-**
-** Requirements:
-** [H12271] [H12272]
-**
-** If the database connection closes while [sqlite3_interrupt()]
-** is running then bad things will likely happen.
-*/
-SQLITE_API void sqlite3_interrupt(sqlite3*);
-
-/*
-** CAPI3REF: Determine If An SQL Statement Is Complete {H10510} <S70200>
-**
-** These routines are useful during command-line input to determine if the
-** currently entered text seems to form a complete SQL statement or
-** if additional input is needed before sending the text into
-** SQLite for parsing. These routines return 1 if the input string
-** appears to be a complete SQL statement. A statement is judged to be
-** complete if it ends with a semicolon token and is not a prefix of a
-** well-formed CREATE TRIGGER statement. Semicolons that are embedded within
-** string literals or quoted identifier names or comments are not
-** independent tokens (they are part of the token in which they are
-** embedded) and thus do not count as a statement terminator. Whitespace
-** and comments that follow the final semicolon are ignored.
-**
-** These routines return 0 if the statement is incomplete. If a
-** memory allocation fails, then SQLITE_NOMEM is returned.
-**
-** These routines do not parse the SQL statements thus
-** will not detect syntactically incorrect SQL.
-**
-** If SQLite has not been initialized using [sqlite3_initialize()] prior
-** to invoking sqlite3_complete16() then sqlite3_initialize() is invoked
-** automatically by sqlite3_complete16(). If that initialization fails,
-** then the return value from sqlite3_complete16() will be non-zero
-** regardless of whether or not the input SQL is complete.
-**
-** Requirements: [H10511] [H10512]
-**
-** The input to [sqlite3_complete()] must be a zero-terminated
-** UTF-8 string.
-**
-** The input to [sqlite3_complete16()] must be a zero-terminated
-** UTF-16 string in native byte order.
-*/
-SQLITE_API int sqlite3_complete(const char *sql);
-SQLITE_API int sqlite3_complete16(const void *sql);
-
-/*
-** CAPI3REF: Register A Callback To Handle SQLITE_BUSY Errors {H12310} <S40400>
-**
-** This routine sets a callback function that might be invoked whenever
-** an attempt is made to open a database table that another thread
-** or process has locked.
-**
-** If the busy callback is NULL, then [SQLITE_BUSY] or [SQLITE_IOERR_BLOCKED]
-** is returned immediately upon encountering the lock. If the busy callback
-** is not NULL, then the callback will be invoked with two arguments.
-**
-** The first argument to the handler is a copy of the void* pointer which
-** is the third argument to sqlite3_busy_handler(). The second argument to
-** the handler callback is the number of times that the busy handler has
-** been invoked for this locking event. If the
-** busy callback returns 0, then no additional attempts are made to
-** access the database and [SQLITE_BUSY] or [SQLITE_IOERR_BLOCKED] is returned.
-** If the callback returns non-zero, then another attempt
-** is made to open the database for reading and the cycle repeats.
-**
-** The presence of a busy handler does not guarantee that it will be invoked
-** when there is lock contention. If SQLite determines that invoking the busy
-** handler could result in a deadlock, it will go ahead and return [SQLITE_BUSY]
-** or [SQLITE_IOERR_BLOCKED] instead of invoking the busy handler.
-** Consider a scenario where one process is holding a read lock that
-** it is trying to promote to a reserved lock and
-** a second process is holding a reserved lock that it is trying
-** to promote to an exclusive lock. The first process cannot proceed
-** because it is blocked by the second and the second process cannot
-** proceed because it is blocked by the first. If both processes
-** invoke the busy handlers, neither will make any progress. Therefore,
-** SQLite returns [SQLITE_BUSY] for the first process, hoping that this
-** will induce the first process to release its read lock and allow
-** the second process to proceed.
-**
-** The default busy callback is NULL.
-**
-** The [SQLITE_BUSY] error is converted to [SQLITE_IOERR_BLOCKED]
-** when SQLite is in the middle of a large transaction where all the
-** changes will not fit into the in-memory cache. SQLite will
-** already hold a RESERVED lock on the database file, but it needs
-** to promote this lock to EXCLUSIVE so that it can spill cache
-** pages into the database file without harm to concurrent
-** readers. If it is unable to promote the lock, then the in-memory
-** cache will be left in an inconsistent state and so the error
-** code is promoted from the relatively benign [SQLITE_BUSY] to
-** the more severe [SQLITE_IOERR_BLOCKED]. This error code promotion
-** forces an automatic rollback of the changes. See the
-** <a href="/cvstrac/wiki?p=CorruptionFollowingBusyError">
-** CorruptionFollowingBusyError</a> wiki page for a discussion of why
-** this is important.
-**
-** There can only be a single busy handler defined for each
-** [database connection]. Setting a new busy handler clears any
-** previously set handler. Note that calling [sqlite3_busy_timeout()]
-** will also set or clear the busy handler.
-**
-** The busy callback should not take any actions which modify the
-** database connection that invoked the busy handler. Any such actions
-** result in undefined behavior.
-**
-** Requirements:
-** [H12311] [H12312] [H12314] [H12316] [H12318]
-**
-** A busy handler must not close the database connection
-** or [prepared statement] that invoked the busy handler.
-*/
-SQLITE_API int sqlite3_busy_handler(sqlite3*, int(*)(void*,int), void*);
-
-/*
-** CAPI3REF: Set A Busy Timeout {H12340} <S40410>
-**
-** This routine sets a [sqlite3_busy_handler | busy handler] that sleeps
-** for a specified amount of time when a table is locked. The handler
-** will sleep multiple times until at least "ms" milliseconds of sleeping
-** have accumulated. {H12343} After "ms" milliseconds of sleeping,
-** the handler returns 0 which causes [sqlite3_step()] to return
-** [SQLITE_BUSY] or [SQLITE_IOERR_BLOCKED].
-**
-** Calling this routine with an argument less than or equal to zero
-** turns off all busy handlers.
-**
-** There can only be a single busy handler for a particular
-** [database connection] any any given moment. If another busy handler
-** was defined (using [sqlite3_busy_handler()]) prior to calling
-** this routine, that other busy handler is cleared.
-**
-** Requirements:
-** [H12341] [H12343] [H12344]
-*/
-SQLITE_API int sqlite3_busy_timeout(sqlite3*, int ms);
-
-/*
-** CAPI3REF: Convenience Routines For Running Queries {H12370} <S10000>
-**
-** Definition: A <b>result table</b> is memory data structure created by the
-** [sqlite3_get_table()] interface. A result table records the
-** complete query results from one or more queries.
-**
-** The table conceptually has a number of rows and columns. But
-** these numbers are not part of the result table itself. These
-** numbers are obtained separately. Let N be the number of rows
-** and M be the number of columns.
-**
-** A result table is an array of pointers to zero-terminated UTF-8 strings.
-** There are (N+1)*M elements in the array. The first M pointers point
-** to zero-terminated strings that contain the names of the columns.
-** The remaining entries all point to query results. NULL values result
-** in NULL pointers. All other values are in their UTF-8 zero-terminated
-** string representation as returned by [sqlite3_column_text()].
-**
-** A result table might consist of one or more memory allocations.
-** It is not safe to pass a result table directly to [sqlite3_free()].
-** A result table should be deallocated using [sqlite3_free_table()].
-**
-** As an example of the result table format, suppose a query result
-** is as follows:
-**
-** <blockquote><pre>
-** Name | Age
-** -----------------------
-** Alice | 43
-** Bob | 28
-** Cindy | 21
-** </pre></blockquote>
-**
-** There are two column (M==2) and three rows (N==3). Thus the
-** result table has 8 entries. Suppose the result table is stored
-** in an array names azResult. Then azResult holds this content:
-**
-** <blockquote><pre>
-** azResult&#91;0] = "Name";
-** azResult&#91;1] = "Age";
-** azResult&#91;2] = "Alice";
-** azResult&#91;3] = "43";
-** azResult&#91;4] = "Bob";
-** azResult&#91;5] = "28";
-** azResult&#91;6] = "Cindy";
-** azResult&#91;7] = "21";
-** </pre></blockquote>
-**
-** The sqlite3_get_table() function evaluates one or more
-** semicolon-separated SQL statements in the zero-terminated UTF-8
-** string of its 2nd parameter. It returns a result table to the
-** pointer given in its 3rd parameter.
-**
-** After the calling function has finished using the result, it should
-** pass the pointer to the result table to sqlite3_free_table() in order to
-** release the memory that was malloced. Because of the way the
-** [sqlite3_malloc()] happens within sqlite3_get_table(), the calling
-** function must not try to call [sqlite3_free()] directly. Only
-** [sqlite3_free_table()] is able to release the memory properly and safely.
-**
-** The sqlite3_get_table() interface is implemented as a wrapper around
-** [sqlite3_exec()]. The sqlite3_get_table() routine does not have access
-** to any internal data structures of SQLite. It uses only the public
-** interface defined here. As a consequence, errors that occur in the
-** wrapper layer outside of the internal [sqlite3_exec()] call are not
-** reflected in subsequent calls to [sqlite3_errcode()] or [sqlite3_errmsg()].
-**
-** Requirements:
-** [H12371] [H12373] [H12374] [H12376] [H12379] [H12382]
-*/
-SQLITE_API int sqlite3_get_table(
- sqlite3 *db, /* An open database */
- const char *zSql, /* SQL to be evaluated */
- char ***pazResult, /* Results of the query */
- int *pnRow, /* Number of result rows written here */
- int *pnColumn, /* Number of result columns written here */
- char **pzErrmsg /* Error msg written here */
-);
-SQLITE_API void sqlite3_free_table(char **result);
-
-/*
-** CAPI3REF: Formatted String Printing Functions {H17400} <S70000><S20000>
-**
-** These routines are work-alikes of the "printf()" family of functions
-** from the standard C library.
-**
-** The sqlite3_mprintf() and sqlite3_vmprintf() routines write their
-** results into memory obtained from [sqlite3_malloc()].
-** The strings returned by these two routines should be
-** released by [sqlite3_free()]. Both routines return a
-** NULL pointer if [sqlite3_malloc()] is unable to allocate enough
-** memory to hold the resulting string.
-**
-** In sqlite3_snprintf() routine is similar to "snprintf()" from
-** the standard C library. The result is written into the
-** buffer supplied as the second parameter whose size is given by
-** the first parameter. Note that the order of the
-** first two parameters is reversed from snprintf(). This is an
-** historical accident that cannot be fixed without breaking
-** backwards compatibility. Note also that sqlite3_snprintf()
-** returns a pointer to its buffer instead of the number of
-** characters actually written into the buffer. We admit that
-** the number of characters written would be a more useful return
-** value but we cannot change the implementation of sqlite3_snprintf()
-** now without breaking compatibility.
-**
-** As long as the buffer size is greater than zero, sqlite3_snprintf()
-** guarantees that the buffer is always zero-terminated. The first
-** parameter "n" is the total size of the buffer, including space for
-** the zero terminator. So the longest string that can be completely
-** written will be n-1 characters.
-**
-** These routines all implement some additional formatting
-** options that are useful for constructing SQL statements.
-** 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
-** 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
-** the string.
-**
-** For example, assume the string variable zText contains text as follows:
-**
-** <blockquote><pre>
-** char *zText = "It's a happy day!";
-** </pre></blockquote>
-**
-** One can use this text in an SQL statement as follows:
-**
-** <blockquote><pre>
-** char *zSQL = sqlite3_mprintf("INSERT INTO table VALUES('%q')", zText);
-** sqlite3_exec(db, zSQL, 0, 0, 0);
-** sqlite3_free(zSQL);
-** </pre></blockquote>
-**
-** Because the %q format string is used, the '\'' character in zText
-** is escaped and the SQL generated is as follows:
-**
-** <blockquote><pre>
-** INSERT INTO table1 VALUES('It''s a happy day!')
-** </pre></blockquote>
-**
-** This is correct. Had we used %s instead of %q, the generated SQL
-** would have looked like this:
-**
-** <blockquote><pre>
-** INSERT INTO table1 VALUES('It's a happy day!');
-** </pre></blockquote>
-**
-** This second example is an SQL syntax error. As a general rule you should
-** always use %q instead of %s when inserting text into a string literal.
-**
-** The %Q option works like %q except it also adds single quotes around
-** the outside of the total string. Additionally, if the parameter in the
-** argument list is a NULL pointer, %Q substitutes the text "NULL" (without
-** single quotes) in place of the %Q option. So, for example, one could say:
-**
-** <blockquote><pre>
-** char *zSQL = sqlite3_mprintf("INSERT INTO table VALUES(%Q)", zText);
-** sqlite3_exec(db, zSQL, 0, 0, 0);
-** sqlite3_free(zSQL);
-** </pre></blockquote>
-**
-** The code above will render a correct SQL statement in the zSQL
-** variable even if the zText variable is a NULL pointer.
-**
-** The "%z" formatting option works exactly like "%s" with the
-** addition that after the string has been read and copied into
-** the result, [sqlite3_free()] is called on the input string. {END}
-**
-** Requirements:
-** [H17403] [H17406] [H17407]
-*/
-SQLITE_API char *sqlite3_mprintf(const char*,...);
-SQLITE_API char *sqlite3_vmprintf(const char*, va_list);
-SQLITE_API char *sqlite3_snprintf(int,char*,const char*, ...);
-
-/*
-** CAPI3REF: Memory Allocation Subsystem {H17300} <S20000>
-**
-** The SQLite core uses these three routines for all of its own
-** internal memory allocation needs. "Core" in the previous sentence
-** does not include operating-system specific VFS implementation. The
-** Windows VFS uses native malloc() and free() for some operations.
-**
-** The sqlite3_malloc() routine returns a pointer to a block
-** of memory at least N bytes in length, where N is the parameter.
-** If sqlite3_malloc() is unable to obtain sufficient free
-** memory, it returns a NULL pointer. If the parameter N to
-** sqlite3_malloc() is zero or negative then sqlite3_malloc() returns
-** a NULL pointer.
-**
-** Calling sqlite3_free() with a pointer previously returned
-** by sqlite3_malloc() or sqlite3_realloc() releases that memory so
-** that it might be reused. The sqlite3_free() routine is
-** a no-op if is called with a NULL pointer. Passing a NULL pointer
-** to sqlite3_free() is harmless. After being freed, memory
-** should neither be read nor written. Even reading previously freed
-** memory might result in a segmentation fault or other severe error.
-** Memory corruption, a segmentation fault, or other severe error
-** might result if sqlite3_free() is called with a non-NULL pointer that
-** was not obtained from sqlite3_malloc() or sqlite3_realloc().
-**
-** The sqlite3_realloc() interface attempts to resize a
-** prior memory allocation to be at least N bytes, where N is the
-** second parameter. The memory allocation to be resized is the first
-** parameter. If the first parameter to sqlite3_realloc()
-** is a NULL pointer then its behavior is identical to calling
-** sqlite3_malloc(N) where N is the second parameter to sqlite3_realloc().
-** If the second parameter to sqlite3_realloc() is zero or
-** negative then the behavior is exactly the same as calling
-** sqlite3_free(P) where P is the first parameter to sqlite3_realloc().
-** sqlite3_realloc() returns a pointer to a memory allocation
-** of at least N bytes in size or NULL if sufficient memory is unavailable.
-** If M is the size of the prior allocation, then min(N,M) bytes
-** of the prior allocation are copied into the beginning of buffer returned
-** by sqlite3_realloc() and the prior allocation is freed.
-** If sqlite3_realloc() returns NULL, then the prior allocation
-** is not freed.
-**
-** The memory returned by sqlite3_malloc() and sqlite3_realloc()
-** is always aligned to at least an 8 byte boundary. {END}
-**
-** The default implementation of the memory allocation subsystem uses
-** the malloc(), realloc() and free() provided by the standard C library.
-** {H17382} However, if SQLite is compiled with the
-** SQLITE_MEMORY_SIZE=<i>NNN</i> C preprocessor macro (where <i>NNN</i>
-** is an integer), then SQLite create a static array of at least
-** <i>NNN</i> bytes in size and uses that array for all of its dynamic
-** memory allocation needs. {END} Additional memory allocator options
-** may be added in future releases.
-**
-** In SQLite version 3.5.0 and 3.5.1, it was possible to define
-** the SQLITE_OMIT_MEMORY_ALLOCATION which would cause the built-in
-** implementation of these routines to be omitted. That capability
-** is no longer provided. Only built-in memory allocators can be used.
-**
-** The Windows OS interface layer calls
-** the system malloc() and free() directly when converting
-** filenames between the UTF-8 encoding used by SQLite
-** and whatever filename encoding is used by the particular Windows
-** installation. Memory allocation errors are detected, but
-** they are reported back as [SQLITE_CANTOPEN] or
-** [SQLITE_IOERR] rather than [SQLITE_NOMEM].
-**
-** Requirements:
-** [H17303] [H17304] [H17305] [H17306] [H17310] [H17312] [H17315] [H17318]
-** [H17321] [H17322] [H17323]
-**
-** The pointer arguments to [sqlite3_free()] and [sqlite3_realloc()]
-** must be either NULL or else pointers obtained from a prior
-** invocation of [sqlite3_malloc()] or [sqlite3_realloc()] that have
-** not yet been released.
-**
-** The application must not read or write any part of
-** a block of memory after it has been released using
-** [sqlite3_free()] or [sqlite3_realloc()].
-*/
-SQLITE_API void *sqlite3_malloc(int);
-SQLITE_API void *sqlite3_realloc(void*, int);
-SQLITE_API void sqlite3_free(void*);
-
-/*
-** CAPI3REF: Memory Allocator Statistics {H17370} <S30210>
-**
-** SQLite provides these two interfaces for reporting on the status
-** of the [sqlite3_malloc()], [sqlite3_free()], and [sqlite3_realloc()]
-** routines, which form the built-in memory allocation subsystem.
-**
-** Requirements:
-** [H17371] [H17373] [H17374] [H17375]
-*/
-SQLITE_API sqlite3_int64 sqlite3_memory_used(void);
-SQLITE_API sqlite3_int64 sqlite3_memory_highwater(int resetFlag);
-
-/*
-** CAPI3REF: Pseudo-Random Number Generator {H17390} <S20000>
-**
-** SQLite contains a high-quality pseudo-random number generator (PRNG) used to
-** select random [ROWID | ROWIDs] when inserting new records into a table that
-** already uses the largest possible [ROWID]. The PRNG is also used for
-** the build-in random() and randomblob() SQL functions. This interface allows
-** applications to access the same PRNG for other purposes.
-**
-** A call to this routine stores N bytes of randomness into buffer P.
-**
-** The first time this routine is invoked (either internally or by
-** the application) the PRNG is seeded using randomness obtained
-** from the xRandomness method of the default [sqlite3_vfs] object.
-** On all subsequent invocations, the pseudo-randomness is generated
-** internally and without recourse to the [sqlite3_vfs] xRandomness
-** method.
-**
-** Requirements:
-** [H17392]
-*/
-SQLITE_API void sqlite3_randomness(int N, void *P);
-
-/*
-** CAPI3REF: Compile-Time Authorization Callbacks {H12500} <S70100>
-**
-** This routine registers a authorizer callback with a particular
-** [database connection], supplied in the first argument.
-** The authorizer callback is invoked as SQL statements are being compiled
-** by [sqlite3_prepare()] or its variants [sqlite3_prepare_v2()],
-** [sqlite3_prepare16()] and [sqlite3_prepare16_v2()]. At various
-** points during the compilation process, as logic is being created
-** to perform various actions, the authorizer callback is invoked to
-** see if those actions are allowed. The authorizer callback should
-** return [SQLITE_OK] to allow the action, [SQLITE_IGNORE] to disallow the
-** specific action but allow the SQL statement to continue to be
-** compiled, or [SQLITE_DENY] to cause the entire SQL statement to be
-** rejected with an error. If the authorizer callback returns
-** any value other than [SQLITE_IGNORE], [SQLITE_OK], or [SQLITE_DENY]
-** then the [sqlite3_prepare_v2()] or equivalent call that triggered
-** the authorizer will fail with an error message.
-**
-** When the callback returns [SQLITE_OK], that means the operation
-** requested is ok. When the callback returns [SQLITE_DENY], the
-** [sqlite3_prepare_v2()] or equivalent call that triggered the
-** authorizer will fail with an error message explaining that
-** access is denied.
-**
-** The first parameter to the authorizer callback is a copy of the third
-** parameter to the sqlite3_set_authorizer() interface. The second parameter
-** to the callback is an integer [SQLITE_COPY | action code] that specifies
-** the particular action to be authorized. The third through sixth parameters
-** to the callback are zero-terminated strings that contain additional
-** details about the action to be authorized.
-**
-** If the action code is [SQLITE_READ]
-** and the callback returns [SQLITE_IGNORE] then the
-** [prepared statement] statement is constructed to substitute
-** a NULL value in place of the table column that would have
-** been read if [SQLITE_OK] had been returned. The [SQLITE_IGNORE]
-** return can be used to deny an untrusted user access to individual
-** columns of a table.
-** If the action code is [SQLITE_DELETE] and the callback returns
-** [SQLITE_IGNORE] then the [DELETE] operation proceeds but the
-** [truncate optimization] is disabled and all rows are deleted individually.
-**
-** An authorizer is used when [sqlite3_prepare | preparing]
-** SQL statements from an untrusted source, to ensure that the SQL statements
-** do not try to access data they are not allowed to see, or that they do not
-** try to execute malicious statements that damage the database. For
-** example, an application may allow a user to enter arbitrary
-** SQL queries for evaluation by a database. But the application does
-** not want the user to be able to make arbitrary changes to the
-** database. An authorizer could then be put in place while the
-** user-entered SQL is being [sqlite3_prepare | prepared] that
-** disallows everything except [SELECT] statements.
-**
-** Applications that need to process SQL from untrusted sources
-** might also consider lowering resource limits using [sqlite3_limit()]
-** and limiting database size using the [max_page_count] [PRAGMA]
-** in addition to using an authorizer.
-**
-** Only a single authorizer can be in place on a database connection
-** at a time. Each call to sqlite3_set_authorizer overrides the
-** previous call. Disable the authorizer by installing a NULL callback.
-** The authorizer is disabled by default.
-**
-** The authorizer callback must not do anything that will modify
-** the database connection that invoked the authorizer callback.
-** Note that [sqlite3_prepare_v2()] and [sqlite3_step()] both modify their
-** database connections for the meaning of "modify" in this paragraph.
-**
-** When [sqlite3_prepare_v2()] is used to prepare a statement, the
-** statement might be re-prepared during [sqlite3_step()] due to a
-** schema change. Hence, the application should ensure that the
-** correct authorizer callback remains in place during the [sqlite3_step()].
-**
-** Note that the authorizer callback is invoked only during
-** [sqlite3_prepare()] or its variants. Authorization is not
-** performed during statement evaluation in [sqlite3_step()], unless
-** as stated in the previous paragraph, sqlite3_step() invokes
-** sqlite3_prepare_v2() to reprepare a statement after a schema change.
-**
-** Requirements:
-** [H12501] [H12502] [H12503] [H12504] [H12505] [H12506] [H12507] [H12510]
-** [H12511] [H12512] [H12520] [H12521] [H12522]
-*/
-SQLITE_API int sqlite3_set_authorizer(
- sqlite3*,
- int (*xAuth)(void*,int,const char*,const char*,const char*,const char*),
- void *pUserData
-);
-
-/*
-** CAPI3REF: Authorizer Return Codes {H12590} <H12500>
-**
-** The [sqlite3_set_authorizer | authorizer callback function] must
-** return either [SQLITE_OK] or one of these two constants in order
-** to signal SQLite whether or not the action is permitted. See the
-** [sqlite3_set_authorizer | authorizer documentation] for additional
-** information.
-*/
-#define SQLITE_DENY 1 /* Abort the SQL statement with an error */
-#define SQLITE_IGNORE 2 /* Don't allow access, but don't generate an error */
-
-/*
-** CAPI3REF: Authorizer Action Codes {H12550} <H12500>
-**
-** The [sqlite3_set_authorizer()] interface registers a callback function
-** that is invoked to authorize certain SQL statement actions. The
-** second parameter to the callback is an integer code that specifies
-** what action is being authorized. These are the integer action codes that
-** the authorizer callback may be passed.
-**
-** These action code values signify what kind of operation is to be
-** authorized. The 3rd and 4th parameters to the authorization
-** callback function will be parameters or NULL depending on which of these
-** codes is used as the second parameter. The 5th parameter to the
-** authorizer callback is the name of the database ("main", "temp",
-** etc.) if applicable. The 6th parameter to the authorizer callback
-** is the name of the inner-most trigger or view that is responsible for
-** the access attempt or NULL if this access attempt is directly from
-** top-level SQL code.
-**
-** Requirements:
-** [H12551] [H12552] [H12553] [H12554]
-*/
-/******************************************* 3rd ************ 4th ***********/
-#define SQLITE_CREATE_INDEX 1 /* Index Name Table Name */
-#define SQLITE_CREATE_TABLE 2 /* Table Name NULL */
-#define SQLITE_CREATE_TEMP_INDEX 3 /* Index Name Table Name */
-#define SQLITE_CREATE_TEMP_TABLE 4 /* Table Name NULL */
-#define SQLITE_CREATE_TEMP_TRIGGER 5 /* Trigger Name Table Name */
-#define SQLITE_CREATE_TEMP_VIEW 6 /* View Name NULL */
-#define SQLITE_CREATE_TRIGGER 7 /* Trigger Name Table Name */
-#define SQLITE_CREATE_VIEW 8 /* View Name NULL */
-#define SQLITE_DELETE 9 /* Table Name NULL */
-#define SQLITE_DROP_INDEX 10 /* Index Name Table Name */
-#define SQLITE_DROP_TABLE 11 /* Table Name NULL */
-#define SQLITE_DROP_TEMP_INDEX 12 /* Index Name Table Name */
-#define SQLITE_DROP_TEMP_TABLE 13 /* Table Name NULL */
-#define SQLITE_DROP_TEMP_TRIGGER 14 /* Trigger Name Table Name */
-#define SQLITE_DROP_TEMP_VIEW 15 /* View Name NULL */
-#define SQLITE_DROP_TRIGGER 16 /* Trigger Name Table Name */
-#define SQLITE_DROP_VIEW 17 /* View Name NULL */
-#define SQLITE_INSERT 18 /* Table Name NULL */
-#define SQLITE_PRAGMA 19 /* Pragma Name 1st arg or NULL */
-#define SQLITE_READ 20 /* Table Name Column Name */
-#define SQLITE_SELECT 21 /* NULL NULL */
-#define SQLITE_TRANSACTION 22 /* Operation NULL */
-#define SQLITE_UPDATE 23 /* Table Name Column Name */
-#define SQLITE_ATTACH 24 /* Filename NULL */
-#define SQLITE_DETACH 25 /* Database Name NULL */
-#define SQLITE_ALTER_TABLE 26 /* Database Name Table Name */
-#define SQLITE_REINDEX 27 /* Index Name NULL */
-#define SQLITE_ANALYZE 28 /* Table Name NULL */
-#define SQLITE_CREATE_VTABLE 29 /* Table Name Module Name */
-#define SQLITE_DROP_VTABLE 30 /* Table Name Module Name */
-#define SQLITE_FUNCTION 31 /* NULL Function Name */
-#define SQLITE_SAVEPOINT 32 /* Operation Savepoint Name */
-#define SQLITE_COPY 0 /* No longer used */
-
-/*
-** CAPI3REF: Tracing And Profiling Functions {H12280} <S60400>
-** EXPERIMENTAL
-**
-** These routines register callback functions that can be used for
-** tracing and profiling the execution of SQL statements.
-**
-** The callback function registered by sqlite3_trace() is invoked at
-** various times when an SQL statement is being run by [sqlite3_step()].
-** The callback returns a UTF-8 rendering of the SQL statement text
-** as the statement first begins executing. Additional callbacks occur
-** as each triggered subprogram is entered. The callbacks for triggers
-** contain a UTF-8 SQL comment that identifies the trigger.
-**
-** The callback function registered by sqlite3_profile() is invoked
-** as each SQL statement finishes. The profile callback contains
-** the original statement text and an estimate of wall-clock time
-** of how long that statement took to run.
-**
-** Requirements:
-** [H12281] [H12282] [H12283] [H12284] [H12285] [H12287] [H12288] [H12289]
-** [H12290]
-*/
-SQLITE_API SQLITE_EXPERIMENTAL void *sqlite3_trace(sqlite3*, void(*xTrace)(void*,const char*), void*);
-SQLITE_API SQLITE_EXPERIMENTAL void *sqlite3_profile(sqlite3*,
- void(*xProfile)(void*,const char*,sqlite3_uint64), void*);
-
-/*
-** CAPI3REF: Query Progress Callbacks {H12910} <S60400>
-**
-** This routine configures a callback function - the
-** progress callback - that is invoked periodically during long
-** running calls to [sqlite3_exec()], [sqlite3_step()] and
-** [sqlite3_get_table()]. An example use for this
-** interface is to keep a GUI updated during a large query.
-**
-** If the progress callback returns non-zero, the operation is
-** interrupted. This feature can be used to implement a
-** "Cancel" button on a GUI progress dialog box.
-**
-** The progress handler must not do anything that will modify
-** the database connection that invoked the progress handler.
-** Note that [sqlite3_prepare_v2()] and [sqlite3_step()] both modify their
-** database connections for the meaning of "modify" in this paragraph.
-**
-** Requirements:
-** [H12911] [H12912] [H12913] [H12914] [H12915] [H12916] [H12917] [H12918]
-**
-*/
-SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
-
-/*
-** CAPI3REF: Opening A New Database Connection {H12700} <S40200>
-**
-** These routines open an SQLite database file whose name is given by the
-** filename argument. The filename argument is interpreted as UTF-8 for
-** sqlite3_open() and sqlite3_open_v2() and as UTF-16 in the native byte
-** order for sqlite3_open16(). A [database connection] handle is usually
-** returned in *ppDb, even if an error occurs. The only exception is that
-** if SQLite is unable to allocate memory to hold the [sqlite3] object,
-** a NULL will be written into *ppDb instead of a pointer to the [sqlite3]
-** object. If the database is opened (and/or created) successfully, then
-** [SQLITE_OK] is returned. Otherwise an [error code] is returned. The
-** [sqlite3_errmsg()] or [sqlite3_errmsg16()] routines can be used to obtain
-** an English language description of the error.
-**
-** The default encoding for the database will be UTF-8 if
-** sqlite3_open() or sqlite3_open_v2() is called and
-** UTF-16 in the native byte order if sqlite3_open16() is used.
-**
-** Whether or not an error occurs when it is opened, resources
-** associated with the [database connection] handle should be released by
-** passing it to [sqlite3_close()] when it is no longer required.
-**
-** The sqlite3_open_v2() interface works like sqlite3_open()
-** except that it accepts two additional parameters for additional control
-** over the new database connection. The flags parameter can take one of
-** the following three values, optionally combined with the
-** [SQLITE_OPEN_NOMUTEX], [SQLITE_OPEN_FULLMUTEX], [SQLITE_OPEN_SHAREDCACHE],
-** and/or [SQLITE_OPEN_PRIVATECACHE] flags:
-**
-** <dl>
-** <dt>[SQLITE_OPEN_READONLY]</dt>
-** <dd>The database is opened in read-only mode. If the database does not
-** already exist, an error is returned.</dd>
-**
-** <dt>[SQLITE_OPEN_READWRITE]</dt>
-** <dd>The database is opened for reading and writing if possible, or reading
-** only if the file is write protected by the operating system. In either
-** case the database must already exist, otherwise an error is returned.</dd>
-**
-** <dt>[SQLITE_OPEN_READWRITE] | [SQLITE_OPEN_CREATE]</dt>
-** <dd>The database is opened for reading and writing, and is creates it if
-** it does not already exist. This is the behavior that is always used for
-** sqlite3_open() and sqlite3_open16().</dd>
-** </dl>
-**
-** If the 3rd parameter to sqlite3_open_v2() is not one of the
-** combinations shown above or one of the combinations shown above combined
-** with the [SQLITE_OPEN_NOMUTEX], [SQLITE_OPEN_FULLMUTEX],
-** [SQLITE_OPEN_SHAREDCACHE] and/or [SQLITE_OPEN_SHAREDCACHE] flags,
-** then the behavior is undefined.
-**
-** If the [SQLITE_OPEN_NOMUTEX] flag is set, then the database connection
-** opens in the multi-thread [threading mode] as long as the single-thread
-** mode has not been set at compile-time or start-time. If the
-** [SQLITE_OPEN_FULLMUTEX] flag is set then the database connection opens
-** in the serialized [threading mode] unless single-thread was
-** previously selected at compile-time or start-time.
-** The [SQLITE_OPEN_SHAREDCACHE] flag causes the database connection to be
-** eligible to use [shared cache mode], regardless of whether or not shared
-** cache is enabled using [sqlite3_enable_shared_cache()]. The
-** [SQLITE_OPEN_PRIVATECACHE] flag causes the database connection to not
-** participate in [shared cache mode] even if it is enabled.
-**
-** If the filename is ":memory:", then a private, temporary in-memory database
-** is created for the connection. This in-memory database will vanish when
-** the database connection is closed. Future versions of SQLite might
-** make use of additional special filenames that begin with the ":" character.
-** It is recommended that when a database filename actually does begin with
-** a ":" character you should prefix the filename with a pathname such as
-** "./" to avoid ambiguity.
-**
-** If the filename is an empty string, then a private, temporary
-** on-disk database will be created. This private database will be
-** automatically deleted as soon as the database connection is closed.
-**
-** The fourth parameter to sqlite3_open_v2() is the name of the
-** [sqlite3_vfs] object that defines the operating system interface that
-** the new database connection should use. If the fourth parameter is
-** a NULL pointer then the default [sqlite3_vfs] object is used.
-**
-** <b>Note to Windows users:</b> The encoding used for the filename argument
-** of sqlite3_open() and sqlite3_open_v2() must be UTF-8, not whatever
-** codepage is currently defined. Filenames containing international
-** characters must be converted to UTF-8 prior to passing them into
-** sqlite3_open() or sqlite3_open_v2().
-**
-** Requirements:
-** [H12701] [H12702] [H12703] [H12704] [H12706] [H12707] [H12709] [H12711]
-** [H12712] [H12713] [H12714] [H12717] [H12719] [H12721] [H12723]
-*/
-SQLITE_API int sqlite3_open(
- const char *filename, /* Database filename (UTF-8) */
- sqlite3 **ppDb /* OUT: SQLite db handle */
-);
-SQLITE_API int sqlite3_open16(
- const void *filename, /* Database filename (UTF-16) */
- sqlite3 **ppDb /* OUT: SQLite db handle */
-);
-SQLITE_API int sqlite3_open_v2(
- const char *filename, /* Database filename (UTF-8) */
- sqlite3 **ppDb, /* OUT: SQLite db handle */
- int flags, /* Flags */
- const char *zVfs /* Name of VFS module to use */
-);
-
-/*
-** CAPI3REF: Error Codes And Messages {H12800} <S60200>
-**
-** The sqlite3_errcode() interface returns the numeric [result code] or
-** [extended result code] for the most recent failed sqlite3_* API call
-** associated with a [database connection]. If a prior API call failed
-** but the most recent API call succeeded, the return value from
-** sqlite3_errcode() is undefined. The sqlite3_extended_errcode()
-** interface is the same except that it always returns the
-** [extended result code] even when extended result codes are
-** disabled.
-**
-** The sqlite3_errmsg() and sqlite3_errmsg16() return English-language
-** text that describes the error, as either UTF-8 or UTF-16 respectively.
-** Memory to hold the error message string is managed internally.
-** The application does not need to worry about freeing the result.
-** However, the error string might be overwritten or deallocated by
-** subsequent calls to other SQLite interface functions.
-**
-** When the serialized [threading mode] is in use, it might be the
-** case that a second error occurs on a separate thread in between
-** the time of the first error and the call to these interfaces.
-** When that happens, the second error will be reported since these
-** interfaces always report the most recent result. To avoid
-** this, each thread can obtain exclusive use of the [database connection] D
-** by invoking [sqlite3_mutex_enter]([sqlite3_db_mutex](D)) before beginning
-** to use D and invoking [sqlite3_mutex_leave]([sqlite3_db_mutex](D)) after
-** all calls to the interfaces listed here are completed.
-**
-** If an interface fails with SQLITE_MISUSE, that means the interface
-** was invoked incorrectly by the application. In that case, the
-** error code and message may or may not be set.
-**
-** Requirements:
-** [H12801] [H12802] [H12803] [H12807] [H12808] [H12809]
-*/
-SQLITE_API int sqlite3_errcode(sqlite3 *db);
-SQLITE_API int sqlite3_extended_errcode(sqlite3 *db);
-SQLITE_API const char *sqlite3_errmsg(sqlite3*);
-SQLITE_API const void *sqlite3_errmsg16(sqlite3*);
-
-/*
-** CAPI3REF: SQL Statement Object {H13000} <H13010>
-** KEYWORDS: {prepared statement} {prepared statements}
-**
-** An instance of this object represents a single SQL statement.
-** This object is variously known as a "prepared statement" or a
-** "compiled SQL statement" or simply as a "statement".
-**
-** The life of a statement object goes something like this:
-**
-** <ol>
-** <li> Create the object using [sqlite3_prepare_v2()] or a related
-** function.
-** <li> Bind values to [host parameters] using the sqlite3_bind_*()
-** interfaces.
-** <li> Run the SQL by calling [sqlite3_step()] one or more times.
-** <li> Reset the statement using [sqlite3_reset()] then go back
-** to step 2. Do this zero or more times.
-** <li> Destroy the object using [sqlite3_finalize()].
-** </ol>
-**
-** Refer to documentation on individual methods above for additional
-** information.
-*/
-typedef struct sqlite3_stmt sqlite3_stmt;
-
-/*
-** CAPI3REF: Run-time Limits {H12760} <S20600>
-**
-** This interface allows the size of various constructs to be limited
-** on a connection by connection basis. The first parameter is the
-** [database connection] whose limit is to be set or queried. The
-** second parameter is one of the [limit categories] that define a
-** class of constructs to be size limited. The third parameter is the
-** new limit for that construct. The function returns the old limit.
-**
-** If the new limit is a negative number, the limit is unchanged.
-** For the limit category of SQLITE_LIMIT_XYZ there is a
-** [limits | hard upper bound]
-** set by a compile-time C preprocessor macro named
-** [limits | SQLITE_MAX_XYZ].
-** (The "_LIMIT_" in the name is changed to "_MAX_".)
-** Attempts to increase a limit above its hard upper bound are
-** silently truncated to the hard upper limit.
-**
-** Run time limits are intended for use in applications that manage
-** both their own internal database and also databases that are controlled
-** by untrusted external sources. An example application might be a
-** web browser that has its own databases for storing history and
-** separate databases controlled by JavaScript applications downloaded
-** off the Internet. The internal databases can be given the
-** large, default limits. Databases managed by external sources can
-** be given much smaller limits designed to prevent a denial of service
-** attack. Developers might also want to use the [sqlite3_set_authorizer()]
-** interface to further control untrusted SQL. The size of the database
-** created by an untrusted script can be contained using the
-** [max_page_count] [PRAGMA].
-**
-** New run-time limit categories may be added in future releases.
-**
-** Requirements:
-** [H12762] [H12766] [H12769]
-*/
-SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal);
-
-/*
-** CAPI3REF: Run-Time Limit Categories {H12790} <H12760>
-** KEYWORDS: {limit category} {limit categories}
-**
-** These constants define various performance limits
-** that can be lowered at run-time using [sqlite3_limit()].
-** The synopsis of the meanings of the various limits is shown below.
-** Additional information is available at [limits | Limits in SQLite].
-**
-** <dl>
-** <dt>SQLITE_LIMIT_LENGTH</dt>
-** <dd>The maximum size of any string or BLOB or table row.<dd>
-**
-** <dt>SQLITE_LIMIT_SQL_LENGTH</dt>
-** <dd>The maximum length of an SQL statement.</dd>
-**
-** <dt>SQLITE_LIMIT_COLUMN</dt>
-** <dd>The maximum number of columns in a table definition or in the
-** result set of a [SELECT] or the maximum number of columns in an index
-** or in an ORDER BY or GROUP BY clause.</dd>
-**
-** <dt>SQLITE_LIMIT_EXPR_DEPTH</dt>
-** <dd>The maximum depth of the parse tree on any expression.</dd>
-**
-** <dt>SQLITE_LIMIT_COMPOUND_SELECT</dt>
-** <dd>The maximum number of terms in a compound SELECT statement.</dd>
-**
-** <dt>SQLITE_LIMIT_VDBE_OP</dt>
-** <dd>The maximum number of instructions in a virtual machine program
-** used to implement an SQL statement.</dd>
-**
-** <dt>SQLITE_LIMIT_FUNCTION_ARG</dt>
-** <dd>The maximum number of arguments on a function.</dd>
-**
-** <dt>SQLITE_LIMIT_ATTACHED</dt>
-** <dd>The maximum number of [ATTACH | attached databases].</dd>
-**
-** <dt>SQLITE_LIMIT_LIKE_PATTERN_LENGTH</dt>
-** <dd>The maximum length of the pattern argument to the [LIKE] or
-** [GLOB] operators.</dd>
-**
-** <dt>SQLITE_LIMIT_VARIABLE_NUMBER</dt>
-** <dd>The maximum number of variables in an SQL statement that can
-** be bound.</dd>
-**
-** <dt>SQLITE_LIMIT_TRIGGER_DEPTH</dt>
-** <dd>The maximum depth of recursion for triggers.</dd>
-** </dl>
-*/
-#define SQLITE_LIMIT_LENGTH 0
-#define SQLITE_LIMIT_SQL_LENGTH 1
-#define SQLITE_LIMIT_COLUMN 2
-#define SQLITE_LIMIT_EXPR_DEPTH 3
-#define SQLITE_LIMIT_COMPOUND_SELECT 4
-#define SQLITE_LIMIT_VDBE_OP 5
-#define SQLITE_LIMIT_FUNCTION_ARG 6
-#define SQLITE_LIMIT_ATTACHED 7
-#define SQLITE_LIMIT_LIKE_PATTERN_LENGTH 8
-#define SQLITE_LIMIT_VARIABLE_NUMBER 9
-#define SQLITE_LIMIT_TRIGGER_DEPTH 10
-
-/*
-** CAPI3REF: Compiling An SQL Statement {H13010} <S10000>
-** KEYWORDS: {SQL statement compiler}
-**
-** To execute an SQL query, it must first be compiled into a byte-code
-** program using one of these routines.
-**
-** The first argument, "db", is a [database connection] obtained from a
-** prior successful call to [sqlite3_open()], [sqlite3_open_v2()] or
-** [sqlite3_open16()]. The database connection must not have been closed.
-**
-** The second argument, "zSql", is the statement to be compiled, encoded
-** as either UTF-8 or UTF-16. The sqlite3_prepare() and sqlite3_prepare_v2()
-** interfaces use UTF-8, and sqlite3_prepare16() and sqlite3_prepare16_v2()
-** use UTF-16.
-**
-** If the nByte argument is less than zero, then zSql is read up to the
-** first zero terminator. If nByte is non-negative, then it is the maximum
-** number of bytes read from zSql. When nByte is non-negative, the
-** zSql string ends at either the first '\000' or '\u0000' character or
-** the nByte-th byte, whichever comes first. If the caller knows
-** that the supplied string is nul-terminated, then there is a small
-** performance advantage to be gained by passing an nByte parameter that
-** is equal to the number of bytes in the input string <i>including</i>
-** the nul-terminator bytes.
-**
-** If pzTail is not NULL then *pzTail is made to point to the first byte
-** past the end of the first SQL statement in zSql. These routines only
-** compile the first statement in zSql, so *pzTail is left pointing to
-** what remains uncompiled.
-**
-** *ppStmt is left pointing to a compiled [prepared statement] that can be
-** executed using [sqlite3_step()]. If there is an error, *ppStmt is set
-** to NULL. If the input text contains no SQL (if the input is an empty
-** string or a comment) then *ppStmt is set to NULL.
-** The calling procedure is responsible for deleting the compiled
-** SQL statement using [sqlite3_finalize()] after it has finished with it.
-** ppStmt may not be NULL.
-**
-** On success, [SQLITE_OK] is returned, otherwise an [error code] is returned.
-**
-** The sqlite3_prepare_v2() and sqlite3_prepare16_v2() interfaces are
-** recommended for all new programs. The two older interfaces are retained
-** for backwards compatibility, but their use is discouraged.
-** In the "v2" interfaces, the prepared statement
-** that is returned (the [sqlite3_stmt] object) contains a copy of the
-** original SQL text. This causes the [sqlite3_step()] interface to
-** behave a differently in two ways:
-**
-** <ol>
-** <li>
-** If the database schema changes, instead of returning [SQLITE_SCHEMA] as it
-** always used to do, [sqlite3_step()] will automatically recompile the SQL
-** statement and try to run it again. If the schema has changed in
-** a way that makes the statement no longer valid, [sqlite3_step()] will still
-** return [SQLITE_SCHEMA]. But unlike the legacy behavior, [SQLITE_SCHEMA] is
-** now a fatal error. Calling [sqlite3_prepare_v2()] again will not make the
-** error go away. Note: use [sqlite3_errmsg()] to find the text
-** of the parsing error that results in an [SQLITE_SCHEMA] return.
-** </li>
-**
-** <li>
-** When an error occurs, [sqlite3_step()] will return one of the detailed
-** [error codes] or [extended error codes]. The legacy behavior was that
-** [sqlite3_step()] would only return a generic [SQLITE_ERROR] result code
-** and you would have to make a second call to [sqlite3_reset()] in order
-** to find the underlying cause of the problem. With the "v2" prepare
-** interfaces, the underlying reason for the error is returned immediately.
-** </li>
-** </ol>
-**
-** Requirements:
-** [H13011] [H13012] [H13013] [H13014] [H13015] [H13016] [H13019] [H13021]
-**
-*/
-SQLITE_API int sqlite3_prepare(
- sqlite3 *db, /* Database handle */
- const char *zSql, /* SQL statement, UTF-8 encoded */
- int nByte, /* Maximum length of zSql in bytes. */
- sqlite3_stmt **ppStmt, /* OUT: Statement handle */
- const char **pzTail /* OUT: Pointer to unused portion of zSql */
-);
-SQLITE_API int sqlite3_prepare_v2(
- sqlite3 *db, /* Database handle */
- const char *zSql, /* SQL statement, UTF-8 encoded */
- int nByte, /* Maximum length of zSql in bytes. */
- sqlite3_stmt **ppStmt, /* OUT: Statement handle */
- const char **pzTail /* OUT: Pointer to unused portion of zSql */
-);
-SQLITE_API int sqlite3_prepare16(
- sqlite3 *db, /* Database handle */
- const void *zSql, /* SQL statement, UTF-16 encoded */
- int nByte, /* Maximum length of zSql in bytes. */
- sqlite3_stmt **ppStmt, /* OUT: Statement handle */
- const void **pzTail /* OUT: Pointer to unused portion of zSql */
-);
-SQLITE_API int sqlite3_prepare16_v2(
- sqlite3 *db, /* Database handle */
- const void *zSql, /* SQL statement, UTF-16 encoded */
- int nByte, /* Maximum length of zSql in bytes. */
- sqlite3_stmt **ppStmt, /* OUT: Statement handle */
- const void **pzTail /* OUT: Pointer to unused portion of zSql */
-);
-
-/*
-** CAPI3REF: Retrieving Statement SQL {H13100} <H13000>
-**
-** This interface can be used to retrieve a saved copy of the original
-** SQL text used to create a [prepared statement] if that statement was
-** compiled using either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()].
-**
-** Requirements:
-** [H13101] [H13102] [H13103]
-*/
-SQLITE_API const char *sqlite3_sql(sqlite3_stmt *pStmt);
-
-/*
-** CAPI3REF: Dynamically Typed Value Object {H15000} <S20200>
-** KEYWORDS: {protected sqlite3_value} {unprotected sqlite3_value}
-**
-** SQLite uses the sqlite3_value object to represent all values
-** that can be stored in a database table. SQLite uses dynamic typing
-** for the values it stores. Values stored in sqlite3_value objects
-** can be integers, floating point values, strings, BLOBs, or NULL.
-**
-** An sqlite3_value object may be either "protected" or "unprotected".
-** Some interfaces require a protected sqlite3_value. Other interfaces
-** will accept either a protected or an unprotected sqlite3_value.
-** Every interface that accepts sqlite3_value arguments specifies
-** whether or not it requires a protected sqlite3_value.
-**
-** The terms "protected" and "unprotected" refer to whether or not
-** a mutex is held. A internal mutex is held for a protected
-** sqlite3_value object but no mutex is held for an unprotected
-** sqlite3_value object. If SQLite is compiled to be single-threaded
-** (with [SQLITE_THREADSAFE=0] and with [sqlite3_threadsafe()] returning 0)
-** or if SQLite is run in one of reduced mutex modes
-** [SQLITE_CONFIG_SINGLETHREAD] or [SQLITE_CONFIG_MULTITHREAD]
-** then there is no distinction between protected and unprotected
-** sqlite3_value objects and they can be used interchangeably. However,
-** for maximum code portability it is recommended that applications
-** still make the distinction between between protected and unprotected
-** sqlite3_value objects even when not strictly required.
-**
-** The sqlite3_value objects that are passed as parameters into the
-** implementation of [application-defined SQL functions] are protected.
-** The sqlite3_value object returned by
-** [sqlite3_column_value()] is unprotected.
-** Unprotected sqlite3_value objects may only be used with
-** [sqlite3_result_value()] and [sqlite3_bind_value()].
-** The [sqlite3_value_blob | sqlite3_value_type()] family of
-** interfaces require protected sqlite3_value objects.
-*/
-typedef struct Mem sqlite3_value;
-
-/*
-** CAPI3REF: SQL Function Context Object {H16001} <S20200>
-**
-** The context in which an SQL function executes is stored in an
-** sqlite3_context object. A pointer to an sqlite3_context object
-** is always first parameter to [application-defined SQL functions].
-** The application-defined SQL function implementation will pass this
-** pointer through into calls to [sqlite3_result_int | sqlite3_result()],
-** [sqlite3_aggregate_context()], [sqlite3_user_data()],
-** [sqlite3_context_db_handle()], [sqlite3_get_auxdata()],
-** and/or [sqlite3_set_auxdata()].
-*/
-typedef struct sqlite3_context sqlite3_context;
-
-/*
-** CAPI3REF: Binding Values To Prepared Statements {H13500} <S70300>
-** KEYWORDS: {host parameter} {host parameters} {host parameter name}
-** KEYWORDS: {SQL parameter} {SQL parameters} {parameter binding}
-**
-** In the SQL strings input to [sqlite3_prepare_v2()] and its variants,
-** literals may be replaced by a [parameter] that matches one of following
-** templates:
-**
-** <ul>
-** <li> ?
-** <li> ?NNN
-** <li> :VVV
-** <li> @VVV
-** <li> $VVV
-** </ul>
-**
-** In the templates above, NNN represents an integer literal,
-** and VVV represents an alphanumeric identifer. The values of these
-** parameters (also called "host parameter names" or "SQL parameters")
-** can be set using the sqlite3_bind_*() routines defined here.
-**
-** The first argument to the sqlite3_bind_*() routines is always
-** a pointer to the [sqlite3_stmt] object returned from
-** [sqlite3_prepare_v2()] or its variants.
-**
-** The second argument is the index of the SQL parameter to be set.
-** The leftmost SQL parameter has an index of 1. When the same named
-** SQL parameter is used more than once, second and subsequent
-** occurrences have the same index as the first occurrence.
-** The index for named parameters can be looked up using the
-** [sqlite3_bind_parameter_index()] API if desired. The index
-** for "?NNN" parameters is the value of NNN.
-** The NNN value must be between 1 and the [sqlite3_limit()]
-** parameter [SQLITE_LIMIT_VARIABLE_NUMBER] (default value: 999).
-**
-** The third argument is the value to bind to the parameter.
-**
-** In those routines that have a fourth argument, its value is the
-** number of bytes in the parameter. To be clear: the value is the
-** number of <u>bytes</u> in the value, not the number of characters.
-** If the fourth parameter is negative, the length of the string is
-** the number of bytes up to the first zero terminator.
-**
-** The fifth argument to sqlite3_bind_blob(), sqlite3_bind_text(), and
-** sqlite3_bind_text16() is a destructor used to dispose of the BLOB or
-** string after SQLite has finished with it. If the fifth argument is
-** the special value [SQLITE_STATIC], then SQLite assumes that the
-** information is in static, unmanaged space and does not need to be freed.
-** If the fifth argument has the value [SQLITE_TRANSIENT], then
-** SQLite makes its own private copy of the data immediately, before
-** the sqlite3_bind_*() routine returns.
-**
-** The sqlite3_bind_zeroblob() routine binds a BLOB of length N that
-** is filled with zeroes. A zeroblob uses a fixed amount of memory
-** (just an integer to hold its size) while it is being processed.
-** Zeroblobs are intended to serve as placeholders for BLOBs whose
-** content is later written using
-** [sqlite3_blob_open | incremental BLOB I/O] routines.
-** A negative value for the zeroblob results in a zero-length BLOB.
-**
-** The sqlite3_bind_*() routines must be called after
-** [sqlite3_prepare_v2()] (and its variants) or [sqlite3_reset()] and
-** before [sqlite3_step()].
-** Bindings are not cleared by the [sqlite3_reset()] routine.
-** Unbound parameters are interpreted as NULL.
-**
-** These routines return [SQLITE_OK] on success or an error code if
-** anything goes wrong. [SQLITE_RANGE] is returned if the parameter
-** index is out of range. [SQLITE_NOMEM] is returned if malloc() fails.
-** [SQLITE_MISUSE] might be returned if these routines are called on a
-** virtual machine that is the wrong state or which has already been finalized.
-** Detection of misuse is unreliable. Applications should not depend
-** on SQLITE_MISUSE returns. SQLITE_MISUSE is intended to indicate a
-** a logic error in the application. Future versions of SQLite might
-** panic rather than return SQLITE_MISUSE.
-**
-** See also: [sqlite3_bind_parameter_count()],
-** [sqlite3_bind_parameter_name()], and [sqlite3_bind_parameter_index()].
-**
-** Requirements:
-** [H13506] [H13509] [H13512] [H13515] [H13518] [H13521] [H13524] [H13527]
-** [H13530] [H13533] [H13536] [H13539] [H13542] [H13545] [H13548] [H13551]
-**
-*/
-SQLITE_API int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*));
-SQLITE_API int sqlite3_bind_double(sqlite3_stmt*, int, double);
-SQLITE_API int sqlite3_bind_int(sqlite3_stmt*, int, int);
-SQLITE_API int sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64);
-SQLITE_API int sqlite3_bind_null(sqlite3_stmt*, int);
-SQLITE_API int sqlite3_bind_text(sqlite3_stmt*, int, const char*, int n, void(*)(void*));
-SQLITE_API int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*));
-SQLITE_API int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*);
-SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n);
-
-/*
-** CAPI3REF: Number Of SQL Parameters {H13600} <S70300>
-**
-** This routine can be used to find the number of [SQL parameters]
-** in a [prepared statement]. SQL parameters are tokens of the
-** form "?", "?NNN", ":AAA", "$AAA", or "@AAA" that serve as
-** placeholders for values that are [sqlite3_bind_blob | bound]
-** to the parameters at a later time.
-**
-** This routine actually returns the index of the largest (rightmost)
-** parameter. For all forms except ?NNN, this will correspond to the
-** number of unique parameters. If parameters of the ?NNN are used,
-** there may be gaps in the list.
-**
-** See also: [sqlite3_bind_blob|sqlite3_bind()],
-** [sqlite3_bind_parameter_name()], and
-** [sqlite3_bind_parameter_index()].
-**
-** Requirements:
-** [H13601]
-*/
-SQLITE_API int sqlite3_bind_parameter_count(sqlite3_stmt*);
-
-/*
-** CAPI3REF: Name Of A Host Parameter {H13620} <S70300>
-**
-** This routine returns a pointer to the name of the n-th
-** [SQL parameter] in a [prepared statement].
-** SQL parameters of the form "?NNN" or ":AAA" or "@AAA" or "$AAA"
-** have a name which is the string "?NNN" or ":AAA" or "@AAA" or "$AAA"
-** respectively.
-** In other words, the initial ":" or "$" or "@" or "?"
-** is included as part of the name.
-** Parameters of the form "?" without a following integer have no name
-** and are also referred to as "anonymous parameters".
-**
-** The first host parameter has an index of 1, not 0.
-**
-** If the value n is out of range or if the n-th parameter is
-** nameless, then NULL is returned. The returned string is
-** always in UTF-8 encoding even if the named parameter was
-** originally specified as UTF-16 in [sqlite3_prepare16()] or
-** [sqlite3_prepare16_v2()].
-**
-** See also: [sqlite3_bind_blob|sqlite3_bind()],
-** [sqlite3_bind_parameter_count()], and
-** [sqlite3_bind_parameter_index()].
-**
-** Requirements:
-** [H13621]
-*/
-SQLITE_API const char *sqlite3_bind_parameter_name(sqlite3_stmt*, int);
-
-/*
-** CAPI3REF: Index Of A Parameter With A Given Name {H13640} <S70300>
-**
-** Return the index of an SQL parameter given its name. The
-** index value returned is suitable for use as the second
-** parameter to [sqlite3_bind_blob|sqlite3_bind()]. A zero
-** is returned if no matching parameter is found. The parameter
-** name must be given in UTF-8 even if the original statement
-** was prepared from UTF-16 text using [sqlite3_prepare16_v2()].
-**
-** See also: [sqlite3_bind_blob|sqlite3_bind()],
-** [sqlite3_bind_parameter_count()], and
-** [sqlite3_bind_parameter_index()].
-**
-** Requirements:
-** [H13641]
-*/
-SQLITE_API int sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName);
-
-/*
-** CAPI3REF: Reset All Bindings On A Prepared Statement {H13660} <S70300>
-**
-** Contrary to the intuition of many, [sqlite3_reset()] does not reset
-** the [sqlite3_bind_blob | bindings] on a [prepared statement].
-** Use this routine to reset all host parameters to NULL.
-**
-** Requirements:
-** [H13661]
-*/
-SQLITE_API int sqlite3_clear_bindings(sqlite3_stmt*);
-
-/*
-** CAPI3REF: Number Of Columns In A Result Set {H13710} <S10700>
-**
-** Return the number of columns in the result set returned by the
-** [prepared statement]. This routine returns 0 if pStmt is an SQL
-** statement that does not return data (for example an [UPDATE]).
-**
-** Requirements:
-** [H13711]
-*/
-SQLITE_API int sqlite3_column_count(sqlite3_stmt *pStmt);
-
-/*
-** CAPI3REF: Column Names In A Result Set {H13720} <S10700>
-**
-** These routines return the name assigned to a particular column
-** in the result set of a [SELECT] statement. The sqlite3_column_name()
-** interface returns a pointer to a zero-terminated UTF-8 string
-** and sqlite3_column_name16() returns a pointer to a zero-terminated
-** UTF-16 string. The first parameter is the [prepared statement]
-** that implements the [SELECT] statement. The second parameter is the
-** column number. The leftmost column is number 0.
-**
-** The returned string pointer is valid until either the [prepared statement]
-** is destroyed by [sqlite3_finalize()] or until the next call to
-** sqlite3_column_name() or sqlite3_column_name16() on the same column.
-**
-** If sqlite3_malloc() fails during the processing of either routine
-** (for example during a conversion from UTF-8 to UTF-16) then a
-** NULL pointer is returned.
-**
-** The name of a result column is the value of the "AS" clause for
-** that column, if there is an AS clause. If there is no AS clause
-** then the name of the column is unspecified and may change from
-** one release of SQLite to the next.
-**
-** Requirements:
-** [H13721] [H13723] [H13724] [H13725] [H13726] [H13727]
-*/
-SQLITE_API const char *sqlite3_column_name(sqlite3_stmt*, int N);
-SQLITE_API const void *sqlite3_column_name16(sqlite3_stmt*, int N);
-
-/*
-** CAPI3REF: Source Of Data In A Query Result {H13740} <S10700>
-**
-** These routines provide a means to determine what column of what
-** table in which database a result of a [SELECT] statement comes from.
-** The name of the database or table or column can be returned as
-** either a UTF-8 or UTF-16 string. The _database_ routines return
-** the database name, the _table_ routines return the table name, and
-** the origin_ routines return the column name.
-** The returned string is valid until the [prepared statement] is destroyed
-** using [sqlite3_finalize()] or until the same information is requested
-** again in a different encoding.
-**
-** The names returned are the original un-aliased names of the
-** database, table, and column.
-**
-** The first argument to the following calls is a [prepared statement].
-** These functions return information about the Nth column returned by
-** the statement, where N is the second function argument.
-**
-** If the Nth column returned by the statement is an expression or
-** subquery and is not a column value, then all of these functions return
-** NULL. These routine might also return NULL if a memory allocation error
-** occurs. Otherwise, they return the name of the attached database, table
-** and column that query result column was extracted from.
-**
-** As with all other SQLite APIs, those postfixed with "16" return
-** UTF-16 encoded strings, the other functions return UTF-8. {END}
-**
-** These APIs are only available if the library was compiled with the
-** [SQLITE_ENABLE_COLUMN_METADATA] C-preprocessor symbol defined.
-**
-** {A13751}
-** If two or more threads call one or more of these routines against the same
-** prepared statement and column at the same time then the results are
-** undefined.
-**
-** Requirements:
-** [H13741] [H13742] [H13743] [H13744] [H13745] [H13746] [H13748]
-**
-** If two or more threads call one or more
-** [sqlite3_column_database_name | column metadata interfaces]
-** for the same [prepared statement] and result column
-** at the same time then the results are undefined.
-*/
-SQLITE_API const char *sqlite3_column_database_name(sqlite3_stmt*,int);
-SQLITE_API const void *sqlite3_column_database_name16(sqlite3_stmt*,int);
-SQLITE_API const char *sqlite3_column_table_name(sqlite3_stmt*,int);
-SQLITE_API const void *sqlite3_column_table_name16(sqlite3_stmt*,int);
-SQLITE_API const char *sqlite3_column_origin_name(sqlite3_stmt*,int);
-SQLITE_API const void *sqlite3_column_origin_name16(sqlite3_stmt*,int);
-
-/*
-** CAPI3REF: Declared Datatype Of A Query Result {H13760} <S10700>
-**
-** The first parameter is a [prepared statement].
-** If this statement is a [SELECT] statement and the Nth column of the
-** returned result set of that [SELECT] is a table column (not an
-** expression or subquery) then the declared type of the table
-** column is returned. If the Nth column of the result set is an
-** expression or subquery, then a NULL pointer is returned.
-** The returned string is always UTF-8 encoded. {END}
-**
-** For example, given the database schema:
-**
-** CREATE TABLE t1(c1 VARIANT);
-**
-** and the following statement to be compiled:
-**
-** SELECT c1 + 1, c1 FROM t1;
-**
-** this routine would return the string "VARIANT" for the second result
-** column (i==1), and a NULL pointer for the first result column (i==0).
-**
-** SQLite uses dynamic run-time typing. So just because a column
-** is declared to contain a particular type does not mean that the
-** data stored in that column is of the declared type. SQLite is
-** strongly typed, but the typing is dynamic not static. Type
-** is associated with individual values, not with the containers
-** used to hold those values.
-**
-** Requirements:
-** [H13761] [H13762] [H13763]
-*/
-SQLITE_API const char *sqlite3_column_decltype(sqlite3_stmt*,int);
-SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt*,int);
-
-/*
-** CAPI3REF: Evaluate An SQL Statement {H13200} <S10000>
-**
-** After a [prepared statement] has been prepared using either
-** [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()] or one of the legacy
-** interfaces [sqlite3_prepare()] or [sqlite3_prepare16()], this function
-** must be called one or more times to evaluate the statement.
-**
-** The details of the behavior of the sqlite3_step() interface depend
-** on whether the statement was prepared using the newer "v2" interface
-** [sqlite3_prepare_v2()] and [sqlite3_prepare16_v2()] or the older legacy
-** interface [sqlite3_prepare()] and [sqlite3_prepare16()]. The use of the
-** new "v2" interface is recommended for new applications but the legacy
-** interface will continue to be supported.
-**
-** In the legacy interface, the return value will be either [SQLITE_BUSY],
-** [SQLITE_DONE], [SQLITE_ROW], [SQLITE_ERROR], or [SQLITE_MISUSE].
-** With the "v2" interface, any of the other [result codes] or
-** [extended result codes] might be returned as well.
-**
-** [SQLITE_BUSY] means that the database engine was unable to acquire the
-** database locks it needs to do its job. If the statement is a [COMMIT]
-** or occurs outside of an explicit transaction, then you can retry the
-** statement. If the statement is not a [COMMIT] and occurs within a
-** explicit transaction then you should rollback the transaction before
-** continuing.
-**
-** [SQLITE_DONE] means that the statement has finished executing
-** successfully. sqlite3_step() should not be called again on this virtual
-** machine without first calling [sqlite3_reset()] to reset the virtual
-** machine back to its initial state.
-**
-** If the SQL statement being executed returns any data, then [SQLITE_ROW]
-** is returned each time a new row of data is ready for processing by the
-** caller. The values may be accessed using the [column access functions].
-** sqlite3_step() is called again to retrieve the next row of data.
-**
-** [SQLITE_ERROR] means that a run-time error (such as a constraint
-** violation) has occurred. sqlite3_step() should not be called again on
-** the VM. More information may be found by calling [sqlite3_errmsg()].
-** With the legacy interface, a more specific error code (for example,
-** [SQLITE_INTERRUPT], [SQLITE_SCHEMA], [SQLITE_CORRUPT], and so forth)
-** can be obtained by calling [sqlite3_reset()] on the
-** [prepared statement]. In the "v2" interface,
-** the more specific error code is returned directly by sqlite3_step().
-**
-** [SQLITE_MISUSE] means that the this routine was called inappropriately.
-** Perhaps it was called on a [prepared statement] that has
-** already been [sqlite3_finalize | finalized] or on one that had
-** previously returned [SQLITE_ERROR] or [SQLITE_DONE]. Or it could
-** be the case that the same database connection is being used by two or
-** more threads at the same moment in time.
-**
-** <b>Goofy Interface Alert:</b> In the legacy interface, the sqlite3_step()
-** API always returns a generic error code, [SQLITE_ERROR], following any
-** error other than [SQLITE_BUSY] and [SQLITE_MISUSE]. You must call
-** [sqlite3_reset()] or [sqlite3_finalize()] in order to find one of the
-** specific [error codes] that better describes the error.
-** We admit that this is a goofy design. The problem has been fixed
-** with the "v2" interface. If you prepare all of your SQL statements
-** using either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()] instead
-** of the legacy [sqlite3_prepare()] and [sqlite3_prepare16()] interfaces,
-** then the more specific [error codes] are returned directly
-** by sqlite3_step(). The use of the "v2" interface is recommended.
-**
-** Requirements:
-** [H13202] [H15304] [H15306] [H15308] [H15310]
-*/
-SQLITE_API int sqlite3_step(sqlite3_stmt*);
-
-/*
-** CAPI3REF: Number of columns in a result set {H13770} <S10700>
-**
-** Returns the number of values in the current row of the result set.
-**
-** Requirements:
-** [H13771] [H13772]
-*/
-SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt);
-
-/*
-** CAPI3REF: Fundamental Datatypes {H10265} <S10110><S10120>
-** KEYWORDS: SQLITE_TEXT
-**
-** {H10266} Every value in SQLite has one of five fundamental datatypes:
-**
-** <ul>
-** <li> 64-bit signed integer
-** <li> 64-bit IEEE floating point number
-** <li> string
-** <li> BLOB
-** <li> NULL
-** </ul> {END}
-**
-** These constants are codes for each of those types.
-**
-** Note that the SQLITE_TEXT constant was also used in SQLite version 2
-** for a completely different meaning. Software that links against both
-** SQLite version 2 and SQLite version 3 should use SQLITE3_TEXT, not
-** SQLITE_TEXT.
-*/
-#define SQLITE_INTEGER 1
-#define SQLITE_FLOAT 2
-#define SQLITE_BLOB 4
-#define SQLITE_NULL 5
-#ifdef SQLITE_TEXT
-# undef SQLITE_TEXT
-#else
-# define SQLITE_TEXT 3
-#endif
-#define SQLITE3_TEXT 3
-
-/*
-** CAPI3REF: Result Values From A Query {H13800} <S10700>
-** KEYWORDS: {column access functions}
-**
-** These routines form the "result set query" interface.
-**
-** These routines return information about a single column of the current
-** result row of a query. In every case the first argument is a pointer
-** to the [prepared statement] that is being evaluated (the [sqlite3_stmt*]
-** that was returned from [sqlite3_prepare_v2()] or one of its variants)
-** and the second argument is the index of the column for which information
-** should be returned. The leftmost column of the result set has the index 0.
-**
-** If the SQL statement does not currently point to a valid row, or if the
-** column index is out of range, the result is undefined.
-** These routines may only be called when the most recent call to
-** [sqlite3_step()] has returned [SQLITE_ROW] and neither
-** [sqlite3_reset()] nor [sqlite3_finalize()] have been called subsequently.
-** If any of these routines are called after [sqlite3_reset()] or
-** [sqlite3_finalize()] or after [sqlite3_step()] has returned
-** something other than [SQLITE_ROW], the results are undefined.
-** If [sqlite3_step()] or [sqlite3_reset()] or [sqlite3_finalize()]
-** are called from a different thread while any of these routines
-** are pending, then the results are undefined.
-**
-** The sqlite3_column_type() routine returns the
-** [SQLITE_INTEGER | datatype code] for the initial data type
-** of the result column. The returned value is one of [SQLITE_INTEGER],
-** [SQLITE_FLOAT], [SQLITE_TEXT], [SQLITE_BLOB], or [SQLITE_NULL]. The value
-** returned by sqlite3_column_type() is only meaningful if no type
-** conversions have occurred as described below. After a type conversion,
-** the value returned by sqlite3_column_type() is undefined. Future
-** versions of SQLite may change the behavior of sqlite3_column_type()
-** following a type conversion.
-**
-** If the result is a BLOB or UTF-8 string then the sqlite3_column_bytes()
-** routine returns the number of bytes in that BLOB or string.
-** If the result is a UTF-16 string, then sqlite3_column_bytes() converts
-** the string to UTF-8 and then returns the number of bytes.
-** If the result is a numeric value then sqlite3_column_bytes() uses
-** [sqlite3_snprintf()] to convert that value to a UTF-8 string and returns
-** the number of bytes in that string.
-** The value returned does not include the zero terminator at the end
-** of the string. For clarity: the value returned is the number of
-** 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
-** value from sqlite3_column_blob() for a zero-length BLOB is an arbitrary
-** pointer, possibly even a NULL pointer.
-**
-** The sqlite3_column_bytes16() routine is similar to sqlite3_column_bytes()
-** but leaves the result in UTF-16 in native byte order instead of UTF-8.
-** The zero terminator is not included in this count.
-**
-** The object returned by [sqlite3_column_value()] is an
-** [unprotected sqlite3_value] object. An unprotected sqlite3_value object
-** may only be used with [sqlite3_bind_value()] and [sqlite3_result_value()].
-** If the [unprotected sqlite3_value] object returned by
-** [sqlite3_column_value()] is used in any other way, including calls
-** to routines like [sqlite3_value_int()], [sqlite3_value_text()],
-** or [sqlite3_value_bytes()], then the behavior is undefined.
-**
-** These routines attempt to convert the value where appropriate. For
-** example, if the internal representation is FLOAT and a text result
-** is requested, [sqlite3_snprintf()] is used internally to perform the
-** conversion automatically. The following table details the conversions
-** that are applied:
-**
-** <blockquote>
-** <table border="1">
-** <tr><th> Internal<br>Type <th> Requested<br>Type <th> Conversion
-**
-** <tr><td> NULL <td> INTEGER <td> Result is 0
-** <tr><td> NULL <td> FLOAT <td> Result is 0.0
-** <tr><td> NULL <td> TEXT <td> Result is NULL pointer
-** <tr><td> NULL <td> BLOB <td> Result is NULL pointer
-** <tr><td> INTEGER <td> FLOAT <td> Convert from integer to float
-** <tr><td> INTEGER <td> TEXT <td> ASCII rendering of the integer
-** <tr><td> INTEGER <td> BLOB <td> Same as INTEGER->TEXT
-** <tr><td> FLOAT <td> INTEGER <td> Convert from float to integer
-** <tr><td> FLOAT <td> TEXT <td> ASCII rendering of the float
-** <tr><td> FLOAT <td> BLOB <td> Same as FLOAT->TEXT
-** <tr><td> TEXT <td> INTEGER <td> Use atoi()
-** <tr><td> TEXT <td> FLOAT <td> Use atof()
-** <tr><td> TEXT <td> BLOB <td> No change
-** <tr><td> BLOB <td> INTEGER <td> Convert to TEXT then use atoi()
-** <tr><td> BLOB <td> FLOAT <td> Convert to TEXT then use atof()
-** <tr><td> BLOB <td> TEXT <td> Add a zero terminator if needed
-** </table>
-** </blockquote>
-**
-** The table above makes reference to standard C library functions atoi()
-** and atof(). SQLite does not really use these functions. It has its
-** own equivalent internal routines. The atoi() and atof() names are
-** used in the table for brevity and because they are familiar to most
-** C programmers.
-**
-** Note that when type conversions occur, pointers returned by prior
-** calls to sqlite3_column_blob(), sqlite3_column_text(), and/or
-** sqlite3_column_text16() may be invalidated.
-** Type conversions and pointer invalidations might occur
-** in the following cases:
-**
-** <ul>
-** <li> The initial content is a BLOB and sqlite3_column_text() or
-** sqlite3_column_text16() is called. A zero-terminator might
-** need to be added to the string.</li>
-** <li> The initial content is UTF-8 text and sqlite3_column_bytes16() or
-** sqlite3_column_text16() is called. The content must be converted
-** to UTF-16.</li>
-** <li> The initial content is UTF-16 text and sqlite3_column_bytes() or
-** sqlite3_column_text() is called. The content must be converted
-** to UTF-8.</li>
-** </ul>
-**
-** Conversions between UTF-16be and UTF-16le are always done in place and do
-** not invalidate a prior pointer, though of course the content of the buffer
-** that the prior pointer points to will have been modified. Other kinds
-** of conversion are done in place when it is possible, but sometimes they
-** are not possible and in those cases prior pointers are invalidated.
-**
-** The safest and easiest to remember policy is to invoke these routines
-** in one of the following ways:
-**
-** <ul>
-** <li>sqlite3_column_text() followed by sqlite3_column_bytes()</li>
-** <li>sqlite3_column_blob() followed by sqlite3_column_bytes()</li>
-** <li>sqlite3_column_text16() followed by sqlite3_column_bytes16()</li>
-** </ul>
-**
-** In other words, you should call sqlite3_column_text(),
-** sqlite3_column_blob(), or sqlite3_column_text16() first to force the result
-** into the desired format, then invoke sqlite3_column_bytes() or
-** sqlite3_column_bytes16() to find the size of the result. Do not mix calls
-** to sqlite3_column_text() or sqlite3_column_blob() with calls to
-** sqlite3_column_bytes16(), and do not mix calls to sqlite3_column_text16()
-** with calls to sqlite3_column_bytes().
-**
-** The pointers returned are valid until a type conversion occurs as
-** described above, or until [sqlite3_step()] or [sqlite3_reset()] or
-** [sqlite3_finalize()] is called. The memory space used to hold strings
-** and BLOBs is freed automatically. Do <b>not</b> pass the pointers returned
-** [sqlite3_column_blob()], [sqlite3_column_text()], etc. into
-** [sqlite3_free()].
-**
-** If a memory allocation error occurs during the evaluation of any
-** of these routines, a default value is returned. The default value
-** is either the integer 0, the floating point number 0.0, or a NULL
-** pointer. Subsequent calls to [sqlite3_errcode()] will return
-** [SQLITE_NOMEM].
-**
-** Requirements:
-** [H13803] [H13806] [H13809] [H13812] [H13815] [H13818] [H13821] [H13824]
-** [H13827] [H13830]
-*/
-SQLITE_API const void *sqlite3_column_blob(sqlite3_stmt*, int iCol);
-SQLITE_API int sqlite3_column_bytes(sqlite3_stmt*, int iCol);
-SQLITE_API int sqlite3_column_bytes16(sqlite3_stmt*, int iCol);
-SQLITE_API double sqlite3_column_double(sqlite3_stmt*, int iCol);
-SQLITE_API int sqlite3_column_int(sqlite3_stmt*, int iCol);
-SQLITE_API sqlite3_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol);
-SQLITE_API const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol);
-SQLITE_API const void *sqlite3_column_text16(sqlite3_stmt*, int iCol);
-SQLITE_API int sqlite3_column_type(sqlite3_stmt*, int iCol);
-SQLITE_API sqlite3_value *sqlite3_column_value(sqlite3_stmt*, int iCol);
-
-/*
-** CAPI3REF: Destroy A Prepared Statement Object {H13300} <S70300><S30100>
-**
-** The sqlite3_finalize() function is called to delete a [prepared statement].
-** If the statement was executed successfully or not executed at all, then
-** SQLITE_OK is returned. If execution of the statement failed then an
-** [error code] or [extended error code] is returned.
-**
-** This routine can be called at any point during the execution of the
-** [prepared statement]. If the virtual machine has not
-** completed execution when this routine is called, that is like
-** encountering an error or an [sqlite3_interrupt | interrupt].
-** Incomplete updates may be rolled back and transactions canceled,
-** depending on the circumstances, and the
-** [error code] returned will be [SQLITE_ABORT].
-**
-** Requirements:
-** [H11302] [H11304]
-*/
-SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt);
-
-/*
-** CAPI3REF: Reset A Prepared Statement Object {H13330} <S70300>
-**
-** The sqlite3_reset() function is called to reset a [prepared statement]
-** object back to its initial state, ready to be re-executed.
-** Any SQL statement variables that had values bound to them using
-** the [sqlite3_bind_blob | sqlite3_bind_*() API] retain their values.
-** Use [sqlite3_clear_bindings()] to reset the bindings.
-**
-** {H11332} The [sqlite3_reset(S)] interface resets the [prepared statement] S
-** back to the beginning of its program.
-**
-** {H11334} If the most recent call to [sqlite3_step(S)] for the
-** [prepared statement] S returned [SQLITE_ROW] or [SQLITE_DONE],
-** or if [sqlite3_step(S)] has never before been called on S,
-** then [sqlite3_reset(S)] returns [SQLITE_OK].
-**
-** {H11336} If the most recent call to [sqlite3_step(S)] for the
-** [prepared statement] S indicated an error, then
-** [sqlite3_reset(S)] returns an appropriate [error code].
-**
-** {H11338} The [sqlite3_reset(S)] interface does not change the values
-** of any [sqlite3_bind_blob|bindings] on the [prepared statement] S.
-*/
-SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt);
-
-/*
-** CAPI3REF: Create Or Redefine SQL Functions {H16100} <S20200>
-** KEYWORDS: {function creation routines}
-** KEYWORDS: {application-defined SQL function}
-** KEYWORDS: {application-defined SQL functions}
-**
-** These two functions (collectively known as "function creation routines")
-** are used to add SQL functions or aggregates or to redefine the behavior
-** of existing SQL functions or aggregates. The only difference between the
-** two is that the second parameter, the name of the (scalar) function or
-** aggregate, is encoded in UTF-8 for sqlite3_create_function() and UTF-16
-** for sqlite3_create_function16().
-**
-** The first parameter is the [database connection] to which the SQL
-** function is to be added. If a single program uses more than one database
-** connection internally, then SQL functions must be added individually to
-** each database connection.
-**
-** The second parameter is the name of the SQL function to be created or
-** redefined. The length of the name is limited to 255 bytes, exclusive of
-** the zero-terminator. Note that the name length limit is in bytes, not
-** characters. Any attempt to create a function with a longer name
-** will result in [SQLITE_ERROR] being returned.
-**
-** The third parameter (nArg)
-** is the number of arguments that the SQL function or
-** aggregate takes. If this parameter is -1, then the SQL function or
-** aggregate may take any number of arguments between 0 and the limit
-** set by [sqlite3_limit]([SQLITE_LIMIT_FUNCTION_ARG]). If the third
-** parameter is less than -1 or greater than 127 then the behavior is
-** undefined.
-**
-** The fourth parameter, eTextRep, specifies what
-** [SQLITE_UTF8 | text encoding] this SQL function prefers for
-** its parameters. Any SQL function implementation should be able to work
-** work with UTF-8, UTF-16le, or UTF-16be. But some implementations may be
-** more efficient with one encoding than another. An application may
-** invoke sqlite3_create_function() or sqlite3_create_function16() multiple
-** times with the same function but with different values of eTextRep.
-** When multiple implementations of the same function are available, SQLite
-** will pick the one that involves the least amount of data conversion.
-** If there is only a single implementation which does not care what text
-** encoding is used, then the fourth argument should be [SQLITE_ANY].
-**
-** The fifth parameter is an arbitrary pointer. The implementation of the
-** function can gain access to this pointer using [sqlite3_user_data()].
-**
-** The seventh, eighth and ninth parameters, xFunc, xStep and xFinal, are
-** pointers to C-language functions that implement the SQL function or
-** aggregate. A scalar SQL function requires an implementation of the xFunc
-** callback only, NULL pointers should be passed as the xStep and xFinal
-** parameters. An aggregate SQL function requires an implementation of xStep
-** and xFinal and NULL should be passed for xFunc. To delete an existing
-** SQL function or aggregate, pass NULL for all three function callbacks.
-**
-** It is permitted to register multiple implementations of the same
-** functions with the same name but with either differing numbers of
-** arguments or differing preferred text encodings. SQLite will use
-** the implementation that most closely matches the way in which the
-** SQL function is used. A function implementation with a non-negative
-** nArg parameter is a better match than a function implementation with
-** a negative nArg. A function where the preferred text encoding
-** matches the database encoding is a better
-** match than a function where the encoding is different.
-** A function where the encoding difference is between UTF16le and UTF16be
-** is a closer match than a function where the encoding difference is
-** between UTF8 and UTF16.
-**
-** Built-in functions may be overloaded by new application-defined functions.
-** The first application-defined function with a given name overrides all
-** built-in functions in the same [database connection] with the same name.
-** Subsequent application-defined functions of the same name only override
-** prior application-defined functions that are an exact match for the
-** number of parameters and preferred encoding.
-**
-** An application-defined function is permitted to call other
-** SQLite interfaces. However, such calls must not
-** close the database connection nor finalize or reset the prepared
-** statement in which the function is running.
-**
-** Requirements:
-** [H16103] [H16106] [H16109] [H16112] [H16118] [H16121] [H16127]
-** [H16130] [H16133] [H16136] [H16139] [H16142]
-*/
-SQLITE_API int sqlite3_create_function(
- sqlite3 *db,
- const char *zFunctionName,
- int nArg,
- int eTextRep,
- void *pApp,
- void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
- void (*xStep)(sqlite3_context*,int,sqlite3_value**),
- void (*xFinal)(sqlite3_context*)
-);
-SQLITE_API int sqlite3_create_function16(
- sqlite3 *db,
- const void *zFunctionName,
- int nArg,
- int eTextRep,
- void *pApp,
- void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
- void (*xStep)(sqlite3_context*,int,sqlite3_value**),
- void (*xFinal)(sqlite3_context*)
-);
-
-/*
-** CAPI3REF: Text Encodings {H10267} <S50200> <H16100>
-**
-** These constant define integer codes that represent the various
-** text encodings supported by SQLite.
-*/
-#define SQLITE_UTF8 1
-#define SQLITE_UTF16LE 2
-#define SQLITE_UTF16BE 3
-#define SQLITE_UTF16 4 /* Use native byte order */
-#define SQLITE_ANY 5 /* sqlite3_create_function only */
-#define SQLITE_UTF16_ALIGNED 8 /* sqlite3_create_collation only */
-
-/*
-** CAPI3REF: Deprecated Functions
-** DEPRECATED
-**
-** These functions are [deprecated]. In order to maintain
-** backwards compatibility with older code, these functions continue
-** to be supported. However, new applications should avoid
-** the use of these functions. To help encourage people to avoid
-** using these functions, we are not going to tell you what they do.
-*/
-#ifndef SQLITE_OMIT_DEPRECATED
-SQLITE_API SQLITE_DEPRECATED int sqlite3_aggregate_count(sqlite3_context*);
-SQLITE_API SQLITE_DEPRECATED int sqlite3_expired(sqlite3_stmt*);
-SQLITE_API SQLITE_DEPRECATED int sqlite3_transfer_bindings(sqlite3_stmt*, sqlite3_stmt*);
-SQLITE_API SQLITE_DEPRECATED int sqlite3_global_recover(void);
-SQLITE_API SQLITE_DEPRECATED void sqlite3_thread_cleanup(void);
-SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int),void*,sqlite3_int64);
-#endif
-
-/*
-** CAPI3REF: Obtaining SQL Function Parameter Values {H15100} <S20200>
-**
-** The C-language implementation of SQL functions and aggregates uses
-** this set of interface routines to access the parameter values on
-** the function or aggregate.
-**
-** The xFunc (for scalar functions) or xStep (for aggregates) parameters
-** to [sqlite3_create_function()] and [sqlite3_create_function16()]
-** define callbacks that implement the SQL functions and aggregates.
-** The 4th parameter to these callbacks is an array of pointers to
-** [protected sqlite3_value] objects. There is one [sqlite3_value] object for
-** each parameter to the SQL function. These routines are used to
-** extract values from the [sqlite3_value] objects.
-**
-** These routines work only with [protected sqlite3_value] objects.
-** Any attempt to use these routines on an [unprotected sqlite3_value]
-** object results in undefined behavior.
-**
-** These routines work just like the corresponding [column access functions]
-** except that these routines take a single [protected sqlite3_value] object
-** pointer instead of a [sqlite3_stmt*] pointer and an integer column number.
-**
-** The sqlite3_value_text16() interface extracts a UTF-16 string
-** in the native byte-order of the host machine. The
-** sqlite3_value_text16be() and sqlite3_value_text16le() interfaces
-** extract UTF-16 strings as big-endian and little-endian respectively.
-**
-** The sqlite3_value_numeric_type() interface attempts to apply
-** numeric affinity to the value. This means that an attempt is
-** made to convert the value to an integer or floating point. If
-** such a conversion is possible without loss of information (in other
-** words, if the value is a string that looks like a number)
-** then the conversion is performed. Otherwise no conversion occurs.
-** The [SQLITE_INTEGER | datatype] after conversion is returned.
-**
-** Please pay particular attention to the fact that the pointer returned
-** from [sqlite3_value_blob()], [sqlite3_value_text()], or
-** [sqlite3_value_text16()] can be invalidated by a subsequent call to
-** [sqlite3_value_bytes()], [sqlite3_value_bytes16()], [sqlite3_value_text()],
-** or [sqlite3_value_text16()].
-**
-** These routines must be called from the same thread as
-** the SQL function that supplied the [sqlite3_value*] parameters.
-**
-** Requirements:
-** [H15103] [H15106] [H15109] [H15112] [H15115] [H15118] [H15121] [H15124]
-** [H15127] [H15130] [H15133] [H15136]
-*/
-SQLITE_API const void *sqlite3_value_blob(sqlite3_value*);
-SQLITE_API int sqlite3_value_bytes(sqlite3_value*);
-SQLITE_API int sqlite3_value_bytes16(sqlite3_value*);
-SQLITE_API double sqlite3_value_double(sqlite3_value*);
-SQLITE_API int sqlite3_value_int(sqlite3_value*);
-SQLITE_API sqlite3_int64 sqlite3_value_int64(sqlite3_value*);
-SQLITE_API const unsigned char *sqlite3_value_text(sqlite3_value*);
-SQLITE_API const void *sqlite3_value_text16(sqlite3_value*);
-SQLITE_API const void *sqlite3_value_text16le(sqlite3_value*);
-SQLITE_API const void *sqlite3_value_text16be(sqlite3_value*);
-SQLITE_API int sqlite3_value_type(sqlite3_value*);
-SQLITE_API int sqlite3_value_numeric_type(sqlite3_value*);
-
-/*
-** CAPI3REF: Obtain Aggregate Function Context {H16210} <S20200>
-**
-** The implementation of aggregate SQL functions use this routine to allocate
-** a structure for storing their state.
-**
-** The first time the sqlite3_aggregate_context() routine is called for a
-** particular aggregate, SQLite allocates nBytes of memory, zeroes out that
-** memory, and returns a pointer to it. On second and subsequent calls to
-** sqlite3_aggregate_context() for the same aggregate function index,
-** the same buffer is returned. The implementation of the aggregate can use
-** the returned buffer to accumulate data.
-**
-** SQLite automatically frees the allocated buffer when the aggregate
-** query concludes.
-**
-** The first parameter should be a copy of the
-** [sqlite3_context | SQL function context] that is the first parameter
-** to the callback routine that implements the aggregate function.
-**
-** This routine must be called from the same thread in which
-** the aggregate SQL function is running.
-**
-** Requirements:
-** [H16211] [H16213] [H16215] [H16217]
-*/
-SQLITE_API void *sqlite3_aggregate_context(sqlite3_context*, int nBytes);
-
-/*
-** CAPI3REF: User Data For Functions {H16240} <S20200>
-**
-** The sqlite3_user_data() interface returns a copy of
-** the pointer that was the pUserData parameter (the 5th parameter)
-** of the [sqlite3_create_function()]
-** and [sqlite3_create_function16()] routines that originally
-** registered the application defined function. {END}
-**
-** This routine must be called from the same thread in which
-** the application-defined function is running.
-**
-** Requirements:
-** [H16243]
-*/
-SQLITE_API void *sqlite3_user_data(sqlite3_context*);
-
-/*
-** CAPI3REF: Database Connection For Functions {H16250} <S60600><S20200>
-**
-** The sqlite3_context_db_handle() interface returns a copy of
-** the pointer to the [database connection] (the 1st parameter)
-** of the [sqlite3_create_function()]
-** and [sqlite3_create_function16()] routines that originally
-** registered the application defined function.
-**
-** Requirements:
-** [H16253]
-*/
-SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*);
-
-/*
-** CAPI3REF: Function Auxiliary Data {H16270} <S20200>
-**
-** The following two functions may be used by scalar SQL functions to
-** associate metadata with argument values. If the same value is passed to
-** multiple invocations of the same SQL function during query execution, under
-** some circumstances the associated metadata may be preserved. This may
-** be used, for example, to add a regular-expression matching scalar
-** function. The compiled version of the regular expression is stored as
-** metadata associated with the SQL value passed as the regular expression
-** pattern. The compiled regular expression can be reused on multiple
-** invocations of the same function so that the original pattern string
-** does not need to be recompiled on each invocation.
-**
-** The sqlite3_get_auxdata() interface returns a pointer to the metadata
-** associated by the sqlite3_set_auxdata() function with the Nth argument
-** value to the application-defined function. If no metadata has been ever
-** been set for the Nth argument of the function, or if the corresponding
-** function parameter has changed since the meta-data was set,
-** then sqlite3_get_auxdata() returns a NULL pointer.
-**
-** The sqlite3_set_auxdata() interface saves the metadata
-** pointed to by its 3rd parameter as the metadata for the N-th
-** argument of the application-defined function. Subsequent
-** calls to sqlite3_get_auxdata() might return this data, if it has
-** not been destroyed.
-** If it is not NULL, SQLite will invoke the destructor
-** function given by the 4th parameter to sqlite3_set_auxdata() on
-** the metadata when the corresponding function parameter changes
-** or when the SQL statement completes, whichever comes first.
-**
-** SQLite is free to call the destructor and drop metadata on any
-** parameter of any function at any time. The only guarantee is that
-** the destructor will be called before the metadata is dropped.
-**
-** In practice, metadata is preserved between function calls for
-** expressions that are constant at compile time. This includes literal
-** values and SQL variables.
-**
-** These routines must be called from the same thread in which
-** the SQL function is running.
-**
-** Requirements:
-** [H16272] [H16274] [H16276] [H16277] [H16278] [H16279]
-*/
-SQLITE_API void *sqlite3_get_auxdata(sqlite3_context*, int N);
-SQLITE_API void sqlite3_set_auxdata(sqlite3_context*, int N, void*, void (*)(void*));
-
-
-/*
-** CAPI3REF: Constants Defining Special Destructor Behavior {H10280} <S30100>
-**
-** These are special values for the destructor that is passed in as the
-** final argument to routines like [sqlite3_result_blob()]. If the destructor
-** argument is SQLITE_STATIC, it means that the content pointer is constant
-** and will never change. It does not need to be destroyed. The
-** SQLITE_TRANSIENT value means that the content will likely change in
-** the near future and that SQLite should make its own private copy of
-** the content before returning.
-**
-** The typedef is necessary to work around problems in certain
-** C++ compilers. See ticket #2191.
-*/
-typedef void (*sqlite3_destructor_type)(void*);
-#define SQLITE_STATIC ((sqlite3_destructor_type)0)
-#define SQLITE_TRANSIENT ((sqlite3_destructor_type)-1)
-
-/*
-** CAPI3REF: Setting The Result Of An SQL Function {H16400} <S20200>
-**
-** These routines are used by the xFunc or xFinal callbacks that
-** implement SQL functions and aggregates. See
-** [sqlite3_create_function()] and [sqlite3_create_function16()]
-** for additional information.
-**
-** These functions work very much like the [parameter binding] family of
-** functions used to bind values to host parameters in prepared statements.
-** Refer to the [SQL parameter] documentation for additional information.
-**
-** The sqlite3_result_blob() interface sets the result from
-** an application-defined function to be the BLOB whose content is pointed
-** to by the second parameter and which is N bytes long where N is the
-** third parameter.
-**
-** The sqlite3_result_zeroblob() interfaces set the result of
-** the application-defined function to be a BLOB containing all zero
-** bytes and N bytes in size, where N is the value of the 2nd parameter.
-**
-** The sqlite3_result_double() interface sets the result from
-** an application-defined function to be a floating point value specified
-** by its 2nd argument.
-**
-** The sqlite3_result_error() and sqlite3_result_error16() functions
-** cause the implemented SQL function to throw an exception.
-** SQLite uses the string pointed to by the
-** 2nd parameter of sqlite3_result_error() or sqlite3_result_error16()
-** as the text of an error message. SQLite interprets the error
-** message string from sqlite3_result_error() as UTF-8. SQLite
-** interprets the string from sqlite3_result_error16() as UTF-16 in native
-** byte order. If the third parameter to sqlite3_result_error()
-** or sqlite3_result_error16() is negative then SQLite takes as the error
-** message all text up through the first zero character.
-** If the third parameter to sqlite3_result_error() or
-** sqlite3_result_error16() is non-negative then SQLite takes that many
-** bytes (not characters) from the 2nd parameter as the error message.
-** The sqlite3_result_error() and sqlite3_result_error16()
-** routines make a private copy of the error message text before
-** they return. Hence, the calling function can deallocate or
-** modify the text after they return without harm.
-** The sqlite3_result_error_code() function changes the error code
-** returned by SQLite as a result of an error in a function. By default,
-** the error code is SQLITE_ERROR. A subsequent call to sqlite3_result_error()
-** or sqlite3_result_error16() resets the error code to SQLITE_ERROR.
-**
-** The sqlite3_result_toobig() interface causes SQLite to throw an error
-** indicating that a string or BLOB is to long to represent.
-**
-** The sqlite3_result_nomem() interface causes SQLite to throw an error
-** indicating that a memory allocation failed.
-**
-** The sqlite3_result_int() interface sets the return value
-** of the application-defined function to be the 32-bit signed integer
-** value given in the 2nd argument.
-** The sqlite3_result_int64() interface sets the return value
-** of the application-defined function to be the 64-bit signed integer
-** value given in the 2nd argument.
-**
-** The sqlite3_result_null() interface sets the return value
-** of the application-defined function to be NULL.
-**
-** The sqlite3_result_text(), sqlite3_result_text16(),
-** sqlite3_result_text16le(), and sqlite3_result_text16be() interfaces
-** set the return value of the application-defined function to be
-** a text string which is represented as UTF-8, UTF-16 native byte order,
-** UTF-16 little endian, or UTF-16 big endian, respectively.
-** SQLite takes the text result from the application from
-** the 2nd parameter of the sqlite3_result_text* interfaces.
-** If the 3rd parameter to the sqlite3_result_text* interfaces
-** is negative, then SQLite takes result text from the 2nd parameter
-** through the first zero character.
-** If the 3rd parameter to the sqlite3_result_text* interfaces
-** is non-negative, then as many bytes (not characters) of the text
-** pointed to by the 2nd parameter are taken as the application-defined
-** function result.
-** If the 4th parameter to the sqlite3_result_text* interfaces
-** or sqlite3_result_blob is a non-NULL pointer, then SQLite calls that
-** function as the destructor on the text or BLOB result when it has
-** finished using that result.
-** If the 4th parameter to the sqlite3_result_text* interfaces or to
-** sqlite3_result_blob is the special constant SQLITE_STATIC, then SQLite
-** assumes that the text or BLOB result is in constant space and does not
-** copy the content of the parameter nor call a destructor on the content
-** when it has finished using that result.
-** If the 4th parameter to the sqlite3_result_text* interfaces
-** or sqlite3_result_blob is the special constant SQLITE_TRANSIENT
-** then SQLite makes a copy of the result into space obtained from
-** from [sqlite3_malloc()] before it returns.
-**
-** The sqlite3_result_value() interface sets the result of
-** the application-defined function to be a copy the
-** [unprotected sqlite3_value] object specified by the 2nd parameter. The
-** sqlite3_result_value() interface makes a copy of the [sqlite3_value]
-** so that the [sqlite3_value] specified in the parameter may change or
-** be deallocated after sqlite3_result_value() returns without harm.
-** A [protected sqlite3_value] object may always be used where an
-** [unprotected sqlite3_value] object is required, so either
-** kind of [sqlite3_value] object can be used with this interface.
-**
-** If these routines are called from within the different thread
-** than the one containing the application-defined function that received
-** the [sqlite3_context] pointer, the results are undefined.
-**
-** Requirements:
-** [H16403] [H16406] [H16409] [H16412] [H16415] [H16418] [H16421] [H16424]
-** [H16427] [H16430] [H16433] [H16436] [H16439] [H16442] [H16445] [H16448]
-** [H16451] [H16454] [H16457] [H16460] [H16463]
-*/
-SQLITE_API void sqlite3_result_blob(sqlite3_context*, const void*, int, void(*)(void*));
-SQLITE_API void sqlite3_result_double(sqlite3_context*, double);
-SQLITE_API void sqlite3_result_error(sqlite3_context*, const char*, int);
-SQLITE_API void sqlite3_result_error16(sqlite3_context*, const void*, int);
-SQLITE_API void sqlite3_result_error_toobig(sqlite3_context*);
-SQLITE_API void sqlite3_result_error_nomem(sqlite3_context*);
-SQLITE_API void sqlite3_result_error_code(sqlite3_context*, int);
-SQLITE_API void sqlite3_result_int(sqlite3_context*, int);
-SQLITE_API void sqlite3_result_int64(sqlite3_context*, sqlite3_int64);
-SQLITE_API void sqlite3_result_null(sqlite3_context*);
-SQLITE_API void sqlite3_result_text(sqlite3_context*, const char*, int, void(*)(void*));
-SQLITE_API void sqlite3_result_text16(sqlite3_context*, const void*, int, void(*)(void*));
-SQLITE_API void sqlite3_result_text16le(sqlite3_context*, const void*, int,void(*)(void*));
-SQLITE_API void sqlite3_result_text16be(sqlite3_context*, const void*, int,void(*)(void*));
-SQLITE_API void sqlite3_result_value(sqlite3_context*, sqlite3_value*);
-SQLITE_API void sqlite3_result_zeroblob(sqlite3_context*, int n);
-
-/*
-** CAPI3REF: Define New Collating Sequences {H16600} <S20300>
-**
-** These functions are used to add new collation sequences to the
-** [database connection] specified as the first argument.
-**
-** The name of the new collation sequence is specified as a UTF-8 string
-** for sqlite3_create_collation() and sqlite3_create_collation_v2()
-** and a UTF-16 string for sqlite3_create_collation16(). In all cases
-** the name is passed as the second function argument.
-**
-** The third argument may be one of the constants [SQLITE_UTF8],
-** [SQLITE_UTF16LE], or [SQLITE_UTF16BE], indicating that the user-supplied
-** routine expects to be passed pointers to strings encoded using UTF-8,
-** UTF-16 little-endian, or UTF-16 big-endian, respectively. The
-** third argument might also be [SQLITE_UTF16] to indicate that the routine
-** expects pointers to be UTF-16 strings in the native byte order, or the
-** argument can be [SQLITE_UTF16_ALIGNED] if the
-** the routine expects pointers to 16-bit word aligned strings
-** of UTF-16 in the native byte order.
-**
-** A pointer to the user supplied routine must be passed as the fifth
-** argument. If it is NULL, this is the same as deleting the collation
-** sequence (so that SQLite cannot call it anymore).
-** Each time the application supplied function is invoked, it is passed
-** as its first parameter a copy of the void* passed as the fourth argument
-** to sqlite3_create_collation() or sqlite3_create_collation16().
-**
-** The remaining arguments to the application-supplied routine are two strings,
-** each represented by a (length, data) pair and encoded in the encoding
-** that was passed as the third argument when the collation sequence was
-** registered. {END} The application defined collation routine should
-** return negative, zero or positive if the first string is less than,
-** equal to, or greater than the second string. i.e. (STRING1 - STRING2).
-**
-** The sqlite3_create_collation_v2() works like sqlite3_create_collation()
-** except that it takes an extra argument which is a destructor for
-** the collation. The destructor is called when the collation is
-** destroyed and is passed a copy of the fourth parameter void* pointer
-** of the sqlite3_create_collation_v2().
-** Collations are destroyed when they are overridden by later calls to the
-** collation creation functions or when the [database connection] is closed
-** using [sqlite3_close()].
-**
-** See also: [sqlite3_collation_needed()] and [sqlite3_collation_needed16()].
-**
-** Requirements:
-** [H16603] [H16604] [H16606] [H16609] [H16612] [H16615] [H16618] [H16621]
-** [H16624] [H16627] [H16630]
-*/
-SQLITE_API int sqlite3_create_collation(
- sqlite3*,
- const char *zName,
- int eTextRep,
- void*,
- int(*xCompare)(void*,int,const void*,int,const void*)
-);
-SQLITE_API int sqlite3_create_collation_v2(
- sqlite3*,
- const char *zName,
- int eTextRep,
- void*,
- int(*xCompare)(void*,int,const void*,int,const void*),
- void(*xDestroy)(void*)
-);
-SQLITE_API int sqlite3_create_collation16(
- sqlite3*,
- const void *zName,
- int eTextRep,
- void*,
- int(*xCompare)(void*,int,const void*,int,const void*)
-);
-
-/*
-** CAPI3REF: Collation Needed Callbacks {H16700} <S20300>
-**
-** To avoid having to register all collation sequences before a database
-** can be used, a single callback function may be registered with the
-** [database connection] to be called whenever an undefined collation
-** sequence is required.
-**
-** If the function is registered using the sqlite3_collation_needed() API,
-** then it is passed the names of undefined collation sequences as strings
-** encoded in UTF-8. {H16703} If sqlite3_collation_needed16() is used,
-** the names are passed as UTF-16 in machine native byte order.
-** A call to either function replaces any existing callback.
-**
-** When the callback is invoked, the first argument passed is a copy
-** of the second argument to sqlite3_collation_needed() or
-** sqlite3_collation_needed16(). The second argument is the database
-** connection. The third argument is one of [SQLITE_UTF8], [SQLITE_UTF16BE],
-** or [SQLITE_UTF16LE], indicating the most desirable form of the collation
-** sequence function required. The fourth parameter is the name of the
-** required collation sequence.
-**
-** The callback function should register the desired collation using
-** [sqlite3_create_collation()], [sqlite3_create_collation16()], or
-** [sqlite3_create_collation_v2()].
-**
-** Requirements:
-** [H16702] [H16704] [H16706]
-*/
-SQLITE_API int sqlite3_collation_needed(
- sqlite3*,
- void*,
- void(*)(void*,sqlite3*,int eTextRep,const char*)
-);
-SQLITE_API int sqlite3_collation_needed16(
- sqlite3*,
- void*,
- void(*)(void*,sqlite3*,int eTextRep,const void*)
-);
-
-/*
-** Specify the key for an encrypted database. This routine should be
-** called right after sqlite3_open().
-**
-** The code to implement this API is not available in the public release
-** of SQLite.
-*/
-SQLITE_API int sqlite3_key(
- sqlite3 *db, /* Database to be rekeyed */
- const void *pKey, int nKey /* The key */
-);
-
-/*
-** Change the key on an open database. If the current database is not
-** encrypted, this routine will encrypt it. If pNew==0 or nNew==0, the
-** database is decrypted.
-**
-** The code to implement this API is not available in the public release
-** of SQLite.
-*/
-SQLITE_API int sqlite3_rekey(
- sqlite3 *db, /* Database to be rekeyed */
- const void *pKey, int nKey /* The new key */
-);
-
-/*
-** CAPI3REF: Suspend Execution For A Short Time {H10530} <S40410>
-**
-** The sqlite3_sleep() function causes the current thread to suspend execution
-** for at least a number of milliseconds specified in its parameter.
-**
-** If the operating system does not support sleep requests with
-** millisecond time resolution, then the time will be rounded up to
-** the nearest second. The number of milliseconds of sleep actually
-** requested from the operating system is returned.
-**
-** SQLite implements this interface by calling the xSleep()
-** method of the default [sqlite3_vfs] object.
-**
-** Requirements: [H10533] [H10536]
-*/
-SQLITE_API int sqlite3_sleep(int);
-
-/*
-** CAPI3REF: Name Of The Folder Holding Temporary Files {H10310} <S20000>
-**
-** If this global variable is made to point to a string which is
-** the name of a folder (a.k.a. directory), then all temporary files
-** created by SQLite will be placed in that directory. If this variable
-** is a NULL pointer, then SQLite performs a search for an appropriate
-** temporary file directory.
-**
-** It is not safe to read or modify this variable in more than one
-** thread at a time. It is not safe to read or modify this variable
-** if a [database connection] is being used at the same time in a separate
-** thread.
-** It is intended that this variable be set once
-** as part of process initialization and before any SQLite interface
-** routines have been called and that this variable remain unchanged
-** thereafter.
-**
-** The [temp_store_directory pragma] may modify this variable and cause
-** it to point to memory obtained from [sqlite3_malloc]. Furthermore,
-** the [temp_store_directory pragma] always assumes that any string
-** that this variable points to is held in memory obtained from
-** [sqlite3_malloc] and the pragma may attempt to free that memory
-** using [sqlite3_free].
-** Hence, if this variable is modified directly, either it should be
-** made NULL or made to point to memory obtained from [sqlite3_malloc]
-** or else the use of the [temp_store_directory pragma] should be avoided.
-*/
-SQLITE_API char *sqlite3_temp_directory;
-
-/*
-** CAPI3REF: Test For Auto-Commit Mode {H12930} <S60200>
-** KEYWORDS: {autocommit mode}
-**
-** The sqlite3_get_autocommit() interface returns non-zero or
-** zero if the given database connection is or is not in autocommit mode,
-** respectively. Autocommit mode is on by default.
-** Autocommit mode is disabled by a [BEGIN] statement.
-** Autocommit mode is re-enabled by a [COMMIT] or [ROLLBACK].
-**
-** If certain kinds of errors occur on a statement within a multi-statement
-** transaction (errors including [SQLITE_FULL], [SQLITE_IOERR],
-** [SQLITE_NOMEM], [SQLITE_BUSY], and [SQLITE_INTERRUPT]) then the
-** transaction might be rolled back automatically. The only way to
-** find out whether SQLite automatically rolled back the transaction after
-** an error is to use this function.
-**
-** If another thread changes the autocommit status of the database
-** connection while this routine is running, then the return value
-** is undefined.
-**
-** Requirements: [H12931] [H12932] [H12933] [H12934]
-*/
-SQLITE_API int sqlite3_get_autocommit(sqlite3*);
-
-/*
-** CAPI3REF: Find The Database Handle Of A Prepared Statement {H13120} <S60600>
-**
-** The sqlite3_db_handle interface returns the [database connection] handle
-** to which a [prepared statement] belongs. The [database connection]
-** returned by sqlite3_db_handle is the same [database connection] that was the first argument
-** to the [sqlite3_prepare_v2()] call (or its variants) that was used to
-** create the statement in the first place.
-**
-** Requirements: [H13123]
-*/
-SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt*);
-
-/*
-** CAPI3REF: Find the next prepared statement {H13140} <S60600>
-**
-** This interface returns a pointer to the next [prepared statement] after
-** pStmt associated with the [database connection] pDb. If pStmt is NULL
-** then this interface returns a pointer to the first prepared statement
-** associated with the database connection pDb. If no prepared statement
-** satisfies the conditions of this routine, it returns NULL.
-**
-** The [database connection] pointer D in a call to
-** [sqlite3_next_stmt(D,S)] must refer to an open database
-** connection and in particular must not be a NULL pointer.
-**
-** Requirements: [H13143] [H13146] [H13149] [H13152]
-*/
-SQLITE_API sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt);
-
-/*
-** CAPI3REF: Commit And Rollback Notification Callbacks {H12950} <S60400>
-**
-** The sqlite3_commit_hook() interface registers a callback
-** function to be invoked whenever a transaction is [COMMIT | committed].
-** Any callback set by a previous call to sqlite3_commit_hook()
-** for the same database connection is overridden.
-** The sqlite3_rollback_hook() interface registers a callback
-** function to be invoked whenever a transaction is [ROLLBACK | rolled back].
-** Any callback set by a previous call to sqlite3_commit_hook()
-** for the same database connection is overridden.
-** The pArg argument is passed through to the callback.
-** If the callback on a commit hook function returns non-zero,
-** then the commit is converted into a rollback.
-**
-** If another function was previously registered, its
-** pArg value is returned. Otherwise NULL is returned.
-**
-** 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.
-**
-** Registering a NULL function disables the callback.
-**
-** When the commit hook callback routine returns zero, the [COMMIT]
-** operation is allowed to continue normally. If the commit hook
-** returns non-zero, then the [COMMIT] is converted into a [ROLLBACK].
-** The rollback hook is invoked on a rollback that results from a commit
-** hook returning non-zero, just as it would be with any other rollback.
-**
-** For the purposes of this API, a transaction is said to have been
-** rolled back if an explicit "ROLLBACK" statement is executed, or
-** an error or constraint causes an implicit rollback to occur.
-** The rollback callback is not invoked if a transaction is
-** automatically rolled back because the database connection is closed.
-** The rollback callback is not invoked if a transaction is
-** rolled back because a commit callback returned non-zero.
-** <todo> Check on this </todo>
-**
-** See also the [sqlite3_update_hook()] interface.
-**
-** Requirements:
-** [H12951] [H12952] [H12953] [H12954] [H12955]
-** [H12961] [H12962] [H12963] [H12964]
-*/
-SQLITE_API void *sqlite3_commit_hook(sqlite3*, int(*)(void*), void*);
-SQLITE_API void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*);
-
-/*
-** CAPI3REF: Data Change Notification Callbacks {H12970} <S60400>
-**
-** The sqlite3_update_hook() interface registers a callback function
-** with the [database connection] identified by the first argument
-** to be invoked whenever a row is updated, inserted or deleted.
-** Any callback set by a previous call to this function
-** for the same database connection is overridden.
-**
-** The second argument is a pointer to the function to invoke when a
-** row is updated, inserted or deleted.
-** The first argument to the callback is a copy of the third argument
-** to sqlite3_update_hook().
-** The second callback argument is one of [SQLITE_INSERT], [SQLITE_DELETE],
-** or [SQLITE_UPDATE], depending on the operation that caused the callback
-** to be invoked.
-** The third and fourth arguments to the callback contain pointers to the
-** database and table name containing the affected row.
-** The final callback parameter is the [rowid] of the row.
-** In the case of an update, this is the [rowid] after the update takes place.
-**
-** The update hook is not invoked when internal system tables are
-** modified (i.e. sqlite_master and sqlite_sequence).
-**
-** In the current implementation, the update hook
-** is not invoked when duplication rows are deleted because of an
-** [ON CONFLICT | ON CONFLICT REPLACE] clause. Nor is the update hook
-** invoked when rows are deleted using the [truncate optimization].
-** The exceptions defined in this paragraph might change in a future
-** release of SQLite.
-**
-** The update hook implementation must not do anything that will modify
-** the database connection that invoked the update hook. Any actions
-** to modify the database connection must be deferred until after the
-** completion of the [sqlite3_step()] call that triggered the update hook.
-** Note that [sqlite3_prepare_v2()] and [sqlite3_step()] both modify their
-** database connections for the meaning of "modify" in this paragraph.
-**
-** If another function was previously registered, its pArg value
-** is returned. Otherwise NULL is returned.
-**
-** See also the [sqlite3_commit_hook()] and [sqlite3_rollback_hook()]
-** interfaces.
-**
-** Requirements:
-** [H12971] [H12973] [H12975] [H12977] [H12979] [H12981] [H12983] [H12986]
-*/
-SQLITE_API void *sqlite3_update_hook(
- sqlite3*,
- void(*)(void *,int ,char const *,char const *,sqlite3_int64),
- void*
-);
-
-/*
-** CAPI3REF: Enable Or Disable Shared Pager Cache {H10330} <S30900>
-** KEYWORDS: {shared cache}
-**
-** This routine enables or disables the sharing of the database cache
-** and schema data structures between [database connection | connections]
-** to the same database. Sharing is enabled if the argument is true
-** and disabled if the argument is false.
-**
-** Cache sharing is enabled and disabled for an entire process.
-** This is a change as of SQLite version 3.5.0. In prior versions of SQLite,
-** sharing was enabled or disabled for each thread separately.
-**
-** The cache sharing mode set by this interface effects all subsequent
-** calls to [sqlite3_open()], [sqlite3_open_v2()], and [sqlite3_open16()].
-** Existing database connections continue use the sharing mode
-** that was in effect at the time they were opened.
-**
-** Virtual tables cannot be used with a shared cache. When shared
-** cache is enabled, the [sqlite3_create_module()] API used to register
-** virtual tables will always return an error.
-**
-** This routine returns [SQLITE_OK] if shared cache was enabled or disabled
-** successfully. An [error code] is returned otherwise.
-**
-** Shared cache is disabled by default. But this might change in
-** future releases of SQLite. Applications that care about shared
-** cache setting should set it explicitly.
-**
-** See Also: [SQLite Shared-Cache Mode]
-**
-** Requirements: [H10331] [H10336] [H10337] [H10339]
-*/
-SQLITE_API int sqlite3_enable_shared_cache(int);
-
-/*
-** CAPI3REF: Attempt To Free Heap Memory {H17340} <S30220>
-**
-** The sqlite3_release_memory() interface attempts to free N bytes
-** of heap memory by deallocating non-essential memory allocations
-** held by the database library. {END} Memory used to cache database
-** pages to improve performance is an example of non-essential memory.
-** sqlite3_release_memory() returns the number of bytes actually freed,
-** which might be more or less than the amount requested.
-**
-** Requirements: [H17341] [H17342]
-*/
-SQLITE_API int sqlite3_release_memory(int);
-
-/*
-** CAPI3REF: Impose A Limit On Heap Size {H17350} <S30220>
-**
-** The sqlite3_soft_heap_limit() interface places a "soft" limit
-** on the amount of heap memory that may be allocated by SQLite.
-** If an internal allocation is requested that would exceed the
-** soft heap limit, [sqlite3_release_memory()] is invoked one or
-** more times to free up some space before the allocation is performed.
-**
-** The limit is called "soft", because if [sqlite3_release_memory()]
-** cannot free sufficient memory to prevent the limit from being exceeded,
-** the memory is allocated anyway and the current operation proceeds.
-**
-** A negative or zero value for N means that there is no soft heap limit and
-** [sqlite3_release_memory()] will only be called when memory is exhausted.
-** The default value for the soft heap limit is zero.
-**
-** SQLite makes a best effort to honor the soft heap limit.
-** But if the soft heap limit cannot be honored, execution will
-** continue without error or notification. This is why the limit is
-** called a "soft" limit. It is advisory only.
-**
-** Prior to SQLite version 3.5.0, this routine only constrained the memory
-** allocated by a single thread - the same thread in which this routine
-** runs. Beginning with SQLite version 3.5.0, the soft heap limit is
-** applied to all threads. The value specified for the soft heap limit
-** is an upper bound on the total memory allocation for all threads. In
-** version 3.5.0 there is no mechanism for limiting the heap usage for
-** individual threads.
-**
-** Requirements:
-** [H16351] [H16352] [H16353] [H16354] [H16355] [H16358]
-*/
-SQLITE_API void sqlite3_soft_heap_limit(int);
-
-/*
-** CAPI3REF: Extract Metadata About A Column Of A Table {H12850} <S60300>
-**
-** This routine returns metadata about a specific column of a specific
-** database table accessible using the [database connection] handle
-** passed as the first function argument.
-**
-** The column is identified by the second, third and fourth parameters to
-** this function. The second parameter is either the name of the database
-** (i.e. "main", "temp" or an attached database) containing the specified
-** table or NULL. If it is NULL, then all attached databases are searched
-** for the table using the same algorithm used by the database engine to
-** resolve unqualified table references.
-**
-** The third and fourth parameters to this function are the table and column
-** name of the desired column, respectively. Neither of these parameters
-** may be NULL.
-**
-** Metadata is returned by writing to the memory locations passed as the 5th
-** and subsequent parameters to this function. Any of these arguments may be
-** NULL, in which case the corresponding element of metadata is omitted.
-**
-** <blockquote>
-** <table border="1">
-** <tr><th> Parameter <th> Output<br>Type <th> Description
-**
-** <tr><td> 5th <td> const char* <td> Data type
-** <tr><td> 6th <td> const char* <td> Name of default collation sequence
-** <tr><td> 7th <td> int <td> True if column has a NOT NULL constraint
-** <tr><td> 8th <td> int <td> True if column is part of the PRIMARY KEY
-** <tr><td> 9th <td> int <td> True if column is [AUTOINCREMENT]
-** </table>
-** </blockquote>
-**
-** The memory pointed to by the character pointers returned for the
-** declaration type and collation sequence is valid only until the next
-** call to any SQLite API function.
-**
-** If the specified table is actually a view, an [error code] is returned.
-**
-** If the specified column is "rowid", "oid" or "_rowid_" and an
-** [INTEGER PRIMARY KEY] column has been explicitly declared, then the output
-** parameters are set for the explicitly declared column. If there is no
-** explicitly declared [INTEGER PRIMARY KEY] column, then the output
-** parameters are set as follows:
-**
-** <pre>
-** data type: "INTEGER"
-** collation sequence: "BINARY"
-** not null: 0
-** primary key: 1
-** auto increment: 0
-** </pre>
-**
-** This function may load one or more schemas from database files. If an
-** error occurs during this process, or if the requested table or column
-** cannot be found, an [error code] is returned and an error message left
-** in the [database connection] (to be retrieved using sqlite3_errmsg()).
-**
-** This API is only available if the library was compiled with the
-** [SQLITE_ENABLE_COLUMN_METADATA] C-preprocessor symbol defined.
-*/
-SQLITE_API int sqlite3_table_column_metadata(
- sqlite3 *db, /* Connection handle */
- const char *zDbName, /* Database name or NULL */
- const char *zTableName, /* Table name */
- const char *zColumnName, /* Column name */
- char const **pzDataType, /* OUTPUT: Declared data type */
- char const **pzCollSeq, /* OUTPUT: Collation sequence name */
- int *pNotNull, /* OUTPUT: True if NOT NULL constraint exists */
- int *pPrimaryKey, /* OUTPUT: True if column part of PK */
- int *pAutoinc /* OUTPUT: True if column is auto-increment */
-);
-
-/*
-** CAPI3REF: Load An Extension {H12600} <S20500>
-**
-** This interface loads an SQLite extension library from the named file.
-**
-** {H12601} The sqlite3_load_extension() interface attempts to load an
-** SQLite extension library contained in the file zFile.
-**
-** {H12602} The entry point is zProc.
-**
-** {H12603} zProc may be 0, in which case the name of the entry point
-** defaults to "sqlite3_extension_init".
-**
-** {H12604} The sqlite3_load_extension() interface shall return
-** [SQLITE_OK] on success and [SQLITE_ERROR] if something goes wrong.
-**
-** {H12605} If an error occurs and pzErrMsg is not 0, then the
-** [sqlite3_load_extension()] interface shall attempt to
-** fill *pzErrMsg with error message text stored in memory
-** obtained from [sqlite3_malloc()]. {END} The calling function
-** should free this memory by calling [sqlite3_free()].
-**
-** {H12606} Extension loading must be enabled using
-** [sqlite3_enable_load_extension()] prior to calling this API,
-** otherwise an error will be returned.
-*/
-SQLITE_API int sqlite3_load_extension(
- sqlite3 *db, /* Load the extension into this database connection */
- const char *zFile, /* Name of the shared library containing extension */
- const char *zProc, /* Entry point. Derived from zFile if 0 */
- char **pzErrMsg /* Put error message here if not 0 */
-);
-
-/*
-** CAPI3REF: Enable Or Disable Extension Loading {H12620} <S20500>
-**
-** So as not to open security holes in older applications that are
-** unprepared to deal with extension loading, and as a means of disabling
-** extension loading while evaluating user-entered SQL, the following API
-** is provided to turn the [sqlite3_load_extension()] mechanism on and off.
-**
-** Extension loading is off by default. See ticket #1863.
-**
-** {H12621} Call the sqlite3_enable_load_extension() routine with onoff==1
-** to turn extension loading on and call it with onoff==0 to turn
-** it back off again.
-**
-** {H12622} Extension loading is off by default.
-*/
-SQLITE_API int sqlite3_enable_load_extension(sqlite3 *db, int onoff);
-
-/*
-** CAPI3REF: Automatically Load An Extensions {H12640} <S20500>
-**
-** This API can be invoked at program startup in order to register
-** one or more statically linked extensions that will be available
-** to all new [database connections]. {END}
-**
-** This routine stores a pointer to the extension in an array that is
-** obtained from [sqlite3_malloc()]. If you run a memory leak checker
-** on your program and it reports a leak because of this array, invoke
-** [sqlite3_reset_auto_extension()] prior to shutdown to free the memory.
-**
-** {H12641} This function registers an extension entry point that is
-** automatically invoked whenever a new [database connection]
-** is opened using [sqlite3_open()], [sqlite3_open16()],
-** or [sqlite3_open_v2()].
-**
-** {H12642} Duplicate extensions are detected so calling this routine
-** multiple times with the same extension is harmless.
-**
-** {H12643} This routine stores a pointer to the extension in an array
-** that is obtained from [sqlite3_malloc()].
-**
-** {H12644} Automatic extensions apply across all threads.
-*/
-SQLITE_API int sqlite3_auto_extension(void (*xEntryPoint)(void));
-
-/*
-** CAPI3REF: Reset Automatic Extension Loading {H12660} <S20500>
-**
-** This function disables all previously registered automatic
-** extensions. {END} It undoes the effect of all prior
-** [sqlite3_auto_extension()] calls.
-**
-** {H12661} This function disables all previously registered
-** automatic extensions.
-**
-** {H12662} This function disables automatic extensions in all threads.
-*/
-SQLITE_API void sqlite3_reset_auto_extension(void);
-
-/*
-****** EXPERIMENTAL - subject to change without notice **************
-**
-** The interface to the virtual-table mechanism is currently considered
-** to be experimental. The interface might change in incompatible ways.
-** If this is a problem for you, do not use the interface at this time.
-**
-** When the virtual-table mechanism stabilizes, we will declare the
-** interface fixed, support it indefinitely, and remove this comment.
-*/
-
-/*
-** Structures used by the virtual table interface
-*/
-typedef struct sqlite3_vtab sqlite3_vtab;
-typedef struct sqlite3_index_info sqlite3_index_info;
-typedef struct sqlite3_vtab_cursor sqlite3_vtab_cursor;
-typedef struct sqlite3_module sqlite3_module;
-
-/*
-** CAPI3REF: Virtual Table Object {H18000} <S20400>
-** KEYWORDS: sqlite3_module {virtual table module}
-** EXPERIMENTAL
-**
-** This structure, sometimes called a a "virtual table module",
-** defines the implementation of a [virtual tables].
-** This structure consists mostly of methods for the module.
-**
-** A virtual table module is created by filling in a persistent
-** instance of this structure and passing a pointer to that instance
-** to [sqlite3_create_module()] or [sqlite3_create_module_v2()].
-** The registration remains valid until it is replaced by a different
-** module or until the [database connection] closes. The content
-** of this structure must not change while it is registered with
-** any database connection.
-*/
-struct sqlite3_module {
- int iVersion;
- int (*xCreate)(sqlite3*, void *pAux,
- int argc, const char *const*argv,
- sqlite3_vtab **ppVTab, char**);
- int (*xConnect)(sqlite3*, void *pAux,
- int argc, const char *const*argv,
- sqlite3_vtab **ppVTab, char**);
- int (*xBestIndex)(sqlite3_vtab *pVTab, sqlite3_index_info*);
- int (*xDisconnect)(sqlite3_vtab *pVTab);
- int (*xDestroy)(sqlite3_vtab *pVTab);
- int (*xOpen)(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor);
- int (*xClose)(sqlite3_vtab_cursor*);
- int (*xFilter)(sqlite3_vtab_cursor*, int idxNum, const char *idxStr,
- int argc, sqlite3_value **argv);
- int (*xNext)(sqlite3_vtab_cursor*);
- int (*xEof)(sqlite3_vtab_cursor*);
- int (*xColumn)(sqlite3_vtab_cursor*, sqlite3_context*, int);
- int (*xRowid)(sqlite3_vtab_cursor*, sqlite3_int64 *pRowid);
- int (*xUpdate)(sqlite3_vtab *, int, sqlite3_value **, sqlite3_int64 *);
- int (*xBegin)(sqlite3_vtab *pVTab);
- int (*xSync)(sqlite3_vtab *pVTab);
- int (*xCommit)(sqlite3_vtab *pVTab);
- int (*xRollback)(sqlite3_vtab *pVTab);
- int (*xFindFunction)(sqlite3_vtab *pVtab, int nArg, const char *zName,
- void (**pxFunc)(sqlite3_context*,int,sqlite3_value**),
- void **ppArg);
- int (*xRename)(sqlite3_vtab *pVtab, const char *zNew);
-};
-
-/*
-** CAPI3REF: Virtual Table Indexing Information {H18100} <S20400>
-** KEYWORDS: sqlite3_index_info
-** EXPERIMENTAL
-**
-** The sqlite3_index_info structure and its substructures is used to
-** pass information into and receive the reply from the [xBestIndex]
-** method of a [virtual table module]. The fields under **Inputs** are the
-** inputs to xBestIndex and are read-only. xBestIndex inserts its
-** results into the **Outputs** fields.
-**
-** The aConstraint[] array records WHERE clause constraints of the form:
-**
-** <pre>column OP expr</pre>
-**
-** where OP is =, &lt;, &lt;=, &gt;, or &gt;=. The particular operator is
-** stored in aConstraint[].op. The index of the column is stored in
-** aConstraint[].iColumn. aConstraint[].usable is TRUE if the
-** expr on the right-hand side can be evaluated (and thus the constraint
-** is usable) and false if it cannot.
-**
-** The optimizer automatically inverts terms of the form "expr OP column"
-** and makes other simplifications to the WHERE clause in an attempt to
-** get as many WHERE clause terms into the form shown above as possible.
-** The aConstraint[] array only reports WHERE clause terms in the correct
-** form that refer to the particular virtual table being queried.
-**
-** Information about the ORDER BY clause is stored in aOrderBy[].
-** Each term of aOrderBy records a column of the ORDER BY clause.
-**
-** The [xBestIndex] method must fill aConstraintUsage[] with information
-** about what parameters to pass to xFilter. If argvIndex>0 then
-** the right-hand side of the corresponding aConstraint[] is evaluated
-** and becomes the argvIndex-th entry in argv. If aConstraintUsage[].omit
-** is true, then the constraint is assumed to be fully handled by the
-** virtual table and is not checked again by SQLite.
-**
-** The idxNum and idxPtr values are recorded and passed into the
-** [xFilter] method.
-** [sqlite3_free()] is used to free idxPtr if and only iff
-** needToFreeIdxPtr is true.
-**
-** The orderByConsumed means that output from [xFilter]/[xNext] will occur in
-** the correct order to satisfy the ORDER BY clause so that no separate
-** sorting step is required.
-**
-** The estimatedCost value is an estimate of the cost of doing the
-** particular lookup. A full scan of a table with N entries should have
-** a cost of N. A binary search of a table of N entries should have a
-** cost of approximately log(N).
-*/
-struct sqlite3_index_info {
- /* Inputs */
- int nConstraint; /* Number of entries in aConstraint */
- struct sqlite3_index_constraint {
- int iColumn; /* Column on left-hand side of constraint */
- unsigned char op; /* Constraint operator */
- unsigned char usable; /* True if this constraint is usable */
- int iTermOffset; /* Used internally - xBestIndex should ignore */
- } *aConstraint; /* Table of WHERE clause constraints */
- int nOrderBy; /* Number of terms in the ORDER BY clause */
- struct sqlite3_index_orderby {
- int iColumn; /* Column number */
- unsigned char desc; /* True for DESC. False for ASC. */
- } *aOrderBy; /* The ORDER BY clause */
- /* Outputs */
- struct sqlite3_index_constraint_usage {
- int argvIndex; /* if >0, constraint is part of argv to xFilter */
- unsigned char omit; /* Do not code a test for this constraint */
- } *aConstraintUsage;
- int idxNum; /* Number used to identify the index */
- char *idxStr; /* String, possibly obtained from sqlite3_malloc */
- int needToFreeIdxStr; /* Free idxStr using sqlite3_free() if true */
- int orderByConsumed; /* True if output is already ordered */
- double estimatedCost; /* Estimated cost of using this index */
-};
-#define SQLITE_INDEX_CONSTRAINT_EQ 2
-#define SQLITE_INDEX_CONSTRAINT_GT 4
-#define SQLITE_INDEX_CONSTRAINT_LE 8
-#define SQLITE_INDEX_CONSTRAINT_LT 16
-#define SQLITE_INDEX_CONSTRAINT_GE 32
-#define SQLITE_INDEX_CONSTRAINT_MATCH 64
-
-/*
-** CAPI3REF: Register A Virtual Table Implementation {H18200} <S20400>
-** EXPERIMENTAL
-**
-** This routine is used to register a new [virtual table module] name.
-** Module names must be registered before
-** creating a new [virtual table] using the module, or before using a
-** preexisting [virtual table] for the module.
-**
-** The module name is registered on the [database connection] specified
-** by the first parameter. The name of the module is given by the
-** second parameter. The third parameter is a pointer to
-** the implementation of the [virtual table module]. The fourth
-** parameter is an arbitrary client data pointer that is passed through
-** into the [xCreate] and [xConnect] methods of the virtual table module
-** when a new virtual table is be being created or reinitialized.
-**
-** This interface has exactly the same effect as calling
-** [sqlite3_create_module_v2()] with a NULL client data destructor.
-*/
-SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_create_module(
- sqlite3 *db, /* SQLite connection to register module with */
- const char *zName, /* Name of the module */
- const sqlite3_module *p, /* Methods for the module */
- void *pClientData /* Client data for xCreate/xConnect */
-);
-
-/*
-** CAPI3REF: Register A Virtual Table Implementation {H18210} <S20400>
-** EXPERIMENTAL
-**
-** This routine is identical to the [sqlite3_create_module()] method,
-** except that it has an extra parameter to specify
-** a destructor function for the client data pointer. SQLite will
-** invoke the destructor function (if it is not NULL) when SQLite
-** no longer needs the pClientData pointer.
-*/
-SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_create_module_v2(
- sqlite3 *db, /* SQLite connection to register module with */
- const char *zName, /* Name of the module */
- const sqlite3_module *p, /* Methods for the module */
- void *pClientData, /* Client data for xCreate/xConnect */
- void(*xDestroy)(void*) /* Module destructor function */
-);
-
-/*
-** CAPI3REF: Virtual Table Instance Object {H18010} <S20400>
-** KEYWORDS: sqlite3_vtab
-** EXPERIMENTAL
-**
-** Every [virtual table module] implementation uses a subclass
-** of the following structure to describe a particular instance
-** of the [virtual table]. Each subclass will
-** be tailored to the specific needs of the module implementation.
-** The purpose of this superclass is to define certain fields that are
-** common to all module implementations.
-**
-** Virtual tables methods can set an error message by assigning a
-** string obtained from [sqlite3_mprintf()] to zErrMsg. The method should
-** take care that any prior string is freed by a call to [sqlite3_free()]
-** prior to assigning a new string to zErrMsg. After the error message
-** is delivered up to the client application, the string will be automatically
-** freed by sqlite3_free() and the zErrMsg field will be zeroed.
-*/
-struct sqlite3_vtab {
- const sqlite3_module *pModule; /* The module for this virtual table */
- int nRef; /* NO LONGER USED */
- char *zErrMsg; /* Error message from sqlite3_mprintf() */
- /* Virtual table implementations will typically add additional fields */
-};
-
-/*
-** CAPI3REF: Virtual Table Cursor Object {H18020} <S20400>
-** KEYWORDS: sqlite3_vtab_cursor {virtual table cursor}
-** EXPERIMENTAL
-**
-** Every [virtual table module] implementation uses a subclass of the
-** following structure to describe cursors that point into the
-** [virtual table] and are used
-** to loop through the virtual table. Cursors are created using the
-** [sqlite3_module.xOpen | xOpen] method of the module and are destroyed
-** by the [sqlite3_module.xClose | xClose] method. Cussors are used
-** by the [xFilter], [xNext], [xEof], [xColumn], and [xRowid] methods
-** of the module. Each module implementation will define
-** the content of a cursor structure to suit its own needs.
-**
-** This superclass exists in order to define fields of the cursor that
-** are common to all implementations.
-*/
-struct sqlite3_vtab_cursor {
- sqlite3_vtab *pVtab; /* Virtual table of this cursor */
- /* Virtual table implementations will typically add additional fields */
-};
-
-/*
-** CAPI3REF: Declare The Schema Of A Virtual Table {H18280} <S20400>
-** EXPERIMENTAL
-**
-** The [xCreate] and [xConnect] methods of a
-** [virtual table module] call this interface
-** to declare the format (the names and datatypes of the columns) of
-** the virtual tables they implement.
-*/
-SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_declare_vtab(sqlite3*, const char *zSQL);
-
-/*
-** CAPI3REF: Overload A Function For A Virtual Table {H18300} <S20400>
-** EXPERIMENTAL
-**
-** Virtual tables can provide alternative implementations of functions
-** using the [xFindFunction] method of the [virtual table module].
-** But global versions of those functions
-** must exist in order to be overloaded.
-**
-** This API makes sure a global version of a function with a particular
-** name and number of parameters exists. If no such function exists
-** before this API is called, a new function is created. The implementation
-** of the new function always causes an exception to be thrown. So
-** the new function is not good for anything by itself. Its only
-** purpose is to be a placeholder function that can be overloaded
-** by a [virtual table].
-*/
-SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_overload_function(sqlite3*, const char *zFuncName, int nArg);
-
-/*
-** The interface to the virtual-table mechanism defined above (back up
-** to a comment remarkably similar to this one) is currently considered
-** to be experimental. The interface might change in incompatible ways.
-** If this is a problem for you, do not use the interface at this time.
-**
-** When the virtual-table mechanism stabilizes, we will declare the
-** interface fixed, support it indefinitely, and remove this comment.
-**
-****** EXPERIMENTAL - subject to change without notice **************
-*/
-
-/*
-** CAPI3REF: A Handle To An Open BLOB {H17800} <S30230>
-** KEYWORDS: {BLOB handle} {BLOB handles}
-**
-** An instance of this object represents an open BLOB on which
-** [sqlite3_blob_open | incremental BLOB I/O] can be performed.
-** Objects of this type are created by [sqlite3_blob_open()]
-** and destroyed by [sqlite3_blob_close()].
-** The [sqlite3_blob_read()] and [sqlite3_blob_write()] interfaces
-** can be used to read or write small subsections of the BLOB.
-** The [sqlite3_blob_bytes()] interface returns the size of the BLOB in bytes.
-*/
-typedef struct sqlite3_blob sqlite3_blob;
-
-/*
-** CAPI3REF: Open A BLOB For Incremental I/O {H17810} <S30230>
-**
-** This interfaces opens a [BLOB handle | handle] to the BLOB located
-** in row iRow, column zColumn, table zTable in database zDb;
-** in other words, the same BLOB that would be selected by:
-**
-** <pre>
-** SELECT zColumn FROM zDb.zTable WHERE [rowid] = iRow;
-** </pre> {END}
-**
-** If the flags parameter is non-zero, then the BLOB is opened for read
-** and write access. If it is zero, the BLOB is opened for read access.
-**
-** Note that the database name is not the filename that contains
-** the database but rather the symbolic name of the database that
-** is assigned when the database is connected using [ATTACH].
-** For the main database file, the database name is "main".
-** For TEMP tables, the database name is "temp".
-**
-** On success, [SQLITE_OK] is returned and the new [BLOB handle] is written
-** to *ppBlob. Otherwise an [error code] is returned and *ppBlob is set
-** to be a null pointer.
-** This function sets the [database connection] error code and message
-** accessible via [sqlite3_errcode()] and [sqlite3_errmsg()] and related
-** functions. Note that the *ppBlob variable is always initialized in a
-** way that makes it safe to invoke [sqlite3_blob_close()] on *ppBlob
-** regardless of the success or failure of this routine.
-**
-** If the row that a BLOB handle points to is modified by an
-** [UPDATE], [DELETE], or by [ON CONFLICT] side-effects
-** then the BLOB handle is marked as "expired".
-** This is true if any column of the row is changed, even a column
-** other than the one the BLOB handle is open on.
-** Calls to [sqlite3_blob_read()] and [sqlite3_blob_write()] for
-** a expired BLOB handle fail with an return code of [SQLITE_ABORT].
-** Changes written into a BLOB prior to the BLOB expiring are not
-** rollback by the expiration of the BLOB. Such changes will eventually
-** commit if the transaction continues to completion.
-**
-** Use the [sqlite3_blob_bytes()] interface to determine the size of
-** the opened blob. The size of a blob may not be changed by this
-** interface. Use the [UPDATE] SQL command to change the size of a
-** blob.
-**
-** The [sqlite3_bind_zeroblob()] and [sqlite3_result_zeroblob()] interfaces
-** and the built-in [zeroblob] SQL function can be used, if desired,
-** to create an empty, zero-filled blob in which to read or write using
-** this interface.
-**
-** To avoid a resource leak, every open [BLOB handle] should eventually
-** be released by a call to [sqlite3_blob_close()].
-**
-** Requirements:
-** [H17813] [H17814] [H17816] [H17819] [H17821] [H17824]
-*/
-SQLITE_API int sqlite3_blob_open(
- sqlite3*,
- const char *zDb,
- const char *zTable,
- const char *zColumn,
- sqlite3_int64 iRow,
- int flags,
- sqlite3_blob **ppBlob
-);
-
-/*
-** CAPI3REF: Close A BLOB Handle {H17830} <S30230>
-**
-** Closes an open [BLOB handle].
-**
-** Closing a BLOB shall cause the current transaction to commit
-** if there are no other BLOBs, no pending prepared statements, and the
-** database connection is in [autocommit mode].
-** If any writes were made to the BLOB, they might be held in cache
-** until the close operation if they will fit.
-**
-** Closing the BLOB often forces the changes
-** out to disk and so if any I/O errors occur, they will likely occur
-** at the time when the BLOB is closed. Any errors that occur during
-** closing are reported as a non-zero return value.
-**
-** The BLOB is closed unconditionally. Even if this routine returns
-** an error code, the BLOB is still closed.
-**
-** Calling this routine with a null pointer (which as would be returned
-** by failed call to [sqlite3_blob_open()]) is a harmless no-op.
-**
-** Requirements:
-** [H17833] [H17836] [H17839]
-*/
-SQLITE_API int sqlite3_blob_close(sqlite3_blob *);
-
-/*
-** CAPI3REF: Return The Size Of An Open BLOB {H17840} <S30230>
-**
-** Returns the size in bytes of the BLOB accessible via the
-** successfully opened [BLOB handle] in its only argument. The
-** incremental blob I/O routines can only read or overwriting existing
-** blob content; they cannot change the size of a blob.
-**
-** This routine only works on a [BLOB handle] which has been created
-** by a prior successful call to [sqlite3_blob_open()] and which has not
-** been closed by [sqlite3_blob_close()]. Passing any other pointer in
-** to this routine results in undefined and probably undesirable behavior.
-**
-** Requirements:
-** [H17843]
-*/
-SQLITE_API int sqlite3_blob_bytes(sqlite3_blob *);
-
-/*
-** CAPI3REF: Read Data From A BLOB Incrementally {H17850} <S30230>
-**
-** This function is used to read data from an open [BLOB handle] into a
-** caller-supplied buffer. N bytes of data are copied into buffer Z
-** from the open BLOB, starting at offset iOffset.
-**
-** If offset iOffset is less than N bytes from the end of the BLOB,
-** [SQLITE_ERROR] is returned and no data is read. If N or iOffset is
-** less than zero, [SQLITE_ERROR] is returned and no data is read.
-** The size of the blob (and hence the maximum value of N+iOffset)
-** can be determined using the [sqlite3_blob_bytes()] interface.
-**
-** An attempt to read from an expired [BLOB handle] fails with an
-** error code of [SQLITE_ABORT].
-**
-** On success, SQLITE_OK is returned.
-** Otherwise, an [error code] or an [extended error code] is returned.
-**
-** This routine only works on a [BLOB handle] which has been created
-** by a prior successful call to [sqlite3_blob_open()] and which has not
-** been closed by [sqlite3_blob_close()]. Passing any other pointer in
-** to this routine results in undefined and probably undesirable behavior.
-**
-** See also: [sqlite3_blob_write()].
-**
-** Requirements:
-** [H17853] [H17856] [H17859] [H17862] [H17863] [H17865] [H17868]
-*/
-SQLITE_API int sqlite3_blob_read(sqlite3_blob *, void *Z, int N, int iOffset);
-
-/*
-** CAPI3REF: Write Data Into A BLOB Incrementally {H17870} <S30230>
-**
-** This function is used to write data into an open [BLOB handle] from a
-** caller-supplied buffer. N bytes of data are copied from the buffer Z
-** into the open BLOB, starting at offset iOffset.
-**
-** If the [BLOB handle] passed as the first argument was not opened for
-** writing (the flags parameter to [sqlite3_blob_open()] was zero),
-** this function returns [SQLITE_READONLY].
-**
-** This function may only modify the contents of the BLOB; it is
-** not possible to increase the size of a BLOB using this API.
-** If offset iOffset is less than N bytes from the end of the BLOB,
-** [SQLITE_ERROR] is returned and no data is written. If N is
-** less than zero [SQLITE_ERROR] is returned and no data is written.
-** The size of the BLOB (and hence the maximum value of N+iOffset)
-** can be determined using the [sqlite3_blob_bytes()] interface.
-**
-** An attempt to write to an expired [BLOB handle] fails with an
-** error code of [SQLITE_ABORT]. Writes to the BLOB that occurred
-** before the [BLOB handle] expired are not rolled back by the
-** expiration of the handle, though of course those changes might
-** have been overwritten by the statement that expired the BLOB handle
-** or by other independent statements.
-**
-** On success, SQLITE_OK is returned.
-** Otherwise, an [error code] or an [extended error code] is returned.
-**
-** This routine only works on a [BLOB handle] which has been created
-** by a prior successful call to [sqlite3_blob_open()] and which has not
-** been closed by [sqlite3_blob_close()]. Passing any other pointer in
-** to this routine results in undefined and probably undesirable behavior.
-**
-** See also: [sqlite3_blob_read()].
-**
-** Requirements:
-** [H17873] [H17874] [H17875] [H17876] [H17877] [H17879] [H17882] [H17885]
-** [H17888]
-*/
-SQLITE_API int sqlite3_blob_write(sqlite3_blob *, const void *z, int n, int iOffset);
-
-/*
-** CAPI3REF: Virtual File System Objects {H11200} <S20100>
-**
-** A virtual filesystem (VFS) is an [sqlite3_vfs] object
-** that SQLite uses to interact
-** with the underlying operating system. Most SQLite builds come with a
-** single default VFS that is appropriate for the host computer.
-** New VFSes can be registered and existing VFSes can be unregistered.
-** The following interfaces are provided.
-**
-** The sqlite3_vfs_find() interface returns a pointer to a VFS given its name.
-** Names are case sensitive.
-** Names are zero-terminated UTF-8 strings.
-** If there is no match, a NULL pointer is returned.
-** If zVfsName is NULL then the default VFS is returned.
-**
-** New VFSes are registered with sqlite3_vfs_register().
-** Each new VFS becomes the default VFS if the makeDflt flag is set.
-** The same VFS can be registered multiple times without injury.
-** To make an existing VFS into the default VFS, register it again
-** with the makeDflt flag set. If two different VFSes with the
-** same name are registered, the behavior is undefined. If a
-** VFS is registered with a name that is NULL or an empty string,
-** then the behavior is undefined.
-**
-** Unregister a VFS with the sqlite3_vfs_unregister() interface.
-** If the default VFS is unregistered, another VFS is chosen as
-** the default. The choice for the new VFS is arbitrary.
-**
-** Requirements:
-** [H11203] [H11206] [H11209] [H11212] [H11215] [H11218]
-*/
-SQLITE_API sqlite3_vfs *sqlite3_vfs_find(const char *zVfsName);
-SQLITE_API int sqlite3_vfs_register(sqlite3_vfs*, int makeDflt);
-SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*);
-
-/*
-** CAPI3REF: Mutexes {H17000} <S20000>
-**
-** The SQLite core uses these routines for thread
-** synchronization. Though they are intended for internal
-** use by SQLite, code that links against SQLite is
-** permitted to use any of these routines.
-**
-** The SQLite source code contains multiple implementations
-** of these mutex routines. An appropriate implementation
-** is selected automatically at compile-time. The following
-** implementations are available in the SQLite core:
-**
-** <ul>
-** <li> SQLITE_MUTEX_OS2
-** <li> SQLITE_MUTEX_PTHREAD
-** <li> SQLITE_MUTEX_W32
-** <li> SQLITE_MUTEX_NOOP
-** </ul>
-**
-** 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
-** are appropriate for use on OS/2, Unix, and Windows.
-**
-** If SQLite is compiled with the SQLITE_MUTEX_APPDEF preprocessor
-** macro defined (with "-DSQLITE_MUTEX_APPDEF=1"), then no mutex
-** implementation is included with the library. In this case the
-** application must supply a custom mutex implementation using the
-** [SQLITE_CONFIG_MUTEX] option of the sqlite3_config() function
-** before calling sqlite3_initialize() or any other public sqlite3_
-** function that calls sqlite3_initialize().
-**
-** {H17011} The sqlite3_mutex_alloc() routine allocates a new
-** mutex and returns a pointer to it. {H17012} If it returns NULL
-** that means that a mutex could not be allocated. {H17013} SQLite
-** will unwind its stack and return an error. {H17014} The argument
-** to sqlite3_mutex_alloc() is one of these integer constants:
-**
-** <ul>
-** <li> SQLITE_MUTEX_FAST
-** <li> SQLITE_MUTEX_RECURSIVE
-** <li> SQLITE_MUTEX_STATIC_MASTER
-** <li> SQLITE_MUTEX_STATIC_MEM
-** <li> SQLITE_MUTEX_STATIC_MEM2
-** <li> SQLITE_MUTEX_STATIC_PRNG
-** <li> SQLITE_MUTEX_STATIC_LRU
-** <li> SQLITE_MUTEX_STATIC_LRU2
-** </ul>
-**
-** {H17015} The first two constants cause sqlite3_mutex_alloc() to create
-** a new mutex. The new mutex is recursive when SQLITE_MUTEX_RECURSIVE
-** is used but not necessarily so when SQLITE_MUTEX_FAST is used. {END}
-** The mutex implementation does not need to make a distinction
-** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does
-** not want to. {H17016} But SQLite will only request a recursive mutex in
-** cases where it really needs one. {END} If a faster non-recursive mutex
-** implementation is available on the host platform, the mutex subsystem
-** might return such a mutex in response to SQLITE_MUTEX_FAST.
-**
-** {H17017} The other allowed parameters to sqlite3_mutex_alloc() each return
-** a pointer to a static preexisting mutex. {END} Six static mutexes are
-** used by the current version of SQLite. Future versions of SQLite
-** may add additional static mutexes. Static mutexes are for internal
-** use by SQLite only. Applications that use SQLite mutexes should
-** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or
-** SQLITE_MUTEX_RECURSIVE.
-**
-** {H17018} Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST
-** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc()
-** returns a different mutex on every call. {H17034} But for the static
-** mutex types, the same mutex is returned on every call that has
-** the same type number.
-**
-** {H17019} The sqlite3_mutex_free() routine deallocates a previously
-** allocated dynamic mutex. {H17020} SQLite is careful to deallocate every
-** dynamic mutex that it allocates. {A17021} The dynamic mutexes must not be in
-** use when they are deallocated. {A17022} Attempting to deallocate a static
-** mutex results in undefined behavior. {H17023} SQLite never deallocates
-** a static mutex. {END}
-**
-** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt
-** to enter a mutex. {H17024} If another thread is already within the mutex,
-** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return
-** SQLITE_BUSY. {H17025} The sqlite3_mutex_try() interface returns [SQLITE_OK]
-** upon successful entry. {H17026} Mutexes created using
-** SQLITE_MUTEX_RECURSIVE can be entered multiple times by the same thread.
-** {H17027} In such cases the,
-** mutex must be exited an equal number of times before another thread
-** can enter. {A17028} If the same thread tries to enter any other
-** kind of mutex more than once, the behavior is undefined.
-** {H17029} SQLite will never exhibit
-** such behavior in its own use of mutexes.
-**
-** Some systems (for example, Windows 95) do not support the operation
-** implemented by sqlite3_mutex_try(). On those systems, sqlite3_mutex_try()
-** will always return SQLITE_BUSY. {H17030} The SQLite core only ever uses
-** sqlite3_mutex_try() as an optimization so this is acceptable behavior.
-**
-** {H17031} The sqlite3_mutex_leave() routine exits a mutex that was
-** previously entered by the same thread. {A17032} The behavior
-** is undefined if the mutex is not currently entered by the
-** calling thread or is not currently allocated. {H17033} SQLite will
-** never do either. {END}
-**
-** If the argument to sqlite3_mutex_enter(), sqlite3_mutex_try(), or
-** sqlite3_mutex_leave() is a NULL pointer, then all three routines
-** behave as no-ops.
-**
-** See also: [sqlite3_mutex_held()] and [sqlite3_mutex_notheld()].
-*/
-SQLITE_API sqlite3_mutex *sqlite3_mutex_alloc(int);
-SQLITE_API void sqlite3_mutex_free(sqlite3_mutex*);
-SQLITE_API void sqlite3_mutex_enter(sqlite3_mutex*);
-SQLITE_API int sqlite3_mutex_try(sqlite3_mutex*);
-SQLITE_API void sqlite3_mutex_leave(sqlite3_mutex*);
-
-/*
-** CAPI3REF: Mutex Methods Object {H17120} <S20130>
-** EXPERIMENTAL
-**
-** An instance of this structure defines the low-level routines
-** used to allocate and use mutexes.
-**
-** Usually, the default mutex implementations provided by SQLite are
-** sufficient, however the user has the option of substituting a custom
-** implementation for specialized deployments or systems for which SQLite
-** does not provide a suitable implementation. In this case, the user
-** creates and populates an instance of this structure to pass
-** to sqlite3_config() along with the [SQLITE_CONFIG_MUTEX] option.
-** Additionally, an instance of this structure can be used as an
-** output variable when querying the system for the current mutex
-** implementation, using the [SQLITE_CONFIG_GETMUTEX] option.
-**
-** The xMutexInit method defined by this structure is invoked as
-** part of system initialization by the sqlite3_initialize() function.
-** {H17001} The xMutexInit routine shall be called by SQLite once for each
-** effective call to [sqlite3_initialize()].
-**
-** The xMutexEnd method defined by this structure is invoked as
-** part of system shutdown by the sqlite3_shutdown() function. The
-** implementation of this method is expected to release all outstanding
-** resources obtained by the mutex methods implementation, especially
-** those obtained by the xMutexInit method. {H17003} The xMutexEnd()
-** interface shall be invoked once for each call to [sqlite3_shutdown()].
-**
-** The remaining seven methods defined by this structure (xMutexAlloc,
-** xMutexFree, xMutexEnter, xMutexTry, xMutexLeave, xMutexHeld and
-** xMutexNotheld) implement the following interfaces (respectively):
-**
-** <ul>
-** <li> [sqlite3_mutex_alloc()] </li>
-** <li> [sqlite3_mutex_free()] </li>
-** <li> [sqlite3_mutex_enter()] </li>
-** <li> [sqlite3_mutex_try()] </li>
-** <li> [sqlite3_mutex_leave()] </li>
-** <li> [sqlite3_mutex_held()] </li>
-** <li> [sqlite3_mutex_notheld()] </li>
-** </ul>
-**
-** The only difference is that the public sqlite3_XXX functions enumerated
-** above silently ignore any invocations that pass a NULL pointer instead
-** of a valid mutex handle. The implementations of the methods defined
-** by this structure are not required to handle this case, the results
-** of passing a NULL pointer instead of a valid mutex handle are undefined
-** (i.e. it is acceptable to provide an implementation that segfaults if
-** it is passed a NULL pointer).
-**
-** The xMutexInit() method must be threadsafe. It must be harmless to
-** invoke xMutexInit() mutiple times within the same process and without
-** intervening calls to xMutexEnd(). Second and subsequent calls to
-** xMutexInit() must be no-ops.
-**
-** xMutexInit() must not use SQLite memory allocation ([sqlite3_malloc()]
-** and its associates). Similarly, xMutexAlloc() must not use SQLite memory
-** allocation for a static mutex. However xMutexAlloc() may use SQLite
-** memory allocation for a fast or recursive mutex.
-**
-** SQLite will invoke the xMutexEnd() method when [sqlite3_shutdown()] is
-** called, but only if the prior call to xMutexInit returned SQLITE_OK.
-** If xMutexInit fails in any way, it is expected to clean up after itself
-** prior to returning.
-*/
-typedef struct sqlite3_mutex_methods sqlite3_mutex_methods;
-struct sqlite3_mutex_methods {
- int (*xMutexInit)(void);
- int (*xMutexEnd)(void);
- sqlite3_mutex *(*xMutexAlloc)(int);
- void (*xMutexFree)(sqlite3_mutex *);
- void (*xMutexEnter)(sqlite3_mutex *);
- int (*xMutexTry)(sqlite3_mutex *);
- void (*xMutexLeave)(sqlite3_mutex *);
- int (*xMutexHeld)(sqlite3_mutex *);
- int (*xMutexNotheld)(sqlite3_mutex *);
-};
-
-/*
-** CAPI3REF: Mutex Verification Routines {H17080} <S20130> <S30800>
-**
-** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routines
-** are intended for use inside assert() statements. {H17081} The SQLite core
-** never uses these routines except inside an assert() and applications
-** are advised to follow the lead of the core. {H17082} The core only
-** provides implementations for these routines when it is compiled
-** with the SQLITE_DEBUG flag. {A17087} External mutex implementations
-** are only required to provide these routines if SQLITE_DEBUG is
-** defined and if NDEBUG is not defined.
-**
-** {H17083} These routines should return true if the mutex in their argument
-** is held or not held, respectively, by the calling thread.
-**
-** {X17084} The implementation is not required to provided 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.
-**
-** {H17085} If the argument to sqlite3_mutex_held() is a NULL pointer then
-** the routine should return 1. {END} This seems counter-intuitive since
-** clearly the mutex cannot be held if it does not exist. But the
-** the reason the mutex does not exist is because the build is not
-** using mutexes. And we do not want the assert() containing the
-** call to sqlite3_mutex_held() to fail, so a non-zero return is
-** the appropriate thing to do. {H17086} The sqlite3_mutex_notheld()
-** interface should also return 1 when given a NULL pointer.
-*/
-SQLITE_API int sqlite3_mutex_held(sqlite3_mutex*);
-SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex*);
-
-/*
-** CAPI3REF: Mutex Types {H17001} <H17000>
-**
-** The [sqlite3_mutex_alloc()] interface takes a single argument
-** which is one of these integer constants.
-**
-** The set of static mutexes may change from one SQLite release to the
-** next. Applications that override the built-in mutex logic must be
-** prepared to accommodate additional static mutexes.
-*/
-#define SQLITE_MUTEX_FAST 0
-#define SQLITE_MUTEX_RECURSIVE 1
-#define SQLITE_MUTEX_STATIC_MASTER 2
-#define SQLITE_MUTEX_STATIC_MEM 3 /* sqlite3_malloc() */
-#define SQLITE_MUTEX_STATIC_MEM2 4 /* NOT USED */
-#define SQLITE_MUTEX_STATIC_OPEN 4 /* sqlite3BtreeOpen() */
-#define SQLITE_MUTEX_STATIC_PRNG 5 /* sqlite3_random() */
-#define SQLITE_MUTEX_STATIC_LRU 6 /* lru page list */
-#define SQLITE_MUTEX_STATIC_LRU2 7 /* lru page list */
-
-/*
-** CAPI3REF: Retrieve the mutex for a database connection {H17002} <H17000>
-**
-** This interface returns a pointer the [sqlite3_mutex] object that
-** serializes access to the [database connection] given in the argument
-** when the [threading mode] is Serialized.
-** If the [threading mode] is Single-thread or Multi-thread then this
-** routine returns a NULL pointer.
-*/
-SQLITE_API sqlite3_mutex *sqlite3_db_mutex(sqlite3*);
-
-/*
-** CAPI3REF: Low-Level Control Of Database Files {H11300} <S30800>
-**
-** {H11301} The [sqlite3_file_control()] interface makes a direct call to the
-** xFileControl method for the [sqlite3_io_methods] object associated
-** with a particular database identified by the second argument. {H11302} The
-** name of the database is the name assigned to the database by the
-** <a href="lang_attach.html">ATTACH</a> SQL command that opened the
-** database. {H11303} To control the main database file, use the name "main"
-** or a NULL pointer. {H11304} The third and fourth parameters to this routine
-** are passed directly through to the second and third parameters of
-** the xFileControl method. {H11305} The return value of the xFileControl
-** method becomes the return value of this routine.
-**
-** {H11306} If the second parameter (zDbName) does not match the name of any
-** open database file, then SQLITE_ERROR is returned. {H11307} This error
-** code is not remembered and will not be recalled by [sqlite3_errcode()]
-** or [sqlite3_errmsg()]. {A11308} The underlying xFileControl method might
-** also return SQLITE_ERROR. {A11309} There is no way to distinguish between
-** an incorrect zDbName and an SQLITE_ERROR return from the underlying
-** xFileControl method. {END}
-**
-** See also: [SQLITE_FCNTL_LOCKSTATE]
-*/
-SQLITE_API int sqlite3_file_control(sqlite3*, const char *zDbName, int op, void*);
-
-/*
-** CAPI3REF: Testing Interface {H11400} <S30800>
-**
-** The sqlite3_test_control() interface is used to read out internal
-** state of SQLite and to inject faults into SQLite for testing
-** purposes. The first parameter is an operation code that determines
-** the number, meaning, and operation of all subsequent parameters.
-**
-** This interface is not for use by applications. It exists solely
-** for verifying the correct operation of the SQLite library. Depending
-** on how the SQLite library is compiled, this interface might not exist.
-**
-** The details of the operation codes, their meanings, the parameters
-** they take, and what they do are all subject to change without notice.
-** Unlike most of the SQLite API, this function is not guaranteed to
-** operate consistently from one release to the next.
-*/
-SQLITE_API int sqlite3_test_control(int op, ...);
-
-/*
-** CAPI3REF: Testing Interface Operation Codes {H11410} <H11400>
-**
-** These constants are the valid operation code parameters used
-** as the first argument to [sqlite3_test_control()].
-**
-** These parameters and their meanings are subject to change
-** without notice. These values are for testing purposes only.
-** Applications should not use any of these parameters or the
-** [sqlite3_test_control()] interface.
-*/
-#define SQLITE_TESTCTRL_PRNG_SAVE 5
-#define SQLITE_TESTCTRL_PRNG_RESTORE 6
-#define SQLITE_TESTCTRL_PRNG_RESET 7
-#define SQLITE_TESTCTRL_BITVEC_TEST 8
-#define SQLITE_TESTCTRL_FAULT_INSTALL 9
-#define SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS 10
-#define SQLITE_TESTCTRL_PENDING_BYTE 11
-#define SQLITE_TESTCTRL_ASSERT 12
-#define SQLITE_TESTCTRL_ALWAYS 13
-#define SQLITE_TESTCTRL_RESERVE 14
-
-/*
-** CAPI3REF: SQLite Runtime Status {H17200} <S60200>
-** EXPERIMENTAL
-**
-** This interface is used to retrieve runtime status information
-** about the preformance of SQLite, and optionally to reset various
-** highwater marks. The first argument is an integer code for
-** the specific parameter to measure. Recognized integer codes
-** are of the form [SQLITE_STATUS_MEMORY_USED | SQLITE_STATUS_...].
-** The current value of the parameter is returned into *pCurrent.
-** The highest recorded value is returned in *pHighwater. If the
-** resetFlag is true, then the highest record value is reset after
-** *pHighwater is written. Some parameters do not record the highest
-** value. For those parameters
-** nothing is written into *pHighwater and the resetFlag is ignored.
-** Other parameters record only the highwater mark and not the current
-** value. For these latter parameters nothing is written into *pCurrent.
-**
-** This routine returns SQLITE_OK on success and a non-zero
-** [error code] on failure.
-**
-** This routine is threadsafe but is not atomic. This routine can be
-** called while other threads are running the same or different SQLite
-** interfaces. However the values returned in *pCurrent and
-** *pHighwater reflect the status of SQLite at different points in time
-** and it is possible that another thread might change the parameter
-** in between the times when *pCurrent and *pHighwater are written.
-**
-** See also: [sqlite3_db_status()]
-*/
-SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag);
-
-
-/*
-** CAPI3REF: Status Parameters {H17250} <H17200>
-** EXPERIMENTAL
-**
-** These integer constants designate various run-time status parameters
-** that can be returned by [sqlite3_status()].
-**
-** <dl>
-** <dt>SQLITE_STATUS_MEMORY_USED</dt>
-** <dd>This parameter is the current amount of memory checked out
-** using [sqlite3_malloc()], either directly or indirectly. The
-** figure includes calls made to [sqlite3_malloc()] by the application
-** and internal memory usage by the SQLite library. Scratch memory
-** controlled by [SQLITE_CONFIG_SCRATCH] and auxiliary page-cache
-** memory controlled by [SQLITE_CONFIG_PAGECACHE] is not included in
-** this parameter. The amount returned is the sum of the allocation
-** sizes as reported by the xSize method in [sqlite3_mem_methods].</dd>
-**
-** <dt>SQLITE_STATUS_MALLOC_SIZE</dt>
-** <dd>This parameter records the largest memory allocation request
-** handed to [sqlite3_malloc()] or [sqlite3_realloc()] (or their
-** internal equivalents). Only the value returned in the
-** *pHighwater parameter to [sqlite3_status()] is of interest.
-** The value written into the *pCurrent parameter is undefined.</dd>
-**
-** <dt>SQLITE_STATUS_PAGECACHE_USED</dt>
-** <dd>This parameter returns the number of pages used out of the
-** [pagecache memory allocator] that was configured using
-** [SQLITE_CONFIG_PAGECACHE]. The
-** value returned is in pages, not in bytes.</dd>
-**
-** <dt>SQLITE_STATUS_PAGECACHE_OVERFLOW</dt>
-** <dd>This parameter returns the number of bytes of page cache
-** allocation which could not be statisfied by the [SQLITE_CONFIG_PAGECACHE]
-** buffer and where forced to overflow to [sqlite3_malloc()]. The
-** returned value includes allocations that overflowed because they
-** where too large (they were larger than the "sz" parameter to
-** [SQLITE_CONFIG_PAGECACHE]) and allocations that overflowed because
-** no space was left in the page cache.</dd>
-**
-** <dt>SQLITE_STATUS_PAGECACHE_SIZE</dt>
-** <dd>This parameter records the largest memory allocation request
-** handed to [pagecache memory allocator]. Only the value returned in the
-** *pHighwater parameter to [sqlite3_status()] is of interest.
-** The value written into the *pCurrent parameter is undefined.</dd>
-**
-** <dt>SQLITE_STATUS_SCRATCH_USED</dt>
-** <dd>This parameter returns the number of allocations used out of the
-** [scratch memory allocator] configured using
-** [SQLITE_CONFIG_SCRATCH]. The value returned is in allocations, not
-** in bytes. Since a single thread may only have one scratch allocation
-** outstanding at time, this parameter also reports the number of threads
-** using scratch memory at the same time.</dd>
-**
-** <dt>SQLITE_STATUS_SCRATCH_OVERFLOW</dt>
-** <dd>This parameter returns the number of bytes of scratch memory
-** allocation which could not be statisfied by the [SQLITE_CONFIG_SCRATCH]
-** buffer and where forced to overflow to [sqlite3_malloc()]. The values
-** returned include overflows because the requested allocation was too
-** larger (that is, because the requested allocation was larger than the
-** "sz" parameter to [SQLITE_CONFIG_SCRATCH]) and because no scratch buffer
-** slots were available.
-** </dd>
-**
-** <dt>SQLITE_STATUS_SCRATCH_SIZE</dt>
-** <dd>This parameter records the largest memory allocation request
-** handed to [scratch memory allocator]. Only the value returned in the
-** *pHighwater parameter to [sqlite3_status()] is of interest.
-** The value written into the *pCurrent parameter is undefined.</dd>
-**
-** <dt>SQLITE_STATUS_PARSER_STACK</dt>
-** <dd>This parameter records the deepest parser stack. It is only
-** meaningful if SQLite is compiled with [YYTRACKMAXSTACKDEPTH].</dd>
-** </dl>
-**
-** New status parameters may be added from time to time.
-*/
-#define SQLITE_STATUS_MEMORY_USED 0
-#define SQLITE_STATUS_PAGECACHE_USED 1
-#define SQLITE_STATUS_PAGECACHE_OVERFLOW 2
-#define SQLITE_STATUS_SCRATCH_USED 3
-#define SQLITE_STATUS_SCRATCH_OVERFLOW 4
-#define SQLITE_STATUS_MALLOC_SIZE 5
-#define SQLITE_STATUS_PARSER_STACK 6
-#define SQLITE_STATUS_PAGECACHE_SIZE 7
-#define SQLITE_STATUS_SCRATCH_SIZE 8
-
-/*
-** CAPI3REF: Database Connection Status {H17500} <S60200>
-** EXPERIMENTAL
-**
-** This interface is used to retrieve runtime status information
-** about a single [database connection]. The first argument is the
-** database connection object to be interrogated. The second argument
-** is the parameter to interrogate. Currently, the only allowed value
-** for the second parameter is [SQLITE_DBSTATUS_LOOKASIDE_USED].
-** Additional options will likely appear in future releases of SQLite.
-**
-** The current value of the requested parameter is written into *pCur
-** and the highest instantaneous value is written into *pHiwtr. If
-** the resetFlg is true, then the highest instantaneous value is
-** reset back down to the current value.
-**
-** See also: [sqlite3_status()] and [sqlite3_stmt_status()].
-*/
-SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg);
-
-/*
-** CAPI3REF: Status Parameters for database connections {H17520} <H17500>
-** EXPERIMENTAL
-**
-** These constants are the available integer "verbs" that can be passed as
-** the second argument to the [sqlite3_db_status()] interface.
-**
-** New verbs may be added in future releases of SQLite. Existing verbs
-** might be discontinued. Applications should check the return code from
-** [sqlite3_db_status()] to make sure that the call worked.
-** The [sqlite3_db_status()] interface will return a non-zero error code
-** if a discontinued or unsupported verb is invoked.
-**
-** <dl>
-** <dt>SQLITE_DBSTATUS_LOOKASIDE_USED</dt>
-** <dd>This parameter returns the number of lookaside memory slots currently
-** checked out.</dd>
-** </dl>
-*/
-#define SQLITE_DBSTATUS_LOOKASIDE_USED 0
-
-
-/*
-** CAPI3REF: Prepared Statement Status {H17550} <S60200>
-** EXPERIMENTAL
-**
-** Each prepared statement maintains various
-** [SQLITE_STMTSTATUS_SORT | counters] that measure the number
-** of times it has performed specific operations. These counters can
-** be used to monitor the performance characteristics of the prepared
-** statements. For example, if the number of table steps greatly exceeds
-** the number of table searches or result rows, that would tend to indicate
-** that the prepared statement is using a full table scan rather than
-** an index.
-**
-** This interface is used to retrieve and reset counter values from
-** a [prepared statement]. The first argument is the prepared statement
-** object to be interrogated. The second argument
-** is an integer code for a specific [SQLITE_STMTSTATUS_SORT | counter]
-** to be interrogated.
-** The current value of the requested counter is returned.
-** If the resetFlg is true, then the counter is reset to zero after this
-** interface call returns.
-**
-** See also: [sqlite3_status()] and [sqlite3_db_status()].
-*/
-SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg);
-
-/*
-** CAPI3REF: Status Parameters for prepared statements {H17570} <H17550>
-** EXPERIMENTAL
-**
-** These preprocessor macros define integer codes that name counter
-** values associated with the [sqlite3_stmt_status()] interface.
-** The meanings of the various counters are as follows:
-**
-** <dl>
-** <dt>SQLITE_STMTSTATUS_FULLSCAN_STEP</dt>
-** <dd>This is the number of times that SQLite has stepped forward in
-** a table as part of a full table scan. Large numbers for this counter
-** may indicate opportunities for performance improvement through
-** careful use of indices.</dd>
-**
-** <dt>SQLITE_STMTSTATUS_SORT</dt>
-** <dd>This is the number of sort operations that have occurred.
-** A non-zero value in this counter may indicate an opportunity to
-** improvement performance through careful use of indices.</dd>
-**
-** </dl>
-*/
-#define SQLITE_STMTSTATUS_FULLSCAN_STEP 1
-#define SQLITE_STMTSTATUS_SORT 2
-
-/*
-** CAPI3REF: Custom Page Cache Object
-** EXPERIMENTAL
-**
-** The sqlite3_pcache type is opaque. It is implemented by
-** the pluggable module. The SQLite core has no knowledge of
-** its size or internal structure and never deals with the
-** sqlite3_pcache object except by holding and passing pointers
-** to the object.
-**
-** See [sqlite3_pcache_methods] for additional information.
-*/
-typedef struct sqlite3_pcache sqlite3_pcache;
-
-/*
-** CAPI3REF: Application Defined Page Cache.
-** KEYWORDS: {page cache}
-** EXPERIMENTAL
-**
-** The [sqlite3_config]([SQLITE_CONFIG_PCACHE], ...) interface can
-** register an alternative page cache implementation by passing in an
-** instance of the sqlite3_pcache_methods structure. The majority of the
-** heap memory used by SQLite is used by the page cache to cache data read
-** from, or ready to be written to, the database file. By implementing a
-** custom page cache using this API, an application can control more
-** precisely the amount of memory consumed by SQLite, the way in which
-** that memory is allocated and released, and the policies used to
-** determine exactly which parts of a database file are cached and for
-** how long.
-**
-** The contents of the sqlite3_pcache_methods 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.
-**
-** The xInit() method is called once for each call to [sqlite3_initialize()]
-** (usually only once during the lifetime of the process). It is passed
-** a copy of the sqlite3_pcache_methods.pArg value. It can be used to set
-** up global structures and mutexes required by the custom page cache
-** implementation.
-**
-** The xShutdown() method is called from within [sqlite3_shutdown()],
-** if the application invokes this API. It can be used to clean up
-** any outstanding resources before process shutdown, if required.
-**
-** SQLite holds a [SQLITE_MUTEX_RECURSIVE] mutex when it invokes
-** the xInit method, so the xInit method need not be threadsafe. The
-** xShutdown method is only called from [sqlite3_shutdown()] so it does
-** not need to be threadsafe either. All other methods must be threadsafe
-** in multithreaded applications.
-**
-** SQLite will never invoke xInit() more than once without an intervening
-** call to xShutdown().
-**
-** The xCreate() method is used to construct a new cache instance. 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 about 100 or 200. 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
-** on the SQLite version, the target platform, and how SQLite was compiled.
-** R is constant for a particular build of SQLite. 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
-** 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
-** never invoke xUnpin() except to deliberately delete a page.
-** In other words, a cache created with bPurgeable set to false will
-** never contain any unpinned pages.
-**
-** The xCachesize() method may be called at any time by SQLite to set the
-** suggested maximum cache-size (number of pages stored by) the cache
-** instance passed as the first argument. This is the value configured using
-** the SQLite "[PRAGMA cache_size]" command. As with the bPurgeable parameter,
-** the implementation is not required to do anything with this
-** value; it is advisory only.
-**
-** The xPagecount() method should return the number of pages currently
-** stored in the cache.
-**
-** The xFetch() method is used to fetch a page and return a pointer to it.
-** A 'page', in this context, is a buffer of szPage bytes aligned at an
-** 8-byte boundary. The page to be fetched is determined by the key. The
-** mimimum 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
-** intact. If the requested page is not already in the cache, then the
-** behavior of the cache implementation is determined by the value of the
-** createFlag parameter passed to xFetch, according to the following table:
-**
-** <table border=1 width=85% align=center>
-** <tr><th> createFlag <th> Behaviour when page is not already in cache
-** <tr><td> 0 <td> Do not allocate a new page. Return NULL.
-** <tr><td> 1 <td> Allocate a new page if it easy and convenient to do so.
-** Otherwise return NULL.
-** <tr><td> 2 <td> Make every effort to allocate a new page. Only return
-** NULL if allocating a new page is effectively impossible.
-** </table>
-**
-** SQLite will normally invoke xFetch() with a createFlag of 0 or 1. If
-** a call to xFetch() with createFlag==1 returns NULL, then SQLite will
-** attempt to unpin one or more cache pages by spilling the content of
-** pinned pages to disk and synching the operating system disk cache. After
-** attempting to unpin pages, the xFetch() method will be invoked again with
-** a createFlag of 2.
-**
-** xUnpin() is called by SQLite with a pointer to a currently pinned page
-** as its second argument. If the third parameter, discard, is non-zero,
-** then the page should be evicted from the cache. In this case SQLite
-** assumes that the next time the page is retrieved from the cache using
-** the xFetch() method, it will be zeroed. If the discard parameter is
-** zero, then the page is considered to be unpinned. The cache implementation
-** may choose to evict unpinned pages at any time.
-**
-** The cache is not required to perform any reference counting. A single
-** call to xUnpin() unpins the page regardless of the number of prior calls
-** to xFetch().
-**
-** The xRekey() method is used to change the key value associated with the
-** page passed as the second argument from oldKey to newKey. If the cache
-** previously contains an entry associated with newKey, it should be
-** discarded. Any prior cache entry associated with newKey is guaranteed not
-** to be pinned.
-**
-** When SQLite calls the xTruncate() method, the cache must discard all
-** existing cache entries with page numbers (keys) greater than or equal
-** to the value of the iLimit parameter passed to xTruncate(). If any
-** of these pages are pinned, they are implicitly unpinned, meaning that
-** they can be safely discarded.
-**
-** 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
-** functions.
-*/
-typedef struct sqlite3_pcache_methods sqlite3_pcache_methods;
-struct sqlite3_pcache_methods {
- void *pArg;
- int (*xInit)(void*);
- void (*xShutdown)(void*);
- sqlite3_pcache *(*xCreate)(int szPage, int bPurgeable);
- void (*xCachesize)(sqlite3_pcache*, int nCachesize);
- int (*xPagecount)(sqlite3_pcache*);
- void *(*xFetch)(sqlite3_pcache*, unsigned key, int createFlag);
- void (*xUnpin)(sqlite3_pcache*, void*, int discard);
- void (*xRekey)(sqlite3_pcache*, void*, unsigned oldKey, unsigned newKey);
- void (*xTruncate)(sqlite3_pcache*, unsigned iLimit);
- void (*xDestroy)(sqlite3_pcache*);
-};
-
-/*
-** CAPI3REF: Online Backup Object
-** EXPERIMENTAL
-**
-** The sqlite3_backup object records state information about an ongoing
-** online backup operation. The sqlite3_backup object is created by
-** a call to [sqlite3_backup_init()] and is destroyed by a call to
-** [sqlite3_backup_finish()].
-**
-** See Also: [Using the SQLite Online Backup API]
-*/
-typedef struct sqlite3_backup sqlite3_backup;
-
-/*
-** CAPI3REF: Online Backup API.
-** EXPERIMENTAL
-**
-** This API is used to overwrite the contents of one database with that
-** of another. It is useful either for creating backups of databases or
-** for copying in-memory databases to or from persistent files.
-**
-** See Also: [Using the SQLite Online Backup API]
-**
-** Exclusive access is required to the destination database for the
-** duration of the operation. However the source database is only
-** read-locked while it is actually being read, it is not locked
-** continuously for the entire operation. Thus, the backup may be
-** performed on a live database without preventing other users from
-** writing to the database for an extended period of time.
-**
-** To perform a backup operation:
-** <ol>
-** <li><b>sqlite3_backup_init()</b> is called once to initialize the
-** backup,
-** <li><b>sqlite3_backup_step()</b> is called one or more times to transfer
-** the data between the two databases, and finally
-** <li><b>sqlite3_backup_finish()</b> is called to release all resources
-** associated with the backup operation.
-** </ol>
-** There should be exactly one call to sqlite3_backup_finish() for each
-** successful call to sqlite3_backup_init().
-**
-** <b>sqlite3_backup_init()</b>
-**
-** The first two arguments passed to [sqlite3_backup_init()] are the database
-** handle associated with the destination database and the database name
-** used to attach the destination database to the handle. The database name
-** is "main" for the main database, "temp" for the temporary database, or
-** the name specified as part of the [ATTACH] statement if the destination is
-** an attached database. The third and fourth arguments passed to
-** sqlite3_backup_init() identify the [database connection]
-** and database name used
-** to access the source database. The values passed for the source and
-** destination [database connection] parameters must not be the same.
-**
-** If an error occurs within sqlite3_backup_init(), then NULL is returned
-** and an error code and error message written into the [database connection]
-** passed as the first argument. They may be retrieved using the
-** [sqlite3_errcode()], [sqlite3_errmsg()], and [sqlite3_errmsg16()] functions.
-** Otherwise, if successful, a pointer to an [sqlite3_backup] object is
-** returned. This pointer may be used with the sqlite3_backup_step() and
-** sqlite3_backup_finish() functions to perform the specified backup
-** operation.
-**
-** <b>sqlite3_backup_step()</b>
-**
-** Function [sqlite3_backup_step()] is used to copy up to nPage pages between
-** the source and destination databases, where nPage is the value of the
-** second parameter passed to sqlite3_backup_step(). If nPage is a negative
-** value, all remaining source pages are copied. If the required pages are
-** succesfully copied, but there are still more pages to copy before the
-** backup is complete, it returns [SQLITE_OK]. If no error occured and there
-** are no more pages to copy, then [SQLITE_DONE] is returned. If an error
-** occurs, then an SQLite error code is returned. As well as [SQLITE_OK] and
-** [SQLITE_DONE], a call to sqlite3_backup_step() may return [SQLITE_READONLY],
-** [SQLITE_NOMEM], [SQLITE_BUSY], [SQLITE_LOCKED], or an
-** [SQLITE_IOERR_ACCESS | SQLITE_IOERR_XXX] extended error code.
-**
-** As well as the case where the destination database file was opened for
-** read-only access, sqlite3_backup_step() may return [SQLITE_READONLY] if
-** the destination is an in-memory database with a different page size
-** from the source database.
-**
-** If sqlite3_backup_step() cannot obtain a required file-system lock, then
-** the [sqlite3_busy_handler | busy-handler function]
-** is invoked (if one is specified). If the
-** busy-handler returns non-zero before the lock is available, then
-** [SQLITE_BUSY] is returned to the caller. In this case the call to
-** sqlite3_backup_step() can be retried later. If the source
-** [database connection]
-** is being used to write to the source database when sqlite3_backup_step()
-** is called, then [SQLITE_LOCKED] is returned immediately. Again, in this
-** case the call to sqlite3_backup_step() can be retried later on. If
-** [SQLITE_IOERR_ACCESS | SQLITE_IOERR_XXX], [SQLITE_NOMEM], or
-** [SQLITE_READONLY] is returned, then
-** there is no point in retrying the call to sqlite3_backup_step(). These
-** errors are considered fatal. At this point the application must accept
-** that the backup operation has failed and pass the backup operation handle
-** to the sqlite3_backup_finish() to release associated resources.
-**
-** Following the first call to sqlite3_backup_step(), an exclusive lock is
-** obtained on the destination file. It is not released until either
-** sqlite3_backup_finish() is called or the backup operation is complete
-** and sqlite3_backup_step() returns [SQLITE_DONE]. Additionally, each time
-** a call to sqlite3_backup_step() is made a [shared lock] is obtained on
-** the source database file. This lock is released before the
-** sqlite3_backup_step() call returns. Because the source database is not
-** locked between calls to sqlite3_backup_step(), it may be modified mid-way
-** through the backup procedure. If the source database is modified by an
-** external process or via a database connection other than the one being
-** used by the backup operation, then the backup will be transparently
-** restarted by the next call to sqlite3_backup_step(). If the source
-** database is modified by the using the same database connection as is used
-** by the backup operation, then the backup database is transparently
-** updated at the same time.
-**
-** <b>sqlite3_backup_finish()</b>
-**
-** Once sqlite3_backup_step() has returned [SQLITE_DONE], or when the
-** application wishes to abandon the backup operation, the [sqlite3_backup]
-** object should be passed to sqlite3_backup_finish(). This releases all
-** resources associated with the backup operation. If sqlite3_backup_step()
-** has not yet returned [SQLITE_DONE], then any active write-transaction on the
-** destination database is rolled back. The [sqlite3_backup] object is invalid
-** and may not be used following a call to sqlite3_backup_finish().
-**
-** The value returned by sqlite3_backup_finish is [SQLITE_OK] if no error
-** occurred, regardless or whether or not sqlite3_backup_step() was called
-** a sufficient number of times to complete the backup operation. Or, if
-** an out-of-memory condition or IO error occured during a call to
-** sqlite3_backup_step() then [SQLITE_NOMEM] or an
-** [SQLITE_IOERR_ACCESS | SQLITE_IOERR_XXX] error code
-** is returned. In this case the error code and an error message are
-** written to the destination [database connection].
-**
-** A return of [SQLITE_BUSY] or [SQLITE_LOCKED] from sqlite3_backup_step() is
-** not a permanent error and does not affect the return value of
-** sqlite3_backup_finish().
-**
-** <b>sqlite3_backup_remaining(), sqlite3_backup_pagecount()</b>
-**
-** Each call to sqlite3_backup_step() sets two values stored internally
-** by an [sqlite3_backup] object. The number of pages still to be backed
-** up, which may be queried by sqlite3_backup_remaining(), and the total
-** number of pages in the source database file, which may be queried by
-** sqlite3_backup_pagecount().
-**
-** The values returned by these functions are only updated by
-** sqlite3_backup_step(). If the source database is modified during a backup
-** operation, then the values are not updated to account for any extra
-** pages that need to be updated or the size of the source database file
-** changing.
-**
-** <b>Concurrent Usage of Database Handles</b>
-**
-** The source [database connection] may be used by the application for other
-** purposes while a backup operation is underway or being initialized.
-** If SQLite is compiled and configured to support threadsafe database
-** connections, then the source database connection may be used concurrently
-** from within other threads.
-**
-** However, the application must guarantee that the destination database
-** connection handle is not passed to any other API (by any thread) after
-** sqlite3_backup_init() is called and before the corresponding call to
-** sqlite3_backup_finish(). Unfortunately SQLite does not currently check
-** for this, if the application does use the destination [database connection]
-** for some other purpose during a backup operation, things may appear to
-** work correctly but in fact be subtly malfunctioning. Use of the
-** destination database connection while a backup is in progress might
-** also cause a mutex deadlock.
-**
-** Furthermore, if running in [shared cache mode], the application must
-** guarantee that the shared cache used by the destination database
-** is not accessed while the backup is running. In practice this means
-** that the application must guarantee that the file-system file being
-** backed up to is not accessed by any connection within the process,
-** not just the specific connection that was passed to sqlite3_backup_init().
-**
-** The [sqlite3_backup] object itself is partially threadsafe. Multiple
-** threads may safely make multiple concurrent calls to sqlite3_backup_step().
-** However, the sqlite3_backup_remaining() and sqlite3_backup_pagecount()
-** APIs are not strictly speaking threadsafe. If they are invoked at the
-** same time as another thread is invoking sqlite3_backup_step() it is
-** possible that they return invalid values.
-*/
-SQLITE_API sqlite3_backup *sqlite3_backup_init(
- sqlite3 *pDest, /* Destination database handle */
- const char *zDestName, /* Destination database name */
- sqlite3 *pSource, /* Source database handle */
- const char *zSourceName /* Source database name */
-);
-SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage);
-SQLITE_API int sqlite3_backup_finish(sqlite3_backup *p);
-SQLITE_API int sqlite3_backup_remaining(sqlite3_backup *p);
-SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p);
-
-/*
-** CAPI3REF: Unlock Notification
-** EXPERIMENTAL
-**
-** When running in shared-cache mode, a database operation may fail with
-** an [SQLITE_LOCKED] error if the required locks on the shared-cache or
-** individual tables within the shared-cache cannot be obtained. See
-** [SQLite Shared-Cache Mode] for a description of shared-cache locking.
-** This API may be used to register a callback that SQLite will invoke
-** when the connection currently holding the required lock relinquishes it.
-** This API is only available if the library was compiled with the
-** [SQLITE_ENABLE_UNLOCK_NOTIFY] C-preprocessor symbol defined.
-**
-** See Also: [Using the SQLite Unlock Notification Feature].
-**
-** Shared-cache locks are released when a database connection concludes
-** its current transaction, either by committing it or rolling it back.
-**
-** When a connection (known as the blocked connection) fails to obtain a
-** shared-cache lock and SQLITE_LOCKED is returned to the caller, the
-** identity of the database connection (the blocking connection) that
-** has locked the required resource is stored internally. After an
-** application receives an SQLITE_LOCKED error, it may call the
-** sqlite3_unlock_notify() method with the blocked connection handle as
-** the first argument to register for a callback that will be invoked
-** when the blocking connections current transaction is concluded. The
-** callback is invoked from within the [sqlite3_step] or [sqlite3_close]
-** call that concludes the blocking connections transaction.
-**
-** If sqlite3_unlock_notify() is called in a multi-threaded application,
-** there is a chance that the blocking connection will have already
-** concluded its transaction by the time sqlite3_unlock_notify() is invoked.
-** If this happens, then the specified callback is invoked immediately,
-** from within the call to sqlite3_unlock_notify().
-**
-** If the blocked connection is attempting to obtain a write-lock on a
-** shared-cache table, and more than one other connection currently holds
-** a read-lock on the same table, then SQLite arbitrarily selects one of
-** the other connections to use as the blocking connection.
-**
-** There may be at most one unlock-notify callback registered by a
-** blocked connection. If sqlite3_unlock_notify() is called when the
-** blocked connection already has a registered unlock-notify callback,
-** then the new callback replaces the old. If sqlite3_unlock_notify() is
-** called with a NULL pointer as its second argument, then any existing
-** unlock-notify callback is cancelled. The blocked connections
-** unlock-notify callback may also be canceled by closing the blocked
-** connection using [sqlite3_close()].
-**
-** The unlock-notify callback is not reentrant. If an application invokes
-** any sqlite3_xxx API functions from within an unlock-notify callback, a
-** crash or deadlock may be the result.
-**
-** Unless deadlock is detected (see below), sqlite3_unlock_notify() always
-** returns SQLITE_OK.
-**
-** <b>Callback Invocation Details</b>
-**
-** When an unlock-notify callback is registered, the application provides a
-** single void* pointer that is passed to the callback when it is invoked.
-** However, the signature of the callback function allows SQLite to pass
-** it an array of void* context pointers. The first argument passed to
-** an unlock-notify callback is a pointer to an array of void* pointers,
-** and the second is the number of entries in the array.
-**
-** When a blocking connections transaction is concluded, there may be
-** more than one blocked connection that has registered for an unlock-notify
-** callback. If two or more such blocked connections have specified the
-** same callback function, then instead of invoking the callback function
-** multiple times, it is invoked once with the set of void* context pointers
-** specified by the blocked connections bundled together into an array.
-** This gives the application an opportunity to prioritize any actions
-** related to the set of unblocked database connections.
-**
-** <b>Deadlock Detection</b>
-**
-** Assuming that after registering for an unlock-notify callback a
-** database waits for the callback to be issued before taking any further
-** action (a reasonable assumption), then using this API may cause the
-** application to deadlock. For example, if connection X is waiting for
-** connection Y's transaction to be concluded, and similarly connection
-** Y is waiting on connection X's transaction, then neither connection
-** will proceed and the system may remain deadlocked indefinitely.
-**
-** To avoid this scenario, the sqlite3_unlock_notify() performs deadlock
-** detection. If a given call to sqlite3_unlock_notify() would put the
-** system in a deadlocked state, then SQLITE_LOCKED is returned and no
-** unlock-notify callback is registered. The system is said to be in
-** a deadlocked state if connection A has registered for an unlock-notify
-** callback on the conclusion of connection B's transaction, and connection
-** B has itself registered for an unlock-notify callback when connection
-** A's transaction is concluded. Indirect deadlock is also detected, so
-** the system is also considered to be deadlocked if connection B has
-** registered for an unlock-notify callback on the conclusion of connection
-** C's transaction, where connection C is waiting on connection A. Any
-** number of levels of indirection are allowed.
-**
-** <b>The "DROP TABLE" Exception</b>
-**
-** When a call to [sqlite3_step()] returns SQLITE_LOCKED, it is almost
-** always appropriate to call sqlite3_unlock_notify(). There is however,
-** one exception. When executing a "DROP TABLE" or "DROP INDEX" statement,
-** SQLite checks if there are any currently executing SELECT statements
-** that belong to the same connection. If there are, SQLITE_LOCKED is
-** returned. In this case there is no "blocking connection", so invoking
-** sqlite3_unlock_notify() results in the unlock-notify callback being
-** invoked immediately. If the application then re-attempts the "DROP TABLE"
-** or "DROP INDEX" query, an infinite loop might be the result.
-**
-** One way around this problem is to check the extended error code returned
-** by an sqlite3_step() call. If there is a blocking connection, then the
-** extended error code is set to SQLITE_LOCKED_SHAREDCACHE. Otherwise, in
-** the special "DROP TABLE/INDEX" case, the extended error code is just
-** SQLITE_LOCKED.
-*/
-SQLITE_API int sqlite3_unlock_notify(
- sqlite3 *pBlocked, /* Waiting connection */
- void (*xNotify)(void **apArg, int nArg), /* Callback function to invoke */
- void *pNotifyArg /* Argument to pass to xNotify */
-);
-
-
-/*
-** CAPI3REF: String Comparison
-** EXPERIMENTAL
-**
-** The [sqlite3_strnicmp()] API allows applications and extensions to
-** compare the contents of two buffers containing UTF-8 strings in a
-** case-indendent fashion, using the same definition of case independence
-** that SQLite uses internally when comparing identifiers.
-*/
-SQLITE_API int sqlite3_strnicmp(const char *, const char *, int);
-
-/*
-** Undo the hack that converts floating point types to integer for
-** builds on processors without floating point support.
-*/
-#ifdef SQLITE_OMIT_FLOATING_POINT
-# undef double
-#endif
-
-#if 0
-} /* End of the 'extern "C"' block */
-#endif
-#endif
-
-
-/************** End of sqlite3.h *********************************************/
-/************** Continuing where we left off in sqliteInt.h ******************/
-/************** Include hash.h in the middle of sqliteInt.h ******************/
-/************** Begin file hash.h ********************************************/
-/*
-** 2001 September 22
-**
-** 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 is the header file for the generic hash-table implemenation
-** used in SQLite.
-**
-** $Id: hash.h,v 1.15 2009/05/02 13:29:38 drh Exp $
-*/
-#ifndef _SQLITE_HASH_H_
-#define _SQLITE_HASH_H_
-
-/* Forward declarations of structures. */
-typedef struct Hash Hash;
-typedef struct HashElem HashElem;
-
-/* A complete hash table is an instance of the following structure.
-** The internals of this structure are intended to be opaque -- client
-** code should not attempt to access or modify the fields of this structure
-** directly. Change this structure only by using the routines below.
-** However, some of the "procedures" and "functions" for modifying and
-** accessing this structure are really macros, so we can't really make
-** this structure opaque.
-**
-** All elements of the hash table are on a single doubly-linked list.
-** Hash.first points to the head of this list.
-**
-** There are Hash.htsize buckets. Each bucket points to a spot in
-** the global doubly-linked list. The contents of the bucket are the
-** element pointed to plus the next _ht.count-1 elements in the list.
-**
-** Hash.htsize and Hash.ht may be zero. In that case lookup is done
-** by a linear search of the global list. For small tables, the
-** Hash.ht table is never allocated because if there are few elements
-** in the table, it is faster to do a linear search than to manage
-** the hash table.
-*/
-struct Hash {
- unsigned int htsize; /* Number of buckets in the hash table */
- unsigned int count; /* Number of entries in this table */
- HashElem *first; /* The first element of the array */
- struct _ht { /* the hash table */
- int count; /* Number of entries with this hash */
- HashElem *chain; /* Pointer to first entry with this hash */
- } *ht;
-};
-
-/* Each element in the hash table is an instance of the following
-** structure. All elements are stored on a single doubly-linked list.
-**
-** Again, this structure is intended to be opaque, but it can't really
-** be opaque because it is used by macros.
-*/
-struct HashElem {
- HashElem *next, *prev; /* Next and previous elements in the table */
- void *data; /* Data associated with this element */
- const char *pKey; int nKey; /* Key associated with this element */
-};
-
-/*
-** Access routines. To delete, insert a NULL pointer.
-*/
-SQLITE_PRIVATE void sqlite3HashInit(Hash*);
-SQLITE_PRIVATE void *sqlite3HashInsert(Hash*, const char *pKey, int nKey, void *pData);
-SQLITE_PRIVATE void *sqlite3HashFind(const Hash*, const char *pKey, int nKey);
-SQLITE_PRIVATE void sqlite3HashClear(Hash*);
-
-/*
-** Macros for looping over all elements of a hash table. The idiom is
-** like this:
-**
-** Hash h;
-** HashElem *p;
-** ...
-** for(p=sqliteHashFirst(&h); p; p=sqliteHashNext(p)){
-** SomeStructure *pData = sqliteHashData(p);
-** // do something with pData
-** }
-*/
-#define sqliteHashFirst(H) ((H)->first)
-#define sqliteHashNext(E) ((E)->next)
-#define sqliteHashData(E) ((E)->data)
-/* #define sqliteHashKey(E) ((E)->pKey) // NOT USED */
-/* #define sqliteHashKeysize(E) ((E)->nKey) // NOT USED */
-
-/*
-** Number of entries in a hash table
-*/
-/* #define sqliteHashCount(H) ((H)->count) // NOT USED */
-
-#endif /* _SQLITE_HASH_H_ */
-
-/************** End of hash.h ************************************************/
-/************** Continuing where we left off in sqliteInt.h ******************/
-/************** Include parse.h in the middle of sqliteInt.h *****************/
-/************** Begin file parse.h *******************************************/
-#define TK_SEMI 1
-#define TK_EXPLAIN 2
-#define TK_QUERY 3
-#define TK_PLAN 4
-#define TK_BEGIN 5
-#define TK_TRANSACTION 6
-#define TK_DEFERRED 7
-#define TK_IMMEDIATE 8
-#define TK_EXCLUSIVE 9
-#define TK_COMMIT 10
-#define TK_END 11
-#define TK_ROLLBACK 12
-#define TK_SAVEPOINT 13
-#define TK_RELEASE 14
-#define TK_TO 15
-#define TK_TABLE 16
-#define TK_CREATE 17
-#define TK_IF 18
-#define TK_NOT 19
-#define TK_EXISTS 20
-#define TK_TEMP 21
-#define TK_LP 22
-#define TK_RP 23
-#define TK_AS 24
-#define TK_COMMA 25
-#define TK_ID 26
-#define TK_INDEXED 27
-#define TK_ABORT 28
-#define TK_AFTER 29
-#define TK_ANALYZE 30
-#define TK_ASC 31
-#define TK_ATTACH 32
-#define TK_BEFORE 33
-#define TK_BY 34
-#define TK_CASCADE 35
-#define TK_CAST 36
-#define TK_COLUMNKW 37
-#define TK_CONFLICT 38
-#define TK_DATABASE 39
-#define TK_DESC 40
-#define TK_DETACH 41
-#define TK_EACH 42
-#define TK_FAIL 43
-#define TK_FOR 44
-#define TK_IGNORE 45
-#define TK_INITIALLY 46
-#define TK_INSTEAD 47
-#define TK_LIKE_KW 48
-#define TK_MATCH 49
-#define TK_KEY 50
-#define TK_OF 51
-#define TK_OFFSET 52
-#define TK_PRAGMA 53
-#define TK_RAISE 54
-#define TK_REPLACE 55
-#define TK_RESTRICT 56
-#define TK_ROW 57
-#define TK_TRIGGER 58
-#define TK_VACUUM 59
-#define TK_VIEW 60
-#define TK_VIRTUAL 61
-#define TK_REINDEX 62
-#define TK_RENAME 63
-#define TK_CTIME_KW 64
-#define TK_ANY 65
-#define TK_OR 66
-#define TK_AND 67
-#define TK_IS 68
-#define TK_BETWEEN 69
-#define TK_IN 70
-#define TK_ISNULL 71
-#define TK_NOTNULL 72
-#define TK_NE 73
-#define TK_EQ 74
-#define TK_GT 75
-#define TK_LE 76
-#define TK_LT 77
-#define TK_GE 78
-#define TK_ESCAPE 79
-#define TK_BITAND 80
-#define TK_BITOR 81
-#define TK_LSHIFT 82
-#define TK_RSHIFT 83
-#define TK_PLUS 84
-#define TK_MINUS 85
-#define TK_STAR 86
-#define TK_SLASH 87
-#define TK_REM 88
-#define TK_CONCAT 89
-#define TK_COLLATE 90
-#define TK_UMINUS 91
-#define TK_UPLUS 92
-#define TK_BITNOT 93
-#define TK_STRING 94
-#define TK_JOIN_KW 95
-#define TK_CONSTRAINT 96
-#define TK_DEFAULT 97
-#define TK_NULL 98
-#define TK_PRIMARY 99
-#define TK_UNIQUE 100
-#define TK_CHECK 101
-#define TK_REFERENCES 102
-#define TK_AUTOINCR 103
-#define TK_ON 104
-#define TK_DELETE 105
-#define TK_UPDATE 106
-#define TK_INSERT 107
-#define TK_SET 108
-#define TK_DEFERRABLE 109
-#define TK_FOREIGN 110
-#define TK_DROP 111
-#define TK_UNION 112
-#define TK_ALL 113
-#define TK_EXCEPT 114
-#define TK_INTERSECT 115
-#define TK_SELECT 116
-#define TK_DISTINCT 117
-#define TK_DOT 118
-#define TK_FROM 119
-#define TK_JOIN 120
-#define TK_USING 121
-#define TK_ORDER 122
-#define TK_GROUP 123
-#define TK_HAVING 124
-#define TK_LIMIT 125
-#define TK_WHERE 126
-#define TK_INTO 127
-#define TK_VALUES 128
-#define TK_INTEGER 129
-#define TK_FLOAT 130
-#define TK_BLOB 131
-#define TK_REGISTER 132
-#define TK_VARIABLE 133
-#define TK_CASE 134
-#define TK_WHEN 135
-#define TK_THEN 136
-#define TK_ELSE 137
-#define TK_INDEX 138
-#define TK_ALTER 139
-#define TK_ADD 140
-#define TK_TO_TEXT 141
-#define TK_TO_BLOB 142
-#define TK_TO_NUMERIC 143
-#define TK_TO_INT 144
-#define TK_TO_REAL 145
-#define TK_END_OF_FILE 146
-#define TK_ILLEGAL 147
-#define TK_SPACE 148
-#define TK_UNCLOSED_STRING 149
-#define TK_FUNCTION 150
-#define TK_COLUMN 151
-#define TK_AGG_FUNCTION 152
-#define TK_AGG_COLUMN 153
-#define TK_CONST_FUNC 154
-
-/************** End of parse.h ***********************************************/
-/************** Continuing where we left off in sqliteInt.h ******************/
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-#include <stddef.h>
-
-/*
-** If compiling for a processor that lacks floating point support,
-** substitute integer for floating-point
-*/
-#ifdef SQLITE_OMIT_FLOATING_POINT
-# define double sqlite_int64
-# define LONGDOUBLE_TYPE sqlite_int64
-# ifndef SQLITE_BIG_DBL
-# define SQLITE_BIG_DBL (((sqlite3_int64)1)<<50)
-# endif
-# define SQLITE_OMIT_DATETIME_FUNCS 1
-# define SQLITE_OMIT_TRACE 1
-# undef SQLITE_MIXED_ENDIAN_64BIT_FLOAT
-# undef SQLITE_HAVE_ISNAN
-#endif
-#ifndef SQLITE_BIG_DBL
-# define SQLITE_BIG_DBL (1e99)
-#endif
-
-/*
-** OMIT_TEMPDB is set to 1 if SQLITE_OMIT_TEMPDB is defined, or 0
-** afterward. Having this macro allows us to cause the C compiler
-** to omit code used by TEMP tables without messy #ifndef statements.
-*/
-#ifdef SQLITE_OMIT_TEMPDB
-#define OMIT_TEMPDB 1
-#else
-#define OMIT_TEMPDB 0
-#endif
-
-/*
-** If the following macro is set to 1, then NULL values are considered
-** distinct when determining whether or not two entries are the same
-** in a UNIQUE index. This is the way PostgreSQL, Oracle, DB2, MySQL,
-** OCELOT, and Firebird all work. The SQL92 spec explicitly says this
-** is the way things are suppose to work.
-**
-** If the following macro is set to 0, the NULLs are indistinct for
-** a UNIQUE index. In this mode, you can only have a single NULL entry
-** for a column declared UNIQUE. This is the way Informix and SQL Server
-** work.
-*/
-#define NULL_DISTINCT_FOR_UNIQUE 1
-
-/*
-** The "file format" number is an integer that is incremented whenever
-** the VDBE-level file format changes. The following macros define the
-** the default file format for new databases and the maximum file format
-** that the library can read.
-*/
-#define SQLITE_MAX_FILE_FORMAT 4
-#ifndef SQLITE_DEFAULT_FILE_FORMAT
-# define SQLITE_DEFAULT_FILE_FORMAT 1
-#endif
-
-#ifndef SQLITE_DEFAULT_RECURSIVE_TRIGGERS
-# define SQLITE_DEFAULT_RECURSIVE_TRIGGERS 0
-#endif
-
-/*
-** Provide a default value for SQLITE_TEMP_STORE in case it is not specified
-** on the command-line
-*/
-#ifndef SQLITE_TEMP_STORE
-# define SQLITE_TEMP_STORE 1
-#endif
-
-/*
-** GCC does not define the offsetof() macro so we'll have to do it
-** ourselves.
-*/
-#ifndef offsetof
-#define offsetof(STRUCTURE,FIELD) ((int)((char*)&((STRUCTURE*)0)->FIELD))
-#endif
-
-/*
-** Check to see if this machine uses EBCDIC. (Yes, believe it or
-** not, there are still machines out there that use EBCDIC.)
-*/
-#if 'A' == '\301'
-# define SQLITE_EBCDIC 1
-#else
-# define SQLITE_ASCII 1
-#endif
-
-/*
-** Integers of known sizes. These typedefs might change for architectures
-** where the sizes very. Preprocessor macros are available so that the
-** types can be conveniently redefined at compile-type. Like this:
-**
-** cc '-DUINTPTR_TYPE=long long int' ...
-*/
-#ifndef UINT32_TYPE
-# ifdef HAVE_UINT32_T
-# define UINT32_TYPE uint32_t
-# else
-# define UINT32_TYPE unsigned int
-# endif
-#endif
-#ifndef UINT16_TYPE
-# ifdef HAVE_UINT16_T
-# define UINT16_TYPE uint16_t
-# else
-# define UINT16_TYPE unsigned short int
-# endif
-#endif
-#ifndef INT16_TYPE
-# ifdef HAVE_INT16_T
-# define INT16_TYPE int16_t
-# else
-# define INT16_TYPE short int
-# endif
-#endif
-#ifndef UINT8_TYPE
-# ifdef HAVE_UINT8_T
-# define UINT8_TYPE uint8_t
-# else
-# define UINT8_TYPE unsigned char
-# endif
-#endif
-#ifndef INT8_TYPE
-# ifdef HAVE_INT8_T
-# define INT8_TYPE int8_t
-# else
-# define INT8_TYPE signed char
-# endif
-#endif
-#ifndef LONGDOUBLE_TYPE
-# define LONGDOUBLE_TYPE long double
-#endif
-typedef sqlite_int64 i64; /* 8-byte signed integer */
-typedef sqlite_uint64 u64; /* 8-byte unsigned integer */
-typedef UINT32_TYPE u32; /* 4-byte unsigned integer */
-typedef UINT16_TYPE u16; /* 2-byte unsigned integer */
-typedef INT16_TYPE i16; /* 2-byte signed integer */
-typedef UINT8_TYPE u8; /* 1-byte unsigned integer */
-typedef INT8_TYPE i8; /* 1-byte signed integer */
-
-/*
-** SQLITE_MAX_U32 is a u64 constant that is the maximum u64 value
-** that can be stored in a u32 without loss of data. The value
-** is 0x00000000ffffffff. But because of quirks of some compilers, we
-** have to specify the value in the less intuitive manner shown:
-*/
-#define SQLITE_MAX_U32 ((((u64)1)<<32)-1)
-
-/*
-** Macros to determine whether the machine is big or little endian,
-** evaluated at runtime.
-*/
-#ifdef SQLITE_AMALGAMATION
-SQLITE_PRIVATE const int sqlite3one = 1;
-#else
-SQLITE_PRIVATE const int sqlite3one;
-#endif
-#if defined(i386) || defined(__i386__) || defined(_M_IX86)\
- || defined(__x86_64) || defined(__x86_64__)
-# define SQLITE_BIGENDIAN 0
-# define SQLITE_LITTLEENDIAN 1
-# define SQLITE_UTF16NATIVE SQLITE_UTF16LE
-#else
-# define SQLITE_BIGENDIAN (*(char *)(&sqlite3one)==0)
-# define SQLITE_LITTLEENDIAN (*(char *)(&sqlite3one)==1)
-# define SQLITE_UTF16NATIVE (SQLITE_BIGENDIAN?SQLITE_UTF16BE:SQLITE_UTF16LE)
-#endif
-
-/*
-** Constants for the largest and smallest possible 64-bit signed integers.
-** These macros are designed to work correctly on both 32-bit and 64-bit
-** compilers.
-*/
-#define LARGEST_INT64 (0xffffffff|(((i64)0x7fffffff)<<32))
-#define SMALLEST_INT64 (((i64)-1) - LARGEST_INT64)
-
-/*
-** Round up a number to the next larger multiple of 8. This is used
-** to force 8-byte alignment on 64-bit architectures.
-*/
-#define ROUND8(x) (((x)+7)&~7)
-
-/*
-** Round down to the nearest multiple of 8
-*/
-#define ROUNDDOWN8(x) ((x)&~7)
-
-/*
-** Assert that the pointer X is aligned to an 8-byte boundary.
-*/
-#define EIGHT_BYTE_ALIGNMENT(X) ((((char*)(X) - (char*)0)&7)==0)
-
-
-/*
-** An instance of the following structure is used to store the busy-handler
-** callback for a given sqlite handle.
-**
-** The sqlite.busyHandler member of the sqlite struct contains the busy
-** callback for the database handle. Each pager opened via the sqlite
-** handle is passed a pointer to sqlite.busyHandler. The busy-handler
-** callback is currently invoked only from within pager.c.
-*/
-typedef struct BusyHandler BusyHandler;
-struct BusyHandler {
- int (*xFunc)(void *,int); /* The busy callback */
- void *pArg; /* First arg to busy callback */
- int nBusy; /* Incremented with each busy call */
-};
-
-/*
-** Name of the master database table. The master database table
-** is a special table that holds the names and attributes of all
-** user tables and indices.
-*/
-#define MASTER_NAME "sqlite_master"
-#define TEMP_MASTER_NAME "sqlite_temp_master"
-
-/*
-** The root-page of the master database table.
-*/
-#define MASTER_ROOT 1
-
-/*
-** The name of the schema table.
-*/
-#define SCHEMA_TABLE(x) ((!OMIT_TEMPDB)&&(x==1)?TEMP_MASTER_NAME:MASTER_NAME)
-
-/*
-** A convenience macro that returns the number of elements in
-** an array.
-*/
-#define ArraySize(X) ((int)(sizeof(X)/sizeof(X[0])))
-
-/*
-** The following value as a destructor means to use sqlite3DbFree().
-** This is an internal extension to SQLITE_STATIC and SQLITE_TRANSIENT.
-*/
-#define SQLITE_DYNAMIC ((sqlite3_destructor_type)sqlite3DbFree)
-
-/*
-** When SQLITE_OMIT_WSD is defined, it means that the target platform does
-** not support Writable Static Data (WSD) such as global and static variables.
-** All variables must either be on the stack or dynamically allocated from
-** the heap. When WSD is unsupported, the variable declarations scattered
-** throughout the SQLite code must become constants instead. The SQLITE_WSD
-** macro is used for this purpose. And instead of referencing the variable
-** directly, we use its constant as a key to lookup the run-time allocated
-** buffer that holds real variable. The constant is also the initializer
-** for the run-time allocated buffer.
-**
-** In the usual case where WSD is supported, the SQLITE_WSD and GLOBAL
-** macros become no-ops and have zero performance impact.
-*/
-#ifdef SQLITE_OMIT_WSD
- #define SQLITE_WSD const
- #define GLOBAL(t,v) (*(t*)sqlite3_wsd_find((void*)&(v), sizeof(v)))
- #define sqlite3GlobalConfig GLOBAL(struct Sqlite3Config, sqlite3Config)
-SQLITE_API int sqlite3_wsd_init(int N, int J);
-SQLITE_API void *sqlite3_wsd_find(void *K, int L);
-#else
- #define SQLITE_WSD
- #define GLOBAL(t,v) v
- #define sqlite3GlobalConfig sqlite3Config
-#endif
-
-/*
-** The following macros are used to suppress compiler warnings and to
-** make it clear to human readers when a function parameter is deliberately
-** left unused within the body of a function. This usually happens when
-** a function is called via a function pointer. For example the
-** implementation of an SQL aggregate step callback may not use the
-** parameter indicating the number of arguments passed to the aggregate,
-** if it knows that this is enforced elsewhere.
-**
-** When a function parameter is not used at all within the body of a function,
-** it is generally named "NotUsed" or "NotUsed2" to make things even clearer.
-** However, these macros may also be used to suppress warnings related to
-** parameters that may or may not be used depending on compilation options.
-** For example those parameters only used in assert() statements. In these
-** cases the parameters are named as per the usual conventions.
-*/
-#define UNUSED_PARAMETER(x) (void)(x)
-#define UNUSED_PARAMETER2(x,y) UNUSED_PARAMETER(x),UNUSED_PARAMETER(y)
-
-/*
-** Forward references to structures
-*/
-typedef struct AggInfo AggInfo;
-typedef struct AuthContext AuthContext;
-typedef struct AutoincInfo AutoincInfo;
-typedef struct Bitvec Bitvec;
-typedef struct RowSet RowSet;
-typedef struct CollSeq CollSeq;
-typedef struct Column Column;
-typedef struct Db Db;
-typedef struct Schema Schema;
-typedef struct Expr Expr;
-typedef struct ExprList ExprList;
-typedef struct ExprSpan ExprSpan;
-typedef struct FKey FKey;
-typedef struct FuncDef FuncDef;
-typedef struct FuncDefHash FuncDefHash;
-typedef struct IdList IdList;
-typedef struct Index Index;
-typedef struct IndexSample IndexSample;
-typedef struct KeyClass KeyClass;
-typedef struct KeyInfo KeyInfo;
-typedef struct Lookaside Lookaside;
-typedef struct LookasideSlot LookasideSlot;
-typedef struct Module Module;
-typedef struct NameContext NameContext;
-typedef struct Parse Parse;
-typedef struct Savepoint Savepoint;
-typedef struct Select Select;
-typedef struct SrcList SrcList;
-typedef struct StrAccum StrAccum;
-typedef struct Table Table;
-typedef struct TableLock TableLock;
-typedef struct Token Token;
-typedef struct TriggerPrg TriggerPrg;
-typedef struct TriggerStep TriggerStep;
-typedef struct Trigger Trigger;
-typedef struct UnpackedRecord UnpackedRecord;
-typedef struct VTable VTable;
-typedef struct Walker Walker;
-typedef struct WherePlan WherePlan;
-typedef struct WhereInfo WhereInfo;
-typedef struct WhereLevel WhereLevel;
-
-/*
-** Defer sourcing vdbe.h and btree.h until after the "u8" and
-** "BusyHandler" typedefs. vdbe.h also requires a few of the opaque
-** pointer types (i.e. FuncDef) defined above.
-*/
-/************** Include btree.h in the middle of sqliteInt.h *****************/
-/************** Begin file btree.h *******************************************/
-/*
-** 2001 September 15
-**
-** 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 header file defines the interface that the sqlite B-Tree file
-** subsystem. See comments in the source code for a detailed description
-** of what each interface routine does.
-**
-** @(#) $Id: btree.h,v 1.120 2009/07/22 00:35:24 drh Exp $
-*/
-#ifndef _BTREE_H_
-#define _BTREE_H_
-
-/* TODO: This definition is just included so other modules compile. It
-** needs to be revisited.
-*/
-#define SQLITE_N_BTREE_META 10
-
-/*
-** If defined as non-zero, auto-vacuum is enabled by default. Otherwise
-** it must be turned on for each database using "PRAGMA auto_vacuum = 1".
-*/
-#ifndef SQLITE_DEFAULT_AUTOVACUUM
- #define SQLITE_DEFAULT_AUTOVACUUM 0
-#endif
-
-#define BTREE_AUTOVACUUM_NONE 0 /* Do not do auto-vacuum */
-#define BTREE_AUTOVACUUM_FULL 1 /* Do full auto-vacuum */
-#define BTREE_AUTOVACUUM_INCR 2 /* Incremental vacuum */
-
-/*
-** Forward declarations of structure
-*/
-typedef struct Btree Btree;
-typedef struct BtCursor BtCursor;
-typedef struct BtShared BtShared;
-typedef struct BtreeMutexArray BtreeMutexArray;
-
-/*
-** This structure records all of the Btrees that need to hold
-** a mutex before we enter sqlite3VdbeExec(). The Btrees are
-** are placed in aBtree[] in order of aBtree[]->pBt. That way,
-** we can always lock and unlock them all quickly.
-*/
-struct BtreeMutexArray {
- int nMutex;
- Btree *aBtree[SQLITE_MAX_ATTACHED+1];
-};
-
-
-SQLITE_PRIVATE int sqlite3BtreeOpen(
- const char *zFilename, /* Name of database file to open */
- sqlite3 *db, /* Associated database connection */
- Btree **ppBtree, /* Return open Btree* here */
- int flags, /* Flags */
- int vfsFlags /* Flags passed through to VFS open */
-);
-
-/* The flags parameter to sqlite3BtreeOpen can be the bitwise or of the
-** following values.
-**
-** NOTE: These values must match the corresponding PAGER_ values in
-** pager.h.
-*/
-#define BTREE_OMIT_JOURNAL 1 /* Do not use journal. No argument */
-#define BTREE_NO_READLOCK 2 /* Omit readlocks on readonly files */
-#define BTREE_MEMORY 4 /* In-memory DB. No argument */
-#define BTREE_READONLY 8 /* Open the database in read-only mode */
-#define BTREE_READWRITE 16 /* Open for both reading and writing */
-#define BTREE_CREATE 32 /* Create the database if it does not exist */
-
-SQLITE_PRIVATE int sqlite3BtreeClose(Btree*);
-SQLITE_PRIVATE int sqlite3BtreeSetCacheSize(Btree*,int);
-SQLITE_PRIVATE int sqlite3BtreeSetSafetyLevel(Btree*,int,int);
-SQLITE_PRIVATE int sqlite3BtreeSyncDisabled(Btree*);
-SQLITE_PRIVATE int sqlite3BtreeSetPageSize(Btree *p, int nPagesize, int nReserve, int eFix);
-SQLITE_PRIVATE int sqlite3BtreeGetPageSize(Btree*);
-SQLITE_PRIVATE int sqlite3BtreeMaxPageCount(Btree*,int);
-SQLITE_PRIVATE int sqlite3BtreeGetReserve(Btree*);
-SQLITE_PRIVATE int sqlite3BtreeSetAutoVacuum(Btree *, int);
-SQLITE_PRIVATE int sqlite3BtreeGetAutoVacuum(Btree *);
-SQLITE_PRIVATE int sqlite3BtreeBeginTrans(Btree*,int);
-SQLITE_PRIVATE int sqlite3BtreeCommitPhaseOne(Btree*, const char *zMaster);
-SQLITE_PRIVATE int sqlite3BtreeCommitPhaseTwo(Btree*);
-SQLITE_PRIVATE int sqlite3BtreeCommit(Btree*);
-SQLITE_PRIVATE int sqlite3BtreeRollback(Btree*);
-SQLITE_PRIVATE int sqlite3BtreeBeginStmt(Btree*,int);
-SQLITE_PRIVATE int sqlite3BtreeCreateTable(Btree*, int*, int flags);
-SQLITE_PRIVATE int sqlite3BtreeIsInTrans(Btree*);
-SQLITE_PRIVATE int sqlite3BtreeIsInReadTrans(Btree*);
-SQLITE_PRIVATE int sqlite3BtreeIsInBackup(Btree*);
-SQLITE_PRIVATE void *sqlite3BtreeSchema(Btree *, int, void(*)(void *));
-SQLITE_PRIVATE int sqlite3BtreeSchemaLocked(Btree *pBtree);
-SQLITE_PRIVATE int sqlite3BtreeLockTable(Btree *pBtree, int iTab, u8 isWriteLock);
-SQLITE_PRIVATE int sqlite3BtreeSavepoint(Btree *, int, int);
-
-SQLITE_PRIVATE const char *sqlite3BtreeGetFilename(Btree *);
-SQLITE_PRIVATE const char *sqlite3BtreeGetJournalname(Btree *);
-SQLITE_PRIVATE int sqlite3BtreeCopyFile(Btree *, Btree *);
-
-SQLITE_PRIVATE int sqlite3BtreeIncrVacuum(Btree *);
-
-/* The flags parameter to sqlite3BtreeCreateTable can be the bitwise OR
-** of the following flags:
-*/
-#define BTREE_INTKEY 1 /* Table has only 64-bit signed integer keys */
-#define BTREE_ZERODATA 2 /* Table has keys only - no data */
-#define BTREE_LEAFDATA 4 /* Data stored in leaves only. Implies INTKEY */
-
-SQLITE_PRIVATE int sqlite3BtreeDropTable(Btree*, int, int*);
-SQLITE_PRIVATE int sqlite3BtreeClearTable(Btree*, int, int*);
-SQLITE_PRIVATE void sqlite3BtreeTripAllCursors(Btree*, int);
-
-SQLITE_PRIVATE void sqlite3BtreeGetMeta(Btree *pBtree, int idx, u32 *pValue);
-SQLITE_PRIVATE int sqlite3BtreeUpdateMeta(Btree*, int idx, u32 value);
-
-/*
-** The second parameter to sqlite3BtreeGetMeta or sqlite3BtreeUpdateMeta
-** should be one of the following values. The integer values are assigned
-** to constants so that the offset of the corresponding field in an
-** SQLite database header may be found using the following formula:
-**
-** offset = 36 + (idx * 4)
-**
-** For example, the free-page-count field is located at byte offset 36 of
-** the database file header. The incr-vacuum-flag field is located at
-** byte offset 64 (== 36+4*7).
-*/
-#define BTREE_FREE_PAGE_COUNT 0
-#define BTREE_SCHEMA_VERSION 1
-#define BTREE_FILE_FORMAT 2
-#define BTREE_DEFAULT_CACHE_SIZE 3
-#define BTREE_LARGEST_ROOT_PAGE 4
-#define BTREE_TEXT_ENCODING 5
-#define BTREE_USER_VERSION 6
-#define BTREE_INCR_VACUUM 7
-
-SQLITE_PRIVATE int sqlite3BtreeCursor(
- Btree*, /* BTree containing table to open */
- int iTable, /* Index of root page */
- int wrFlag, /* 1 for writing. 0 for read-only */
- struct KeyInfo*, /* First argument to compare function */
- BtCursor *pCursor /* Space to write cursor structure */
-);
-SQLITE_PRIVATE int sqlite3BtreeCursorSize(void);
-
-SQLITE_PRIVATE int sqlite3BtreeCloseCursor(BtCursor*);
-SQLITE_PRIVATE int sqlite3BtreeMovetoUnpacked(
- BtCursor*,
- UnpackedRecord *pUnKey,
- i64 intKey,
- int bias,
- int *pRes
-);
-SQLITE_PRIVATE int sqlite3BtreeCursorHasMoved(BtCursor*, int*);
-SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor*);
-SQLITE_PRIVATE int sqlite3BtreeInsert(BtCursor*, const void *pKey, i64 nKey,
- const void *pData, int nData,
- int nZero, int bias, int seekResult);
-SQLITE_PRIVATE int sqlite3BtreeFirst(BtCursor*, int *pRes);
-SQLITE_PRIVATE int sqlite3BtreeLast(BtCursor*, int *pRes);
-SQLITE_PRIVATE int sqlite3BtreeNext(BtCursor*, int *pRes);
-SQLITE_PRIVATE int sqlite3BtreeEof(BtCursor*);
-SQLITE_PRIVATE int sqlite3BtreePrevious(BtCursor*, int *pRes);
-SQLITE_PRIVATE int sqlite3BtreeKeySize(BtCursor*, i64 *pSize);
-SQLITE_PRIVATE int sqlite3BtreeKey(BtCursor*, u32 offset, u32 amt, void*);
-SQLITE_PRIVATE const void *sqlite3BtreeKeyFetch(BtCursor*, int *pAmt);
-SQLITE_PRIVATE const void *sqlite3BtreeDataFetch(BtCursor*, int *pAmt);
-SQLITE_PRIVATE int sqlite3BtreeDataSize(BtCursor*, u32 *pSize);
-SQLITE_PRIVATE int sqlite3BtreeData(BtCursor*, u32 offset, u32 amt, void*);
-SQLITE_PRIVATE void sqlite3BtreeSetCachedRowid(BtCursor*, sqlite3_int64);
-SQLITE_PRIVATE sqlite3_int64 sqlite3BtreeGetCachedRowid(BtCursor*);
-
-SQLITE_PRIVATE char *sqlite3BtreeIntegrityCheck(Btree*, int *aRoot, int nRoot, int, int*);
-SQLITE_PRIVATE struct Pager *sqlite3BtreePager(Btree*);
-
-SQLITE_PRIVATE int sqlite3BtreePutData(BtCursor*, u32 offset, u32 amt, void*);
-SQLITE_PRIVATE void sqlite3BtreeCacheOverflow(BtCursor *);
-SQLITE_PRIVATE void sqlite3BtreeClearCursor(BtCursor *);
-
-#ifndef NDEBUG
-SQLITE_PRIVATE int sqlite3BtreeCursorIsValid(BtCursor*);
-#endif
-
-#ifndef SQLITE_OMIT_BTREECOUNT
-SQLITE_PRIVATE int sqlite3BtreeCount(BtCursor *, i64 *);
-#endif
-
-#ifdef SQLITE_TEST
-SQLITE_PRIVATE int sqlite3BtreeCursorInfo(BtCursor*, int*, int);
-SQLITE_PRIVATE void sqlite3BtreeCursorList(Btree*);
-#endif
-
-/*
-** If we are not using shared cache, then there is no need to
-** use mutexes to access the BtShared structures. So make the
-** Enter and Leave procedures no-ops.
-*/
-#ifndef SQLITE_OMIT_SHARED_CACHE
-SQLITE_PRIVATE void sqlite3BtreeEnter(Btree*);
-SQLITE_PRIVATE void sqlite3BtreeEnterAll(sqlite3*);
-#else
-# define sqlite3BtreeEnter(X)
-# define sqlite3BtreeEnterAll(X)
-#endif
-
-#if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE
-SQLITE_PRIVATE void sqlite3BtreeLeave(Btree*);
-SQLITE_PRIVATE void sqlite3BtreeEnterCursor(BtCursor*);
-SQLITE_PRIVATE void sqlite3BtreeLeaveCursor(BtCursor*);
-SQLITE_PRIVATE void sqlite3BtreeLeaveAll(sqlite3*);
-SQLITE_PRIVATE void sqlite3BtreeMutexArrayEnter(BtreeMutexArray*);
-SQLITE_PRIVATE void sqlite3BtreeMutexArrayLeave(BtreeMutexArray*);
-SQLITE_PRIVATE void sqlite3BtreeMutexArrayInsert(BtreeMutexArray*, Btree*);
-#ifndef NDEBUG
- /* These routines are used inside assert() statements only. */
-SQLITE_PRIVATE int sqlite3BtreeHoldsMutex(Btree*);
-SQLITE_PRIVATE int sqlite3BtreeHoldsAllMutexes(sqlite3*);
-#endif
-#else
-
-# define sqlite3BtreeLeave(X)
-# define sqlite3BtreeEnterCursor(X)
-# define sqlite3BtreeLeaveCursor(X)
-# define sqlite3BtreeLeaveAll(X)
-# define sqlite3BtreeMutexArrayEnter(X)
-# define sqlite3BtreeMutexArrayLeave(X)
-# define sqlite3BtreeMutexArrayInsert(X,Y)
-
-# define sqlite3BtreeHoldsMutex(X) 1
-# define sqlite3BtreeHoldsAllMutexes(X) 1
-#endif
-
-
-#endif /* _BTREE_H_ */
-
-/************** End of btree.h ***********************************************/
-/************** Continuing where we left off in sqliteInt.h ******************/
-/************** Include vdbe.h in the middle of sqliteInt.h ******************/
-/************** Begin file vdbe.h ********************************************/
-/*
-** 2001 September 15
-**
-** 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.
-**
-*************************************************************************
-** Header file for the Virtual DataBase Engine (VDBE)
-**
-** This header defines the interface to the virtual database engine
-** or VDBE. The VDBE implements an abstract machine that runs a
-** simple program to access and modify the underlying database.
-**
-** $Id: vdbe.h,v 1.142 2009/07/24 17:58:53 danielk1977 Exp $
-*/
-#ifndef _SQLITE_VDBE_H_
-#define _SQLITE_VDBE_H_
-
-/*
-** A single VDBE is an opaque structure named "Vdbe". Only routines
-** in the source file sqliteVdbe.c are allowed to see the insides
-** of this structure.
-*/
-typedef struct Vdbe Vdbe;
-
-/*
-** The names of the following types declared in vdbeInt.h are required
-** for the VdbeOp definition.
-*/
-typedef struct VdbeFunc VdbeFunc;
-typedef struct Mem Mem;
-typedef struct SubProgram SubProgram;
-
-/*
-** A single instruction of the virtual machine has an opcode
-** and as many as three operands. The instruction is recorded
-** as an instance of the following structure:
-*/
-struct VdbeOp {
- u8 opcode; /* What operation to perform */
- signed char p4type; /* One of the P4_xxx constants for p4 */
- u8 opflags; /* Not currently used */
- u8 p5; /* Fifth parameter is an unsigned character */
- int p1; /* First operand */
- int p2; /* Second parameter (often the jump destination) */
- int p3; /* The third parameter */
- union { /* fourth parameter */
- int i; /* Integer value if p4type==P4_INT32 */
- void *p; /* Generic pointer */
- char *z; /* Pointer to data for string (char array) types */
- i64 *pI64; /* Used when p4type is P4_INT64 */
- double *pReal; /* Used when p4type is P4_REAL */
- FuncDef *pFunc; /* Used when p4type is P4_FUNCDEF */
- VdbeFunc *pVdbeFunc; /* Used when p4type is P4_VDBEFUNC */
- CollSeq *pColl; /* Used when p4type is P4_COLLSEQ */
- Mem *pMem; /* Used when p4type is P4_MEM */
- VTable *pVtab; /* Used when p4type is P4_VTAB */
- KeyInfo *pKeyInfo; /* Used when p4type is P4_KEYINFO */
- int *ai; /* Used when p4type is P4_INTARRAY */
- SubProgram *pProgram; /* Used when p4type is P4_SUBPROGRAM */
- } p4;
-#ifdef SQLITE_DEBUG
- char *zComment; /* Comment to improve readability */
-#endif
-#ifdef VDBE_PROFILE
- int cnt; /* Number of times this instruction was executed */
- u64 cycles; /* Total time spent executing this instruction */
-#endif
-};
-typedef struct VdbeOp VdbeOp;
-
-
-/*
-** A sub-routine used to implement a trigger program.
-*/
-struct SubProgram {
- VdbeOp *aOp; /* Array of opcodes for sub-program */
- int nOp; /* Elements in aOp[] */
- int nMem; /* Number of memory cells required */
- int nCsr; /* Number of cursors required */
- int nRef; /* Number of pointers to this structure */
- void *token; /* id that may be used to recursive triggers */
-};
-
-/*
-** A smaller version of VdbeOp used for the VdbeAddOpList() function because
-** it takes up less space.
-*/
-struct VdbeOpList {
- u8 opcode; /* What operation to perform */
- signed char p1; /* First operand */
- signed char p2; /* Second parameter (often the jump destination) */
- signed char p3; /* Third parameter */
-};
-typedef struct VdbeOpList VdbeOpList;
-
-/*
-** Allowed values of VdbeOp.p4type
-*/
-#define P4_NOTUSED 0 /* The P4 parameter is not used */
-#define P4_DYNAMIC (-1) /* Pointer to a string obtained from sqliteMalloc() */
-#define P4_STATIC (-2) /* Pointer to a static string */
-#define P4_COLLSEQ (-4) /* P4 is a pointer to a CollSeq structure */
-#define P4_FUNCDEF (-5) /* P4 is a pointer to a FuncDef structure */
-#define P4_KEYINFO (-6) /* P4 is a pointer to a KeyInfo structure */
-#define P4_VDBEFUNC (-7) /* P4 is a pointer to a VdbeFunc structure */
-#define P4_MEM (-8) /* P4 is a pointer to a Mem* structure */
-#define P4_TRANSIENT (-9) /* P4 is a pointer to a transient string */
-#define P4_VTAB (-10) /* P4 is a pointer to an sqlite3_vtab structure */
-#define P4_MPRINTF (-11) /* P4 is a string obtained from sqlite3_mprintf() */
-#define P4_REAL (-12) /* P4 is a 64-bit floating point value */
-#define P4_INT64 (-13) /* P4 is a 64-bit signed integer */
-#define P4_INT32 (-14) /* P4 is a 32-bit signed integer */
-#define P4_INTARRAY (-15) /* P4 is a vector of 32-bit integers */
-#define P4_SUBPROGRAM (-18) /* P4 is a pointer to a SubProgram structure */
-
-/* When adding a P4 argument using P4_KEYINFO, a copy of the KeyInfo structure
-** is made. That copy is freed when the Vdbe is finalized. But if the
-** argument is P4_KEYINFO_HANDOFF, the passed in pointer is used. It still
-** gets freed when the Vdbe is finalized so it still should be obtained
-** from a single sqliteMalloc(). But no copy is made and the calling
-** function should *not* try to free the KeyInfo.
-*/
-#define P4_KEYINFO_HANDOFF (-16)
-#define P4_KEYINFO_STATIC (-17)
-
-/*
-** The Vdbe.aColName array contains 5n Mem structures, where n is the
-** number of columns of data returned by the statement.
-*/
-#define COLNAME_NAME 0
-#define COLNAME_DECLTYPE 1
-#define COLNAME_DATABASE 2
-#define COLNAME_TABLE 3
-#define COLNAME_COLUMN 4
-#ifdef SQLITE_ENABLE_COLUMN_METADATA
-# define COLNAME_N 5 /* Number of COLNAME_xxx symbols */
-#else
-# ifdef SQLITE_OMIT_DECLTYPE
-# define COLNAME_N 1 /* Store only the name */
-# else
-# define COLNAME_N 2 /* Store the name and decltype */
-# endif
-#endif
-
-/*
-** The following macro converts a relative address in the p2 field
-** of a VdbeOp structure into a negative number so that
-** sqlite3VdbeAddOpList() knows that the address is relative. Calling
-** the macro again restores the address.
-*/
-#define ADDR(X) (-1-(X))
-
-/*
-** The makefile scans the vdbe.c source file and creates the "opcodes.h"
-** header file that defines a number for each opcode used by the VDBE.
-*/
-/************** Include opcodes.h in the middle of vdbe.h ********************/
-/************** Begin file opcodes.h *****************************************/
-/* Automatically generated. Do not edit */
-/* See the mkopcodeh.awk script for details */
-#define OP_VNext 1
-#define OP_Affinity 2
-#define OP_Column 3
-#define OP_SetCookie 4
-#define OP_Seek 5
-#define OP_Real 130 /* same as TK_FLOAT */
-#define OP_Sequence 6
-#define OP_Savepoint 7
-#define OP_Ge 78 /* same as TK_GE */
-#define OP_RowKey 8
-#define OP_SCopy 9
-#define OP_Eq 74 /* same as TK_EQ */
-#define OP_OpenWrite 10
-#define OP_NotNull 72 /* same as TK_NOTNULL */
-#define OP_If 11
-#define OP_ToInt 144 /* same as TK_TO_INT */
-#define OP_String8 94 /* same as TK_STRING */
-#define OP_CollSeq 12
-#define OP_OpenRead 13
-#define OP_Expire 14
-#define OP_AutoCommit 15
-#define OP_Gt 75 /* same as TK_GT */
-#define OP_Pagecount 16
-#define OP_IntegrityCk 17
-#define OP_Sort 18
-#define OP_Copy 20
-#define OP_Trace 21
-#define OP_Function 22
-#define OP_IfNeg 23
-#define OP_And 67 /* same as TK_AND */
-#define OP_Subtract 85 /* same as TK_MINUS */
-#define OP_Noop 24
-#define OP_Program 25
-#define OP_Return 26
-#define OP_Remainder 88 /* same as TK_REM */
-#define OP_NewRowid 27
-#define OP_Multiply 86 /* same as TK_STAR */
-#define OP_Variable 28
-#define OP_String 29
-#define OP_RealAffinity 30
-#define OP_VRename 31
-#define OP_ParseSchema 32
-#define OP_VOpen 33
-#define OP_Close 34
-#define OP_CreateIndex 35
-#define OP_IsUnique 36
-#define OP_NotFound 37
-#define OP_Int64 38
-#define OP_MustBeInt 39
-#define OP_Halt 40
-#define OP_Rowid 41
-#define OP_IdxLT 42
-#define OP_AddImm 43
-#define OP_RowData 44
-#define OP_MemMax 45
-#define OP_Or 66 /* same as TK_OR */
-#define OP_NotExists 46
-#define OP_Gosub 47
-#define OP_Divide 87 /* same as TK_SLASH */
-#define OP_Integer 48
-#define OP_ToNumeric 143 /* same as TK_TO_NUMERIC*/
-#define OP_Prev 49
-#define OP_RowSetRead 50
-#define OP_Concat 89 /* same as TK_CONCAT */
-#define OP_RowSetAdd 51
-#define OP_BitAnd 80 /* same as TK_BITAND */
-#define OP_VColumn 52
-#define OP_CreateTable 53
-#define OP_Last 54
-#define OP_SeekLe 55
-#define OP_IsNull 71 /* same as TK_ISNULL */
-#define OP_IncrVacuum 56
-#define OP_IdxRowid 57
-#define OP_ShiftRight 83 /* same as TK_RSHIFT */
-#define OP_ResetCount 58
-#define OP_Yield 59
-#define OP_DropTrigger 60
-#define OP_DropIndex 61
-#define OP_Param 62
-#define OP_IdxGE 63
-#define OP_IdxDelete 64
-#define OP_Vacuum 65
-#define OP_IfNot 68
-#define OP_DropTable 69
-#define OP_SeekLt 70
-#define OP_MakeRecord 79
-#define OP_ToBlob 142 /* same as TK_TO_BLOB */
-#define OP_ResultRow 90
-#define OP_Delete 91
-#define OP_AggFinal 92
-#define OP_Compare 95
-#define OP_ShiftLeft 82 /* same as TK_LSHIFT */
-#define OP_Goto 96
-#define OP_TableLock 97
-#define OP_Clear 98
-#define OP_Le 76 /* same as TK_LE */
-#define OP_VerifyCookie 99
-#define OP_AggStep 100
-#define OP_ToText 141 /* same as TK_TO_TEXT */
-#define OP_Not 19 /* same as TK_NOT */
-#define OP_ToReal 145 /* same as TK_TO_REAL */
-#define OP_Transaction 101
-#define OP_VFilter 102
-#define OP_Ne 73 /* same as TK_NE */
-#define OP_VDestroy 103
-#define OP_BitOr 81 /* same as TK_BITOR */
-#define OP_Next 104
-#define OP_Count 105
-#define OP_IdxInsert 106
-#define OP_Lt 77 /* same as TK_LT */
-#define OP_SeekGe 107
-#define OP_Insert 108
-#define OP_Destroy 109
-#define OP_ReadCookie 110
-#define OP_RowSetTest 111
-#define OP_LoadAnalysis 112
-#define OP_Explain 113
-#define OP_HaltIfNull 114
-#define OP_OpenPseudo 115
-#define OP_OpenEphemeral 116
-#define OP_Null 117
-#define OP_Move 118
-#define OP_Blob 119
-#define OP_Add 84 /* same as TK_PLUS */
-#define OP_Rewind 120
-#define OP_SeekGt 121
-#define OP_VBegin 122
-#define OP_VUpdate 123
-#define OP_IfZero 124
-#define OP_BitNot 93 /* same as TK_BITNOT */
-#define OP_VCreate 125
-#define OP_Found 126
-#define OP_IfPos 127
-#define OP_NullRow 128
-#define OP_Jump 129
-#define OP_Permutation 131
-
-/* The following opcode values are never used */
-#define OP_NotUsed_132 132
-#define OP_NotUsed_133 133
-#define OP_NotUsed_134 134
-#define OP_NotUsed_135 135
-#define OP_NotUsed_136 136
-#define OP_NotUsed_137 137
-#define OP_NotUsed_138 138
-#define OP_NotUsed_139 139
-#define OP_NotUsed_140 140
-
-
-/* Properties such as "out2" or "jump" that are specified in
-** comments following the "case" for each opcode in the vdbe.c
-** are encoded into bitvectors as follows:
-*/
-#define OPFLG_JUMP 0x0001 /* jump: P2 holds jmp target */
-#define OPFLG_OUT2_PRERELEASE 0x0002 /* out2-prerelease: */
-#define OPFLG_IN1 0x0004 /* in1: P1 is an input */
-#define OPFLG_IN2 0x0008 /* in2: P2 is an input */
-#define OPFLG_IN3 0x0010 /* in3: P3 is an input */
-#define OPFLG_OUT3 0x0020 /* out3: P3 is an output */
-#define OPFLG_INITIALIZER {\
-/* 0 */ 0x00, 0x01, 0x00, 0x00, 0x10, 0x08, 0x02, 0x00,\
-/* 8 */ 0x00, 0x04, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00,\
-/* 16 */ 0x02, 0x00, 0x01, 0x04, 0x04, 0x00, 0x00, 0x05,\
-/* 24 */ 0x00, 0x01, 0x04, 0x02, 0x00, 0x02, 0x04, 0x00,\
-/* 32 */ 0x00, 0x00, 0x00, 0x02, 0x11, 0x11, 0x02, 0x05,\
-/* 40 */ 0x00, 0x02, 0x11, 0x04, 0x00, 0x08, 0x11, 0x01,\
-/* 48 */ 0x02, 0x01, 0x21, 0x08, 0x00, 0x02, 0x01, 0x11,\
-/* 56 */ 0x01, 0x02, 0x00, 0x04, 0x00, 0x00, 0x02, 0x11,\
-/* 64 */ 0x00, 0x00, 0x2c, 0x2c, 0x05, 0x00, 0x11, 0x05,\
-/* 72 */ 0x05, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x00,\
-/* 80 */ 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c,\
-/* 88 */ 0x2c, 0x2c, 0x00, 0x00, 0x00, 0x04, 0x02, 0x00,\
-/* 96 */ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,\
-/* 104 */ 0x01, 0x02, 0x08, 0x11, 0x00, 0x02, 0x02, 0x15,\
-/* 112 */ 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, 0x00, 0x02,\
-/* 120 */ 0x01, 0x11, 0x00, 0x00, 0x05, 0x00, 0x11, 0x05,\
-/* 128 */ 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,\
-/* 136 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04,\
-/* 144 */ 0x04, 0x04,}
-
-/************** End of opcodes.h *********************************************/
-/************** Continuing where we left off in vdbe.h ***********************/
-
-/*
-** Prototypes for the VDBE interface. See comments on the implementation
-** for a description of what each of these routines does.
-*/
-SQLITE_PRIVATE Vdbe *sqlite3VdbeCreate(sqlite3*);
-SQLITE_PRIVATE int sqlite3VdbeAddOp0(Vdbe*,int);
-SQLITE_PRIVATE int sqlite3VdbeAddOp1(Vdbe*,int,int);
-SQLITE_PRIVATE int sqlite3VdbeAddOp2(Vdbe*,int,int,int);
-SQLITE_PRIVATE int sqlite3VdbeAddOp3(Vdbe*,int,int,int,int);
-SQLITE_PRIVATE int sqlite3VdbeAddOp4(Vdbe*,int,int,int,int,const char *zP4,int);
-SQLITE_PRIVATE int sqlite3VdbeAddOpList(Vdbe*, int nOp, VdbeOpList const *aOp);
-SQLITE_PRIVATE void sqlite3VdbeChangeP1(Vdbe*, int addr, int P1);
-SQLITE_PRIVATE void sqlite3VdbeChangeP2(Vdbe*, int addr, int P2);
-SQLITE_PRIVATE void sqlite3VdbeChangeP3(Vdbe*, int addr, int P3);
-SQLITE_PRIVATE void sqlite3VdbeChangeP5(Vdbe*, u8 P5);
-SQLITE_PRIVATE void sqlite3VdbeJumpHere(Vdbe*, int addr);
-SQLITE_PRIVATE void sqlite3VdbeChangeToNoop(Vdbe*, int addr, int N);
-SQLITE_PRIVATE void sqlite3VdbeChangeP4(Vdbe*, int addr, const char *zP4, int N);
-SQLITE_PRIVATE void sqlite3VdbeUsesBtree(Vdbe*, int);
-SQLITE_PRIVATE VdbeOp *sqlite3VdbeGetOp(Vdbe*, int);
-SQLITE_PRIVATE int sqlite3VdbeMakeLabel(Vdbe*);
-SQLITE_PRIVATE void sqlite3VdbeDelete(Vdbe*);
-SQLITE_PRIVATE void sqlite3VdbeMakeReady(Vdbe*,int,int,int,int,int,int);
-SQLITE_PRIVATE int sqlite3VdbeFinalize(Vdbe*);
-SQLITE_PRIVATE void sqlite3VdbeResolveLabel(Vdbe*, int);
-SQLITE_PRIVATE int sqlite3VdbeCurrentAddr(Vdbe*);
-#ifdef SQLITE_DEBUG
-SQLITE_PRIVATE int sqlite3VdbeAssertMayAbort(Vdbe *, int);
-SQLITE_PRIVATE void sqlite3VdbeTrace(Vdbe*,FILE*);
-#endif
-SQLITE_PRIVATE void sqlite3VdbeResetStepResult(Vdbe*);
-SQLITE_PRIVATE int sqlite3VdbeReset(Vdbe*);
-SQLITE_PRIVATE void sqlite3VdbeSetNumCols(Vdbe*,int);
-SQLITE_PRIVATE int sqlite3VdbeSetColName(Vdbe*, int, int, const char *, void(*)(void*));
-SQLITE_PRIVATE void sqlite3VdbeCountChanges(Vdbe*);
-SQLITE_PRIVATE sqlite3 *sqlite3VdbeDb(Vdbe*);
-SQLITE_PRIVATE void sqlite3VdbeSetSql(Vdbe*, const char *z, int n, int);
-SQLITE_PRIVATE void sqlite3VdbeSwap(Vdbe*,Vdbe*);
-SQLITE_PRIVATE VdbeOp *sqlite3VdbeTakeOpArray(Vdbe*, int*, int*);
-SQLITE_PRIVATE void sqlite3VdbeProgramDelete(sqlite3 *, SubProgram *, int);
-
-#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
-SQLITE_PRIVATE int sqlite3VdbeReleaseMemory(int);
-#endif
-SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeRecordUnpack(KeyInfo*,int,const void*,char*,int);
-SQLITE_PRIVATE void sqlite3VdbeDeleteUnpackedRecord(UnpackedRecord*);
-SQLITE_PRIVATE int sqlite3VdbeRecordCompare(int,const void*,UnpackedRecord*);
-
-
-#ifndef NDEBUG
-SQLITE_PRIVATE void sqlite3VdbeComment(Vdbe*, const char*, ...);
-# define VdbeComment(X) sqlite3VdbeComment X
-SQLITE_PRIVATE void sqlite3VdbeNoopComment(Vdbe*, const char*, ...);
-# define VdbeNoopComment(X) sqlite3VdbeNoopComment X
-#else
-# define VdbeComment(X)
-# define VdbeNoopComment(X)
-#endif
-
-#endif
-
-/************** End of vdbe.h ************************************************/
-/************** Continuing where we left off in sqliteInt.h ******************/
-/************** Include pager.h in the middle of sqliteInt.h *****************/
-/************** Begin file pager.h *******************************************/
-/*
-** 2001 September 15
-**
-** 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 header file defines the interface that the sqlite page cache
-** subsystem. The page cache subsystem reads and writes a file a page
-** at a time and provides a journal for rollback.
-**
-** @(#) $Id: pager.h,v 1.104 2009/07/24 19:01:19 drh Exp $
-*/
-
-#ifndef _PAGER_H_
-#define _PAGER_H_
-
-/*
-** Default maximum size for persistent journal files. A negative
-** value means no limit. This value may be overridden using the
-** sqlite3PagerJournalSizeLimit() API. See also "PRAGMA journal_size_limit".
-*/
-#ifndef SQLITE_DEFAULT_JOURNAL_SIZE_LIMIT
- #define SQLITE_DEFAULT_JOURNAL_SIZE_LIMIT -1
-#endif
-
-/*
-** The type used to represent a page number. The first page in a file
-** is called page 1. 0 is used to represent "not a page".
-*/
-typedef u32 Pgno;
-
-/*
-** Each open file is managed by a separate instance of the "Pager" structure.
-*/
-typedef struct Pager Pager;
-
-/*
-** Handle type for pages.
-*/
-typedef struct PgHdr DbPage;
-
-/*
-** Page number PAGER_MJ_PGNO is never used in an SQLite database (it is
-** reserved for working around a windows/posix incompatibility). It is
-** used in the journal to signify that the remainder of the journal file
-** is devoted to storing a master journal name - there are no more pages to
-** roll back. See comments for function writeMasterJournal() in pager.c
-** for details.
-*/
-#define PAGER_MJ_PGNO(x) ((Pgno)((PENDING_BYTE/((x)->pageSize))+1))
-
-/*
-** Allowed values for the flags parameter to sqlite3PagerOpen().
-**
-** NOTE: These values must match the corresponding BTREE_ values in btree.h.
-*/
-#define PAGER_OMIT_JOURNAL 0x0001 /* Do not use a rollback journal */
-#define PAGER_NO_READLOCK 0x0002 /* Omit readlocks on readonly files */
-
-/*
-** Valid values for the second argument to sqlite3PagerLockingMode().
-*/
-#define PAGER_LOCKINGMODE_QUERY -1
-#define PAGER_LOCKINGMODE_NORMAL 0
-#define PAGER_LOCKINGMODE_EXCLUSIVE 1
-
-/*
-** Valid values for the second argument to sqlite3PagerJournalMode().
-*/
-#define PAGER_JOURNALMODE_QUERY -1
-#define PAGER_JOURNALMODE_DELETE 0 /* Commit by deleting journal file */
-#define PAGER_JOURNALMODE_PERSIST 1 /* Commit by zeroing journal header */
-#define PAGER_JOURNALMODE_OFF 2 /* Journal omitted. */
-#define PAGER_JOURNALMODE_TRUNCATE 3 /* Commit by truncating journal */
-#define PAGER_JOURNALMODE_MEMORY 4 /* In-memory journal file */
-
-/*
-** The remainder of this file contains the declarations of the functions
-** that make up the Pager sub-system API. See source code comments for
-** a detailed description of each routine.
-*/
-
-/* Open and close a Pager connection. */
-SQLITE_PRIVATE int sqlite3PagerOpen(
- sqlite3_vfs*,
- Pager **ppPager,
- const char*,
- int,
- int,
- int,
- void(*)(DbPage*)
-);
-SQLITE_PRIVATE int sqlite3PagerClose(Pager *pPager);
-SQLITE_PRIVATE int sqlite3PagerReadFileheader(Pager*, int, unsigned char*);
-
-/* Functions used to configure a Pager object. */
-SQLITE_PRIVATE void sqlite3PagerSetBusyhandler(Pager*, int(*)(void *), void *);
-SQLITE_PRIVATE int sqlite3PagerSetPagesize(Pager*, u16*, int);
-SQLITE_PRIVATE int sqlite3PagerMaxPageCount(Pager*, int);
-SQLITE_PRIVATE void sqlite3PagerSetCachesize(Pager*, int);
-SQLITE_PRIVATE void sqlite3PagerSetSafetyLevel(Pager*,int,int);
-SQLITE_PRIVATE int sqlite3PagerLockingMode(Pager *, int);
-SQLITE_PRIVATE int sqlite3PagerJournalMode(Pager *, int);
-SQLITE_PRIVATE i64 sqlite3PagerJournalSizeLimit(Pager *, i64);
-SQLITE_PRIVATE sqlite3_backup **sqlite3PagerBackupPtr(Pager*);
-
-/* Functions used to obtain and release page references. */
-SQLITE_PRIVATE int sqlite3PagerAcquire(Pager *pPager, Pgno pgno, DbPage **ppPage, int clrFlag);
-#define sqlite3PagerGet(A,B,C) sqlite3PagerAcquire(A,B,C,0)
-SQLITE_PRIVATE DbPage *sqlite3PagerLookup(Pager *pPager, Pgno pgno);
-SQLITE_PRIVATE void sqlite3PagerRef(DbPage*);
-SQLITE_PRIVATE void sqlite3PagerUnref(DbPage*);
-
-/* Operations on page references. */
-SQLITE_PRIVATE int sqlite3PagerWrite(DbPage*);
-SQLITE_PRIVATE void sqlite3PagerDontWrite(DbPage*);
-SQLITE_PRIVATE int sqlite3PagerMovepage(Pager*,DbPage*,Pgno,int);
-SQLITE_PRIVATE int sqlite3PagerPageRefcount(DbPage*);
-SQLITE_PRIVATE void *sqlite3PagerGetData(DbPage *);
-SQLITE_PRIVATE void *sqlite3PagerGetExtra(DbPage *);
-
-/* Functions used to manage pager transactions and savepoints. */
-SQLITE_PRIVATE int sqlite3PagerPagecount(Pager*, int*);
-SQLITE_PRIVATE int sqlite3PagerBegin(Pager*, int exFlag, int);
-SQLITE_PRIVATE int sqlite3PagerCommitPhaseOne(Pager*,const char *zMaster, int);
-SQLITE_PRIVATE int sqlite3PagerSync(Pager *pPager);
-SQLITE_PRIVATE int sqlite3PagerCommitPhaseTwo(Pager*);
-SQLITE_PRIVATE int sqlite3PagerRollback(Pager*);
-SQLITE_PRIVATE int sqlite3PagerOpenSavepoint(Pager *pPager, int n);
-SQLITE_PRIVATE int sqlite3PagerSavepoint(Pager *pPager, int op, int iSavepoint);
-SQLITE_PRIVATE int sqlite3PagerSharedLock(Pager *pPager);
-
-/* Functions used to query pager state and configuration. */
-SQLITE_PRIVATE u8 sqlite3PagerIsreadonly(Pager*);
-SQLITE_PRIVATE int sqlite3PagerRefcount(Pager*);
-SQLITE_PRIVATE const char *sqlite3PagerFilename(Pager*);
-SQLITE_PRIVATE const sqlite3_vfs *sqlite3PagerVfs(Pager*);
-SQLITE_PRIVATE sqlite3_file *sqlite3PagerFile(Pager*);
-SQLITE_PRIVATE const char *sqlite3PagerJournalname(Pager*);
-SQLITE_PRIVATE int sqlite3PagerNosync(Pager*);
-SQLITE_PRIVATE void *sqlite3PagerTempSpace(Pager*);
-SQLITE_PRIVATE int sqlite3PagerIsMemdb(Pager*);
-
-/* Functions used to truncate the database file. */
-SQLITE_PRIVATE void sqlite3PagerTruncateImage(Pager*,Pgno);
-
-/* Functions to support testing and debugging. */
-#if !defined(NDEBUG) || defined(SQLITE_TEST)
-SQLITE_PRIVATE Pgno sqlite3PagerPagenumber(DbPage*);
-SQLITE_PRIVATE int sqlite3PagerIswriteable(DbPage*);
-#endif
-#ifdef SQLITE_TEST
-SQLITE_PRIVATE int *sqlite3PagerStats(Pager*);
-SQLITE_PRIVATE void sqlite3PagerRefdump(Pager*);
- void disable_simulated_io_errors(void);
- void enable_simulated_io_errors(void);
-#else
-# define disable_simulated_io_errors()
-# define enable_simulated_io_errors()
-#endif
-
-#endif /* _PAGER_H_ */
-
-/************** End of pager.h ***********************************************/
-/************** Continuing where we left off in sqliteInt.h ******************/
-/************** Include pcache.h in the middle of sqliteInt.h ****************/
-/************** Begin file pcache.h ******************************************/
-/*
-** 2008 August 05
-**
-** 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 header file defines the interface that the sqlite page cache
-** subsystem.
-**
-** @(#) $Id: pcache.h,v 1.20 2009/07/25 11:46:49 danielk1977 Exp $
-*/
-
-#ifndef _PCACHE_H_
-
-typedef struct PgHdr PgHdr;
-typedef struct PCache PCache;
-
-/*
-** Every page in the cache is controlled by an instance of the following
-** structure.
-*/
-struct PgHdr {
- void *pData; /* Content of this page */
- void *pExtra; /* Extra content */
- PgHdr *pDirty; /* Transient list of dirty pages */
- Pgno pgno; /* Page number for this page */
- Pager *pPager; /* The pager this page is part of */
-#ifdef SQLITE_CHECK_PAGES
- u32 pageHash; /* Hash of page content */
-#endif
- u16 flags; /* PGHDR flags defined below */
-
- /**********************************************************************
- ** Elements above are public. All that follows is private to pcache.c
- ** and should not be accessed by other modules.
- */
- i16 nRef; /* Number of users of this page */
- PCache *pCache; /* Cache that owns this page */
-
- PgHdr *pDirtyNext; /* Next element in list of dirty pages */
- PgHdr *pDirtyPrev; /* Previous element in list of dirty pages */
-};
-
-/* Bit values for PgHdr.flags */
-#define PGHDR_DIRTY 0x002 /* Page has changed */
-#define PGHDR_NEED_SYNC 0x004 /* Fsync the rollback journal before
- ** writing this page to the database */
-#define PGHDR_NEED_READ 0x008 /* Content is unread */
-#define PGHDR_REUSE_UNLIKELY 0x010 /* A hint that reuse is unlikely */
-#define PGHDR_DONT_WRITE 0x020 /* Do not write content to disk */
-
-/* Initialize and shutdown the page cache subsystem */
-SQLITE_PRIVATE int sqlite3PcacheInitialize(void);
-SQLITE_PRIVATE void sqlite3PcacheShutdown(void);
-
-/* Page cache buffer management:
-** These routines implement SQLITE_CONFIG_PAGECACHE.
-*/
-SQLITE_PRIVATE void sqlite3PCacheBufferSetup(void *, int sz, int n);
-
-/* Create a new pager cache.
-** Under memory stress, invoke xStress to try to make pages clean.
-** Only clean and unpinned pages can be reclaimed.
-*/
-SQLITE_PRIVATE void sqlite3PcacheOpen(
- int szPage, /* Size of every page */
- int szExtra, /* Extra space associated with each page */
- int bPurgeable, /* True if pages are on backing store */
- int (*xStress)(void*, PgHdr*), /* Call to try to make pages clean */
- void *pStress, /* Argument to xStress */
- PCache *pToInit /* Preallocated space for the PCache */
-);
-
-/* Modify the page-size after the cache has been created. */
-SQLITE_PRIVATE void sqlite3PcacheSetPageSize(PCache *, int);
-
-/* Return the size in bytes of a PCache object. Used to preallocate
-** storage space.
-*/
-SQLITE_PRIVATE int sqlite3PcacheSize(void);
-
-/* One release per successful fetch. Page is pinned until released.
-** Reference counted.
-*/
-SQLITE_PRIVATE int sqlite3PcacheFetch(PCache*, Pgno, int createFlag, PgHdr**);
-SQLITE_PRIVATE void sqlite3PcacheRelease(PgHdr*);
-
-SQLITE_PRIVATE void sqlite3PcacheDrop(PgHdr*); /* Remove page from cache */
-SQLITE_PRIVATE void sqlite3PcacheMakeDirty(PgHdr*); /* Make sure page is marked dirty */
-SQLITE_PRIVATE void sqlite3PcacheMakeClean(PgHdr*); /* Mark a single page as clean */
-SQLITE_PRIVATE void sqlite3PcacheCleanAll(PCache*); /* Mark all dirty list pages as clean */
-
-/* Change a page number. Used by incr-vacuum. */
-SQLITE_PRIVATE void sqlite3PcacheMove(PgHdr*, Pgno);
-
-/* Remove all pages with pgno>x. Reset the cache if x==0 */
-SQLITE_PRIVATE void sqlite3PcacheTruncate(PCache*, Pgno x);
-
-/* Get a list of all dirty pages in the cache, sorted by page number */
-SQLITE_PRIVATE PgHdr *sqlite3PcacheDirtyList(PCache*);
-
-/* Reset and close the cache object */
-SQLITE_PRIVATE void sqlite3PcacheClose(PCache*);
-
-/* Clear flags from pages of the page cache */
-SQLITE_PRIVATE void sqlite3PcacheClearSyncFlags(PCache *);
-
-/* Discard the contents of the cache */
-SQLITE_PRIVATE void sqlite3PcacheClear(PCache*);
-
-/* Return the total number of outstanding page references */
-SQLITE_PRIVATE int sqlite3PcacheRefCount(PCache*);
-
-/* Increment the reference count of an existing page */
-SQLITE_PRIVATE void sqlite3PcacheRef(PgHdr*);
-
-SQLITE_PRIVATE int sqlite3PcachePageRefcount(PgHdr*);
-
-/* Return the total number of pages stored in the cache */
-SQLITE_PRIVATE int sqlite3PcachePagecount(PCache*);
-
-#if defined(SQLITE_CHECK_PAGES) || defined(SQLITE_DEBUG)
-/* Iterate through all dirty pages currently stored in the cache. This
-** interface is only available if SQLITE_CHECK_PAGES is defined when the
-** library is built.
-*/
-SQLITE_PRIVATE void sqlite3PcacheIterateDirty(PCache *pCache, void (*xIter)(PgHdr *));
-#endif
-
-/* Set and get the suggested cache-size for the specified pager-cache.
-**
-** If no global maximum is configured, then the system attempts to limit
-** the total number of pages cached by purgeable pager-caches to the sum
-** of the suggested cache-sizes.
-*/
-SQLITE_PRIVATE void sqlite3PcacheSetCachesize(PCache *, int);
-#ifdef SQLITE_TEST
-SQLITE_PRIVATE int sqlite3PcacheGetCachesize(PCache *);
-#endif
-
-#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
-/* Try to return memory used by the pcache module to the main memory heap */
-SQLITE_PRIVATE int sqlite3PcacheReleaseMemory(int);
-#endif
-
-#ifdef SQLITE_TEST
-SQLITE_PRIVATE void sqlite3PcacheStats(int*,int*,int*,int*);
-#endif
-
-SQLITE_PRIVATE void sqlite3PCacheSetDefault(void);
-
-#endif /* _PCACHE_H_ */
-
-/************** End of pcache.h **********************************************/
-/************** Continuing where we left off in sqliteInt.h ******************/
-
-/************** Include os.h in the middle of sqliteInt.h ********************/
-/************** Begin file os.h **********************************************/
-/*
-** 2001 September 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 header file (together with is companion C source-code file
-** "os.c") attempt to abstract the underlying operating system so that
-** the SQLite library will work on both POSIX and windows systems.
-**
-** This header file is #include-ed by sqliteInt.h and thus ends up
-** being included by every source file.
-**
-** $Id: os.h,v 1.108 2009/02/05 16:31:46 drh Exp $
-*/
-#ifndef _SQLITE_OS_H_
-#define _SQLITE_OS_H_
-
-/*
-** 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
-
-/*
-** 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
-*/
-#if SQLITE_OS_WIN
-# include <windows.h>
-# define SQLITE_TEMPNAME_SIZE (MAX_PATH+50)
-#elif SQLITE_OS_OS2
-# if (__GNUC__ > 3 || __GNUC__ == 3 && __GNUC_MINOR__ >= 3) && defined(OS2_HIGH_MEMORY)
-# include <os2safe.h> /* has to be included before os2.h for linking to work */
-# endif
-# define INCL_DOSDATETIME
-# define INCL_DOSFILEMGR
-# define INCL_DOSERRORS
-# define INCL_DOSMISC
-# define INCL_DOSPROCESS
-# define INCL_DOSMODULEMGR
-# define INCL_DOSSEMAPHORES
-# include <os2.h>
-# include <uconv.h>
-# define SQLITE_TEMPNAME_SIZE (CCHMAXPATHCOMP)
-#else
-# define SQLITE_TEMPNAME_SIZE 200
-#endif
-
-/* If the SET_FULLSYNC macro is not defined above, then make it
-** a no-op
-*/
-#ifndef SET_FULLSYNC
-# define SET_FULLSYNC(x,y)
-#endif
-
-/*
-** The default size of a disk sector
-*/
-#ifndef SQLITE_DEFAULT_SECTOR_SIZE
-# define SQLITE_DEFAULT_SECTOR_SIZE 512
-#endif
-
-/*
-** Temporary files are named starting with this prefix followed by 16 random
-** alphanumeric characters, and no file extension. They are stored in the
-** OS's standard temporary file directory, and are deleted prior to exit.
-** If sqlite is being embedded in another program, you may wish to change the
-** prefix to reflect your program's name, so that if your program exits
-** prematurely, old temporary files can be easily identified. This can be done
-** using -DSQLITE_TEMP_FILE_PREFIX=myprefix_ on the compiler command line.
-**
-** 2006-10-31: The default prefix used to be "sqlite_". But then
-** Mcafee started using SQLite in their anti-virus product and it
-** started putting files with the "sqlite" name in the c:/temp folder.
-** This annoyed many windows users. Those users would then do a
-** Google search for "sqlite", find the telephone numbers of the
-** developers and call to wake them up at night and complain.
-** For this reason, the default name prefix is changed to be "sqlite"
-** spelled backwards. So the temp files are still identified, but
-** anybody smart enough to figure out the code is also likely smart
-** enough to know that calling the developer will not help get rid
-** of the file.
-*/
-#ifndef SQLITE_TEMP_FILE_PREFIX
-# define SQLITE_TEMP_FILE_PREFIX "etilqs_"
-#endif
-
-/*
-** The following values may be passed as the second argument to
-** sqlite3OsLock(). The various locks exhibit the following semantics:
-**
-** SHARED: Any number of processes may hold a SHARED lock simultaneously.
-** RESERVED: A single process may hold a RESERVED lock on a file at
-** any time. Other processes may hold and obtain new SHARED locks.
-** PENDING: A single process may hold a PENDING lock on a file at
-** any one time. Existing SHARED locks may persist, but no new
-** SHARED locks may be obtained by other processes.
-** EXCLUSIVE: An EXCLUSIVE lock precludes all other locks.
-**
-** PENDING_LOCK may not be passed directly to sqlite3OsLock(). Instead, a
-** process that requests an EXCLUSIVE lock may actually obtain a PENDING
-** lock. This can be upgraded to an EXCLUSIVE lock by a subsequent call to
-** sqlite3OsLock().
-*/
-#define NO_LOCK 0
-#define SHARED_LOCK 1
-#define RESERVED_LOCK 2
-#define PENDING_LOCK 3
-#define EXCLUSIVE_LOCK 4
-
-/*
-** File Locking Notes: (Mostly about windows but also some info for Unix)
-**
-** We cannot use LockFileEx() or UnlockFileEx() on Win95/98/ME because
-** those functions are not available. So we use only LockFile() and
-** UnlockFile().
-**
-** LockFile() prevents not just writing but also reading by other processes.
-** A SHARED_LOCK is obtained by locking a single randomly-chosen
-** byte out of a specific range of bytes. The lock byte is obtained at
-** random so two separate readers can probably access the file at the
-** same time, unless they are unlucky and choose the same lock byte.
-** An EXCLUSIVE_LOCK is obtained by locking all bytes in the range.
-** There can only be one writer. A RESERVED_LOCK is obtained by locking
-** a single byte of the file that is designated as the reserved lock byte.
-** A PENDING_LOCK is obtained by locking a designated byte different from
-** the RESERVED_LOCK byte.
-**
-** On WinNT/2K/XP systems, LockFileEx() and UnlockFileEx() are available,
-** which means we can use reader/writer locks. When reader/writer locks
-** are used, the lock is placed on the same range of bytes that is used
-** for probabilistic locking in Win95/98/ME. Hence, the locking scheme
-** will support two or more Win95 readers or two or more WinNT readers.
-** But a single Win95 reader will lock out all WinNT readers and a single
-** WinNT reader will lock out all other Win95 readers.
-**
-** The following #defines specify the range of bytes used for locking.
-** SHARED_SIZE is the number of bytes available in the pool from which
-** a random byte is selected for a shared lock. The pool of bytes for
-** shared locks begins at SHARED_FIRST.
-**
-** The same locking strategy and
-** byte ranges are used for Unix. This leaves open the possiblity of having
-** clients on win95, winNT, and unix all talking to the same shared file
-** and all locking correctly. To do so would require that samba (or whatever
-** tool is being used for file sharing) implements locks correctly between
-** windows and unix. I'm guessing that isn't likely to happen, but by
-** using the same locking range we are at least open to the possibility.
-**
-** Locking in windows is manditory. For this reason, we cannot store
-** actual data in the bytes used for locking. The pager never allocates
-** the pages involved in locking therefore. SHARED_SIZE is selected so
-** that all locks will fit on a single page even at the minimum page size.
-** PENDING_BYTE defines the beginning of the locks. By default PENDING_BYTE
-** is set high so that we don't have to allocate an unused page except
-** for very large databases. But one should test the page skipping logic
-** by setting PENDING_BYTE low and running the entire regression suite.
-**
-** Changing the value of PENDING_BYTE results in a subtly incompatible
-** file format. Depending on how it is changed, you might not notice
-** the incompatibility right away, even running a full regression test.
-** The default location of PENDING_BYTE is the first byte past the
-** 1GB boundary.
-**
-*/
-#define PENDING_BYTE sqlite3PendingByte
-#define RESERVED_BYTE (PENDING_BYTE+1)
-#define SHARED_FIRST (PENDING_BYTE+2)
-#define SHARED_SIZE 510
-
-/*
-** Wrapper around OS specific sqlite3_os_init() function.
-*/
-SQLITE_PRIVATE int sqlite3OsInit(void);
-
-/*
-** Functions for accessing sqlite3_file methods
-*/
-SQLITE_PRIVATE int sqlite3OsClose(sqlite3_file*);
-SQLITE_PRIVATE int sqlite3OsRead(sqlite3_file*, void*, int amt, i64 offset);
-SQLITE_PRIVATE int sqlite3OsWrite(sqlite3_file*, const void*, int amt, i64 offset);
-SQLITE_PRIVATE int sqlite3OsTruncate(sqlite3_file*, i64 size);
-SQLITE_PRIVATE int sqlite3OsSync(sqlite3_file*, int);
-SQLITE_PRIVATE int sqlite3OsFileSize(sqlite3_file*, i64 *pSize);
-SQLITE_PRIVATE int sqlite3OsLock(sqlite3_file*, int);
-SQLITE_PRIVATE int sqlite3OsUnlock(sqlite3_file*, int);
-SQLITE_PRIVATE int sqlite3OsCheckReservedLock(sqlite3_file *id, int *pResOut);
-SQLITE_PRIVATE int sqlite3OsFileControl(sqlite3_file*,int,void*);
-#define SQLITE_FCNTL_DB_UNCHANGED 0xca093fa0
-SQLITE_PRIVATE int sqlite3OsSectorSize(sqlite3_file *id);
-SQLITE_PRIVATE int sqlite3OsDeviceCharacteristics(sqlite3_file *id);
-
-/*
-** Functions for accessing sqlite3_vfs methods
-*/
-SQLITE_PRIVATE int sqlite3OsOpen(sqlite3_vfs *, const char *, sqlite3_file*, int, int *);
-SQLITE_PRIVATE int sqlite3OsDelete(sqlite3_vfs *, const char *, int);
-SQLITE_PRIVATE int sqlite3OsAccess(sqlite3_vfs *, const char *, int, int *pResOut);
-SQLITE_PRIVATE int sqlite3OsFullPathname(sqlite3_vfs *, const char *, int, char *);
-#ifndef SQLITE_OMIT_LOAD_EXTENSION
-SQLITE_PRIVATE void *sqlite3OsDlOpen(sqlite3_vfs *, const char *);
-SQLITE_PRIVATE void sqlite3OsDlError(sqlite3_vfs *, int, char *);
-SQLITE_PRIVATE void (*sqlite3OsDlSym(sqlite3_vfs *, void *, const char *))(void);
-SQLITE_PRIVATE void sqlite3OsDlClose(sqlite3_vfs *, void *);
-#endif /* SQLITE_OMIT_LOAD_EXTENSION */
-SQLITE_PRIVATE int sqlite3OsRandomness(sqlite3_vfs *, int, char *);
-SQLITE_PRIVATE int sqlite3OsSleep(sqlite3_vfs *, int);
-SQLITE_PRIVATE int sqlite3OsCurrentTime(sqlite3_vfs *, double*);
-
-/*
-** Convenience functions for opening and closing files using
-** sqlite3_malloc() to obtain space for the file-handle structure.
-*/
-SQLITE_PRIVATE int sqlite3OsOpenMalloc(sqlite3_vfs *, const char *, sqlite3_file **, int,int*);
-SQLITE_PRIVATE int sqlite3OsCloseFree(sqlite3_file *);
-
-#endif /* _SQLITE_OS_H_ */
-
-/************** End of os.h **************************************************/
-/************** Continuing where we left off in sqliteInt.h ******************/
-/************** Include mutex.h in the middle of sqliteInt.h *****************/
-/************** Begin file mutex.h *******************************************/
-/*
-** 2007 August 28
-**
-** 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 common header for all mutex implementations.
-** The sqliteInt.h header #includes this file so that it is available
-** to all source files. We break it out in an effort to keep the code
-** better organized.
-**
-** NOTE: source files should *not* #include this header file directly.
-** Source files should #include the sqliteInt.h file and let that file
-** include this one indirectly.
-**
-** $Id: mutex.h,v 1.9 2008/10/07 15:25:48 drh Exp $
-*/
-
-
-/*
-** Figure out what version of the code to use. The choices are
-**
-** SQLITE_MUTEX_OMIT No mutex logic. Not even stubs. The
-** mutexes implemention cannot be overridden
-** at start-time.
-**
-** SQLITE_MUTEX_NOOP For single-threaded applications. No
-** mutual exclusion is provided. But this
-** implementation can be overridden at
-** start-time.
-**
-** SQLITE_MUTEX_PTHREADS For multi-threaded applications on Unix.
-**
-** SQLITE_MUTEX_W32 For multi-threaded applications on Win32.
-**
-** SQLITE_MUTEX_OS2 For multi-threaded applications on OS/2.
-*/
-#if !SQLITE_THREADSAFE
-# define SQLITE_MUTEX_OMIT
-#endif
-#if SQLITE_THREADSAFE && !defined(SQLITE_MUTEX_NOOP)
-# if SQLITE_OS_UNIX
-# define SQLITE_MUTEX_PTHREADS
-# elif SQLITE_OS_WIN
-# define SQLITE_MUTEX_W32
-# elif SQLITE_OS_OS2
-# define SQLITE_MUTEX_OS2
-# else
-# define SQLITE_MUTEX_NOOP
-# endif
-#endif
-
-#ifdef SQLITE_MUTEX_OMIT
-/*
-** If this is a no-op implementation, implement everything as macros.
-*/
-#define sqlite3_mutex_alloc(X) ((sqlite3_mutex*)8)
-#define sqlite3_mutex_free(X)
-#define sqlite3_mutex_enter(X)
-#define sqlite3_mutex_try(X) SQLITE_OK
-#define sqlite3_mutex_leave(X)
-#define sqlite3_mutex_held(X) 1
-#define sqlite3_mutex_notheld(X) 1
-#define sqlite3MutexAlloc(X) ((sqlite3_mutex*)8)
-#define sqlite3MutexInit() SQLITE_OK
-#define sqlite3MutexEnd()
-#endif /* defined(SQLITE_OMIT_MUTEX) */
-
-/************** End of mutex.h ***********************************************/
-/************** Continuing where we left off in sqliteInt.h ******************/
-
-
-/*
-** Each database file to be accessed by the system is an instance
-** of the following structure. There are normally two of these structures
-** in the sqlite.aDb[] array. aDb[0] is the main database file and
-** aDb[1] is the database file used to hold temporary tables. Additional
-** databases may be attached.
-*/
-struct Db {
- char *zName; /* Name of this database */
- Btree *pBt; /* The B*Tree structure for this database file */
- u8 inTrans; /* 0: not writable. 1: Transaction. 2: Checkpoint */
- u8 safety_level; /* How aggressive at syncing data to disk */
- Schema *pSchema; /* Pointer to database schema (possibly shared) */
-};
-
-/*
-** An instance of the following structure stores a database schema.
-**
-** If there are no virtual tables configured in this schema, the
-** Schema.db variable is set to NULL. After the first virtual table
-** has been added, it is set to point to the database connection
-** used to create the connection. Once a virtual table has been
-** added to the Schema structure and the Schema.db variable populated,
-** only that database connection may use the Schema to prepare
-** statements.
-*/
-struct Schema {
- int schema_cookie; /* Database schema version number for this file */
- Hash tblHash; /* All tables indexed by name */
- Hash idxHash; /* All (named) indices indexed by name */
- Hash trigHash; /* All triggers indexed by name */
- Table *pSeqTab; /* The sqlite_sequence table used by AUTOINCREMENT */
- u8 file_format; /* Schema format version for this file */
- u8 enc; /* Text encoding used by this database */
- u16 flags; /* Flags associated with this schema */
- int cache_size; /* Number of pages to use in the cache */
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- sqlite3 *db; /* "Owner" connection. See comment above */
-#endif
-};
-
-/*
-** These macros can be used to test, set, or clear bits in the
-** Db.flags field.
-*/
-#define DbHasProperty(D,I,P) (((D)->aDb[I].pSchema->flags&(P))==(P))
-#define DbHasAnyProperty(D,I,P) (((D)->aDb[I].pSchema->flags&(P))!=0)
-#define DbSetProperty(D,I,P) (D)->aDb[I].pSchema->flags|=(P)
-#define DbClearProperty(D,I,P) (D)->aDb[I].pSchema->flags&=~(P)
-
-/*
-** Allowed values for the DB.flags field.
-**
-** The DB_SchemaLoaded flag is set after the database schema has been
-** read into internal hash tables.
-**
-** DB_UnresetViews means that one or more views have column names that
-** have been filled out. If the schema changes, these column names might
-** changes and so the view will need to be reset.
-*/
-#define DB_SchemaLoaded 0x0001 /* The schema has been loaded */
-#define DB_UnresetViews 0x0002 /* Some views have defined column names */
-#define DB_Empty 0x0004 /* The file is empty (length 0 bytes) */
-
-/*
-** The number of different kinds of things that can be limited
-** using the sqlite3_limit() interface.
-*/
-#define SQLITE_N_LIMIT (SQLITE_LIMIT_TRIGGER_DEPTH+1)
-
-/*
-** Lookaside malloc is a set of fixed-size buffers that can be used
-** to satisfy small transient memory allocation requests for objects
-** associated with a particular database connection. The use of
-** lookaside malloc provides a significant performance enhancement
-** (approx 10%) by avoiding numerous malloc/free requests while parsing
-** SQL statements.
-**
-** The Lookaside structure holds configuration information about the
-** lookaside malloc subsystem. Each available memory allocation in
-** the lookaside subsystem is stored on a linked list of LookasideSlot
-** objects.
-**
-** Lookaside allocations are only allowed for objects that are associated
-** with a particular database connection. Hence, schema information cannot
-** be stored in lookaside because in shared cache mode the schema information
-** is shared by multiple database connections. Therefore, while parsing
-** schema information, the Lookaside.bEnabled flag is cleared so that
-** lookaside allocations are not used to construct the schema objects.
-*/
-struct Lookaside {
- u16 sz; /* Size of each buffer in bytes */
- u8 bEnabled; /* False to disable new lookaside allocations */
- u8 bMalloced; /* True if pStart obtained from sqlite3_malloc() */
- int nOut; /* Number of buffers currently checked out */
- int mxOut; /* Highwater mark for nOut */
- LookasideSlot *pFree; /* List of available buffers */
- void *pStart; /* First byte of available memory space */
- void *pEnd; /* First byte past end of available space */
-};
-struct LookasideSlot {
- LookasideSlot *pNext; /* Next buffer in the list of free buffers */
-};
-
-/*
-** A hash table for function definitions.
-**
-** Hash each FuncDef structure into one of the FuncDefHash.a[] slots.
-** Collisions are on the FuncDef.pHash chain.
-*/
-struct FuncDefHash {
- FuncDef *a[23]; /* Hash table for functions */
-};
-
-/*
-** Each database is an instance of the following structure.
-**
-** The sqlite.lastRowid records the last insert rowid generated by an
-** insert statement. Inserts on views do not affect its value. Each
-** trigger has its own context, so that lastRowid can be updated inside
-** triggers as usual. The previous value will be restored once the trigger
-** exits. Upon entering a before or instead of trigger, lastRowid is no
-** longer (since after version 2.8.12) reset to -1.
-**
-** The sqlite.nChange does not count changes within triggers and keeps no
-** context. It is reset at start of sqlite3_exec.
-** The sqlite.lsChange represents the number of changes made by the last
-** insert, update, or delete statement. It remains constant throughout the
-** length of a statement and is then updated by OP_SetCounts. It keeps a
-** context stack just like lastRowid so that the count of changes
-** within a trigger is not seen outside the trigger. Changes to views do not
-** affect the value of lsChange.
-** The sqlite.csChange keeps track of the number of current changes (since
-** the last statement) and is used to update sqlite_lsChange.
-**
-** The member variables sqlite.errCode, sqlite.zErrMsg and sqlite.zErrMsg16
-** store the most recent error code and, if applicable, string. The
-** internal function sqlite3Error() is used to set these variables
-** consistently.
-*/
-struct sqlite3 {
- sqlite3_vfs *pVfs; /* OS Interface */
- int nDb; /* Number of backends currently in use */
- Db *aDb; /* All backends */
- int flags; /* Miscellaneous flags. See below */
- int openFlags; /* Flags passed to sqlite3_vfs.xOpen() */
- int errCode; /* Most recent error code (SQLITE_*) */
- int errMask; /* & result codes with this before returning */
- u8 autoCommit; /* The auto-commit flag. */
- u8 temp_store; /* 1: file 2: memory 0: default */
- u8 mallocFailed; /* True if we have seen a malloc failure */
- u8 dfltLockMode; /* Default locking-mode for attached dbs */
- u8 dfltJournalMode; /* Default journal mode for attached dbs */
- signed char nextAutovac; /* Autovac setting after VACUUM if >=0 */
- int nextPagesize; /* Pagesize after VACUUM if >0 */
- int nTable; /* Number of tables in the database */
- CollSeq *pDfltColl; /* The default collating sequence (BINARY) */
- i64 lastRowid; /* ROWID of most recent insert (see above) */
- u32 magic; /* Magic number for detect library misuse */
- int nChange; /* Value returned by sqlite3_changes() */
- int nTotalChange; /* Value returned by sqlite3_total_changes() */
- sqlite3_mutex *mutex; /* Connection mutex */
- int aLimit[SQLITE_N_LIMIT]; /* Limits */
- struct sqlite3InitInfo { /* Information used during initialization */
- int iDb; /* When back is being initialized */
- int newTnum; /* Rootpage of table being initialized */
- u8 busy; /* TRUE if currently initializing */
- u8 orphanTrigger; /* Last statement is orphaned TEMP trigger */
- } init;
- int nExtension; /* Number of loaded extensions */
- void **aExtension; /* Array of shared library handles */
- struct Vdbe *pVdbe; /* List of active virtual machines */
- int activeVdbeCnt; /* Number of VDBEs currently executing */
- int writeVdbeCnt; /* Number of active VDBEs that are writing */
- void (*xTrace)(void*,const char*); /* Trace function */
- void *pTraceArg; /* Argument to the trace function */
- void (*xProfile)(void*,const char*,u64); /* Profiling function */
- void *pProfileArg; /* Argument to profile function */
- void *pCommitArg; /* Argument to xCommitCallback() */
- int (*xCommitCallback)(void*); /* Invoked at every commit. */
- void *pRollbackArg; /* Argument to xRollbackCallback() */
- void (*xRollbackCallback)(void*); /* Invoked at every commit. */
- void *pUpdateArg;
- void (*xUpdateCallback)(void*,int, const char*,const char*,sqlite_int64);
- void(*xCollNeeded)(void*,sqlite3*,int eTextRep,const char*);
- void(*xCollNeeded16)(void*,sqlite3*,int eTextRep,const void*);
- void *pCollNeededArg;
- sqlite3_value *pErr; /* Most recent error message */
- char *zErrMsg; /* Most recent error message (UTF-8 encoded) */
- char *zErrMsg16; /* Most recent error message (UTF-16 encoded) */
- union {
- volatile int isInterrupted; /* True if sqlite3_interrupt has been called */
- double notUsed1; /* Spacer */
- } u1;
- Lookaside lookaside; /* Lookaside malloc configuration */
-#ifndef SQLITE_OMIT_AUTHORIZATION
- int (*xAuth)(void*,int,const char*,const char*,const char*,const char*);
- /* Access authorization function */
- void *pAuthArg; /* 1st argument to the access auth function */
-#endif
-#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
- int (*xProgress)(void *); /* The progress callback */
- void *pProgressArg; /* Argument to the progress callback */
- int nProgressOps; /* Number of opcodes for progress callback */
-#endif
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- Hash aModule; /* populated by sqlite3_create_module() */
- Table *pVTab; /* vtab with active Connect/Create method */
- VTable **aVTrans; /* Virtual tables with open transactions */
- int nVTrans; /* Allocated size of aVTrans */
- VTable *pDisconnect; /* Disconnect these in next sqlite3_prepare() */
-#endif
- FuncDefHash aFunc; /* Hash table of connection functions */
- Hash aCollSeq; /* All collating sequences */
- BusyHandler busyHandler; /* Busy callback */
- int busyTimeout; /* Busy handler timeout, in msec */
- Db aDbStatic[2]; /* Static space for the 2 default backends */
- Savepoint *pSavepoint; /* List of active savepoints */
- int nSavepoint; /* Number of non-transaction savepoints */
- int nStatement; /* Number of nested statement-transactions */
- u8 isTransactionSavepoint; /* True if the outermost savepoint is a TS */
-
-#ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
- /* The following variables are all protected by the STATIC_MASTER
- ** mutex, not by sqlite3.mutex. They are used by code in notify.c.
- **
- ** When X.pUnlockConnection==Y, that means that X is waiting for Y to
- ** unlock so that it can proceed.
- **
- ** When X.pBlockingConnection==Y, that means that something that X tried
- ** tried to do recently failed with an SQLITE_LOCKED error due to locks
- ** held by Y.
- */
- sqlite3 *pBlockingConnection; /* Connection that caused SQLITE_LOCKED */
- sqlite3 *pUnlockConnection; /* Connection to watch for unlock */
- void *pUnlockArg; /* Argument to xUnlockNotify */
- void (*xUnlockNotify)(void **, int); /* Unlock notify callback */
- sqlite3 *pNextBlocked; /* Next in list of all blocked connections */
-#endif
-};
-
-/*
-** A macro to discover the encoding of a database.
-*/
-#define ENC(db) ((db)->aDb[0].pSchema->enc)
-
-/*
-** Possible values for the sqlite.flags and or Db.flags fields.
-**
-** On sqlite.flags, the SQLITE_InTrans value means that we have
-** executed a BEGIN. On Db.flags, SQLITE_InTrans means a statement
-** transaction is active on that particular database file.
-*/
-#define SQLITE_VdbeTrace 0x00000001 /* True to trace VDBE execution */
-#define SQLITE_InTrans 0x00000008 /* True if in a transaction */
-#define SQLITE_InternChanges 0x00000010 /* Uncommitted Hash table changes */
-#define SQLITE_FullColNames 0x00000020 /* Show full column names on SELECT */
-#define SQLITE_ShortColNames 0x00000040 /* Show short columns names */
-#define SQLITE_CountRows 0x00000080 /* Count rows changed by INSERT, */
- /* DELETE, or UPDATE and return */
- /* the count using a callback. */
-#define SQLITE_NullCallback 0x00000100 /* Invoke the callback once if the */
- /* result set is empty */
-#define SQLITE_SqlTrace 0x00000200 /* Debug print SQL as it executes */
-#define SQLITE_VdbeListing 0x00000400 /* Debug listings of VDBE programs */
-#define SQLITE_WriteSchema 0x00000800 /* OK to update SQLITE_MASTER */
-#define SQLITE_NoReadlock 0x00001000 /* Readlocks are omitted when
- ** accessing read-only databases */
-#define SQLITE_IgnoreChecks 0x00002000 /* Do not enforce check constraints */
-#define SQLITE_ReadUncommitted 0x00004000 /* For shared-cache mode */
-#define SQLITE_LegacyFileFmt 0x00008000 /* Create new databases in format 1 */
-#define SQLITE_FullFSync 0x00010000 /* Use full fsync on the backend */
-#define SQLITE_LoadExtension 0x00020000 /* Enable load_extension */
-
-#define SQLITE_RecoveryMode 0x00040000 /* Ignore schema errors */
-#define SQLITE_ReverseOrder 0x00100000 /* Reverse unordered SELECTs */
-#define SQLITE_RecTriggers 0x00200000 /* Enable recursive triggers */
-
-/*
-** Possible values for the sqlite.magic field.
-** The numbers are obtained at random and have no special meaning, other
-** than being distinct from one another.
-*/
-#define SQLITE_MAGIC_OPEN 0xa029a697 /* Database is open */
-#define SQLITE_MAGIC_CLOSED 0x9f3c2d33 /* Database is closed */
-#define SQLITE_MAGIC_SICK 0x4b771290 /* Error and awaiting close */
-#define SQLITE_MAGIC_BUSY 0xf03b7906 /* Database currently in use */
-#define SQLITE_MAGIC_ERROR 0xb5357930 /* An SQLITE_MISUSE error occurred */
-
-/*
-** Each SQL function is defined by an instance of the following
-** structure. A pointer to this structure is stored in the sqlite.aFunc
-** hash table. When multiple functions have the same name, the hash table
-** points to a linked list of these structures.
-*/
-struct FuncDef {
- i16 nArg; /* Number of arguments. -1 means unlimited */
- u8 iPrefEnc; /* Preferred text encoding (SQLITE_UTF8, 16LE, 16BE) */
- u8 flags; /* Some combination of SQLITE_FUNC_* */
- void *pUserData; /* User data parameter */
- FuncDef *pNext; /* Next function with same name */
- void (*xFunc)(sqlite3_context*,int,sqlite3_value**); /* Regular function */
- void (*xStep)(sqlite3_context*,int,sqlite3_value**); /* Aggregate step */
- void (*xFinalize)(sqlite3_context*); /* Aggregate finalizer */
- char *zName; /* SQL name of the function. */
- FuncDef *pHash; /* Next with a different name but the same hash */
-};
-
-/*
-** Possible values for FuncDef.flags
-*/
-#define SQLITE_FUNC_LIKE 0x01 /* Candidate for the LIKE optimization */
-#define SQLITE_FUNC_CASE 0x02 /* Case-sensitive LIKE-type function */
-#define SQLITE_FUNC_EPHEM 0x04 /* Ephemeral. Delete with VDBE */
-#define SQLITE_FUNC_NEEDCOLL 0x08 /* sqlite3GetFuncCollSeq() might be called */
-#define SQLITE_FUNC_PRIVATE 0x10 /* Allowed for internal use only */
-#define SQLITE_FUNC_COUNT 0x20 /* Built-in count(*) aggregate */
-
-/*
-** The following three macros, FUNCTION(), LIKEFUNC() and AGGREGATE() are
-** used to create the initializers for the FuncDef structures.
-**
-** FUNCTION(zName, nArg, iArg, bNC, xFunc)
-** Used to create a scalar function definition of a function zName
-** implemented by C function xFunc that accepts nArg arguments. The
-** value passed as iArg is cast to a (void*) and made available
-** as the user-data (sqlite3_user_data()) for the function. If
-** argument bNC is true, then the SQLITE_FUNC_NEEDCOLL flag is set.
-**
-** AGGREGATE(zName, nArg, iArg, bNC, xStep, xFinal)
-** Used to create an aggregate function definition implemented by
-** the C functions xStep and xFinal. The first four parameters
-** are interpreted in the same way as the first 4 parameters to
-** FUNCTION().
-**
-** LIKEFUNC(zName, nArg, pArg, flags)
-** Used to create a scalar function definition of a function zName
-** that accepts nArg arguments and is implemented by a call to C
-** function likeFunc. Argument pArg is cast to a (void *) and made
-** available as the function user-data (sqlite3_user_data()). The
-** FuncDef.flags variable is set to the value passed as the flags
-** parameter.
-*/
-#define FUNCTION(zName, nArg, iArg, bNC, xFunc) \
- {nArg, SQLITE_UTF8, bNC*SQLITE_FUNC_NEEDCOLL, \
- SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, #zName, 0}
-#define STR_FUNCTION(zName, nArg, pArg, bNC, xFunc) \
- {nArg, SQLITE_UTF8, bNC*SQLITE_FUNC_NEEDCOLL, \
- pArg, 0, xFunc, 0, 0, #zName, 0}
-#define LIKEFUNC(zName, nArg, arg, flags) \
- {nArg, SQLITE_UTF8, flags, (void *)arg, 0, likeFunc, 0, 0, #zName, 0}
-#define AGGREGATE(zName, nArg, arg, nc, xStep, xFinal) \
- {nArg, SQLITE_UTF8, nc*SQLITE_FUNC_NEEDCOLL, \
- SQLITE_INT_TO_PTR(arg), 0, 0, xStep,xFinal,#zName,0}
-
-/*
-** All current savepoints are stored in a linked list starting at
-** sqlite3.pSavepoint. The first element in the list is the most recently
-** opened savepoint. Savepoints are added to the list by the vdbe
-** OP_Savepoint instruction.
-*/
-struct Savepoint {
- char *zName; /* Savepoint name (nul-terminated) */
- Savepoint *pNext; /* Parent savepoint (if any) */
-};
-
-/*
-** The following are used as the second parameter to sqlite3Savepoint(),
-** and as the P1 argument to the OP_Savepoint instruction.
-*/
-#define SAVEPOINT_BEGIN 0
-#define SAVEPOINT_RELEASE 1
-#define SAVEPOINT_ROLLBACK 2
-
-
-/*
-** Each SQLite module (virtual table definition) is defined by an
-** instance of the following structure, stored in the sqlite3.aModule
-** hash table.
-*/
-struct Module {
- const sqlite3_module *pModule; /* Callback pointers */
- const char *zName; /* Name passed to create_module() */
- void *pAux; /* pAux passed to create_module() */
- void (*xDestroy)(void *); /* Module destructor function */
-};
-
-/*
-** information about each column of an SQL table is held in an instance
-** of this structure.
-*/
-struct Column {
- char *zName; /* Name of this column */
- Expr *pDflt; /* Default value of this column */
- char *zDflt; /* Original text of the default value */
- char *zType; /* Data type for this column */
- char *zColl; /* Collating sequence. If NULL, use the default */
- u8 notNull; /* True if there is a NOT NULL constraint */
- u8 isPrimKey; /* True if this column is part of the PRIMARY KEY */
- char affinity; /* One of the SQLITE_AFF_... values */
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- u8 isHidden; /* True if this column is 'hidden' */
-#endif
-};
-
-/*
-** A "Collating Sequence" is defined by an instance of the following
-** structure. Conceptually, a collating sequence consists of a name and
-** a comparison routine that defines the order of that sequence.
-**
-** There may two separate implementations of the collation function, one
-** that processes text in UTF-8 encoding (CollSeq.xCmp) and another that
-** processes text encoded in UTF-16 (CollSeq.xCmp16), using the machine
-** native byte order. When a collation sequence is invoked, SQLite selects
-** the version that will require the least expensive encoding
-** translations, if any.
-**
-** The CollSeq.pUser member variable is an extra parameter that passed in
-** as the first argument to the UTF-8 comparison function, xCmp.
-** CollSeq.pUser16 is the equivalent for the UTF-16 comparison function,
-** xCmp16.
-**
-** If both CollSeq.xCmp and CollSeq.xCmp16 are NULL, it means that the
-** collating sequence is undefined. Indices built on an undefined
-** collating sequence may not be read or written.
-*/
-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.
-*/
-#define SQLITE_SO_ASC 0 /* Sort in ascending order */
-#define SQLITE_SO_DESC 1 /* Sort in ascending order */
-
-/*
-** Column affinity types.
-**
-** These used to have mnemonic name like 'i' for SQLITE_AFF_INTEGER and
-** 't' for SQLITE_AFF_TEXT. But we can save a little space and improve
-** the speed a little by numbering the values consecutively.
-**
-** But rather than start with 0 or 1, we begin with 'a'. That way,
-** when multiple affinity types are concatenated into a string and
-** used as the P4 operand, they will be more readable.
-**
-** Note also that the numeric types are grouped together so that testing
-** for a numeric type is a single comparison.
-*/
-#define SQLITE_AFF_TEXT 'a'
-#define SQLITE_AFF_NONE 'b'
-#define SQLITE_AFF_NUMERIC 'c'
-#define SQLITE_AFF_INTEGER 'd'
-#define SQLITE_AFF_REAL 'e'
-
-#define sqlite3IsNumericAffinity(X) ((X)>=SQLITE_AFF_NUMERIC)
-
-/*
-** The SQLITE_AFF_MASK values masks off the significant bits of an
-** affinity value.
-*/
-#define SQLITE_AFF_MASK 0x67
-
-/*
-** Additional bit values that can be ORed with an affinity without
-** changing the affinity.
-*/
-#define SQLITE_JUMPIFNULL 0x08 /* jumps if either operand is NULL */
-#define SQLITE_STOREP2 0x10 /* Store result in reg[P2] rather than jump */
-
-/*
-** An object of this type is created for each virtual table present in
-** the database schema.
-**
-** If the database schema is shared, then there is one instance of this
-** structure for each database connection (sqlite3*) that uses the shared
-** schema. This is because each database connection requires its own unique
-** instance of the sqlite3_vtab* handle used to access the virtual table
-** implementation. sqlite3_vtab* handles can not be shared between
-** database connections, even when the rest of the in-memory database
-** schema is shared, as the implementation often stores the database
-** connection handle passed to it via the xConnect() or xCreate() method
-** during initialization internally. This database connection handle may
-** then used by the virtual table implementation to access real tables
-** within the database. So that they appear as part of the callers
-** transaction, these accesses need to be made via the same database
-** connection as that used to execute SQL operations on the virtual table.
-**
-** All VTable objects that correspond to a single table in a shared
-** database schema are initially stored in a linked-list pointed to by
-** the Table.pVTable member variable of the corresponding Table object.
-** When an sqlite3_prepare() operation is required to access the virtual
-** table, it searches the list for the VTable that corresponds to the
-** database connection doing the preparing so as to use the correct
-** sqlite3_vtab* handle in the compiled query.
-**
-** When an in-memory Table object is deleted (for example when the
-** schema is being reloaded for some reason), the VTable objects are not
-** deleted and the sqlite3_vtab* handles are not xDisconnect()ed
-** immediately. Instead, they are moved from the Table.pVTable list to
-** another linked list headed by the sqlite3.pDisconnect member of the
-** corresponding sqlite3 structure. They are then deleted/xDisconnected
-** next time a statement is prepared using said sqlite3*. This is done
-** to avoid deadlock issues involving multiple sqlite3.mutex mutexes.
-** Refer to comments above function sqlite3VtabUnlockList() for an
-** explanation as to why it is safe to add an entry to an sqlite3.pDisconnect
-** list without holding the corresponding sqlite3.mutex mutex.
-**
-** The memory for objects of this type is always allocated by
-** sqlite3DbMalloc(), using the connection handle stored in VTable.db as
-** the first argument.
-*/
-struct VTable {
- sqlite3 *db; /* Database connection associated with this table */
- Module *pMod; /* Pointer to module implementation */
- sqlite3_vtab *pVtab; /* Pointer to vtab instance */
- int nRef; /* Number of pointers to this structure */
- VTable *pNext; /* Next in linked list (see above) */
-};
-
-/*
-** Each SQL table is represented in memory by an instance of the
-** following structure.
-**
-** Table.zName is the name of the table. The case of the original
-** CREATE TABLE statement is stored, but case is not significant for
-** comparisons.
-**
-** Table.nCol is the number of columns in this table. Table.aCol is a
-** pointer to an array of Column structures, one for each column.
-**
-** If the table has an INTEGER PRIMARY KEY, then Table.iPKey is the index of
-** the column that is that key. Otherwise Table.iPKey is negative. Note
-** that the datatype of the PRIMARY KEY must be INTEGER for this field to
-** be set. An INTEGER PRIMARY KEY is used as the rowid for each row of
-** the table. If a table has no INTEGER PRIMARY KEY, then a random rowid
-** is generated for each row of the table. TF_HasPrimaryKey is set if
-** the table has any PRIMARY KEY, INTEGER or otherwise.
-**
-** Table.tnum is the page number for the root BTree page of the table in the
-** database file. If Table.iDb is the index of the database table backend
-** in sqlite.aDb[]. 0 is for the main database and 1 is for the file that
-** holds temporary tables and indices. If TF_Ephemeral is set
-** then the table is stored in a file that is automatically deleted
-** when the VDBE cursor to the table is closed. In this case Table.tnum
-** refers VDBE cursor number that holds the table open, not to the root
-** page number. Transient tables are used to hold the results of a
-** sub-query that appears instead of a real table name in the FROM clause
-** of a SELECT statement.
-*/
-struct Table {
- sqlite3 *dbMem; /* DB connection used for lookaside allocations. */
- char *zName; /* Name of the table or view */
- int iPKey; /* If not negative, use aCol[iPKey] as the primary key */
- int nCol; /* Number of columns in this table */
- Column *aCol; /* Information about each column */
- Index *pIndex; /* List of SQL indexes on this table. */
- int tnum; /* Root BTree node for this table (see note above) */
- Select *pSelect; /* NULL for tables. Points to definition if a view. */
- u16 nRef; /* Number of pointers to this Table */
- u8 tabFlags; /* Mask of TF_* values */
- u8 keyConf; /* What to do in case of uniqueness conflict on iPKey */
- FKey *pFKey; /* Linked list of all foreign keys in this table */
- char *zColAff; /* String defining the affinity of each column */
-#ifndef SQLITE_OMIT_CHECK
- Expr *pCheck; /* The AND of all CHECK constraints */
-#endif
-#ifndef SQLITE_OMIT_ALTERTABLE
- int addColOffset; /* Offset in CREATE TABLE stmt to add a new column */
-#endif
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- VTable *pVTable; /* List of VTable objects. */
- int nModuleArg; /* Number of arguments to the module */
- char **azModuleArg; /* Text of all module args. [0] is module name */
-#endif
- Trigger *pTrigger; /* List of triggers stored in pSchema */
- Schema *pSchema; /* Schema that contains this table */
- Table *pNextZombie; /* Next on the Parse.pZombieTab list */
-};
-
-/*
-** Allowed values for Tabe.tabFlags.
-*/
-#define TF_Readonly 0x01 /* Read-only system table */
-#define TF_Ephemeral 0x02 /* An ephemeral table */
-#define TF_HasPrimaryKey 0x04 /* Table has a primary key */
-#define TF_Autoincrement 0x08 /* Integer primary key is autoincrement */
-#define TF_Virtual 0x10 /* Is a virtual table */
-#define TF_NeedMetadata 0x20 /* aCol[].zType and aCol[].pColl missing */
-
-
-
-/*
-** Test to see whether or not a table is a virtual table. This is
-** done as a macro so that it will be optimized out when virtual
-** table support is omitted from the build.
-*/
-#ifndef SQLITE_OMIT_VIRTUALTABLE
-# define IsVirtual(X) (((X)->tabFlags & TF_Virtual)!=0)
-# define IsHiddenColumn(X) ((X)->isHidden)
-#else
-# define IsVirtual(X) 0
-# define IsHiddenColumn(X) 0
-#endif
-
-/*
-** Each foreign key constraint is an instance of the following structure.
-**
-** A foreign key is associated with two tables. The "from" table is
-** the table that contains the REFERENCES clause that creates the foreign
-** key. The "to" table is the table that is named in the REFERENCES clause.
-** Consider this example:
-**
-** CREATE TABLE ex1(
-** a INTEGER PRIMARY KEY,
-** b INTEGER CONSTRAINT fk1 REFERENCES ex2(x)
-** );
-**
-** For foreign key "fk1", the from-table is "ex1" and the to-table is "ex2".
-**
-** Each REFERENCES clause generates an instance of the following structure
-** which is attached to the from-table. The to-table need not exist when
-** the from-table is created. The existence of the to-table is not checked.
-*/
-struct FKey {
- Table *pFrom; /* The table that contains the REFERENCES clause */
- FKey *pNextFrom; /* Next foreign key in pFrom */
- char *zTo; /* Name of table that the key points to */
- int nCol; /* Number of columns in this key */
- u8 isDeferred; /* True if constraint checking is deferred till COMMIT */
- u8 updateConf; /* How to resolve conflicts that occur on UPDATE */
- u8 deleteConf; /* How to resolve conflicts that occur on DELETE */
- u8 insertConf; /* How to resolve conflicts that occur on INSERT */
- struct sColMap { /* Mapping of columns in pFrom to columns in zTo */
- int iFrom; /* Index of column in pFrom */
- char *zCol; /* Name of column in zTo. If 0 use PRIMARY KEY */
- } aCol[1]; /* One entry for each of nCol column s */
-};
-
-/*
-** SQLite supports many different ways to resolve a constraint
-** error. ROLLBACK processing means that a constraint violation
-** causes the operation in process to fail and for the current transaction
-** to be rolled back. ABORT processing means the operation in process
-** fails and any prior changes from that one operation are backed out,
-** but the transaction is not rolled back. FAIL processing means that
-** the operation in progress stops and returns an error code. But prior
-** changes due to the same operation are not backed out and no rollback
-** occurs. IGNORE means that the particular row that caused the constraint
-** error is not inserted or updated. Processing continues and no error
-** is returned. REPLACE means that preexisting database rows that caused
-** a UNIQUE constraint violation are removed so that the new insert or
-** update can proceed. Processing continues and no error is reported.
-**
-** RESTRICT, SETNULL, and CASCADE actions apply only to foreign keys.
-** RESTRICT is the same as ABORT for IMMEDIATE foreign keys and the
-** same as ROLLBACK for DEFERRED keys. SETNULL means that the foreign
-** key is set to NULL. CASCADE means that a DELETE or UPDATE of the
-** referenced table row is propagated into the row that holds the
-** foreign key.
-**
-** The following symbolic values are used to record which type
-** of action to take.
-*/
-#define OE_None 0 /* There is no constraint to check */
-#define OE_Rollback 1 /* Fail the operation and rollback the transaction */
-#define OE_Abort 2 /* Back out changes but do no rollback transaction */
-#define OE_Fail 3 /* Stop the operation but leave all prior changes */
-#define OE_Ignore 4 /* Ignore the error. Do not do the INSERT or UPDATE */
-#define OE_Replace 5 /* Delete existing record, then do INSERT or UPDATE */
-
-#define OE_Restrict 6 /* OE_Abort for IMMEDIATE, OE_Rollback for DEFERRED */
-#define OE_SetNull 7 /* Set the foreign key value to NULL */
-#define OE_SetDflt 8 /* Set the foreign key value to its default */
-#define OE_Cascade 9 /* Cascade the changes */
-
-#define OE_Default 99 /* Do whatever the default action is */
-
-
-/*
-** An instance of the following structure is passed as the first
-** argument to sqlite3VdbeKeyCompare and is used to control the
-** comparison of the two index keys.
-*/
-struct KeyInfo {
- sqlite3 *db; /* The database connection */
- u8 enc; /* Text encoding - one of the TEXT_Utf* values */
- u16 nField; /* Number of entries in aColl[] */
- u8 *aSortOrder; /* If defined an aSortOrder[i] is true, sort DESC */
- CollSeq *aColl[1]; /* Collating sequence for each term of the key */
-};
-
-/*
-** An instance of the following structure holds information about a
-** single index record that has already been parsed out into individual
-** values.
-**
-** A record is an object that contains one or more fields of data.
-** Records are used to store the content of a table row and to store
-** the key of an index. A blob encoding of a record is created by
-** the OP_MakeRecord opcode of the VDBE and is disassembled by the
-** OP_Column opcode.
-**
-** This structure holds a record that has already been disassembled
-** into its constituent fields.
-*/
-struct UnpackedRecord {
- KeyInfo *pKeyInfo; /* Collation and sort-order information */
- u16 nField; /* Number of entries in apMem[] */
- u16 flags; /* Boolean settings. UNPACKED_... below */
- i64 rowid; /* Used by UNPACKED_PREFIX_SEARCH */
- Mem *aMem; /* Values */
-};
-
-/*
-** 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 */
-
-/*
-** Each SQL index is represented in memory by an
-** instance of the following structure.
-**
-** The columns of the table that are to be indexed are described
-** by the aiColumn[] field of this structure. For example, suppose
-** we have the following table and index:
-**
-** CREATE TABLE Ex1(c1 int, c2 int, c3 text);
-** CREATE INDEX Ex2 ON Ex1(c3,c1);
-**
-** In the Table structure describing Ex1, nCol==3 because there are
-** three columns in the table. In the Index structure describing
-** Ex2, nColumn==2 since 2 of the 3 columns of Ex1 are indexed.
-** The value of aiColumn is {2, 0}. aiColumn[0]==2 because the
-** first column to be indexed (c3) has an index of 2 in Ex1.aCol[].
-** The second column to be indexed (c1) has an index of 0 in
-** Ex1.aCol[], hence Ex2.aiColumn[1]==0.
-**
-** The Index.onError field determines whether or not the indexed columns
-** must be unique and what to do if they are not. When Index.onError=OE_None,
-** it means this is not a unique index. Otherwise it is a unique index
-** and the value of Index.onError indicate the which conflict resolution
-** algorithm to employ whenever an attempt is made to insert a non-unique
-** element.
-*/
-struct Index {
- char *zName; /* Name of this index */
- int nColumn; /* Number of columns in the table used by this index */
- int *aiColumn; /* Which columns are used by this index. 1st is 0 */
- unsigned *aiRowEst; /* Result of ANALYZE: Est. rows selected by each column */
- Table *pTable; /* The SQL table being indexed */
- int tnum; /* Page containing root of this index in database file */
- u8 onError; /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */
- u8 autoIndex; /* True if is automatically created (ex: by UNIQUE) */
- char *zColAff; /* String defining the affinity of each column */
- Index *pNext; /* The next index associated with the same table */
- Schema *pSchema; /* Schema containing this index */
- u8 *aSortOrder; /* Array of size Index.nColumn. True==DESC, False==ASC */
- char **azColl; /* Array of collation sequence names for index */
- IndexSample *aSample; /* Array of SQLITE_INDEX_SAMPLES samples */
-};
-
-/*
-** Each sample stored in the sqlite_stat2 table is represented in memory
-** using a structure of this type.
-*/
-struct IndexSample {
- union {
- char *z; /* Value if eType is SQLITE_TEXT or SQLITE_BLOB */
- double r; /* Value if eType is SQLITE_FLOAT or SQLITE_INTEGER */
- } u;
- u8 eType; /* SQLITE_NULL, SQLITE_INTEGER ... etc. */
- u8 nByte; /* Size in byte of text or blob. */
-};
-
-/*
-** Each token coming out of the lexer is an instance of
-** this structure. Tokens are also used as part of an expression.
-**
-** Note if Token.z==0 then Token.dyn and Token.n are undefined and
-** may contain random values. Do not make any assumptions about Token.dyn
-** and Token.n when Token.z==0.
-*/
-struct Token {
- const char *z; /* Text of the token. Not NULL-terminated! */
- unsigned int n; /* Number of characters in this token */
-};
-
-/*
-** An instance of this structure contains information needed to generate
-** code for a SELECT that contains aggregate functions.
-**
-** If Expr.op==TK_AGG_COLUMN or TK_AGG_FUNCTION then Expr.pAggInfo is a
-** pointer to this structure. The Expr.iColumn field is the index in
-** AggInfo.aCol[] or AggInfo.aFunc[] of information needed to generate
-** code for that node.
-**
-** AggInfo.pGroupBy and AggInfo.aFunc.pExpr point to fields within the
-** original Select structure that describes the SELECT statement. These
-** fields do not need to be freed when deallocating the AggInfo structure.
-*/
-struct AggInfo {
- u8 directMode; /* Direct rendering mode means take data directly
- ** from source tables rather than from accumulators */
- u8 useSortingIdx; /* In direct mode, reference the sorting index rather
- ** than the source table */
- int sortingIdx; /* Cursor number of the sorting index */
- ExprList *pGroupBy; /* The group by clause */
- int nSortingColumn; /* Number of columns in the sorting index */
- struct AggInfo_col { /* For each column used in source tables */
- Table *pTab; /* Source table */
- int iTable; /* Cursor number of the source table */
- int iColumn; /* Column number within the source table */
- int iSorterColumn; /* Column number in the sorting index */
- int iMem; /* Memory location that acts as accumulator */
- Expr *pExpr; /* The original expression */
- } *aCol;
- int nColumn; /* Number of used entries in aCol[] */
- int nColumnAlloc; /* Number of slots allocated for aCol[] */
- int nAccumulator; /* Number of columns that show through to the output.
- ** Additional columns are used only as parameters to
- ** aggregate functions */
- struct AggInfo_func { /* For each aggregate function */
- Expr *pExpr; /* Expression encoding the function */
- FuncDef *pFunc; /* The aggregate function implementation */
- int iMem; /* Memory location that acts as accumulator */
- int iDistinct; /* Ephemeral table used to enforce DISTINCT */
- } *aFunc;
- int nFunc; /* Number of entries in aFunc[] */
- int nFuncAlloc; /* Number of slots allocated for aFunc[] */
-};
-
-/*
-** Each node of an expression in the parse tree is an instance
-** of this structure.
-**
-** Expr.op is the opcode. The integer parser token codes are reused
-** as opcodes here. For example, the parser defines TK_GE to be an integer
-** code representing the ">=" operator. This same integer code is reused
-** to represent the greater-than-or-equal-to operator in the expression
-** tree.
-**
-** If the expression is an SQL literal (TK_INTEGER, TK_FLOAT, TK_BLOB,
-** or TK_STRING), then Expr.token contains the text of the SQL literal. If
-** the expression is a variable (TK_VARIABLE), then Expr.token contains the
-** variable name. Finally, if the expression is an SQL function (TK_FUNCTION),
-** then Expr.token contains the name of the function.
-**
-** Expr.pRight and Expr.pLeft are the left and right subexpressions of a
-** binary operator. Either or both may be NULL.
-**
-** Expr.x.pList is a list of arguments if the expression is an SQL function,
-** a CASE expression or an IN expression of the form "<lhs> IN (<y>, <z>...)".
-** Expr.x.pSelect is used if the expression is a sub-select or an expression of
-** the form "<lhs> IN (SELECT ...)". If the EP_xIsSelect bit is set in the
-** Expr.flags mask, then Expr.x.pSelect is valid. Otherwise, Expr.x.pList is
-** valid.
-**
-** An expression of the form ID or ID.ID refers to a column in a table.
-** For such expressions, Expr.op is set to TK_COLUMN and Expr.iTable is
-** the integer cursor number of a VDBE cursor pointing to that table and
-** Expr.iColumn is the column number for the specific column. If the
-** expression is used as a result in an aggregate SELECT, then the
-** value is also stored in the Expr.iAgg column in the aggregate so that
-** it can be accessed after all aggregates are computed.
-**
-** If the expression is an unbound variable marker (a question mark
-** character '?' in the original SQL) then the Expr.iTable holds the index
-** number for that variable.
-**
-** If the expression is a subquery then Expr.iColumn holds an integer
-** register number containing the result of the subquery. If the
-** subquery gives a constant result, then iTable is -1. If the subquery
-** gives a different answer at different times during statement processing
-** then iTable is the address of a subroutine that computes the subquery.
-**
-** If the Expr is of type OP_Column, and the table it is selecting from
-** is a disk table or the "old.*" pseudo-table, then pTab points to the
-** corresponding table definition.
-**
-** ALLOCATION NOTES:
-**
-** Expr objects can use a lot of memory space in database schema. To
-** help reduce memory requirements, sometimes an Expr object will be
-** truncated. And to reduce the number of memory allocations, sometimes
-** two or more Expr objects will be stored in a single memory allocation,
-** together with Expr.zToken strings.
-**
-** If the EP_Reduced and EP_TokenOnly flags are set when
-** an Expr object is truncated. When EP_Reduced is set, then all
-** the child Expr objects in the Expr.pLeft and Expr.pRight subtrees
-** are contained within the same memory allocation. Note, however, that
-** the subtrees in Expr.x.pList or Expr.x.pSelect are always separately
-** allocated, regardless of whether or not EP_Reduced is set.
-*/
-struct Expr {
- u8 op; /* Operation performed by this node */
- char affinity; /* The affinity of the column or 0 if not a column */
- u16 flags; /* Various flags. EP_* See below */
- union {
- char *zToken; /* Token value. Zero terminated and dequoted */
- int iValue; /* Integer value if EP_IntValue */
- } u;
-
- /* If the EP_TokenOnly flag is set in the Expr.flags mask, then no
- ** space is allocated for the fields below this point. An attempt to
- ** access them will result in a segfault or malfunction.
- *********************************************************************/
-
- Expr *pLeft; /* Left subnode */
- Expr *pRight; /* Right subnode */
- union {
- ExprList *pList; /* Function arguments or in "<expr> IN (<expr-list)" */
- Select *pSelect; /* Used for sub-selects and "<expr> IN (<select>)" */
- } x;
- CollSeq *pColl; /* The collation type of the column or 0 */
-
- /* If the EP_Reduced flag is set in the Expr.flags mask, then no
- ** space is allocated for the fields below this point. An attempt to
- ** access them will result in a segfault or malfunction.
- *********************************************************************/
-
- int iTable; /* TK_COLUMN: cursor number of table holding column
- ** TK_REGISTER: register number
- ** TK_TRIGGER: 1 -> new, 0 -> old */
- i16 iColumn; /* TK_COLUMN: column index. -1 for rowid */
- i16 iAgg; /* Which entry in pAggInfo->aCol[] or ->aFunc[] */
- i16 iRightJoinTable; /* If EP_FromJoin, the right table of the join */
- u8 flags2; /* Second set of flags. EP2_... */
- u8 op2; /* If a TK_REGISTER, the original value of Expr.op */
- AggInfo *pAggInfo; /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */
- Table *pTab; /* Table for TK_COLUMN expressions. */
-#if SQLITE_MAX_EXPR_DEPTH>0
- int nHeight; /* Height of the tree headed by this node */
-#endif
-};
-
-/*
-** The following are the meanings of bits in the Expr.flags field.
-*/
-#define EP_FromJoin 0x0001 /* Originated in ON or USING clause of a join */
-#define EP_Agg 0x0002 /* Contains one or more aggregate functions */
-#define EP_Resolved 0x0004 /* IDs have been resolved to COLUMNs */
-#define EP_Error 0x0008 /* Expression contains one or more errors */
-#define EP_Distinct 0x0010 /* Aggregate function with DISTINCT keyword */
-#define EP_VarSelect 0x0020 /* pSelect is correlated, not constant */
-#define EP_DblQuoted 0x0040 /* token.z was originally in "..." */
-#define EP_InfixFunc 0x0080 /* True for an infix function: LIKE, GLOB, etc */
-#define EP_ExpCollate 0x0100 /* Collating sequence specified explicitly */
-#define EP_AnyAff 0x0200 /* Can take a cached column of any affinity */
-#define EP_FixedDest 0x0400 /* Result needed in a specific register */
-#define EP_IntValue 0x0800 /* Integer value contained in u.iValue */
-#define EP_xIsSelect 0x1000 /* x.pSelect is valid (otherwise x.pList is) */
-
-#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.
-*/
-#define EP2_MallocedToken 0x0001 /* Need to sqlite3DbFree() Expr.zToken */
-#define EP2_Irreducible 0x0002 /* Cannot EXPRDUP_REDUCE this Expr */
-
-/*
-** The pseudo-routine sqlite3ExprSetIrreducible sets the EP2_Irreducible
-** flag on an expression structure. This flag is used for VV&A only. The
-** routine is implemented as a macro that only works when in debugging mode,
-** so as not to burden production code.
-*/
-#ifdef SQLITE_DEBUG
-# define ExprSetIrreducible(X) (X)->flags2 |= EP2_Irreducible
-#else
-# define ExprSetIrreducible(X)
-#endif
-
-/*
-** These macros can be used to test, set, or clear bits in the
-** Expr.flags field.
-*/
-#define ExprHasProperty(E,P) (((E)->flags&(P))==(P))
-#define ExprHasAnyProperty(E,P) (((E)->flags&(P))!=0)
-#define ExprSetProperty(E,P) (E)->flags|=(P)
-#define ExprClearProperty(E,P) (E)->flags&=~(P)
-
-/*
-** Macros to determine the number of bytes required by a normal Expr
-** struct, an Expr struct with the EP_Reduced flag set in Expr.flags
-** and an Expr struct with the EP_TokenOnly flag set.
-*/
-#define EXPR_FULLSIZE sizeof(Expr) /* Full size */
-#define EXPR_REDUCEDSIZE offsetof(Expr,iTable) /* Common features */
-#define EXPR_TOKENONLYSIZE offsetof(Expr,pLeft) /* Fewer features */
-
-/*
-** Flags passed to the sqlite3ExprDup() function. See the header comment
-** above sqlite3ExprDup() for details.
-*/
-#define EXPRDUP_REDUCE 0x0001 /* Used reduced-size Expr nodes */
-
-/*
-** A list of expressions. Each expression may optionally have a
-** name. An expr/name combination can be used in several ways, such
-** as the list of "expr AS ID" fields following a "SELECT" or in the
-** list of "ID = expr" items in an UPDATE. A list of expressions can
-** also be used as the argument to a function, in which case the a.zName
-** field is not used.
-*/
-struct ExprList {
- int nExpr; /* Number of expressions on the list */
- int nAlloc; /* Number of entries allocated below */
- int iECursor; /* VDBE Cursor associated with this ExprList */
- struct ExprList_item {
- Expr *pExpr; /* The list of expressions */
- char *zName; /* Token associated with this expression */
- 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 iAlias; /* Index into Parse.aAlias[] for zName */
- } *a; /* One entry for each expression */
-};
-
-/*
-** An instance of this structure is used by the parser to record both
-** the parse tree for an expression and the span of input text for an
-** expression.
-*/
-struct ExprSpan {
- Expr *pExpr; /* The expression parse tree */
- const char *zStart; /* First character of input text */
- const char *zEnd; /* One character past the end of input text */
-};
-
-/*
-** An instance of this structure can hold a simple list of identifiers,
-** such as the list "a,b,c" in the following statements:
-**
-** INSERT INTO t(a,b,c) VALUES ...;
-** CREATE INDEX idx ON t(a,b,c);
-** CREATE TRIGGER trig BEFORE UPDATE ON t(a,b,c) ...;
-**
-** The IdList.a.idx field is used when the IdList represents the list of
-** column names after a table name in an INSERT statement. In the statement
-**
-** INSERT INTO t(a,b,c) ...
-**
-** If "a" is the k-th column of table "t", then IdList.a[0].idx==k.
-*/
-struct IdList {
- struct IdList_item {
- char *zName; /* Name of the identifier */
- int idx; /* Index in some Table.aCol[] of a column named zName */
- } *a;
- int nId; /* Number of identifiers on the list */
- int nAlloc; /* Number of entries allocated for a[] below */
-};
-
-/*
-** The bitmask datatype defined below is used for various optimizations.
-**
-** Changing this from a 64-bit to a 32-bit type limits the number of
-** tables in a join to 32 instead of 64. But it also reduces the size
-** of the library by 738 bytes on ix86.
-*/
-typedef u64 Bitmask;
-
-/*
-** The number of bits in a Bitmask. "BMS" means "BitMask Size".
-*/
-#define BMS ((int)(sizeof(Bitmask)*8))
-
-/*
-** The following structure describes the FROM clause of a SELECT statement.
-** Each table or subquery in the FROM clause is a separate element of
-** the SrcList.a[] array.
-**
-** With the addition of multiple database support, the following structure
-** can also be used to describe a particular table such as the table that
-** is modified by an INSERT, DELETE, or UPDATE statement. In standard SQL,
-** such a table must be a simple name: ID. But in SQLite, the table can
-** now be identified by a database name, a dot, then the table name: ID.ID.
-**
-** The jointype starts out showing the join type between the current table
-** and the next table on the list. The parser builds the list this way.
-** But sqlite3SrcListShiftJoinType() later shifts the jointypes so that each
-** jointype expresses the join between the table and the previous table.
-*/
-struct SrcList {
- i16 nSrc; /* Number of tables or subqueries in the FROM clause */
- i16 nAlloc; /* Number of entries allocated in a[] below */
- struct SrcList_item {
- char *zDatabase; /* Name of database holding this table */
- char *zName; /* Name of the table */
- char *zAlias; /* The "B" part of a "A AS B" phrase. zName is the "A" */
- Table *pTab; /* An SQL table corresponding to zName */
- Select *pSelect; /* A SELECT statement used in place of a table name */
- u8 isPopulated; /* Temporary table associated with SELECT is populated */
- u8 jointype; /* Type of join between this able and the previous */
- u8 notIndexed; /* True if there is a NOT INDEXED clause */
- int iCursor; /* The VDBE cursor number used to access this table */
- Expr *pOn; /* The ON clause of a join */
- IdList *pUsing; /* The USING clause of a join */
- Bitmask colUsed; /* Bit N (1<<N) set if column N of pTab is used */
- char *zIndex; /* Identifier from "INDEXED BY <zIndex>" clause */
- Index *pIndex; /* Index structure corresponding to zIndex, if any */
- } a[1]; /* One entry for each identifier on the list */
-};
-
-/*
-** Permitted values of the SrcList.a.jointype field
-*/
-#define JT_INNER 0x0001 /* Any kind of inner or cross join */
-#define JT_CROSS 0x0002 /* Explicit use of the CROSS keyword */
-#define JT_NATURAL 0x0004 /* True for a "natural" join */
-#define JT_LEFT 0x0008 /* Left outer join */
-#define JT_RIGHT 0x0010 /* Right outer join */
-#define JT_OUTER 0x0020 /* The "OUTER" keyword is present */
-#define JT_ERROR 0x0040 /* unknown or unsupported join type */
-
-
-/*
-** A WherePlan object holds information that describes a lookup
-** strategy.
-**
-** This object is intended to be opaque outside of the where.c module.
-** It is included here only so that that compiler will know how big it
-** is. None of the fields in this object should be used outside of
-** the where.c module.
-**
-** Within the union, pIdx is only used when wsFlags&WHERE_INDEXED is true.
-** pTerm is only used when wsFlags&WHERE_MULTI_OR is true. And pVtabIdx
-** is only used when wsFlags&WHERE_VIRTUALTABLE is true. It is never the
-** case that more than one of these conditions is true.
-*/
-struct WherePlan {
- u32 wsFlags; /* WHERE_* flags that describe the strategy */
- u32 nEq; /* Number of == constraints */
- union {
- Index *pIdx; /* Index when WHERE_INDEXED is true */
- struct WhereTerm *pTerm; /* WHERE clause term for OR-search */
- sqlite3_index_info *pVtabIdx; /* Virtual table index to use */
- } u;
-};
-
-/*
-** For each nested loop in a WHERE clause implementation, the WhereInfo
-** structure contains a single instance of this structure. This structure
-** is intended to be private the the where.c module and should not be
-** access or modified by other modules.
-**
-** The pIdxInfo field is used to help pick the best index on a
-** virtual table. The pIdxInfo pointer contains indexing
-** information for the i-th table in the FROM clause before reordering.
-** All the pIdxInfo pointers are freed by whereInfoFree() in where.c.
-** All other information in the i-th WhereLevel object for the i-th table
-** after FROM clause ordering.
-*/
-struct WhereLevel {
- WherePlan plan; /* query plan for this element of the FROM clause */
- int iLeftJoin; /* Memory cell used to implement LEFT OUTER JOIN */
- int iTabCur; /* The VDBE cursor used to access the table */
- int iIdxCur; /* The VDBE cursor used to access pIdx */
- int addrBrk; /* Jump here to break out of the loop */
- int addrNxt; /* Jump here to start the next IN combination */
- int addrCont; /* Jump here to continue with the next loop cycle */
- int addrFirst; /* First instruction of interior of the loop */
- u8 iFrom; /* Which entry in the FROM clause */
- u8 op, p5; /* Opcode and P5 of the opcode that ends the loop */
- int p1, p2; /* Operands of the opcode used to ends the loop */
- union { /* Information that depends on plan.wsFlags */
- struct {
- int nIn; /* Number of entries in aInLoop[] */
- struct InLoop {
- int iCur; /* The VDBE cursor used by this IN operator */
- int addrInTop; /* Top of the IN loop */
- } *aInLoop; /* Information about each nested IN operator */
- } in; /* Used when plan.wsFlags&WHERE_IN_ABLE */
- } u;
-
- /* The following field is really not part of the current level. But
- ** we need a place to cache virtual table index information for each
- ** virtual table in the FROM clause and the WhereLevel structure is
- ** a convenient place since there is one WhereLevel for each FROM clause
- ** element.
- */
- sqlite3_index_info *pIdxInfo; /* Index info for n-th source table */
-};
-
-/*
-** Flags appropriate for the wctrlFlags parameter of sqlite3WhereBegin()
-** and the WhereInfo.wctrlFlags member.
-*/
-#define WHERE_ORDERBY_NORMAL 0x0000 /* No-op */
-#define WHERE_ORDERBY_MIN 0x0001 /* ORDER BY processing for min() func */
-#define WHERE_ORDERBY_MAX 0x0002 /* ORDER BY processing for max() func */
-#define WHERE_ONEPASS_DESIRED 0x0004 /* Want to do one-pass UPDATE/DELETE */
-#define WHERE_DUPLICATES_OK 0x0008 /* Ok to return a row more than once */
-#define WHERE_OMIT_OPEN 0x0010 /* Table cursor are already open */
-#define WHERE_OMIT_CLOSE 0x0020 /* Omit close of table & index cursors */
-#define WHERE_FORCE_TABLE 0x0040 /* Do not use an index-only search */
-
-/*
-** The WHERE clause processing routine has two halves. The
-** first part does the start of the WHERE loop and the second
-** half does the tail of the WHERE loop. An instance of
-** this structure is returned by the first half and passed
-** into the second half to give some continuity.
-*/
-struct WhereInfo {
- Parse *pParse; /* Parsing and code generating context */
- u16 wctrlFlags; /* Flags originally passed to sqlite3WhereBegin() */
- u8 okOnePass; /* Ok to use one-pass algorithm for UPDATE or DELETE */
- SrcList *pTabList; /* List of tables in the join */
- int iTop; /* The very beginning of the WHERE loop */
- int iContinue; /* Jump here to continue with next record */
- int iBreak; /* Jump here to break out of the loop */
- int nLevel; /* Number of nested loop */
- struct WhereClause *pWC; /* Decomposition of the WHERE clause */
- WhereLevel a[1]; /* Information about each nest loop in WHERE */
-};
-
-/*
-** A NameContext defines a context in which to resolve table and column
-** names. The context consists of a list of tables (the pSrcList) field and
-** a list of named expression (pEList). The named expression list may
-** be NULL. The pSrc corresponds to the FROM clause of a SELECT or
-** to the table being operated on by INSERT, UPDATE, or DELETE. The
-** pEList corresponds to the result set of a SELECT and is NULL for
-** other statements.
-**
-** NameContexts can be nested. When resolving names, the inner-most
-** context is searched first. If no match is found, the next outer
-** context is checked. If there is still no match, the next context
-** is checked. This process continues until either a match is found
-** or all contexts are check. When a match is found, the nRef member of
-** the context containing the match is incremented.
-**
-** Each subquery gets a new NameContext. The pNext field points to the
-** NameContext in the parent query. Thus the process of scanning the
-** NameContext list corresponds to searching through successively outer
-** subqueries looking for a match.
-*/
-struct NameContext {
- Parse *pParse; /* The parser */
- SrcList *pSrcList; /* One or more tables used to resolve names */
- ExprList *pEList; /* Optional list of named expressions */
- int nRef; /* Number of names resolved by this context */
- int nErr; /* Number of errors encountered while resolving names */
- u8 allowAgg; /* Aggregate functions allowed here */
- u8 hasAgg; /* True if aggregates are seen */
- u8 isCheck; /* True if resolving names in a CHECK constraint */
- int nDepth; /* Depth of subquery recursion. 1 for no recursion */
- AggInfo *pAggInfo; /* Information about aggregates at this level */
- NameContext *pNext; /* Next outer name context. NULL for outermost */
-};
-
-/*
-** An instance of the following structure contains all information
-** needed to generate code for a single SELECT statement.
-**
-** nLimit is set to -1 if there is no LIMIT clause. nOffset is set to 0.
-** If there is a LIMIT clause, the parser sets nLimit to the value of the
-** limit and nOffset to the value of the offset (or 0 if there is not
-** offset). But later on, nLimit and nOffset become the memory locations
-** in the VDBE that record the limit and offset counters.
-**
-** addrOpenEphm[] entries contain the address of OP_OpenEphemeral opcodes.
-** These addresses must be stored so that we can go back and fill in
-** the P4_KEYINFO and P2 parameters later. Neither the KeyInfo nor
-** the number of columns in P2 can be computed at the same time
-** as the OP_OpenEphm instruction is coded because not
-** enough information about the compound query is known at that point.
-** The KeyInfo for addrOpenTran[0] and [1] contains collating sequences
-** for the result set. The KeyInfo for addrOpenTran[2] contains collating
-** sequences for the ORDER BY clause.
-*/
-struct Select {
- ExprList *pEList; /* The fields of the result */
- u8 op; /* One of: TK_UNION TK_ALL TK_INTERSECT TK_EXCEPT */
- char affinity; /* MakeRecord with this affinity for SRT_Set */
- u16 selFlags; /* Various SF_* values */
- SrcList *pSrc; /* The FROM clause */
- Expr *pWhere; /* The WHERE clause */
- ExprList *pGroupBy; /* The GROUP BY clause */
- Expr *pHaving; /* The HAVING clause */
- ExprList *pOrderBy; /* The ORDER BY clause */
- Select *pPrior; /* Prior select in a compound select statement */
- Select *pNext; /* Next select to the left in a compound */
- Select *pRightmost; /* Right-most select in a compound select statement */
- Expr *pLimit; /* LIMIT expression. NULL means not used. */
- Expr *pOffset; /* OFFSET expression. NULL means not used. */
- int iLimit, iOffset; /* Memory registers holding LIMIT & OFFSET counters */
- int addrOpenEphm[3]; /* OP_OpenEphem opcodes related to this 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 */
-
-
-/*
-** The results of a select can be distributed in several ways. The
-** "SRT" prefix means "SELECT Result Type".
-*/
-#define SRT_Union 1 /* Store result as keys in an index */
-#define SRT_Except 2 /* Remove result from a UNION index */
-#define SRT_Exists 3 /* Store 1 if the result is not empty */
-#define SRT_Discard 4 /* Do not save the results anywhere */
-
-/* The ORDER BY clause is ignored for all of the above */
-#define IgnorableOrderby(X) ((X->eDest)<=SRT_Discard)
-
-#define SRT_Output 5 /* Output each row of result */
-#define SRT_Mem 6 /* Store result in a memory cell */
-#define SRT_Set 7 /* Store results as keys in an index */
-#define SRT_Table 8 /* Store result as data with an automatic rowid */
-#define SRT_EphemTab 9 /* Create transient tab and store like SRT_Table */
-#define SRT_Coroutine 10 /* Generate a single row of result */
-
-/*
-** A structure used to customize the behavior of sqlite3Select(). See
-** comments above sqlite3Select() for details.
-*/
-typedef struct SelectDest SelectDest;
-struct SelectDest {
- u8 eDest; /* How to dispose of the results */
- u8 affinity; /* Affinity used when eDest==SRT_Set */
- int iParm; /* A parameter used by the eDest disposal method */
- int iMem; /* Base register where results are written */
- int nMem; /* Number of registers allocated */
-};
-
-/*
-** During code generation of statements that do inserts into AUTOINCREMENT
-** tables, the following information is attached to the Table.u.autoInc.p
-** pointer of each autoincrement table to record some side information that
-** the code generator needs. We have to keep per-table autoincrement
-** information in case inserts are down within triggers. Triggers do not
-** normally coordinate their activities, but we do need to coordinate the
-** loading and saving of autoincrement information.
-*/
-struct AutoincInfo {
- AutoincInfo *pNext; /* Next info block in a list of them all */
- Table *pTab; /* Table this info block refers to */
- int iDb; /* Index in sqlite3.aDb[] of database holding pTab */
- int regCtr; /* Memory register holding the rowid counter */
-};
-
-/*
-** Size of the column cache
-*/
-#ifndef SQLITE_N_COLCACHE
-# define SQLITE_N_COLCACHE 10
-#endif
-
-/*
-** At least one instance of the following structure is created for each
-** trigger that may be fired while parsing an INSERT, UPDATE or DELETE
-** statement. All such objects are stored in the linked list headed at
-** Parse.pTriggerPrg and deleted once statement compilation has been
-** completed.
-**
-** A Vdbe sub-program that implements the body and WHEN clause of trigger
-** TriggerPrg.pTrigger, assuming a default ON CONFLICT clause of
-** TriggerPrg.orconf, is stored in the TriggerPrg.pProgram variable.
-** The Parse.pTriggerPrg list never contains two entries with the same
-** values for both pTrigger and orconf.
-**
-** The TriggerPrg.oldmask variable is set to a mask of old.* columns
-** accessed (or set to 0 for triggers fired as a result of INSERT
-** statements).
-*/
-struct TriggerPrg {
- Trigger *pTrigger; /* Trigger this program was coded from */
- int orconf; /* Default ON CONFLICT policy */
- SubProgram *pProgram; /* Program implementing pTrigger/orconf */
- u32 oldmask; /* Mask of old.* columns accessed */
- TriggerPrg *pNext; /* Next entry in Parse.pTriggerPrg list */
-};
-
-/*
-** An SQL parser context. A copy of this structure is passed through
-** the parser and down into all the parser action routine in order to
-** carry around information that is global to the entire parse.
-**
-** The structure is divided into two parts. When the parser and code
-** generate call themselves recursively, the first part of the structure
-** is constant but the second part is reset at the beginning and end of
-** each recursion.
-**
-** The nTableLock and aTableLock variables are only used if the shared-cache
-** feature is enabled (if sqlite3Tsd()->useSharedData is true). They are
-** used to store the set of table-locks required by the statement being
-** compiled. Function sqlite3TableLock() is used to add entries to the
-** list.
-*/
-struct Parse {
- sqlite3 *db; /* The main database structure */
- int rc; /* Return code from execution */
- 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 */
- int nRangeReg; /* Size of the temporary register block */
- int iRangeReg; /* First register in temporary register block */
- int nErr; /* Number of errors seen */
- 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 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 */
- struct yColCache {
- int iTable; /* Table cursor number */
- int iColumn; /* Table column number */
- u8 affChange; /* True if this register has had an affinity change */
- u8 tempReg; /* iReg is a temp register that needs to be freed */
- int iLevel; /* Nesting level */
- int iReg; /* Reg with value of this column. 0 means none. */
- int lru; /* Least recently used entry has the smallest value */
- } aColCache[SQLITE_N_COLCACHE]; /* One for each column cache entry */
- u32 writeMask; /* Start a write transaction on these databases */
- u32 cookieMask; /* Bitmask of schema verified databases */
- u8 isMultiWrite; /* True if statement may affect/insert multiple rows */
- u8 mayAbort; /* True if statement may throw an ABORT exception */
- int cookieGoto; /* Address of OP_Goto to cookie verifier subroutine */
- int cookieValue[SQLITE_MAX_ATTACHED+2]; /* Values of cookies to verify */
-#ifndef SQLITE_OMIT_SHARED_CACHE
- int nTableLock; /* Number of locks in aTableLock */
- TableLock *aTableLock; /* Required table locks for shared-cache mode */
-#endif
- int regRowid; /* Register holding rowid of CREATE TABLE entry */
- int regRoot; /* Register holding root page number for new objects */
- AutoincInfo *pAinc; /* Information about AUTOINCREMENT counters */
- int nMaxArg; /* Max args passed to user function by sub-program */
-
- /* Information used while coding trigger programs. */
- Parse *pToplevel; /* Parse structure for main program (or NULL) */
- Table *pTriggerTab; /* Table triggers are being coded for */
- u32 oldmask; /* Mask of old.* columns referenced */
- u8 eTriggerOp; /* TK_UPDATE, TK_INSERT or TK_DELETE */
- u8 eOrconf; /* Default ON CONFLICT policy for trigger steps */
-
- /* Above is constant between recursions. Below is reset before and after
- ** each recursion */
-
- int nVar; /* Number of '?' variables seen in the SQL so far */
- int nVarExpr; /* Number of used slots in apVarExpr[] */
- int nVarExprAlloc; /* Number of allocated slots in apVarExpr[] */
- Expr **apVarExpr; /* Pointers to :aaa and $aaaa wildcard expressions */
- 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 */
- Token sLastToken; /* The last token parsed */
- const char *zTail; /* All SQL text past the last semicolon parsed */
- Table *pNewTable; /* A table being constructed by CREATE TABLE */
- Trigger *pNewTrigger; /* Trigger under construct by a CREATE TRIGGER */
- const char *zAuthContext; /* The 6th parameter to db->xAuth callbacks */
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- Token sArg; /* Complete text of a module argument */
- u8 declareVtab; /* True if inside sqlite3_declare_vtab() */
- int nVtabLock; /* Number of virtual tables to lock */
- Table **apVtabLock; /* Pointer to virtual tables needing locking */
-#endif
- int nHeight; /* Expression tree height of current sub-select */
- Table *pZombieTab; /* List of Table objects to delete after code gen */
- TriggerPrg *pTriggerPrg; /* Linked list of coded triggers */
-};
-
-#ifdef SQLITE_OMIT_VIRTUALTABLE
- #define IN_DECLARE_VTAB 0
-#else
- #define IN_DECLARE_VTAB (pParse->declareVtab)
-#endif
-
-/*
-** An instance of the following structure can be declared on a stack and used
-** to save the Parse.zAuthContext value so that it can be restored later.
-*/
-struct AuthContext {
- const char *zAuthContext; /* Put saved Parse.zAuthContext here */
- Parse *pParse; /* The Parse structure */
-};
-
-/*
-** Bitfield flags for P5 value in OP_Insert and OP_Delete
-*/
-#define OPFLAG_NCHANGE 0x01 /* Set to update db->nChange */
-#define OPFLAG_LASTROWID 0x02 /* Set to update db->lastRowid */
-#define OPFLAG_ISUPDATE 0x04 /* This OP_Insert is an sql UPDATE */
-#define OPFLAG_APPEND 0x08 /* This is likely to be an append */
-#define OPFLAG_USESEEKRESULT 0x10 /* Try to avoid a seek in BtreeInsert() */
-#define OPFLAG_CLEARCACHE 0x20 /* Clear pseudo-table cache in OP_Column */
-
-/*
- * Each trigger present in the database schema is stored as an instance of
- * struct Trigger.
- *
- * Pointers to instances of struct Trigger are stored in two ways.
- * 1. In the "trigHash" hash table (part of the sqlite3* that represents the
- * database). This allows Trigger structures to be retrieved by name.
- * 2. All triggers associated with a single table form a linked list, using the
- * pNext member of struct Trigger. A pointer to the first element of the
- * linked list is stored as the "pTrigger" member of the associated
- * struct Table.
- *
- * The "step_list" member points to the first element of a linked list
- * containing the SQL statements specified as the trigger program.
- */
-struct Trigger {
- char *zName; /* The name of the trigger */
- char *table; /* The table or view to which the trigger applies */
- u8 op; /* One of TK_DELETE, TK_UPDATE, TK_INSERT */
- u8 tr_tm; /* One of TRIGGER_BEFORE, TRIGGER_AFTER */
- Expr *pWhen; /* The WHEN clause of the expression (may be NULL) */
- IdList *pColumns; /* If this is an UPDATE OF <column-list> trigger,
- the <column-list> is stored here */
- Schema *pSchema; /* Schema containing the trigger */
- Schema *pTabSchema; /* Schema containing the table */
- TriggerStep *step_list; /* Link list of trigger program steps */
- Trigger *pNext; /* Next trigger associated with the table */
-};
-
-/*
-** A trigger is either a BEFORE or an AFTER trigger. The following constants
-** determine which.
-**
-** If there are multiple triggers, you might of some BEFORE and some AFTER.
-** In that cases, the constants below can be ORed together.
-*/
-#define TRIGGER_BEFORE 1
-#define TRIGGER_AFTER 2
-
-/*
- * An instance of struct TriggerStep is used to store a single SQL statement
- * that is a part of a trigger-program.
- *
- * Instances of struct TriggerStep are stored in a singly linked list (linked
- * using the "pNext" member) referenced by the "step_list" member of the
- * associated struct Trigger instance. The first element of the linked list is
- * the first step of the trigger-program.
- *
- * The "op" member indicates whether this is a "DELETE", "INSERT", "UPDATE" or
- * "SELECT" statement. The meanings of the other members is determined by the
- * value of "op" as follows:
- *
- * (op == TK_INSERT)
- * orconf -> stores the ON CONFLICT algorithm
- * pSelect -> If this is an INSERT INTO ... SELECT ... statement, then
- * this stores a pointer to the SELECT statement. Otherwise NULL.
- * target -> A token holding the quoted name of the table to insert into.
- * pExprList -> If this is an INSERT INTO ... VALUES ... statement, then
- * this stores values to be inserted. Otherwise NULL.
- * pIdList -> If this is an INSERT INTO ... (<column-names>) VALUES ...
- * statement, then this stores the column-names to be
- * inserted into.
- *
- * (op == TK_DELETE)
- * target -> A token holding the quoted name of the table to delete from.
- * pWhere -> The WHERE clause of the DELETE statement if one is specified.
- * Otherwise NULL.
- *
- * (op == TK_UPDATE)
- * target -> A token holding the quoted name of the table to update rows of.
- * pWhere -> The WHERE clause of the UPDATE statement if one is specified.
- * Otherwise NULL.
- * pExprList -> A list of the columns to update and the expressions to update
- * them to. See sqlite3Update() documentation of "pChanges"
- * argument.
- *
- */
-struct TriggerStep {
- u8 op; /* One of TK_DELETE, TK_UPDATE, TK_INSERT, TK_SELECT */
- u8 orconf; /* OE_Rollback etc. */
- Trigger *pTrig; /* The trigger that this step is a part of */
- Select *pSelect; /* SELECT statment or RHS of INSERT INTO .. SELECT ... */
- Token target; /* Target table for DELETE, UPDATE, INSERT */
- Expr *pWhere; /* The WHERE clause for DELETE or UPDATE steps */
- ExprList *pExprList; /* SET clause for UPDATE. VALUES clause for INSERT */
- IdList *pIdList; /* Column names for INSERT */
- TriggerStep *pNext; /* Next in the link-list */
- TriggerStep *pLast; /* Last element in link-list. Valid for 1st elem only */
-};
-
-/*
-** The following structure contains information used by the sqliteFix...
-** routines as they walk the parse tree to make database references
-** explicit.
-*/
-typedef struct DbFixer DbFixer;
-struct DbFixer {
- Parse *pParse; /* The parsing context. Error messages written here */
- const char *zDb; /* Make sure all objects are contained in this database */
- const char *zType; /* Type of the container - used for error messages */
- const Token *pName; /* Name of the container - used for error messages */
-};
-
-/*
-** An objected used to accumulate the text of a string where we
-** do not necessarily know how big the string will be in the end.
-*/
-struct StrAccum {
- sqlite3 *db; /* Optional database for lookaside. Can be NULL */
- char *zBase; /* A base allocation. Not from malloc. */
- char *zText; /* The string collected so far */
- int nChar; /* Length of the string so far */
- int nAlloc; /* Amount of space allocated in zText */
- int mxAlloc; /* Maximum allowed string length */
- u8 mallocFailed; /* Becomes true if any memory allocation fails */
- u8 useMalloc; /* True if zText is enlargeable using realloc */
- u8 tooBig; /* Becomes true if string size exceeds limits */
-};
-
-/*
-** A pointer to this structure is used to communicate information
-** from sqlite3Init and OP_ParseSchema into the sqlite3InitCallback.
-*/
-typedef struct {
- sqlite3 *db; /* The database being initialized */
- int iDb; /* 0 for main database. 1 for TEMP, 2.. for ATTACHed */
- char **pzErrMsg; /* Error message stored here */
- int rc; /* Result code stored here */
-} InitData;
-
-/*
-** Structure containing global configuration data for the SQLite library.
-**
-** This structure also contains some state information.
-*/
-struct Sqlite3Config {
- int bMemstat; /* True to enable memory status */
- int bCoreMutex; /* True to enable core mutexing */
- int bFullMutex; /* True to enable full mutexing */
- int mxStrlen; /* Maximum string length */
- int szLookaside; /* Default lookaside buffer size */
- 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 */
- void *pHeap; /* Heap storage space */
- int nHeap; /* Size of pHeap[] */
- int mnReq, mxReq; /* Min and max heap requests sizes */
- void *pScratch; /* Scratch memory */
- int szScratch; /* Size of each scratch buffer */
- int nScratch; /* Number of scratch buffers */
- void *pPage; /* Page cache memory */
- int szPage; /* Size of each page in pPage[] */
- int nPage; /* Number of pages in pPage[] */
- int mxParserStack; /* maximum depth of the parser stack */
- int sharedCacheEnabled; /* true if shared-cache mode enabled */
- /* The above might be initialized to non-zero. The following need to always
- ** initially be zero, however. */
- int isInit; /* True after initialization has finished */
- int inProgress; /* True while initialization in progress */
- int isMutexInit; /* True after mutexes are initialized */
- int isMallocInit; /* True after malloc is initialized */
- int isPCacheInit; /* True after malloc is initialized */
- sqlite3_mutex *pInitMutex; /* Mutex used by sqlite3_initialize() */
- int nRefInitMutex; /* Number of users of pInitMutex */
-};
-
-/*
-** Context pointer passed down through the tree-walk.
-*/
-struct Walker {
- int (*xExprCallback)(Walker*, Expr*); /* Callback for expressions */
- int (*xSelectCallback)(Walker*,Select*); /* Callback for SELECTs */
- Parse *pParse; /* Parser context. */
- union { /* Extra data for callback */
- NameContext *pNC; /* Naming context */
- int i; /* Integer value */
- } u;
-};
-
-/* Forward declarations */
-SQLITE_PRIVATE int sqlite3WalkExpr(Walker*, Expr*);
-SQLITE_PRIVATE int sqlite3WalkExprList(Walker*, ExprList*);
-SQLITE_PRIVATE int sqlite3WalkSelect(Walker*, Select*);
-SQLITE_PRIVATE int sqlite3WalkSelectExpr(Walker*, Select*);
-SQLITE_PRIVATE int sqlite3WalkSelectFrom(Walker*, Select*);
-
-/*
-** Return code from the parse-tree walking primitives and their
-** callbacks.
-*/
-#define WRC_Continue 0 /* Continue down into children */
-#define WRC_Prune 1 /* Omit children but continue walking siblings */
-#define WRC_Abort 2 /* Abandon the tree walk */
-
-/*
-** Assuming zIn points to the first byte of a UTF-8 character,
-** advance zIn to point to the first byte of the next UTF-8 character.
-*/
-#define SQLITE_SKIP_UTF8(zIn) { \
- if( (*(zIn++))>=0xc0 ){ \
- while( (*zIn & 0xc0)==0x80 ){ zIn++; } \
- } \
-}
-
-/*
-** The SQLITE_CORRUPT_BKPT macro can be either a constant (for production
-** builds) or a function call (for debugging). If it is a function call,
-** it allows the operator to set a breakpoint at the spot where database
-** corruption is first detected.
-*/
-#ifdef SQLITE_DEBUG
-SQLITE_PRIVATE int sqlite3Corrupt(void);
-# define SQLITE_CORRUPT_BKPT sqlite3Corrupt()
-#else
-# define SQLITE_CORRUPT_BKPT SQLITE_CORRUPT
-#endif
-
-/*
-** The ctype.h header is needed for non-ASCII systems. It is also
-** needed by FTS3 when FTS3 is included in the amalgamation.
-*/
-#if !defined(SQLITE_ASCII) || \
- (defined(SQLITE_ENABLE_FTS3) && defined(SQLITE_AMALGAMATION))
-# include <ctype.h>
-#endif
-
-/*
-** The following macros mimic the standard library functions toupper(),
-** isspace(), isalnum(), isdigit() and isxdigit(), respectively. The
-** sqlite versions only work for ASCII characters, regardless of locale.
-*/
-#ifdef SQLITE_ASCII
-# define sqlite3Toupper(x) ((x)&~(sqlite3CtypeMap[(unsigned char)(x)]&0x20))
-# define sqlite3Isspace(x) (sqlite3CtypeMap[(unsigned char)(x)]&0x01)
-# define sqlite3Isalnum(x) (sqlite3CtypeMap[(unsigned char)(x)]&0x06)
-# define sqlite3Isalpha(x) (sqlite3CtypeMap[(unsigned char)(x)]&0x02)
-# define sqlite3Isdigit(x) (sqlite3CtypeMap[(unsigned char)(x)]&0x04)
-# define sqlite3Isxdigit(x) (sqlite3CtypeMap[(unsigned char)(x)]&0x08)
-# define sqlite3Tolower(x) (sqlite3UpperToLower[(unsigned char)(x)])
-#else
-# define sqlite3Toupper(x) toupper((unsigned char)(x))
-# define sqlite3Isspace(x) isspace((unsigned char)(x))
-# define sqlite3Isalnum(x) isalnum((unsigned char)(x))
-# define sqlite3Isalpha(x) isalpha((unsigned char)(x))
-# define sqlite3Isdigit(x) isdigit((unsigned char)(x))
-# define sqlite3Isxdigit(x) isxdigit((unsigned char)(x))
-# define sqlite3Tolower(x) tolower((unsigned char)(x))
-#endif
-
-/*
-** Internal function prototypes
-*/
-SQLITE_PRIVATE int sqlite3StrICmp(const char *, const char *);
-SQLITE_PRIVATE int sqlite3IsNumber(const char*, int*, u8);
-SQLITE_PRIVATE int sqlite3Strlen30(const char*);
-#define sqlite3StrNICmp sqlite3_strnicmp
-
-SQLITE_PRIVATE int sqlite3MallocInit(void);
-SQLITE_PRIVATE void sqlite3MallocEnd(void);
-SQLITE_PRIVATE void *sqlite3Malloc(int);
-SQLITE_PRIVATE void *sqlite3MallocZero(int);
-SQLITE_PRIVATE void *sqlite3DbMallocZero(sqlite3*, int);
-SQLITE_PRIVATE void *sqlite3DbMallocRaw(sqlite3*, int);
-SQLITE_PRIVATE char *sqlite3DbStrDup(sqlite3*,const char*);
-SQLITE_PRIVATE char *sqlite3DbStrNDup(sqlite3*,const char*, int);
-SQLITE_PRIVATE void *sqlite3Realloc(void*, int);
-SQLITE_PRIVATE void *sqlite3DbReallocOrFree(sqlite3 *, void *, int);
-SQLITE_PRIVATE void *sqlite3DbRealloc(sqlite3 *, void *, int);
-SQLITE_PRIVATE void sqlite3DbFree(sqlite3*, void*);
-SQLITE_PRIVATE int sqlite3MallocSize(void*);
-SQLITE_PRIVATE int sqlite3DbMallocSize(sqlite3*, void*);
-SQLITE_PRIVATE void *sqlite3ScratchMalloc(int);
-SQLITE_PRIVATE void sqlite3ScratchFree(void*);
-SQLITE_PRIVATE void *sqlite3PageMalloc(int);
-SQLITE_PRIVATE void sqlite3PageFree(void*);
-SQLITE_PRIVATE void sqlite3MemSetDefault(void);
-SQLITE_PRIVATE void sqlite3BenignMallocHooks(void (*)(void), void (*)(void));
-SQLITE_PRIVATE int sqlite3MemoryAlarm(void (*)(void*, sqlite3_int64, int), void*, sqlite3_int64);
-
-/*
-** On systems with ample stack space and that support alloca(), make
-** use of alloca() to obtain space for large automatic objects. By default,
-** obtain space from malloc().
-**
-** The alloca() routine never returns NULL. This will cause code paths
-** that deal with sqlite3StackAlloc() failures to be unreachable.
-*/
-#ifdef SQLITE_USE_ALLOCA
-# define sqlite3StackAllocRaw(D,N) alloca(N)
-# define sqlite3StackAllocZero(D,N) memset(alloca(N), 0, N)
-# define sqlite3StackFree(D,P)
-#else
-# define sqlite3StackAllocRaw(D,N) sqlite3DbMallocRaw(D,N)
-# define sqlite3StackAllocZero(D,N) sqlite3DbMallocZero(D,N)
-# define sqlite3StackFree(D,P) sqlite3DbFree(D,P)
-#endif
-
-#ifdef SQLITE_ENABLE_MEMSYS3
-SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetMemsys3(void);
-#endif
-#ifdef SQLITE_ENABLE_MEMSYS5
-SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetMemsys5(void);
-#endif
-
-
-#ifndef SQLITE_MUTEX_OMIT
-SQLITE_PRIVATE sqlite3_mutex_methods *sqlite3DefaultMutex(void);
-SQLITE_PRIVATE sqlite3_mutex *sqlite3MutexAlloc(int);
-SQLITE_PRIVATE int sqlite3MutexInit(void);
-SQLITE_PRIVATE int sqlite3MutexEnd(void);
-#endif
-
-SQLITE_PRIVATE int sqlite3StatusValue(int);
-SQLITE_PRIVATE void sqlite3StatusAdd(int, int);
-SQLITE_PRIVATE void sqlite3StatusSet(int, int);
-
-SQLITE_PRIVATE int sqlite3IsNaN(double);
-
-SQLITE_PRIVATE void sqlite3VXPrintf(StrAccum*, int, const char*, va_list);
-SQLITE_PRIVATE char *sqlite3MPrintf(sqlite3*,const char*, ...);
-SQLITE_PRIVATE char *sqlite3VMPrintf(sqlite3*,const char*, va_list);
-SQLITE_PRIVATE char *sqlite3MAppendf(sqlite3*,char*,const char*,...);
-#if defined(SQLITE_TEST) || defined(SQLITE_DEBUG)
-SQLITE_PRIVATE void sqlite3DebugPrintf(const char*, ...);
-#endif
-#if defined(SQLITE_TEST)
-SQLITE_PRIVATE void *sqlite3TestTextToPtr(const char*);
-#endif
-SQLITE_PRIVATE void sqlite3SetString(char **, sqlite3*, const char*, ...);
-SQLITE_PRIVATE void sqlite3ErrorMsg(Parse*, const char*, ...);
-SQLITE_PRIVATE void sqlite3ErrorClear(Parse*);
-SQLITE_PRIVATE int sqlite3Dequote(char*);
-SQLITE_PRIVATE int sqlite3KeywordCode(const unsigned char*, int);
-SQLITE_PRIVATE int sqlite3RunParser(Parse*, const char*, char **);
-SQLITE_PRIVATE void sqlite3FinishCoding(Parse*);
-SQLITE_PRIVATE int sqlite3GetTempReg(Parse*);
-SQLITE_PRIVATE void sqlite3ReleaseTempReg(Parse*,int);
-SQLITE_PRIVATE int sqlite3GetTempRange(Parse*,int);
-SQLITE_PRIVATE void sqlite3ReleaseTempRange(Parse*,int,int);
-SQLITE_PRIVATE Expr *sqlite3ExprAlloc(sqlite3*,int,const Token*,int);
-SQLITE_PRIVATE Expr *sqlite3Expr(sqlite3*,int,const char*);
-SQLITE_PRIVATE void sqlite3ExprAttachSubtrees(sqlite3*,Expr*,Expr*,Expr*);
-SQLITE_PRIVATE Expr *sqlite3PExpr(Parse*, int, Expr*, Expr*, const Token*);
-SQLITE_PRIVATE Expr *sqlite3ExprAnd(sqlite3*,Expr*, Expr*);
-SQLITE_PRIVATE Expr *sqlite3ExprFunction(Parse*,ExprList*, Token*);
-SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse*, Expr*);
-SQLITE_PRIVATE void sqlite3ExprClear(sqlite3*, Expr*);
-SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3*, Expr*);
-SQLITE_PRIVATE ExprList *sqlite3ExprListAppend(Parse*,ExprList*,Expr*);
-SQLITE_PRIVATE void sqlite3ExprListSetName(Parse*,ExprList*,Token*,int);
-SQLITE_PRIVATE void sqlite3ExprListSetSpan(Parse*,ExprList*,ExprSpan*);
-SQLITE_PRIVATE void sqlite3ExprListDelete(sqlite3*, ExprList*);
-SQLITE_PRIVATE int sqlite3Init(sqlite3*, char**);
-SQLITE_PRIVATE int sqlite3InitCallback(void*, int, char**, char**);
-SQLITE_PRIVATE void sqlite3Pragma(Parse*,Token*,Token*,Token*,int);
-SQLITE_PRIVATE void sqlite3ResetInternalSchema(sqlite3*, int);
-SQLITE_PRIVATE void sqlite3BeginParse(Parse*,int);
-SQLITE_PRIVATE void sqlite3CommitInternalChanges(sqlite3*);
-SQLITE_PRIVATE Table *sqlite3ResultSetOfSelect(Parse*,Select*);
-SQLITE_PRIVATE void sqlite3OpenMasterTable(Parse *, int);
-SQLITE_PRIVATE void sqlite3StartTable(Parse*,Token*,Token*,int,int,int,int);
-SQLITE_PRIVATE void sqlite3AddColumn(Parse*,Token*);
-SQLITE_PRIVATE void sqlite3AddNotNull(Parse*, int);
-SQLITE_PRIVATE void sqlite3AddPrimaryKey(Parse*, ExprList*, int, int, int);
-SQLITE_PRIVATE void sqlite3AddCheckConstraint(Parse*, Expr*);
-SQLITE_PRIVATE void sqlite3AddColumnType(Parse*,Token*);
-SQLITE_PRIVATE void sqlite3AddDefaultValue(Parse*,ExprSpan*);
-SQLITE_PRIVATE void sqlite3AddCollateType(Parse*, Token*);
-SQLITE_PRIVATE void sqlite3EndTable(Parse*,Token*,Token*,Select*);
-
-SQLITE_PRIVATE Bitvec *sqlite3BitvecCreate(u32);
-SQLITE_PRIVATE int sqlite3BitvecTest(Bitvec*, u32);
-SQLITE_PRIVATE int sqlite3BitvecSet(Bitvec*, u32);
-SQLITE_PRIVATE void sqlite3BitvecClear(Bitvec*, u32, void*);
-SQLITE_PRIVATE void sqlite3BitvecDestroy(Bitvec*);
-SQLITE_PRIVATE u32 sqlite3BitvecSize(Bitvec*);
-SQLITE_PRIVATE int sqlite3BitvecBuiltinTest(int,int*);
-
-SQLITE_PRIVATE RowSet *sqlite3RowSetInit(sqlite3*, void*, unsigned int);
-SQLITE_PRIVATE void sqlite3RowSetClear(RowSet*);
-SQLITE_PRIVATE void sqlite3RowSetInsert(RowSet*, i64);
-SQLITE_PRIVATE int sqlite3RowSetTest(RowSet*, u8 iBatch, i64);
-SQLITE_PRIVATE int sqlite3RowSetNext(RowSet*, i64*);
-
-SQLITE_PRIVATE void sqlite3CreateView(Parse*,Token*,Token*,Token*,Select*,int,int);
-
-#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE)
-SQLITE_PRIVATE int sqlite3ViewGetColumnNames(Parse*,Table*);
-#else
-# define sqlite3ViewGetColumnNames(A,B) 0
-#endif
-
-SQLITE_PRIVATE void sqlite3DropTable(Parse*, SrcList*, int, int);
-SQLITE_PRIVATE void sqlite3DeleteTable(Table*);
-#ifndef SQLITE_OMIT_AUTOINCREMENT
-SQLITE_PRIVATE void sqlite3AutoincrementBegin(Parse *pParse);
-SQLITE_PRIVATE void sqlite3AutoincrementEnd(Parse *pParse);
-#else
-# define sqlite3AutoincrementBegin(X)
-# define sqlite3AutoincrementEnd(X)
-#endif
-SQLITE_PRIVATE void sqlite3Insert(Parse*, SrcList*, ExprList*, Select*, IdList*, int);
-SQLITE_PRIVATE void *sqlite3ArrayAllocate(sqlite3*,void*,int,int,int*,int*,int*);
-SQLITE_PRIVATE IdList *sqlite3IdListAppend(sqlite3*, IdList*, Token*);
-SQLITE_PRIVATE int sqlite3IdListIndex(IdList*,const char*);
-SQLITE_PRIVATE SrcList *sqlite3SrcListEnlarge(sqlite3*, SrcList*, int, int);
-SQLITE_PRIVATE SrcList *sqlite3SrcListAppend(sqlite3*, SrcList*, Token*, Token*);
-SQLITE_PRIVATE SrcList *sqlite3SrcListAppendFromTerm(Parse*, SrcList*, Token*, Token*,
- Token*, Select*, Expr*, IdList*);
-SQLITE_PRIVATE void sqlite3SrcListIndexedBy(Parse *, SrcList *, Token *);
-SQLITE_PRIVATE int sqlite3IndexedByLookup(Parse *, struct SrcList_item *);
-SQLITE_PRIVATE void sqlite3SrcListShiftJoinType(SrcList*);
-SQLITE_PRIVATE void sqlite3SrcListAssignCursors(Parse*, SrcList*);
-SQLITE_PRIVATE void sqlite3IdListDelete(sqlite3*, IdList*);
-SQLITE_PRIVATE void sqlite3SrcListDelete(sqlite3*, SrcList*);
-SQLITE_PRIVATE void sqlite3CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*,int,Token*,
- Token*, int, int);
-SQLITE_PRIVATE void sqlite3DropIndex(Parse*, SrcList*, int);
-SQLITE_PRIVATE int sqlite3Select(Parse*, Select*, SelectDest*);
-SQLITE_PRIVATE Select *sqlite3SelectNew(Parse*,ExprList*,SrcList*,Expr*,ExprList*,
- Expr*,ExprList*,int,Expr*,Expr*);
-SQLITE_PRIVATE void sqlite3SelectDelete(sqlite3*, Select*);
-SQLITE_PRIVATE Table *sqlite3SrcListLookup(Parse*, SrcList*);
-SQLITE_PRIVATE int sqlite3IsReadOnly(Parse*, Table*, int);
-SQLITE_PRIVATE void sqlite3OpenTable(Parse*, int iCur, int iDb, Table*, int);
-#if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY)
-SQLITE_PRIVATE Expr *sqlite3LimitWhere(Parse *, SrcList *, Expr *, ExprList *, Expr *, Expr *, char *);
-#endif
-SQLITE_PRIVATE void sqlite3DeleteFrom(Parse*, SrcList*, Expr*);
-SQLITE_PRIVATE void sqlite3Update(Parse*, SrcList*, ExprList*, Expr*, int);
-SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(Parse*, SrcList*, Expr*, ExprList**, u16);
-SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo*);
-SQLITE_PRIVATE int sqlite3ExprCodeGetColumn(Parse*, Table*, int, int, int, int);
-SQLITE_PRIVATE void sqlite3ExprCodeMove(Parse*, int, int, int);
-SQLITE_PRIVATE void sqlite3ExprCodeCopy(Parse*, int, int, int);
-SQLITE_PRIVATE void sqlite3ExprCacheStore(Parse*, int, int, int);
-SQLITE_PRIVATE void sqlite3ExprCachePush(Parse*);
-SQLITE_PRIVATE void sqlite3ExprCachePop(Parse*, int);
-SQLITE_PRIVATE void sqlite3ExprCacheRemove(Parse*, int);
-SQLITE_PRIVATE void sqlite3ExprCacheClear(Parse*);
-SQLITE_PRIVATE void sqlite3ExprCacheAffinityChange(Parse*, int, int);
-SQLITE_PRIVATE void sqlite3ExprHardCopy(Parse*,int,int);
-SQLITE_PRIVATE int sqlite3ExprCode(Parse*, Expr*, int);
-SQLITE_PRIVATE int sqlite3ExprCodeTemp(Parse*, Expr*, int*);
-SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse*, Expr*, int);
-SQLITE_PRIVATE int sqlite3ExprCodeAndCache(Parse*, Expr*, int);
-SQLITE_PRIVATE void sqlite3ExprCodeConstants(Parse*, Expr*);
-SQLITE_PRIVATE int sqlite3ExprCodeExprList(Parse*, ExprList*, int, int);
-SQLITE_PRIVATE void sqlite3ExprIfTrue(Parse*, Expr*, int, int);
-SQLITE_PRIVATE void sqlite3ExprIfFalse(Parse*, Expr*, int, int);
-SQLITE_PRIVATE Table *sqlite3FindTable(sqlite3*,const char*, const char*);
-SQLITE_PRIVATE Table *sqlite3LocateTable(Parse*,int isView,const char*, const char*);
-SQLITE_PRIVATE Index *sqlite3FindIndex(sqlite3*,const char*, const char*);
-SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTable(sqlite3*,int,const char*);
-SQLITE_PRIVATE void sqlite3UnlinkAndDeleteIndex(sqlite3*,int,const char*);
-SQLITE_PRIVATE void sqlite3Vacuum(Parse*);
-SQLITE_PRIVATE int sqlite3RunVacuum(char**, sqlite3*);
-SQLITE_PRIVATE char *sqlite3NameFromToken(sqlite3*, Token*);
-SQLITE_PRIVATE int sqlite3ExprCompare(Expr*, Expr*);
-SQLITE_PRIVATE void sqlite3ExprAnalyzeAggregates(NameContext*, Expr*);
-SQLITE_PRIVATE void sqlite3ExprAnalyzeAggList(NameContext*,ExprList*);
-SQLITE_PRIVATE Vdbe *sqlite3GetVdbe(Parse*);
-SQLITE_PRIVATE Expr *sqlite3CreateIdExpr(Parse *, const char*);
-SQLITE_PRIVATE void sqlite3PrngSaveState(void);
-SQLITE_PRIVATE void sqlite3PrngRestoreState(void);
-SQLITE_PRIVATE void sqlite3PrngResetState(void);
-SQLITE_PRIVATE void sqlite3RollbackAll(sqlite3*);
-SQLITE_PRIVATE void sqlite3CodeVerifySchema(Parse*, int);
-SQLITE_PRIVATE void sqlite3BeginTransaction(Parse*, int);
-SQLITE_PRIVATE void sqlite3CommitTransaction(Parse*);
-SQLITE_PRIVATE void sqlite3RollbackTransaction(Parse*);
-SQLITE_PRIVATE void sqlite3Savepoint(Parse*, int, Token*);
-SQLITE_PRIVATE void sqlite3CloseSavepoints(sqlite3 *);
-SQLITE_PRIVATE int sqlite3ExprIsConstant(Expr*);
-SQLITE_PRIVATE int sqlite3ExprIsConstantNotJoin(Expr*);
-SQLITE_PRIVATE int sqlite3ExprIsConstantOrFunction(Expr*);
-SQLITE_PRIVATE int sqlite3ExprIsInteger(Expr*, int*);
-SQLITE_PRIVATE int sqlite3IsRowid(const char*);
-SQLITE_PRIVATE void sqlite3GenerateRowDelete(Parse*, Table*, int, int, int, Trigger *, int);
-SQLITE_PRIVATE void sqlite3GenerateRowIndexDelete(Parse*, Table*, int, int*);
-SQLITE_PRIVATE int sqlite3GenerateIndexKey(Parse*, Index*, int, int, int);
-SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(Parse*,Table*,int,int,
- int*,int,int,int,int,int*);
-SQLITE_PRIVATE void sqlite3CompleteInsertion(Parse*, Table*, int, int, int*, int, int, int);
-SQLITE_PRIVATE int sqlite3OpenTableAndIndices(Parse*, Table*, int, int);
-SQLITE_PRIVATE void sqlite3BeginWriteOperation(Parse*, int, int);
-SQLITE_PRIVATE void sqlite3MayAbort(Parse *);
-SQLITE_PRIVATE void sqlite3HaltConstraint(Parse*, int, char*, int);
-SQLITE_PRIVATE Expr *sqlite3ExprDup(sqlite3*,Expr*,int);
-SQLITE_PRIVATE ExprList *sqlite3ExprListDup(sqlite3*,ExprList*,int);
-SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3*,SrcList*,int);
-SQLITE_PRIVATE IdList *sqlite3IdListDup(sqlite3*,IdList*);
-SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3*,Select*,int);
-SQLITE_PRIVATE void sqlite3FuncDefInsert(FuncDefHash*, FuncDef*);
-SQLITE_PRIVATE FuncDef *sqlite3FindFunction(sqlite3*,const char*,int,int,u8,int);
-SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(sqlite3*);
-SQLITE_PRIVATE void sqlite3RegisterDateTimeFunctions(void);
-SQLITE_PRIVATE void sqlite3RegisterGlobalFunctions(void);
-#ifdef SQLITE_DEBUG
-SQLITE_PRIVATE int sqlite3SafetyOn(sqlite3*);
-SQLITE_PRIVATE int sqlite3SafetyOff(sqlite3*);
-#else
-# define sqlite3SafetyOn(A) 0
-# define sqlite3SafetyOff(A) 0
-#endif
-SQLITE_PRIVATE int sqlite3SafetyCheckOk(sqlite3*);
-SQLITE_PRIVATE int sqlite3SafetyCheckSickOrOk(sqlite3*);
-SQLITE_PRIVATE void sqlite3ChangeCookie(Parse*, int);
-
-#if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER)
-SQLITE_PRIVATE void sqlite3MaterializeView(Parse*, Table*, Expr*, int);
-#endif
-
-#ifndef SQLITE_OMIT_TRIGGER
-SQLITE_PRIVATE void sqlite3BeginTrigger(Parse*, Token*,Token*,int,int,IdList*,SrcList*,
- Expr*,int, int);
-SQLITE_PRIVATE void sqlite3FinishTrigger(Parse*, TriggerStep*, Token*);
-SQLITE_PRIVATE void sqlite3DropTrigger(Parse*, SrcList*, int);
-SQLITE_PRIVATE void sqlite3DropTriggerPtr(Parse*, Trigger*);
-SQLITE_PRIVATE Trigger *sqlite3TriggersExist(Parse *, Table*, int, ExprList*, int *pMask);
-SQLITE_PRIVATE Trigger *sqlite3TriggerList(Parse *, Table *);
-SQLITE_PRIVATE void sqlite3CodeRowTrigger(Parse*, Trigger *, int, ExprList*, int, Table *,
- int, int, int, int);
- void sqliteViewTriggers(Parse*, Table*, Expr*, int, ExprList*);
-SQLITE_PRIVATE void sqlite3DeleteTriggerStep(sqlite3*, TriggerStep*);
-SQLITE_PRIVATE TriggerStep *sqlite3TriggerSelectStep(sqlite3*,Select*);
-SQLITE_PRIVATE TriggerStep *sqlite3TriggerInsertStep(sqlite3*,Token*, IdList*,
- ExprList*,Select*,u8);
-SQLITE_PRIVATE TriggerStep *sqlite3TriggerUpdateStep(sqlite3*,Token*,ExprList*, Expr*, u8);
-SQLITE_PRIVATE TriggerStep *sqlite3TriggerDeleteStep(sqlite3*,Token*, Expr*);
-SQLITE_PRIVATE void sqlite3DeleteTrigger(sqlite3*, Trigger*);
-SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTrigger(sqlite3*,int,const char*);
-SQLITE_PRIVATE u32 sqlite3TriggerOldmask(Parse*,Trigger*,int,ExprList*,Table*,int);
-# define sqlite3ParseToplevel(p) ((p)->pToplevel ? (p)->pToplevel : (p))
-#else
-# define sqlite3TriggersExist(B,C,D,E,F) 0
-# define sqlite3DeleteTrigger(A,B)
-# define sqlite3DropTriggerPtr(A,B)
-# define sqlite3UnlinkAndDeleteTrigger(A,B,C)
-# define sqlite3CodeRowTrigger(A,B,C,D,E,F,G,H,I,J)
-# define sqlite3TriggerList(X, Y) 0
-# define sqlite3ParseToplevel(p) p
-# define sqlite3TriggerOldmask(A,B,C,D,E,F) 0
-#endif
-
-SQLITE_PRIVATE int sqlite3JoinType(Parse*, Token*, Token*, Token*);
-SQLITE_PRIVATE void sqlite3CreateForeignKey(Parse*, ExprList*, Token*, ExprList*, int);
-SQLITE_PRIVATE void sqlite3DeferForeignKey(Parse*, int);
-#ifndef SQLITE_OMIT_AUTHORIZATION
-SQLITE_PRIVATE void sqlite3AuthRead(Parse*,Expr*,Schema*,SrcList*);
-SQLITE_PRIVATE int sqlite3AuthCheck(Parse*,int, const char*, const char*, const char*);
-SQLITE_PRIVATE void sqlite3AuthContextPush(Parse*, AuthContext*, const char*);
-SQLITE_PRIVATE void sqlite3AuthContextPop(AuthContext*);
-#else
-# define sqlite3AuthRead(a,b,c,d)
-# define sqlite3AuthCheck(a,b,c,d,e) SQLITE_OK
-# define sqlite3AuthContextPush(a,b,c)
-# define sqlite3AuthContextPop(a) ((void)(a))
-#endif
-SQLITE_PRIVATE void sqlite3Attach(Parse*, Expr*, Expr*, Expr*);
-SQLITE_PRIVATE void sqlite3Detach(Parse*, Expr*);
-SQLITE_PRIVATE int sqlite3BtreeFactory(const sqlite3 *db, const char *zFilename,
- int omitJournal, int nCache, int flags, Btree **ppBtree);
-SQLITE_PRIVATE int sqlite3FixInit(DbFixer*, Parse*, int, const char*, const Token*);
-SQLITE_PRIVATE int sqlite3FixSrcList(DbFixer*, SrcList*);
-SQLITE_PRIVATE int sqlite3FixSelect(DbFixer*, Select*);
-SQLITE_PRIVATE int sqlite3FixExpr(DbFixer*, Expr*);
-SQLITE_PRIVATE int sqlite3FixExprList(DbFixer*, ExprList*);
-SQLITE_PRIVATE int sqlite3FixTriggerStep(DbFixer*, TriggerStep*);
-SQLITE_PRIVATE int sqlite3AtoF(const char *z, double*);
-SQLITE_PRIVATE int sqlite3GetInt32(const char *, int*);
-SQLITE_PRIVATE int sqlite3FitsIn64Bits(const char *, int);
-SQLITE_PRIVATE int sqlite3Utf16ByteLen(const void *pData, int nChar);
-SQLITE_PRIVATE int sqlite3Utf8CharLen(const char *pData, int nByte);
-SQLITE_PRIVATE int sqlite3Utf8Read(const u8*, const u8**);
-
-/*
-** Routines to read and write variable-length integers. These used to
-** be defined locally, but now we use the varint routines in the util.c
-** file. Code should use the MACRO forms below, as the Varint32 versions
-** are coded to assume the single byte case is already handled (which
-** the MACRO form does).
-*/
-SQLITE_PRIVATE int sqlite3PutVarint(unsigned char*, u64);
-SQLITE_PRIVATE int sqlite3PutVarint32(unsigned char*, u32);
-SQLITE_PRIVATE u8 sqlite3GetVarint(const unsigned char *, u64 *);
-SQLITE_PRIVATE u8 sqlite3GetVarint32(const unsigned char *, u32 *);
-SQLITE_PRIVATE int sqlite3VarintLen(u64 v);
-
-/*
-** The header of a record consists of a sequence variable-length integers.
-** These integers are almost always small and are encoded as a single byte.
-** The following macros take advantage this fact to provide a fast encode
-** and decode of the integers in a record header. It is faster for the common
-** case where the integer is a single byte. It is a little slower when the
-** integer is two or more bytes. But overall it is faster.
-**
-** The following expressions are equivalent:
-**
-** x = sqlite3GetVarint32( A, &B );
-** x = sqlite3PutVarint32( A, B );
-**
-** x = getVarint32( A, B );
-** x = putVarint32( A, B );
-**
-*/
-#define getVarint32(A,B) (u8)((*(A)<(u8)0x80) ? ((B) = (u32)*(A)),1 : sqlite3GetVarint32((A), (u32 *)&(B)))
-#define putVarint32(A,B) (u8)(((u32)(B)<(u32)0x80) ? (*(A) = (unsigned char)(B)),1 : sqlite3PutVarint32((A), (B)))
-#define getVarint sqlite3GetVarint
-#define putVarint sqlite3PutVarint
-
-
-SQLITE_PRIVATE const char *sqlite3IndexAffinityStr(Vdbe *, Index *);
-SQLITE_PRIVATE void sqlite3TableAffinityStr(Vdbe *, Table *);
-SQLITE_PRIVATE char sqlite3CompareAffinity(Expr *pExpr, char aff2);
-SQLITE_PRIVATE int sqlite3IndexAffinityOk(Expr *pExpr, char idx_affinity);
-SQLITE_PRIVATE char sqlite3ExprAffinity(Expr *pExpr);
-SQLITE_PRIVATE int sqlite3Atoi64(const char*, i64*);
-SQLITE_PRIVATE void sqlite3Error(sqlite3*, int, const char*,...);
-SQLITE_PRIVATE void *sqlite3HexToBlob(sqlite3*, const char *z, int n);
-SQLITE_PRIVATE int sqlite3TwoPartName(Parse *, Token *, Token *, Token **);
-SQLITE_PRIVATE const char *sqlite3ErrStr(int);
-SQLITE_PRIVATE int sqlite3ReadSchema(Parse *pParse);
-SQLITE_PRIVATE CollSeq *sqlite3FindCollSeq(sqlite3*,u8 enc, const char*,int);
-SQLITE_PRIVATE CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char*zName);
-SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr);
-SQLITE_PRIVATE Expr *sqlite3ExprSetColl(Parse *pParse, Expr *, Token *);
-SQLITE_PRIVATE int sqlite3CheckCollSeq(Parse *, CollSeq *);
-SQLITE_PRIVATE int sqlite3CheckObjectName(Parse *, const char *);
-SQLITE_PRIVATE void sqlite3VdbeSetChanges(sqlite3 *, int);
-
-SQLITE_PRIVATE const void *sqlite3ValueText(sqlite3_value*, u8);
-SQLITE_PRIVATE int sqlite3ValueBytes(sqlite3_value*, u8);
-SQLITE_PRIVATE void sqlite3ValueSetStr(sqlite3_value*, int, const void *,u8,
- void(*)(void*));
-SQLITE_PRIVATE void sqlite3ValueFree(sqlite3_value*);
-SQLITE_PRIVATE sqlite3_value *sqlite3ValueNew(sqlite3 *);
-SQLITE_PRIVATE char *sqlite3Utf16to8(sqlite3 *, const void*, int);
-#ifdef SQLITE_ENABLE_STAT2
-SQLITE_PRIVATE char *sqlite3Utf8to16(sqlite3 *, u8, char *, int, int *);
-#endif
-SQLITE_PRIVATE int sqlite3ValueFromExpr(sqlite3 *, Expr *, u8, u8, sqlite3_value **);
-SQLITE_PRIVATE void sqlite3ValueApplyAffinity(sqlite3_value *, u8, u8);
-#ifndef SQLITE_AMALGAMATION
-SQLITE_PRIVATE const unsigned char sqlite3UpperToLower[];
-SQLITE_PRIVATE const unsigned char sqlite3CtypeMap[];
-SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config sqlite3Config;
-SQLITE_PRIVATE SQLITE_WSD FuncDefHash sqlite3GlobalFunctions;
-SQLITE_PRIVATE int sqlite3PendingByte;
-#endif
-SQLITE_PRIVATE void sqlite3RootPageMoved(Db*, int, int);
-SQLITE_PRIVATE void sqlite3Reindex(Parse*, Token*, Token*);
-SQLITE_PRIVATE void sqlite3AlterFunctions(sqlite3*);
-SQLITE_PRIVATE void sqlite3AlterRenameTable(Parse*, SrcList*, Token*);
-SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *, int *);
-SQLITE_PRIVATE void sqlite3NestedParse(Parse*, const char*, ...);
-SQLITE_PRIVATE void sqlite3ExpirePreparedStatements(sqlite3*);
-SQLITE_PRIVATE void sqlite3CodeSubselect(Parse *, Expr *, int, int);
-SQLITE_PRIVATE void sqlite3SelectPrep(Parse*, Select*, NameContext*);
-SQLITE_PRIVATE int sqlite3ResolveExprNames(NameContext*, Expr*);
-SQLITE_PRIVATE void sqlite3ResolveSelectNames(Parse*, Select*, NameContext*);
-SQLITE_PRIVATE int sqlite3ResolveOrderGroupBy(Parse*, Select*, ExprList*, const char*);
-SQLITE_PRIVATE void sqlite3ColumnDefault(Vdbe *, Table *, int, int);
-SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *, Token *);
-SQLITE_PRIVATE void sqlite3AlterBeginAddColumn(Parse *, SrcList *);
-SQLITE_PRIVATE CollSeq *sqlite3GetCollSeq(sqlite3*, u8, CollSeq *, const char*);
-SQLITE_PRIVATE char sqlite3AffinityType(const char*);
-SQLITE_PRIVATE void sqlite3Analyze(Parse*, Token*, Token*);
-SQLITE_PRIVATE int sqlite3InvokeBusyHandler(BusyHandler*);
-SQLITE_PRIVATE int sqlite3FindDb(sqlite3*, Token*);
-SQLITE_PRIVATE int sqlite3FindDbName(sqlite3 *, const char *);
-SQLITE_PRIVATE int sqlite3AnalysisLoad(sqlite3*,int iDB);
-SQLITE_PRIVATE void sqlite3DeleteIndexSamples(Index*);
-SQLITE_PRIVATE void sqlite3DefaultRowEst(Index*);
-SQLITE_PRIVATE void sqlite3RegisterLikeFunctions(sqlite3*, int);
-SQLITE_PRIVATE int sqlite3IsLikeFunction(sqlite3*,Expr*,int*,char*);
-SQLITE_PRIVATE void sqlite3MinimumFileFormat(Parse*, int, int);
-SQLITE_PRIVATE void sqlite3SchemaFree(void *);
-SQLITE_PRIVATE Schema *sqlite3SchemaGet(sqlite3 *, Btree *);
-SQLITE_PRIVATE int sqlite3SchemaToIndex(sqlite3 *db, Schema *);
-SQLITE_PRIVATE KeyInfo *sqlite3IndexKeyinfo(Parse *, Index *);
-SQLITE_PRIVATE int sqlite3CreateFunc(sqlite3 *, const char *, int, int, void *,
- void (*)(sqlite3_context*,int,sqlite3_value **),
- void (*)(sqlite3_context*,int,sqlite3_value **), void (*)(sqlite3_context*));
-SQLITE_PRIVATE int sqlite3ApiExit(sqlite3 *db, int);
-SQLITE_PRIVATE int sqlite3OpenTempDatabase(Parse *);
-
-SQLITE_PRIVATE void sqlite3StrAccumInit(StrAccum*, char*, int, int);
-SQLITE_PRIVATE void sqlite3StrAccumAppend(StrAccum*,const char*,int);
-SQLITE_PRIVATE char *sqlite3StrAccumFinish(StrAccum*);
-SQLITE_PRIVATE void sqlite3StrAccumReset(StrAccum*);
-SQLITE_PRIVATE void sqlite3SelectDestInit(SelectDest*,int,int);
-
-SQLITE_PRIVATE void sqlite3BackupRestart(sqlite3_backup *);
-SQLITE_PRIVATE void sqlite3BackupUpdate(sqlite3_backup *, Pgno, const u8 *);
-
-/*
-** The interface to the LEMON-generated parser
-*/
-SQLITE_PRIVATE void *sqlite3ParserAlloc(void*(*)(size_t));
-SQLITE_PRIVATE void sqlite3ParserFree(void*, void(*)(void*));
-SQLITE_PRIVATE void sqlite3Parser(void*, int, Token, Parse*);
-#ifdef YYTRACKMAXSTACKDEPTH
-SQLITE_PRIVATE int sqlite3ParserStackPeak(void*);
-#endif
-
-SQLITE_PRIVATE void sqlite3AutoLoadExtensions(sqlite3*);
-#ifndef SQLITE_OMIT_LOAD_EXTENSION
-SQLITE_PRIVATE void sqlite3CloseExtensions(sqlite3*);
-#else
-# define sqlite3CloseExtensions(X)
-#endif
-
-#ifndef SQLITE_OMIT_SHARED_CACHE
-SQLITE_PRIVATE void sqlite3TableLock(Parse *, int, int, u8, const char *);
-#else
- #define sqlite3TableLock(v,w,x,y,z)
-#endif
-
-#ifdef SQLITE_TEST
-SQLITE_PRIVATE int sqlite3Utf8To8(unsigned char*);
-#endif
-
-#ifdef SQLITE_OMIT_VIRTUALTABLE
-# define sqlite3VtabClear(Y)
-# define sqlite3VtabSync(X,Y) SQLITE_OK
-# define sqlite3VtabRollback(X)
-# define sqlite3VtabCommit(X)
-# define sqlite3VtabInSync(db) 0
-# define sqlite3VtabLock(X)
-# define sqlite3VtabUnlock(X)
-# define sqlite3VtabUnlockList(X)
-#else
-SQLITE_PRIVATE void sqlite3VtabClear(Table*);
-SQLITE_PRIVATE int sqlite3VtabSync(sqlite3 *db, char **);
-SQLITE_PRIVATE int sqlite3VtabRollback(sqlite3 *db);
-SQLITE_PRIVATE int sqlite3VtabCommit(sqlite3 *db);
-SQLITE_PRIVATE void sqlite3VtabLock(VTable *);
-SQLITE_PRIVATE void sqlite3VtabUnlock(VTable *);
-SQLITE_PRIVATE void sqlite3VtabUnlockList(sqlite3*);
-# define sqlite3VtabInSync(db) ((db)->nVTrans>0 && (db)->aVTrans==0)
-#endif
-SQLITE_PRIVATE void sqlite3VtabMakeWritable(Parse*,Table*);
-SQLITE_PRIVATE void sqlite3VtabBeginParse(Parse*, Token*, Token*, Token*);
-SQLITE_PRIVATE void sqlite3VtabFinishParse(Parse*, Token*);
-SQLITE_PRIVATE void sqlite3VtabArgInit(Parse*);
-SQLITE_PRIVATE void sqlite3VtabArgExtend(Parse*, Token*);
-SQLITE_PRIVATE int sqlite3VtabCallCreate(sqlite3*, int, const char *, char **);
-SQLITE_PRIVATE int sqlite3VtabCallConnect(Parse*, Table*);
-SQLITE_PRIVATE int sqlite3VtabCallDestroy(sqlite3*, int, const char *);
-SQLITE_PRIVATE int sqlite3VtabBegin(sqlite3 *, VTable *);
-SQLITE_PRIVATE FuncDef *sqlite3VtabOverloadFunction(sqlite3 *,FuncDef*, int nArg, Expr*);
-SQLITE_PRIVATE void sqlite3InvalidFunction(sqlite3_context*,int,sqlite3_value**);
-SQLITE_PRIVATE int sqlite3TransferBindings(sqlite3_stmt *, sqlite3_stmt *);
-SQLITE_PRIVATE int sqlite3Reprepare(Vdbe*);
-SQLITE_PRIVATE void sqlite3ExprListCheckLength(Parse*, ExprList*, const char*);
-SQLITE_PRIVATE CollSeq *sqlite3BinaryCompareCollSeq(Parse *, Expr *, Expr *);
-SQLITE_PRIVATE int sqlite3TempInMemory(const sqlite3*);
-SQLITE_PRIVATE VTable *sqlite3GetVTable(sqlite3*, Table*);
-
-
-
-/*
-** Available fault injectors. Should be numbered beginning with 0.
-*/
-#define SQLITE_FAULTINJECTOR_MALLOC 0
-#define SQLITE_FAULTINJECTOR_COUNT 1
-
-/*
-** The interface to the code in fault.c used for identifying "benign"
-** malloc failures. This is only present if SQLITE_OMIT_BUILTIN_TEST
-** is not defined.
-*/
-#ifndef SQLITE_OMIT_BUILTIN_TEST
-SQLITE_PRIVATE void sqlite3BeginBenignMalloc(void);
-SQLITE_PRIVATE void sqlite3EndBenignMalloc(void);
-#else
- #define sqlite3BeginBenignMalloc()
- #define sqlite3EndBenignMalloc()
-#endif
-
-#define IN_INDEX_ROWID 1
-#define IN_INDEX_EPH 2
-#define IN_INDEX_INDEX 3
-SQLITE_PRIVATE int sqlite3FindInIndex(Parse *, Expr *, int*);
-
-#ifdef SQLITE_ENABLE_ATOMIC_WRITE
-SQLITE_PRIVATE int sqlite3JournalOpen(sqlite3_vfs *, const char *, sqlite3_file *, int, int);
-SQLITE_PRIVATE int sqlite3JournalSize(sqlite3_vfs *);
-SQLITE_PRIVATE int sqlite3JournalCreate(sqlite3_file *);
-#else
- #define sqlite3JournalSize(pVfs) ((pVfs)->szOsFile)
-#endif
-
-SQLITE_PRIVATE void sqlite3MemJournalOpen(sqlite3_file *);
-SQLITE_PRIVATE int sqlite3MemJournalSize(void);
-SQLITE_PRIVATE int sqlite3IsMemJournal(sqlite3_file *);
-
-#if SQLITE_MAX_EXPR_DEPTH>0
-SQLITE_PRIVATE void sqlite3ExprSetHeight(Parse *pParse, Expr *p);
-SQLITE_PRIVATE int sqlite3SelectExprHeight(Select *);
-SQLITE_PRIVATE int sqlite3ExprCheckHeight(Parse*, int);
-#else
- #define sqlite3ExprSetHeight(x,y)
- #define sqlite3SelectExprHeight(x) 0
- #define sqlite3ExprCheckHeight(x,y)
-#endif
-
-SQLITE_PRIVATE u32 sqlite3Get4byte(const u8*);
-SQLITE_PRIVATE void sqlite3Put4byte(u8*, u32);
-
-#ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
-SQLITE_PRIVATE void sqlite3ConnectionBlocked(sqlite3 *, sqlite3 *);
-SQLITE_PRIVATE void sqlite3ConnectionUnlocked(sqlite3 *db);
-SQLITE_PRIVATE void sqlite3ConnectionClosed(sqlite3 *db);
-#else
- #define sqlite3ConnectionBlocked(x,y)
- #define sqlite3ConnectionUnlocked(x)
- #define sqlite3ConnectionClosed(x)
-#endif
-
-#ifdef SQLITE_DEBUG
-SQLITE_PRIVATE void sqlite3ParserTrace(FILE*, char *);
-#endif
-
-/*
-** If the SQLITE_ENABLE IOTRACE exists then the global variable
-** sqlite3IoTrace is a pointer to a printf-like routine used to
-** print I/O tracing messages.
-*/
-#ifdef SQLITE_ENABLE_IOTRACE
-# define IOTRACE(A) if( sqlite3IoTrace ){ sqlite3IoTrace A; }
-SQLITE_PRIVATE void sqlite3VdbeIOTraceSql(Vdbe*);
-SQLITE_PRIVATE void (*sqlite3IoTrace)(const char*,...);
-#else
-# define IOTRACE(A)
-# define sqlite3VdbeIOTraceSql(X)
-#endif
-
-#endif
-
-/************** End of sqliteInt.h *******************************************/
-/************** Begin file global.c ******************************************/
-/*
-** 2008 June 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 definitions of global variables and contants.
-*/
-
-
-/* An array to map all upper-case characters into their corresponding
-** lower-case character.
-**
-** SQLite only considers US-ASCII (or EBCDIC) characters. We do not
-** handle case conversions for the UTF character set since the tables
-** involved are nearly as big or bigger than SQLite itself.
-*/
-SQLITE_PRIVATE const unsigned char sqlite3UpperToLower[] = {
-#ifdef SQLITE_ASCII
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
- 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
- 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
- 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 97, 98, 99,100,101,102,103,
- 104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,
- 122, 91, 92, 93, 94, 95, 96, 97, 98, 99,100,101,102,103,104,105,106,107,
- 108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,
- 126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
- 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,
- 162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,
- 180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,
- 198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,
- 216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,
- 234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,
- 252,253,254,255
-#endif
-#ifdef SQLITE_EBCDIC
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /* 0x */
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, /* 1x */
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, /* 2x */
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, /* 3x */
- 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, /* 4x */
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, /* 5x */
- 96, 97, 66, 67, 68, 69, 70, 71, 72, 73,106,107,108,109,110,111, /* 6x */
- 112, 81, 82, 83, 84, 85, 86, 87, 88, 89,122,123,124,125,126,127, /* 7x */
- 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, /* 8x */
- 144,145,146,147,148,149,150,151,152,153,154,155,156,157,156,159, /* 9x */
- 160,161,162,163,164,165,166,167,168,169,170,171,140,141,142,175, /* Ax */
- 176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191, /* Bx */
- 192,129,130,131,132,133,134,135,136,137,202,203,204,205,206,207, /* Cx */
- 208,145,146,147,148,149,150,151,152,153,218,219,220,221,222,223, /* Dx */
- 224,225,162,163,164,165,166,167,168,169,232,203,204,205,206,207, /* Ex */
- 239,240,241,242,243,244,245,246,247,248,249,219,220,221,222,255, /* Fx */
-#endif
-};
-
-/*
-** The following 256 byte lookup table is used to support SQLites built-in
-** equivalents to the following standard library functions:
-**
-** isspace() 0x01
-** isalpha() 0x02
-** isdigit() 0x04
-** isalnum() 0x06
-** isxdigit() 0x08
-** toupper() 0x20
-**
-** Bit 0x20 is set if the mapped character requires translation to upper
-** case. i.e. if the character is a lower-case ASCII character.
-** If x is a lower-case ASCII character, then its upper-case equivalent
-** is (x - 0x20). Therefore toupper() can be implemented as:
-**
-** (x & ~(map[x]&0x20))
-**
-** Standard function tolower() is implemented using the sqlite3UpperToLower[]
-** array. tolower() is used more often than toupper() by SQLite.
-**
-** SQLite's versions are identical to the standard versions assuming a
-** locale of "C". They are implemented as macros in sqliteInt.h.
-*/
-#ifdef SQLITE_ASCII
-SQLITE_PRIVATE const unsigned char sqlite3CtypeMap[256] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 00..07 ........ */
- 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, /* 08..0f ........ */
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 10..17 ........ */
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 18..1f ........ */
- 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 20..27 !"#$%&' */
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 28..2f ()*+,-./ */
- 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, /* 30..37 01234567 */
- 0x0c, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 38..3f 89:;<=>? */
-
- 0x00, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x02, /* 40..47 @ABCDEFG */
- 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* 48..4f HIJKLMNO */
- 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* 50..57 PQRSTUVW */
- 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, /* 58..5f XYZ[\]^_ */
- 0x00, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x22, /* 60..67 `abcdefg */
- 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, /* 68..6f hijklmno */
- 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, /* 70..77 pqrstuvw */
- 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, /* 78..7f xyz{|}~. */
-
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 80..87 ........ */
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 88..8f ........ */
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 90..97 ........ */
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 98..9f ........ */
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* a0..a7 ........ */
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* a8..af ........ */
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* b0..b7 ........ */
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* b8..bf ........ */
-
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* c0..c7 ........ */
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* c8..cf ........ */
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* d0..d7 ........ */
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* d8..df ........ */
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* e0..e7 ........ */
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* e8..ef ........ */
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* f0..f7 ........ */
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* f8..ff ........ */
-};
-#endif
-
-
-
-/*
-** The following singleton contains the global configuration for
-** the SQLite library.
-*/
-SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config sqlite3Config = {
- SQLITE_DEFAULT_MEMSTATUS, /* bMemstat */
- 1, /* bCoreMutex */
- SQLITE_THREADSAFE==1, /* bFullMutex */
- 0x7ffffffe, /* mxStrlen */
- 100, /* szLookaside */
- 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 */
- (void*)0, /* pHeap */
- 0, /* nHeap */
- 0, 0, /* mnHeap, mxHeap */
- (void*)0, /* pScratch */
- 0, /* szScratch */
- 0, /* nScratch */
- (void*)0, /* pPage */
- 0, /* szPage */
- 0, /* nPage */
- 0, /* mxParserStack */
- 0, /* sharedCacheEnabled */
- /* All the rest should always be initialized to zero */
- 0, /* isInit */
- 0, /* inProgress */
- 0, /* isMutexInit */
- 0, /* isMallocInit */
- 0, /* isPCacheInit */
- 0, /* pInitMutex */
- 0, /* nRefInitMutex */
-};
-
-
-/*
-** Hash table for global functions - functions common to all
-** database connections. After initialization, this table is
-** read-only.
-*/
-SQLITE_PRIVATE SQLITE_WSD FuncDefHash sqlite3GlobalFunctions;
-
-/*
-** The value of the "pending" byte must be 0x40000000 (1 byte past the
-** 1-gibabyte boundary) in a compatible database. SQLite never uses
-** the database page that contains the pending byte. It never attempts
-** to read or write that page. The pending byte page is set assign
-** for use by the VFS layers as space for managing file locks.
-**
-** During testing, it is often desirable to move the pending byte to
-** a different position in the file. This allows code that has to
-** deal with the pending byte to run on files that are much smaller
-** than 1 GiB. The sqlite3_test_control() interface can be used to
-** move the pending byte.
-**
-** IMPORTANT: Changing the pending byte to any value other than
-** 0x40000000 results in an incompatible database file format!
-** Changing the pending byte during operating results in undefined
-** and dileterious behavior.
-*/
-SQLITE_PRIVATE int sqlite3PendingByte = 0x40000000;
-
-/************** End of global.c **********************************************/
-/************** Begin file status.c ******************************************/
-/*
-** 2008 June 18
-**
-** 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 module implements the sqlite3_status() interface and related
-** functionality.
-**
-** $Id: status.c,v 1.9 2008/09/02 00:52:52 drh Exp $
-*/
-
-/*
-** Variables in which to record status information.
-*/
-typedef struct sqlite3StatType sqlite3StatType;
-static SQLITE_WSD struct sqlite3StatType {
- int nowValue[9]; /* Current value */
- int mxValue[9]; /* Maximum value */
-} sqlite3Stat = { {0,}, {0,} };
-
-
-/* The "wsdStat" macro will resolve to the status information
-** state vector. If writable static data is unsupported on the target,
-** we have to locate the state vector at run-time. In the more common
-** case where writable static data is supported, wsdStat can refer directly
-** to the "sqlite3Stat" state vector declared above.
-*/
-#ifdef SQLITE_OMIT_WSD
-# define wsdStatInit sqlite3StatType *x = &GLOBAL(sqlite3StatType,sqlite3Stat)
-# define wsdStat x[0]
-#else
-# define wsdStatInit
-# define wsdStat sqlite3Stat
-#endif
-
-/*
-** Return the current value of a status parameter.
-*/
-SQLITE_PRIVATE int sqlite3StatusValue(int op){
- wsdStatInit;
- assert( op>=0 && op<ArraySize(wsdStat.nowValue) );
- return wsdStat.nowValue[op];
-}
-
-/*
-** Add N to the value of a status record. It is assumed that the
-** caller holds appropriate locks.
-*/
-SQLITE_PRIVATE void sqlite3StatusAdd(int op, int N){
- wsdStatInit;
- assert( op>=0 && op<ArraySize(wsdStat.nowValue) );
- wsdStat.nowValue[op] += N;
- if( wsdStat.nowValue[op]>wsdStat.mxValue[op] ){
- wsdStat.mxValue[op] = wsdStat.nowValue[op];
- }
-}
-
-/*
-** Set the value of a status to X.
-*/
-SQLITE_PRIVATE void sqlite3StatusSet(int op, int X){
- wsdStatInit;
- assert( op>=0 && op<ArraySize(wsdStat.nowValue) );
- wsdStat.nowValue[op] = X;
- if( wsdStat.nowValue[op]>wsdStat.mxValue[op] ){
- wsdStat.mxValue[op] = wsdStat.nowValue[op];
- }
-}
-
-/*
-** Query status information.
-**
-** This implementation assumes that reading or writing an aligned
-** 32-bit integer is an atomic operation. If that assumption is not true,
-** then this routine is not threadsafe.
-*/
-SQLITE_API int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag){
- wsdStatInit;
- if( op<0 || op>=ArraySize(wsdStat.nowValue) ){
- return SQLITE_MISUSE;
- }
- *pCurrent = wsdStat.nowValue[op];
- *pHighwater = wsdStat.mxValue[op];
- if( resetFlag ){
- wsdStat.mxValue[op] = wsdStat.nowValue[op];
- }
- return SQLITE_OK;
-}
-
-/*
-** Query status information for a single database connection
-*/
-SQLITE_API int sqlite3_db_status(
- sqlite3 *db, /* The database connection whose status is desired */
- int op, /* Status verb */
- int *pCurrent, /* Write current value here */
- int *pHighwater, /* Write high-water mark here */
- int resetFlag /* Reset high-water mark if true */
-){
- switch( op ){
- case SQLITE_DBSTATUS_LOOKASIDE_USED: {
- *pCurrent = db->lookaside.nOut;
- *pHighwater = db->lookaside.mxOut;
- if( resetFlag ){
- db->lookaside.mxOut = db->lookaside.nOut;
- }
- break;
- }
- default: {
- return SQLITE_ERROR;
- }
- }
- return SQLITE_OK;
-}
-
-/************** End of status.c **********************************************/
-/************** Begin file date.c ********************************************/
-/*
-** 2003 October 31
-**
-** 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 C functions that implement date and time
-** functions for SQLite.
-**
-** There is only one exported symbol in this file - the function
-** sqlite3RegisterDateTimeFunctions() found at the bottom of the file.
-** All other code has file scope.
-**
-** $Id: date.c,v 1.107 2009/05/03 20:23:53 drh Exp $
-**
-** SQLite processes all times and dates as Julian Day numbers. The
-** dates and times are stored as the number of days since noon
-** in Greenwich on November 24, 4714 B.C. according to the Gregorian
-** calendar system.
-**
-** 1970-01-01 00:00:00 is JD 2440587.5
-** 2000-01-01 00:00:00 is JD 2451544.5
-**
-** This implemention requires years to be expressed as a 4-digit number
-** which means that only dates between 0000-01-01 and 9999-12-31 can
-** be represented, even though julian day numbers allow a much wider
-** range of dates.
-**
-** The Gregorian calendar system is used for all dates and times,
-** even those that predate the Gregorian calendar. Historians usually
-** use the Julian calendar for dates prior to 1582-10-15 and for some
-** dates afterwards, depending on locale. Beware of this difference.
-**
-** The conversion algorithms are implemented based on descriptions
-** in the following text:
-**
-** Jean Meeus
-** Astronomical Algorithms, 2nd Edition, 1998
-** ISBM 0-943396-61-1
-** Willmann-Bell, Inc
-** Richmond, Virginia (USA)
-*/
-#include <time.h>
-
-#ifndef SQLITE_OMIT_DATETIME_FUNCS
-
-/*
-** On recent Windows platforms, the localtime_s() function is available
-** as part of the "Secure CRT". It is essentially equivalent to
-** localtime_r() available under most POSIX platforms, except that the
-** order of the parameters is reversed.
-**
-** See http://msdn.microsoft.com/en-us/library/a442x3ye(VS.80).aspx.
-**
-** If the user has not indicated to use localtime_r() or localtime_s()
-** already, check for an MSVC build environment that provides
-** localtime_s().
-*/
-#if !defined(HAVE_LOCALTIME_R) && !defined(HAVE_LOCALTIME_S) && \
- defined(_MSC_VER) && defined(_CRT_INSECURE_DEPRECATE)
-#define HAVE_LOCALTIME_S 1
-#endif
-
-/*
-** A structure for holding a single date and time.
-*/
-typedef struct DateTime DateTime;
-struct DateTime {
- sqlite3_int64 iJD; /* The julian day number times 86400000 */
- int Y, M, D; /* Year, month, and day */
- int h, m; /* Hour and minutes */
- int tz; /* Timezone offset in minutes */
- double s; /* Seconds */
- char validYMD; /* True (1) if Y,M,D are valid */
- char validHMS; /* True (1) if h,m,s are valid */
- char validJD; /* True (1) if iJD is valid */
- char validTZ; /* True (1) if tz is valid */
-};
-
-
-/*
-** Convert zDate into one or more integers. Additional arguments
-** come in groups of 5 as follows:
-**
-** N number of digits in the integer
-** min minimum allowed value of the integer
-** max maximum allowed value of the integer
-** nextC first character after the integer
-** pVal where to write the integers value.
-**
-** Conversions continue until one with nextC==0 is encountered.
-** The function returns the number of successful conversions.
-*/
-static int getDigits(const char *zDate, ...){
- va_list ap;
- int val;
- int N;
- int min;
- int max;
- int nextC;
- int *pVal;
- int cnt = 0;
- va_start(ap, zDate);
- do{
- N = va_arg(ap, int);
- min = va_arg(ap, int);
- max = va_arg(ap, int);
- nextC = va_arg(ap, int);
- pVal = va_arg(ap, int*);
- val = 0;
- while( N-- ){
- if( !sqlite3Isdigit(*zDate) ){
- goto end_getDigits;
- }
- val = val*10 + *zDate - '0';
- zDate++;
- }
- if( val<min || val>max || (nextC!=0 && nextC!=*zDate) ){
- goto end_getDigits;
- }
- *pVal = val;
- zDate++;
- cnt++;
- }while( nextC );
-end_getDigits:
- va_end(ap);
- return cnt;
-}
-
-/*
-** Read text from z[] and convert into a floating point number. Return
-** the number of digits converted.
-*/
-#define getValue sqlite3AtoF
-
-/*
-** Parse a timezone extension on the end of a date-time.
-** The extension is of the form:
-**
-** (+/-)HH:MM
-**
-** Or the "zulu" notation:
-**
-** Z
-**
-** If the parse is successful, write the number of minutes
-** of change in p->tz and return 0. If a parser error occurs,
-** return non-zero.
-**
-** A missing specifier is not considered an error.
-*/
-static int parseTimezone(const char *zDate, DateTime *p){
- int sgn = 0;
- int nHr, nMn;
- int c;
- while( sqlite3Isspace(*zDate) ){ zDate++; }
- p->tz = 0;
- c = *zDate;
- if( c=='-' ){
- sgn = -1;
- }else if( c=='+' ){
- sgn = +1;
- }else if( c=='Z' || c=='z' ){
- zDate++;
- goto zulu_time;
- }else{
- return c!=0;
- }
- zDate++;
- if( getDigits(zDate, 2, 0, 14, ':', &nHr, 2, 0, 59, 0, &nMn)!=2 ){
- return 1;
- }
- zDate += 5;
- p->tz = sgn*(nMn + nHr*60);
-zulu_time:
- while( sqlite3Isspace(*zDate) ){ zDate++; }
- return *zDate!=0;
-}
-
-/*
-** Parse times of the form HH:MM or HH:MM:SS or HH:MM:SS.FFFF.
-** The HH, MM, and SS must each be exactly 2 digits. The
-** fractional seconds FFFF can be one or more digits.
-**
-** Return 1 if there is a parsing error and 0 on success.
-*/
-static int parseHhMmSs(const char *zDate, DateTime *p){
- int h, m, s;
- double ms = 0.0;
- if( getDigits(zDate, 2, 0, 24, ':', &h, 2, 0, 59, 0, &m)!=2 ){
- return 1;
- }
- zDate += 5;
- if( *zDate==':' ){
- zDate++;
- if( getDigits(zDate, 2, 0, 59, 0, &s)!=1 ){
- return 1;
- }
- zDate += 2;
- if( *zDate=='.' && sqlite3Isdigit(zDate[1]) ){
- double rScale = 1.0;
- zDate++;
- while( sqlite3Isdigit(*zDate) ){
- ms = ms*10.0 + *zDate - '0';
- rScale *= 10.0;
- zDate++;
- }
- ms /= rScale;
- }
- }else{
- s = 0;
- }
- p->validJD = 0;
- p->validHMS = 1;
- p->h = h;
- p->m = m;
- p->s = s + ms;
- if( parseTimezone(zDate, p) ) return 1;
- p->validTZ = (p->tz!=0)?1:0;
- return 0;
-}
-
-/*
-** Convert from YYYY-MM-DD HH:MM:SS to julian day. We always assume
-** that the YYYY-MM-DD is according to the Gregorian calendar.
-**
-** Reference: Meeus page 61
-*/
-static void computeJD(DateTime *p){
- int Y, M, D, A, B, X1, X2;
-
- if( p->validJD ) return;
- if( p->validYMD ){
- Y = p->Y;
- M = p->M;
- D = p->D;
- }else{
- Y = 2000; /* If no YMD specified, assume 2000-Jan-01 */
- M = 1;
- D = 1;
- }
- if( M<=2 ){
- Y--;
- M += 12;
- }
- A = Y/100;
- B = 2 - A + (A/4);
- X1 = 36525*(Y+4716)/100;
- X2 = 306001*(M+1)/10000;
- p->iJD = (sqlite3_int64)((X1 + X2 + D + B - 1524.5 ) * 86400000);
- p->validJD = 1;
- if( p->validHMS ){
- p->iJD += p->h*3600000 + p->m*60000 + (sqlite3_int64)(p->s*1000);
- if( p->validTZ ){
- p->iJD -= p->tz*60000;
- p->validYMD = 0;
- p->validHMS = 0;
- p->validTZ = 0;
- }
- }
-}
-
-/*
-** Parse dates of the form
-**
-** YYYY-MM-DD HH:MM:SS.FFF
-** YYYY-MM-DD HH:MM:SS
-** YYYY-MM-DD HH:MM
-** YYYY-MM-DD
-**
-** Write the result into the DateTime structure and return 0
-** on success and 1 if the input string is not a well-formed
-** date.
-*/
-static int parseYyyyMmDd(const char *zDate, DateTime *p){
- int Y, M, D, neg;
-
- if( zDate[0]=='-' ){
- zDate++;
- neg = 1;
- }else{
- neg = 0;
- }
- if( getDigits(zDate,4,0,9999,'-',&Y,2,1,12,'-',&M,2,1,31,0,&D)!=3 ){
- return 1;
- }
- zDate += 10;
- while( sqlite3Isspace(*zDate) || 'T'==*(u8*)zDate ){ zDate++; }
- if( parseHhMmSs(zDate, p)==0 ){
- /* We got the time */
- }else if( *zDate==0 ){
- p->validHMS = 0;
- }else{
- return 1;
- }
- p->validJD = 0;
- p->validYMD = 1;
- p->Y = neg ? -Y : Y;
- p->M = M;
- p->D = D;
- if( p->validTZ ){
- computeJD(p);
- }
- return 0;
-}
-
-/*
-** Set the time to the current time reported by the VFS
-*/
-static void setDateTimeToCurrent(sqlite3_context *context, DateTime *p){
- double r;
- sqlite3 *db = sqlite3_context_db_handle(context);
- sqlite3OsCurrentTime(db->pVfs, &r);
- p->iJD = (sqlite3_int64)(r*86400000.0 + 0.5);
- p->validJD = 1;
-}
-
-/*
-** Attempt to parse the given string into a Julian Day Number. Return
-** the number of errors.
-**
-** The following are acceptable forms for the input string:
-**
-** YYYY-MM-DD HH:MM:SS.FFF +/-HH:MM
-** DDDD.DD
-** now
-**
-** In the first form, the +/-HH:MM is always optional. The fractional
-** seconds extension (the ".FFF") is optional. The seconds portion
-** (":SS.FFF") is option. The year and date can be omitted as long
-** as there is a time string. The time string can be omitted as long
-** as there is a year and date.
-*/
-static int parseDateOrTime(
- sqlite3_context *context,
- const char *zDate,
- DateTime *p
-){
- int isRealNum; /* Return from sqlite3IsNumber(). Not used */
- if( parseYyyyMmDd(zDate,p)==0 ){
- return 0;
- }else if( parseHhMmSs(zDate, p)==0 ){
- return 0;
- }else if( sqlite3StrICmp(zDate,"now")==0){
- setDateTimeToCurrent(context, p);
- return 0;
- }else if( sqlite3IsNumber(zDate, &isRealNum, SQLITE_UTF8) ){
- double r;
- getValue(zDate, &r);
- p->iJD = (sqlite3_int64)(r*86400000.0 + 0.5);
- p->validJD = 1;
- return 0;
- }
- return 1;
-}
-
-/*
-** Compute the Year, Month, and Day from the julian day number.
-*/
-static void computeYMD(DateTime *p){
- int Z, A, B, C, D, E, X1;
- if( p->validYMD ) return;
- if( !p->validJD ){
- p->Y = 2000;
- p->M = 1;
- p->D = 1;
- }else{
- Z = (int)((p->iJD + 43200000)/86400000);
- A = (int)((Z - 1867216.25)/36524.25);
- A = Z + 1 + A - (A/4);
- B = A + 1524;
- C = (int)((B - 122.1)/365.25);
- D = (36525*C)/100;
- E = (int)((B-D)/30.6001);
- X1 = (int)(30.6001*E);
- p->D = B - D - X1;
- p->M = E<14 ? E-1 : E-13;
- p->Y = p->M>2 ? C - 4716 : C - 4715;
- }
- p->validYMD = 1;
-}
-
-/*
-** Compute the Hour, Minute, and Seconds from the julian day number.
-*/
-static void computeHMS(DateTime *p){
- int s;
- if( p->validHMS ) return;
- computeJD(p);
- s = (int)((p->iJD + 43200000) % 86400000);
- p->s = s/1000.0;
- s = (int)p->s;
- p->s -= s;
- p->h = s/3600;
- s -= p->h*3600;
- p->m = s/60;
- p->s += s - p->m*60;
- p->validHMS = 1;
-}
-
-/*
-** Compute both YMD and HMS
-*/
-static void computeYMD_HMS(DateTime *p){
- computeYMD(p);
- computeHMS(p);
-}
-
-/*
-** Clear the YMD and HMS and the TZ
-*/
-static void clearYMD_HMS_TZ(DateTime *p){
- p->validYMD = 0;
- p->validHMS = 0;
- p->validTZ = 0;
-}
-
-#ifndef SQLITE_OMIT_LOCALTIME
-/*
-** Compute the difference (in milliseconds)
-** between localtime and UTC (a.k.a. GMT)
-** for the time value p where p is in UTC.
-*/
-static sqlite3_int64 localtimeOffset(DateTime *p){
- DateTime x, y;
- time_t t;
- x = *p;
- computeYMD_HMS(&x);
- if( x.Y<1971 || x.Y>=2038 ){
- x.Y = 2000;
- x.M = 1;
- x.D = 1;
- x.h = 0;
- x.m = 0;
- x.s = 0.0;
- } else {
- int s = (int)(x.s + 0.5);
- x.s = s;
- }
- x.tz = 0;
- x.validJD = 0;
- computeJD(&x);
- t = (time_t)(x.iJD/1000 - 21086676*(i64)10000);
-#ifdef HAVE_LOCALTIME_R
- {
- struct tm sLocal;
- localtime_r(&t, &sLocal);
- y.Y = sLocal.tm_year + 1900;
- y.M = sLocal.tm_mon + 1;
- y.D = sLocal.tm_mday;
- y.h = sLocal.tm_hour;
- y.m = sLocal.tm_min;
- y.s = sLocal.tm_sec;
- }
-#elif defined(HAVE_LOCALTIME_S)
- {
- struct tm sLocal;
- localtime_s(&sLocal, &t);
- y.Y = sLocal.tm_year + 1900;
- y.M = sLocal.tm_mon + 1;
- y.D = sLocal.tm_mday;
- y.h = sLocal.tm_hour;
- y.m = sLocal.tm_min;
- y.s = sLocal.tm_sec;
- }
-#else
- {
- struct tm *pTm;
- sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
- pTm = localtime(&t);
- y.Y = pTm->tm_year + 1900;
- y.M = pTm->tm_mon + 1;
- y.D = pTm->tm_mday;
- y.h = pTm->tm_hour;
- y.m = pTm->tm_min;
- y.s = pTm->tm_sec;
- sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
- }
-#endif
- y.validYMD = 1;
- y.validHMS = 1;
- y.validJD = 0;
- y.validTZ = 0;
- computeJD(&y);
- return y.iJD - x.iJD;
-}
-#endif /* SQLITE_OMIT_LOCALTIME */
-
-/*
-** Process a modifier to a date-time stamp. The modifiers are
-** as follows:
-**
-** NNN days
-** NNN hours
-** NNN minutes
-** NNN.NNNN seconds
-** NNN months
-** NNN years
-** start of month
-** start of year
-** start of week
-** start of day
-** weekday N
-** unixepoch
-** localtime
-** utc
-**
-** Return 0 on success and 1 if there is any kind of error.
-*/
-static int parseModifier(const char *zMod, DateTime *p){
- int rc = 1;
- int n;
- double r;
- char *z, zBuf[30];
- z = zBuf;
- for(n=0; n<ArraySize(zBuf)-1 && zMod[n]; n++){
- z[n] = (char)sqlite3UpperToLower[(u8)zMod[n]];
- }
- z[n] = 0;
- switch( z[0] ){
-#ifndef SQLITE_OMIT_LOCALTIME
- case 'l': {
- /* localtime
- **
- ** Assuming the current time value is UTC (a.k.a. GMT), shift it to
- ** show local time.
- */
- if( strcmp(z, "localtime")==0 ){
- computeJD(p);
- p->iJD += localtimeOffset(p);
- clearYMD_HMS_TZ(p);
- rc = 0;
- }
- break;
- }
-#endif
- case 'u': {
- /*
- ** unixepoch
- **
- ** Treat the current value of p->iJD as the number of
- ** seconds since 1970. Convert to a real julian day number.
- */
- if( strcmp(z, "unixepoch")==0 && p->validJD ){
- p->iJD = (p->iJD + 43200)/86400 + 21086676*(i64)10000000;
- clearYMD_HMS_TZ(p);
- rc = 0;
- }
-#ifndef SQLITE_OMIT_LOCALTIME
- else if( strcmp(z, "utc")==0 ){
- sqlite3_int64 c1;
- computeJD(p);
- c1 = localtimeOffset(p);
- p->iJD -= c1;
- clearYMD_HMS_TZ(p);
- p->iJD += c1 - localtimeOffset(p);
- rc = 0;
- }
-#endif
- break;
- }
- case 'w': {
- /*
- ** weekday N
- **
- ** Move the date to the same time on the next occurrence of
- ** weekday N where 0==Sunday, 1==Monday, and so forth. If the
- ** date is already on the appropriate weekday, this is a no-op.
- */
- if( strncmp(z, "weekday ", 8)==0 && getValue(&z[8],&r)>0
- && (n=(int)r)==r && n>=0 && r<7 ){
- sqlite3_int64 Z;
- computeYMD_HMS(p);
- p->validTZ = 0;
- p->validJD = 0;
- computeJD(p);
- Z = ((p->iJD + 129600000)/86400000) % 7;
- if( Z>n ) Z -= 7;
- p->iJD += (n - Z)*86400000;
- clearYMD_HMS_TZ(p);
- rc = 0;
- }
- break;
- }
- case 's': {
- /*
- ** start of TTTTT
- **
- ** Move the date backwards to the beginning of the current day,
- ** or month or year.
- */
- if( strncmp(z, "start of ", 9)!=0 ) break;
- z += 9;
- computeYMD(p);
- p->validHMS = 1;
- p->h = p->m = 0;
- p->s = 0.0;
- p->validTZ = 0;
- p->validJD = 0;
- if( strcmp(z,"month")==0 ){
- p->D = 1;
- rc = 0;
- }else if( strcmp(z,"year")==0 ){
- computeYMD(p);
- p->M = 1;
- p->D = 1;
- rc = 0;
- }else if( strcmp(z,"day")==0 ){
- rc = 0;
- }
- break;
- }
- case '+':
- case '-':
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9': {
- double rRounder;
- n = getValue(z, &r);
- assert( n>=1 );
- if( z[n]==':' ){
- /* A modifier of the form (+|-)HH:MM:SS.FFF adds (or subtracts) the
- ** specified number of hours, minutes, seconds, and fractional seconds
- ** to the time. The ".FFF" may be omitted. The ":SS.FFF" may be
- ** omitted.
- */
- const char *z2 = z;
- DateTime tx;
- sqlite3_int64 day;
- if( !sqlite3Isdigit(*z2) ) z2++;
- memset(&tx, 0, sizeof(tx));
- if( parseHhMmSs(z2, &tx) ) break;
- computeJD(&tx);
- tx.iJD -= 43200000;
- day = tx.iJD/86400000;
- tx.iJD -= day*86400000;
- if( z[0]=='-' ) tx.iJD = -tx.iJD;
- computeJD(p);
- clearYMD_HMS_TZ(p);
- p->iJD += tx.iJD;
- rc = 0;
- break;
- }
- z += n;
- while( sqlite3Isspace(*z) ) z++;
- n = sqlite3Strlen30(z);
- if( n>10 || n<3 ) break;
- if( z[n-1]=='s' ){ z[n-1] = 0; n--; }
- computeJD(p);
- rc = 0;
- rRounder = r<0 ? -0.5 : +0.5;
- if( n==3 && strcmp(z,"day")==0 ){
- p->iJD += (sqlite3_int64)(r*86400000.0 + rRounder);
- }else if( n==4 && strcmp(z,"hour")==0 ){
- p->iJD += (sqlite3_int64)(r*(86400000.0/24.0) + rRounder);
- }else if( n==6 && strcmp(z,"minute")==0 ){
- p->iJD += (sqlite3_int64)(r*(86400000.0/(24.0*60.0)) + rRounder);
- }else if( n==6 && strcmp(z,"second")==0 ){
- p->iJD += (sqlite3_int64)(r*(86400000.0/(24.0*60.0*60.0)) + rRounder);
- }else if( n==5 && strcmp(z,"month")==0 ){
- int x, y;
- computeYMD_HMS(p);
- p->M += (int)r;
- x = p->M>0 ? (p->M-1)/12 : (p->M-12)/12;
- p->Y += x;
- p->M -= x*12;
- p->validJD = 0;
- computeJD(p);
- y = (int)r;
- if( y!=r ){
- p->iJD += (sqlite3_int64)((r - y)*30.0*86400000.0 + rRounder);
- }
- }else if( n==4 && strcmp(z,"year")==0 ){
- int y = (int)r;
- computeYMD_HMS(p);
- p->Y += y;
- p->validJD = 0;
- computeJD(p);
- if( y!=r ){
- p->iJD += (sqlite3_int64)((r - y)*365.0*86400000.0 + rRounder);
- }
- }else{
- rc = 1;
- }
- clearYMD_HMS_TZ(p);
- break;
- }
- default: {
- break;
- }
- }
- return rc;
-}
-
-/*
-** Process time function arguments. argv[0] is a date-time stamp.
-** argv[1] and following are modifiers. Parse them all and write
-** the resulting time into the DateTime structure p. Return 0
-** on success and 1 if there are any errors.
-**
-** If there are zero parameters (if even argv[0] is undefined)
-** then assume a default value of "now" for argv[0].
-*/
-static int isDate(
- sqlite3_context *context,
- int argc,
- sqlite3_value **argv,
- DateTime *p
-){
- int i;
- const unsigned char *z;
- int eType;
- memset(p, 0, sizeof(*p));
- if( argc==0 ){
- setDateTimeToCurrent(context, p);
- }else if( (eType = sqlite3_value_type(argv[0]))==SQLITE_FLOAT
- || eType==SQLITE_INTEGER ){
- p->iJD = (sqlite3_int64)(sqlite3_value_double(argv[0])*86400000.0 + 0.5);
- p->validJD = 1;
- }else{
- z = sqlite3_value_text(argv[0]);
- if( !z || parseDateOrTime(context, (char*)z, p) ){
- return 1;
- }
- }
- for(i=1; i<argc; i++){
- if( (z = sqlite3_value_text(argv[i]))==0 || parseModifier((char*)z, p) ){
- return 1;
- }
- }
- return 0;
-}
-
-
-/*
-** The following routines implement the various date and time functions
-** of SQLite.
-*/
-
-/*
-** julianday( TIMESTRING, MOD, MOD, ...)
-**
-** Return the julian day number of the date specified in the arguments
-*/
-static void juliandayFunc(
- sqlite3_context *context,
- int argc,
- sqlite3_value **argv
-){
- DateTime x;
- if( isDate(context, argc, argv, &x)==0 ){
- computeJD(&x);
- sqlite3_result_double(context, x.iJD/86400000.0);
- }
-}
-
-/*
-** datetime( TIMESTRING, MOD, MOD, ...)
-**
-** Return YYYY-MM-DD HH:MM:SS
-*/
-static void datetimeFunc(
- sqlite3_context *context,
- int argc,
- sqlite3_value **argv
-){
- DateTime x;
- if( isDate(context, argc, argv, &x)==0 ){
- char zBuf[100];
- computeYMD_HMS(&x);
- sqlite3_snprintf(sizeof(zBuf), zBuf, "%04d-%02d-%02d %02d:%02d:%02d",
- x.Y, x.M, x.D, x.h, x.m, (int)(x.s));
- sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
- }
-}
-
-/*
-** time( TIMESTRING, MOD, MOD, ...)
-**
-** Return HH:MM:SS
-*/
-static void timeFunc(
- sqlite3_context *context,
- int argc,
- sqlite3_value **argv
-){
- DateTime x;
- if( isDate(context, argc, argv, &x)==0 ){
- char zBuf[100];
- computeHMS(&x);
- sqlite3_snprintf(sizeof(zBuf), zBuf, "%02d:%02d:%02d", x.h, x.m, (int)x.s);
- sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
- }
-}
-
-/*
-** date( TIMESTRING, MOD, MOD, ...)
-**
-** Return YYYY-MM-DD
-*/
-static void dateFunc(
- sqlite3_context *context,
- int argc,
- sqlite3_value **argv
-){
- DateTime x;
- if( isDate(context, argc, argv, &x)==0 ){
- char zBuf[100];
- computeYMD(&x);
- sqlite3_snprintf(sizeof(zBuf), zBuf, "%04d-%02d-%02d", x.Y, x.M, x.D);
- sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
- }
-}
-
-/*
-** strftime( FORMAT, TIMESTRING, MOD, MOD, ...)
-**
-** Return a string described by FORMAT. Conversions as follows:
-**
-** %d day of month
-** %f ** fractional seconds SS.SSS
-** %H hour 00-24
-** %j day of year 000-366
-** %J ** Julian day number
-** %m month 01-12
-** %M minute 00-59
-** %s seconds since 1970-01-01
-** %S seconds 00-59
-** %w day of week 0-6 sunday==0
-** %W week of year 00-53
-** %Y year 0000-9999
-** %% %
-*/
-static void strftimeFunc(
- sqlite3_context *context,
- int argc,
- sqlite3_value **argv
-){
- DateTime x;
- u64 n;
- size_t i,j;
- char *z;
- sqlite3 *db;
- const char *zFmt = (const char*)sqlite3_value_text(argv[0]);
- char zBuf[100];
- if( zFmt==0 || isDate(context, argc-1, argv+1, &x) ) return;
- db = sqlite3_context_db_handle(context);
- for(i=0, n=1; zFmt[i]; i++, n++){
- if( zFmt[i]=='%' ){
- switch( zFmt[i+1] ){
- case 'd':
- case 'H':
- case 'm':
- case 'M':
- case 'S':
- case 'W':
- n++;
- /* fall thru */
- case 'w':
- case '%':
- break;
- case 'f':
- n += 8;
- break;
- case 'j':
- n += 3;
- break;
- case 'Y':
- n += 8;
- break;
- case 's':
- case 'J':
- n += 50;
- break;
- default:
- return; /* ERROR. return a NULL */
- }
- i++;
- }
- }
- testcase( n==sizeof(zBuf)-1 );
- testcase( n==sizeof(zBuf) );
- testcase( n==(u64)db->aLimit[SQLITE_LIMIT_LENGTH]+1 );
- testcase( n==(u64)db->aLimit[SQLITE_LIMIT_LENGTH] );
- if( n<sizeof(zBuf) ){
- z = zBuf;
- }else if( n>(u64)db->aLimit[SQLITE_LIMIT_LENGTH] ){
- sqlite3_result_error_toobig(context);
- return;
- }else{
- z = sqlite3DbMallocRaw(db, (int)n);
- if( z==0 ){
- sqlite3_result_error_nomem(context);
- return;
- }
- }
- computeJD(&x);
- computeYMD_HMS(&x);
- for(i=j=0; zFmt[i]; i++){
- if( zFmt[i]!='%' ){
- z[j++] = zFmt[i];
- }else{
- i++;
- switch( zFmt[i] ){
- case 'd': sqlite3_snprintf(3, &z[j],"%02d",x.D); j+=2; break;
- case 'f': {
- double s = x.s;
- if( s>59.999 ) s = 59.999;
- sqlite3_snprintf(7, &z[j],"%06.3f", s);
- j += sqlite3Strlen30(&z[j]);
- break;
- }
- case 'H': sqlite3_snprintf(3, &z[j],"%02d",x.h); j+=2; break;
- case 'W': /* Fall thru */
- case 'j': {
- int nDay; /* Number of days since 1st day of year */
- DateTime y = x;
- y.validJD = 0;
- y.M = 1;
- y.D = 1;
- computeJD(&y);
- nDay = (int)((x.iJD-y.iJD+43200000)/86400000);
- if( zFmt[i]=='W' ){
- int wd; /* 0=Monday, 1=Tuesday, ... 6=Sunday */
- wd = (int)(((x.iJD+43200000)/86400000)%7);
- sqlite3_snprintf(3, &z[j],"%02d",(nDay+7-wd)/7);
- j += 2;
- }else{
- sqlite3_snprintf(4, &z[j],"%03d",nDay+1);
- j += 3;
- }
- break;
- }
- case 'J': {
- sqlite3_snprintf(20, &z[j],"%.16g",x.iJD/86400000.0);
- j+=sqlite3Strlen30(&z[j]);
- break;
- }
- case 'm': sqlite3_snprintf(3, &z[j],"%02d",x.M); j+=2; break;
- case 'M': sqlite3_snprintf(3, &z[j],"%02d",x.m); j+=2; break;
- case 's': {
- sqlite3_snprintf(30,&z[j],"%lld",
- (i64)(x.iJD/1000 - 21086676*(i64)10000));
- j += sqlite3Strlen30(&z[j]);
- break;
- }
- case 'S': sqlite3_snprintf(3,&z[j],"%02d",(int)x.s); j+=2; break;
- case 'w': {
- z[j++] = (char)(((x.iJD+129600000)/86400000) % 7) + '0';
- break;
- }
- case 'Y': {
- sqlite3_snprintf(5,&z[j],"%04d",x.Y); j+=sqlite3Strlen30(&z[j]);
- break;
- }
- default: z[j++] = '%'; break;
- }
- }
- }
- z[j] = 0;
- sqlite3_result_text(context, z, -1,
- z==zBuf ? SQLITE_TRANSIENT : SQLITE_DYNAMIC);
-}
-
-/*
-** current_time()
-**
-** This function returns the same value as time('now').
-*/
-static void ctimeFunc(
- sqlite3_context *context,
- int NotUsed,
- sqlite3_value **NotUsed2
-){
- UNUSED_PARAMETER2(NotUsed, NotUsed2);
- timeFunc(context, 0, 0);
-}
-
-/*
-** current_date()
-**
-** This function returns the same value as date('now').
-*/
-static void cdateFunc(
- sqlite3_context *context,
- int NotUsed,
- sqlite3_value **NotUsed2
-){
- UNUSED_PARAMETER2(NotUsed, NotUsed2);
- dateFunc(context, 0, 0);
-}
-
-/*
-** current_timestamp()
-**
-** This function returns the same value as datetime('now').
-*/
-static void ctimestampFunc(
- sqlite3_context *context,
- int NotUsed,
- sqlite3_value **NotUsed2
-){
- UNUSED_PARAMETER2(NotUsed, NotUsed2);
- datetimeFunc(context, 0, 0);
-}
-#endif /* !defined(SQLITE_OMIT_DATETIME_FUNCS) */
-
-#ifdef SQLITE_OMIT_DATETIME_FUNCS
-/*
-** If the library is compiled to omit the full-scale date and time
-** handling (to get a smaller binary), the following minimal version
-** of the functions current_time(), current_date() and current_timestamp()
-** are included instead. This is to support column declarations that
-** include "DEFAULT CURRENT_TIME" etc.
-**
-** This function uses the C-library functions time(), gmtime()
-** and strftime(). The format string to pass to strftime() is supplied
-** as the user-data for the function.
-*/
-static void currentTimeFunc(
- sqlite3_context *context,
- int argc,
- sqlite3_value **argv
-){
- time_t t;
- char *zFormat = (char *)sqlite3_user_data(context);
- sqlite3 *db;
- double rT;
- char zBuf[20];
-
- UNUSED_PARAMETER(argc);
- UNUSED_PARAMETER(argv);
-
- db = sqlite3_context_db_handle(context);
- sqlite3OsCurrentTime(db->pVfs, &rT);
-#ifndef SQLITE_OMIT_FLOATING_POINT
- t = 86400.0*(rT - 2440587.5) + 0.5;
-#else
- /* without floating point support, rT will have
- ** already lost fractional day precision.
- */
- t = 86400 * (rT - 2440587) - 43200;
-#endif
-#ifdef HAVE_GMTIME_R
- {
- struct tm sNow;
- gmtime_r(&t, &sNow);
- strftime(zBuf, 20, zFormat, &sNow);
- }
-#else
- {
- struct tm *pTm;
- sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
- pTm = gmtime(&t);
- strftime(zBuf, 20, zFormat, pTm);
- sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
- }
-#endif
-
- sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
-}
-#endif
-
-/*
-** This function registered all of the above C functions as SQL
-** functions. This should be the only routine in this file with
-** external linkage.
-*/
-SQLITE_PRIVATE void sqlite3RegisterDateTimeFunctions(void){
- static SQLITE_WSD FuncDef aDateTimeFuncs[] = {
-#ifndef SQLITE_OMIT_DATETIME_FUNCS
- FUNCTION(julianday, -1, 0, 0, juliandayFunc ),
- FUNCTION(date, -1, 0, 0, dateFunc ),
- FUNCTION(time, -1, 0, 0, timeFunc ),
- FUNCTION(datetime, -1, 0, 0, datetimeFunc ),
- FUNCTION(strftime, -1, 0, 0, strftimeFunc ),
- FUNCTION(current_time, 0, 0, 0, ctimeFunc ),
- FUNCTION(current_timestamp, 0, 0, 0, ctimestampFunc),
- FUNCTION(current_date, 0, 0, 0, cdateFunc ),
-#else
- STR_FUNCTION(current_time, 0, "%H:%M:%S", 0, currentTimeFunc),
- STR_FUNCTION(current_timestamp, 0, "%Y-%m-%d", 0, currentTimeFunc),
- STR_FUNCTION(current_date, 0, "%Y-%m-%d %H:%M:%S", 0, currentTimeFunc),
-#endif
- };
- int i;
- FuncDefHash *pHash = &GLOBAL(FuncDefHash, sqlite3GlobalFunctions);
- FuncDef *aFunc = (FuncDef*)&GLOBAL(FuncDef, aDateTimeFuncs);
-
- for(i=0; i<ArraySize(aDateTimeFuncs); i++){
- sqlite3FuncDefInsert(pHash, &aFunc[i]);
- }
-}
-
-/************** End of date.c ************************************************/
-/************** Begin file os.c **********************************************/
-/*
-** 2005 November 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.
-**
-******************************************************************************
-**
-** This file contains OS interface code that is common to all
-** architectures.
-**
-** $Id: os.c,v 1.127 2009/07/27 11:41:21 danielk1977 Exp $
-*/
-#define _SQLITE_OS_C_ 1
-#undef _SQLITE_OS_C_
-
-/*
-** The default SQLite sqlite3_vfs implementations do not allocate
-** memory (actually, os_unix.c allocates a small amount of memory
-** from within OsOpen()), but some third-party implementations may.
-** So we test the effects of a malloc() failing and the sqlite3OsXXX()
-** function returning SQLITE_IOERR_NOMEM using the DO_OS_MALLOC_TEST macro.
-**
-** The following functions are instrumented for malloc() failure
-** testing:
-**
-** sqlite3OsOpen()
-** sqlite3OsRead()
-** sqlite3OsWrite()
-** sqlite3OsSync()
-** sqlite3OsLock()
-**
-*/
-#if defined(SQLITE_TEST) && (SQLITE_OS_WIN==0)
- #define DO_OS_MALLOC_TEST(x) if (!x || !sqlite3IsMemJournal(x)) { \
- void *pTstAlloc = sqlite3Malloc(10); \
- if (!pTstAlloc) return SQLITE_IOERR_NOMEM; \
- sqlite3_free(pTstAlloc); \
- }
-#else
- #define DO_OS_MALLOC_TEST(x)
-#endif
-
-/*
-** The following routines are convenience wrappers around methods
-** of the sqlite3_file object. This is mostly just syntactic sugar. All
-** of this would be completely automatic if SQLite were coded using
-** C++ instead of plain old C.
-*/
-SQLITE_PRIVATE int sqlite3OsClose(sqlite3_file *pId){
- int rc = SQLITE_OK;
- if( pId->pMethods ){
- rc = pId->pMethods->xClose(pId);
- pId->pMethods = 0;
- }
- return rc;
-}
-SQLITE_PRIVATE int sqlite3OsRead(sqlite3_file *id, void *pBuf, int amt, i64 offset){
- DO_OS_MALLOC_TEST(id);
- return id->pMethods->xRead(id, pBuf, amt, offset);
-}
-SQLITE_PRIVATE int sqlite3OsWrite(sqlite3_file *id, const void *pBuf, int amt, i64 offset){
- DO_OS_MALLOC_TEST(id);
- return id->pMethods->xWrite(id, pBuf, amt, offset);
-}
-SQLITE_PRIVATE int sqlite3OsTruncate(sqlite3_file *id, i64 size){
- return id->pMethods->xTruncate(id, size);
-}
-SQLITE_PRIVATE int sqlite3OsSync(sqlite3_file *id, int flags){
- DO_OS_MALLOC_TEST(id);
- return id->pMethods->xSync(id, flags);
-}
-SQLITE_PRIVATE int sqlite3OsFileSize(sqlite3_file *id, i64 *pSize){
- DO_OS_MALLOC_TEST(id);
- return id->pMethods->xFileSize(id, pSize);
-}
-SQLITE_PRIVATE int sqlite3OsLock(sqlite3_file *id, int lockType){
- DO_OS_MALLOC_TEST(id);
- return id->pMethods->xLock(id, lockType);
-}
-SQLITE_PRIVATE int sqlite3OsUnlock(sqlite3_file *id, int lockType){
- return id->pMethods->xUnlock(id, lockType);
-}
-SQLITE_PRIVATE int sqlite3OsCheckReservedLock(sqlite3_file *id, int *pResOut){
- DO_OS_MALLOC_TEST(id);
- return id->pMethods->xCheckReservedLock(id, pResOut);
-}
-SQLITE_PRIVATE int sqlite3OsFileControl(sqlite3_file *id, int op, void *pArg){
- return id->pMethods->xFileControl(id, op, pArg);
-}
-SQLITE_PRIVATE int sqlite3OsSectorSize(sqlite3_file *id){
- int (*xSectorSize)(sqlite3_file*) = id->pMethods->xSectorSize;
- return (xSectorSize ? xSectorSize(id) : SQLITE_DEFAULT_SECTOR_SIZE);
-}
-SQLITE_PRIVATE int sqlite3OsDeviceCharacteristics(sqlite3_file *id){
- return id->pMethods->xDeviceCharacteristics(id);
-}
-
-/*
-** The next group of routines are convenience wrappers around the
-** VFS methods.
-*/
-SQLITE_PRIVATE int sqlite3OsOpen(
- sqlite3_vfs *pVfs,
- const char *zPath,
- sqlite3_file *pFile,
- int flags,
- int *pFlagsOut
-){
- int rc;
- DO_OS_MALLOC_TEST(0);
- /* 0x7f1f 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. */
- rc = pVfs->xOpen(pVfs, zPath, pFile, flags & 0x7f1f, pFlagsOut);
- assert( rc==SQLITE_OK || pFile->pMethods==0 );
- return rc;
-}
-SQLITE_PRIVATE int sqlite3OsDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
- return pVfs->xDelete(pVfs, zPath, dirSync);
-}
-SQLITE_PRIVATE int sqlite3OsAccess(
- sqlite3_vfs *pVfs,
- const char *zPath,
- int flags,
- int *pResOut
-){
- DO_OS_MALLOC_TEST(0);
- return pVfs->xAccess(pVfs, zPath, flags, pResOut);
-}
-SQLITE_PRIVATE int sqlite3OsFullPathname(
- sqlite3_vfs *pVfs,
- const char *zPath,
- int nPathOut,
- char *zPathOut
-){
- return pVfs->xFullPathname(pVfs, zPath, nPathOut, zPathOut);
-}
-#ifndef SQLITE_OMIT_LOAD_EXTENSION
-SQLITE_PRIVATE void *sqlite3OsDlOpen(sqlite3_vfs *pVfs, const char *zPath){
- return pVfs->xDlOpen(pVfs, zPath);
-}
-SQLITE_PRIVATE void sqlite3OsDlError(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
- pVfs->xDlError(pVfs, nByte, zBufOut);
-}
-SQLITE_PRIVATE void (*sqlite3OsDlSym(sqlite3_vfs *pVfs, void *pHdle, const char *zSym))(void){
- return pVfs->xDlSym(pVfs, pHdle, zSym);
-}
-SQLITE_PRIVATE void sqlite3OsDlClose(sqlite3_vfs *pVfs, void *pHandle){
- pVfs->xDlClose(pVfs, pHandle);
-}
-#endif /* SQLITE_OMIT_LOAD_EXTENSION */
-SQLITE_PRIVATE int sqlite3OsRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
- return pVfs->xRandomness(pVfs, nByte, zBufOut);
-}
-SQLITE_PRIVATE int sqlite3OsSleep(sqlite3_vfs *pVfs, int nMicro){
- return pVfs->xSleep(pVfs, nMicro);
-}
-SQLITE_PRIVATE int sqlite3OsCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){
- return pVfs->xCurrentTime(pVfs, pTimeOut);
-}
-
-SQLITE_PRIVATE int sqlite3OsOpenMalloc(
- sqlite3_vfs *pVfs,
- const char *zFile,
- sqlite3_file **ppFile,
- int flags,
- int *pOutFlags
-){
- int rc = SQLITE_NOMEM;
- sqlite3_file *pFile;
- pFile = (sqlite3_file *)sqlite3Malloc(pVfs->szOsFile);
- if( pFile ){
- rc = sqlite3OsOpen(pVfs, zFile, pFile, flags, pOutFlags);
- if( rc!=SQLITE_OK ){
- sqlite3_free(pFile);
- }else{
- *ppFile = pFile;
- }
- }
- return rc;
-}
-SQLITE_PRIVATE int sqlite3OsCloseFree(sqlite3_file *pFile){
- int rc = SQLITE_OK;
- assert( pFile );
- rc = sqlite3OsClose(pFile);
- sqlite3_free(pFile);
- return rc;
-}
-
-/*
-** This function is a wrapper around the OS specific implementation of
-** sqlite3_os_init(). The purpose of the wrapper is to provide the
-** ability to simulate a malloc failure, so that the handling of an
-** error in sqlite3_os_init() by the upper layers can be tested.
-*/
-SQLITE_PRIVATE int sqlite3OsInit(void){
- void *p = sqlite3_malloc(10);
- if( p==0 ) return SQLITE_NOMEM;
- sqlite3_free(p);
- return sqlite3_os_init();
-}
-
-/*
-** The list of all registered VFS implementations.
-*/
-static sqlite3_vfs * SQLITE_WSD vfsList = 0;
-#define vfsList GLOBAL(sqlite3_vfs *, vfsList)
-
-/*
-** Locate a VFS by name. If no name is given, simply return the
-** first VFS on the list.
-*/
-SQLITE_API sqlite3_vfs *sqlite3_vfs_find(const char *zVfs){
- sqlite3_vfs *pVfs = 0;
-#if SQLITE_THREADSAFE
- sqlite3_mutex *mutex;
-#endif
-#ifndef SQLITE_OMIT_AUTOINIT
- int rc = sqlite3_initialize();
- if( rc ) return 0;
-#endif
-#if SQLITE_THREADSAFE
- mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
-#endif
- sqlite3_mutex_enter(mutex);
- for(pVfs = vfsList; pVfs; pVfs=pVfs->pNext){
- if( zVfs==0 ) break;
- if( strcmp(zVfs, pVfs->zName)==0 ) break;
- }
- sqlite3_mutex_leave(mutex);
- return pVfs;
-}
-
-/*
-** Unlink a VFS from the linked list
-*/
-static void vfsUnlink(sqlite3_vfs *pVfs){
- assert( sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)) );
- if( pVfs==0 ){
- /* No-op */
- }else if( vfsList==pVfs ){
- vfsList = pVfs->pNext;
- }else if( vfsList ){
- sqlite3_vfs *p = vfsList;
- while( p->pNext && p->pNext!=pVfs ){
- p = p->pNext;
- }
- if( p->pNext==pVfs ){
- p->pNext = pVfs->pNext;
- }
- }
-}
-
-/*
-** Register a VFS with the system. It is harmless to register the same
-** VFS multiple times. The new VFS becomes the default if makeDflt is
-** true.
-*/
-SQLITE_API int sqlite3_vfs_register(sqlite3_vfs *pVfs, int makeDflt){
- sqlite3_mutex *mutex = 0;
-#ifndef SQLITE_OMIT_AUTOINIT
- int rc = sqlite3_initialize();
- if( rc ) return rc;
-#endif
- mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
- sqlite3_mutex_enter(mutex);
- vfsUnlink(pVfs);
- if( makeDflt || vfsList==0 ){
- pVfs->pNext = vfsList;
- vfsList = pVfs;
- }else{
- pVfs->pNext = vfsList->pNext;
- vfsList->pNext = pVfs;
- }
- assert(vfsList);
- sqlite3_mutex_leave(mutex);
- return SQLITE_OK;
-}
-
-/*
-** Unregister a VFS so that it is no longer accessible.
-*/
-SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs *pVfs){
-#if SQLITE_THREADSAFE
- sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
-#endif
- sqlite3_mutex_enter(mutex);
- vfsUnlink(pVfs);
- sqlite3_mutex_leave(mutex);
- return SQLITE_OK;
-}
-
-/************** End of os.c **************************************************/
-/************** Begin file fault.c *******************************************/
-/*
-** 2008 Jan 22
-**
-** 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.
-**
-*************************************************************************
-**
-** $Id: fault.c,v 1.11 2008/09/02 00:52:52 drh Exp $
-*/
-
-/*
-** This file contains code to support the concept of "benign"
-** malloc failures (when the xMalloc() or xRealloc() method of the
-** sqlite3_mem_methods structure fails to allocate a block of memory
-** and returns 0).
-**
-** Most malloc failures are non-benign. After they occur, SQLite
-** abandons the current operation and returns an error code (usually
-** SQLITE_NOMEM) to the user. However, sometimes a fault is not necessarily
-** fatal. For example, if a malloc fails while resizing a hash table, this
-** is completely recoverable simply by not carrying out the resize. The
-** hash table will continue to function normally. So a malloc failure
-** during a hash table resize is a benign fault.
-*/
-
-
-#ifndef SQLITE_OMIT_BUILTIN_TEST
-
-/*
-** Global variables.
-*/
-typedef struct BenignMallocHooks BenignMallocHooks;
-static SQLITE_WSD struct BenignMallocHooks {
- void (*xBenignBegin)(void);
- void (*xBenignEnd)(void);
-} sqlite3Hooks = { 0, 0 };
-
-/* The "wsdHooks" macro will resolve to the appropriate BenignMallocHooks
-** structure. If writable static data is unsupported on the target,
-** we have to locate the state vector at run-time. In the more common
-** case where writable static data is supported, wsdHooks can refer directly
-** to the "sqlite3Hooks" state vector declared above.
-*/
-#ifdef SQLITE_OMIT_WSD
-# define wsdHooksInit \
- BenignMallocHooks *x = &GLOBAL(BenignMallocHooks,sqlite3Hooks)
-# define wsdHooks x[0]
-#else
-# define wsdHooksInit
-# define wsdHooks sqlite3Hooks
-#endif
-
-
-/*
-** Register hooks to call when sqlite3BeginBenignMalloc() and
-** sqlite3EndBenignMalloc() are called, respectively.
-*/
-SQLITE_PRIVATE void sqlite3BenignMallocHooks(
- void (*xBenignBegin)(void),
- void (*xBenignEnd)(void)
-){
- wsdHooksInit;
- wsdHooks.xBenignBegin = xBenignBegin;
- wsdHooks.xBenignEnd = xBenignEnd;
-}
-
-/*
-** This (sqlite3EndBenignMalloc()) is called by SQLite code to indicate that
-** subsequent malloc failures are benign. A call to sqlite3EndBenignMalloc()
-** indicates that subsequent malloc failures are non-benign.
-*/
-SQLITE_PRIVATE void sqlite3BeginBenignMalloc(void){
- wsdHooksInit;
- if( wsdHooks.xBenignBegin ){
- wsdHooks.xBenignBegin();
- }
-}
-SQLITE_PRIVATE void sqlite3EndBenignMalloc(void){
- wsdHooksInit;
- if( wsdHooks.xBenignEnd ){
- wsdHooks.xBenignEnd();
- }
-}
-
-#endif /* #ifndef SQLITE_OMIT_BUILTIN_TEST */
-
-/************** End of fault.c ***********************************************/
-/************** Begin file mem0.c ********************************************/
-/*
-** 2008 October 28
-**
-** 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 a no-op memory allocation drivers for use when
-** SQLITE_ZERO_MALLOC is defined. The allocation drivers implemented
-** here always fail. SQLite will not operate with these drivers. These
-** are merely placeholders. Real drivers must be substituted using
-** sqlite3_config() before SQLite will operate.
-**
-** $Id: mem0.c,v 1.1 2008/10/28 18:58:20 drh Exp $
-*/
-
-/*
-** This version of the memory allocator is the default. It is
-** used when no other memory allocator is specified using compile-time
-** macros.
-*/
-#ifdef SQLITE_ZERO_MALLOC
-
-/*
-** No-op versions of all memory allocation routines
-*/
-static void *sqlite3MemMalloc(int nByte){ return 0; }
-static void sqlite3MemFree(void *pPrior){ return; }
-static void *sqlite3MemRealloc(void *pPrior, int nByte){ return 0; }
-static int sqlite3MemSize(void *pPrior){ return 0; }
-static int sqlite3MemRoundup(int n){ return n; }
-static int sqlite3MemInit(void *NotUsed){ return SQLITE_OK; }
-static void sqlite3MemShutdown(void *NotUsed){ return; }
-
-/*
-** This routine is the only routine in this file with external linkage.
-**
-** Populate the low-level memory allocation function pointers in
-** sqlite3GlobalConfig.m with pointers to the routines in this file.
-*/
-SQLITE_PRIVATE void sqlite3MemSetDefault(void){
- static const sqlite3_mem_methods defaultMethods = {
- sqlite3MemMalloc,
- sqlite3MemFree,
- sqlite3MemRealloc,
- sqlite3MemSize,
- sqlite3MemRoundup,
- sqlite3MemInit,
- sqlite3MemShutdown,
- 0
- };
- sqlite3_config(SQLITE_CONFIG_MALLOC, &defaultMethods);
-}
-
-#endif /* SQLITE_ZERO_MALLOC */
-
-/************** End of mem0.c ************************************************/
-/************** Begin file mem1.c ********************************************/
-/*
-** 2007 August 14
-**
-** 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 low-level memory allocation drivers for when
-** SQLite will use the standard C-library malloc/realloc/free interface
-** to obtain the memory it needs.
-**
-** This file contains implementations of the low-level memory allocation
-** routines specified in the sqlite3_mem_methods object.
-**
-** $Id: mem1.c,v 1.30 2009/03/23 04:33:33 danielk1977 Exp $
-*/
-
-/*
-** This version of the memory allocator is the default. It is
-** used when no other memory allocator is specified using compile-time
-** macros.
-*/
-#ifdef SQLITE_SYSTEM_MALLOC
-
-/*
-** Like malloc(), but remember the size of the allocation
-** so that we can find it later using sqlite3MemSize().
-**
-** For this low-level routine, we are guaranteed that nByte>0 because
-** cases of nByte<=0 will be intercepted and dealt with by higher level
-** routines.
-*/
-static void *sqlite3MemMalloc(int nByte){
- sqlite3_int64 *p;
- assert( nByte>0 );
- nByte = ROUND8(nByte);
- p = malloc( nByte+8 );
- if( p ){
- p[0] = nByte;
- p++;
- }
- return (void *)p;
-}
-
-/*
-** Like free() but works for allocations obtained from sqlite3MemMalloc()
-** or sqlite3MemRealloc().
-**
-** For this low-level routine, we already know that pPrior!=0 since
-** cases where pPrior==0 will have been intecepted and dealt with
-** by higher-level routines.
-*/
-static void sqlite3MemFree(void *pPrior){
- sqlite3_int64 *p = (sqlite3_int64*)pPrior;
- assert( pPrior!=0 );
- p--;
- free(p);
-}
-
-/*
-** Like realloc(). Resize an allocation previously obtained from
-** sqlite3MemMalloc().
-**
-** For this low-level interface, we know that pPrior!=0. Cases where
-** pPrior==0 while have been intercepted by higher-level routine and
-** redirected to xMalloc. Similarly, we know that nByte>0 becauses
-** cases where nByte<=0 will have been intercepted by higher-level
-** routines and redirected to xFree.
-*/
-static void *sqlite3MemRealloc(void *pPrior, int nByte){
- sqlite3_int64 *p = (sqlite3_int64*)pPrior;
- assert( pPrior!=0 && nByte>0 );
- nByte = ROUND8(nByte);
- p = (sqlite3_int64*)pPrior;
- p--;
- p = realloc(p, nByte+8 );
- if( p ){
- p[0] = nByte;
- p++;
- }
- return (void*)p;
-}
-
-/*
-** Report the allocated size of a prior return from xMalloc()
-** or xRealloc().
-*/
-static int sqlite3MemSize(void *pPrior){
- sqlite3_int64 *p;
- if( pPrior==0 ) return 0;
- p = (sqlite3_int64*)pPrior;
- p--;
- return (int)p[0];
-}
-
-/*
-** Round up a request size to the next valid allocation size.
-*/
-static int sqlite3MemRoundup(int n){
- return ROUND8(n);
-}
-
-/*
-** Initialize this module.
-*/
-static int sqlite3MemInit(void *NotUsed){
- UNUSED_PARAMETER(NotUsed);
- return SQLITE_OK;
-}
-
-/*
-** Deinitialize this module.
-*/
-static void sqlite3MemShutdown(void *NotUsed){
- UNUSED_PARAMETER(NotUsed);
- return;
-}
-
-/*
-** This routine is the only routine in this file with external linkage.
-**
-** Populate the low-level memory allocation function pointers in
-** sqlite3GlobalConfig.m with pointers to the routines in this file.
-*/
-SQLITE_PRIVATE void sqlite3MemSetDefault(void){
- static const sqlite3_mem_methods defaultMethods = {
- sqlite3MemMalloc,
- sqlite3MemFree,
- sqlite3MemRealloc,
- sqlite3MemSize,
- sqlite3MemRoundup,
- sqlite3MemInit,
- sqlite3MemShutdown,
- 0
- };
- sqlite3_config(SQLITE_CONFIG_MALLOC, &defaultMethods);
-}
-
-#endif /* SQLITE_SYSTEM_MALLOC */
-
-/************** End of mem1.c ************************************************/
-/************** Begin file mem2.c ********************************************/
-/*
-** 2007 August 15
-**
-** 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 low-level memory allocation drivers for when
-** SQLite will use the standard C-library malloc/realloc/free interface
-** to obtain the memory it needs while adding lots of additional debugging
-** information to each allocation in order to help detect and fix memory
-** leaks and memory usage errors.
-**
-** This file contains implementations of the low-level memory allocation
-** routines specified in the sqlite3_mem_methods object.
-**
-** $Id: mem2.c,v 1.45 2009/03/23 04:33:33 danielk1977 Exp $
-*/
-
-/*
-** This version of the memory allocator is used only if the
-** SQLITE_MEMDEBUG macro is defined
-*/
-#ifdef SQLITE_MEMDEBUG
-
-/*
-** The backtrace functionality is only available with GLIBC
-*/
-#ifdef __GLIBC__
- extern int backtrace(void**,int);
- extern void backtrace_symbols_fd(void*const*,int,int);
-#else
-# define backtrace(A,B) 1
-# define backtrace_symbols_fd(A,B,C)
-#endif
-
-/*
-** Each memory allocation looks like this:
-**
-** ------------------------------------------------------------------------
-** | Title | backtrace pointers | MemBlockHdr | allocation | EndGuard |
-** ------------------------------------------------------------------------
-**
-** The application code sees only a pointer to the allocation. We have
-** to back up from the allocation pointer to find the MemBlockHdr. The
-** MemBlockHdr tells us the size of the allocation and the number of
-** backtrace pointers. There is also a guard word at the end of the
-** MemBlockHdr.
-*/
-struct MemBlockHdr {
- i64 iSize; /* Size of this allocation */
- struct MemBlockHdr *pNext, *pPrev; /* Linked list of all unfreed memory */
- char nBacktrace; /* Number of backtraces on this alloc */
- char nBacktraceSlots; /* Available backtrace slots */
- short nTitle; /* Bytes of title; includes '\0' */
- int iForeGuard; /* Guard word for sanity */
-};
-
-/*
-** Guard words
-*/
-#define FOREGUARD 0x80F5E153
-#define REARGUARD 0xE4676B53
-
-/*
-** Number of malloc size increments to track.
-*/
-#define NCSIZE 1000
-
-/*
-** All of the static variables used by this module are collected
-** into a single structure named "mem". This is to keep the
-** static variables organized and to reduce namespace pollution
-** when this module is combined with other in the amalgamation.
-*/
-static struct {
-
- /*
- ** Mutex to control access to the memory allocation subsystem.
- */
- sqlite3_mutex *mutex;
-
- /*
- ** Head and tail of a linked list of all outstanding allocations
- */
- struct MemBlockHdr *pFirst;
- struct MemBlockHdr *pLast;
-
- /*
- ** The number of levels of backtrace to save in new allocations.
- */
- int nBacktrace;
- void (*xBacktrace)(int, int, void **);
-
- /*
- ** Title text to insert in front of each block
- */
- int nTitle; /* Bytes of zTitle to save. Includes '\0' and padding */
- char zTitle[100]; /* The title text */
-
- /*
- ** sqlite3MallocDisallow() increments the following counter.
- ** sqlite3MallocAllow() decrements it.
- */
- int disallow; /* Do not allow memory allocation */
-
- /*
- ** Gather statistics on the sizes of memory allocations.
- ** nAlloc[i] is the number of allocation attempts of i*8
- ** bytes. i==NCSIZE is the number of allocation attempts for
- ** sizes more than NCSIZE*8 bytes.
- */
- int nAlloc[NCSIZE]; /* Total number of allocations */
- int nCurrent[NCSIZE]; /* Current number of allocations */
- int mxCurrent[NCSIZE]; /* Highwater mark for nCurrent */
-
-} mem;
-
-
-/*
-** Adjust memory usage statistics
-*/
-static void adjustStats(int iSize, int increment){
- int i = ROUND8(iSize)/8;
- if( i>NCSIZE-1 ){
- i = NCSIZE - 1;
- }
- if( increment>0 ){
- mem.nAlloc[i]++;
- mem.nCurrent[i]++;
- if( mem.nCurrent[i]>mem.mxCurrent[i] ){
- mem.mxCurrent[i] = mem.nCurrent[i];
- }
- }else{
- mem.nCurrent[i]--;
- assert( mem.nCurrent[i]>=0 );
- }
-}
-
-/*
-** Given an allocation, find the MemBlockHdr for that allocation.
-**
-** This routine checks the guards at either end of the allocation and
-** if they are incorrect it asserts.
-*/
-static struct MemBlockHdr *sqlite3MemsysGetHeader(void *pAllocation){
- struct MemBlockHdr *p;
- int *pInt;
- u8 *pU8;
- int nReserve;
-
- p = (struct MemBlockHdr*)pAllocation;
- p--;
- assert( p->iForeGuard==(int)FOREGUARD );
- nReserve = ROUND8(p->iSize);
- pInt = (int*)pAllocation;
- pU8 = (u8*)pAllocation;
- assert( pInt[nReserve/sizeof(int)]==(int)REARGUARD );
- /* This checks any of the "extra" bytes allocated due
- ** to rounding up to an 8 byte boundary to ensure
- ** they haven't been overwritten.
- */
- while( nReserve-- > p->iSize ) assert( pU8[nReserve]==0x65 );
- return p;
-}
-
-/*
-** Return the number of bytes currently allocated at address p.
-*/
-static int sqlite3MemSize(void *p){
- struct MemBlockHdr *pHdr;
- if( !p ){
- return 0;
- }
- pHdr = sqlite3MemsysGetHeader(p);
- return pHdr->iSize;
-}
-
-/*
-** Initialize the memory allocation subsystem.
-*/
-static int sqlite3MemInit(void *NotUsed){
- UNUSED_PARAMETER(NotUsed);
- assert( (sizeof(struct MemBlockHdr)&7) == 0 );
- if( !sqlite3GlobalConfig.bMemstat ){
- /* If memory status is enabled, then the malloc.c wrapper will already
- ** hold the STATIC_MEM mutex when the routines here are invoked. */
- mem.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM);
- }
- return SQLITE_OK;
-}
-
-/*
-** Deinitialize the memory allocation subsystem.
-*/
-static void sqlite3MemShutdown(void *NotUsed){
- UNUSED_PARAMETER(NotUsed);
- mem.mutex = 0;
-}
-
-/*
-** Round up a request size to the next valid allocation size.
-*/
-static int sqlite3MemRoundup(int n){
- return ROUND8(n);
-}
-
-/*
-** Allocate nByte bytes of memory.
-*/
-static void *sqlite3MemMalloc(int nByte){
- struct MemBlockHdr *pHdr;
- void **pBt;
- char *z;
- int *pInt;
- void *p = 0;
- int totalSize;
- int nReserve;
- sqlite3_mutex_enter(mem.mutex);
- assert( mem.disallow==0 );
- nReserve = ROUND8(nByte);
- totalSize = nReserve + sizeof(*pHdr) + sizeof(int) +
- mem.nBacktrace*sizeof(void*) + mem.nTitle;
- p = malloc(totalSize);
- if( p ){
- z = p;
- pBt = (void**)&z[mem.nTitle];
- pHdr = (struct MemBlockHdr*)&pBt[mem.nBacktrace];
- pHdr->pNext = 0;
- pHdr->pPrev = mem.pLast;
- if( mem.pLast ){
- mem.pLast->pNext = pHdr;
- }else{
- mem.pFirst = pHdr;
- }
- mem.pLast = pHdr;
- pHdr->iForeGuard = FOREGUARD;
- pHdr->nBacktraceSlots = mem.nBacktrace;
- pHdr->nTitle = mem.nTitle;
- if( mem.nBacktrace ){
- void *aAddr[40];
- pHdr->nBacktrace = backtrace(aAddr, mem.nBacktrace+1)-1;
- memcpy(pBt, &aAddr[1], pHdr->nBacktrace*sizeof(void*));
- assert(pBt[0]);
- if( mem.xBacktrace ){
- mem.xBacktrace(nByte, pHdr->nBacktrace-1, &aAddr[1]);
- }
- }else{
- pHdr->nBacktrace = 0;
- }
- if( mem.nTitle ){
- memcpy(z, mem.zTitle, mem.nTitle);
- }
- pHdr->iSize = nByte;
- adjustStats(nByte, +1);
- pInt = (int*)&pHdr[1];
- pInt[nReserve/sizeof(int)] = REARGUARD;
- memset(pInt, 0x65, nReserve);
- p = (void*)pInt;
- }
- sqlite3_mutex_leave(mem.mutex);
- return p;
-}
-
-/*
-** Free memory.
-*/
-static void sqlite3MemFree(void *pPrior){
- struct MemBlockHdr *pHdr;
- void **pBt;
- char *z;
- assert( sqlite3GlobalConfig.bMemstat || mem.mutex!=0 );
- pHdr = sqlite3MemsysGetHeader(pPrior);
- pBt = (void**)pHdr;
- pBt -= pHdr->nBacktraceSlots;
- sqlite3_mutex_enter(mem.mutex);
- if( pHdr->pPrev ){
- assert( pHdr->pPrev->pNext==pHdr );
- pHdr->pPrev->pNext = pHdr->pNext;
- }else{
- assert( mem.pFirst==pHdr );
- mem.pFirst = pHdr->pNext;
- }
- if( pHdr->pNext ){
- assert( pHdr->pNext->pPrev==pHdr );
- pHdr->pNext->pPrev = pHdr->pPrev;
- }else{
- assert( mem.pLast==pHdr );
- mem.pLast = pHdr->pPrev;
- }
- z = (char*)pBt;
- z -= pHdr->nTitle;
- adjustStats(pHdr->iSize, -1);
- memset(z, 0x2b, sizeof(void*)*pHdr->nBacktraceSlots + sizeof(*pHdr) +
- pHdr->iSize + sizeof(int) + pHdr->nTitle);
- free(z);
- sqlite3_mutex_leave(mem.mutex);
-}
-
-/*
-** Change the size of an existing memory allocation.
-**
-** For this debugging implementation, we *always* make a copy of the
-** allocation into a new place in memory. In this way, if the
-** higher level code is using pointer to the old allocation, it is
-** much more likely to break and we are much more liking to find
-** the error.
-*/
-static void *sqlite3MemRealloc(void *pPrior, int nByte){
- struct MemBlockHdr *pOldHdr;
- void *pNew;
- assert( mem.disallow==0 );
- pOldHdr = sqlite3MemsysGetHeader(pPrior);
- pNew = sqlite3MemMalloc(nByte);
- if( pNew ){
- memcpy(pNew, pPrior, nByte<pOldHdr->iSize ? nByte : pOldHdr->iSize);
- if( nByte>pOldHdr->iSize ){
- memset(&((char*)pNew)[pOldHdr->iSize], 0x2b, nByte - pOldHdr->iSize);
- }
- sqlite3MemFree(pPrior);
- }
- return pNew;
-}
-
-/*
-** Populate the low-level memory allocation function pointers in
-** sqlite3GlobalConfig.m with pointers to the routines in this file.
-*/
-SQLITE_PRIVATE void sqlite3MemSetDefault(void){
- static const sqlite3_mem_methods defaultMethods = {
- sqlite3MemMalloc,
- sqlite3MemFree,
- sqlite3MemRealloc,
- sqlite3MemSize,
- sqlite3MemRoundup,
- sqlite3MemInit,
- sqlite3MemShutdown,
- 0
- };
- sqlite3_config(SQLITE_CONFIG_MALLOC, &defaultMethods);
-}
-
-/*
-** Set the number of backtrace levels kept for each allocation.
-** A value of zero turns off backtracing. The number is always rounded
-** up to a multiple of 2.
-*/
-SQLITE_PRIVATE void sqlite3MemdebugBacktrace(int depth){
- if( depth<0 ){ depth = 0; }
- if( depth>20 ){ depth = 20; }
- depth = (depth+1)&0xfe;
- mem.nBacktrace = depth;
-}
-
-SQLITE_PRIVATE void sqlite3MemdebugBacktraceCallback(void (*xBacktrace)(int, int, void **)){
- mem.xBacktrace = xBacktrace;
-}
-
-/*
-** Set the title string for subsequent allocations.
-*/
-SQLITE_PRIVATE void sqlite3MemdebugSettitle(const char *zTitle){
- unsigned int n = sqlite3Strlen30(zTitle) + 1;
- sqlite3_mutex_enter(mem.mutex);
- if( n>=sizeof(mem.zTitle) ) n = sizeof(mem.zTitle)-1;
- memcpy(mem.zTitle, zTitle, n);
- mem.zTitle[n] = 0;
- mem.nTitle = ROUND8(n);
- sqlite3_mutex_leave(mem.mutex);
-}
-
-SQLITE_PRIVATE void sqlite3MemdebugSync(){
- struct MemBlockHdr *pHdr;
- for(pHdr=mem.pFirst; pHdr; pHdr=pHdr->pNext){
- void **pBt = (void**)pHdr;
- pBt -= pHdr->nBacktraceSlots;
- mem.xBacktrace(pHdr->iSize, pHdr->nBacktrace-1, &pBt[1]);
- }
-}
-
-/*
-** Open the file indicated and write a log of all unfreed memory
-** allocations into that log.
-*/
-SQLITE_PRIVATE void sqlite3MemdebugDump(const char *zFilename){
- FILE *out;
- struct MemBlockHdr *pHdr;
- void **pBt;
- int i;
- out = fopen(zFilename, "w");
- if( out==0 ){
- fprintf(stderr, "** Unable to output memory debug output log: %s **\n",
- zFilename);
- return;
- }
- for(pHdr=mem.pFirst; pHdr; pHdr=pHdr->pNext){
- char *z = (char*)pHdr;
- z -= pHdr->nBacktraceSlots*sizeof(void*) + pHdr->nTitle;
- fprintf(out, "**** %lld bytes at %p from %s ****\n",
- pHdr->iSize, &pHdr[1], pHdr->nTitle ? z : "???");
- if( pHdr->nBacktrace ){
- fflush(out);
- pBt = (void**)pHdr;
- pBt -= pHdr->nBacktraceSlots;
- backtrace_symbols_fd(pBt, pHdr->nBacktrace, fileno(out));
- fprintf(out, "\n");
- }
- }
- fprintf(out, "COUNTS:\n");
- for(i=0; i<NCSIZE-1; i++){
- if( mem.nAlloc[i] ){
- fprintf(out, " %5d: %10d %10d %10d\n",
- i*8, mem.nAlloc[i], mem.nCurrent[i], mem.mxCurrent[i]);
- }
- }
- if( mem.nAlloc[NCSIZE-1] ){
- fprintf(out, " %5d: %10d %10d %10d\n",
- NCSIZE*8-8, mem.nAlloc[NCSIZE-1],
- mem.nCurrent[NCSIZE-1], mem.mxCurrent[NCSIZE-1]);
- }
- fclose(out);
-}
-
-/*
-** Return the number of times sqlite3MemMalloc() has been called.
-*/
-SQLITE_PRIVATE int sqlite3MemdebugMallocCount(){
- int i;
- int nTotal = 0;
- for(i=0; i<NCSIZE; i++){
- nTotal += mem.nAlloc[i];
- }
- return nTotal;
-}
-
-
-#endif /* SQLITE_MEMDEBUG */
-
-/************** End of mem2.c ************************************************/
-/************** Begin file mem3.c ********************************************/
-/*
-** 2007 October 14
-**
-** 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 C functions that implement a memory
-** allocation subsystem for use by SQLite.
-**
-** This version of the memory allocation subsystem omits all
-** use of malloc(). The SQLite user supplies a block of memory
-** before calling sqlite3_initialize() from which allocations
-** are made and returned by the xMalloc() and xRealloc()
-** implementations. Once sqlite3_initialize() has been called,
-** the amount of memory available to SQLite is fixed and cannot
-** be changed.
-**
-** This version of the memory allocation subsystem is included
-** in the build only if SQLITE_ENABLE_MEMSYS3 is defined.
-**
-** $Id: mem3.c,v 1.25 2008/11/19 16:52:44 danielk1977 Exp $
-*/
-
-/*
-** This version of the memory allocator is only built into the library
-** SQLITE_ENABLE_MEMSYS3 is defined. Defining this symbol does not
-** mean that the library will use a memory-pool by default, just that
-** it is available. The mempool allocator is activated by calling
-** sqlite3_config().
-*/
-#ifdef SQLITE_ENABLE_MEMSYS3
-
-/*
-** Maximum size (in Mem3Blocks) of a "small" chunk.
-*/
-#define MX_SMALL 10
-
-
-/*
-** Number of freelist hash slots
-*/
-#define N_HASH 61
-
-/*
-** A memory allocation (also called a "chunk") consists of two or
-** more blocks where each block is 8 bytes. The first 8 bytes are
-** a header that is not returned to the user.
-**
-** A chunk is two or more blocks that is either checked out or
-** free. The first block has format u.hdr. u.hdr.size4x is 4 times the
-** size of the allocation in blocks if the allocation is free.
-** The u.hdr.size4x&1 bit is true if the chunk is checked out and
-** false if the chunk is on the freelist. The u.hdr.size4x&2 bit
-** is true if the previous chunk is checked out and false if the
-** previous chunk is free. The u.hdr.prevSize field is the size of
-** the previous chunk in blocks if the previous chunk is on the
-** freelist. If the previous chunk is checked out, then
-** u.hdr.prevSize can be part of the data for that chunk and should
-** not be read or written.
-**
-** We often identify a chunk by its index in mem3.aPool[]. When
-** this is done, the chunk index refers to the second block of
-** the chunk. In this way, the first chunk has an index of 1.
-** A chunk index of 0 means "no such chunk" and is the equivalent
-** of a NULL pointer.
-**
-** The second block of free chunks is of the form u.list. The
-** two fields form a double-linked list of chunks of related sizes.
-** Pointers to the head of the list are stored in mem3.aiSmall[]
-** for smaller chunks and mem3.aiHash[] for larger chunks.
-**
-** The second block of a chunk is user data if the chunk is checked
-** out. If a chunk is checked out, the user data may extend into
-** the u.hdr.prevSize value of the following chunk.
-*/
-typedef struct Mem3Block Mem3Block;
-struct Mem3Block {
- union {
- struct {
- u32 prevSize; /* Size of previous chunk in Mem3Block elements */
- u32 size4x; /* 4x the size of current chunk in Mem3Block elements */
- } hdr;
- struct {
- u32 next; /* Index in mem3.aPool[] of next free chunk */
- u32 prev; /* Index in mem3.aPool[] of previous free chunk */
- } list;
- } u;
-};
-
-/*
-** All of the static variables used by this module are collected
-** into a single structure named "mem3". This is to keep the
-** static variables organized and to reduce namespace pollution
-** when this module is combined with other in the amalgamation.
-*/
-static SQLITE_WSD struct Mem3Global {
- /*
- ** Memory available for allocation. nPool is the size of the array
- ** (in Mem3Blocks) pointed to by aPool less 2.
- */
- u32 nPool;
- Mem3Block *aPool;
-
- /*
- ** True if we are evaluating an out-of-memory callback.
- */
- int alarmBusy;
-
- /*
- ** Mutex to control access to the memory allocation subsystem.
- */
- sqlite3_mutex *mutex;
-
- /*
- ** The minimum amount of free space that we have seen.
- */
- u32 mnMaster;
-
- /*
- ** iMaster is the index of the master chunk. Most new allocations
- ** occur off of this chunk. szMaster is the size (in Mem3Blocks)
- ** of the current master. iMaster is 0 if there is not master chunk.
- ** The master chunk is not in either the aiHash[] or aiSmall[].
- */
- u32 iMaster;
- u32 szMaster;
-
- /*
- ** Array of lists of free blocks according to the block size
- ** for smaller chunks, or a hash on the block size for larger
- ** chunks.
- */
- u32 aiSmall[MX_SMALL-1]; /* For sizes 2 through MX_SMALL, inclusive */
- u32 aiHash[N_HASH]; /* For sizes MX_SMALL+1 and larger */
-} mem3 = { 97535575 };
-
-#define mem3 GLOBAL(struct Mem3Global, mem3)
-
-/*
-** Unlink the chunk at mem3.aPool[i] from list it is currently
-** on. *pRoot is the list that i is a member of.
-*/
-static void memsys3UnlinkFromList(u32 i, u32 *pRoot){
- u32 next = mem3.aPool[i].u.list.next;
- u32 prev = mem3.aPool[i].u.list.prev;
- assert( sqlite3_mutex_held(mem3.mutex) );
- if( prev==0 ){
- *pRoot = next;
- }else{
- mem3.aPool[prev].u.list.next = next;
- }
- if( next ){
- mem3.aPool[next].u.list.prev = prev;
- }
- mem3.aPool[i].u.list.next = 0;
- mem3.aPool[i].u.list.prev = 0;
-}
-
-/*
-** Unlink the chunk at index i from
-** whatever list is currently a member of.
-*/
-static void memsys3Unlink(u32 i){
- u32 size, hash;
- assert( sqlite3_mutex_held(mem3.mutex) );
- assert( (mem3.aPool[i-1].u.hdr.size4x & 1)==0 );
- assert( i>=1 );
- size = mem3.aPool[i-1].u.hdr.size4x/4;
- assert( size==mem3.aPool[i+size-1].u.hdr.prevSize );
- assert( size>=2 );
- if( size <= MX_SMALL ){
- memsys3UnlinkFromList(i, &mem3.aiSmall[size-2]);
- }else{
- hash = size % N_HASH;
- memsys3UnlinkFromList(i, &mem3.aiHash[hash]);
- }
-}
-
-/*
-** Link the chunk at mem3.aPool[i] so that is on the list rooted
-** at *pRoot.
-*/
-static void memsys3LinkIntoList(u32 i, u32 *pRoot){
- assert( sqlite3_mutex_held(mem3.mutex) );
- mem3.aPool[i].u.list.next = *pRoot;
- mem3.aPool[i].u.list.prev = 0;
- if( *pRoot ){
- mem3.aPool[*pRoot].u.list.prev = i;
- }
- *pRoot = i;
-}
-
-/*
-** Link the chunk at index i into either the appropriate
-** small chunk list, or into the large chunk hash table.
-*/
-static void memsys3Link(u32 i){
- u32 size, hash;
- assert( sqlite3_mutex_held(mem3.mutex) );
- assert( i>=1 );
- assert( (mem3.aPool[i-1].u.hdr.size4x & 1)==0 );
- size = mem3.aPool[i-1].u.hdr.size4x/4;
- assert( size==mem3.aPool[i+size-1].u.hdr.prevSize );
- assert( size>=2 );
- if( size <= MX_SMALL ){
- memsys3LinkIntoList(i, &mem3.aiSmall[size-2]);
- }else{
- hash = size % N_HASH;
- memsys3LinkIntoList(i, &mem3.aiHash[hash]);
- }
-}
-
-/*
-** If the STATIC_MEM mutex is not already held, obtain it now. The mutex
-** will already be held (obtained by code in malloc.c) if
-** sqlite3GlobalConfig.bMemStat is true.
-*/
-static void memsys3Enter(void){
- if( sqlite3GlobalConfig.bMemstat==0 && mem3.mutex==0 ){
- mem3.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM);
- }
- sqlite3_mutex_enter(mem3.mutex);
-}
-static void memsys3Leave(void){
- sqlite3_mutex_leave(mem3.mutex);
-}
-
-/*
-** Called when we are unable to satisfy an allocation of nBytes.
-*/
-static void memsys3OutOfMemory(int nByte){
- if( !mem3.alarmBusy ){
- mem3.alarmBusy = 1;
- assert( sqlite3_mutex_held(mem3.mutex) );
- sqlite3_mutex_leave(mem3.mutex);
- sqlite3_release_memory(nByte);
- sqlite3_mutex_enter(mem3.mutex);
- mem3.alarmBusy = 0;
- }
-}
-
-
-/*
-** Chunk i is a free chunk that has been unlinked. Adjust its
-** size parameters for check-out and return a pointer to the
-** user portion of the chunk.
-*/
-static void *memsys3Checkout(u32 i, u32 nBlock){
- u32 x;
- assert( sqlite3_mutex_held(mem3.mutex) );
- assert( i>=1 );
- assert( mem3.aPool[i-1].u.hdr.size4x/4==nBlock );
- assert( mem3.aPool[i+nBlock-1].u.hdr.prevSize==nBlock );
- x = mem3.aPool[i-1].u.hdr.size4x;
- mem3.aPool[i-1].u.hdr.size4x = nBlock*4 | 1 | (x&2);
- mem3.aPool[i+nBlock-1].u.hdr.prevSize = nBlock;
- mem3.aPool[i+nBlock-1].u.hdr.size4x |= 2;
- return &mem3.aPool[i];
-}
-
-/*
-** Carve a piece off of the end of the mem3.iMaster free chunk.
-** Return a pointer to the new allocation. Or, if the master chunk
-** is not large enough, return 0.
-*/
-static void *memsys3FromMaster(u32 nBlock){
- assert( sqlite3_mutex_held(mem3.mutex) );
- assert( mem3.szMaster>=nBlock );
- if( nBlock>=mem3.szMaster-1 ){
- /* Use the entire master */
- void *p = memsys3Checkout(mem3.iMaster, mem3.szMaster);
- mem3.iMaster = 0;
- mem3.szMaster = 0;
- mem3.mnMaster = 0;
- return p;
- }else{
- /* Split the master block. Return the tail. */
- u32 newi, x;
- newi = mem3.iMaster + mem3.szMaster - nBlock;
- assert( newi > mem3.iMaster+1 );
- mem3.aPool[mem3.iMaster+mem3.szMaster-1].u.hdr.prevSize = nBlock;
- mem3.aPool[mem3.iMaster+mem3.szMaster-1].u.hdr.size4x |= 2;
- mem3.aPool[newi-1].u.hdr.size4x = nBlock*4 + 1;
- mem3.szMaster -= nBlock;
- mem3.aPool[newi-1].u.hdr.prevSize = mem3.szMaster;
- x = mem3.aPool[mem3.iMaster-1].u.hdr.size4x & 2;
- mem3.aPool[mem3.iMaster-1].u.hdr.size4x = mem3.szMaster*4 | x;
- if( mem3.szMaster < mem3.mnMaster ){
- mem3.mnMaster = mem3.szMaster;
- }
- return (void*)&mem3.aPool[newi];
- }
-}
-
-/*
-** *pRoot is the head of a list of free chunks of the same size
-** or same size hash. In other words, *pRoot is an entry in either
-** mem3.aiSmall[] or mem3.aiHash[].
-**
-** This routine examines all entries on the given list and tries
-** to coalesce each entries with adjacent free chunks.
-**
-** If it sees a chunk that is larger than mem3.iMaster, it replaces
-** the current mem3.iMaster with the new larger chunk. In order for
-** this mem3.iMaster replacement to work, the master chunk must be
-** linked into the hash tables. That is not the normal state of
-** affairs, of course. The calling routine must link the master
-** chunk before invoking this routine, then must unlink the (possibly
-** changed) master chunk once this routine has finished.
-*/
-static void memsys3Merge(u32 *pRoot){
- u32 iNext, prev, size, i, x;
-
- assert( sqlite3_mutex_held(mem3.mutex) );
- for(i=*pRoot; i>0; i=iNext){
- iNext = mem3.aPool[i].u.list.next;
- size = mem3.aPool[i-1].u.hdr.size4x;
- assert( (size&1)==0 );
- if( (size&2)==0 ){
- memsys3UnlinkFromList(i, pRoot);
- assert( i > mem3.aPool[i-1].u.hdr.prevSize );
- prev = i - mem3.aPool[i-1].u.hdr.prevSize;
- if( prev==iNext ){
- iNext = mem3.aPool[prev].u.list.next;
- }
- memsys3Unlink(prev);
- size = i + size/4 - prev;
- x = mem3.aPool[prev-1].u.hdr.size4x & 2;
- mem3.aPool[prev-1].u.hdr.size4x = size*4 | x;
- mem3.aPool[prev+size-1].u.hdr.prevSize = size;
- memsys3Link(prev);
- i = prev;
- }else{
- size /= 4;
- }
- if( size>mem3.szMaster ){
- mem3.iMaster = i;
- mem3.szMaster = size;
- }
- }
-}
-
-/*
-** Return a block of memory of at least nBytes in size.
-** Return NULL if unable.
-**
-** This function assumes that the necessary mutexes, if any, are
-** already held by the caller. Hence "Unsafe".
-*/
-static void *memsys3MallocUnsafe(int nByte){
- u32 i;
- u32 nBlock;
- u32 toFree;
-
- assert( sqlite3_mutex_held(mem3.mutex) );
- assert( sizeof(Mem3Block)==8 );
- if( nByte<=12 ){
- nBlock = 2;
- }else{
- nBlock = (nByte + 11)/8;
- }
- assert( nBlock>=2 );
-
- /* STEP 1:
- ** Look for an entry of the correct size in either the small
- ** chunk table or in the large chunk hash table. This is
- ** successful most of the time (about 9 times out of 10).
- */
- if( nBlock <= MX_SMALL ){
- i = mem3.aiSmall[nBlock-2];
- if( i>0 ){
- memsys3UnlinkFromList(i, &mem3.aiSmall[nBlock-2]);
- return memsys3Checkout(i, nBlock);
- }
- }else{
- int hash = nBlock % N_HASH;
- for(i=mem3.aiHash[hash]; i>0; i=mem3.aPool[i].u.list.next){
- if( mem3.aPool[i-1].u.hdr.size4x/4==nBlock ){
- memsys3UnlinkFromList(i, &mem3.aiHash[hash]);
- return memsys3Checkout(i, nBlock);
- }
- }
- }
-
- /* STEP 2:
- ** Try to satisfy the allocation by carving a piece off of the end
- ** of the master chunk. This step usually works if step 1 fails.
- */
- if( mem3.szMaster>=nBlock ){
- return memsys3FromMaster(nBlock);
- }
-
-
- /* STEP 3:
- ** Loop through the entire memory pool. Coalesce adjacent free
- ** chunks. Recompute the master chunk as the largest free chunk.
- ** Then try again to satisfy the allocation by carving a piece off
- ** of the end of the master chunk. This step happens very
- ** rarely (we hope!)
- */
- for(toFree=nBlock*16; toFree<(mem3.nPool*16); toFree *= 2){
- memsys3OutOfMemory(toFree);
- if( mem3.iMaster ){
- memsys3Link(mem3.iMaster);
- mem3.iMaster = 0;
- mem3.szMaster = 0;
- }
- for(i=0; i<N_HASH; i++){
- memsys3Merge(&mem3.aiHash[i]);
- }
- for(i=0; i<MX_SMALL-1; i++){
- memsys3Merge(&mem3.aiSmall[i]);
- }
- if( mem3.szMaster ){
- memsys3Unlink(mem3.iMaster);
- if( mem3.szMaster>=nBlock ){
- return memsys3FromMaster(nBlock);
- }
- }
- }
-
- /* If none of the above worked, then we fail. */
- return 0;
-}
-
-/*
-** Free an outstanding memory allocation.
-**
-** This function assumes that the necessary mutexes, if any, are
-** already held by the caller. Hence "Unsafe".
-*/
-void memsys3FreeUnsafe(void *pOld){
- Mem3Block *p = (Mem3Block*)pOld;
- int i;
- u32 size, x;
- assert( sqlite3_mutex_held(mem3.mutex) );
- assert( p>mem3.aPool && p<&mem3.aPool[mem3.nPool] );
- i = p - mem3.aPool;
- assert( (mem3.aPool[i-1].u.hdr.size4x&1)==1 );
- size = mem3.aPool[i-1].u.hdr.size4x/4;
- assert( i+size<=mem3.nPool+1 );
- mem3.aPool[i-1].u.hdr.size4x &= ~1;
- mem3.aPool[i+size-1].u.hdr.prevSize = size;
- mem3.aPool[i+size-1].u.hdr.size4x &= ~2;
- memsys3Link(i);
-
- /* Try to expand the master using the newly freed chunk */
- if( mem3.iMaster ){
- while( (mem3.aPool[mem3.iMaster-1].u.hdr.size4x&2)==0 ){
- size = mem3.aPool[mem3.iMaster-1].u.hdr.prevSize;
- mem3.iMaster -= size;
- mem3.szMaster += size;
- memsys3Unlink(mem3.iMaster);
- x = mem3.aPool[mem3.iMaster-1].u.hdr.size4x & 2;
- mem3.aPool[mem3.iMaster-1].u.hdr.size4x = mem3.szMaster*4 | x;
- mem3.aPool[mem3.iMaster+mem3.szMaster-1].u.hdr.prevSize = mem3.szMaster;
- }
- x = mem3.aPool[mem3.iMaster-1].u.hdr.size4x & 2;
- while( (mem3.aPool[mem3.iMaster+mem3.szMaster-1].u.hdr.size4x&1)==0 ){
- memsys3Unlink(mem3.iMaster+mem3.szMaster);
- mem3.szMaster += mem3.aPool[mem3.iMaster+mem3.szMaster-1].u.hdr.size4x/4;
- mem3.aPool[mem3.iMaster-1].u.hdr.size4x = mem3.szMaster*4 | x;
- mem3.aPool[mem3.iMaster+mem3.szMaster-1].u.hdr.prevSize = mem3.szMaster;
- }
- }
-}
-
-/*
-** Return the size of an outstanding allocation, in bytes. The
-** size returned omits the 8-byte header overhead. This only
-** works for chunks that are currently checked out.
-*/
-static int memsys3Size(void *p){
- Mem3Block *pBlock;
- if( p==0 ) return 0;
- pBlock = (Mem3Block*)p;
- assert( (pBlock[-1].u.hdr.size4x&1)!=0 );
- return (pBlock[-1].u.hdr.size4x&~3)*2 - 4;
-}
-
-/*
-** Round up a request size to the next valid allocation size.
-*/
-static int memsys3Roundup(int n){
- if( n<=12 ){
- return 12;
- }else{
- return ((n+11)&~7) - 4;
- }
-}
-
-/*
-** Allocate nBytes of memory.
-*/
-static void *memsys3Malloc(int nBytes){
- sqlite3_int64 *p;
- assert( nBytes>0 ); /* malloc.c filters out 0 byte requests */
- memsys3Enter();
- p = memsys3MallocUnsafe(nBytes);
- memsys3Leave();
- return (void*)p;
-}
-
-/*
-** Free memory.
-*/
-void memsys3Free(void *pPrior){
- assert( pPrior );
- memsys3Enter();
- memsys3FreeUnsafe(pPrior);
- memsys3Leave();
-}
-
-/*
-** Change the size of an existing memory allocation
-*/
-void *memsys3Realloc(void *pPrior, int nBytes){
- int nOld;
- void *p;
- if( pPrior==0 ){
- return sqlite3_malloc(nBytes);
- }
- if( nBytes<=0 ){
- sqlite3_free(pPrior);
- return 0;
- }
- nOld = memsys3Size(pPrior);
- if( nBytes<=nOld && nBytes>=nOld-128 ){
- return pPrior;
- }
- memsys3Enter();
- p = memsys3MallocUnsafe(nBytes);
- if( p ){
- if( nOld<nBytes ){
- memcpy(p, pPrior, nOld);
- }else{
- memcpy(p, pPrior, nBytes);
- }
- memsys3FreeUnsafe(pPrior);
- }
- memsys3Leave();
- return p;
-}
-
-/*
-** Initialize this module.
-*/
-static int memsys3Init(void *NotUsed){
- UNUSED_PARAMETER(NotUsed);
- if( !sqlite3GlobalConfig.pHeap ){
- return SQLITE_ERROR;
- }
-
- /* Store a pointer to the memory block in global structure mem3. */
- assert( sizeof(Mem3Block)==8 );
- mem3.aPool = (Mem3Block *)sqlite3GlobalConfig.pHeap;
- mem3.nPool = (sqlite3GlobalConfig.nHeap / sizeof(Mem3Block)) - 2;
-
- /* Initialize the master block. */
- mem3.szMaster = mem3.nPool;
- mem3.mnMaster = mem3.szMaster;
- mem3.iMaster = 1;
- mem3.aPool[0].u.hdr.size4x = (mem3.szMaster<<2) + 2;
- mem3.aPool[mem3.nPool].u.hdr.prevSize = mem3.nPool;
- mem3.aPool[mem3.nPool].u.hdr.size4x = 1;
-
- return SQLITE_OK;
-}
-
-/*
-** Deinitialize this module.
-*/
-static void memsys3Shutdown(void *NotUsed){
- UNUSED_PARAMETER(NotUsed);
- return;
-}
-
-
-
-/*
-** Open the file indicated and write a log of all unfreed memory
-** allocations into that log.
-*/
-SQLITE_PRIVATE void sqlite3Memsys3Dump(const char *zFilename){
-#ifdef SQLITE_DEBUG
- FILE *out;
- u32 i, j;
- u32 size;
- if( zFilename==0 || zFilename[0]==0 ){
- out = stdout;
- }else{
- out = fopen(zFilename, "w");
- if( out==0 ){
- fprintf(stderr, "** Unable to output memory debug output log: %s **\n",
- zFilename);
- return;
- }
- }
- memsys3Enter();
- fprintf(out, "CHUNKS:\n");
- for(i=1; i<=mem3.nPool; i+=size/4){
- size = mem3.aPool[i-1].u.hdr.size4x;
- if( size/4<=1 ){
- fprintf(out, "%p size error\n", &mem3.aPool[i]);
- assert( 0 );
- break;
- }
- if( (size&1)==0 && mem3.aPool[i+size/4-1].u.hdr.prevSize!=size/4 ){
- fprintf(out, "%p tail size does not match\n", &mem3.aPool[i]);
- assert( 0 );
- break;
- }
- if( ((mem3.aPool[i+size/4-1].u.hdr.size4x&2)>>1)!=(size&1) ){
- fprintf(out, "%p tail checkout bit is incorrect\n", &mem3.aPool[i]);
- assert( 0 );
- break;
- }
- if( size&1 ){
- fprintf(out, "%p %6d bytes checked out\n", &mem3.aPool[i], (size/4)*8-8);
- }else{
- fprintf(out, "%p %6d bytes free%s\n", &mem3.aPool[i], (size/4)*8-8,
- i==mem3.iMaster ? " **master**" : "");
- }
- }
- for(i=0; i<MX_SMALL-1; i++){
- if( mem3.aiSmall[i]==0 ) continue;
- fprintf(out, "small(%2d):", i);
- for(j = mem3.aiSmall[i]; j>0; j=mem3.aPool[j].u.list.next){
- fprintf(out, " %p(%d)", &mem3.aPool[j],
- (mem3.aPool[j-1].u.hdr.size4x/4)*8-8);
- }
- fprintf(out, "\n");
- }
- for(i=0; i<N_HASH; i++){
- if( mem3.aiHash[i]==0 ) continue;
- fprintf(out, "hash(%2d):", i);
- for(j = mem3.aiHash[i]; j>0; j=mem3.aPool[j].u.list.next){
- fprintf(out, " %p(%d)", &mem3.aPool[j],
- (mem3.aPool[j-1].u.hdr.size4x/4)*8-8);
- }
- fprintf(out, "\n");
- }
- fprintf(out, "master=%d\n", mem3.iMaster);
- fprintf(out, "nowUsed=%d\n", mem3.nPool*8 - mem3.szMaster*8);
- fprintf(out, "mxUsed=%d\n", mem3.nPool*8 - mem3.mnMaster*8);
- sqlite3_mutex_leave(mem3.mutex);
- if( out==stdout ){
- fflush(stdout);
- }else{
- fclose(out);
- }
-#else
- UNUSED_PARAMETER(zFilename);
-#endif
-}
-
-/*
-** This routine is the only routine in this file with external
-** linkage.
-**
-** Populate the low-level memory allocation function pointers in
-** sqlite3GlobalConfig.m with pointers to the routines in this file. The
-** arguments specify the block of memory to manage.
-**
-** This routine is only called by sqlite3_config(), and therefore
-** is not required to be threadsafe (it is not).
-*/
-SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetMemsys3(void){
- static const sqlite3_mem_methods mempoolMethods = {
- memsys3Malloc,
- memsys3Free,
- memsys3Realloc,
- memsys3Size,
- memsys3Roundup,
- memsys3Init,
- memsys3Shutdown,
- 0
- };
- return &mempoolMethods;
-}
-
-#endif /* SQLITE_ENABLE_MEMSYS3 */
-
-/************** End of mem3.c ************************************************/
-/************** Begin file mem5.c ********************************************/
-/*
-** 2007 October 14
-**
-** 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 C functions that implement a memory
-** allocation subsystem for use by SQLite.
-**
-** This version of the memory allocation subsystem omits all
-** use of malloc(). The application gives SQLite a block of memory
-** before calling sqlite3_initialize() from which allocations
-** are made and returned by the xMalloc() and xRealloc()
-** implementations. Once sqlite3_initialize() has been called,
-** the amount of memory available to SQLite is fixed and cannot
-** be changed.
-**
-** This version of the memory allocation subsystem is included
-** in the build only if SQLITE_ENABLE_MEMSYS5 is defined.
-**
-** This memory allocator uses the following algorithm:
-**
-** 1. All memory allocations sizes are rounded up to a power of 2.
-**
-** 2. If two adjacent free blocks are the halves of a larger block,
-** then the two blocks are coalesed into the single larger block.
-**
-** 3. New memory is allocated from the first available free block.
-**
-** This algorithm is described in: J. M. Robson. "Bounds for Some Functions
-** Concerning Dynamic Storage Allocation". Journal of the Association for
-** Computing Machinery, Volume 21, Number 8, July 1974, pages 491-499.
-**
-** Let n be the size of the largest allocation divided by the minimum
-** allocation size (after rounding all sizes up to a power of 2.) Let M
-** be the maximum amount of memory ever outstanding at one time. Let
-** N be the total amount of memory available for allocation. Robson
-** proved that this memory allocator will never breakdown due to
-** fragmentation as long as the following constraint holds:
-**
-** N >= M*(1 + log2(n)/2) - n + 1
-**
-** The sqlite3_status() logic tracks the maximum values of n and M so
-** that an application can, at any time, verify this constraint.
-*/
-
-/*
-** This version of the memory allocator is used only when
-** SQLITE_ENABLE_MEMSYS5 is defined.
-*/
-#ifdef SQLITE_ENABLE_MEMSYS5
-
-/*
-** A minimum allocation is an instance of the following structure.
-** Larger allocations are an array of these structures where the
-** size of the array is a power of 2.
-**
-** The size of this object must be a power of two. That fact is
-** verified in memsys5Init().
-*/
-typedef struct Mem5Link Mem5Link;
-struct Mem5Link {
- int next; /* Index of next free chunk */
- int prev; /* Index of previous free chunk */
-};
-
-/*
-** Maximum size of any allocation is ((1<<LOGMAX)*mem5.szAtom). Since
-** mem5.szAtom is always at least 8 and 32-bit integers are used,
-** it is not actually possible to reach this limit.
-*/
-#define LOGMAX 30
-
-/*
-** Masks used for mem5.aCtrl[] elements.
-*/
-#define CTRL_LOGSIZE 0x1f /* Log2 Size of this block */
-#define CTRL_FREE 0x20 /* True if not checked out */
-
-/*
-** All of the static variables used by this module are collected
-** into a single structure named "mem5". This is to keep the
-** static variables organized and to reduce namespace pollution
-** when this module is combined with other in the amalgamation.
-*/
-static SQLITE_WSD struct Mem5Global {
- /*
- ** Memory available for allocation
- */
- int szAtom; /* Smallest possible allocation in bytes */
- int nBlock; /* Number of szAtom sized blocks in zPool */
- u8 *zPool; /* Memory available to be allocated */
-
- /*
- ** Mutex to control access to the memory allocation subsystem.
- */
- sqlite3_mutex *mutex;
-
- /*
- ** Performance statistics
- */
- u64 nAlloc; /* Total number of calls to malloc */
- u64 totalAlloc; /* Total of all malloc calls - includes internal frag */
- u64 totalExcess; /* Total internal fragmentation */
- u32 currentOut; /* Current checkout, including internal fragmentation */
- u32 currentCount; /* Current number of distinct checkouts */
- u32 maxOut; /* Maximum instantaneous currentOut */
- u32 maxCount; /* Maximum instantaneous currentCount */
- u32 maxRequest; /* Largest allocation (exclusive of internal frag) */
-
- /*
- ** Lists of free blocks. aiFreelist[0] is a list of free blocks of
- ** size mem5.szAtom. aiFreelist[1] holds blocks of size szAtom*2.
- ** and so forth.
- */
- int aiFreelist[LOGMAX+1];
-
- /*
- ** Space for tracking which blocks are checked out and the size
- ** of each block. One byte per block.
- */
- u8 *aCtrl;
-
-} mem5 = { 0 };
-
-/*
-** Access the static variable through a macro for SQLITE_OMIT_WSD
-*/
-#define mem5 GLOBAL(struct Mem5Global, mem5)
-
-/*
-** Assuming mem5.zPool is divided up into an array of Mem5Link
-** structures, return a pointer to the idx-th such lik.
-*/
-#define MEM5LINK(idx) ((Mem5Link *)(&mem5.zPool[(idx)*mem5.szAtom]))
-
-/*
-** Unlink the chunk at mem5.aPool[i] from list it is currently
-** on. It should be found on mem5.aiFreelist[iLogsize].
-*/
-static void memsys5Unlink(int i, int iLogsize){
- int next, prev;
- assert( i>=0 && i<mem5.nBlock );
- assert( iLogsize>=0 && iLogsize<=LOGMAX );
- assert( (mem5.aCtrl[i] & CTRL_LOGSIZE)==iLogsize );
-
- next = MEM5LINK(i)->next;
- prev = MEM5LINK(i)->prev;
- if( prev<0 ){
- mem5.aiFreelist[iLogsize] = next;
- }else{
- MEM5LINK(prev)->next = next;
- }
- if( next>=0 ){
- MEM5LINK(next)->prev = prev;
- }
-}
-
-/*
-** Link the chunk at mem5.aPool[i] so that is on the iLogsize
-** free list.
-*/
-static void memsys5Link(int i, int iLogsize){
- int x;
- assert( sqlite3_mutex_held(mem5.mutex) );
- assert( i>=0 && i<mem5.nBlock );
- assert( iLogsize>=0 && iLogsize<=LOGMAX );
- assert( (mem5.aCtrl[i] & CTRL_LOGSIZE)==iLogsize );
-
- x = MEM5LINK(i)->next = mem5.aiFreelist[iLogsize];
- MEM5LINK(i)->prev = -1;
- if( x>=0 ){
- assert( x<mem5.nBlock );
- MEM5LINK(x)->prev = i;
- }
- mem5.aiFreelist[iLogsize] = i;
-}
-
-/*
-** If the STATIC_MEM mutex is not already held, obtain it now. The mutex
-** will already be held (obtained by code in malloc.c) if
-** sqlite3GlobalConfig.bMemStat is true.
-*/
-static void memsys5Enter(void){
- sqlite3_mutex_enter(mem5.mutex);
-}
-static void memsys5Leave(void){
- sqlite3_mutex_leave(mem5.mutex);
-}
-
-/*
-** Return the size of an outstanding allocation, in bytes. The
-** size returned omits the 8-byte header overhead. This only
-** works for chunks that are currently checked out.
-*/
-static int memsys5Size(void *p){
- int iSize = 0;
- if( p ){
- int i = ((u8 *)p-mem5.zPool)/mem5.szAtom;
- assert( i>=0 && i<mem5.nBlock );
- iSize = mem5.szAtom * (1 << (mem5.aCtrl[i]&CTRL_LOGSIZE));
- }
- return iSize;
-}
-
-/*
-** Find the first entry on the freelist iLogsize. Unlink that
-** entry and return its index.
-*/
-static int memsys5UnlinkFirst(int iLogsize){
- int i;
- int iFirst;
-
- assert( iLogsize>=0 && iLogsize<=LOGMAX );
- i = iFirst = mem5.aiFreelist[iLogsize];
- assert( iFirst>=0 );
- while( i>0 ){
- if( i<iFirst ) iFirst = i;
- i = MEM5LINK(i)->next;
- }
- memsys5Unlink(iFirst, iLogsize);
- return iFirst;
-}
-
-/*
-** Return a block of memory of at least nBytes in size.
-** Return NULL if unable. Return NULL if nBytes==0.
-**
-** The caller guarantees that nByte positive.
-**
-** The caller has obtained a mutex prior to invoking this
-** routine so there is never any chance that two or more
-** threads can be in this routine at the same time.
-*/
-static void *memsys5MallocUnsafe(int nByte){
- int i; /* Index of a mem5.aPool[] slot */
- int iBin; /* Index into mem5.aiFreelist[] */
- int iFullSz; /* Size of allocation rounded up to power of 2 */
- int iLogsize; /* Log2 of iFullSz/POW2_MIN */
-
- /* nByte must be a positive */
- assert( nByte>0 );
-
- /* Keep track of the maximum allocation request. Even unfulfilled
- ** requests are counted */
- if( (u32)nByte>mem5.maxRequest ){
- mem5.maxRequest = nByte;
- }
-
- /* Abort if the requested allocation size is larger than the largest
- ** power of two that we can represent using 32-bit signed integers.
- */
- if( nByte > 0x40000000 ){
- return 0;
- }
-
- /* Round nByte up to the next valid power of two */
- for(iFullSz=mem5.szAtom, iLogsize=0; iFullSz<nByte; iFullSz *= 2, iLogsize++){}
-
- /* Make sure mem5.aiFreelist[iLogsize] contains at least one free
- ** block. If not, then split a block of the next larger power of
- ** two in order to create a new free block of size iLogsize.
- */
- for(iBin=iLogsize; mem5.aiFreelist[iBin]<0 && iBin<=LOGMAX; iBin++){}
- if( iBin>LOGMAX ) return 0;
- i = memsys5UnlinkFirst(iBin);
- while( iBin>iLogsize ){
- int newSize;
-
- iBin--;
- newSize = 1 << iBin;
- mem5.aCtrl[i+newSize] = CTRL_FREE | iBin;
- memsys5Link(i+newSize, iBin);
- }
- mem5.aCtrl[i] = iLogsize;
-
- /* Update allocator performance statistics. */
- mem5.nAlloc++;
- mem5.totalAlloc += iFullSz;
- mem5.totalExcess += iFullSz - nByte;
- mem5.currentCount++;
- mem5.currentOut += iFullSz;
- if( mem5.maxCount<mem5.currentCount ) mem5.maxCount = mem5.currentCount;
- if( mem5.maxOut<mem5.currentOut ) mem5.maxOut = mem5.currentOut;
-
- /* Return a pointer to the allocated memory. */
- return (void*)&mem5.zPool[i*mem5.szAtom];
-}
-
-/*
-** Free an outstanding memory allocation.
-*/
-static void memsys5FreeUnsafe(void *pOld){
- u32 size, iLogsize;
- int iBlock;
-
- /* Set iBlock to the index of the block pointed to by pOld in
- ** the array of mem5.szAtom byte blocks pointed to by mem5.zPool.
- */
- iBlock = ((u8 *)pOld-mem5.zPool)/mem5.szAtom;
-
- /* Check that the pointer pOld points to a valid, non-free block. */
- assert( iBlock>=0 && iBlock<mem5.nBlock );
- assert( ((u8 *)pOld-mem5.zPool)%mem5.szAtom==0 );
- assert( (mem5.aCtrl[iBlock] & CTRL_FREE)==0 );
-
- iLogsize = mem5.aCtrl[iBlock] & CTRL_LOGSIZE;
- size = 1<<iLogsize;
- assert( iBlock+size-1<(u32)mem5.nBlock );
-
- mem5.aCtrl[iBlock] |= CTRL_FREE;
- mem5.aCtrl[iBlock+size-1] |= CTRL_FREE;
- assert( mem5.currentCount>0 );
- assert( mem5.currentOut>=(size*mem5.szAtom) );
- mem5.currentCount--;
- mem5.currentOut -= size*mem5.szAtom;
- assert( mem5.currentOut>0 || mem5.currentCount==0 );
- assert( mem5.currentCount>0 || mem5.currentOut==0 );
-
- mem5.aCtrl[iBlock] = CTRL_FREE | iLogsize;
- while( ALWAYS(iLogsize<LOGMAX) ){
- int iBuddy;
- if( (iBlock>>iLogsize) & 1 ){
- iBuddy = iBlock - size;
- }else{
- iBuddy = iBlock + size;
- }
- assert( iBuddy>=0 );
- if( (iBuddy+(1<<iLogsize))>mem5.nBlock ) break;
- if( mem5.aCtrl[iBuddy]!=(CTRL_FREE | iLogsize) ) break;
- memsys5Unlink(iBuddy, iLogsize);
- iLogsize++;
- if( iBuddy<iBlock ){
- mem5.aCtrl[iBuddy] = CTRL_FREE | iLogsize;
- mem5.aCtrl[iBlock] = 0;
- iBlock = iBuddy;
- }else{
- mem5.aCtrl[iBlock] = CTRL_FREE | iLogsize;
- mem5.aCtrl[iBuddy] = 0;
- }
- size *= 2;
- }
- memsys5Link(iBlock, iLogsize);
-}
-
-/*
-** Allocate nBytes of memory
-*/
-static void *memsys5Malloc(int nBytes){
- sqlite3_int64 *p = 0;
- if( nBytes>0 ){
- memsys5Enter();
- p = memsys5MallocUnsafe(nBytes);
- memsys5Leave();
- }
- return (void*)p;
-}
-
-/*
-** Free memory.
-**
-** The outer layer memory allocator prevents this routine from
-** being called with pPrior==0.
-*/
-static void memsys5Free(void *pPrior){
- assert( pPrior!=0 );
- memsys5Enter();
- memsys5FreeUnsafe(pPrior);
- memsys5Leave();
-}
-
-/*
-** Change the size of an existing memory allocation.
-**
-** The outer layer memory allocator prevents this routine from
-** being called with pPrior==0.
-**
-** nBytes is always a value obtained from a prior call to
-** memsys5Round(). Hence nBytes is always a non-negative power
-** of two. If nBytes==0 that means that an oversize allocation
-** (an allocation larger than 0x40000000) was requested and this
-** routine should return 0 without freeing pPrior.
-*/
-static void *memsys5Realloc(void *pPrior, int nBytes){
- int nOld;
- void *p;
- assert( pPrior!=0 );
- assert( (nBytes&(nBytes-1))==0 );
- assert( nBytes>=0 );
- if( nBytes==0 ){
- return 0;
- }
- nOld = memsys5Size(pPrior);
- if( nBytes<=nOld ){
- return pPrior;
- }
- memsys5Enter();
- p = memsys5MallocUnsafe(nBytes);
- if( p ){
- memcpy(p, pPrior, nOld);
- memsys5FreeUnsafe(pPrior);
- }
- memsys5Leave();
- return p;
-}
-
-/*
-** Round up a request size to the next valid allocation size. If
-** the allocation is too large to be handled by this allocation system,
-** return 0.
-**
-** All allocations must be a power of two and must be expressed by a
-** 32-bit signed integer. Hence the largest allocation is 0x40000000
-** or 1073741824 bytes.
-*/
-static int memsys5Roundup(int n){
- int iFullSz;
- if( n > 0x40000000 ) return 0;
- for(iFullSz=mem5.szAtom; iFullSz<n; iFullSz *= 2);
- return iFullSz;
-}
-
-/*
-** Return the ceiling of the logarithm base 2 of iValue.
-**
-** Examples: memsys5Log(1) -> 0
-** memsys5Log(2) -> 1
-** memsys5Log(4) -> 2
-** memsys5Log(5) -> 3
-** memsys5Log(8) -> 3
-** memsys5Log(9) -> 4
-*/
-static int memsys5Log(int iValue){
- int iLog;
- for(iLog=0; (1<<iLog)<iValue; iLog++);
- return iLog;
-}
-
-/*
-** Initialize the memory allocator.
-**
-** This routine is not threadsafe. The caller must be holding a mutex
-** to prevent multiple threads from entering at the same time.
-*/
-static int memsys5Init(void *NotUsed){
- int ii; /* Loop counter */
- int nByte; /* Number of bytes of memory available to this allocator */
- u8 *zByte; /* Memory usable by this allocator */
- int nMinLog; /* Log base 2 of minimum allocation size in bytes */
- int iOffset; /* An offset into mem5.aCtrl[] */
-
- UNUSED_PARAMETER(NotUsed);
-
- /* For the purposes of this routine, disable the mutex */
- mem5.mutex = 0;
-
- /* The size of a Mem5Link object must be a power of two. Verify that
- ** this is case.
- */
- assert( (sizeof(Mem5Link)&(sizeof(Mem5Link)-1))==0 );
-
- nByte = sqlite3GlobalConfig.nHeap;
- zByte = (u8*)sqlite3GlobalConfig.pHeap;
- assert( zByte!=0 ); /* sqlite3_config() does not allow otherwise */
-
- nMinLog = memsys5Log(sqlite3GlobalConfig.mnReq);
- mem5.szAtom = (1<<nMinLog);
- while( (int)sizeof(Mem5Link)>mem5.szAtom ){
- mem5.szAtom = mem5.szAtom << 1;
- }
-
- mem5.nBlock = (nByte / (mem5.szAtom+sizeof(u8)));
- mem5.zPool = zByte;
- mem5.aCtrl = (u8 *)&mem5.zPool[mem5.nBlock*mem5.szAtom];
-
- for(ii=0; ii<=LOGMAX; ii++){
- mem5.aiFreelist[ii] = -1;
- }
-
- iOffset = 0;
- for(ii=LOGMAX; ii>=0; ii--){
- int nAlloc = (1<<ii);
- if( (iOffset+nAlloc)<=mem5.nBlock ){
- mem5.aCtrl[iOffset] = ii | CTRL_FREE;
- memsys5Link(iOffset, ii);
- iOffset += nAlloc;
- }
- assert((iOffset+nAlloc)>mem5.nBlock);
- }
-
- /* If a mutex is required for normal operation, allocate one */
- if( sqlite3GlobalConfig.bMemstat==0 ){
- mem5.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM);
- }
-
- return SQLITE_OK;
-}
-
-/*
-** Deinitialize this module.
-*/
-static void memsys5Shutdown(void *NotUsed){
- UNUSED_PARAMETER(NotUsed);
- mem5.mutex = 0;
- return;
-}
-
-#ifdef SQLITE_TEST
-/*
-** Open the file indicated and write a log of all unfreed memory
-** allocations into that log.
-*/
-SQLITE_PRIVATE void sqlite3Memsys5Dump(const char *zFilename){
- FILE *out;
- int i, j, n;
- int nMinLog;
-
- if( zFilename==0 || zFilename[0]==0 ){
- out = stdout;
- }else{
- out = fopen(zFilename, "w");
- if( out==0 ){
- fprintf(stderr, "** Unable to output memory debug output log: %s **\n",
- zFilename);
- return;
- }
- }
- memsys5Enter();
- nMinLog = memsys5Log(mem5.szAtom);
- for(i=0; i<=LOGMAX && i+nMinLog<32; i++){
- for(n=0, j=mem5.aiFreelist[i]; j>=0; j = MEM5LINK(j)->next, n++){}
- fprintf(out, "freelist items of size %d: %d\n", mem5.szAtom << i, n);
- }
- fprintf(out, "mem5.nAlloc = %llu\n", mem5.nAlloc);
- fprintf(out, "mem5.totalAlloc = %llu\n", mem5.totalAlloc);
- fprintf(out, "mem5.totalExcess = %llu\n", mem5.totalExcess);
- fprintf(out, "mem5.currentOut = %u\n", mem5.currentOut);
- fprintf(out, "mem5.currentCount = %u\n", mem5.currentCount);
- fprintf(out, "mem5.maxOut = %u\n", mem5.maxOut);
- fprintf(out, "mem5.maxCount = %u\n", mem5.maxCount);
- fprintf(out, "mem5.maxRequest = %u\n", mem5.maxRequest);
- memsys5Leave();
- if( out==stdout ){
- fflush(stdout);
- }else{
- fclose(out);
- }
-}
-#endif
-
-/*
-** This routine is the only routine in this file with external
-** linkage. It returns a pointer to a static sqlite3_mem_methods
-** struct populated with the memsys5 methods.
-*/
-SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetMemsys5(void){
- static const sqlite3_mem_methods memsys5Methods = {
- memsys5Malloc,
- memsys5Free,
- memsys5Realloc,
- memsys5Size,
- memsys5Roundup,
- memsys5Init,
- memsys5Shutdown,
- 0
- };
- return &memsys5Methods;
-}
-
-#endif /* SQLITE_ENABLE_MEMSYS5 */
-
-/************** End of mem5.c ************************************************/
-/************** Begin file mutex.c *******************************************/
-/*
-** 2007 August 14
-**
-** 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 C functions that implement mutexes.
-**
-** This file contains code that is common across all mutex implementations.
-
-**
-** $Id: mutex.c,v 1.31 2009/07/16 18:21:18 drh Exp $
-*/
-
-#if defined(SQLITE_DEBUG) && !defined(SQLITE_MUTEX_OMIT)
-/*
-** For debugging purposes, record when the mutex subsystem is initialized
-** and uninitialized so that we can assert() if there is an attempt to
-** allocate a mutex while the system is uninitialized.
-*/
-static SQLITE_WSD int mutexIsInit = 0;
-#endif /* SQLITE_DEBUG */
-
-
-#ifndef SQLITE_MUTEX_OMIT
-/*
-** Initialize the mutex system.
-*/
-SQLITE_PRIVATE int sqlite3MutexInit(void){
- int rc = SQLITE_OK;
- if( sqlite3GlobalConfig.bCoreMutex ){
- if( !sqlite3GlobalConfig.mutex.xMutexAlloc ){
- /* If the xMutexAlloc method has not been set, then the user did not
- ** install a mutex implementation via sqlite3_config() prior to
- ** sqlite3_initialize() being called. This block copies pointers to
- ** the default implementation into the sqlite3GlobalConfig structure.
- */
- sqlite3_mutex_methods *pFrom = sqlite3DefaultMutex();
- sqlite3_mutex_methods *pTo = &sqlite3GlobalConfig.mutex;
-
- memcpy(pTo, pFrom, offsetof(sqlite3_mutex_methods, xMutexAlloc));
- memcpy(&pTo->xMutexFree, &pFrom->xMutexFree,
- sizeof(*pTo) - offsetof(sqlite3_mutex_methods, xMutexFree));
- pTo->xMutexAlloc = pFrom->xMutexAlloc;
- }
- rc = sqlite3GlobalConfig.mutex.xMutexInit();
- }
-
-#ifdef SQLITE_DEBUG
- GLOBAL(int, mutexIsInit) = 1;
-#endif
-
- return rc;
-}
-
-/*
-** Shutdown the mutex system. This call frees resources allocated by
-** sqlite3MutexInit().
-*/
-SQLITE_PRIVATE int sqlite3MutexEnd(void){
- int rc = SQLITE_OK;
- if( sqlite3GlobalConfig.mutex.xMutexEnd ){
- rc = sqlite3GlobalConfig.mutex.xMutexEnd();
- }
-
-#ifdef SQLITE_DEBUG
- GLOBAL(int, mutexIsInit) = 0;
-#endif
-
- return rc;
-}
-
-/*
-** Retrieve a pointer to a static mutex or allocate a new dynamic one.
-*/
-SQLITE_API sqlite3_mutex *sqlite3_mutex_alloc(int id){
-#ifndef SQLITE_OMIT_AUTOINIT
- if( sqlite3_initialize() ) return 0;
-#endif
- return sqlite3GlobalConfig.mutex.xMutexAlloc(id);
-}
-
-SQLITE_PRIVATE sqlite3_mutex *sqlite3MutexAlloc(int id){
- if( !sqlite3GlobalConfig.bCoreMutex ){
- return 0;
- }
- assert( GLOBAL(int, mutexIsInit) );
- return sqlite3GlobalConfig.mutex.xMutexAlloc(id);
-}
-
-/*
-** Free a dynamic mutex.
-*/
-SQLITE_API void sqlite3_mutex_free(sqlite3_mutex *p){
- if( p ){
- sqlite3GlobalConfig.mutex.xMutexFree(p);
- }
-}
-
-/*
-** Obtain the mutex p. If some other thread already has the mutex, block
-** until it can be obtained.
-*/
-SQLITE_API void sqlite3_mutex_enter(sqlite3_mutex *p){
- if( p ){
- sqlite3GlobalConfig.mutex.xMutexEnter(p);
- }
-}
-
-/*
-** Obtain the mutex p. If successful, return SQLITE_OK. Otherwise, if another
-** thread holds the mutex and it cannot be obtained, return SQLITE_BUSY.
-*/
-SQLITE_API int sqlite3_mutex_try(sqlite3_mutex *p){
- int rc = SQLITE_OK;
- if( p ){
- return sqlite3GlobalConfig.mutex.xMutexTry(p);
- }
- return rc;
-}
-
-/*
-** The sqlite3_mutex_leave() routine exits a mutex that was previously
-** entered by the same thread. The behavior is undefined if the mutex
-** is not currently entered. If a NULL pointer is passed as an argument
-** this function is a no-op.
-*/
-SQLITE_API void sqlite3_mutex_leave(sqlite3_mutex *p){
- if( p ){
- sqlite3GlobalConfig.mutex.xMutexLeave(p);
- }
-}
-
-#ifndef NDEBUG
-/*
-** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
-** intended for use inside assert() statements.
-*/
-SQLITE_API int sqlite3_mutex_held(sqlite3_mutex *p){
- return p==0 || sqlite3GlobalConfig.mutex.xMutexHeld(p);
-}
-SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex *p){
- return p==0 || sqlite3GlobalConfig.mutex.xMutexNotheld(p);
-}
-#endif
-
-#endif /* SQLITE_OMIT_MUTEX */
-
-/************** End of mutex.c ***********************************************/
-/************** Begin file mutex_noop.c **************************************/
-/*
-** 2008 October 07
-**
-** 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 C functions that implement mutexes.
-**
-** This implementation in this file does not provide any mutual
-** exclusion and is thus suitable for use only in applications
-** that use SQLite in a single thread. The routines defined
-** here are place-holders. Applications can substitute working
-** mutex routines at start-time using the
-**
-** sqlite3_config(SQLITE_CONFIG_MUTEX,...)
-**
-** interface.
-**
-** If compiled with SQLITE_DEBUG, then additional logic is inserted
-** that does error checking on mutexes to make sure they are being
-** called correctly.
-**
-** $Id: mutex_noop.c,v 1.3 2008/12/05 17:17:08 drh Exp $
-*/
-
-
-#if defined(SQLITE_MUTEX_NOOP) && !defined(SQLITE_DEBUG)
-/*
-** Stub routines for all mutex methods.
-**
-** This routines provide no mutual exclusion or error checking.
-*/
-static int noopMutexHeld(sqlite3_mutex *p){ return 1; }
-static int noopMutexNotheld(sqlite3_mutex *p){ return 1; }
-static int noopMutexInit(void){ return SQLITE_OK; }
-static int noopMutexEnd(void){ return SQLITE_OK; }
-static sqlite3_mutex *noopMutexAlloc(int id){ return (sqlite3_mutex*)8; }
-static void noopMutexFree(sqlite3_mutex *p){ return; }
-static void noopMutexEnter(sqlite3_mutex *p){ return; }
-static int noopMutexTry(sqlite3_mutex *p){ return SQLITE_OK; }
-static void noopMutexLeave(sqlite3_mutex *p){ return; }
-
-SQLITE_PRIVATE sqlite3_mutex_methods *sqlite3DefaultMutex(void){
- static sqlite3_mutex_methods sMutex = {
- noopMutexInit,
- noopMutexEnd,
- noopMutexAlloc,
- noopMutexFree,
- noopMutexEnter,
- noopMutexTry,
- noopMutexLeave,
-
- noopMutexHeld,
- noopMutexNotheld
- };
-
- return &sMutex;
-}
-#endif /* defined(SQLITE_MUTEX_NOOP) && !defined(SQLITE_DEBUG) */
-
-#if defined(SQLITE_MUTEX_NOOP) && defined(SQLITE_DEBUG)
-/*
-** In this implementation, error checking is provided for testing
-** and debugging purposes. The mutexes still do not provide any
-** mutual exclusion.
-*/
-
-/*
-** The mutex object
-*/
-struct sqlite3_mutex {
- int id; /* The mutex type */
- int cnt; /* Number of entries without a matching leave */
-};
-
-/*
-** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
-** intended for use inside assert() statements.
-*/
-static int debugMutexHeld(sqlite3_mutex *p){
- return p==0 || p->cnt>0;
-}
-static int debugMutexNotheld(sqlite3_mutex *p){
- return p==0 || p->cnt==0;
-}
-
-/*
-** Initialize and deinitialize the mutex subsystem.
-*/
-static int debugMutexInit(void){ return SQLITE_OK; }
-static int debugMutexEnd(void){ return SQLITE_OK; }
-
-/*
-** The sqlite3_mutex_alloc() routine allocates a new
-** mutex and returns a pointer to it. If it returns NULL
-** that means that a mutex could not be allocated.
-*/
-static sqlite3_mutex *debugMutexAlloc(int id){
- static sqlite3_mutex aStatic[6];
- sqlite3_mutex *pNew = 0;
- switch( id ){
- case SQLITE_MUTEX_FAST:
- case SQLITE_MUTEX_RECURSIVE: {
- pNew = sqlite3Malloc(sizeof(*pNew));
- if( pNew ){
- pNew->id = id;
- pNew->cnt = 0;
- }
- break;
- }
- default: {
- assert( id-2 >= 0 );
- assert( id-2 < (int)(sizeof(aStatic)/sizeof(aStatic[0])) );
- pNew = &aStatic[id-2];
- pNew->id = id;
- break;
- }
- }
- return pNew;
-}
-
-/*
-** This routine deallocates a previously allocated mutex.
-*/
-static void debugMutexFree(sqlite3_mutex *p){
- assert( p->cnt==0 );
- assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE );
- sqlite3_free(p);
-}
-
-/*
-** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt
-** to enter a mutex. If another thread is already within the mutex,
-** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return
-** SQLITE_BUSY. The sqlite3_mutex_try() interface returns SQLITE_OK
-** upon successful entry. Mutexes created using SQLITE_MUTEX_RECURSIVE can
-** be entered multiple times by the same thread. In such cases the,
-** mutex must be exited an equal number of times before another thread
-** can enter. If the same thread tries to enter any other kind of mutex
-** more than once, the behavior is undefined.
-*/
-static void debugMutexEnter(sqlite3_mutex *p){
- assert( p->id==SQLITE_MUTEX_RECURSIVE || debugMutexNotheld(p) );
- p->cnt++;
-}
-static int debugMutexTry(sqlite3_mutex *p){
- assert( p->id==SQLITE_MUTEX_RECURSIVE || debugMutexNotheld(p) );
- p->cnt++;
- return SQLITE_OK;
-}
-
-/*
-** The sqlite3_mutex_leave() routine exits a mutex that was
-** previously entered by the same thread. The behavior
-** is undefined if the mutex is not currently entered or
-** is not currently allocated. SQLite will never do either.
-*/
-static void debugMutexLeave(sqlite3_mutex *p){
- assert( debugMutexHeld(p) );
- p->cnt--;
- assert( p->id==SQLITE_MUTEX_RECURSIVE || debugMutexNotheld(p) );
-}
-
-SQLITE_PRIVATE sqlite3_mutex_methods *sqlite3DefaultMutex(void){
- static sqlite3_mutex_methods sMutex = {
- debugMutexInit,
- debugMutexEnd,
- debugMutexAlloc,
- debugMutexFree,
- debugMutexEnter,
- debugMutexTry,
- debugMutexLeave,
-
- debugMutexHeld,
- debugMutexNotheld
- };
-
- return &sMutex;
-}
-#endif /* defined(SQLITE_MUTEX_NOOP) && defined(SQLITE_DEBUG) */
-
-/************** End of mutex_noop.c ******************************************/
-/************** Begin file mutex_os2.c ***************************************/
-/*
-** 2007 August 28
-**
-** 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 C functions that implement mutexes for OS/2
-**
-** $Id: mutex_os2.c,v 1.11 2008/11/22 19:50:54 pweilbacher Exp $
-*/
-
-/*
-** The code in this file is only used if SQLITE_MUTEX_OS2 is defined.
-** See the mutex.h file for details.
-*/
-#ifdef SQLITE_MUTEX_OS2
-
-/********************** OS/2 Mutex Implementation **********************
-**
-** This implementation of mutexes is built using the OS/2 API.
-*/
-
-/*
-** The mutex object
-** Each recursive mutex is an instance of the following structure.
-*/
-struct sqlite3_mutex {
- HMTX mutex; /* Mutex controlling the lock */
- int id; /* Mutex type */
- int nRef; /* Number of references */
- TID owner; /* Thread holding this mutex */
-};
-
-#define OS2_MUTEX_INITIALIZER 0,0,0,0
-
-/*
-** Initialize and deinitialize the mutex subsystem.
-*/
-static int os2MutexInit(void){ return SQLITE_OK; }
-static int os2MutexEnd(void){ return SQLITE_OK; }
-
-/*
-** The sqlite3_mutex_alloc() routine allocates a new
-** mutex and returns a pointer to it. If it returns NULL
-** that means that a mutex could not be allocated.
-** SQLite will unwind its stack and return an error. The argument
-** to sqlite3_mutex_alloc() is one of these integer constants:
-**
-** <ul>
-** <li> SQLITE_MUTEX_FAST 0
-** <li> SQLITE_MUTEX_RECURSIVE 1
-** <li> SQLITE_MUTEX_STATIC_MASTER 2
-** <li> SQLITE_MUTEX_STATIC_MEM 3
-** <li> SQLITE_MUTEX_STATIC_PRNG 4
-** </ul>
-**
-** The first two constants cause sqlite3_mutex_alloc() to create
-** a new mutex. The new mutex is recursive when SQLITE_MUTEX_RECURSIVE
-** is used but not necessarily so when SQLITE_MUTEX_FAST is used.
-** The mutex implementation does not need to make a distinction
-** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does
-** not want to. But SQLite will only request a recursive mutex in
-** cases where it really needs one. If a faster non-recursive mutex
-** implementation is available on the host platform, the mutex subsystem
-** might return such a mutex in response to SQLITE_MUTEX_FAST.
-**
-** The other allowed parameters to sqlite3_mutex_alloc() each return
-** a pointer to a static preexisting mutex. Three static mutexes are
-** used by the current version of SQLite. Future versions of SQLite
-** may add additional static mutexes. Static mutexes are for internal
-** use by SQLite only. Applications that use SQLite mutexes should
-** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or
-** SQLITE_MUTEX_RECURSIVE.
-**
-** Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST
-** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc()
-** returns a different mutex on every call. But for the static
-** mutex types, the same mutex is returned on every call that has
-** the same type number.
-*/
-static sqlite3_mutex *os2MutexAlloc(int iType){
- sqlite3_mutex *p = NULL;
- switch( iType ){
- case SQLITE_MUTEX_FAST:
- case SQLITE_MUTEX_RECURSIVE: {
- p = sqlite3MallocZero( sizeof(*p) );
- if( p ){
- p->id = iType;
- if( DosCreateMutexSem( 0, &p->mutex, 0, FALSE ) != NO_ERROR ){
- sqlite3_free( p );
- p = NULL;
- }
- }
- break;
- }
- default: {
- static volatile int isInit = 0;
- static sqlite3_mutex staticMutexes[] = {
- { OS2_MUTEX_INITIALIZER, },
- { OS2_MUTEX_INITIALIZER, },
- { OS2_MUTEX_INITIALIZER, },
- { OS2_MUTEX_INITIALIZER, },
- { OS2_MUTEX_INITIALIZER, },
- { OS2_MUTEX_INITIALIZER, },
- };
- if ( !isInit ){
- APIRET rc;
- PTIB ptib;
- PPIB ppib;
- HMTX mutex;
- char name[32];
- DosGetInfoBlocks( &ptib, &ppib );
- sqlite3_snprintf( sizeof(name), name, "\\SEM32\\SQLITE%04x",
- ppib->pib_ulpid );
- while( !isInit ){
- mutex = 0;
- rc = DosCreateMutexSem( name, &mutex, 0, FALSE);
- if( rc == NO_ERROR ){
- unsigned int i;
- if( !isInit ){
- for( i = 0; i < sizeof(staticMutexes)/sizeof(staticMutexes[0]); i++ ){
- DosCreateMutexSem( 0, &staticMutexes[i].mutex, 0, FALSE );
- }
- isInit = 1;
- }
- DosCloseMutexSem( mutex );
- }else if( rc == ERROR_DUPLICATE_NAME ){
- DosSleep( 1 );
- }else{
- return p;
- }
- }
- }
- assert( iType-2 >= 0 );
- assert( iType-2 < sizeof(staticMutexes)/sizeof(staticMutexes[0]) );
- p = &staticMutexes[iType-2];
- p->id = iType;
- break;
- }
- }
- return p;
-}
-
-
-/*
-** This routine deallocates a previously allocated mutex.
-** SQLite is careful to deallocate every mutex that it allocates.
-*/
-static void os2MutexFree(sqlite3_mutex *p){
- if( p==0 ) return;
- assert( p->nRef==0 );
- assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE );
- DosCloseMutexSem( p->mutex );
- sqlite3_free( p );
-}
-
-/*
-** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt
-** to enter a mutex. If another thread is already within the mutex,
-** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return
-** SQLITE_BUSY. The sqlite3_mutex_try() interface returns SQLITE_OK
-** upon successful entry. Mutexes created using SQLITE_MUTEX_RECURSIVE can
-** be entered multiple times by the same thread. In such cases the,
-** mutex must be exited an equal number of times before another thread
-** can enter. If the same thread tries to enter any other kind of mutex
-** more than once, the behavior is undefined.
-*/
-static void os2MutexEnter(sqlite3_mutex *p){
- TID tid;
- PID holder1;
- ULONG holder2;
- if( p==0 ) return;
- assert( p->id==SQLITE_MUTEX_RECURSIVE || os2MutexNotheld(p) );
- DosRequestMutexSem(p->mutex, SEM_INDEFINITE_WAIT);
- DosQueryMutexSem(p->mutex, &holder1, &tid, &holder2);
- p->owner = tid;
- p->nRef++;
-}
-static int os2MutexTry(sqlite3_mutex *p){
- int rc;
- TID tid;
- PID holder1;
- ULONG holder2;
- if( p==0 ) return SQLITE_OK;
- assert( p->id==SQLITE_MUTEX_RECURSIVE || os2MutexNotheld(p) );
- if( DosRequestMutexSem(p->mutex, SEM_IMMEDIATE_RETURN) == NO_ERROR) {
- DosQueryMutexSem(p->mutex, &holder1, &tid, &holder2);
- p->owner = tid;
- p->nRef++;
- rc = SQLITE_OK;
- } else {
- rc = SQLITE_BUSY;
- }
-
- return rc;
-}
-
-/*
-** The sqlite3_mutex_leave() routine exits a mutex that was
-** previously entered by the same thread. The behavior
-** is undefined if the mutex is not currently entered or
-** is not currently allocated. SQLite will never do either.
-*/
-static void os2MutexLeave(sqlite3_mutex *p){
- TID tid;
- PID holder1;
- ULONG holder2;
- if( p==0 ) return;
- assert( p->nRef>0 );
- DosQueryMutexSem(p->mutex, &holder1, &tid, &holder2);
- assert( p->owner==tid );
- p->nRef--;
- assert( p->nRef==0 || p->id==SQLITE_MUTEX_RECURSIVE );
- DosReleaseMutexSem(p->mutex);
-}
-
-#ifdef SQLITE_DEBUG
-/*
-** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
-** intended for use inside assert() statements.
-*/
-static int os2MutexHeld(sqlite3_mutex *p){
- TID tid;
- PID pid;
- ULONG ulCount;
- PTIB ptib;
- if( p!=0 ) {
- DosQueryMutexSem(p->mutex, &pid, &tid, &ulCount);
- } else {
- DosGetInfoBlocks(&ptib, NULL);
- tid = ptib->tib_ptib2->tib2_ultid;
- }
- return p==0 || (p->nRef!=0 && p->owner==tid);
-}
-static int os2MutexNotheld(sqlite3_mutex *p){
- TID tid;
- PID pid;
- ULONG ulCount;
- PTIB ptib;
- if( p!= 0 ) {
- DosQueryMutexSem(p->mutex, &pid, &tid, &ulCount);
- } else {
- DosGetInfoBlocks(&ptib, NULL);
- tid = ptib->tib_ptib2->tib2_ultid;
- }
- return p==0 || p->nRef==0 || p->owner!=tid;
-}
-#endif
-
-SQLITE_PRIVATE sqlite3_mutex_methods *sqlite3DefaultMutex(void){
- static sqlite3_mutex_methods sMutex = {
- os2MutexInit,
- os2MutexEnd,
- os2MutexAlloc,
- os2MutexFree,
- os2MutexEnter,
- os2MutexTry,
- os2MutexLeave,
-#ifdef SQLITE_DEBUG
- os2MutexHeld,
- os2MutexNotheld
-#endif
- };
-
- return &sMutex;
-}
-#endif /* SQLITE_MUTEX_OS2 */
-
-/************** End of mutex_os2.c *******************************************/
-/************** Begin file mutex_unix.c **************************************/
-/*
-** 2007 August 28
-**
-** 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 C functions that implement mutexes for pthreads
-**
-** $Id: mutex_unix.c,v 1.16 2008/12/08 18:19:18 drh Exp $
-*/
-
-/*
-** The code in this file is only used if we are compiling threadsafe
-** under unix with pthreads.
-**
-** Note that this implementation requires a version of pthreads that
-** supports recursive mutexes.
-*/
-#ifdef SQLITE_MUTEX_PTHREADS
-
-#include <pthread.h>
-
-
-/*
-** Each recursive mutex is an instance of the following structure.
-*/
-struct sqlite3_mutex {
- pthread_mutex_t mutex; /* Mutex controlling the lock */
- int id; /* Mutex type */
- int nRef; /* Number of entrances */
- pthread_t owner; /* Thread that is within this mutex */
-#ifdef SQLITE_DEBUG
- int trace; /* True to trace changes */
-#endif
-};
-#ifdef SQLITE_DEBUG
-#define SQLITE3_MUTEX_INITIALIZER { PTHREAD_MUTEX_INITIALIZER, 0, 0, (pthread_t)0, 0 }
-#else
-#define SQLITE3_MUTEX_INITIALIZER { PTHREAD_MUTEX_INITIALIZER, 0, 0, (pthread_t)0 }
-#endif
-
-/*
-** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
-** intended for use only inside assert() statements. On some platforms,
-** there might be race conditions that can cause these routines to
-** deliver incorrect results. In particular, if pthread_equal() is
-** not an atomic operation, then these routines might delivery
-** incorrect results. On most platforms, pthread_equal() is a
-** comparison of two integers and is therefore atomic. But we are
-** told that HPUX is not such a platform. If so, then these routines
-** will not always work correctly on HPUX.
-**
-** On those platforms where pthread_equal() is not atomic, SQLite
-** should be compiled without -DSQLITE_DEBUG and with -DNDEBUG to
-** make sure no assert() statements are evaluated and hence these
-** routines are never called.
-*/
-#if !defined(NDEBUG) || defined(SQLITE_DEBUG)
-static int pthreadMutexHeld(sqlite3_mutex *p){
- return (p->nRef!=0 && pthread_equal(p->owner, pthread_self()));
-}
-static int pthreadMutexNotheld(sqlite3_mutex *p){
- return p->nRef==0 || pthread_equal(p->owner, pthread_self())==0;
-}
-#endif
-
-/*
-** Initialize and deinitialize the mutex subsystem.
-*/
-static int pthreadMutexInit(void){ return SQLITE_OK; }
-static int pthreadMutexEnd(void){ return SQLITE_OK; }
-
-/*
-** The sqlite3_mutex_alloc() routine allocates a new
-** mutex and returns a pointer to it. If it returns NULL
-** that means that a mutex could not be allocated. SQLite
-** will unwind its stack and return an error. The argument
-** to sqlite3_mutex_alloc() is one of these integer constants:
-**
-** <ul>
-** <li> SQLITE_MUTEX_FAST
-** <li> SQLITE_MUTEX_RECURSIVE
-** <li> SQLITE_MUTEX_STATIC_MASTER
-** <li> SQLITE_MUTEX_STATIC_MEM
-** <li> SQLITE_MUTEX_STATIC_MEM2
-** <li> SQLITE_MUTEX_STATIC_PRNG
-** <li> SQLITE_MUTEX_STATIC_LRU
-** <li> SQLITE_MUTEX_STATIC_LRU2
-** </ul>
-**
-** The first two constants cause sqlite3_mutex_alloc() to create
-** a new mutex. The new mutex is recursive when SQLITE_MUTEX_RECURSIVE
-** is used but not necessarily so when SQLITE_MUTEX_FAST is used.
-** The mutex implementation does not need to make a distinction
-** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does
-** not want to. But SQLite will only request a recursive mutex in
-** cases where it really needs one. If a faster non-recursive mutex
-** implementation is available on the host platform, the mutex subsystem
-** might return such a mutex in response to SQLITE_MUTEX_FAST.
-**
-** The other allowed parameters to sqlite3_mutex_alloc() each return
-** a pointer to a static preexisting mutex. Six static mutexes are
-** used by the current version of SQLite. Future versions of SQLite
-** may add additional static mutexes. Static mutexes are for internal
-** use by SQLite only. Applications that use SQLite mutexes should
-** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or
-** SQLITE_MUTEX_RECURSIVE.
-**
-** Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST
-** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc()
-** returns a different mutex on every call. But for the static
-** mutex types, the same mutex is returned on every call that has
-** the same type number.
-*/
-static sqlite3_mutex *pthreadMutexAlloc(int iType){
- static sqlite3_mutex staticMutexes[] = {
- SQLITE3_MUTEX_INITIALIZER,
- SQLITE3_MUTEX_INITIALIZER,
- SQLITE3_MUTEX_INITIALIZER,
- SQLITE3_MUTEX_INITIALIZER,
- SQLITE3_MUTEX_INITIALIZER,
- SQLITE3_MUTEX_INITIALIZER
- };
- sqlite3_mutex *p;
- switch( iType ){
- case SQLITE_MUTEX_RECURSIVE: {
- p = sqlite3MallocZero( sizeof(*p) );
- if( p ){
-#ifdef SQLITE_HOMEGROWN_RECURSIVE_MUTEX
- /* If recursive mutexes are not available, we will have to
- ** build our own. See below. */
- pthread_mutex_init(&p->mutex, 0);
-#else
- /* Use a recursive mutex if it is available */
- pthread_mutexattr_t recursiveAttr;
- pthread_mutexattr_init(&recursiveAttr);
- pthread_mutexattr_settype(&recursiveAttr, PTHREAD_MUTEX_RECURSIVE);
- pthread_mutex_init(&p->mutex, &recursiveAttr);
- pthread_mutexattr_destroy(&recursiveAttr);
-#endif
- p->id = iType;
- }
- break;
- }
- case SQLITE_MUTEX_FAST: {
- p = sqlite3MallocZero( sizeof(*p) );
- if( p ){
- p->id = iType;
- pthread_mutex_init(&p->mutex, 0);
- }
- break;
- }
- default: {
- assert( iType-2 >= 0 );
- assert( iType-2 < ArraySize(staticMutexes) );
- p = &staticMutexes[iType-2];
- p->id = iType;
- break;
- }
- }
- return p;
-}
-
-
-/*
-** This routine deallocates a previously
-** allocated mutex. SQLite is careful to deallocate every
-** mutex that it allocates.
-*/
-static void pthreadMutexFree(sqlite3_mutex *p){
- assert( p->nRef==0 );
- assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE );
- pthread_mutex_destroy(&p->mutex);
- sqlite3_free(p);
-}
-
-/*
-** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt
-** to enter a mutex. If another thread is already within the mutex,
-** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return
-** SQLITE_BUSY. The sqlite3_mutex_try() interface returns SQLITE_OK
-** upon successful entry. Mutexes created using SQLITE_MUTEX_RECURSIVE can
-** be entered multiple times by the same thread. In such cases the,
-** mutex must be exited an equal number of times before another thread
-** can enter. If the same thread tries to enter any other kind of mutex
-** more than once, the behavior is undefined.
-*/
-static void pthreadMutexEnter(sqlite3_mutex *p){
- assert( p->id==SQLITE_MUTEX_RECURSIVE || pthreadMutexNotheld(p) );
-
-#ifdef SQLITE_HOMEGROWN_RECURSIVE_MUTEX
- /* If recursive mutexes are not available, then we have to grow
- ** our own. This implementation assumes that pthread_equal()
- ** is atomic - that it cannot be deceived into thinking self
- ** and p->owner are equal if p->owner changes between two values
- ** that are not equal to self while the comparison is taking place.
- ** This implementation also assumes a coherent cache - that
- ** separate processes cannot read different values from the same
- ** address at the same time. If either of these two conditions
- ** are not met, then the mutexes will fail and problems will result.
- */
- {
- pthread_t self = pthread_self();
- if( p->nRef>0 && pthread_equal(p->owner, self) ){
- p->nRef++;
- }else{
- pthread_mutex_lock(&p->mutex);
- assert( p->nRef==0 );
- p->owner = self;
- p->nRef = 1;
- }
- }
-#else
- /* Use the built-in recursive mutexes if they are available.
- */
- pthread_mutex_lock(&p->mutex);
- p->owner = pthread_self();
- p->nRef++;
-#endif
-
-#ifdef SQLITE_DEBUG
- if( p->trace ){
- printf("enter mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef);
- }
-#endif
-}
-static int pthreadMutexTry(sqlite3_mutex *p){
- int rc;
- assert( p->id==SQLITE_MUTEX_RECURSIVE || pthreadMutexNotheld(p) );
-
-#ifdef SQLITE_HOMEGROWN_RECURSIVE_MUTEX
- /* If recursive mutexes are not available, then we have to grow
- ** our own. This implementation assumes that pthread_equal()
- ** is atomic - that it cannot be deceived into thinking self
- ** and p->owner are equal if p->owner changes between two values
- ** that are not equal to self while the comparison is taking place.
- ** This implementation also assumes a coherent cache - that
- ** separate processes cannot read different values from the same
- ** address at the same time. If either of these two conditions
- ** are not met, then the mutexes will fail and problems will result.
- */
- {
- pthread_t self = pthread_self();
- if( p->nRef>0 && pthread_equal(p->owner, self) ){
- p->nRef++;
- rc = SQLITE_OK;
- }else if( pthread_mutex_trylock(&p->mutex)==0 ){
- assert( p->nRef==0 );
- p->owner = self;
- p->nRef = 1;
- rc = SQLITE_OK;
- }else{
- rc = SQLITE_BUSY;
- }
- }
-#else
- /* Use the built-in recursive mutexes if they are available.
- */
- if( pthread_mutex_trylock(&p->mutex)==0 ){
- p->owner = pthread_self();
- p->nRef++;
- rc = SQLITE_OK;
- }else{
- rc = SQLITE_BUSY;
- }
-#endif
-
-#ifdef SQLITE_DEBUG
- if( rc==SQLITE_OK && p->trace ){
- printf("enter mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef);
- }
-#endif
- return rc;
-}
-
-/*
-** The sqlite3_mutex_leave() routine exits a mutex that was
-** previously entered by the same thread. The behavior
-** is undefined if the mutex is not currently entered or
-** is not currently allocated. SQLite will never do either.
-*/
-static void pthreadMutexLeave(sqlite3_mutex *p){
- assert( pthreadMutexHeld(p) );
- p->nRef--;
- assert( p->nRef==0 || p->id==SQLITE_MUTEX_RECURSIVE );
-
-#ifdef SQLITE_HOMEGROWN_RECURSIVE_MUTEX
- if( p->nRef==0 ){
- pthread_mutex_unlock(&p->mutex);
- }
-#else
- pthread_mutex_unlock(&p->mutex);
-#endif
-
-#ifdef SQLITE_DEBUG
- if( p->trace ){
- printf("leave mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef);
- }
-#endif
-}
-
-SQLITE_PRIVATE sqlite3_mutex_methods *sqlite3DefaultMutex(void){
- static sqlite3_mutex_methods sMutex = {
- pthreadMutexInit,
- pthreadMutexEnd,
- pthreadMutexAlloc,
- pthreadMutexFree,
- pthreadMutexEnter,
- pthreadMutexTry,
- pthreadMutexLeave,
-#ifdef SQLITE_DEBUG
- pthreadMutexHeld,
- pthreadMutexNotheld
-#else
- 0,
- 0
-#endif
- };
-
- return &sMutex;
-}
-
-#endif /* SQLITE_MUTEX_PTHREAD */
-
-/************** End of mutex_unix.c ******************************************/
-/************** Begin file mutex_w32.c ***************************************/
-/*
-** 2007 August 14
-**
-** 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 C functions that implement mutexes for win32
-**
-** $Id: mutex_w32.c,v 1.18 2009/08/10 03:23:21 shane Exp $
-*/
-
-/*
-** The code in this file is only used if we are compiling multithreaded
-** on a win32 system.
-*/
-#ifdef SQLITE_MUTEX_W32
-
-/*
-** Each recursive mutex is an instance of the following structure.
-*/
-struct sqlite3_mutex {
- CRITICAL_SECTION mutex; /* Mutex controlling the lock */
- int id; /* Mutex type */
- int nRef; /* Number of enterances */
- DWORD owner; /* Thread holding this mutex */
-};
-
-/*
-** Return true (non-zero) if we are running under WinNT, Win2K, WinXP,
-** or WinCE. Return false (zero) for Win95, Win98, or WinME.
-**
-** Here is an interesting observation: Win95, Win98, and WinME lack
-** the LockFileEx() API. But we can still statically link against that
-** API as long as we don't call it win running Win95/98/ME. A call to
-** this routine is used to determine if the host is Win95/98/ME or
-** WinNT/2K/XP so that we will know whether or not we can safely call
-** the LockFileEx() API.
-**
-** mutexIsNT() is only used for the TryEnterCriticalSection() API call,
-** which is only available if your application was compiled with
-** _WIN32_WINNT defined to a value >= 0x0400. Currently, the only
-** call to TryEnterCriticalSection() is #ifdef'ed out, so #ifdef
-** this out as well.
-*/
-#if 0
-#if SQLITE_OS_WINCE
-# define mutexIsNT() (1)
-#else
- static int mutexIsNT(void){
- static int osType = 0;
- if( osType==0 ){
- OSVERSIONINFO sInfo;
- sInfo.dwOSVersionInfoSize = sizeof(sInfo);
- GetVersionEx(&sInfo);
- osType = sInfo.dwPlatformId==VER_PLATFORM_WIN32_NT ? 2 : 1;
- }
- return osType==2;
- }
-#endif /* SQLITE_OS_WINCE */
-#endif
-
-#ifdef SQLITE_DEBUG
-/*
-** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
-** intended for use only inside assert() statements.
-*/
-static int winMutexHeld(sqlite3_mutex *p){
- return p->nRef!=0 && p->owner==GetCurrentThreadId();
-}
-static int winMutexNotheld(sqlite3_mutex *p){
- return p->nRef==0 || p->owner!=GetCurrentThreadId();
-}
-#endif
-
-
-/*
-** Initialize and deinitialize the mutex subsystem.
-*/
-static sqlite3_mutex winMutex_staticMutexes[6];
-static int winMutex_isInit = 0;
-/* As winMutexInit() and winMutexEnd() are called as part
-** of the sqlite3_initialize and sqlite3_shutdown()
-** processing, the "interlocked" magic is probably not
-** strictly necessary.
-*/
-static long winMutex_lock = 0;
-
-static int winMutexInit(void){
- /* The first to increment to 1 does actual initialization */
- if( InterlockedCompareExchange(&winMutex_lock, 1, 0)==0 ){
- int i;
- for(i=0; i<ArraySize(winMutex_staticMutexes); i++){
- InitializeCriticalSection(&winMutex_staticMutexes[i].mutex);
- }
- winMutex_isInit = 1;
- }else{
- /* Someone else is in the process of initing the static mutexes */
- while( !winMutex_isInit ){
- Sleep(1);
- }
- }
- return SQLITE_OK;
-}
-
-static int winMutexEnd(void){
- /* The first to decrement to 0 does actual shutdown
- ** (which should be the last to shutdown.) */
- if( InterlockedCompareExchange(&winMutex_lock, 0, 1)==1 ){
- if( winMutex_isInit==1 ){
- int i;
- for(i=0; i<ArraySize(winMutex_staticMutexes); i++){
- DeleteCriticalSection(&winMutex_staticMutexes[i].mutex);
- }
- winMutex_isInit = 0;
- }
- }
- return SQLITE_OK;
-}
-
-/*
-** The sqlite3_mutex_alloc() routine allocates a new
-** mutex and returns a pointer to it. If it returns NULL
-** that means that a mutex could not be allocated. SQLite
-** will unwind its stack and return an error. The argument
-** to sqlite3_mutex_alloc() is one of these integer constants:
-**
-** <ul>
-** <li> SQLITE_MUTEX_FAST
-** <li> SQLITE_MUTEX_RECURSIVE
-** <li> SQLITE_MUTEX_STATIC_MASTER
-** <li> SQLITE_MUTEX_STATIC_MEM
-** <li> SQLITE_MUTEX_STATIC_MEM2
-** <li> SQLITE_MUTEX_STATIC_PRNG
-** <li> SQLITE_MUTEX_STATIC_LRU
-** <li> SQLITE_MUTEX_STATIC_LRU2
-** </ul>
-**
-** The first two constants cause sqlite3_mutex_alloc() to create
-** a new mutex. The new mutex is recursive when SQLITE_MUTEX_RECURSIVE
-** is used but not necessarily so when SQLITE_MUTEX_FAST is used.
-** The mutex implementation does not need to make a distinction
-** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does
-** not want to. But SQLite will only request a recursive mutex in
-** cases where it really needs one. If a faster non-recursive mutex
-** implementation is available on the host platform, the mutex subsystem
-** might return such a mutex in response to SQLITE_MUTEX_FAST.
-**
-** The other allowed parameters to sqlite3_mutex_alloc() each return
-** a pointer to a static preexisting mutex. Six static mutexes are
-** used by the current version of SQLite. Future versions of SQLite
-** may add additional static mutexes. Static mutexes are for internal
-** use by SQLite only. Applications that use SQLite mutexes should
-** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or
-** SQLITE_MUTEX_RECURSIVE.
-**
-** Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST
-** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc()
-** returns a different mutex on every call. But for the static
-** mutex types, the same mutex is returned on every call that has
-** the same type number.
-*/
-static sqlite3_mutex *winMutexAlloc(int iType){
- sqlite3_mutex *p;
-
- switch( iType ){
- case SQLITE_MUTEX_FAST:
- case SQLITE_MUTEX_RECURSIVE: {
- p = sqlite3MallocZero( sizeof(*p) );
- if( p ){
- p->id = iType;
- InitializeCriticalSection(&p->mutex);
- }
- break;
- }
- default: {
- assert( winMutex_isInit==1 );
- assert( iType-2 >= 0 );
- assert( iType-2 < ArraySize(winMutex_staticMutexes) );
- p = &winMutex_staticMutexes[iType-2];
- p->id = iType;
- break;
- }
- }
- return p;
-}
-
-
-/*
-** This routine deallocates a previously
-** allocated mutex. SQLite is careful to deallocate every
-** mutex that it allocates.
-*/
-static void winMutexFree(sqlite3_mutex *p){
- assert( p );
- assert( p->nRef==0 );
- assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE );
- DeleteCriticalSection(&p->mutex);
- sqlite3_free(p);
-}
-
-/*
-** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt
-** to enter a mutex. If another thread is already within the mutex,
-** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return
-** SQLITE_BUSY. The sqlite3_mutex_try() interface returns SQLITE_OK
-** upon successful entry. Mutexes created using SQLITE_MUTEX_RECURSIVE can
-** be entered multiple times by the same thread. In such cases the,
-** mutex must be exited an equal number of times before another thread
-** can enter. If the same thread tries to enter any other kind of mutex
-** more than once, the behavior is undefined.
-*/
-static void winMutexEnter(sqlite3_mutex *p){
- assert( p->id==SQLITE_MUTEX_RECURSIVE || winMutexNotheld(p) );
- EnterCriticalSection(&p->mutex);
- p->owner = GetCurrentThreadId();
- p->nRef++;
-}
-static int winMutexTry(sqlite3_mutex *p){
- int rc = SQLITE_BUSY;
- assert( p->id==SQLITE_MUTEX_RECURSIVE || winMutexNotheld(p) );
- /*
- ** The sqlite3_mutex_try() routine is very rarely used, and when it
- ** is used it is merely an optimization. So it is OK for it to always
- ** fail.
- **
- ** The TryEnterCriticalSection() interface is only available on WinNT.
- ** And some windows compilers complain if you try to use it without
- ** first doing some #defines that prevent SQLite from building on Win98.
- ** For that reason, we will omit this optimization for now. See
- ** ticket #2685.
- */
-#if 0
- if( mutexIsNT() && TryEnterCriticalSection(&p->mutex) ){
- p->owner = GetCurrentThreadId();
- p->nRef++;
- rc = SQLITE_OK;
- }
-#else
- UNUSED_PARAMETER(p);
-#endif
- return rc;
-}
-
-/*
-** The sqlite3_mutex_leave() routine exits a mutex that was
-** previously entered by the same thread. The behavior
-** is undefined if the mutex is not currently entered or
-** is not currently allocated. SQLite will never do either.
-*/
-static void winMutexLeave(sqlite3_mutex *p){
- assert( p->nRef>0 );
- assert( p->owner==GetCurrentThreadId() );
- p->nRef--;
- assert( p->nRef==0 || p->id==SQLITE_MUTEX_RECURSIVE );
- LeaveCriticalSection(&p->mutex);
-}
-
-SQLITE_PRIVATE sqlite3_mutex_methods *sqlite3DefaultMutex(void){
- static sqlite3_mutex_methods sMutex = {
- winMutexInit,
- winMutexEnd,
- winMutexAlloc,
- winMutexFree,
- winMutexEnter,
- winMutexTry,
- winMutexLeave,
-#ifdef SQLITE_DEBUG
- winMutexHeld,
- winMutexNotheld
-#else
- 0,
- 0
-#endif
- };
-
- return &sMutex;
-}
-#endif /* SQLITE_MUTEX_W32 */
-
-/************** End of mutex_w32.c *******************************************/
-/************** Begin file malloc.c ******************************************/
-/*
-** 2001 September 15
-**
-** 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.
-**
-*************************************************************************
-**
-** Memory allocation functions used throughout sqlite.
-**
-** $Id: malloc.c,v 1.66 2009/07/17 11:44:07 drh Exp $
-*/
-
-/*
-** This routine runs when the memory allocator sees that the
-** total memory allocation is about to exceed the soft heap
-** limit.
-*/
-static void softHeapLimitEnforcer(
- void *NotUsed,
- sqlite3_int64 NotUsed2,
- int allocSize
-){
- UNUSED_PARAMETER2(NotUsed, NotUsed2);
- sqlite3_release_memory(allocSize);
-}
-
-/*
-** Set the soft heap-size limit for the library. Passing a zero or
-** negative value indicates no limit.
-*/
-SQLITE_API void sqlite3_soft_heap_limit(int n){
- sqlite3_uint64 iLimit;
- int overage;
- if( n<0 ){
- iLimit = 0;
- }else{
- iLimit = n;
- }
-#ifndef SQLITE_OMIT_AUTOINIT
- sqlite3_initialize();
-#endif
- if( iLimit>0 ){
- sqlite3MemoryAlarm(softHeapLimitEnforcer, 0, iLimit);
- }else{
- sqlite3MemoryAlarm(0, 0, 0);
- }
- overage = (int)(sqlite3_memory_used() - (i64)n);
- if( overage>0 ){
- sqlite3_release_memory(overage);
- }
-}
-
-/*
-** Attempt to release up to n bytes of non-essential memory currently
-** held by SQLite. An example of non-essential memory is memory used to
-** cache database pages that are not currently in use.
-*/
-SQLITE_API int sqlite3_release_memory(int n){
-#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
- int nRet = 0;
-#if 0
- nRet += sqlite3VdbeReleaseMemory(n);
-#endif
- nRet += sqlite3PcacheReleaseMemory(n-nRet);
- return nRet;
-#else
- UNUSED_PARAMETER(n);
- return SQLITE_OK;
-#endif
-}
-
-/*
-** State information local to the memory allocation subsystem.
-*/
-static SQLITE_WSD struct Mem0Global {
- /* Number of free pages for scratch and page-cache memory */
- u32 nScratchFree;
- u32 nPageFree;
-
- sqlite3_mutex *mutex; /* Mutex to serialize access */
-
- /*
- ** The alarm callback and its arguments. The mem0.mutex lock will
- ** be held while the callback is running. Recursive calls into
- ** the memory subsystem are allowed, but no new callbacks will be
- ** issued.
- */
- sqlite3_int64 alarmThreshold;
- void (*alarmCallback)(void*, sqlite3_int64,int);
- void *alarmArg;
-
- /*
- ** Pointers to the end of sqlite3GlobalConfig.pScratch and
- ** sqlite3GlobalConfig.pPage to a block of memory that records
- ** which pages are available.
- */
- u32 *aScratchFree;
- u32 *aPageFree;
-} mem0 = { 0, 0, 0, 0, 0, 0, 0, 0 };
-
-#define mem0 GLOBAL(struct Mem0Global, mem0)
-
-/*
-** Initialize the memory allocation subsystem.
-*/
-SQLITE_PRIVATE int sqlite3MallocInit(void){
- if( sqlite3GlobalConfig.m.xMalloc==0 ){
- sqlite3MemSetDefault();
- }
- memset(&mem0, 0, sizeof(mem0));
- if( sqlite3GlobalConfig.bCoreMutex ){
- mem0.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM);
- }
- if( sqlite3GlobalConfig.pScratch && sqlite3GlobalConfig.szScratch>=100
- && sqlite3GlobalConfig.nScratch>=0 ){
- int i;
- sqlite3GlobalConfig.szScratch = ROUNDDOWN8(sqlite3GlobalConfig.szScratch-4);
- mem0.aScratchFree = (u32*)&((char*)sqlite3GlobalConfig.pScratch)
- [sqlite3GlobalConfig.szScratch*sqlite3GlobalConfig.nScratch];
- for(i=0; i<sqlite3GlobalConfig.nScratch; i++){ mem0.aScratchFree[i] = i; }
- mem0.nScratchFree = sqlite3GlobalConfig.nScratch;
- }else{
- sqlite3GlobalConfig.pScratch = 0;
- sqlite3GlobalConfig.szScratch = 0;
- }
- if( sqlite3GlobalConfig.pPage && sqlite3GlobalConfig.szPage>=512
- && sqlite3GlobalConfig.nPage>=1 ){
- int i;
- int overhead;
- int sz = ROUNDDOWN8(sqlite3GlobalConfig.szPage);
- int n = sqlite3GlobalConfig.nPage;
- overhead = (4*n + sz - 1)/sz;
- sqlite3GlobalConfig.nPage -= overhead;
- mem0.aPageFree = (u32*)&((char*)sqlite3GlobalConfig.pPage)
- [sqlite3GlobalConfig.szPage*sqlite3GlobalConfig.nPage];
- for(i=0; i<sqlite3GlobalConfig.nPage; i++){ mem0.aPageFree[i] = i; }
- mem0.nPageFree = sqlite3GlobalConfig.nPage;
- }else{
- sqlite3GlobalConfig.pPage = 0;
- sqlite3GlobalConfig.szPage = 0;
- }
- return sqlite3GlobalConfig.m.xInit(sqlite3GlobalConfig.m.pAppData);
-}
-
-/*
-** Deinitialize the memory allocation subsystem.
-*/
-SQLITE_PRIVATE void sqlite3MallocEnd(void){
- if( sqlite3GlobalConfig.m.xShutdown ){
- sqlite3GlobalConfig.m.xShutdown(sqlite3GlobalConfig.m.pAppData);
- }
- memset(&mem0, 0, sizeof(mem0));
-}
-
-/*
-** Return the amount of memory currently checked out.
-*/
-SQLITE_API sqlite3_int64 sqlite3_memory_used(void){
- int n, mx;
- sqlite3_int64 res;
- sqlite3_status(SQLITE_STATUS_MEMORY_USED, &n, &mx, 0);
- res = (sqlite3_int64)n; /* Work around bug in Borland C. Ticket #3216 */
- return res;
-}
-
-/*
-** Return the maximum amount of memory that has ever been
-** checked out since either the beginning of this process
-** or since the most recent reset.
-*/
-SQLITE_API sqlite3_int64 sqlite3_memory_highwater(int resetFlag){
- int n, mx;
- sqlite3_int64 res;
- sqlite3_status(SQLITE_STATUS_MEMORY_USED, &n, &mx, resetFlag);
- res = (sqlite3_int64)mx; /* Work around bug in Borland C. Ticket #3216 */
- return res;
-}
-
-/*
-** Change the alarm callback
-*/
-SQLITE_PRIVATE int sqlite3MemoryAlarm(
- void(*xCallback)(void *pArg, sqlite3_int64 used,int N),
- void *pArg,
- sqlite3_int64 iThreshold
-){
- sqlite3_mutex_enter(mem0.mutex);
- mem0.alarmCallback = xCallback;
- mem0.alarmArg = pArg;
- mem0.alarmThreshold = iThreshold;
- sqlite3_mutex_leave(mem0.mutex);
- return SQLITE_OK;
-}
-
-#ifndef SQLITE_OMIT_DEPRECATED
-/*
-** Deprecated external interface. Internal/core SQLite code
-** should call sqlite3MemoryAlarm.
-*/
-SQLITE_API int sqlite3_memory_alarm(
- void(*xCallback)(void *pArg, sqlite3_int64 used,int N),
- void *pArg,
- sqlite3_int64 iThreshold
-){
- return sqlite3MemoryAlarm(xCallback, pArg, iThreshold);
-}
-#endif
-
-/*
-** Trigger the alarm
-*/
-static void sqlite3MallocAlarm(int nByte){
- void (*xCallback)(void*,sqlite3_int64,int);
- sqlite3_int64 nowUsed;
- void *pArg;
- if( mem0.alarmCallback==0 ) return;
- xCallback = mem0.alarmCallback;
- nowUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
- pArg = mem0.alarmArg;
- mem0.alarmCallback = 0;
- sqlite3_mutex_leave(mem0.mutex);
- xCallback(pArg, nowUsed, nByte);
- sqlite3_mutex_enter(mem0.mutex);
- mem0.alarmCallback = xCallback;
- mem0.alarmArg = pArg;
-}
-
-/*
-** Do a memory allocation with statistics and alarms. Assume the
-** lock is already held.
-*/
-static int mallocWithAlarm(int n, void **pp){
- int nFull;
- void *p;
- assert( sqlite3_mutex_held(mem0.mutex) );
- nFull = sqlite3GlobalConfig.m.xRoundup(n);
- sqlite3StatusSet(SQLITE_STATUS_MALLOC_SIZE, n);
- if( mem0.alarmCallback!=0 ){
- int nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
- if( nUsed+nFull >= mem0.alarmThreshold ){
- sqlite3MallocAlarm(nFull);
- }
- }
- p = sqlite3GlobalConfig.m.xMalloc(nFull);
- if( p==0 && mem0.alarmCallback ){
- sqlite3MallocAlarm(nFull);
- p = sqlite3GlobalConfig.m.xMalloc(nFull);
- }
- if( p ){
- nFull = sqlite3MallocSize(p);
- sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, nFull);
- }
- *pp = p;
- return nFull;
-}
-
-/*
-** Allocate memory. This routine is like sqlite3_malloc() except that it
-** assumes the memory subsystem has already been initialized.
-*/
-SQLITE_PRIVATE void *sqlite3Malloc(int n){
- void *p;
- if( n<=0 || n>=0x7fffff00 ){
- /* A memory allocation of a number of bytes which is near the maximum
- ** signed integer value might cause an integer overflow inside of the
- ** xMalloc(). Hence we limit the maximum size to 0x7fffff00, giving
- ** 255 bytes of overhead. SQLite itself will never use anything near
- ** this amount. The only way to reach the limit is with sqlite3_malloc() */
- p = 0;
- }else if( sqlite3GlobalConfig.bMemstat ){
- sqlite3_mutex_enter(mem0.mutex);
- mallocWithAlarm(n, &p);
- sqlite3_mutex_leave(mem0.mutex);
- }else{
- p = sqlite3GlobalConfig.m.xMalloc(n);
- }
- return p;
-}
-
-/*
-** This version of the memory allocation is for use by the application.
-** First make sure the memory subsystem is initialized, then do the
-** allocation.
-*/
-SQLITE_API void *sqlite3_malloc(int n){
-#ifndef SQLITE_OMIT_AUTOINIT
- if( sqlite3_initialize() ) return 0;
-#endif
- return sqlite3Malloc(n);
-}
-
-/*
-** Each thread may only have a single outstanding allocation from
-** xScratchMalloc(). We verify this constraint in the single-threaded
-** case by setting scratchAllocOut to 1 when an allocation
-** is outstanding clearing it when the allocation is freed.
-*/
-#if SQLITE_THREADSAFE==0 && !defined(NDEBUG)
-static int scratchAllocOut = 0;
-#endif
-
-
-/*
-** Allocate memory that is to be used and released right away.
-** This routine is similar to alloca() in that it is not intended
-** for situations where the memory might be held long-term. This
-** routine is intended to get memory to old large transient data
-** structures that would not normally fit on the stack of an
-** embedded processor.
-*/
-SQLITE_PRIVATE void *sqlite3ScratchMalloc(int n){
- void *p;
- assert( n>0 );
-
-#if SQLITE_THREADSAFE==0 && !defined(NDEBUG)
- /* Verify that no more than one scratch allocation per thread
- ** is outstanding at one time. (This is only checked in the
- ** single-threaded case since checking in the multi-threaded case
- ** would be much more complicated.) */
- assert( scratchAllocOut==0 );
-#endif
-
- if( sqlite3GlobalConfig.szScratch<n ){
- goto scratch_overflow;
- }else{
- sqlite3_mutex_enter(mem0.mutex);
- if( mem0.nScratchFree==0 ){
- sqlite3_mutex_leave(mem0.mutex);
- goto scratch_overflow;
- }else{
- int i;
- i = mem0.aScratchFree[--mem0.nScratchFree];
- i *= sqlite3GlobalConfig.szScratch;
- sqlite3StatusAdd(SQLITE_STATUS_SCRATCH_USED, 1);
- sqlite3StatusSet(SQLITE_STATUS_SCRATCH_SIZE, n);
- sqlite3_mutex_leave(mem0.mutex);
- p = (void*)&((char*)sqlite3GlobalConfig.pScratch)[i];
- assert( (((u8*)p - (u8*)0) & 7)==0 );
- }
- }
-#if SQLITE_THREADSAFE==0 && !defined(NDEBUG)
- scratchAllocOut = p!=0;
-#endif
-
- return p;
-
-scratch_overflow:
- if( sqlite3GlobalConfig.bMemstat ){
- sqlite3_mutex_enter(mem0.mutex);
- sqlite3StatusSet(SQLITE_STATUS_SCRATCH_SIZE, n);
- n = mallocWithAlarm(n, &p);
- if( p ) sqlite3StatusAdd(SQLITE_STATUS_SCRATCH_OVERFLOW, n);
- sqlite3_mutex_leave(mem0.mutex);
- }else{
- p = sqlite3GlobalConfig.m.xMalloc(n);
- }
-#if SQLITE_THREADSAFE==0 && !defined(NDEBUG)
- scratchAllocOut = p!=0;
-#endif
- return p;
-}
-SQLITE_PRIVATE void sqlite3ScratchFree(void *p){
- if( p ){
-
-#if SQLITE_THREADSAFE==0 && !defined(NDEBUG)
- /* Verify that no more than one scratch allocation per thread
- ** is outstanding at one time. (This is only checked in the
- ** single-threaded case since checking in the multi-threaded case
- ** would be much more complicated.) */
- assert( scratchAllocOut==1 );
- scratchAllocOut = 0;
-#endif
-
- if( sqlite3GlobalConfig.pScratch==0
- || p<sqlite3GlobalConfig.pScratch
- || p>=(void*)mem0.aScratchFree ){
- if( sqlite3GlobalConfig.bMemstat ){
- int iSize = sqlite3MallocSize(p);
- sqlite3_mutex_enter(mem0.mutex);
- sqlite3StatusAdd(SQLITE_STATUS_SCRATCH_OVERFLOW, -iSize);
- sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, -iSize);
- sqlite3GlobalConfig.m.xFree(p);
- sqlite3_mutex_leave(mem0.mutex);
- }else{
- sqlite3GlobalConfig.m.xFree(p);
- }
- }else{
- int i;
- i = (int)((u8*)p - (u8*)sqlite3GlobalConfig.pScratch);
- i /= sqlite3GlobalConfig.szScratch;
- assert( i>=0 && i<sqlite3GlobalConfig.nScratch );
- sqlite3_mutex_enter(mem0.mutex);
- assert( mem0.nScratchFree<(u32)sqlite3GlobalConfig.nScratch );
- mem0.aScratchFree[mem0.nScratchFree++] = i;
- sqlite3StatusAdd(SQLITE_STATUS_SCRATCH_USED, -1);
- sqlite3_mutex_leave(mem0.mutex);
- }
- }
-}
-
-/*
-** TRUE if p is a lookaside memory allocation from db
-*/
-#ifndef SQLITE_OMIT_LOOKASIDE
-static int isLookaside(sqlite3 *db, void *p){
- return db && p && p>=db->lookaside.pStart && p<db->lookaside.pEnd;
-}
-#else
-#define isLookaside(A,B) 0
-#endif
-
-/*
-** Return the size of a memory allocation previously obtained from
-** sqlite3Malloc() or sqlite3_malloc().
-*/
-SQLITE_PRIVATE int sqlite3MallocSize(void *p){
- return sqlite3GlobalConfig.m.xSize(p);
-}
-SQLITE_PRIVATE int sqlite3DbMallocSize(sqlite3 *db, void *p){
- assert( db==0 || sqlite3_mutex_held(db->mutex) );
- if( isLookaside(db, p) ){
- return db->lookaside.sz;
- }else{
- return sqlite3GlobalConfig.m.xSize(p);
- }
-}
-
-/*
-** Free memory previously obtained from sqlite3Malloc().
-*/
-SQLITE_API void sqlite3_free(void *p){
- if( p==0 ) return;
- if( sqlite3GlobalConfig.bMemstat ){
- sqlite3_mutex_enter(mem0.mutex);
- sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, -sqlite3MallocSize(p));
- sqlite3GlobalConfig.m.xFree(p);
- sqlite3_mutex_leave(mem0.mutex);
- }else{
- sqlite3GlobalConfig.m.xFree(p);
- }
-}
-
-/*
-** Free memory that might be associated with a particular database
-** connection.
-*/
-SQLITE_PRIVATE void sqlite3DbFree(sqlite3 *db, void *p){
- assert( db==0 || sqlite3_mutex_held(db->mutex) );
- if( isLookaside(db, p) ){
- LookasideSlot *pBuf = (LookasideSlot*)p;
- pBuf->pNext = db->lookaside.pFree;
- db->lookaside.pFree = pBuf;
- db->lookaside.nOut--;
- }else{
- sqlite3_free(p);
- }
-}
-
-/*
-** Change the size of an existing memory allocation
-*/
-SQLITE_PRIVATE void *sqlite3Realloc(void *pOld, int nBytes){
- int nOld, nNew;
- void *pNew;
- if( pOld==0 ){
- return sqlite3Malloc(nBytes);
- }
- if( nBytes<=0 ){
- sqlite3_free(pOld);
- return 0;
- }
- if( nBytes>=0x7fffff00 ){
- /* The 0x7ffff00 limit term is explained in comments on sqlite3Malloc() */
- return 0;
- }
- nOld = sqlite3MallocSize(pOld);
- nNew = sqlite3GlobalConfig.m.xRoundup(nBytes);
- if( nOld==nNew ){
- pNew = pOld;
- }else if( sqlite3GlobalConfig.bMemstat ){
- sqlite3_mutex_enter(mem0.mutex);
- sqlite3StatusSet(SQLITE_STATUS_MALLOC_SIZE, nBytes);
- if( sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED)+nNew-nOld >=
- mem0.alarmThreshold ){
- sqlite3MallocAlarm(nNew-nOld);
- }
- pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew);
- if( pNew==0 && mem0.alarmCallback ){
- sqlite3MallocAlarm(nBytes);
- pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew);
- }
- if( pNew ){
- nNew = sqlite3MallocSize(pNew);
- sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, nNew-nOld);
- }
- sqlite3_mutex_leave(mem0.mutex);
- }else{
- pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew);
- }
- return pNew;
-}
-
-/*
-** The public interface to sqlite3Realloc. Make sure that the memory
-** subsystem is initialized prior to invoking sqliteRealloc.
-*/
-SQLITE_API void *sqlite3_realloc(void *pOld, int n){
-#ifndef SQLITE_OMIT_AUTOINIT
- if( sqlite3_initialize() ) return 0;
-#endif
- return sqlite3Realloc(pOld, n);
-}
-
-
-/*
-** Allocate and zero memory.
-*/
-SQLITE_PRIVATE void *sqlite3MallocZero(int n){
- void *p = sqlite3Malloc(n);
- if( p ){
- memset(p, 0, n);
- }
- return p;
-}
-
-/*
-** Allocate and zero memory. If the allocation fails, make
-** the mallocFailed flag in the connection pointer.
-*/
-SQLITE_PRIVATE void *sqlite3DbMallocZero(sqlite3 *db, int n){
- void *p = sqlite3DbMallocRaw(db, n);
- if( p ){
- memset(p, 0, n);
- }
- return p;
-}
-
-/*
-** Allocate and zero memory. If the allocation fails, make
-** the mallocFailed flag in the connection pointer.
-**
-** If db!=0 and db->mallocFailed is true (indicating a prior malloc
-** failure on the same database connection) then always return 0.
-** Hence for a particular database connection, once malloc starts
-** failing, it fails consistently until mallocFailed is reset.
-** This is an important assumption. There are many places in the
-** code that do things like this:
-**
-** int *a = (int*)sqlite3DbMallocRaw(db, 100);
-** int *b = (int*)sqlite3DbMallocRaw(db, 200);
-** if( b ) a[10] = 9;
-**
-** In other words, if a subsequent malloc (ex: "b") worked, it is assumed
-** that all prior mallocs (ex: "a") worked too.
-*/
-SQLITE_PRIVATE void *sqlite3DbMallocRaw(sqlite3 *db, int n){
- void *p;
- assert( db==0 || sqlite3_mutex_held(db->mutex) );
-#ifndef SQLITE_OMIT_LOOKASIDE
- if( db ){
- LookasideSlot *pBuf;
- if( db->mallocFailed ){
- return 0;
- }
- if( db->lookaside.bEnabled && n<=db->lookaside.sz
- && (pBuf = db->lookaside.pFree)!=0 ){
- db->lookaside.pFree = pBuf->pNext;
- db->lookaside.nOut++;
- if( db->lookaside.nOut>db->lookaside.mxOut ){
- db->lookaside.mxOut = db->lookaside.nOut;
- }
- return (void*)pBuf;
- }
- }
-#else
- if( db && db->mallocFailed ){
- return 0;
- }
-#endif
- p = sqlite3Malloc(n);
- if( !p && db ){
- db->mallocFailed = 1;
- }
- return p;
-}
-
-/*
-** Resize the block of memory pointed to by p to n bytes. If the
-** resize fails, set the mallocFailed flag in the connection object.
-*/
-SQLITE_PRIVATE void *sqlite3DbRealloc(sqlite3 *db, void *p, int n){
- void *pNew = 0;
- assert( db!=0 );
- assert( sqlite3_mutex_held(db->mutex) );
- if( db->mallocFailed==0 ){
- if( p==0 ){
- return sqlite3DbMallocRaw(db, n);
- }
- if( isLookaside(db, p) ){
- if( n<=db->lookaside.sz ){
- return p;
- }
- pNew = sqlite3DbMallocRaw(db, n);
- if( pNew ){
- memcpy(pNew, p, db->lookaside.sz);
- sqlite3DbFree(db, p);
- }
- }else{
- pNew = sqlite3_realloc(p, n);
- if( !pNew ){
- db->mallocFailed = 1;
- }
- }
- }
- return pNew;
-}
-
-/*
-** Attempt to reallocate p. If the reallocation fails, then free p
-** and set the mallocFailed flag in the database connection.
-*/
-SQLITE_PRIVATE void *sqlite3DbReallocOrFree(sqlite3 *db, void *p, int n){
- void *pNew;
- pNew = sqlite3DbRealloc(db, p, n);
- if( !pNew ){
- sqlite3DbFree(db, p);
- }
- return pNew;
-}
-
-/*
-** Make a copy of a string in memory obtained from sqliteMalloc(). These
-** functions call sqlite3MallocRaw() directly instead of sqliteMalloc(). This
-** is because when memory debugging is turned on, these two functions are
-** called via macros that record the current file and line number in the
-** ThreadData structure.
-*/
-SQLITE_PRIVATE char *sqlite3DbStrDup(sqlite3 *db, const char *z){
- char *zNew;
- size_t n;
- if( z==0 ){
- return 0;
- }
- n = sqlite3Strlen30(z) + 1;
- assert( (n&0x7fffffff)==n );
- zNew = sqlite3DbMallocRaw(db, (int)n);
- if( zNew ){
- memcpy(zNew, z, n);
- }
- return zNew;
-}
-SQLITE_PRIVATE char *sqlite3DbStrNDup(sqlite3 *db, const char *z, int n){
- char *zNew;
- if( z==0 ){
- return 0;
- }
- assert( (n&0x7fffffff)==n );
- zNew = sqlite3DbMallocRaw(db, n+1);
- if( zNew ){
- memcpy(zNew, z, n);
- zNew[n] = 0;
- }
- return zNew;
-}
-
-/*
-** Create a string from the zFromat argument and the va_list that follows.
-** Store the string in memory obtained from sqliteMalloc() and make *pz
-** point to that string.
-*/
-SQLITE_PRIVATE void sqlite3SetString(char **pz, sqlite3 *db, const char *zFormat, ...){
- va_list ap;
- char *z;
-
- va_start(ap, zFormat);
- z = sqlite3VMPrintf(db, zFormat, ap);
- va_end(ap);
- sqlite3DbFree(db, *pz);
- *pz = z;
-}
-
-
-/*
-** This function must be called before exiting any API function (i.e.
-** returning control to the user) that has called sqlite3_malloc or
-** sqlite3_realloc.
-**
-** The returned value is normally a copy of the second argument to this
-** function. However, if a malloc() failure has occurred since the previous
-** invocation SQLITE_NOMEM is returned instead.
-**
-** If the first argument, db, is not NULL and a malloc() error has occurred,
-** then the connection error-code (the value returned by sqlite3_errcode())
-** is set to SQLITE_NOMEM.
-*/
-SQLITE_PRIVATE int sqlite3ApiExit(sqlite3* db, int rc){
- /* If the db handle is not NULL, then we must hold the connection handle
- ** mutex here. Otherwise the read (and possible write) of db->mallocFailed
- ** is unsafe, as is the call to sqlite3Error().
- */
- assert( !db || sqlite3_mutex_held(db->mutex) );
- if( db && (db->mallocFailed || rc==SQLITE_IOERR_NOMEM) ){
- sqlite3Error(db, SQLITE_NOMEM, 0);
- db->mallocFailed = 0;
- rc = SQLITE_NOMEM;
- }
- return rc & (db ? db->errMask : 0xff);
-}
-
-/************** End of malloc.c **********************************************/
-/************** Begin file printf.c ******************************************/
-/*
-** The "printf" code that follows dates from the 1980's. It is in
-** the public domain. The original comments are included here for
-** completeness. They are very out-of-date but might be useful as
-** an historical reference. Most of the "enhancements" have been backed
-** out so that the functionality is now the same as standard printf().
-**
-** $Id: printf.c,v 1.104 2009/06/03 01:24:54 drh Exp $
-**
-**************************************************************************
-**
-** The following modules is an enhanced replacement for the "printf" subroutines
-** found in the standard C library. The following enhancements are
-** supported:
-**
-** + Additional functions. The standard set of "printf" functions
-** includes printf, fprintf, sprintf, vprintf, vfprintf, and
-** vsprintf. This module adds the following:
-**
-** * snprintf -- Works like sprintf, but has an extra argument
-** which is the size of the buffer written to.
-**
-** * mprintf -- Similar to sprintf. Writes output to memory
-** obtained from malloc.
-**
-** * xprintf -- Calls a function to dispose of output.
-**
-** * nprintf -- No output, but returns the number of characters
-** that would have been output by printf.
-**
-** * A v- version (ex: vsnprintf) of every function is also
-** supplied.
-**
-** + A few extensions to the formatting notation are supported:
-**
-** * The "=" flag (similar to "-") causes the output to be
-** be centered in the appropriately sized field.
-**
-** * The %b field outputs an integer in binary notation.
-**
-** * The %c field now accepts a precision. The character output
-** is repeated by the number of times the precision specifies.
-**
-** * The %' field works like %c, but takes as its character the
-** next character of the format string, instead of the next
-** argument. For example, printf("%.78'-") prints 78 minus
-** signs, the same as printf("%.78c",'-').
-**
-** + When compiled using GCC on a SPARC, this version of printf is
-** faster than the library printf for SUN OS 4.1.
-**
-** + All functions are fully reentrant.
-**
-*/
-
-/*
-** Conversion types fall into various categories as defined by the
-** following enumeration.
-*/
-#define etRADIX 1 /* Integer types. %d, %x, %o, and so forth */
-#define etFLOAT 2 /* Floating point. %f */
-#define etEXP 3 /* Exponentional notation. %e and %E */
-#define etGENERIC 4 /* Floating or exponential, depending on exponent. %g */
-#define etSIZE 5 /* Return number of characters processed so far. %n */
-#define etSTRING 6 /* Strings. %s */
-#define etDYNSTRING 7 /* Dynamically allocated strings. %z */
-#define etPERCENT 8 /* Percent symbol. %% */
-#define etCHARX 9 /* Characters. %c */
-/* The rest are extensions, not normally found in printf() */
-#define etSQLESCAPE 10 /* Strings with '\'' doubled. %q */
-#define etSQLESCAPE2 11 /* Strings with '\'' doubled and enclosed in '',
- NULL pointers replaced by SQL NULL. %Q */
-#define etTOKEN 12 /* a pointer to a Token structure */
-#define etSRCLIST 13 /* a pointer to a SrcList */
-#define etPOINTER 14 /* The %p conversion */
-#define etSQLESCAPE3 15 /* %w -> Strings with '\"' doubled */
-#define etORDINAL 16 /* %r -> 1st, 2nd, 3rd, 4th, etc. English only */
-
-#define etINVALID 0 /* Any unrecognized conversion type */
-
-
-/*
-** An "etByte" is an 8-bit unsigned value.
-*/
-typedef unsigned char etByte;
-
-/*
-** Each builtin conversion character (ex: the 'd' in "%d") is described
-** by an instance of the following structure
-*/
-typedef struct et_info { /* Information about each format field */
- char fmttype; /* The format field code letter */
- etByte base; /* The base for radix conversion */
- etByte flags; /* One or more of FLAG_ constants below */
- etByte type; /* Conversion paradigm */
- etByte charset; /* Offset into aDigits[] of the digits string */
- etByte prefix; /* Offset into aPrefix[] of the prefix string */
-} et_info;
-
-/*
-** Allowed values for et_info.flags
-*/
-#define FLAG_SIGNED 1 /* True if the value to convert is signed */
-#define FLAG_INTERN 2 /* True if for internal use only */
-#define FLAG_STRING 4 /* Allow infinity precision */
-
-
-/*
-** The following table is searched linearly, so it is good to put the
-** most frequently used conversion types first.
-*/
-static const char aDigits[] = "0123456789ABCDEF0123456789abcdef";
-static const char aPrefix[] = "-x0\000X0";
-static const et_info fmtinfo[] = {
- { 'd', 10, 1, etRADIX, 0, 0 },
- { 's', 0, 4, etSTRING, 0, 0 },
- { 'g', 0, 1, etGENERIC, 30, 0 },
- { 'z', 0, 4, etDYNSTRING, 0, 0 },
- { 'q', 0, 4, etSQLESCAPE, 0, 0 },
- { 'Q', 0, 4, etSQLESCAPE2, 0, 0 },
- { 'w', 0, 4, etSQLESCAPE3, 0, 0 },
- { 'c', 0, 0, etCHARX, 0, 0 },
- { 'o', 8, 0, etRADIX, 0, 2 },
- { 'u', 10, 0, etRADIX, 0, 0 },
- { 'x', 16, 0, etRADIX, 16, 1 },
- { 'X', 16, 0, etRADIX, 0, 4 },
-#ifndef SQLITE_OMIT_FLOATING_POINT
- { 'f', 0, 1, etFLOAT, 0, 0 },
- { 'e', 0, 1, etEXP, 30, 0 },
- { 'E', 0, 1, etEXP, 14, 0 },
- { 'G', 0, 1, etGENERIC, 14, 0 },
-#endif
- { 'i', 10, 1, etRADIX, 0, 0 },
- { 'n', 0, 0, etSIZE, 0, 0 },
- { '%', 0, 0, etPERCENT, 0, 0 },
- { 'p', 16, 0, etPOINTER, 0, 1 },
-
-/* All the rest have the FLAG_INTERN bit set and are thus for internal
-** use only */
- { 'T', 0, 2, etTOKEN, 0, 0 },
- { 'S', 0, 2, etSRCLIST, 0, 0 },
- { 'r', 10, 3, etORDINAL, 0, 0 },
-};
-
-/*
-** If SQLITE_OMIT_FLOATING_POINT is defined, then none of the floating point
-** conversions will work.
-*/
-#ifndef SQLITE_OMIT_FLOATING_POINT
-/*
-** "*val" is a double such that 0.1 <= *val < 10.0
-** Return the ascii code for the leading digit of *val, then
-** multiply "*val" by 10.0 to renormalize.
-**
-** Example:
-** input: *val = 3.14159
-** output: *val = 1.4159 function return = '3'
-**
-** The counter *cnt is incremented each time. After counter exceeds
-** 16 (the number of significant digits in a 64-bit float) '0' is
-** always returned.
-*/
-static char et_getdigit(LONGDOUBLE_TYPE *val, int *cnt){
- int digit;
- LONGDOUBLE_TYPE d;
- if( (*cnt)++ >= 16 ) return '0';
- digit = (int)*val;
- d = digit;
- digit += '0';
- *val = (*val - d)*10.0;
- return (char)digit;
-}
-#endif /* SQLITE_OMIT_FLOATING_POINT */
-
-/*
-** Append N space characters to the given string buffer.
-*/
-static void appendSpace(StrAccum *pAccum, int N){
- static const char zSpaces[] = " ";
- while( N>=(int)sizeof(zSpaces)-1 ){
- sqlite3StrAccumAppend(pAccum, zSpaces, sizeof(zSpaces)-1);
- N -= sizeof(zSpaces)-1;
- }
- if( N>0 ){
- sqlite3StrAccumAppend(pAccum, zSpaces, N);
- }
-}
-
-/*
-** On machines with a small stack size, you can redefine the
-** SQLITE_PRINT_BUF_SIZE to be less than 350.
-*/
-#ifndef SQLITE_PRINT_BUF_SIZE
-# if defined(SQLITE_SMALL_STACK)
-# define SQLITE_PRINT_BUF_SIZE 50
-# else
-# define SQLITE_PRINT_BUF_SIZE 350
-# endif
-#endif
-#define etBUFSIZE SQLITE_PRINT_BUF_SIZE /* Size of the output buffer */
-
-/*
-** The root program. All variations call this core.
-**
-** INPUTS:
-** func This is a pointer to a function taking three arguments
-** 1. A pointer to anything. Same as the "arg" parameter.
-** 2. A pointer to the list of characters to be output
-** (Note, this list is NOT null terminated.)
-** 3. An integer number of characters to be output.
-** (Note: This number might be zero.)
-**
-** arg This is the pointer to anything which will be passed as the
-** first argument to "func". Use it for whatever you like.
-**
-** fmt This is the format string, as in the usual print.
-**
-** ap This is a pointer to a list of arguments. Same as in
-** vfprint.
-**
-** OUTPUTS:
-** The return value is the total number of characters sent to
-** the function "func". Returns -1 on a error.
-**
-** Note that the order in which automatic variables are declared below
-** seems to make a big difference in determining how fast this beast
-** will run.
-*/
-SQLITE_PRIVATE void sqlite3VXPrintf(
- StrAccum *pAccum, /* Accumulate results here */
- int useExtended, /* Allow extended %-conversions */
- const char *fmt, /* Format string */
- va_list ap /* arguments */
-){
- int c; /* Next character in the format string */
- char *bufpt; /* Pointer to the conversion buffer */
- int precision; /* Precision of the current field */
- int length; /* Length of the field */
- int idx; /* A general purpose loop counter */
- int width; /* Width of the current field */
- etByte flag_leftjustify; /* True if "-" flag is present */
- etByte flag_plussign; /* True if "+" flag is present */
- etByte flag_blanksign; /* True if " " flag is present */
- etByte flag_alternateform; /* True if "#" flag is present */
- etByte flag_altform2; /* True if "!" flag is present */
- etByte flag_zeropad; /* True if field width constant starts with zero */
- etByte flag_long; /* True if "l" flag is present */
- etByte flag_longlong; /* True if the "ll" flag is present */
- etByte done; /* Loop termination flag */
- sqlite_uint64 longvalue; /* Value for integer types */
- LONGDOUBLE_TYPE realvalue; /* Value for real types */
- const et_info *infop; /* Pointer to the appropriate info structure */
- char buf[etBUFSIZE]; /* Conversion buffer */
- char prefix; /* Prefix character. "+" or "-" or " " or '\0'. */
- etByte xtype = 0; /* Conversion paradigm */
- char *zExtra; /* Extra memory used for etTCLESCAPE conversions */
-#ifndef SQLITE_OMIT_FLOATING_POINT
- int exp, e2; /* exponent of real numbers */
- double rounder; /* Used for rounding floating point values */
- etByte flag_dp; /* True if decimal point should be shown */
- etByte flag_rtz; /* True if trailing zeros should be removed */
- etByte flag_exp; /* True to force display of the exponent */
- int nsd; /* Number of significant digits returned */
-#endif
-
- length = 0;
- bufpt = 0;
- for(; (c=(*fmt))!=0; ++fmt){
- if( c!='%' ){
- int amt;
- bufpt = (char *)fmt;
- amt = 1;
- while( (c=(*++fmt))!='%' && c!=0 ) amt++;
- sqlite3StrAccumAppend(pAccum, bufpt, amt);
- if( c==0 ) break;
- }
- if( (c=(*++fmt))==0 ){
- sqlite3StrAccumAppend(pAccum, "%", 1);
- break;
- }
- /* Find out what flags are present */
- flag_leftjustify = flag_plussign = flag_blanksign =
- flag_alternateform = flag_altform2 = flag_zeropad = 0;
- done = 0;
- do{
- switch( c ){
- case '-': flag_leftjustify = 1; break;
- case '+': flag_plussign = 1; break;
- case ' ': flag_blanksign = 1; break;
- case '#': flag_alternateform = 1; break;
- case '!': flag_altform2 = 1; break;
- case '0': flag_zeropad = 1; break;
- default: done = 1; break;
- }
- }while( !done && (c=(*++fmt))!=0 );
- /* Get the field width */
- width = 0;
- if( c=='*' ){
- width = va_arg(ap,int);
- if( width<0 ){
- flag_leftjustify = 1;
- width = -width;
- }
- c = *++fmt;
- }else{
- while( c>='0' && c<='9' ){
- width = width*10 + c - '0';
- c = *++fmt;
- }
- }
- if( width > etBUFSIZE-10 ){
- width = etBUFSIZE-10;
- }
- /* Get the precision */
- if( c=='.' ){
- precision = 0;
- c = *++fmt;
- if( c=='*' ){
- precision = va_arg(ap,int);
- if( precision<0 ) precision = -precision;
- c = *++fmt;
- }else{
- while( c>='0' && c<='9' ){
- precision = precision*10 + c - '0';
- c = *++fmt;
- }
- }
- }else{
- precision = -1;
- }
- /* Get the conversion type modifier */
- if( c=='l' ){
- flag_long = 1;
- c = *++fmt;
- if( c=='l' ){
- flag_longlong = 1;
- c = *++fmt;
- }else{
- flag_longlong = 0;
- }
- }else{
- flag_long = flag_longlong = 0;
- }
- /* Fetch the info entry for the field */
- infop = &fmtinfo[0];
- xtype = etINVALID;
- for(idx=0; idx<ArraySize(fmtinfo); idx++){
- if( c==fmtinfo[idx].fmttype ){
- infop = &fmtinfo[idx];
- if( useExtended || (infop->flags & FLAG_INTERN)==0 ){
- xtype = infop->type;
- }else{
- return;
- }
- break;
- }
- }
- zExtra = 0;
-
-
- /* Limit the precision to prevent overflowing buf[] during conversion */
- if( precision>etBUFSIZE-40 && (infop->flags & FLAG_STRING)==0 ){
- precision = etBUFSIZE-40;
- }
-
- /*
- ** At this point, variables are initialized as follows:
- **
- ** flag_alternateform TRUE if a '#' is present.
- ** flag_altform2 TRUE if a '!' is present.
- ** flag_plussign TRUE if a '+' is present.
- ** flag_leftjustify TRUE if a '-' is present or if the
- ** field width was negative.
- ** flag_zeropad TRUE if the width began with 0.
- ** flag_long TRUE if the letter 'l' (ell) prefixed
- ** the conversion character.
- ** flag_longlong TRUE if the letter 'll' (ell ell) prefixed
- ** the conversion character.
- ** flag_blanksign TRUE if a ' ' is present.
- ** width The specified field width. This is
- ** always non-negative. Zero is the default.
- ** precision The specified precision. The default
- ** is -1.
- ** xtype The class of the conversion.
- ** infop Pointer to the appropriate info struct.
- */
- switch( xtype ){
- case etPOINTER:
- flag_longlong = sizeof(char*)==sizeof(i64);
- flag_long = sizeof(char*)==sizeof(long int);
- /* Fall through into the next case */
- case etORDINAL:
- case etRADIX:
- if( infop->flags & FLAG_SIGNED ){
- i64 v;
- if( flag_longlong ){
- v = va_arg(ap,i64);
- }else if( flag_long ){
- v = va_arg(ap,long int);
- }else{
- v = va_arg(ap,int);
- }
- if( v<0 ){
- longvalue = -v;
- prefix = '-';
- }else{
- longvalue = v;
- if( flag_plussign ) prefix = '+';
- else if( flag_blanksign ) prefix = ' ';
- else prefix = 0;
- }
- }else{
- if( flag_longlong ){
- longvalue = va_arg(ap,u64);
- }else if( flag_long ){
- longvalue = va_arg(ap,unsigned long int);
- }else{
- longvalue = va_arg(ap,unsigned int);
- }
- prefix = 0;
- }
- if( longvalue==0 ) flag_alternateform = 0;
- if( flag_zeropad && precision<width-(prefix!=0) ){
- precision = width-(prefix!=0);
- }
- bufpt = &buf[etBUFSIZE-1];
- if( xtype==etORDINAL ){
- static const char zOrd[] = "thstndrd";
- int x = (int)(longvalue % 10);
- if( x>=4 || (longvalue/10)%10==1 ){
- x = 0;
- }
- buf[etBUFSIZE-3] = zOrd[x*2];
- buf[etBUFSIZE-2] = zOrd[x*2+1];
- bufpt -= 2;
- }
- {
- register const char *cset; /* Use registers for speed */
- register int base;
- cset = &aDigits[infop->charset];
- base = infop->base;
- do{ /* Convert to ascii */
- *(--bufpt) = cset[longvalue%base];
- longvalue = longvalue/base;
- }while( longvalue>0 );
- }
- length = (int)(&buf[etBUFSIZE-1]-bufpt);
- for(idx=precision-length; idx>0; idx--){
- *(--bufpt) = '0'; /* Zero pad */
- }
- if( prefix ) *(--bufpt) = prefix; /* Add sign */
- if( flag_alternateform && infop->prefix ){ /* Add "0" or "0x" */
- const char *pre;
- char x;
- pre = &aPrefix[infop->prefix];
- for(; (x=(*pre))!=0; pre++) *(--bufpt) = x;
- }
- length = (int)(&buf[etBUFSIZE-1]-bufpt);
- break;
- case etFLOAT:
- case etEXP:
- case etGENERIC:
- realvalue = va_arg(ap,double);
-#ifndef SQLITE_OMIT_FLOATING_POINT
- if( precision<0 ) precision = 6; /* Set default precision */
- if( precision>etBUFSIZE/2-10 ) precision = etBUFSIZE/2-10;
- if( realvalue<0.0 ){
- realvalue = -realvalue;
- prefix = '-';
- }else{
- if( flag_plussign ) prefix = '+';
- else if( flag_blanksign ) prefix = ' ';
- else prefix = 0;
- }
- if( xtype==etGENERIC && precision>0 ) precision--;
-#if 0
- /* Rounding works like BSD when the constant 0.4999 is used. Wierd! */
- for(idx=precision, rounder=0.4999; idx>0; idx--, rounder*=0.1);
-#else
- /* It makes more sense to use 0.5 */
- for(idx=precision, rounder=0.5; idx>0; idx--, rounder*=0.1){}
-#endif
- if( xtype==etFLOAT ) realvalue += rounder;
- /* Normalize realvalue to within 10.0 > realvalue >= 1.0 */
- exp = 0;
- if( sqlite3IsNaN((double)realvalue) ){
- bufpt = "NaN";
- length = 3;
- break;
- }
- if( realvalue>0.0 ){
- while( realvalue>=1e32 && exp<=350 ){ realvalue *= 1e-32; exp+=32; }
- while( realvalue>=1e8 && exp<=350 ){ realvalue *= 1e-8; exp+=8; }
- while( realvalue>=10.0 && exp<=350 ){ realvalue *= 0.1; exp++; }
- while( realvalue<1e-8 ){ realvalue *= 1e8; exp-=8; }
- while( realvalue<1.0 ){ realvalue *= 10.0; exp--; }
- if( exp>350 ){
- if( prefix=='-' ){
- bufpt = "-Inf";
- }else if( prefix=='+' ){
- bufpt = "+Inf";
- }else{
- bufpt = "Inf";
- }
- length = sqlite3Strlen30(bufpt);
- break;
- }
- }
- bufpt = buf;
- /*
- ** If the field type is etGENERIC, then convert to either etEXP
- ** or etFLOAT, as appropriate.
- */
- flag_exp = xtype==etEXP;
- if( xtype!=etFLOAT ){
- realvalue += rounder;
- if( realvalue>=10.0 ){ realvalue *= 0.1; exp++; }
- }
- if( xtype==etGENERIC ){
- flag_rtz = !flag_alternateform;
- if( exp<-4 || exp>precision ){
- xtype = etEXP;
- }else{
- precision = precision - exp;
- xtype = etFLOAT;
- }
- }else{
- flag_rtz = 0;
- }
- if( xtype==etEXP ){
- e2 = 0;
- }else{
- e2 = exp;
- }
- nsd = 0;
- flag_dp = (precision>0 ?1:0) | flag_alternateform | flag_altform2;
- /* The sign in front of the number */
- if( prefix ){
- *(bufpt++) = prefix;
- }
- /* Digits prior to the decimal point */
- if( e2<0 ){
- *(bufpt++) = '0';
- }else{
- for(; e2>=0; e2--){
- *(bufpt++) = et_getdigit(&realvalue,&nsd);
- }
- }
- /* The decimal point */
- if( flag_dp ){
- *(bufpt++) = '.';
- }
- /* "0" digits after the decimal point but before the first
- ** significant digit of the number */
- for(e2++; e2<0; precision--, e2++){
- assert( precision>0 );
- *(bufpt++) = '0';
- }
- /* Significant digits after the decimal point */
- while( (precision--)>0 ){
- *(bufpt++) = et_getdigit(&realvalue,&nsd);
- }
- /* Remove trailing zeros and the "." if no digits follow the "." */
- if( flag_rtz && flag_dp ){
- while( bufpt[-1]=='0' ) *(--bufpt) = 0;
- assert( bufpt>buf );
- if( bufpt[-1]=='.' ){
- if( flag_altform2 ){
- *(bufpt++) = '0';
- }else{
- *(--bufpt) = 0;
- }
- }
- }
- /* Add the "eNNN" suffix */
- if( flag_exp || xtype==etEXP ){
- *(bufpt++) = aDigits[infop->charset];
- if( exp<0 ){
- *(bufpt++) = '-'; exp = -exp;
- }else{
- *(bufpt++) = '+';
- }
- if( exp>=100 ){
- *(bufpt++) = (char)((exp/100)+'0'); /* 100's digit */
- exp %= 100;
- }
- *(bufpt++) = (char)(exp/10+'0'); /* 10's digit */
- *(bufpt++) = (char)(exp%10+'0'); /* 1's digit */
- }
- *bufpt = 0;
-
- /* The converted number is in buf[] and zero terminated. Output it.
- ** Note that the number is in the usual order, not reversed as with
- ** integer conversions. */
- length = (int)(bufpt-buf);
- bufpt = buf;
-
- /* Special case: Add leading zeros if the flag_zeropad flag is
- ** set and we are not left justified */
- if( flag_zeropad && !flag_leftjustify && length < width){
- int i;
- int nPad = width - length;
- for(i=width; i>=nPad; i--){
- bufpt[i] = bufpt[i-nPad];
- }
- i = prefix!=0;
- while( nPad-- ) bufpt[i++] = '0';
- length = width;
- }
-#endif
- break;
- case etSIZE:
- *(va_arg(ap,int*)) = pAccum->nChar;
- length = width = 0;
- break;
- case etPERCENT:
- buf[0] = '%';
- bufpt = buf;
- length = 1;
- break;
- case etCHARX:
- c = va_arg(ap,int);
- buf[0] = (char)c;
- if( precision>=0 ){
- for(idx=1; idx<precision; idx++) buf[idx] = (char)c;
- length = precision;
- }else{
- length =1;
- }
- bufpt = buf;
- break;
- case etSTRING:
- case etDYNSTRING:
- bufpt = va_arg(ap,char*);
- if( bufpt==0 ){
- bufpt = "";
- }else if( xtype==etDYNSTRING ){
- zExtra = bufpt;
- }
- if( precision>=0 ){
- for(length=0; length<precision && bufpt[length]; length++){}
- }else{
- length = sqlite3Strlen30(bufpt);
- }
- break;
- case etSQLESCAPE:
- case etSQLESCAPE2:
- case etSQLESCAPE3: {
- int i, j, n, isnull;
- int needQuote;
- char ch;
- char q = ((xtype==etSQLESCAPE3)?'"':'\''); /* Quote character */
- char *escarg = va_arg(ap,char*);
- isnull = escarg==0;
- if( isnull ) escarg = (xtype==etSQLESCAPE2 ? "NULL" : "(NULL)");
- for(i=n=0; (ch=escarg[i])!=0; i++){
- if( ch==q ) n++;
- }
- needQuote = !isnull && xtype==etSQLESCAPE2;
- n += i + 1 + needQuote*2;
- if( n>etBUFSIZE ){
- bufpt = zExtra = sqlite3Malloc( n );
- if( bufpt==0 ){
- pAccum->mallocFailed = 1;
- return;
- }
- }else{
- bufpt = buf;
- }
- j = 0;
- if( needQuote ) bufpt[j++] = q;
- for(i=0; (ch=escarg[i])!=0; i++){
- bufpt[j++] = ch;
- if( ch==q ) bufpt[j++] = ch;
- }
- if( needQuote ) bufpt[j++] = q;
- bufpt[j] = 0;
- length = j;
- /* The precision is ignored on %q and %Q */
- /* if( precision>=0 && precision<length ) length = precision; */
- break;
- }
- case etTOKEN: {
- Token *pToken = va_arg(ap, Token*);
- if( pToken ){
- sqlite3StrAccumAppend(pAccum, (const char*)pToken->z, pToken->n);
- }
- length = width = 0;
- break;
- }
- case etSRCLIST: {
- SrcList *pSrc = va_arg(ap, SrcList*);
- int k = va_arg(ap, int);
- struct SrcList_item *pItem = &pSrc->a[k];
- assert( k>=0 && k<pSrc->nSrc );
- if( pItem->zDatabase ){
- sqlite3StrAccumAppend(pAccum, pItem->zDatabase, -1);
- sqlite3StrAccumAppend(pAccum, ".", 1);
- }
- sqlite3StrAccumAppend(pAccum, pItem->zName, -1);
- length = width = 0;
- break;
- }
- default: {
- assert( xtype==etINVALID );
- return;
- }
- }/* End switch over the format type */
- /*
- ** The text of the conversion is pointed to by "bufpt" and is
- ** "length" characters long. The field width is "width". Do
- ** the output.
- */
- if( !flag_leftjustify ){
- register int nspace;
- nspace = width-length;
- if( nspace>0 ){
- appendSpace(pAccum, nspace);
- }
- }
- if( length>0 ){
- sqlite3StrAccumAppend(pAccum, bufpt, length);
- }
- if( flag_leftjustify ){
- register int nspace;
- nspace = width-length;
- if( nspace>0 ){
- appendSpace(pAccum, nspace);
- }
- }
- if( zExtra ){
- sqlite3_free(zExtra);
- }
- }/* End for loop over the format string */
-} /* End of function */
-
-/*
-** Append N bytes of text from z to the StrAccum object.
-*/
-SQLITE_PRIVATE void sqlite3StrAccumAppend(StrAccum *p, const char *z, int N){
- assert( z!=0 || N==0 );
- if( p->tooBig | p->mallocFailed ){
- testcase(p->tooBig);
- testcase(p->mallocFailed);
- return;
- }
- if( N<0 ){
- N = sqlite3Strlen30(z);
- }
- if( N==0 || NEVER(z==0) ){
- return;
- }
- if( p->nChar+N >= p->nAlloc ){
- char *zNew;
- if( !p->useMalloc ){
- p->tooBig = 1;
- N = p->nAlloc - p->nChar - 1;
- if( N<=0 ){
- return;
- }
- }else{
- i64 szNew = p->nChar;
- szNew += N + 1;
- if( szNew > p->mxAlloc ){
- sqlite3StrAccumReset(p);
- p->tooBig = 1;
- return;
- }else{
- p->nAlloc = (int)szNew;
- }
- zNew = sqlite3DbMallocRaw(p->db, p->nAlloc );
- if( zNew ){
- memcpy(zNew, p->zText, p->nChar);
- sqlite3StrAccumReset(p);
- p->zText = zNew;
- }else{
- p->mallocFailed = 1;
- sqlite3StrAccumReset(p);
- return;
- }
- }
- }
- memcpy(&p->zText[p->nChar], z, N);
- p->nChar += N;
-}
-
-/*
-** Finish off a string by making sure it is zero-terminated.
-** Return a pointer to the resulting string. Return a NULL
-** pointer if any kind of error was encountered.
-*/
-SQLITE_PRIVATE char *sqlite3StrAccumFinish(StrAccum *p){
- if( p->zText ){
- p->zText[p->nChar] = 0;
- if( p->useMalloc && p->zText==p->zBase ){
- p->zText = sqlite3DbMallocRaw(p->db, p->nChar+1 );
- if( p->zText ){
- memcpy(p->zText, p->zBase, p->nChar+1);
- }else{
- p->mallocFailed = 1;
- }
- }
- }
- return p->zText;
-}
-
-/*
-** Reset an StrAccum string. Reclaim all malloced memory.
-*/
-SQLITE_PRIVATE void sqlite3StrAccumReset(StrAccum *p){
- if( p->zText!=p->zBase ){
- sqlite3DbFree(p->db, p->zText);
- }
- p->zText = 0;
-}
-
-/*
-** Initialize a string accumulator
-*/
-SQLITE_PRIVATE void sqlite3StrAccumInit(StrAccum *p, char *zBase, int n, int mx){
- p->zText = p->zBase = zBase;
- p->db = 0;
- p->nChar = 0;
- p->nAlloc = n;
- p->mxAlloc = mx;
- p->useMalloc = 1;
- p->tooBig = 0;
- p->mallocFailed = 0;
-}
-
-/*
-** Print into memory obtained from sqliteMalloc(). Use the internal
-** %-conversion extensions.
-*/
-SQLITE_PRIVATE char *sqlite3VMPrintf(sqlite3 *db, const char *zFormat, va_list ap){
- char *z;
- char zBase[SQLITE_PRINT_BUF_SIZE];
- StrAccum acc;
- assert( db!=0 );
- sqlite3StrAccumInit(&acc, zBase, sizeof(zBase),
- db->aLimit[SQLITE_LIMIT_LENGTH]);
- acc.db = db;
- sqlite3VXPrintf(&acc, 1, zFormat, ap);
- z = sqlite3StrAccumFinish(&acc);
- if( acc.mallocFailed ){
- db->mallocFailed = 1;
- }
- return z;
-}
-
-/*
-** Print into memory obtained from sqliteMalloc(). Use the internal
-** %-conversion extensions.
-*/
-SQLITE_PRIVATE char *sqlite3MPrintf(sqlite3 *db, const char *zFormat, ...){
- va_list ap;
- char *z;
- va_start(ap, zFormat);
- z = sqlite3VMPrintf(db, zFormat, ap);
- va_end(ap);
- return z;
-}
-
-/*
-** Like sqlite3MPrintf(), but call sqlite3DbFree() on zStr after formatting
-** the string and before returnning. This routine is intended to be used
-** to modify an existing string. For example:
-**
-** x = sqlite3MPrintf(db, x, "prefix %s suffix", x);
-**
-*/
-SQLITE_PRIVATE char *sqlite3MAppendf(sqlite3 *db, char *zStr, const char *zFormat, ...){
- va_list ap;
- char *z;
- va_start(ap, zFormat);
- z = sqlite3VMPrintf(db, zFormat, ap);
- va_end(ap);
- sqlite3DbFree(db, zStr);
- return z;
-}
-
-/*
-** Print into memory obtained from sqlite3_malloc(). Omit the internal
-** %-conversion extensions.
-*/
-SQLITE_API char *sqlite3_vmprintf(const char *zFormat, va_list ap){
- char *z;
- char zBase[SQLITE_PRINT_BUF_SIZE];
- StrAccum acc;
-#ifndef SQLITE_OMIT_AUTOINIT
- if( sqlite3_initialize() ) return 0;
-#endif
- sqlite3StrAccumInit(&acc, zBase, sizeof(zBase), SQLITE_MAX_LENGTH);
- sqlite3VXPrintf(&acc, 0, zFormat, ap);
- z = sqlite3StrAccumFinish(&acc);
- return z;
-}
-
-/*
-** Print into memory obtained from sqlite3_malloc()(). Omit the internal
-** %-conversion extensions.
-*/
-SQLITE_API char *sqlite3_mprintf(const char *zFormat, ...){
- va_list ap;
- char *z;
-#ifndef SQLITE_OMIT_AUTOINIT
- if( sqlite3_initialize() ) return 0;
-#endif
- va_start(ap, zFormat);
- z = sqlite3_vmprintf(zFormat, ap);
- va_end(ap);
- return z;
-}
-
-/*
-** sqlite3_snprintf() works like snprintf() except that it ignores the
-** current locale settings. This is important for SQLite because we
-** are not able to use a "," as the decimal point in place of "." as
-** specified by some locales.
-*/
-SQLITE_API char *sqlite3_snprintf(int n, char *zBuf, const char *zFormat, ...){
- char *z;
- va_list ap;
- StrAccum acc;
-
- if( n<=0 ){
- return zBuf;
- }
- sqlite3StrAccumInit(&acc, zBuf, n, 0);
- acc.useMalloc = 0;
- va_start(ap,zFormat);
- sqlite3VXPrintf(&acc, 0, zFormat, ap);
- va_end(ap);
- z = sqlite3StrAccumFinish(&acc);
- return z;
-}
-
-#if defined(SQLITE_DEBUG)
-/*
-** A version of printf() that understands %lld. Used for debugging.
-** The printf() built into some versions of windows does not understand %lld
-** and segfaults if you give it a long long int.
-*/
-SQLITE_PRIVATE void sqlite3DebugPrintf(const char *zFormat, ...){
- va_list ap;
- StrAccum acc;
- char zBuf[500];
- sqlite3StrAccumInit(&acc, zBuf, sizeof(zBuf), 0);
- acc.useMalloc = 0;
- va_start(ap,zFormat);
- sqlite3VXPrintf(&acc, 0, zFormat, ap);
- va_end(ap);
- sqlite3StrAccumFinish(&acc);
- fprintf(stdout,"%s", zBuf);
- fflush(stdout);
-}
-#endif
-
-/************** End of printf.c **********************************************/
-/************** Begin file random.c ******************************************/
-/*
-** 2001 September 15
-**
-** 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 code to implement a pseudo-random number
-** generator (PRNG) for SQLite.
-**
-** Random numbers are used by some of the database backends in order
-** to generate random integer keys for tables or random filenames.
-**
-** $Id: random.c,v 1.29 2008/12/10 19:26:24 drh Exp $
-*/
-
-
-/* All threads share a single random number generator.
-** This structure is the current state of the generator.
-*/
-static SQLITE_WSD struct sqlite3PrngType {
- unsigned char isInit; /* True if initialized */
- unsigned char i, j; /* State variables */
- unsigned char s[256]; /* State variables */
-} sqlite3Prng;
-
-/*
-** Get a single 8-bit random value from the RC4 PRNG. The Mutex
-** must be held while executing this routine.
-**
-** Why not just use a library random generator like lrand48() for this?
-** Because the OP_NewRowid opcode in the VDBE depends on having a very
-** good source of random numbers. The lrand48() library function may
-** well be good enough. But maybe not. Or maybe lrand48() has some
-** subtle problems on some systems that could cause problems. It is hard
-** to know. To minimize the risk of problems due to bad lrand48()
-** implementations, SQLite uses this random number generator based
-** on RC4, which we know works very well.
-**
-** (Later): Actually, OP_NewRowid does not depend on a good source of
-** randomness any more. But we will leave this code in all the same.
-*/
-static u8 randomByte(void){
- unsigned char t;
-
-
- /* The "wsdPrng" macro will resolve to the pseudo-random number generator
- ** state vector. If writable static data is unsupported on the target,
- ** we have to locate the state vector at run-time. In the more common
- ** case where writable static data is supported, wsdPrng can refer directly
- ** to the "sqlite3Prng" state vector declared above.
- */
-#ifdef SQLITE_OMIT_WSD
- struct sqlite3PrngType *p = &GLOBAL(struct sqlite3PrngType, sqlite3Prng);
-# define wsdPrng p[0]
-#else
-# define wsdPrng sqlite3Prng
-#endif
-
-
- /* Initialize the state of the random number generator once,
- ** the first time this routine is called. The seed value does
- ** not need to contain a lot of randomness since we are not
- ** trying to do secure encryption or anything like that...
- **
- ** Nothing in this file or anywhere else in SQLite does any kind of
- ** encryption. The RC4 algorithm is being used as a PRNG (pseudo-random
- ** number generator) not as an encryption device.
- */
- if( !wsdPrng.isInit ){
- int i;
- char k[256];
- wsdPrng.j = 0;
- wsdPrng.i = 0;
- sqlite3OsRandomness(sqlite3_vfs_find(0), 256, k);
- for(i=0; i<256; i++){
- wsdPrng.s[i] = (u8)i;
- }
- for(i=0; i<256; i++){
- wsdPrng.j += wsdPrng.s[i] + k[i];
- t = wsdPrng.s[wsdPrng.j];
- wsdPrng.s[wsdPrng.j] = wsdPrng.s[i];
- wsdPrng.s[i] = t;
- }
- wsdPrng.isInit = 1;
- }
-
- /* Generate and return single random byte
- */
- wsdPrng.i++;
- t = wsdPrng.s[wsdPrng.i];
- wsdPrng.j += t;
- wsdPrng.s[wsdPrng.i] = wsdPrng.s[wsdPrng.j];
- wsdPrng.s[wsdPrng.j] = t;
- t += wsdPrng.s[wsdPrng.i];
- return wsdPrng.s[t];
-}
-
-/*
-** Return N random bytes.
-*/
-SQLITE_API void sqlite3_randomness(int N, void *pBuf){
- unsigned char *zBuf = pBuf;
-#if SQLITE_THREADSAFE
- sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_PRNG);
-#endif
- sqlite3_mutex_enter(mutex);
- while( N-- ){
- *(zBuf++) = randomByte();
- }
- sqlite3_mutex_leave(mutex);
-}
-
-#ifndef SQLITE_OMIT_BUILTIN_TEST
-/*
-** For testing purposes, we sometimes want to preserve the state of
-** PRNG and restore the PRNG to its saved state at a later time, or
-** to reset the PRNG to its initial state. These routines accomplish
-** those tasks.
-**
-** The sqlite3_test_control() interface calls these routines to
-** control the PRNG.
-*/
-static SQLITE_WSD struct sqlite3PrngType sqlite3SavedPrng;
-SQLITE_PRIVATE void sqlite3PrngSaveState(void){
- memcpy(
- &GLOBAL(struct sqlite3PrngType, sqlite3SavedPrng),
- &GLOBAL(struct sqlite3PrngType, sqlite3Prng),
- sizeof(sqlite3Prng)
- );
-}
-SQLITE_PRIVATE void sqlite3PrngRestoreState(void){
- memcpy(
- &GLOBAL(struct sqlite3PrngType, sqlite3Prng),
- &GLOBAL(struct sqlite3PrngType, sqlite3SavedPrng),
- sizeof(sqlite3Prng)
- );
-}
-SQLITE_PRIVATE void sqlite3PrngResetState(void){
- GLOBAL(struct sqlite3PrngType, sqlite3Prng).isInit = 0;
-}
-#endif /* SQLITE_OMIT_BUILTIN_TEST */
-
-/************** End of random.c **********************************************/
-/************** Begin file utf.c *********************************************/
-/*
-** 2004 April 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 routines used to translate between UTF-8,
-** UTF-16, UTF-16BE, and UTF-16LE.
-**
-** $Id: utf.c,v 1.73 2009/04/01 18:40:32 drh Exp $
-**
-** Notes on UTF-8:
-**
-** Byte-0 Byte-1 Byte-2 Byte-3 Value
-** 0xxxxxxx 00000000 00000000 0xxxxxxx
-** 110yyyyy 10xxxxxx 00000000 00000yyy yyxxxxxx
-** 1110zzzz 10yyyyyy 10xxxxxx 00000000 zzzzyyyy yyxxxxxx
-** 11110uuu 10uuzzzz 10yyyyyy 10xxxxxx 000uuuuu zzzzyyyy yyxxxxxx
-**
-**
-** Notes on UTF-16: (with wwww+1==uuuuu)
-**
-** Word-0 Word-1 Value
-** 110110ww wwzzzzyy 110111yy yyxxxxxx 000uuuuu zzzzyyyy yyxxxxxx
-** zzzzyyyy yyxxxxxx 00000000 zzzzyyyy yyxxxxxx
-**
-**
-** BOM or Byte Order Mark:
-** 0xff 0xfe little-endian utf-16 follows
-** 0xfe 0xff big-endian utf-16 follows
-**
-*/
-/************** Include vdbeInt.h in the middle of utf.c *********************/
-/************** Begin file vdbeInt.h *****************************************/
-/*
-** 2003 September 6
-**
-** 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 is the header file for information that is private to the
-** VDBE. This information used to all be at the top of the single
-** source code file "vdbe.c". When that file became too big (over
-** 6000 lines long) it was split up into several smaller files and
-** this header information was factored out.
-**
-** $Id: vdbeInt.h,v 1.174 2009/06/23 14:15:04 drh Exp $
-*/
-#ifndef _VDBEINT_H_
-#define _VDBEINT_H_
-
-/*
-** SQL is translated into a sequence of instructions to be
-** executed by a virtual machine. Each instruction is an instance
-** of the following structure.
-*/
-typedef struct VdbeOp Op;
-
-/*
-** Boolean values
-*/
-typedef unsigned char Bool;
-
-/*
-** 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
-** loop over all entries of the Btree. You can also insert new BTree
-** entries or retrieve the key or data from the entry that the cursor
-** is currently pointing to.
-**
-** Every cursor that the virtual machine has open is represented by an
-** instance of the following structure.
-**
-** If the VdbeCursor.isTriggerRow flag is set it means that this cursor is
-** really a single row that represents the NEW or OLD pseudo-table of
-** a row trigger. The data for the row is stored in VdbeCursor.pData and
-** the rowid is in VdbeCursor.iKey.
-*/
-struct VdbeCursor {
- BtCursor *pCursor; /* The cursor structure of the backend */
- int iDb; /* Index of cursor database in db->aDb[] (or -1) */
- i64 lastRowid; /* Last rowid from a Next or NextIdx operation */
- Bool zeroed; /* True if zeroed out and ready for reuse */
- Bool rowidIsValid; /* True if lastRowid is valid */
- Bool atFirst; /* True if pointing to first entry */
- Bool useRandomRowid; /* Generate new record numbers semi-randomly */
- Bool nullRow; /* True if pointing to a row with no data */
- Bool deferredMoveto; /* A call to sqlite3BtreeMoveto() is needed */
- Bool isTable; /* True if a table requiring integer keys */
- Bool isIndex; /* True if an index containing keys only - no data */
- i64 movetoTarget; /* Argument to the deferred sqlite3BtreeMoveto() */
- Btree *pBt; /* Separate file holding temporary table */
- int pseudoTableReg; /* Register holding pseudotable content. */
- KeyInfo *pKeyInfo; /* Info about index keys needed by index cursors */
- int nField; /* Number of fields in the header */
- i64 seqCount; /* Sequence counter */
- sqlite3_vtab_cursor *pVtabCursor; /* The cursor for a virtual table */
- const sqlite3_module *pModule; /* Module for cursor pVtabCursor */
-
- /* Result of last sqlite3BtreeMoveto() done by an OP_NotExists or
- ** OP_IsUnique opcode on this cursor. */
- int seekResult;
-
- /* Cached information about the header for the data record that the
- ** cursor is currently pointing to. Only valid if cacheStatus matches
- ** Vdbe.cacheCtr. Vdbe.cacheCtr will never take on the value of
- ** CACHE_STALE and so setting cacheStatus=CACHE_STALE guarantees that
- ** the cache is out of date.
- **
- ** aRow might point to (ephemeral) data for the current row, or it might
- ** be NULL.
- */
- u32 cacheStatus; /* Cache is valid if this matches Vdbe.cacheCtr */
- int payloadSize; /* Total number of bytes in the record */
- u32 *aType; /* Type values for all entries in the record */
- u32 *aOffset; /* Cached offsets to the start of each columns data */
- u8 *aRow; /* Data for the current row, if all on one page */
-};
-typedef struct VdbeCursor VdbeCursor;
-
-/*
-** When a sub-program is executed (OP_Program), a structure of this type
-** is allocated to store the current value of the program counter, as
-** well as the current memory cell array and various other frame specific
-** values stored in the Vdbe struct. When the sub-program is finished,
-** these values are copied back to the Vdbe from the VdbeFrame structure,
-** restoring the state of the VM to as it was before the sub-program
-** began executing.
-**
-** Frames are stored in a linked list headed at Vdbe.pParent. Vdbe.pParent
-** is the parent of the current frame, or zero if the current frame
-** is the main Vdbe program.
-*/
-typedef struct VdbeFrame VdbeFrame;
-struct VdbeFrame {
- Vdbe *v; /* VM this frame belongs to */
- int pc; /* Program Counter */
- Op *aOp; /* Program instructions */
- int nOp; /* Size of aOp array */
- Mem *aMem; /* Array of memory cells */
- int nMem; /* Number of entries in aMem */
- VdbeCursor **apCsr; /* Element of Vdbe cursors */
- u16 nCursor; /* Number of entries in apCsr */
- void *token; /* Copy of SubProgram.token */
- int nChildMem; /* Number of memory cells for child frame */
- int nChildCsr; /* Number of cursors for child frame */
- i64 lastRowid; /* Last insert rowid (sqlite3.lastRowid) */
- int nChange; /* Statement changes (Vdbe.nChanges) */
- VdbeFrame *pParent; /* Parent of this frame */
-};
-
-#define VdbeFrameMem(p) ((Mem *)&((u8 *)p)[ROUND8(sizeof(VdbeFrame))])
-
-/*
-** A value for VdbeCursor.cacheValid that means the cache is always invalid.
-*/
-#define CACHE_STALE 0
-
-/*
-** Internally, the vdbe manipulates nearly all SQL values as Mem
-** structures. Each Mem struct may cache multiple representations (string,
-** integer etc.) of the same value. A value (and therefore Mem structure)
-** has the following properties:
-**
-** Each value has a manifest type. The manifest type of the value stored
-** in a Mem struct is returned by the MemType(Mem*) macro. The type is
-** one of SQLITE_NULL, SQLITE_INTEGER, SQLITE_REAL, SQLITE_TEXT or
-** SQLITE_BLOB.
-*/
-struct Mem {
- union {
- i64 i; /* Integer value. */
- int nZero; /* Used when bit MEM_Zero is set in flags */
- FuncDef *pDef; /* Used only when flags==MEM_Agg */
- RowSet *pRowSet; /* Used only when flags==MEM_RowSet */
- VdbeFrame *pFrame; /* Used when flags==MEM_Frame */
- } u;
- double r; /* Real value */
- sqlite3 *db; /* The associated database connection */
- char *z; /* String or BLOB value */
- int n; /* Number of characters in string value, excluding '\0' */
- u16 flags; /* Some combination of MEM_Null, MEM_Str, MEM_Dyn, etc. */
- u8 type; /* One of SQLITE_NULL, SQLITE_TEXT, SQLITE_INTEGER, etc */
- u8 enc; /* SQLITE_UTF8, SQLITE_UTF16BE, SQLITE_UTF16LE */
- void (*xDel)(void *); /* If not null, call this function to delete Mem.z */
- char *zMalloc; /* Dynamic buffer allocated by sqlite3_malloc() */
-};
-
-/* One or more of the following flags are set to indicate the validOK
-** representations of the value stored in the Mem struct.
-**
-** If the MEM_Null flag is set, then the value is an SQL NULL value.
-** No other flags may be set in this case.
-**
-** If the MEM_Str flag is set then Mem.z points at a string representation.
-** Usually this is encoded in the same unicode encoding as the main
-** database (see below for exceptions). If the MEM_Term flag is also
-** set, then the string is nul terminated. The MEM_Int and MEM_Real
-** flags may coexist with the MEM_Str flag.
-**
-** Multiple of these values can appear in Mem.flags. But only one
-** at a time can appear in Mem.type.
-*/
-#define MEM_Null 0x0001 /* Value is NULL */
-#define MEM_Str 0x0002 /* Value is a string */
-#define MEM_Int 0x0004 /* Value is an integer */
-#define MEM_Real 0x0008 /* Value is a real number */
-#define MEM_Blob 0x0010 /* Value is a BLOB */
-#define MEM_RowSet 0x0020 /* Value is a RowSet object */
-#define MEM_Frame 0x0040 /* Value is a VdbeFrame object */
-#define MEM_TypeMask 0x00ff /* Mask of type bits */
-
-/* Whenever Mem contains a valid string or blob representation, one of
-** the following flags must be set to determine the memory management
-** policy for Mem.z. The MEM_Term flag tells us whether or not the
-** string is \000 or \u0000 terminated
-*/
-#define MEM_Term 0x0200 /* String rep is nul terminated */
-#define MEM_Dyn 0x0400 /* Need to call sqliteFree() on Mem.z */
-#define MEM_Static 0x0800 /* Mem.z points to a static string */
-#define MEM_Ephem 0x1000 /* Mem.z points to an ephemeral string */
-#define MEM_Agg 0x2000 /* Mem.z points to an agg function context */
-#define MEM_Zero 0x4000 /* Mem.i contains count of 0s appended to blob */
-
-#ifdef SQLITE_OMIT_INCRBLOB
- #undef MEM_Zero
- #define MEM_Zero 0x0000
-#endif
-
-
-/*
-** Clear any existing type flags from a Mem and replace them with f
-*/
-#define MemSetTypeFlag(p, f) \
- ((p)->flags = ((p)->flags&~(MEM_TypeMask|MEM_Zero))|f)
-
-
-/* A VdbeFunc is just a FuncDef (defined in sqliteInt.h) that contains
-** additional information about auxiliary information bound to arguments
-** of the function. This is used to implement the sqlite3_get_auxdata()
-** and sqlite3_set_auxdata() APIs. The "auxdata" is some auxiliary data
-** that can be associated with a constant argument to a function. This
-** allows functions such as "regexp" to compile their constant regular
-** expression argument once and reused the compiled code for multiple
-** invocations.
-*/
-struct VdbeFunc {
- FuncDef *pFunc; /* The definition of the function */
- int nAux; /* Number of entries allocated for apAux[] */
- struct AuxData {
- void *pAux; /* Aux data for the i-th argument */
- void (*xDelete)(void *); /* Destructor for the aux data */
- } apAux[1]; /* One slot for each function argument */
-};
-
-/*
-** The "context" argument for a installable function. A pointer to an
-** instance of this structure is the first argument to the routines used
-** implement the SQL functions.
-**
-** There is a typedef for this structure in sqlite.h. So all routines,
-** even the public interface to SQLite, can use a pointer to this structure.
-** But this file is the only place where the internal details of this
-** structure are known.
-**
-** This structure is defined inside of vdbeInt.h because it uses substructures
-** (Mem) which are only defined there.
-*/
-struct sqlite3_context {
- FuncDef *pFunc; /* Pointer to function information. MUST BE FIRST */
- VdbeFunc *pVdbeFunc; /* Auxilary data, if created. */
- Mem s; /* The return value is stored here */
- Mem *pMem; /* Memory cell used to store aggregate context */
- int isError; /* Error code returned by the function. */
- CollSeq *pColl; /* Collating sequence */
-};
-
-/*
-** A Set structure is used for quick testing to see if a value
-** is part of a small set. Sets are used to implement code like
-** this:
-** x.y IN ('hi','hoo','hum')
-*/
-typedef struct Set Set;
-struct Set {
- Hash hash; /* A set is just a hash table */
- HashElem *prev; /* Previously accessed hash elemen */
-};
-
-/*
-** An instance of the virtual machine. This structure contains the complete
-** state of the virtual machine.
-**
-** The "sqlite3_stmt" structure pointer that is returned by sqlite3_compile()
-** is really a pointer to an instance of this structure.
-**
-** The Vdbe.inVtabMethod variable is set to non-zero for the duration of
-** any virtual table method invocations made by the vdbe program. It is
-** set to 2 for xDestroy method calls and 1 for all other methods. This
-** variable is used for two purposes: to allow xDestroy methods to execute
-** "DROP TABLE" statements and to prevent some nasty side effects of
-** malloc failure when SQLite is invoked recursively by a virtual table
-** method function.
-*/
-struct Vdbe {
- sqlite3 *db; /* The database connection that owns this statement */
- Vdbe *pPrev,*pNext; /* Linked list of VDBEs with the same Vdbe.db */
- int nOp; /* Number of instructions in the program */
- int nOpAlloc; /* Number of slots allocated for aOp[] */
- Op *aOp; /* Space to hold the virtual machine's program */
- int nLabel; /* Number of labels used */
- int nLabelAlloc; /* Number of slots allocated in aLabel[] */
- int *aLabel; /* Space to hold the labels */
- Mem **apArg; /* Arguments to currently executing user function */
- Mem *aColName; /* Column names to return */
- Mem *pResultSet; /* Pointer to an array of results */
- u16 nResColumn; /* Number of columns in one row of the result set */
- u16 nCursor; /* Number of slots in apCsr[] */
- VdbeCursor **apCsr; /* One element of this array for each open cursor */
- u8 errorAction; /* Recovery action to do in case of an error */
- u8 okVar; /* True if azVar[] has been initialized */
- u16 nVar; /* Number of entries in aVar[] */
- Mem *aVar; /* Values for the OP_Variable opcode. */
- char **azVar; /* Name of variables */
- u32 magic; /* Magic number for sanity checking */
- int nMem; /* Number of memory locations currently allocated */
- Mem *aMem; /* The memory locations */
- u32 cacheCtr; /* VdbeCursor row cache generation counter */
- int pc; /* The program counter */
- int rc; /* Value to return */
- char *zErrMsg; /* Error message written here */
- u8 explain; /* True if EXPLAIN present on SQL command */
- u8 changeCntOn; /* True to update the change-counter */
- u8 expired; /* True if the VM needs to be recompiled */
- u8 minWriteFileFormat; /* Minimum file format for writable database files */
- u8 inVtabMethod; /* See comments above */
- u8 usesStmtJournal; /* True if uses a statement journal */
- u8 readOnly; /* True for read-only statements */
- u8 isPrepareV2; /* True if prepared with prepare_v2() */
- int nChange; /* Number of db changes made since last reset */
- int btreeMask; /* Bitmask of db->aDb[] entries referenced */
- i64 startTime; /* Time when query started - used for profiling */
- BtreeMutexArray aMutex; /* An array of Btree used here and needing locks */
- int aCounter[2]; /* Counters used by sqlite3_stmt_status() */
- char *zSql; /* Text of the SQL statement that generated this */
- void *pFree; /* Free this when deleting the vdbe */
- int iStatement; /* Statement number (or 0 if has not opened stmt) */
-#ifdef SQLITE_DEBUG
- FILE *trace; /* Write an execution trace here, if not NULL */
-#endif
- VdbeFrame *pFrame; /* Parent frame */
- int nFrame; /* Number of frames in pFrame list */
-};
-
-/*
-** The following are allowed values for Vdbe.magic
-*/
-#define VDBE_MAGIC_INIT 0x26bceaa5 /* Building a VDBE program */
-#define VDBE_MAGIC_RUN 0xbdf20da3 /* VDBE is ready to execute */
-#define VDBE_MAGIC_HALT 0x519c2973 /* VDBE has completed execution */
-#define VDBE_MAGIC_DEAD 0xb606c3c8 /* The VDBE has been deallocated */
-
-/*
-** Function prototypes
-*/
-SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *, VdbeCursor*);
-void sqliteVdbePopStack(Vdbe*,int);
-SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor*);
-#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
-SQLITE_PRIVATE void sqlite3VdbePrintOp(FILE*, int, Op*);
-#endif
-SQLITE_PRIVATE u32 sqlite3VdbeSerialTypeLen(u32);
-SQLITE_PRIVATE u32 sqlite3VdbeSerialType(Mem*, int);
-SQLITE_PRIVATE u32 sqlite3VdbeSerialPut(unsigned char*, int, Mem*, int);
-SQLITE_PRIVATE u32 sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*);
-SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(VdbeFunc*, int);
-
-int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *);
-SQLITE_PRIVATE int sqlite3VdbeIdxKeyCompare(VdbeCursor*,UnpackedRecord*,int*);
-SQLITE_PRIVATE int sqlite3VdbeIdxRowid(sqlite3*, BtCursor *, i64 *);
-SQLITE_PRIVATE int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*);
-SQLITE_PRIVATE int sqlite3VdbeExec(Vdbe*);
-SQLITE_PRIVATE int sqlite3VdbeList(Vdbe*);
-SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe*);
-SQLITE_PRIVATE int sqlite3VdbeChangeEncoding(Mem *, int);
-SQLITE_PRIVATE int sqlite3VdbeMemTooBig(Mem*);
-SQLITE_PRIVATE int sqlite3VdbeMemCopy(Mem*, const Mem*);
-SQLITE_PRIVATE void sqlite3VdbeMemShallowCopy(Mem*, const Mem*, int);
-SQLITE_PRIVATE void sqlite3VdbeMemMove(Mem*, Mem*);
-SQLITE_PRIVATE int sqlite3VdbeMemNulTerminate(Mem*);
-SQLITE_PRIVATE int sqlite3VdbeMemSetStr(Mem*, const char*, int, u8, void(*)(void*));
-SQLITE_PRIVATE void sqlite3VdbeMemSetInt64(Mem*, i64);
-SQLITE_PRIVATE void sqlite3VdbeMemSetDouble(Mem*, double);
-SQLITE_PRIVATE void sqlite3VdbeMemSetNull(Mem*);
-SQLITE_PRIVATE void sqlite3VdbeMemSetZeroBlob(Mem*,int);
-SQLITE_PRIVATE void sqlite3VdbeMemSetRowSet(Mem*);
-SQLITE_PRIVATE int sqlite3VdbeMemMakeWriteable(Mem*);
-SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem*, int);
-SQLITE_PRIVATE i64 sqlite3VdbeIntValue(Mem*);
-SQLITE_PRIVATE int sqlite3VdbeMemIntegerify(Mem*);
-SQLITE_PRIVATE double sqlite3VdbeRealValue(Mem*);
-SQLITE_PRIVATE void sqlite3VdbeIntegerAffinity(Mem*);
-SQLITE_PRIVATE int sqlite3VdbeMemRealify(Mem*);
-SQLITE_PRIVATE int sqlite3VdbeMemNumerify(Mem*);
-SQLITE_PRIVATE int sqlite3VdbeMemFromBtree(BtCursor*,int,int,int,Mem*);
-SQLITE_PRIVATE void sqlite3VdbeMemRelease(Mem *p);
-SQLITE_PRIVATE void sqlite3VdbeMemReleaseExternal(Mem *p);
-SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem*, FuncDef*);
-SQLITE_PRIVATE const char *sqlite3OpcodeName(int);
-SQLITE_PRIVATE int sqlite3VdbeOpcodeHasProperty(int, int);
-SQLITE_PRIVATE int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve);
-SQLITE_PRIVATE int sqlite3VdbeCloseStatement(Vdbe *, int);
-SQLITE_PRIVATE void sqlite3VdbeFrameDelete(VdbeFrame*);
-SQLITE_PRIVATE int sqlite3VdbeFrameRestore(VdbeFrame *);
-#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
-SQLITE_PRIVATE int sqlite3VdbeReleaseBuffers(Vdbe *p);
-#endif
-
-#ifndef SQLITE_OMIT_SHARED_CACHE
-SQLITE_PRIVATE void sqlite3VdbeMutexArrayEnter(Vdbe *p);
-#else
-# define sqlite3VdbeMutexArrayEnter(p)
-#endif
-
-SQLITE_PRIVATE int sqlite3VdbeMemTranslate(Mem*, u8);
-#ifdef SQLITE_DEBUG
-SQLITE_PRIVATE void sqlite3VdbePrintSql(Vdbe*);
-SQLITE_PRIVATE void sqlite3VdbeMemPrettyPrint(Mem *pMem, char *zBuf);
-#endif
-SQLITE_PRIVATE int sqlite3VdbeMemHandleBom(Mem *pMem);
-
-#ifndef SQLITE_OMIT_INCRBLOB
-SQLITE_PRIVATE int sqlite3VdbeMemExpandBlob(Mem *);
-#else
- #define sqlite3VdbeMemExpandBlob(x) SQLITE_OK
-#endif
-
-#endif /* !defined(_VDBEINT_H_) */
-
-/************** End of vdbeInt.h *********************************************/
-/************** Continuing where we left off in utf.c ************************/
-
-#ifndef SQLITE_AMALGAMATION
-/*
-** The following constant value is used by the SQLITE_BIGENDIAN and
-** SQLITE_LITTLEENDIAN macros.
-*/
-SQLITE_PRIVATE const int sqlite3one = 1;
-#endif /* SQLITE_AMALGAMATION */
-
-/*
-** This lookup table is used to help decode the first byte of
-** a multi-byte UTF8 character.
-*/
-static const unsigned char sqlite3Utf8Trans1[] = {
- 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
- 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
- 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
- 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
- 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
- 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
- 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
- 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x00, 0x00,
-};
-
-
-#define WRITE_UTF8(zOut, c) { \
- if( c<0x00080 ){ \
- *zOut++ = (u8)(c&0xFF); \
- } \
- else if( c<0x00800 ){ \
- *zOut++ = 0xC0 + (u8)((c>>6)&0x1F); \
- *zOut++ = 0x80 + (u8)(c & 0x3F); \
- } \
- else if( c<0x10000 ){ \
- *zOut++ = 0xE0 + (u8)((c>>12)&0x0F); \
- *zOut++ = 0x80 + (u8)((c>>6) & 0x3F); \
- *zOut++ = 0x80 + (u8)(c & 0x3F); \
- }else{ \
- *zOut++ = 0xF0 + (u8)((c>>18) & 0x07); \
- *zOut++ = 0x80 + (u8)((c>>12) & 0x3F); \
- *zOut++ = 0x80 + (u8)((c>>6) & 0x3F); \
- *zOut++ = 0x80 + (u8)(c & 0x3F); \
- } \
-}
-
-#define WRITE_UTF16LE(zOut, c) { \
- if( c<=0xFFFF ){ \
- *zOut++ = (u8)(c&0x00FF); \
- *zOut++ = (u8)((c>>8)&0x00FF); \
- }else{ \
- *zOut++ = (u8)(((c>>10)&0x003F) + (((c-0x10000)>>10)&0x00C0)); \
- *zOut++ = (u8)(0x00D8 + (((c-0x10000)>>18)&0x03)); \
- *zOut++ = (u8)(c&0x00FF); \
- *zOut++ = (u8)(0x00DC + ((c>>8)&0x03)); \
- } \
-}
-
-#define WRITE_UTF16BE(zOut, c) { \
- if( c<=0xFFFF ){ \
- *zOut++ = (u8)((c>>8)&0x00FF); \
- *zOut++ = (u8)(c&0x00FF); \
- }else{ \
- *zOut++ = (u8)(0x00D8 + (((c-0x10000)>>18)&0x03)); \
- *zOut++ = (u8)(((c>>10)&0x003F) + (((c-0x10000)>>10)&0x00C0)); \
- *zOut++ = (u8)(0x00DC + ((c>>8)&0x03)); \
- *zOut++ = (u8)(c&0x00FF); \
- } \
-}
-
-#define READ_UTF16LE(zIn, c){ \
- c = (*zIn++); \
- c += ((*zIn++)<<8); \
- if( c>=0xD800 && c<0xE000 ){ \
- int c2 = (*zIn++); \
- c2 += ((*zIn++)<<8); \
- c = (c2&0x03FF) + ((c&0x003F)<<10) + (((c&0x03C0)+0x0040)<<10); \
- } \
-}
-
-#define READ_UTF16BE(zIn, c){ \
- c = ((*zIn++)<<8); \
- c += (*zIn++); \
- if( c>=0xD800 && c<0xE000 ){ \
- int c2 = ((*zIn++)<<8); \
- c2 += (*zIn++); \
- c = (c2&0x03FF) + ((c&0x003F)<<10) + (((c&0x03C0)+0x0040)<<10); \
- } \
-}
-
-/*
-** Translate a single UTF-8 character. Return the unicode value.
-**
-** During translation, assume that the byte that zTerm points
-** is a 0x00.
-**
-** Write a pointer to the next unread byte back into *pzNext.
-**
-** Notes On Invalid UTF-8:
-**
-** * This routine never allows a 7-bit character (0x00 through 0x7f) to
-** be encoded as a multi-byte character. Any multi-byte character that
-** attempts to encode a value between 0x00 and 0x7f is rendered as 0xfffd.
-**
-** * This routine never allows a UTF16 surrogate value to be encoded.
-** If a multi-byte character attempts to encode a value between
-** 0xd800 and 0xe000 then it is rendered as 0xfffd.
-**
-** * Bytes in the range of 0x80 through 0xbf which occur as the first
-** byte of a character are interpreted as single-byte characters
-** and rendered as themselves even though they are technically
-** invalid characters.
-**
-** * This routine accepts an infinite number of different UTF8 encodings
-** for unicode values 0x80 and greater. It do not change over-length
-** encodings to 0xfffd as some systems recommend.
-*/
-#define READ_UTF8(zIn, zTerm, c) \
- c = *(zIn++); \
- if( c>=0xc0 ){ \
- c = sqlite3Utf8Trans1[c-0xc0]; \
- while( zIn!=zTerm && (*zIn & 0xc0)==0x80 ){ \
- c = (c<<6) + (0x3f & *(zIn++)); \
- } \
- if( c<0x80 \
- || (c&0xFFFFF800)==0xD800 \
- || (c&0xFFFFFFFE)==0xFFFE ){ c = 0xFFFD; } \
- }
-SQLITE_PRIVATE int sqlite3Utf8Read(
- const unsigned char *zIn, /* First byte of UTF-8 character */
- const unsigned char **pzNext /* Write first byte past UTF-8 char here */
-){
- int c;
-
- /* Same as READ_UTF8() above but without the zTerm parameter.
- ** For this routine, we assume the UTF8 string is always zero-terminated.
- */
- c = *(zIn++);
- if( c>=0xc0 ){
- c = sqlite3Utf8Trans1[c-0xc0];
- while( (*zIn & 0xc0)==0x80 ){
- c = (c<<6) + (0x3f & *(zIn++));
- }
- if( c<0x80
- || (c&0xFFFFF800)==0xD800
- || (c&0xFFFFFFFE)==0xFFFE ){ c = 0xFFFD; }
- }
- *pzNext = zIn;
- return c;
-}
-
-
-
-
-/*
-** If the TRANSLATE_TRACE macro is defined, the value of each Mem is
-** printed on stderr on the way into and out of sqlite3VdbeMemTranslate().
-*/
-/* #define TRANSLATE_TRACE 1 */
-
-#ifndef SQLITE_OMIT_UTF16
-/*
-** This routine transforms the internal text encoding used by pMem to
-** desiredEnc. It is an error if the string is already of the desired
-** encoding, or if *pMem does not contain a string value.
-*/
-SQLITE_PRIVATE int sqlite3VdbeMemTranslate(Mem *pMem, u8 desiredEnc){
- int len; /* Maximum length of output string in bytes */
- unsigned char *zOut; /* Output buffer */
- unsigned char *zIn; /* Input iterator */
- unsigned char *zTerm; /* End of input */
- unsigned char *z; /* Output iterator */
- unsigned int c;
-
- assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
- assert( pMem->flags&MEM_Str );
- assert( pMem->enc!=desiredEnc );
- assert( pMem->enc!=0 );
- assert( pMem->n>=0 );
-
-#if defined(TRANSLATE_TRACE) && defined(SQLITE_DEBUG)
- {
- char zBuf[100];
- sqlite3VdbeMemPrettyPrint(pMem, zBuf);
- fprintf(stderr, "INPUT: %s\n", zBuf);
- }
-#endif
-
- /* If the translation is between UTF-16 little and big endian, then
- ** all that is required is to swap the byte order. This case is handled
- ** differently from the others.
- */
- if( pMem->enc!=SQLITE_UTF8 && desiredEnc!=SQLITE_UTF8 ){
- u8 temp;
- int rc;
- rc = sqlite3VdbeMemMakeWriteable(pMem);
- if( rc!=SQLITE_OK ){
- assert( rc==SQLITE_NOMEM );
- return SQLITE_NOMEM;
- }
- zIn = (u8*)pMem->z;
- zTerm = &zIn[pMem->n&~1];
- while( zIn<zTerm ){
- temp = *zIn;
- *zIn = *(zIn+1);
- zIn++;
- *zIn++ = temp;
- }
- pMem->enc = desiredEnc;
- goto translate_out;
- }
-
- /* Set len to the maximum number of bytes required in the output buffer. */
- if( desiredEnc==SQLITE_UTF8 ){
- /* When converting from UTF-16, the maximum growth results from
- ** translating a 2-byte character to a 4-byte UTF-8 character.
- ** A single byte is required for the output string
- ** nul-terminator.
- */
- pMem->n &= ~1;
- len = pMem->n * 2 + 1;
- }else{
- /* When converting from UTF-8 to UTF-16 the maximum growth is caused
- ** when a 1-byte UTF-8 character is translated into a 2-byte UTF-16
- ** character. Two bytes are required in the output buffer for the
- ** nul-terminator.
- */
- len = pMem->n * 2 + 2;
- }
-
- /* Set zIn to point at the start of the input buffer and zTerm to point 1
- ** byte past the end.
- **
- ** Variable zOut is set to point at the output buffer, space obtained
- ** from sqlite3_malloc().
- */
- zIn = (u8*)pMem->z;
- zTerm = &zIn[pMem->n];
- zOut = sqlite3DbMallocRaw(pMem->db, len);
- if( !zOut ){
- return SQLITE_NOMEM;
- }
- z = zOut;
-
- if( pMem->enc==SQLITE_UTF8 ){
- if( desiredEnc==SQLITE_UTF16LE ){
- /* UTF-8 -> UTF-16 Little-endian */
- while( zIn<zTerm ){
- /* c = sqlite3Utf8Read(zIn, zTerm, (const u8**)&zIn); */
- READ_UTF8(zIn, zTerm, c);
- WRITE_UTF16LE(z, c);
- }
- }else{
- assert( desiredEnc==SQLITE_UTF16BE );
- /* UTF-8 -> UTF-16 Big-endian */
- while( zIn<zTerm ){
- /* c = sqlite3Utf8Read(zIn, zTerm, (const u8**)&zIn); */
- READ_UTF8(zIn, zTerm, c);
- WRITE_UTF16BE(z, c);
- }
- }
- pMem->n = (int)(z - zOut);
- *z++ = 0;
- }else{
- assert( desiredEnc==SQLITE_UTF8 );
- if( pMem->enc==SQLITE_UTF16LE ){
- /* UTF-16 Little-endian -> UTF-8 */
- while( zIn<zTerm ){
- READ_UTF16LE(zIn, c);
- WRITE_UTF8(z, c);
- }
- }else{
- /* UTF-16 Big-endian -> UTF-8 */
- while( zIn<zTerm ){
- READ_UTF16BE(zIn, c);
- WRITE_UTF8(z, c);
- }
- }
- pMem->n = (int)(z - zOut);
- }
- *z = 0;
- assert( (pMem->n+(desiredEnc==SQLITE_UTF8?1:2))<=len );
-
- sqlite3VdbeMemRelease(pMem);
- pMem->flags &= ~(MEM_Static|MEM_Dyn|MEM_Ephem);
- pMem->enc = desiredEnc;
- pMem->flags |= (MEM_Term|MEM_Dyn);
- pMem->z = (char*)zOut;
- pMem->zMalloc = pMem->z;
-
-translate_out:
-#if defined(TRANSLATE_TRACE) && defined(SQLITE_DEBUG)
- {
- char zBuf[100];
- sqlite3VdbeMemPrettyPrint(pMem, zBuf);
- fprintf(stderr, "OUTPUT: %s\n", zBuf);
- }
-#endif
- return SQLITE_OK;
-}
-
-/*
-** This routine checks for a byte-order mark at the beginning of the
-** UTF-16 string stored in *pMem. If one is present, it is removed and
-** the encoding of the Mem adjusted. This routine does not do any
-** byte-swapping, it just sets Mem.enc appropriately.
-**
-** The allocation (static, dynamic etc.) and encoding of the Mem may be
-** changed by this function.
-*/
-SQLITE_PRIVATE int sqlite3VdbeMemHandleBom(Mem *pMem){
- int rc = SQLITE_OK;
- u8 bom = 0;
-
- assert( pMem->n>=0 );
- if( pMem->n>1 ){
- u8 b1 = *(u8 *)pMem->z;
- u8 b2 = *(((u8 *)pMem->z) + 1);
- if( b1==0xFE && b2==0xFF ){
- bom = SQLITE_UTF16BE;
- }
- if( b1==0xFF && b2==0xFE ){
- bom = SQLITE_UTF16LE;
- }
- }
-
- if( bom ){
- rc = sqlite3VdbeMemMakeWriteable(pMem);
- if( rc==SQLITE_OK ){
- pMem->n -= 2;
- memmove(pMem->z, &pMem->z[2], pMem->n);
- pMem->z[pMem->n] = '\0';
- pMem->z[pMem->n+1] = '\0';
- pMem->flags |= MEM_Term;
- pMem->enc = bom;
- }
- }
- return rc;
-}
-#endif /* SQLITE_OMIT_UTF16 */
-
-/*
-** pZ is a UTF-8 encoded unicode string. If nByte is less than zero,
-** return the number of unicode characters in pZ up to (but not including)
-** the first 0x00 byte. If nByte is not less than zero, return the
-** number of unicode characters in the first nByte of pZ (or up to
-** the first 0x00, whichever comes first).
-*/
-SQLITE_PRIVATE int sqlite3Utf8CharLen(const char *zIn, int nByte){
- int r = 0;
- const u8 *z = (const u8*)zIn;
- const u8 *zTerm;
- if( nByte>=0 ){
- zTerm = &z[nByte];
- }else{
- zTerm = (const u8*)(-1);
- }
- assert( z<=zTerm );
- while( *z!=0 && z<zTerm ){
- SQLITE_SKIP_UTF8(z);
- r++;
- }
- return r;
-}
-
-/* This test function is not currently used by the automated test-suite.
-** Hence it is only available in debug builds.
-*/
-#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG)
-/*
-** Translate UTF-8 to UTF-8.
-**
-** This has the effect of making sure that the string is well-formed
-** UTF-8. Miscoded characters are removed.
-**
-** The translation is done in-place (since it is impossible for the
-** correct UTF-8 encoding to be longer than a malformed encoding).
-*/
-SQLITE_PRIVATE int sqlite3Utf8To8(unsigned char *zIn){
- unsigned char *zOut = zIn;
- unsigned char *zStart = zIn;
- u32 c;
-
- while( zIn[0] ){
- c = sqlite3Utf8Read(zIn, (const u8**)&zIn);
- if( c!=0xfffd ){
- WRITE_UTF8(zOut, c);
- }
- }
- *zOut = 0;
- return (int)(zOut - zStart);
-}
-#endif
-
-#ifndef SQLITE_OMIT_UTF16
-/*
-** Convert a UTF-16 string in the native encoding into a UTF-8 string.
-** Memory to hold the UTF-8 string is obtained from sqlite3_malloc and must
-** be freed by the calling function.
-**
-** NULL is returned if there is an allocation error.
-*/
-SQLITE_PRIVATE char *sqlite3Utf16to8(sqlite3 *db, const void *z, int nByte){
- Mem m;
- memset(&m, 0, sizeof(m));
- m.db = db;
- sqlite3VdbeMemSetStr(&m, z, nByte, SQLITE_UTF16NATIVE, SQLITE_STATIC);
- sqlite3VdbeChangeEncoding(&m, SQLITE_UTF8);
- if( db->mallocFailed ){
- sqlite3VdbeMemRelease(&m);
- m.z = 0;
- }
- assert( (m.flags & MEM_Term)!=0 || db->mallocFailed );
- assert( (m.flags & MEM_Str)!=0 || db->mallocFailed );
- return (m.flags & MEM_Dyn)!=0 ? m.z : sqlite3DbStrDup(db, m.z);
-}
-
-/*
-** Convert a UTF-8 string to the UTF-16 encoding specified by parameter
-** enc. A pointer to the new string is returned, and the value of *pnOut
-** is set to the length of the returned string in bytes. The call should
-** arrange to call sqlite3DbFree() on the returned pointer when it is
-** no longer required.
-**
-** If a malloc failure occurs, NULL is returned and the db.mallocFailed
-** flag set.
-*/
-#ifdef SQLITE_ENABLE_STAT2
-SQLITE_PRIVATE char *sqlite3Utf8to16(sqlite3 *db, u8 enc, char *z, int n, int *pnOut){
- Mem m;
- memset(&m, 0, sizeof(m));
- m.db = db;
- sqlite3VdbeMemSetStr(&m, z, n, SQLITE_UTF8, SQLITE_STATIC);
- if( sqlite3VdbeMemTranslate(&m, enc) ){
- assert( db->mallocFailed );
- return 0;
- }
- assert( m.z==m.zMalloc );
- *pnOut = m.n;
- return m.z;
-}
-#endif
-
-/*
-** pZ is a UTF-16 encoded unicode string at least nChar characters long.
-** Return the number of bytes in the first nChar unicode characters
-** in pZ. nChar must be non-negative.
-*/
-SQLITE_PRIVATE int sqlite3Utf16ByteLen(const void *zIn, int nChar){
- int c;
- unsigned char const *z = zIn;
- int n = 0;
- if( SQLITE_UTF16NATIVE==SQLITE_UTF16BE ){
- /* Using an "if (SQLITE_UTF16NATIVE==SQLITE_UTF16BE)" construct here
- ** and in other parts of this file means that at one branch will
- ** not be covered by coverage testing on any single host. But coverage
- ** will be complete if the tests are run on both a little-endian and
- ** big-endian host. Because both the UTF16NATIVE and SQLITE_UTF16BE
- ** macros are constant at compile time the compiler can determine
- ** which branch will be followed. It is therefore assumed that no runtime
- ** penalty is paid for this "if" statement.
- */
- while( n<nChar ){
- READ_UTF16BE(z, c);
- n++;
- }
- }else{
- while( n<nChar ){
- READ_UTF16LE(z, c);
- n++;
- }
- }
- return (int)(z-(unsigned char const *)zIn);
-}
-
-#if defined(SQLITE_TEST)
-/*
-** This routine is called from the TCL test function "translate_selftest".
-** It checks that the primitives for serializing and deserializing
-** characters in each encoding are inverses of each other.
-*/
-SQLITE_PRIVATE void sqlite3UtfSelfTest(void){
- unsigned int i, t;
- unsigned char zBuf[20];
- unsigned char *z;
- int n;
- unsigned int c;
-
- for(i=0; i<0x00110000; i++){
- z = zBuf;
- WRITE_UTF8(z, i);
- n = (int)(z-zBuf);
- assert( n>0 && n<=4 );
- z[0] = 0;
- z = zBuf;
- c = sqlite3Utf8Read(z, (const u8**)&z);
- t = i;
- if( i>=0xD800 && i<=0xDFFF ) t = 0xFFFD;
- if( (i&0xFFFFFFFE)==0xFFFE ) t = 0xFFFD;
- assert( c==t );
- assert( (z-zBuf)==n );
- }
- for(i=0; i<0x00110000; i++){
- if( i>=0xD800 && i<0xE000 ) continue;
- z = zBuf;
- WRITE_UTF16LE(z, i);
- n = (int)(z-zBuf);
- assert( n>0 && n<=4 );
- z[0] = 0;
- z = zBuf;
- READ_UTF16LE(z, c);
- assert( c==i );
- assert( (z-zBuf)==n );
- }
- for(i=0; i<0x00110000; i++){
- if( i>=0xD800 && i<0xE000 ) continue;
- z = zBuf;
- WRITE_UTF16BE(z, i);
- n = (int)(z-zBuf);
- assert( n>0 && n<=4 );
- z[0] = 0;
- z = zBuf;
- READ_UTF16BE(z, c);
- assert( c==i );
- assert( (z-zBuf)==n );
- }
-}
-#endif /* SQLITE_TEST */
-#endif /* SQLITE_OMIT_UTF16 */
-
-/************** End of utf.c *************************************************/
-/************** Begin file util.c ********************************************/
-/*
-** 2001 September 15
-**
-** 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.
-**
-*************************************************************************
-** Utility functions used throughout sqlite.
-**
-** This file contains functions for allocating memory, comparing
-** strings, and stuff like that.
-**
-*/
-#ifdef SQLITE_HAVE_ISNAN
-# include <math.h>
-#endif
-
-/*
-** Routine needed to support the testcase() macro.
-*/
-#ifdef SQLITE_COVERAGE_TEST
-SQLITE_PRIVATE void sqlite3Coverage(int x){
- static int dummy = 0;
- dummy += x;
-}
-#endif
-
-/*
-** Return true if the floating point value is Not a Number (NaN).
-**
-** Use the math library isnan() function if compiled with SQLITE_HAVE_ISNAN.
-** Otherwise, we have our own implementation that works on most systems.
-*/
-SQLITE_PRIVATE int sqlite3IsNaN(double x){
- int rc; /* The value return */
-#if !defined(SQLITE_HAVE_ISNAN)
- /*
- ** Systems that support the isnan() library function should probably
- ** make use of it by compiling with -DSQLITE_HAVE_ISNAN. But we have
- ** found that many systems do not have a working isnan() function so
- ** this implementation is provided as an alternative.
- **
- ** This NaN test sometimes fails if compiled on GCC with -ffast-math.
- ** On the other hand, the use of -ffast-math comes with the following
- ** warning:
- **
- ** This option [-ffast-math] should never be turned on by any
- ** -O option since it can result in incorrect output for programs
- ** which depend on an exact implementation of IEEE or ISO
- ** rules/specifications for math functions.
- **
- ** Under MSVC, this NaN test may fail if compiled with a floating-
- ** point precision mode other than /fp:precise. From the MSDN
- ** documentation:
- **
- ** The compiler [with /fp:precise] will properly handle comparisons
- ** involving NaN. For example, x != x evaluates to true if x is NaN
- ** ...
- */
-#ifdef __FAST_MATH__
-# error SQLite will not work correctly with the -ffast-math option of GCC.
-#endif
- volatile double y = x;
- volatile double z = y;
- rc = (y!=z);
-#else /* if defined(SQLITE_HAVE_ISNAN) */
- rc = isnan(x);
-#endif /* SQLITE_HAVE_ISNAN */
- testcase( rc );
- return rc;
-}
-
-/*
-** Compute a string length that is limited to what can be stored in
-** lower 30 bits of a 32-bit signed integer.
-**
-** The value returned will never be negative. Nor will it ever be greater
-** than the actual length of the string. For very long strings (greater
-** than 1GiB) the value returned might be less than the true string length.
-*/
-SQLITE_PRIVATE int sqlite3Strlen30(const char *z){
- const char *z2 = z;
- if( z==0 ) return 0;
- while( *z2 ){ z2++; }
- return 0x3fffffff & (int)(z2 - z);
-}
-
-/*
-** Set the most recent error code and error string for the sqlite
-** handle "db". The error code is set to "err_code".
-**
-** If it is not NULL, string zFormat specifies the format of the
-** error string in the style of the printf functions: The following
-** format characters are allowed:
-**
-** %s Insert a string
-** %z A string that should be freed after use
-** %d Insert an integer
-** %T Insert a token
-** %S Insert the first element of a SrcList
-**
-** zFormat and any string tokens that follow it are assumed to be
-** encoded in UTF-8.
-**
-** To clear the most recent error for sqlite handle "db", sqlite3Error
-** should be called with err_code set to SQLITE_OK and zFormat set
-** to NULL.
-*/
-SQLITE_PRIVATE void sqlite3Error(sqlite3 *db, int err_code, const char *zFormat, ...){
- if( db && (db->pErr || (db->pErr = sqlite3ValueNew(db))!=0) ){
- db->errCode = err_code;
- if( zFormat ){
- char *z;
- va_list ap;
- va_start(ap, zFormat);
- z = sqlite3VMPrintf(db, zFormat, ap);
- va_end(ap);
- sqlite3ValueSetStr(db->pErr, -1, z, SQLITE_UTF8, SQLITE_DYNAMIC);
- }else{
- sqlite3ValueSetStr(db->pErr, 0, 0, SQLITE_UTF8, SQLITE_STATIC);
- }
- }
-}
-
-/*
-** Add an error message to pParse->zErrMsg and increment pParse->nErr.
-** The following formatting characters are allowed:
-**
-** %s Insert a string
-** %z A string that should be freed after use
-** %d Insert an integer
-** %T Insert a token
-** %S Insert the first element of a SrcList
-**
-** This function should be used to report any error that occurs whilst
-** compiling an SQL statement (i.e. within sqlite3_prepare()). The
-** last thing the sqlite3_prepare() function does is copy the error
-** stored by this function into the database handle using sqlite3Error().
-** Function sqlite3Error() should be used during statement execution
-** (sqlite3_step() etc.).
-*/
-SQLITE_PRIVATE void sqlite3ErrorMsg(Parse *pParse, const char *zFormat, ...){
- va_list ap;
- sqlite3 *db = pParse->db;
- pParse->nErr++;
- sqlite3DbFree(db, pParse->zErrMsg);
- va_start(ap, zFormat);
- pParse->zErrMsg = sqlite3VMPrintf(db, zFormat, ap);
- va_end(ap);
- pParse->rc = SQLITE_ERROR;
-}
-
-/*
-** Clear the error message in pParse, if any
-*/
-SQLITE_PRIVATE void sqlite3ErrorClear(Parse *pParse){
- sqlite3DbFree(pParse->db, pParse->zErrMsg);
- pParse->zErrMsg = 0;
- pParse->nErr = 0;
-}
-
-/*
-** Convert an SQL-style quoted string into a normal string by removing
-** the quote characters. The conversion is done in-place. If the
-** input does not begin with a quote character, then this routine
-** is a no-op.
-**
-** The input string must be zero-terminated. A new zero-terminator
-** is added to the dequoted string.
-**
-** The return value is -1 if no dequoting occurs or the length of the
-** dequoted string, exclusive of the zero terminator, if dequoting does
-** occur.
-**
-** 2002-Feb-14: This routine is extended to remove MS-Access style
-** brackets from around identifers. For example: "[a-b-c]" becomes
-** "a-b-c".
-*/
-SQLITE_PRIVATE int sqlite3Dequote(char *z){
- char quote;
- int i, j;
- if( z==0 ) return -1;
- quote = z[0];
- switch( quote ){
- case '\'': break;
- case '"': break;
- case '`': break; /* For MySQL compatibility */
- case '[': quote = ']'; break; /* For MS SqlServer compatibility */
- default: return -1;
- }
- for(i=1, j=0; ALWAYS(z[i]); i++){
- if( z[i]==quote ){
- if( z[i+1]==quote ){
- z[j++] = quote;
- i++;
- }else{
- break;
- }
- }else{
- z[j++] = z[i];
- }
- }
- z[j] = 0;
- return j;
-}
-
-/* Convenient short-hand */
-#define UpperToLower sqlite3UpperToLower
-
-/*
-** Some systems have stricmp(). Others have strcasecmp(). Because
-** there is no consistency, we will define our own.
-*/
-SQLITE_PRIVATE int sqlite3StrICmp(const char *zLeft, const char *zRight){
- register unsigned char *a, *b;
- a = (unsigned char *)zLeft;
- b = (unsigned char *)zRight;
- while( *a!=0 && UpperToLower[*a]==UpperToLower[*b]){ a++; b++; }
- return UpperToLower[*a] - UpperToLower[*b];
-}
-SQLITE_API int sqlite3_strnicmp(const char *zLeft, const char *zRight, int N){
- register unsigned char *a, *b;
- a = (unsigned char *)zLeft;
- b = (unsigned char *)zRight;
- while( N-- > 0 && *a!=0 && UpperToLower[*a]==UpperToLower[*b]){ a++; b++; }
- return N<0 ? 0 : UpperToLower[*a] - UpperToLower[*b];
-}
-
-/*
-** Return TRUE if z is a pure numeric string. Return FALSE and leave
-** *realnum unchanged if the string contains any character which is not
-** part of a number.
-**
-** If the string is pure numeric, set *realnum to TRUE if the string
-** contains the '.' character or an "E+000" style exponentiation suffix.
-** Otherwise set *realnum to FALSE. Note that just becaue *realnum is
-** false does not mean that the number can be successfully converted into
-** an integer - it might be too big.
-**
-** An empty string is considered non-numeric.
-*/
-SQLITE_PRIVATE int sqlite3IsNumber(const char *z, int *realnum, u8 enc){
- int incr = (enc==SQLITE_UTF8?1:2);
- if( enc==SQLITE_UTF16BE ) z++;
- if( *z=='-' || *z=='+' ) z += incr;
- if( !sqlite3Isdigit(*z) ){
- return 0;
- }
- z += incr;
- *realnum = 0;
- while( sqlite3Isdigit(*z) ){ z += incr; }
- if( *z=='.' ){
- z += incr;
- if( !sqlite3Isdigit(*z) ) return 0;
- while( sqlite3Isdigit(*z) ){ z += incr; }
- *realnum = 1;
- }
- if( *z=='e' || *z=='E' ){
- z += incr;
- if( *z=='+' || *z=='-' ) z += incr;
- if( !sqlite3Isdigit(*z) ) return 0;
- while( sqlite3Isdigit(*z) ){ z += incr; }
- *realnum = 1;
- }
- return *z==0;
-}
-
-/*
-** The string z[] is an ASCII representation of a real number.
-** Convert this string to a double.
-**
-** This routine assumes that z[] really is a valid number. If it
-** is not, the result is undefined.
-**
-** This routine is used instead of the library atof() function because
-** the library atof() might want to use "," as the decimal point instead
-** of "." depending on how locale is set. But that would cause problems
-** for SQL. So this routine always uses "." regardless of locale.
-*/
-SQLITE_PRIVATE int sqlite3AtoF(const char *z, double *pResult){
-#ifndef SQLITE_OMIT_FLOATING_POINT
- const char *zBegin = z;
- /* sign * significand * (10 ^ (esign * exponent)) */
- int sign = 1; /* sign of significand */
- i64 s = 0; /* significand */
- int d = 0; /* adjust exponent for shifting decimal point */
- int esign = 1; /* sign of exponent */
- int e = 0; /* exponent */
- double result;
- int nDigits = 0;
-
- /* skip leading spaces */
- while( sqlite3Isspace(*z) ) z++;
- /* get sign of significand */
- if( *z=='-' ){
- sign = -1;
- z++;
- }else if( *z=='+' ){
- z++;
- }
- /* skip leading zeroes */
- while( z[0]=='0' ) z++, nDigits++;
-
- /* copy max significant digits to significand */
- while( sqlite3Isdigit(*z) && s<((LARGEST_INT64-9)/10) ){
- s = s*10 + (*z - '0');
- z++, nDigits++;
- }
- /* skip non-significant significand digits
- ** (increase exponent by d to shift decimal left) */
- while( sqlite3Isdigit(*z) ) z++, nDigits++, d++;
-
- /* if decimal point is present */
- if( *z=='.' ){
- z++;
- /* copy digits from after decimal to significand
- ** (decrease exponent by d to shift decimal right) */
- while( sqlite3Isdigit(*z) && s<((LARGEST_INT64-9)/10) ){
- s = s*10 + (*z - '0');
- z++, nDigits++, d--;
- }
- /* skip non-significant digits */
- while( sqlite3Isdigit(*z) ) z++, nDigits++;
- }
-
- /* if exponent is present */
- if( *z=='e' || *z=='E' ){
- z++;
- /* get sign of exponent */
- if( *z=='-' ){
- esign = -1;
- z++;
- }else if( *z=='+' ){
- z++;
- }
- /* copy digits to exponent */
- while( sqlite3Isdigit(*z) ){
- e = e*10 + (*z - '0');
- z++;
- }
- }
-
- /* adjust exponent by d, and update sign */
- e = (e*esign) + d;
- if( e<0 ) {
- esign = -1;
- e *= -1;
- } else {
- esign = 1;
- }
-
- /* if 0 significand */
- if( !s ) {
- /* In the IEEE 754 standard, zero is signed.
- ** Add the sign if we've seen at least one digit */
- result = (sign<0 && nDigits) ? -(double)0 : (double)0;
- } else {
- /* attempt to reduce exponent */
- if( esign>0 ){
- while( s<(LARGEST_INT64/10) && e>0 ) e--,s*=10;
- }else{
- while( !(s%10) && e>0 ) e--,s/=10;
- }
-
- /* adjust the sign of significand */
- s = sign<0 ? -s : s;
-
- /* if exponent, scale significand as appropriate
- ** and store in result. */
- if( e ){
- double scale = 1.0;
- /* attempt to handle extremely small/large numbers better */
- if( e>307 && e<342 ){
- while( e%308 ) { scale *= 1.0e+1; e -= 1; }
- if( esign<0 ){
- result = s / scale;
- result /= 1.0e+308;
- }else{
- result = s * scale;
- result *= 1.0e+308;
- }
- }else{
- /* 1.0e+22 is the largest power of 10 than can be
- ** represented exactly. */
- while( e%22 ) { scale *= 1.0e+1; e -= 1; }
- while( e>0 ) { scale *= 1.0e+22; e -= 22; }
- if( esign<0 ){
- result = s / scale;
- }else{
- result = s * scale;
- }
- }
- } else {
- result = (double)s;
- }
- }
-
- /* store the result */
- *pResult = result;
-
- /* return number of characters used */
- return (int)(z - zBegin);
-#else
- return sqlite3Atoi64(z, pResult);
-#endif /* SQLITE_OMIT_FLOATING_POINT */
-}
-
-/*
-** Compare the 19-character string zNum against the text representation
-** value 2^63: 9223372036854775808. Return negative, zero, or positive
-** if zNum is less than, equal to, or greater than the string.
-**
-** Unlike memcmp() this routine is guaranteed to return the difference
-** in the values of the last digit if the only difference is in the
-** last digit. So, for example,
-**
-** compare2pow63("9223372036854775800")
-**
-** will return -8.
-*/
-static int compare2pow63(const char *zNum){
- int c;
- c = memcmp(zNum,"922337203685477580",18)*10;
- if( c==0 ){
- c = zNum[18] - '8';
- }
- return c;
-}
-
-
-/*
-** Return TRUE if zNum is a 64-bit signed integer and write
-** the value of the integer into *pNum. If zNum is not an integer
-** or is an integer that is too large to be expressed with 64 bits,
-** then return false.
-**
-** When this routine was originally written it dealt with only
-** 32-bit numbers. At that time, it was much faster than the
-** atoi() library routine in RedHat 7.2.
-*/
-SQLITE_PRIVATE int sqlite3Atoi64(const char *zNum, i64 *pNum){
- i64 v = 0;
- int neg;
- int i, c;
- const char *zStart;
- while( sqlite3Isspace(*zNum) ) zNum++;
- if( *zNum=='-' ){
- neg = 1;
- zNum++;
- }else if( *zNum=='+' ){
- neg = 0;
- zNum++;
- }else{
- neg = 0;
- }
- zStart = zNum;
- while( zNum[0]=='0' ){ zNum++; } /* Skip over leading zeros. Ticket #2454 */
- for(i=0; (c=zNum[i])>='0' && c<='9'; i++){
- v = v*10 + c - '0';
- }
- *pNum = neg ? -v : v;
- if( c!=0 || (i==0 && zStart==zNum) || i>19 ){
- /* zNum is empty or contains non-numeric text or is longer
- ** than 19 digits (thus guaranting that it is too large) */
- return 0;
- }else if( i<19 ){
- /* Less than 19 digits, so we know that it fits in 64 bits */
- return 1;
- }else{
- /* 19-digit numbers must be no larger than 9223372036854775807 if positive
- ** or 9223372036854775808 if negative. Note that 9223372036854665808
- ** is 2^63. */
- return compare2pow63(zNum)<neg;
- }
-}
-
-/*
-** The string zNum represents an unsigned integer. The zNum string
-** consists of one or more digit characters and is terminated by
-** a zero character. Any stray characters in zNum result in undefined
-** behavior.
-**
-** If the unsigned integer that zNum represents will fit in a
-** 64-bit signed integer, return TRUE. Otherwise return FALSE.
-**
-** If the negFlag parameter is true, that means that zNum really represents
-** a negative number. (The leading "-" is omitted from zNum.) This
-** parameter is needed to determine a boundary case. A string
-** of "9223373036854775808" returns false if negFlag is false or true
-** if negFlag is true.
-**
-** Leading zeros are ignored.
-*/
-SQLITE_PRIVATE int sqlite3FitsIn64Bits(const char *zNum, int negFlag){
- int i;
- int neg = 0;
-
- assert( zNum[0]>='0' && zNum[0]<='9' ); /* zNum is an unsigned number */
-
- if( negFlag ) neg = 1-neg;
- while( *zNum=='0' ){
- zNum++; /* Skip leading zeros. Ticket #2454 */
- }
- for(i=0; zNum[i]; i++){ assert( zNum[i]>='0' && zNum[i]<='9' ); }
- if( i<19 ){
- /* Guaranteed to fit if less than 19 digits */
- return 1;
- }else if( i>19 ){
- /* Guaranteed to be too big if greater than 19 digits */
- return 0;
- }else{
- /* Compare against 2^63. */
- return compare2pow63(zNum)<neg;
- }
-}
-
-/*
-** If zNum represents an integer that will fit in 32-bits, then set
-** *pValue to that integer and return true. Otherwise return false.
-**
-** Any non-numeric characters that following zNum are ignored.
-** This is different from sqlite3Atoi64() which requires the
-** input number to be zero-terminated.
-*/
-SQLITE_PRIVATE int sqlite3GetInt32(const char *zNum, int *pValue){
- sqlite_int64 v = 0;
- int i, c;
- int neg = 0;
- if( zNum[0]=='-' ){
- neg = 1;
- zNum++;
- }else if( zNum[0]=='+' ){
- zNum++;
- }
- while( zNum[0]=='0' ) zNum++;
- for(i=0; i<11 && (c = zNum[i] - '0')>=0 && c<=9; i++){
- v = v*10 + c;
- }
-
- /* The longest decimal representation of a 32 bit integer is 10 digits:
- **
- ** 1234567890
- ** 2^31 -> 2147483648
- */
- if( i>10 ){
- return 0;
- }
- if( v-neg>2147483647 ){
- return 0;
- }
- if( neg ){
- v = -v;
- }
- *pValue = (int)v;
- return 1;
-}
-
-/*
-** The variable-length integer encoding is as follows:
-**
-** KEY:
-** A = 0xxxxxxx 7 bits of data and one flag bit
-** B = 1xxxxxxx 7 bits of data and one flag bit
-** C = xxxxxxxx 8 bits of data
-**
-** 7 bits - A
-** 14 bits - BA
-** 21 bits - BBA
-** 28 bits - BBBA
-** 35 bits - BBBBA
-** 42 bits - BBBBBA
-** 49 bits - BBBBBBA
-** 56 bits - BBBBBBBA
-** 64 bits - BBBBBBBBC
-*/
-
-/*
-** Write a 64-bit variable-length integer to memory starting at p[0].
-** The length of data write will be between 1 and 9 bytes. The number
-** of bytes written is returned.
-**
-** A variable-length integer consists of the lower 7 bits of each byte
-** for all bytes that have the 8th bit set and one byte with the 8th
-** bit clear. Except, if we get to the 9th byte, it stores the full
-** 8 bits and is the last byte.
-*/
-SQLITE_PRIVATE int sqlite3PutVarint(unsigned char *p, u64 v){
- int i, j, n;
- u8 buf[10];
- if( v & (((u64)0xff000000)<<32) ){
- p[8] = (u8)v;
- v >>= 8;
- for(i=7; i>=0; i--){
- p[i] = (u8)((v & 0x7f) | 0x80);
- v >>= 7;
- }
- return 9;
- }
- n = 0;
- do{
- buf[n++] = (u8)((v & 0x7f) | 0x80);
- v >>= 7;
- }while( v!=0 );
- buf[0] &= 0x7f;
- assert( n<=9 );
- for(i=0, j=n-1; j>=0; j--, i++){
- p[i] = buf[j];
- }
- return n;
-}
-
-/*
-** This routine is a faster version of sqlite3PutVarint() that only
-** works for 32-bit positive integers and which is optimized for
-** the common case of small integers. A MACRO version, putVarint32,
-** is provided which inlines the single-byte case. All code should use
-** the MACRO version as this function assumes the single-byte case has
-** already been handled.
-*/
-SQLITE_PRIVATE int sqlite3PutVarint32(unsigned char *p, u32 v){
-#ifndef putVarint32
- if( (v & ~0x7f)==0 ){
- p[0] = v;
- return 1;
- }
-#endif
- if( (v & ~0x3fff)==0 ){
- p[0] = (u8)((v>>7) | 0x80);
- p[1] = (u8)(v & 0x7f);
- return 2;
- }
- return sqlite3PutVarint(p, v);
-}
-
-/*
-** Read a 64-bit variable-length integer from memory starting at p[0].
-** Return the number of bytes read. The value is stored in *v.
-*/
-SQLITE_PRIVATE u8 sqlite3GetVarint(const unsigned char *p, u64 *v){
- u32 a,b,s;
-
- a = *p;
- /* a: p0 (unmasked) */
- if (!(a&0x80))
- {
- *v = a;
- return 1;
- }
-
- p++;
- b = *p;
- /* b: p1 (unmasked) */
- if (!(b&0x80))
- {
- a &= 0x7f;
- a = a<<7;
- a |= b;
- *v = a;
- return 2;
- }
-
- p++;
- a = a<<14;
- a |= *p;
- /* a: p0<<14 | p2 (unmasked) */
- if (!(a&0x80))
- {
- a &= (0x7f<<14)|(0x7f);
- b &= 0x7f;
- b = b<<7;
- a |= b;
- *v = a;
- return 3;
- }
-
- /* CSE1 from below */
- a &= (0x7f<<14)|(0x7f);
- p++;
- b = b<<14;
- b |= *p;
- /* b: p1<<14 | p3 (unmasked) */
- if (!(b&0x80))
- {
- b &= (0x7f<<14)|(0x7f);
- /* moved CSE1 up */
- /* a &= (0x7f<<14)|(0x7f); */
- a = a<<7;
- a |= b;
- *v = a;
- return 4;
- }
-
- /* a: p0<<14 | p2 (masked) */
- /* b: p1<<14 | p3 (unmasked) */
- /* 1:save off p0<<21 | p1<<14 | p2<<7 | p3 (masked) */
- /* moved CSE1 up */
- /* a &= (0x7f<<14)|(0x7f); */
- b &= (0x7f<<14)|(0x7f);
- s = a;
- /* s: p0<<14 | p2 (masked) */
-
- p++;
- a = a<<14;
- a |= *p;
- /* a: p0<<28 | p2<<14 | p4 (unmasked) */
- if (!(a&0x80))
- {
- /* we can skip these cause they were (effectively) done above in calc'ing s */
- /* a &= (0x7f<<28)|(0x7f<<14)|(0x7f); */
- /* b &= (0x7f<<14)|(0x7f); */
- b = b<<7;
- a |= b;
- s = s>>18;
- *v = ((u64)s)<<32 | a;
- return 5;
- }
-
- /* 2:save off p0<<21 | p1<<14 | p2<<7 | p3 (masked) */
- s = s<<7;
- s |= b;
- /* s: p0<<21 | p1<<14 | p2<<7 | p3 (masked) */
-
- p++;
- b = b<<14;
- b |= *p;
- /* b: p1<<28 | p3<<14 | p5 (unmasked) */
- if (!(b&0x80))
- {
- /* we can skip this cause it was (effectively) done above in calc'ing s */
- /* b &= (0x7f<<28)|(0x7f<<14)|(0x7f); */
- a &= (0x7f<<14)|(0x7f);
- a = a<<7;
- a |= b;
- s = s>>18;
- *v = ((u64)s)<<32 | a;
- return 6;
- }
-
- p++;
- a = a<<14;
- a |= *p;
- /* a: p2<<28 | p4<<14 | p6 (unmasked) */
- if (!(a&0x80))
- {
- a &= (0x1f<<28)|(0x7f<<14)|(0x7f);
- b &= (0x7f<<14)|(0x7f);
- b = b<<7;
- a |= b;
- s = s>>11;
- *v = ((u64)s)<<32 | a;
- return 7;
- }
-
- /* CSE2 from below */
- a &= (0x7f<<14)|(0x7f);
- p++;
- b = b<<14;
- b |= *p;
- /* b: p3<<28 | p5<<14 | p7 (unmasked) */
- if (!(b&0x80))
- {
- b &= (0x1f<<28)|(0x7f<<14)|(0x7f);
- /* moved CSE2 up */
- /* a &= (0x7f<<14)|(0x7f); */
- a = a<<7;
- a |= b;
- s = s>>4;
- *v = ((u64)s)<<32 | a;
- return 8;
- }
-
- p++;
- a = a<<15;
- a |= *p;
- /* a: p4<<29 | p6<<15 | p8 (unmasked) */
-
- /* moved CSE2 up */
- /* a &= (0x7f<<29)|(0x7f<<15)|(0xff); */
- b &= (0x7f<<14)|(0x7f);
- b = b<<8;
- a |= b;
-
- s = s<<4;
- b = p[-4];
- b &= 0x7f;
- b = b>>3;
- s |= b;
-
- *v = ((u64)s)<<32 | a;
-
- return 9;
-}
-
-/*
-** Read a 32-bit variable-length integer from memory starting at p[0].
-** Return the number of bytes read. The value is stored in *v.
-**
-** If the varint stored in p[0] is larger than can fit in a 32-bit unsigned
-** integer, then set *v to 0xffffffff.
-**
-** A MACRO version, getVarint32, is provided which inlines the
-** single-byte case. All code should use the MACRO version as
-** this function assumes the single-byte case has already been handled.
-*/
-SQLITE_PRIVATE u8 sqlite3GetVarint32(const unsigned char *p, u32 *v){
- u32 a,b;
-
- /* The 1-byte case. Overwhelmingly the most common. Handled inline
- ** by the getVarin32() macro */
- a = *p;
- /* a: p0 (unmasked) */
-#ifndef getVarint32
- if (!(a&0x80))
- {
- /* Values between 0 and 127 */
- *v = a;
- return 1;
- }
-#endif
-
- /* The 2-byte case */
- p++;
- b = *p;
- /* b: p1 (unmasked) */
- if (!(b&0x80))
- {
- /* Values between 128 and 16383 */
- a &= 0x7f;
- a = a<<7;
- *v = a | b;
- return 2;
- }
-
- /* The 3-byte case */
- p++;
- a = a<<14;
- a |= *p;
- /* a: p0<<14 | p2 (unmasked) */
- if (!(a&0x80))
- {
- /* Values between 16384 and 2097151 */
- a &= (0x7f<<14)|(0x7f);
- b &= 0x7f;
- b = b<<7;
- *v = a | b;
- return 3;
- }
-
- /* A 32-bit varint is used to store size information in btrees.
- ** Objects are rarely larger than 2MiB limit of a 3-byte varint.
- ** A 3-byte varint is sufficient, for example, to record the size
- ** of a 1048569-byte BLOB or string.
- **
- ** We only unroll the first 1-, 2-, and 3- byte cases. The very
- ** rare larger cases can be handled by the slower 64-bit varint
- ** routine.
- */
-#if 1
- {
- u64 v64;
- u8 n;
-
- p -= 2;
- n = sqlite3GetVarint(p, &v64);
- assert( n>3 && n<=9 );
- if( (v64 & SQLITE_MAX_U32)!=v64 ){
- *v = 0xffffffff;
- }else{
- *v = (u32)v64;
- }
- return n;
- }
-
-#else
- /* For following code (kept for historical record only) shows an
- ** unrolling for the 3- and 4-byte varint cases. This code is
- ** slightly faster, but it is also larger and much harder to test.
- */
- p++;
- b = b<<14;
- b |= *p;
- /* b: p1<<14 | p3 (unmasked) */
- if (!(b&0x80))
- {
- /* Values between 2097152 and 268435455 */
- b &= (0x7f<<14)|(0x7f);
- a &= (0x7f<<14)|(0x7f);
- a = a<<7;
- *v = a | b;
- return 4;
- }
-
- p++;
- a = a<<14;
- a |= *p;
- /* a: p0<<28 | p2<<14 | p4 (unmasked) */
- if (!(a&0x80))
- {
- /* Walues between 268435456 and 34359738367 */
- a &= (0x1f<<28)|(0x7f<<14)|(0x7f);
- b &= (0x1f<<28)|(0x7f<<14)|(0x7f);
- b = b<<7;
- *v = a | b;
- return 5;
- }
-
- /* We can only reach this point when reading a corrupt database
- ** file. In that case we are not in any hurry. Use the (relatively
- ** slow) general-purpose sqlite3GetVarint() routine to extract the
- ** value. */
- {
- u64 v64;
- u8 n;
-
- p -= 4;
- n = sqlite3GetVarint(p, &v64);
- assert( n>5 && n<=9 );
- *v = (u32)v64;
- return n;
- }
-#endif
-}
-
-/*
-** Return the number of bytes that will be needed to store the given
-** 64-bit integer.
-*/
-SQLITE_PRIVATE int sqlite3VarintLen(u64 v){
- int i = 0;
- do{
- i++;
- v >>= 7;
- }while( v!=0 && ALWAYS(i<9) );
- return i;
-}
-
-
-/*
-** Read or write a four-byte big-endian integer value.
-*/
-SQLITE_PRIVATE u32 sqlite3Get4byte(const u8 *p){
- return (p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3];
-}
-SQLITE_PRIVATE void sqlite3Put4byte(unsigned char *p, u32 v){
- p[0] = (u8)(v>>24);
- p[1] = (u8)(v>>16);
- p[2] = (u8)(v>>8);
- p[3] = (u8)v;
-}
-
-
-
-#if !defined(SQLITE_OMIT_BLOB_LITERAL) || defined(SQLITE_HAS_CODEC)
-/*
-** Translate a single byte of Hex into an integer.
-** This routine only works if h really is a valid hexadecimal
-** character: 0..9a..fA..F
-*/
-static u8 hexToInt(int h){
- assert( (h>='0' && h<='9') || (h>='a' && h<='f') || (h>='A' && h<='F') );
-#ifdef SQLITE_ASCII
- h += 9*(1&(h>>6));
-#endif
-#ifdef SQLITE_EBCDIC
- h += 9*(1&~(h>>4));
-#endif
- return (u8)(h & 0xf);
-}
-#endif /* !SQLITE_OMIT_BLOB_LITERAL || SQLITE_HAS_CODEC */
-
-#if !defined(SQLITE_OMIT_BLOB_LITERAL) || defined(SQLITE_HAS_CODEC)
-/*
-** Convert a BLOB literal of the form "x'hhhhhh'" into its binary
-** value. Return a pointer to its binary value. Space to hold the
-** binary value has been obtained from malloc and must be freed by
-** the calling routine.
-*/
-SQLITE_PRIVATE void *sqlite3HexToBlob(sqlite3 *db, const char *z, int n){
- char *zBlob;
- int i;
-
- zBlob = (char *)sqlite3DbMallocRaw(db, n/2 + 1);
- n--;
- if( zBlob ){
- for(i=0; i<n; i+=2){
- zBlob[i/2] = (hexToInt(z[i])<<4) | hexToInt(z[i+1]);
- }
- zBlob[i/2] = 0;
- }
- return zBlob;
-}
-#endif /* !SQLITE_OMIT_BLOB_LITERAL || SQLITE_HAS_CODEC */
-
-
-/*
-** Change the sqlite.magic from SQLITE_MAGIC_OPEN to SQLITE_MAGIC_BUSY.
-** Return an error (non-zero) if the magic was not SQLITE_MAGIC_OPEN
-** when this routine is called.
-**
-** This routine is called when entering an SQLite API. The SQLITE_MAGIC_OPEN
-** value indicates that the database connection passed into the API is
-** open and is not being used by another thread. By changing the value
-** to SQLITE_MAGIC_BUSY we indicate that the connection is in use.
-** sqlite3SafetyOff() below will change the value back to SQLITE_MAGIC_OPEN
-** when the API exits.
-**
-** This routine is a attempt to detect if two threads use the
-** same sqlite* pointer at the same time. There is a race
-** condition so it is possible that the error is not detected.
-** But usually the problem will be seen. The result will be an
-** error which can be used to debug the application that is
-** using SQLite incorrectly.
-**
-** Ticket #202: If db->magic is not a valid open value, take care not
-** to modify the db structure at all. It could be that db is a stale
-** pointer. In other words, it could be that there has been a prior
-** call to sqlite3_close(db) and db has been deallocated. And we do
-** not want to write into deallocated memory.
-*/
-#ifdef SQLITE_DEBUG
-SQLITE_PRIVATE int sqlite3SafetyOn(sqlite3 *db){
- if( db->magic==SQLITE_MAGIC_OPEN ){
- db->magic = SQLITE_MAGIC_BUSY;
- assert( sqlite3_mutex_held(db->mutex) );
- return 0;
- }else if( db->magic==SQLITE_MAGIC_BUSY ){
- db->magic = SQLITE_MAGIC_ERROR;
- db->u1.isInterrupted = 1;
- }
- return 1;
-}
-#endif
-
-/*
-** Change the magic from SQLITE_MAGIC_BUSY to SQLITE_MAGIC_OPEN.
-** Return an error (non-zero) if the magic was not SQLITE_MAGIC_BUSY
-** when this routine is called.
-*/
-#ifdef SQLITE_DEBUG
-SQLITE_PRIVATE int sqlite3SafetyOff(sqlite3 *db){
- if( db->magic==SQLITE_MAGIC_BUSY ){
- db->magic = SQLITE_MAGIC_OPEN;
- assert( sqlite3_mutex_held(db->mutex) );
- return 0;
- }else{
- db->magic = SQLITE_MAGIC_ERROR;
- db->u1.isInterrupted = 1;
- return 1;
- }
-}
-#endif
-
-/*
-** Check to make sure we have a valid db pointer. This test is not
-** foolproof but it does provide some measure of protection against
-** misuse of the interface such as passing in db pointers that are
-** NULL or which have been previously closed. If this routine returns
-** 1 it means that the db pointer is valid and 0 if it should not be
-** dereferenced for any reason. The calling function should invoke
-** SQLITE_MISUSE immediately.
-**
-** sqlite3SafetyCheckOk() requires that the db pointer be valid for
-** use. sqlite3SafetyCheckSickOrOk() allows a db pointer that failed to
-** open properly and is not fit for general use but which can be
-** used as an argument to sqlite3_errmsg() or sqlite3_close().
-*/
-SQLITE_PRIVATE int sqlite3SafetyCheckOk(sqlite3 *db){
- u32 magic;
- if( db==0 ) return 0;
- magic = db->magic;
- if( magic!=SQLITE_MAGIC_OPEN
-#ifdef SQLITE_DEBUG
- && magic!=SQLITE_MAGIC_BUSY
-#endif
- ){
- return 0;
- }else{
- return 1;
- }
-}
-SQLITE_PRIVATE int sqlite3SafetyCheckSickOrOk(sqlite3 *db){
- u32 magic;
- magic = db->magic;
- if( magic!=SQLITE_MAGIC_SICK &&
- magic!=SQLITE_MAGIC_OPEN &&
- magic!=SQLITE_MAGIC_BUSY ) return 0;
- return 1;
-}
-
-/************** End of util.c ************************************************/
-/************** Begin file hash.c ********************************************/
-/*
-** 2001 September 22
-**
-** 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 is the implementation of generic hash-tables
-** used in SQLite.
-**
-** $Id: hash.c,v 1.38 2009/05/09 23:29:12 drh Exp $
-*/
-
-/* Turn bulk memory into a hash table object by initializing the
-** fields of the Hash structure.
-**
-** "pNew" is a pointer to the hash table that is to be initialized.
-*/
-SQLITE_PRIVATE void sqlite3HashInit(Hash *pNew){
- assert( pNew!=0 );
- pNew->first = 0;
- pNew->count = 0;
- pNew->htsize = 0;
- pNew->ht = 0;
-}
-
-/* Remove all entries from a hash table. Reclaim all memory.
-** Call this routine to delete a hash table or to reset a hash table
-** to the empty state.
-*/
-SQLITE_PRIVATE void sqlite3HashClear(Hash *pH){
- HashElem *elem; /* For looping over all elements of the table */
-
- assert( pH!=0 );
- elem = pH->first;
- pH->first = 0;
- sqlite3_free(pH->ht);
- pH->ht = 0;
- pH->htsize = 0;
- while( elem ){
- HashElem *next_elem = elem->next;
- sqlite3_free(elem);
- elem = next_elem;
- }
- pH->count = 0;
-}
-
-/*
-** The hashing function.
-*/
-static unsigned int strHash(const char *z, int nKey){
- int h = 0;
- assert( nKey>=0 );
- while( nKey > 0 ){
- h = (h<<3) ^ h ^ sqlite3UpperToLower[(unsigned char)*z++];
- nKey--;
- }
- return h;
-}
-
-
-/* Link pNew element into the hash table pH. If pEntry!=0 then also
-** insert pNew into the pEntry hash bucket.
-*/
-static void insertElement(
- Hash *pH, /* The complete hash table */
- struct _ht *pEntry, /* The entry into which pNew is inserted */
- HashElem *pNew /* The element to be inserted */
-){
- HashElem *pHead; /* First element already in pEntry */
- if( pEntry ){
- pHead = pEntry->count ? pEntry->chain : 0;
- pEntry->count++;
- pEntry->chain = pNew;
- }else{
- pHead = 0;
- }
- if( pHead ){
- pNew->next = pHead;
- pNew->prev = pHead->prev;
- if( pHead->prev ){ pHead->prev->next = pNew; }
- else { pH->first = pNew; }
- pHead->prev = pNew;
- }else{
- pNew->next = pH->first;
- if( pH->first ){ pH->first->prev = pNew; }
- pNew->prev = 0;
- pH->first = pNew;
- }
-}
-
-
-/* Resize the hash table so that it cantains "new_size" buckets.
-**
-** The hash table might fail to resize if sqlite3_malloc() fails or
-** if the new size is the same as the prior size.
-** Return TRUE if the resize occurs and false if not.
-*/
-static int rehash(Hash *pH, unsigned int new_size){
- struct _ht *new_ht; /* The new hash table */
- HashElem *elem, *next_elem; /* For looping over existing elements */
-
-#if SQLITE_MALLOC_SOFT_LIMIT>0
- if( new_size*sizeof(struct _ht)>SQLITE_MALLOC_SOFT_LIMIT ){
- new_size = SQLITE_MALLOC_SOFT_LIMIT/sizeof(struct _ht);
- }
- if( new_size==pH->htsize ) return 0;
-#endif
-
- /* The inability to allocates space for a larger hash table is
- ** a performance hit but it is not a fatal error. So mark the
- ** allocation as a benign.
- */
- sqlite3BeginBenignMalloc();
- new_ht = (struct _ht *)sqlite3Malloc( new_size*sizeof(struct _ht) );
- sqlite3EndBenignMalloc();
-
- if( new_ht==0 ) return 0;
- sqlite3_free(pH->ht);
- pH->ht = new_ht;
- pH->htsize = new_size = sqlite3MallocSize(new_ht)/sizeof(struct _ht);
- memset(new_ht, 0, new_size*sizeof(struct _ht));
- for(elem=pH->first, pH->first=0; elem; elem = next_elem){
- unsigned int h = strHash(elem->pKey, elem->nKey) % new_size;
- next_elem = elem->next;
- insertElement(pH, &new_ht[h], elem);
- }
- return 1;
-}
-
-/* This function (for internal use only) locates an element in an
-** hash table that matches the given key. The hash for this key has
-** already been computed and is passed as the 4th parameter.
-*/
-static HashElem *findElementGivenHash(
- const Hash *pH, /* The pH to be searched */
- const char *pKey, /* The key we are searching for */
- int nKey, /* Bytes in key (not counting zero terminator) */
- unsigned int h /* The hash for this key. */
-){
- HashElem *elem; /* Used to loop thru the element list */
- int count; /* Number of elements left to test */
-
- if( pH->ht ){
- struct _ht *pEntry = &pH->ht[h];
- elem = pEntry->chain;
- count = pEntry->count;
- }else{
- elem = pH->first;
- count = pH->count;
- }
- while( count-- && ALWAYS(elem) ){
- if( elem->nKey==nKey && sqlite3StrNICmp(elem->pKey,pKey,nKey)==0 ){
- return elem;
- }
- elem = elem->next;
- }
- return 0;
-}
-
-/* Remove a single entry from the hash table given a pointer to that
-** element and a hash on the element's key.
-*/
-static void removeElementGivenHash(
- Hash *pH, /* The pH containing "elem" */
- HashElem* elem, /* The element to be removed from the pH */
- unsigned int h /* Hash value for the element */
-){
- struct _ht *pEntry;
- if( elem->prev ){
- elem->prev->next = elem->next;
- }else{
- pH->first = elem->next;
- }
- if( elem->next ){
- elem->next->prev = elem->prev;
- }
- if( pH->ht ){
- pEntry = &pH->ht[h];
- if( pEntry->chain==elem ){
- pEntry->chain = elem->next;
- }
- pEntry->count--;
- assert( pEntry->count>=0 );
- }
- sqlite3_free( elem );
- pH->count--;
- if( pH->count<=0 ){
- assert( pH->first==0 );
- assert( pH->count==0 );
- sqlite3HashClear(pH);
- }
-}
-
-/* Attempt to locate an element of the hash table pH with a key
-** that matches pKey,nKey. Return the data for this element if it is
-** found, or NULL if there is no match.
-*/
-SQLITE_PRIVATE void *sqlite3HashFind(const Hash *pH, const char *pKey, int nKey){
- HashElem *elem; /* The element that matches key */
- unsigned int h; /* A hash on key */
-
- assert( pH!=0 );
- assert( pKey!=0 );
- assert( nKey>=0 );
- if( pH->ht ){
- h = strHash(pKey, nKey) % pH->htsize;
- }else{
- h = 0;
- }
- elem = findElementGivenHash(pH, pKey, nKey, h);
- return elem ? elem->data : 0;
-}
-
-/* Insert an element into the hash table pH. The key is pKey,nKey
-** and the data is "data".
-**
-** If no element exists with a matching key, then a new
-** element is created and NULL is returned.
-**
-** If another element already exists with the same key, then the
-** new data replaces the old data and the old data is returned.
-** The key is not copied in this instance. If a malloc fails, then
-** the new data is returned and the hash table is unchanged.
-**
-** If the "data" parameter to this function is NULL, then the
-** element corresponding to "key" is removed from the hash table.
-*/
-SQLITE_PRIVATE void *sqlite3HashInsert(Hash *pH, const char *pKey, int nKey, void *data){
- unsigned int h; /* the hash of the key modulo hash table size */
- HashElem *elem; /* Used to loop thru the element list */
- HashElem *new_elem; /* New element added to the pH */
-
- assert( pH!=0 );
- assert( pKey!=0 );
- assert( nKey>=0 );
- if( pH->htsize ){
- h = strHash(pKey, nKey) % pH->htsize;
- }else{
- h = 0;
- }
- elem = findElementGivenHash(pH,pKey,nKey,h);
- if( elem ){
- void *old_data = elem->data;
- if( data==0 ){
- removeElementGivenHash(pH,elem,h);
- }else{
- elem->data = data;
- elem->pKey = pKey;
- assert(nKey==elem->nKey);
- }
- return old_data;
- }
- if( data==0 ) return 0;
- new_elem = (HashElem*)sqlite3Malloc( sizeof(HashElem) );
- if( new_elem==0 ) return data;
- new_elem->pKey = pKey;
- new_elem->nKey = nKey;
- new_elem->data = data;
- pH->count++;
- if( pH->count>=10 && pH->count > 2*pH->htsize ){
- if( rehash(pH, pH->count*2) ){
- assert( pH->htsize>0 );
- h = strHash(pKey, nKey) % pH->htsize;
- }
- }
- if( pH->ht ){
- insertElement(pH, &pH->ht[h], new_elem);
- }else{
- insertElement(pH, 0, new_elem);
- }
- return 0;
-}
-
-/************** End of hash.c ************************************************/
-/************** Begin file opcodes.c *****************************************/
-/* Automatically generated. Do not edit */
-/* See the mkopcodec.awk script for details. */
-#if !defined(SQLITE_OMIT_EXPLAIN) || !defined(NDEBUG) || defined(VDBE_PROFILE) || defined(SQLITE_DEBUG)
-SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){
- static const char *const azName[] = { "?",
- /* 1 */ "VNext",
- /* 2 */ "Affinity",
- /* 3 */ "Column",
- /* 4 */ "SetCookie",
- /* 5 */ "Seek",
- /* 6 */ "Sequence",
- /* 7 */ "Savepoint",
- /* 8 */ "RowKey",
- /* 9 */ "SCopy",
- /* 10 */ "OpenWrite",
- /* 11 */ "If",
- /* 12 */ "CollSeq",
- /* 13 */ "OpenRead",
- /* 14 */ "Expire",
- /* 15 */ "AutoCommit",
- /* 16 */ "Pagecount",
- /* 17 */ "IntegrityCk",
- /* 18 */ "Sort",
- /* 19 */ "Not",
- /* 20 */ "Copy",
- /* 21 */ "Trace",
- /* 22 */ "Function",
- /* 23 */ "IfNeg",
- /* 24 */ "Noop",
- /* 25 */ "Program",
- /* 26 */ "Return",
- /* 27 */ "NewRowid",
- /* 28 */ "Variable",
- /* 29 */ "String",
- /* 30 */ "RealAffinity",
- /* 31 */ "VRename",
- /* 32 */ "ParseSchema",
- /* 33 */ "VOpen",
- /* 34 */ "Close",
- /* 35 */ "CreateIndex",
- /* 36 */ "IsUnique",
- /* 37 */ "NotFound",
- /* 38 */ "Int64",
- /* 39 */ "MustBeInt",
- /* 40 */ "Halt",
- /* 41 */ "Rowid",
- /* 42 */ "IdxLT",
- /* 43 */ "AddImm",
- /* 44 */ "RowData",
- /* 45 */ "MemMax",
- /* 46 */ "NotExists",
- /* 47 */ "Gosub",
- /* 48 */ "Integer",
- /* 49 */ "Prev",
- /* 50 */ "RowSetRead",
- /* 51 */ "RowSetAdd",
- /* 52 */ "VColumn",
- /* 53 */ "CreateTable",
- /* 54 */ "Last",
- /* 55 */ "SeekLe",
- /* 56 */ "IncrVacuum",
- /* 57 */ "IdxRowid",
- /* 58 */ "ResetCount",
- /* 59 */ "Yield",
- /* 60 */ "DropTrigger",
- /* 61 */ "DropIndex",
- /* 62 */ "Param",
- /* 63 */ "IdxGE",
- /* 64 */ "IdxDelete",
- /* 65 */ "Vacuum",
- /* 66 */ "Or",
- /* 67 */ "And",
- /* 68 */ "IfNot",
- /* 69 */ "DropTable",
- /* 70 */ "SeekLt",
- /* 71 */ "IsNull",
- /* 72 */ "NotNull",
- /* 73 */ "Ne",
- /* 74 */ "Eq",
- /* 75 */ "Gt",
- /* 76 */ "Le",
- /* 77 */ "Lt",
- /* 78 */ "Ge",
- /* 79 */ "MakeRecord",
- /* 80 */ "BitAnd",
- /* 81 */ "BitOr",
- /* 82 */ "ShiftLeft",
- /* 83 */ "ShiftRight",
- /* 84 */ "Add",
- /* 85 */ "Subtract",
- /* 86 */ "Multiply",
- /* 87 */ "Divide",
- /* 88 */ "Remainder",
- /* 89 */ "Concat",
- /* 90 */ "ResultRow",
- /* 91 */ "Delete",
- /* 92 */ "AggFinal",
- /* 93 */ "BitNot",
- /* 94 */ "String8",
- /* 95 */ "Compare",
- /* 96 */ "Goto",
- /* 97 */ "TableLock",
- /* 98 */ "Clear",
- /* 99 */ "VerifyCookie",
- /* 100 */ "AggStep",
- /* 101 */ "Transaction",
- /* 102 */ "VFilter",
- /* 103 */ "VDestroy",
- /* 104 */ "Next",
- /* 105 */ "Count",
- /* 106 */ "IdxInsert",
- /* 107 */ "SeekGe",
- /* 108 */ "Insert",
- /* 109 */ "Destroy",
- /* 110 */ "ReadCookie",
- /* 111 */ "RowSetTest",
- /* 112 */ "LoadAnalysis",
- /* 113 */ "Explain",
- /* 114 */ "HaltIfNull",
- /* 115 */ "OpenPseudo",
- /* 116 */ "OpenEphemeral",
- /* 117 */ "Null",
- /* 118 */ "Move",
- /* 119 */ "Blob",
- /* 120 */ "Rewind",
- /* 121 */ "SeekGt",
- /* 122 */ "VBegin",
- /* 123 */ "VUpdate",
- /* 124 */ "IfZero",
- /* 125 */ "VCreate",
- /* 126 */ "Found",
- /* 127 */ "IfPos",
- /* 128 */ "NullRow",
- /* 129 */ "Jump",
- /* 130 */ "Real",
- /* 131 */ "Permutation",
- /* 132 */ "NotUsed_132",
- /* 133 */ "NotUsed_133",
- /* 134 */ "NotUsed_134",
- /* 135 */ "NotUsed_135",
- /* 136 */ "NotUsed_136",
- /* 137 */ "NotUsed_137",
- /* 138 */ "NotUsed_138",
- /* 139 */ "NotUsed_139",
- /* 140 */ "NotUsed_140",
- /* 141 */ "ToText",
- /* 142 */ "ToBlob",
- /* 143 */ "ToNumeric",
- /* 144 */ "ToInt",
- /* 145 */ "ToReal",
- };
- return azName[i];
-}
-#endif
-
-/************** End of opcodes.c *********************************************/
-/************** Begin file os_os2.c ******************************************/
-/*
-** 2006 Feb 14
-**
-** 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 code that is specific to OS/2.
-**
-** $Id: os_os2.c,v 1.63 2008/12/10 19:26:24 drh Exp $
-*/
-
-
-#if SQLITE_OS_OS2
-
-/*
-** 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. OS/2 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 OS/2
-** desktops but not so well in embedded systems.
-*/
-
-/*
-** Macros used to determine whether or not to use threads.
-*/
-#if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE
-# define SQLITE_OS2_THREADS 1
-#endif
-
-/*
-** Include code that is common to all os_*.c files
-*/
-/************** Include os_common.h in the middle of os_os2.c ****************/
-/************** Begin file os_common.h ***************************************/
-/*
-** 2004 May 22
-**
-** 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 macros and a little bit of code that is common to
-** all of the platform-specific files (os_*.c) and is #included into those
-** files.
-**
-** This file should be #included by the os_*.c files only. It is not a
-** general purpose header file.
-**
-** $Id: os_common.h,v 1.38 2009/02/24 18:40:50 danielk1977 Exp $
-*/
-#ifndef _OS_COMMON_H_
-#define _OS_COMMON_H_
-
-/*
-** At least two bugs have slipped in because we changed the MEMORY_DEBUG
-** macro to SQLITE_DEBUG and some older makefiles have not yet made the
-** switch. The following code should catch this problem at compile-time.
-*/
-#ifdef MEMORY_DEBUG
-# error "The MEMORY_DEBUG macro is obsolete. Use SQLITE_DEBUG instead."
-#endif
-
-#ifdef SQLITE_DEBUG
-SQLITE_PRIVATE int sqlite3OSTrace = 0;
-#define OSTRACE1(X) if( sqlite3OSTrace ) sqlite3DebugPrintf(X)
-#define OSTRACE2(X,Y) if( sqlite3OSTrace ) sqlite3DebugPrintf(X,Y)
-#define OSTRACE3(X,Y,Z) if( sqlite3OSTrace ) sqlite3DebugPrintf(X,Y,Z)
-#define OSTRACE4(X,Y,Z,A) if( sqlite3OSTrace ) sqlite3DebugPrintf(X,Y,Z,A)
-#define OSTRACE5(X,Y,Z,A,B) if( sqlite3OSTrace ) sqlite3DebugPrintf(X,Y,Z,A,B)
-#define OSTRACE6(X,Y,Z,A,B,C) \
- if(sqlite3OSTrace) sqlite3DebugPrintf(X,Y,Z,A,B,C)
-#define OSTRACE7(X,Y,Z,A,B,C,D) \
- if(sqlite3OSTrace) sqlite3DebugPrintf(X,Y,Z,A,B,C,D)
-#else
-#define OSTRACE1(X)
-#define OSTRACE2(X,Y)
-#define OSTRACE3(X,Y,Z)
-#define OSTRACE4(X,Y,Z,A)
-#define OSTRACE5(X,Y,Z,A,B)
-#define OSTRACE6(X,Y,Z,A,B,C)
-#define OSTRACE7(X,Y,Z,A,B,C,D)
-#endif
-
-/*
-** Macros for performance tracing. Normally turned off. Only works
-** on i486 hardware.
-*/
-#ifdef SQLITE_PERFORMANCE_TRACE
-
-/*
-** hwtime.h contains inline assembler code for implementing
-** high-performance timing routines.
-*/
-/************** Include hwtime.h in the middle of os_common.h ****************/
-/************** Begin file hwtime.h ******************************************/
-/*
-** 2008 May 27
-**
-** 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 inline asm code for retrieving "high-performance"
-** counters for x86 class CPUs.
-**
-** $Id: hwtime.h,v 1.3 2008/08/01 14:33:15 shane Exp $
-*/
-#ifndef _HWTIME_H_
-#define _HWTIME_H_
-
-/*
-** The following routine only works on pentium-class (or newer) processors.
-** It uses the RDTSC opcode to read the cycle count value out of the
-** processor and returns that value. This can be used for high-res
-** profiling.
-*/
-#if (defined(__GNUC__) || defined(_MSC_VER)) && \
- (defined(i386) || defined(__i386__) || defined(_M_IX86))
-
- #if defined(__GNUC__)
-
- __inline__ sqlite_uint64 sqlite3Hwtime(void){
- unsigned int lo, hi;
- __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
- return (sqlite_uint64)hi << 32 | lo;
- }
-
- #elif defined(_MSC_VER)
-
- __declspec(naked) __inline sqlite_uint64 __cdecl sqlite3Hwtime(void){
- __asm {
- rdtsc
- ret ; return value at EDX:EAX
- }
- }
-
- #endif
-
-#elif (defined(__GNUC__) && defined(__x86_64__))
-
- __inline__ sqlite_uint64 sqlite3Hwtime(void){
- unsigned long val;
- __asm__ __volatile__ ("rdtsc" : "=A" (val));
- return val;
- }
-
-#elif (defined(__GNUC__) && defined(__ppc__))
-
- __inline__ sqlite_uint64 sqlite3Hwtime(void){
- unsigned long long retval;
- unsigned long junk;
- __asm__ __volatile__ ("\n\
- 1: mftbu %1\n\
- mftb %L0\n\
- mftbu %0\n\
- cmpw %0,%1\n\
- bne 1b"
- : "=r" (retval), "=r" (junk));
- return retval;
- }
-
-#else
-
- #error Need implementation of sqlite3Hwtime() for your platform.
-
- /*
- ** To compile without implementing sqlite3Hwtime() for your platform,
- ** you can remove the above #error and use the following
- ** stub function. You will lose timing support for many
- ** of the debugging and testing utilities, but it should at
- ** least compile and run.
- */
-SQLITE_PRIVATE sqlite_uint64 sqlite3Hwtime(void){ return ((sqlite_uint64)0); }
-
-#endif
-
-#endif /* !defined(_HWTIME_H_) */
-
-/************** End of hwtime.h **********************************************/
-/************** Continuing where we left off in os_common.h ******************/
-
-static sqlite_uint64 g_start;
-static sqlite_uint64 g_elapsed;
-#define TIMER_START g_start=sqlite3Hwtime()
-#define TIMER_END g_elapsed=sqlite3Hwtime()-g_start
-#define TIMER_ELAPSED g_elapsed
-#else
-#define TIMER_START
-#define TIMER_END
-#define TIMER_ELAPSED ((sqlite_uint64)0)
-#endif
-
-/*
-** If we compile with the SQLITE_TEST macro set, then the following block
-** of code will give us the ability to simulate a disk I/O error. This
-** is used for testing the I/O recovery logic.
-*/
-#ifdef SQLITE_TEST
-SQLITE_API int sqlite3_io_error_hit = 0; /* Total number of I/O Errors */
-SQLITE_API int sqlite3_io_error_hardhit = 0; /* Number of non-benign errors */
-SQLITE_API int sqlite3_io_error_pending = 0; /* Count down to first I/O error */
-SQLITE_API int sqlite3_io_error_persist = 0; /* True if I/O errors persist */
-SQLITE_API int sqlite3_io_error_benign = 0; /* True if errors are benign */
-SQLITE_API int sqlite3_diskfull_pending = 0;
-SQLITE_API int sqlite3_diskfull = 0;
-#define SimulateIOErrorBenign(X) sqlite3_io_error_benign=(X)
-#define SimulateIOError(CODE) \
- if( (sqlite3_io_error_persist && sqlite3_io_error_hit) \
- || sqlite3_io_error_pending-- == 1 ) \
- { local_ioerr(); CODE; }
-static void local_ioerr(){
- IOTRACE(("IOERR\n"));
- sqlite3_io_error_hit++;
- if( !sqlite3_io_error_benign ) sqlite3_io_error_hardhit++;
-}
-#define SimulateDiskfullError(CODE) \
- if( sqlite3_diskfull_pending ){ \
- if( sqlite3_diskfull_pending == 1 ){ \
- local_ioerr(); \
- sqlite3_diskfull = 1; \
- sqlite3_io_error_hit = 1; \
- CODE; \
- }else{ \
- sqlite3_diskfull_pending--; \
- } \
- }
-#else
-#define SimulateIOErrorBenign(X)
-#define SimulateIOError(A)
-#define SimulateDiskfullError(A)
-#endif
-
-/*
-** When testing, keep a count of the number of open files.
-*/
-#ifdef SQLITE_TEST
-SQLITE_API int sqlite3_open_file_count = 0;
-#define OpenCounter(X) sqlite3_open_file_count+=(X)
-#else
-#define OpenCounter(X)
-#endif
-
-#endif /* !defined(_OS_COMMON_H_) */
-
-/************** End of os_common.h *******************************************/
-/************** Continuing where we left off in os_os2.c *********************/
-
-/*
-** The os2File structure is subclass of sqlite3_file specific for the OS/2
-** protability layer.
-*/
-typedef struct os2File os2File;
-struct os2File {
- const sqlite3_io_methods *pMethod; /* Always the first entry */
- HFILE h; /* Handle for accessing the file */
- char* pathToDel; /* Name of file to delete on close, NULL if not */
- unsigned char locktype; /* Type of lock currently held on this file */
-};
-
-#define LOCK_TIMEOUT 10L /* the default locking timeout */
-
-/*****************************************************************************
-** The next group of routines implement the I/O methods specified
-** by the sqlite3_io_methods object.
-******************************************************************************/
-
-/*
-** Close a file.
-*/
-static int os2Close( sqlite3_file *id ){
- APIRET rc = NO_ERROR;
- os2File *pFile;
- if( id && (pFile = (os2File*)id) != 0 ){
- OSTRACE2( "CLOSE %d\n", pFile->h );
- rc = DosClose( pFile->h );
- pFile->locktype = NO_LOCK;
- if( pFile->pathToDel != NULL ){
- rc = DosForceDelete( (PSZ)pFile->pathToDel );
- free( pFile->pathToDel );
- pFile->pathToDel = NULL;
- }
- id = 0;
- OpenCounter( -1 );
- }
-
- return rc == NO_ERROR ? SQLITE_OK : SQLITE_IOERR;
-}
-
-/*
-** Read data from a file into a buffer. Return SQLITE_OK if all
-** bytes were read successfully and SQLITE_IOERR if anything goes
-** wrong.
-*/
-static int os2Read(
- sqlite3_file *id, /* File to read from */
- void *pBuf, /* Write content into this buffer */
- int amt, /* Number of bytes to read */
- sqlite3_int64 offset /* Begin reading at this offset */
-){
- ULONG fileLocation = 0L;
- ULONG got;
- os2File *pFile = (os2File*)id;
- assert( id!=0 );
- SimulateIOError( return SQLITE_IOERR_READ );
- OSTRACE3( "READ %d lock=%d\n", pFile->h, pFile->locktype );
- if( DosSetFilePtr(pFile->h, offset, FILE_BEGIN, &fileLocation) != NO_ERROR ){
- return SQLITE_IOERR;
- }
- if( DosRead( pFile->h, pBuf, amt, &got ) != NO_ERROR ){
- return SQLITE_IOERR_READ;
- }
- if( got == (ULONG)amt )
- return SQLITE_OK;
- else {
- /* Unread portions of the input buffer must be zero-filled */
- memset(&((char*)pBuf)[got], 0, amt-got);
- return SQLITE_IOERR_SHORT_READ;
- }
-}
-
-/*
-** Write data from a buffer into a file. Return SQLITE_OK on success
-** or some other error code on failure.
-*/
-static int os2Write(
- sqlite3_file *id, /* File to write into */
- const void *pBuf, /* The bytes to be written */
- int amt, /* Number of bytes to write */
- sqlite3_int64 offset /* Offset into the file to begin writing at */
-){
- ULONG fileLocation = 0L;
- APIRET rc = NO_ERROR;
- ULONG wrote;
- os2File *pFile = (os2File*)id;
- assert( id!=0 );
- SimulateIOError( return SQLITE_IOERR_WRITE );
- SimulateDiskfullError( return SQLITE_FULL );
- OSTRACE3( "WRITE %d lock=%d\n", pFile->h, pFile->locktype );
- if( DosSetFilePtr(pFile->h, offset, FILE_BEGIN, &fileLocation) != NO_ERROR ){
- return SQLITE_IOERR;
- }
- assert( amt>0 );
- while( amt > 0 &&
- ( rc = DosWrite( pFile->h, (PVOID)pBuf, amt, &wrote ) ) == NO_ERROR &&
- wrote > 0
- ){
- amt -= wrote;
- pBuf = &((char*)pBuf)[wrote];
- }
-
- return ( rc != NO_ERROR || amt > (int)wrote ) ? SQLITE_FULL : SQLITE_OK;
-}
-
-/*
-** Truncate an open file to a specified size
-*/
-static int os2Truncate( sqlite3_file *id, i64 nByte ){
- APIRET rc = NO_ERROR;
- os2File *pFile = (os2File*)id;
- OSTRACE3( "TRUNCATE %d %lld\n", pFile->h, nByte );
- SimulateIOError( return SQLITE_IOERR_TRUNCATE );
- rc = DosSetFileSize( pFile->h, nByte );
- return rc == NO_ERROR ? SQLITE_OK : SQLITE_IOERR_TRUNCATE;
-}
-
-#ifdef SQLITE_TEST
-/*
-** Count the number of fullsyncs and normal syncs. This is used to test
-** that syncs and fullsyncs are occuring at the right times.
-*/
-SQLITE_API int sqlite3_sync_count = 0;
-SQLITE_API int sqlite3_fullsync_count = 0;
-#endif
-
-/*
-** Make sure all writes to a particular file are committed to disk.
-*/
-static int os2Sync( sqlite3_file *id, int flags ){
- os2File *pFile = (os2File*)id;
- OSTRACE3( "SYNC %d lock=%d\n", pFile->h, pFile->locktype );
-#ifdef SQLITE_TEST
- if( flags & SQLITE_SYNC_FULL){
- sqlite3_fullsync_count++;
- }
- sqlite3_sync_count++;
-#endif
- /* If we compiled with the SQLITE_NO_SYNC flag, then syncing is a
- ** no-op
- */
-#ifdef SQLITE_NO_SYNC
- UNUSED_PARAMETER(pFile);
- return SQLITE_OK;
-#else
- return DosResetBuffer( pFile->h ) == NO_ERROR ? SQLITE_OK : SQLITE_IOERR;
-#endif
-}
-
-/*
-** Determine the current size of a file in bytes
-*/
-static int os2FileSize( sqlite3_file *id, sqlite3_int64 *pSize ){
- APIRET rc = NO_ERROR;
- FILESTATUS3 fsts3FileInfo;
- memset(&fsts3FileInfo, 0, sizeof(fsts3FileInfo));
- assert( id!=0 );
- SimulateIOError( return SQLITE_IOERR_FSTAT );
- rc = DosQueryFileInfo( ((os2File*)id)->h, FIL_STANDARD, &fsts3FileInfo, sizeof(FILESTATUS3) );
- if( rc == NO_ERROR ){
- *pSize = fsts3FileInfo.cbFile;
- return SQLITE_OK;
- }else{
- return SQLITE_IOERR_FSTAT;
- }
-}
-
-/*
-** Acquire a reader lock.
-*/
-static int getReadLock( os2File *pFile ){
- FILELOCK LockArea,
- UnlockArea;
- APIRET res;
- memset(&LockArea, 0, sizeof(LockArea));
- memset(&UnlockArea, 0, sizeof(UnlockArea));
- LockArea.lOffset = SHARED_FIRST;
- LockArea.lRange = SHARED_SIZE;
- UnlockArea.lOffset = 0L;
- UnlockArea.lRange = 0L;
- res = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 1L );
- OSTRACE3( "GETREADLOCK %d res=%d\n", pFile->h, res );
- return res;
-}
-
-/*
-** Undo a readlock
-*/
-static int unlockReadLock( os2File *id ){
- FILELOCK LockArea,
- UnlockArea;
- APIRET res;
- memset(&LockArea, 0, sizeof(LockArea));
- memset(&UnlockArea, 0, sizeof(UnlockArea));
- LockArea.lOffset = 0L;
- LockArea.lRange = 0L;
- UnlockArea.lOffset = SHARED_FIRST;
- UnlockArea.lRange = SHARED_SIZE;
- res = DosSetFileLocks( id->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 1L );
- OSTRACE3( "UNLOCK-READLOCK file handle=%d res=%d?\n", id->h, res );
- return res;
-}
-
-/*
-** Lock the file with the lock specified by parameter locktype - one
-** of the following:
-**
-** (1) SHARED_LOCK
-** (2) RESERVED_LOCK
-** (3) PENDING_LOCK
-** (4) EXCLUSIVE_LOCK
-**
-** Sometimes when requesting one lock state, additional lock states
-** are inserted in between. The locking might fail on one of the later
-** transitions leaving the lock state different from what it started but
-** still short of its goal. The following chart shows the allowed
-** transitions and the inserted intermediate states:
-**
-** UNLOCKED -> SHARED
-** SHARED -> RESERVED
-** SHARED -> (PENDING) -> EXCLUSIVE
-** RESERVED -> (PENDING) -> EXCLUSIVE
-** PENDING -> EXCLUSIVE
-**
-** This routine will only increase a lock. The os2Unlock() routine
-** erases all locks at once and returns us immediately to locking level 0.
-** It is not possible to lower the locking level one step at a time. You
-** must go straight to locking level 0.
-*/
-static int os2Lock( sqlite3_file *id, int locktype ){
- int rc = SQLITE_OK; /* Return code from subroutines */
- APIRET res = NO_ERROR; /* Result of an OS/2 lock call */
- int newLocktype; /* Set pFile->locktype to this value before exiting */
- int gotPendingLock = 0;/* True if we acquired a PENDING lock this time */
- FILELOCK LockArea,
- UnlockArea;
- os2File *pFile = (os2File*)id;
- memset(&LockArea, 0, sizeof(LockArea));
- memset(&UnlockArea, 0, sizeof(UnlockArea));
- assert( pFile!=0 );
- OSTRACE4( "LOCK %d %d was %d\n", pFile->h, locktype, pFile->locktype );
-
- /* If there is already a lock of this type or more restrictive on the
- ** os2File, do nothing. Don't use the end_lock: exit path, as
- ** sqlite3_mutex_enter() hasn't been called yet.
- */
- if( pFile->locktype>=locktype ){
- OSTRACE3( "LOCK %d %d ok (already held)\n", pFile->h, locktype );
- return SQLITE_OK;
- }
-
- /* Make sure the locking sequence is correct
- */
- assert( pFile->locktype!=NO_LOCK || locktype==SHARED_LOCK );
- assert( locktype!=PENDING_LOCK );
- assert( locktype!=RESERVED_LOCK || pFile->locktype==SHARED_LOCK );
-
- /* Lock the PENDING_LOCK byte if we need to acquire a PENDING lock or
- ** a SHARED lock. If we are acquiring a SHARED lock, the acquisition of
- ** the PENDING_LOCK byte is temporary.
- */
- newLocktype = pFile->locktype;
- if( pFile->locktype==NO_LOCK
- || (locktype==EXCLUSIVE_LOCK && pFile->locktype==RESERVED_LOCK)
- ){
- LockArea.lOffset = PENDING_BYTE;
- LockArea.lRange = 1L;
- UnlockArea.lOffset = 0L;
- UnlockArea.lRange = 0L;
-
- /* wait longer than LOCK_TIMEOUT here not to have to try multiple times */
- res = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, 100L, 0L );
- if( res == NO_ERROR ){
- gotPendingLock = 1;
- OSTRACE3( "LOCK %d pending lock boolean set. res=%d\n", pFile->h, res );
- }
- }
-
- /* Acquire a shared lock
- */
- if( locktype==SHARED_LOCK && res == NO_ERROR ){
- assert( pFile->locktype==NO_LOCK );
- res = getReadLock(pFile);
- if( res == NO_ERROR ){
- newLocktype = SHARED_LOCK;
- }
- OSTRACE3( "LOCK %d acquire shared lock. res=%d\n", pFile->h, res );
- }
-
- /* Acquire a RESERVED lock
- */
- if( locktype==RESERVED_LOCK && res == NO_ERROR ){
- assert( pFile->locktype==SHARED_LOCK );
- LockArea.lOffset = RESERVED_BYTE;
- LockArea.lRange = 1L;
- UnlockArea.lOffset = 0L;
- UnlockArea.lRange = 0L;
- res = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 0L );
- if( res == NO_ERROR ){
- newLocktype = RESERVED_LOCK;
- }
- OSTRACE3( "LOCK %d acquire reserved lock. res=%d\n", pFile->h, res );
- }
-
- /* Acquire a PENDING lock
- */
- if( locktype==EXCLUSIVE_LOCK && res == NO_ERROR ){
- newLocktype = PENDING_LOCK;
- gotPendingLock = 0;
- OSTRACE2( "LOCK %d acquire pending lock. pending lock boolean unset.\n", pFile->h );
- }
-
- /* Acquire an EXCLUSIVE lock
- */
- if( locktype==EXCLUSIVE_LOCK && res == NO_ERROR ){
- assert( pFile->locktype>=SHARED_LOCK );
- res = unlockReadLock(pFile);
- OSTRACE2( "unreadlock = %d\n", res );
- LockArea.lOffset = SHARED_FIRST;
- LockArea.lRange = SHARED_SIZE;
- UnlockArea.lOffset = 0L;
- UnlockArea.lRange = 0L;
- res = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 0L );
- if( res == NO_ERROR ){
- newLocktype = EXCLUSIVE_LOCK;
- }else{
- OSTRACE2( "OS/2 error-code = %d\n", res );
- getReadLock(pFile);
- }
- OSTRACE3( "LOCK %d acquire exclusive lock. res=%d\n", pFile->h, res );
- }
-
- /* If we are holding a PENDING lock that ought to be released, then
- ** release it now.
- */
- if( gotPendingLock && locktype==SHARED_LOCK ){
- int r;
- LockArea.lOffset = 0L;
- LockArea.lRange = 0L;
- UnlockArea.lOffset = PENDING_BYTE;
- UnlockArea.lRange = 1L;
- r = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 0L );
- OSTRACE3( "LOCK %d unlocking pending/is shared. r=%d\n", pFile->h, r );
- }
-
- /* Update the state of the lock has held in the file descriptor then
- ** return the appropriate result code.
- */
- if( res == NO_ERROR ){
- rc = SQLITE_OK;
- }else{
- OSTRACE4( "LOCK FAILED %d trying for %d but got %d\n", pFile->h,
- locktype, newLocktype );
- rc = SQLITE_BUSY;
- }
- pFile->locktype = newLocktype;
- OSTRACE3( "LOCK %d now %d\n", pFile->h, pFile->locktype );
- return rc;
-}
-
-/*
-** This routine checks if there is a RESERVED lock held on the specified
-** file by this or any other process. If such a lock is held, return
-** non-zero, otherwise zero.
-*/
-static int os2CheckReservedLock( sqlite3_file *id, int *pOut ){
- int r = 0;
- os2File *pFile = (os2File*)id;
- assert( pFile!=0 );
- if( pFile->locktype>=RESERVED_LOCK ){
- r = 1;
- OSTRACE3( "TEST WR-LOCK %d %d (local)\n", pFile->h, r );
- }else{
- FILELOCK LockArea,
- UnlockArea;
- APIRET rc = NO_ERROR;
- memset(&LockArea, 0, sizeof(LockArea));
- memset(&UnlockArea, 0, sizeof(UnlockArea));
- LockArea.lOffset = RESERVED_BYTE;
- LockArea.lRange = 1L;
- UnlockArea.lOffset = 0L;
- UnlockArea.lRange = 0L;
- rc = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 0L );
- OSTRACE3( "TEST WR-LOCK %d lock reserved byte rc=%d\n", pFile->h, rc );
- if( rc == NO_ERROR ){
- APIRET rcu = NO_ERROR; /* return code for unlocking */
- LockArea.lOffset = 0L;
- LockArea.lRange = 0L;
- UnlockArea.lOffset = RESERVED_BYTE;
- UnlockArea.lRange = 1L;
- rcu = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 0L );
- OSTRACE3( "TEST WR-LOCK %d unlock reserved byte r=%d\n", pFile->h, rcu );
- }
- r = !(rc == NO_ERROR);
- OSTRACE3( "TEST WR-LOCK %d %d (remote)\n", pFile->h, r );
- }
- *pOut = r;
- return SQLITE_OK;
-}
-
-/*
-** Lower the locking level on file descriptor id to locktype. locktype
-** must be either NO_LOCK or SHARED_LOCK.
-**
-** If the locking level of the file descriptor is already at or below
-** the requested locking level, this routine is a no-op.
-**
-** It is not possible for this routine to fail if the second argument
-** is NO_LOCK. If the second argument is SHARED_LOCK then this routine
-** might return SQLITE_IOERR;
-*/
-static int os2Unlock( sqlite3_file *id, int locktype ){
- int type;
- os2File *pFile = (os2File*)id;
- APIRET rc = SQLITE_OK;
- APIRET res = NO_ERROR;
- FILELOCK LockArea,
- UnlockArea;
- memset(&LockArea, 0, sizeof(LockArea));
- memset(&UnlockArea, 0, sizeof(UnlockArea));
- assert( pFile!=0 );
- assert( locktype<=SHARED_LOCK );
- OSTRACE4( "UNLOCK %d to %d was %d\n", pFile->h, locktype, pFile->locktype );
- type = pFile->locktype;
- if( type>=EXCLUSIVE_LOCK ){
- LockArea.lOffset = 0L;
- LockArea.lRange = 0L;
- UnlockArea.lOffset = SHARED_FIRST;
- UnlockArea.lRange = SHARED_SIZE;
- res = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 0L );
- OSTRACE3( "UNLOCK %d exclusive lock res=%d\n", pFile->h, res );
- if( locktype==SHARED_LOCK && getReadLock(pFile) != NO_ERROR ){
- /* This should never happen. We should always be able to
- ** reacquire the read lock */
- OSTRACE3( "UNLOCK %d to %d getReadLock() failed\n", pFile->h, locktype );
- rc = SQLITE_IOERR_UNLOCK;
- }
- }
- if( type>=RESERVED_LOCK ){
- LockArea.lOffset = 0L;
- LockArea.lRange = 0L;
- UnlockArea.lOffset = RESERVED_BYTE;
- UnlockArea.lRange = 1L;
- res = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 0L );
- OSTRACE3( "UNLOCK %d reserved res=%d\n", pFile->h, res );
- }
- if( locktype==NO_LOCK && type>=SHARED_LOCK ){
- res = unlockReadLock(pFile);
- OSTRACE5( "UNLOCK %d is %d want %d res=%d\n", pFile->h, type, locktype, res );
- }
- if( type>=PENDING_LOCK ){
- LockArea.lOffset = 0L;
- LockArea.lRange = 0L;
- UnlockArea.lOffset = PENDING_BYTE;
- UnlockArea.lRange = 1L;
- res = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 0L );
- OSTRACE3( "UNLOCK %d pending res=%d\n", pFile->h, res );
- }
- pFile->locktype = locktype;
- OSTRACE3( "UNLOCK %d now %d\n", pFile->h, pFile->locktype );
- return rc;
-}
-
-/*
-** Control and query of the open file handle.
-*/
-static int os2FileControl(sqlite3_file *id, int op, void *pArg){
- switch( op ){
- case SQLITE_FCNTL_LOCKSTATE: {
- *(int*)pArg = ((os2File*)id)->locktype;
- OSTRACE3( "FCNTL_LOCKSTATE %d lock=%d\n", ((os2File*)id)->h, ((os2File*)id)->locktype );
- return SQLITE_OK;
- }
- }
- return SQLITE_ERROR;
-}
-
-/*
-** Return the sector size in bytes of the underlying block device for
-** the specified file. This is almost always 512 bytes, but may be
-** larger for some devices.
-**
-** SQLite code assumes this function cannot fail. It also assumes that
-** if two files are created in the same file-system directory (i.e.
-** a database and its journal file) that the sector size will be the
-** same for both.
-*/
-static int os2SectorSize(sqlite3_file *id){
- return SQLITE_DEFAULT_SECTOR_SIZE;
-}
-
-/*
-** Return a vector of device characteristics.
-*/
-static int os2DeviceCharacteristics(sqlite3_file *id){
- return 0;
-}
-
-
-/*
-** Character set conversion objects used by conversion routines.
-*/
-static UconvObject ucUtf8 = NULL; /* convert between UTF-8 and UCS-2 */
-static UconvObject uclCp = NULL; /* convert between local codepage and UCS-2 */
-
-/*
-** Helper function to initialize the conversion objects from and to UTF-8.
-*/
-static void initUconvObjects( void ){
- if( UniCreateUconvObject( UTF_8, &ucUtf8 ) != ULS_SUCCESS )
- ucUtf8 = NULL;
- if ( UniCreateUconvObject( (UniChar *)L"@path=yes", &uclCp ) != ULS_SUCCESS )
- uclCp = NULL;
-}
-
-/*
-** Helper function to free the conversion objects from and to UTF-8.
-*/
-static void freeUconvObjects( void ){
- if ( ucUtf8 )
- UniFreeUconvObject( ucUtf8 );
- if ( uclCp )
- UniFreeUconvObject( uclCp );
- ucUtf8 = NULL;
- uclCp = NULL;
-}
-
-/*
-** Helper function to convert UTF-8 filenames to local OS/2 codepage.
-** The two-step process: first convert the incoming UTF-8 string
-** into UCS-2 and then from UCS-2 to the current codepage.
-** The returned char pointer has to be freed.
-*/
-static char *convertUtf8PathToCp( const char *in ){
- UniChar tempPath[CCHMAXPATH];
- char *out = (char *)calloc( CCHMAXPATH, 1 );
-
- if( !out )
- return NULL;
-
- if( !ucUtf8 || !uclCp )
- initUconvObjects();
-
- /* determine string for the conversion of UTF-8 which is CP1208 */
- if( UniStrToUcs( ucUtf8, tempPath, (char *)in, CCHMAXPATH ) != ULS_SUCCESS )
- return out; /* if conversion fails, return the empty string */
-
- /* conversion for current codepage which can be used for paths */
- UniStrFromUcs( uclCp, out, tempPath, CCHMAXPATH );
-
- return out;
-}
-
-/*
-** Helper function to convert filenames from local codepage to UTF-8.
-** The two-step process: first convert the incoming codepage-specific
-** string into UCS-2 and then from UCS-2 to the codepage of UTF-8.
-** The returned char pointer has to be freed.
-**
-** This function is non-static to be able to use this in shell.c and
-** similar applications that take command line arguments.
-*/
-char *convertCpPathToUtf8( const char *in ){
- UniChar tempPath[CCHMAXPATH];
- char *out = (char *)calloc( CCHMAXPATH, 1 );
-
- if( !out )
- return NULL;
-
- if( !ucUtf8 || !uclCp )
- initUconvObjects();
-
- /* conversion for current codepage which can be used for paths */
- if( UniStrToUcs( uclCp, tempPath, (char *)in, CCHMAXPATH ) != ULS_SUCCESS )
- return out; /* if conversion fails, return the empty string */
-
- /* determine string for the conversion of UTF-8 which is CP1208 */
- UniStrFromUcs( ucUtf8, out, tempPath, CCHMAXPATH );
-
- return out;
-}
-
-/*
-** This vector defines all the methods that can operate on an
-** sqlite3_file for os2.
-*/
-static const sqlite3_io_methods os2IoMethod = {
- 1, /* iVersion */
- os2Close,
- os2Read,
- os2Write,
- os2Truncate,
- os2Sync,
- os2FileSize,
- os2Lock,
- os2Unlock,
- os2CheckReservedLock,
- os2FileControl,
- os2SectorSize,
- os2DeviceCharacteristics
-};
-
-/***************************************************************************
-** Here ends the I/O methods that form the sqlite3_io_methods object.
-**
-** The next block of code implements the VFS methods.
-****************************************************************************/
-
-/*
-** Create a temporary file name in zBuf. zBuf must be big enough to
-** hold at pVfs->mxPathname characters.
-*/
-static int getTempname(int nBuf, char *zBuf ){
- static const unsigned char zChars[] =
- "abcdefghijklmnopqrstuvwxyz"
- "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
- "0123456789";
- int i, j;
- char zTempPathBuf[3];
- PSZ zTempPath = (PSZ)&zTempPathBuf;
- if( sqlite3_temp_directory ){
- zTempPath = sqlite3_temp_directory;
- }else{
- if( DosScanEnv( (PSZ)"TEMP", &zTempPath ) ){
- if( DosScanEnv( (PSZ)"TMP", &zTempPath ) ){
- if( DosScanEnv( (PSZ)"TMPDIR", &zTempPath ) ){
- ULONG ulDriveNum = 0, ulDriveMap = 0;
- DosQueryCurrentDisk( &ulDriveNum, &ulDriveMap );
- sprintf( (char*)zTempPath, "%c:", (char)( 'A' + ulDriveNum - 1 ) );
- }
- }
- }
- }
- /* Strip off a trailing slashes or backslashes, otherwise we would get *
- * multiple (back)slashes which causes DosOpen() to fail. *
- * Trailing spaces are not allowed, either. */
- j = sqlite3Strlen30(zTempPath);
- while( j > 0 && ( zTempPath[j-1] == '\\' || zTempPath[j-1] == '/'
- || zTempPath[j-1] == ' ' ) ){
- j--;
- }
- zTempPath[j] = '\0';
- if( !sqlite3_temp_directory ){
- char *zTempPathUTF = convertCpPathToUtf8( zTempPath );
- sqlite3_snprintf( nBuf-30, zBuf,
- "%s\\"SQLITE_TEMP_FILE_PREFIX, zTempPathUTF );
- free( zTempPathUTF );
- }else{
- sqlite3_snprintf( nBuf-30, zBuf,
- "%s\\"SQLITE_TEMP_FILE_PREFIX, zTempPath );
- }
- j = sqlite3Strlen30( zBuf );
- sqlite3_randomness( 20, &zBuf[j] );
- for( i = 0; i < 20; i++, j++ ){
- zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
- }
- zBuf[j] = 0;
- OSTRACE2( "TEMP FILENAME: %s\n", zBuf );
- return SQLITE_OK;
-}
-
-
-/*
-** Turn a relative pathname into a full pathname. Write the full
-** pathname into zFull[]. zFull[] will be at least pVfs->mxPathname
-** bytes in size.
-*/
-static int os2FullPathname(
- sqlite3_vfs *pVfs, /* Pointer to vfs object */
- const char *zRelative, /* Possibly relative input path */
- int nFull, /* Size of output buffer in bytes */
- char *zFull /* Output buffer */
-){
- char *zRelativeCp = convertUtf8PathToCp( zRelative );
- char zFullCp[CCHMAXPATH] = "\0";
- char *zFullUTF;
- APIRET rc = DosQueryPathInfo( zRelativeCp, FIL_QUERYFULLNAME, zFullCp,
- CCHMAXPATH );
- free( zRelativeCp );
- zFullUTF = convertCpPathToUtf8( zFullCp );
- sqlite3_snprintf( nFull, zFull, zFullUTF );
- free( zFullUTF );
- return rc == NO_ERROR ? SQLITE_OK : SQLITE_IOERR;
-}
-
-
-/*
-** Open a file.
-*/
-static int os2Open(
- sqlite3_vfs *pVfs, /* Not used */
- const char *zName, /* Name of the file */
- sqlite3_file *id, /* Write the SQLite file handle here */
- int flags, /* Open mode flags */
- int *pOutFlags /* Status return flags */
-){
- HFILE h;
- ULONG ulFileAttribute = FILE_NORMAL;
- ULONG ulOpenFlags = 0;
- ULONG ulOpenMode = 0;
- os2File *pFile = (os2File*)id;
- APIRET rc = NO_ERROR;
- ULONG ulAction;
- char *zNameCp;
- char zTmpname[CCHMAXPATH+1]; /* Buffer to hold name of temp file */
-
- /* If the second argument to this function is NULL, generate a
- ** temporary file name to use
- */
- if( !zName ){
- int rc = getTempname(CCHMAXPATH+1, zTmpname);
- if( rc!=SQLITE_OK ){
- return rc;
- }
- zName = zTmpname;
- }
-
-
- memset( pFile, 0, sizeof(*pFile) );
-
- OSTRACE2( "OPEN want %d\n", flags );
-
- if( flags & SQLITE_OPEN_READWRITE ){
- ulOpenMode |= OPEN_ACCESS_READWRITE;
- OSTRACE1( "OPEN read/write\n" );
- }else{
- ulOpenMode |= OPEN_ACCESS_READONLY;
- OSTRACE1( "OPEN read only\n" );
- }
-
- if( flags & SQLITE_OPEN_CREATE ){
- ulOpenFlags |= OPEN_ACTION_OPEN_IF_EXISTS | OPEN_ACTION_CREATE_IF_NEW;
- OSTRACE1( "OPEN open new/create\n" );
- }else{
- ulOpenFlags |= OPEN_ACTION_OPEN_IF_EXISTS | OPEN_ACTION_FAIL_IF_NEW;
- OSTRACE1( "OPEN open existing\n" );
- }
-
- if( flags & SQLITE_OPEN_MAIN_DB ){
- ulOpenMode |= OPEN_SHARE_DENYNONE;
- OSTRACE1( "OPEN share read/write\n" );
- }else{
- ulOpenMode |= OPEN_SHARE_DENYWRITE;
- OSTRACE1( "OPEN share read only\n" );
- }
-
- if( flags & SQLITE_OPEN_DELETEONCLOSE ){
- char pathUtf8[CCHMAXPATH];
-#ifdef NDEBUG /* when debugging we want to make sure it is deleted */
- ulFileAttribute = FILE_HIDDEN;
-#endif
- os2FullPathname( pVfs, zName, CCHMAXPATH, pathUtf8 );
- pFile->pathToDel = convertUtf8PathToCp( pathUtf8 );
- OSTRACE1( "OPEN hidden/delete on close file attributes\n" );
- }else{
- pFile->pathToDel = NULL;
- OSTRACE1( "OPEN normal file attribute\n" );
- }
-
- /* always open in random access mode for possibly better speed */
- ulOpenMode |= OPEN_FLAGS_RANDOM;
- ulOpenMode |= OPEN_FLAGS_FAIL_ON_ERROR;
- ulOpenMode |= OPEN_FLAGS_NOINHERIT;
-
- zNameCp = convertUtf8PathToCp( zName );
- rc = DosOpen( (PSZ)zNameCp,
- &h,
- &ulAction,
- 0L,
- ulFileAttribute,
- ulOpenFlags,
- ulOpenMode,
- (PEAOP2)NULL );
- free( zNameCp );
- if( rc != NO_ERROR ){
- OSTRACE7( "OPEN Invalid handle rc=%d: zName=%s, ulAction=%#lx, ulAttr=%#lx, ulFlags=%#lx, ulMode=%#lx\n",
- rc, zName, ulAction, ulFileAttribute, ulOpenFlags, ulOpenMode );
- if( pFile->pathToDel )
- free( pFile->pathToDel );
- pFile->pathToDel = NULL;
- if( flags & SQLITE_OPEN_READWRITE ){
- OSTRACE2( "OPEN %d Invalid handle\n", ((flags | SQLITE_OPEN_READONLY) & ~SQLITE_OPEN_READWRITE) );
- return os2Open( pVfs, zName, id,
- ((flags | SQLITE_OPEN_READONLY) & ~SQLITE_OPEN_READWRITE),
- pOutFlags );
- }else{
- return SQLITE_CANTOPEN;
- }
- }
-
- if( pOutFlags ){
- *pOutFlags = flags & SQLITE_OPEN_READWRITE ? SQLITE_OPEN_READWRITE : SQLITE_OPEN_READONLY;
- }
-
- pFile->pMethod = &os2IoMethod;
- pFile->h = h;
- OpenCounter(+1);
- OSTRACE3( "OPEN %d pOutFlags=%d\n", pFile->h, pOutFlags );
- return SQLITE_OK;
-}
-
-/*
-** Delete the named file.
-*/
-static int os2Delete(
- sqlite3_vfs *pVfs, /* Not used on os2 */
- const char *zFilename, /* Name of file to delete */
- int syncDir /* Not used on os2 */
-){
- APIRET rc = NO_ERROR;
- char *zFilenameCp = convertUtf8PathToCp( zFilename );
- SimulateIOError( return SQLITE_IOERR_DELETE );
- rc = DosDelete( (PSZ)zFilenameCp );
- free( zFilenameCp );
- OSTRACE2( "DELETE \"%s\"\n", zFilename );
- return rc == NO_ERROR ? SQLITE_OK : SQLITE_IOERR_DELETE;
-}
-
-/*
-** Check the existance and status of a file.
-*/
-static int os2Access(
- sqlite3_vfs *pVfs, /* Not used on os2 */
- const char *zFilename, /* Name of file to check */
- int flags, /* Type of test to make on this file */
- int *pOut /* Write results here */
-){
- FILESTATUS3 fsts3ConfigInfo;
- APIRET rc = NO_ERROR;
- char *zFilenameCp = convertUtf8PathToCp( zFilename );
-
- memset( &fsts3ConfigInfo, 0, sizeof(fsts3ConfigInfo) );
- rc = DosQueryPathInfo( (PSZ)zFilenameCp, FIL_STANDARD,
- &fsts3ConfigInfo, sizeof(FILESTATUS3) );
- free( zFilenameCp );
- OSTRACE4( "ACCESS fsts3ConfigInfo.attrFile=%d flags=%d rc=%d\n",
- fsts3ConfigInfo.attrFile, flags, rc );
- switch( flags ){
- case SQLITE_ACCESS_READ:
- case SQLITE_ACCESS_EXISTS:
- rc = (rc == NO_ERROR);
- OSTRACE3( "ACCESS %s access of read and exists rc=%d\n", zFilename, rc );
- break;
- case SQLITE_ACCESS_READWRITE:
- rc = (rc == NO_ERROR) && ( (fsts3ConfigInfo.attrFile & FILE_READONLY) == 0 );
- OSTRACE3( "ACCESS %s access of read/write rc=%d\n", zFilename, rc );
- break;
- default:
- assert( !"Invalid flags argument" );
- }
- *pOut = rc;
- return SQLITE_OK;
-}
-
-
-#ifndef SQLITE_OMIT_LOAD_EXTENSION
-/*
-** Interfaces for opening a shared library, finding entry points
-** within the shared library, and closing the shared library.
-*/
-/*
-** Interfaces for opening a shared library, finding entry points
-** within the shared library, and closing the shared library.
-*/
-static void *os2DlOpen(sqlite3_vfs *pVfs, const char *zFilename){
- UCHAR loadErr[256];
- HMODULE hmod;
- APIRET rc;
- char *zFilenameCp = convertUtf8PathToCp(zFilename);
- rc = DosLoadModule((PSZ)loadErr, sizeof(loadErr), zFilenameCp, &hmod);
- free(zFilenameCp);
- return rc != NO_ERROR ? 0 : (void*)hmod;
-}
-/*
-** A no-op since the error code is returned on the DosLoadModule call.
-** os2Dlopen returns zero if DosLoadModule is not successful.
-*/
-static void os2DlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){
-/* no-op */
-}
-static void *os2DlSym(sqlite3_vfs *pVfs, void *pHandle, const char *zSymbol){
- PFN pfn;
- APIRET rc;
- rc = DosQueryProcAddr((HMODULE)pHandle, 0L, zSymbol, &pfn);
- if( rc != NO_ERROR ){
- /* if the symbol itself was not found, search again for the same
- * symbol with an extra underscore, that might be needed depending
- * on the calling convention */
- char _zSymbol[256] = "_";
- strncat(_zSymbol, zSymbol, 255);
- rc = DosQueryProcAddr((HMODULE)pHandle, 0L, _zSymbol, &pfn);
- }
- return rc != NO_ERROR ? 0 : (void*)pfn;
-}
-static void os2DlClose(sqlite3_vfs *pVfs, void *pHandle){
- DosFreeModule((HMODULE)pHandle);
-}
-#else /* if SQLITE_OMIT_LOAD_EXTENSION is defined: */
- #define os2DlOpen 0
- #define os2DlError 0
- #define os2DlSym 0
- #define os2DlClose 0
-#endif
-
-
-/*
-** Write up to nBuf bytes of randomness into zBuf.
-*/
-static int os2Randomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf ){
- int n = 0;
-#if defined(SQLITE_TEST)
- n = nBuf;
- memset(zBuf, 0, nBuf);
-#else
- int sizeofULong = sizeof(ULONG);
- if( (int)sizeof(DATETIME) <= nBuf - n ){
- DATETIME x;
- DosGetDateTime(&x);
- memcpy(&zBuf[n], &x, sizeof(x));
- n += sizeof(x);
- }
-
- if( sizeofULong <= nBuf - n ){
- PPIB ppib;
- DosGetInfoBlocks(NULL, &ppib);
- memcpy(&zBuf[n], &ppib->pib_ulpid, sizeofULong);
- n += sizeofULong;
- }
-
- if( sizeofULong <= nBuf - n ){
- PTIB ptib;
- DosGetInfoBlocks(&ptib, NULL);
- memcpy(&zBuf[n], &ptib->tib_ptib2->tib2_ultid, sizeofULong);
- n += sizeofULong;
- }
-
- /* if we still haven't filled the buffer yet the following will */
- /* grab everything once instead of making several calls for a single item */
- if( sizeofULong <= nBuf - n ){
- ULONG ulSysInfo[QSV_MAX];
- DosQuerySysInfo(1L, QSV_MAX, ulSysInfo, sizeofULong * QSV_MAX);
-
- memcpy(&zBuf[n], &ulSysInfo[QSV_MS_COUNT - 1], sizeofULong);
- n += sizeofULong;
-
- if( sizeofULong <= nBuf - n ){
- memcpy(&zBuf[n], &ulSysInfo[QSV_TIMER_INTERVAL - 1], sizeofULong);
- n += sizeofULong;
- }
- if( sizeofULong <= nBuf - n ){
- memcpy(&zBuf[n], &ulSysInfo[QSV_TIME_LOW - 1], sizeofULong);
- n += sizeofULong;
- }
- if( sizeofULong <= nBuf - n ){
- memcpy(&zBuf[n], &ulSysInfo[QSV_TIME_HIGH - 1], sizeofULong);
- n += sizeofULong;
- }
- if( sizeofULong <= nBuf - n ){
- memcpy(&zBuf[n], &ulSysInfo[QSV_TOTAVAILMEM - 1], sizeofULong);
- n += sizeofULong;
- }
- }
-#endif
-
- return n;
-}
-
-/*
-** Sleep for a little while. Return the amount of time slept.
-** The argument is the number of microseconds we want to sleep.
-** The return value is the number of microseconds of sleep actually
-** requested from the underlying operating system, a number which
-** might be greater than or equal to the argument, but not less
-** than the argument.
-*/
-static int os2Sleep( sqlite3_vfs *pVfs, int microsec ){
- DosSleep( (microsec/1000) );
- return microsec;
-}
-
-/*
-** The following variable, if set to a non-zero value, becomes the result
-** returned from sqlite3OsCurrentTime(). This is used for testing.
-*/
-#ifdef SQLITE_TEST
-SQLITE_API int sqlite3_current_time = 0;
-#endif
-
-/*
-** Find the current time (in Universal Coordinated Time). Write the
-** current time and date as a Julian Day number into *prNow and
-** return 0. Return 1 if the time and date cannot be found.
-*/
-int os2CurrentTime( sqlite3_vfs *pVfs, double *prNow ){
- double now;
- SHORT minute; /* needs to be able to cope with negative timezone offset */
- USHORT second, hour,
- day, month, year;
- DATETIME dt;
- DosGetDateTime( &dt );
- second = (USHORT)dt.seconds;
- minute = (SHORT)dt.minutes + dt.timezone;
- hour = (USHORT)dt.hours;
- day = (USHORT)dt.day;
- month = (USHORT)dt.month;
- year = (USHORT)dt.year;
-
- /* Calculations from http://www.astro.keele.ac.uk/~rno/Astronomy/hjd.html
- http://www.astro.keele.ac.uk/~rno/Astronomy/hjd-0.1.c */
- /* Calculate the Julian days */
- now = day - 32076 +
- 1461*(year + 4800 + (month - 14)/12)/4 +
- 367*(month - 2 - (month - 14)/12*12)/12 -
- 3*((year + 4900 + (month - 14)/12)/100)/4;
-
- /* Add the fractional hours, mins and seconds */
- now += (hour + 12.0)/24.0;
- now += minute/1440.0;
- now += second/86400.0;
- *prNow = now;
-#ifdef SQLITE_TEST
- if( sqlite3_current_time ){
- *prNow = sqlite3_current_time/86400.0 + 2440587.5;
- }
-#endif
- return 0;
-}
-
-static int os2GetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
- return 0;
-}
-
-/*
-** Initialize and deinitialize the operating system interface.
-*/
-SQLITE_API int sqlite3_os_init(void){
- static sqlite3_vfs os2Vfs = {
- 1, /* iVersion */
- sizeof(os2File), /* szOsFile */
- CCHMAXPATH, /* mxPathname */
- 0, /* pNext */
- "os2", /* zName */
- 0, /* pAppData */
-
- os2Open, /* xOpen */
- os2Delete, /* xDelete */
- os2Access, /* xAccess */
- os2FullPathname, /* xFullPathname */
- os2DlOpen, /* xDlOpen */
- os2DlError, /* xDlError */
- os2DlSym, /* xDlSym */
- os2DlClose, /* xDlClose */
- os2Randomness, /* xRandomness */
- os2Sleep, /* xSleep */
- os2CurrentTime, /* xCurrentTime */
- os2GetLastError /* xGetLastError */
- };
- sqlite3_vfs_register(&os2Vfs, 1);
- initUconvObjects();
- return SQLITE_OK;
-}
-SQLITE_API int sqlite3_os_end(void){
- freeUconvObjects();
- return SQLITE_OK;
-}
-
-#endif /* SQLITE_OS_OS2 */
-
-/************** End of os_os2.c **********************************************/
-/************** Begin file os_unix.c *****************************************/
-/*
-** 2004 May 22
-**
-** 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 VFS implementation for unix-like operating systems
-** include Linux, MacOSX, *BSD, QNX, VxWorks, AIX, HPUX, and others.
-**
-** There are actually several different VFS implementations in this file.
-** The differences are in the way that file locking is done. The default
-** implementation uses Posix Advisory Locks. Alternative implementations
-** use flock(), dot-files, various proprietary locking schemas, or simply
-** skip locking all together.
-**
-** This source file is organized into divisions where the logic for various
-** subfunctions is contained within the appropriate division. PLEASE
-** KEEP THE STRUCTURE OF THIS FILE INTACT. New code should be placed
-** in the correct division and should be clearly labeled.
-**
-** The layout of divisions is as follows:
-**
-** * General-purpose declarations and utility functions.
-** * Unique file ID logic used by VxWorks.
-** * Various locking primitive implementations (all except proxy locking):
-** + for Posix Advisory Locks
-** + for no-op locks
-** + for dot-file locks
-** + for flock() locking
-** + for named semaphore locks (VxWorks only)
-** + for AFP filesystem locks (MacOSX only)
-** * sqlite3_file methods not associated with locking.
-** * Definitions of sqlite3_io_methods objects for all locking
-** methods plus "finder" functions for each locking method.
-** * sqlite3_vfs method implementations.
-** * Locking primitives for the proxy uber-locking-method. (MacOSX only)
-** * Definitions of sqlite3_vfs objects for all locking methods
-** plus implementations of sqlite3_os_init() and sqlite3_os_end().
-*/
-#if SQLITE_OS_UNIX /* This file is used on unix only */
-
-/*
-** There are various methods for file locking used for concurrency
-** control:
-**
-** 1. POSIX locking (the default),
-** 2. No locking,
-** 3. Dot-file locking,
-** 4. flock() locking,
-** 5. AFP locking (OSX only),
-** 6. Named POSIX semaphores (VXWorks only),
-** 7. proxy locking. (OSX only)
-**
-** Styles 4, 5, and 7 are only available of SQLITE_ENABLE_LOCKING_STYLE
-** is defined to 1. The SQLITE_ENABLE_LOCKING_STYLE also enables automatic
-** selection of the appropriate locking style based on the filesystem
-** where the database is located.
-*/
-#if !defined(SQLITE_ENABLE_LOCKING_STYLE)
-# if defined(__APPLE__)
-# define SQLITE_ENABLE_LOCKING_STYLE 1
-# else
-# define SQLITE_ENABLE_LOCKING_STYLE 0
-# endif
-#endif
-
-/*
-** Define the OS_VXWORKS pre-processor macro to 1 if building on
-** vxworks, or 0 otherwise.
-*/
-#ifndef OS_VXWORKS
-# if defined(__RTP__) || defined(_WRS_KERNEL)
-# define OS_VXWORKS 1
-# else
-# define OS_VXWORKS 0
-# endif
-#endif
-
-/*
-** These #defines should enable >2GB file support on Posix if the
-** underlying operating system supports it. If the OS lacks
-** large file support, these should be no-ops.
-**
-** Large file support can be disabled using the -DSQLITE_DISABLE_LFS switch
-** on the compiler command line. This is necessary if you are compiling
-** on a recent machine (ex: RedHat 7.2) but you want your code to work
-** on an older machine (ex: RedHat 6.0). If you compile on RedHat 7.2
-** without this option, LFS is enable. But LFS does not exist in the kernel
-** in RedHat 6.0, so the code won't work. Hence, for maximum binary
-** portability you should omit LFS.
-**
-** The previous paragraph was written in 2005. (This paragraph is written
-** on 2008-11-28.) These days, all Linux kernels support large files, so
-** you should probably leave LFS enabled. But some embedded platforms might
-** lack LFS in which case the SQLITE_DISABLE_LFS macro might still be useful.
-*/
-#ifndef SQLITE_DISABLE_LFS
-# define _LARGE_FILE 1
-# ifndef _FILE_OFFSET_BITS
-# define _FILE_OFFSET_BITS 64
-# endif
-# define _LARGEFILE_SOURCE 1
-#endif
-
-/*
-** standard include files.
-*/
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <sys/time.h>
-#include <errno.h>
-
-#if SQLITE_ENABLE_LOCKING_STYLE
-# include <sys/ioctl.h>
-# if OS_VXWORKS
-# include <semaphore.h>
-# include <limits.h>
-# else
-# include <sys/file.h>
-# include <sys/param.h>
-# include <sys/mount.h>
-# endif
-#endif /* SQLITE_ENABLE_LOCKING_STYLE */
-
-/*
-** If we are to be thread-safe, include the pthreads header and define
-** the SQLITE_UNIX_THREADS macro.
-*/
-#if SQLITE_THREADSAFE
-# define SQLITE_UNIX_THREADS 1
-#endif
-
-/*
-** Default permissions when creating a new file
-*/
-#ifndef SQLITE_DEFAULT_FILE_PERMISSIONS
-# define SQLITE_DEFAULT_FILE_PERMISSIONS 0644
-#endif
-
-/*
- ** Default permissions when creating auto proxy dir
- */
-#ifndef SQLITE_DEFAULT_PROXYDIR_PERMISSIONS
-# define SQLITE_DEFAULT_PROXYDIR_PERMISSIONS 0755
-#endif
-
-/*
-** Maximum supported path-length.
-*/
-#define MAX_PATHNAME 512
-
-/*
-** Only set the lastErrno if the error code is a real error and not
-** a normal expected return code of SQLITE_BUSY or SQLITE_OK
-*/
-#define IS_LOCK_ERROR(x) ((x != SQLITE_OK) && (x != SQLITE_BUSY))
-
-
-/*
-** Sometimes, after a file handle is closed by SQLite, the file descriptor
-** cannot be closed immediately. In these cases, instances of the following
-** structure are used to store the file descriptor while waiting for an
-** opportunity to either close or reuse it.
-*/
-typedef struct UnixUnusedFd UnixUnusedFd;
-struct UnixUnusedFd {
- int fd; /* File descriptor to close */
- int flags; /* Flags this file descriptor was opened with */
- UnixUnusedFd *pNext; /* Next unused file descriptor on same file */
-};
-
-/*
-** The unixFile structure is subclass of sqlite3_file specific to the unix
-** VFS implementations.
-*/
-typedef struct unixFile unixFile;
-struct unixFile {
- sqlite3_io_methods const *pMethod; /* Always the first entry */
- struct unixOpenCnt *pOpen; /* Info about all open fd's on this inode */
- struct unixLockInfo *pLock; /* Info about locks on this inode */
- int h; /* The file descriptor */
- int dirfd; /* File descriptor for the directory */
- unsigned char locktype; /* The type of lock held on this fd */
- int lastErrno; /* The unix errno from the last I/O error */
- void *lockingContext; /* Locking style specific state */
- UnixUnusedFd *pUnused; /* Pre-allocated UnixUnusedFd */
- int fileFlags; /* Miscellanous flags */
-#if SQLITE_ENABLE_LOCKING_STYLE
- int openFlags; /* The flags specified at open() */
-#endif
-#if SQLITE_THREADSAFE && defined(__linux__)
- pthread_t tid; /* The thread that "owns" this unixFile */
-#endif
-#if OS_VXWORKS
- int isDelete; /* Delete on close if true */
- struct vxworksFileId *pId; /* Unique file ID */
-#endif
-#ifndef NDEBUG
- /* The next group of variables are used to track whether or not the
- ** transaction counter in bytes 24-27 of database files are updated
- ** whenever any part of the database changes. An assertion fault will
- ** occur if a file is updated without also updating the transaction
- ** counter. This test is made to avoid new problems similar to the
- ** one described by ticket #3584.
- */
- unsigned char transCntrChng; /* True if the transaction counter changed */
- unsigned char dbUpdate; /* True if any part of database file changed */
- unsigned char inNormalWrite; /* True if in a normal write operation */
-#endif
-#ifdef SQLITE_TEST
- /* In test mode, increase the size of this structure a bit so that
- ** it is larger than the struct CrashFile defined in test6.c.
- */
- char aPadding[32];
-#endif
-};
-
-/*
-** The following macros define bits in unixFile.fileFlags
-*/
-#define SQLITE_WHOLE_FILE_LOCKING 0x0001 /* Use whole-file locking */
-
-/*
-** Include code that is common to all os_*.c files
-*/
-/************** Include os_common.h in the middle of os_unix.c ***************/
-/************** Begin file os_common.h ***************************************/
-/*
-** 2004 May 22
-**
-** 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 macros and a little bit of code that is common to
-** all of the platform-specific files (os_*.c) and is #included into those
-** files.
-**
-** This file should be #included by the os_*.c files only. It is not a
-** general purpose header file.
-**
-** $Id: os_common.h,v 1.38 2009/02/24 18:40:50 danielk1977 Exp $
-*/
-#ifndef _OS_COMMON_H_
-#define _OS_COMMON_H_
-
-/*
-** At least two bugs have slipped in because we changed the MEMORY_DEBUG
-** macro to SQLITE_DEBUG and some older makefiles have not yet made the
-** switch. The following code should catch this problem at compile-time.
-*/
-#ifdef MEMORY_DEBUG
-# error "The MEMORY_DEBUG macro is obsolete. Use SQLITE_DEBUG instead."
-#endif
-
-#ifdef SQLITE_DEBUG
-SQLITE_PRIVATE int sqlite3OSTrace = 0;
-#define OSTRACE1(X) if( sqlite3OSTrace ) sqlite3DebugPrintf(X)
-#define OSTRACE2(X,Y) if( sqlite3OSTrace ) sqlite3DebugPrintf(X,Y)
-#define OSTRACE3(X,Y,Z) if( sqlite3OSTrace ) sqlite3DebugPrintf(X,Y,Z)
-#define OSTRACE4(X,Y,Z,A) if( sqlite3OSTrace ) sqlite3DebugPrintf(X,Y,Z,A)
-#define OSTRACE5(X,Y,Z,A,B) if( sqlite3OSTrace ) sqlite3DebugPrintf(X,Y,Z,A,B)
-#define OSTRACE6(X,Y,Z,A,B,C) \
- if(sqlite3OSTrace) sqlite3DebugPrintf(X,Y,Z,A,B,C)
-#define OSTRACE7(X,Y,Z,A,B,C,D) \
- if(sqlite3OSTrace) sqlite3DebugPrintf(X,Y,Z,A,B,C,D)
-#else
-#define OSTRACE1(X)
-#define OSTRACE2(X,Y)
-#define OSTRACE3(X,Y,Z)
-#define OSTRACE4(X,Y,Z,A)
-#define OSTRACE5(X,Y,Z,A,B)
-#define OSTRACE6(X,Y,Z,A,B,C)
-#define OSTRACE7(X,Y,Z,A,B,C,D)
-#endif
-
-/*
-** Macros for performance tracing. Normally turned off. Only works
-** on i486 hardware.
-*/
-#ifdef SQLITE_PERFORMANCE_TRACE
-
-/*
-** hwtime.h contains inline assembler code for implementing
-** high-performance timing routines.
-*/
-/************** Include hwtime.h in the middle of os_common.h ****************/
-/************** Begin file hwtime.h ******************************************/
-/*
-** 2008 May 27
-**
-** 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 inline asm code for retrieving "high-performance"
-** counters for x86 class CPUs.
-**
-** $Id: hwtime.h,v 1.3 2008/08/01 14:33:15 shane Exp $
-*/
-#ifndef _HWTIME_H_
-#define _HWTIME_H_
-
-/*
-** The following routine only works on pentium-class (or newer) processors.
-** It uses the RDTSC opcode to read the cycle count value out of the
-** processor and returns that value. This can be used for high-res
-** profiling.
-*/
-#if (defined(__GNUC__) || defined(_MSC_VER)) && \
- (defined(i386) || defined(__i386__) || defined(_M_IX86))
-
- #if defined(__GNUC__)
-
- __inline__ sqlite_uint64 sqlite3Hwtime(void){
- unsigned int lo, hi;
- __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
- return (sqlite_uint64)hi << 32 | lo;
- }
-
- #elif defined(_MSC_VER)
-
- __declspec(naked) __inline sqlite_uint64 __cdecl sqlite3Hwtime(void){
- __asm {
- rdtsc
- ret ; return value at EDX:EAX
- }
- }
-
- #endif
-
-#elif (defined(__GNUC__) && defined(__x86_64__))
-
- __inline__ sqlite_uint64 sqlite3Hwtime(void){
- unsigned long val;
- __asm__ __volatile__ ("rdtsc" : "=A" (val));
- return val;
- }
-
-#elif (defined(__GNUC__) && defined(__ppc__))
-
- __inline__ sqlite_uint64 sqlite3Hwtime(void){
- unsigned long long retval;
- unsigned long junk;
- __asm__ __volatile__ ("\n\
- 1: mftbu %1\n\
- mftb %L0\n\
- mftbu %0\n\
- cmpw %0,%1\n\
- bne 1b"
- : "=r" (retval), "=r" (junk));
- return retval;
- }
-
-#else
-
- #error Need implementation of sqlite3Hwtime() for your platform.
-
- /*
- ** To compile without implementing sqlite3Hwtime() for your platform,
- ** you can remove the above #error and use the following
- ** stub function. You will lose timing support for many
- ** of the debugging and testing utilities, but it should at
- ** least compile and run.
- */
-SQLITE_PRIVATE sqlite_uint64 sqlite3Hwtime(void){ return ((sqlite_uint64)0); }
-
-#endif
-
-#endif /* !defined(_HWTIME_H_) */
-
-/************** End of hwtime.h **********************************************/
-/************** Continuing where we left off in os_common.h ******************/
-
-static sqlite_uint64 g_start;
-static sqlite_uint64 g_elapsed;
-#define TIMER_START g_start=sqlite3Hwtime()
-#define TIMER_END g_elapsed=sqlite3Hwtime()-g_start
-#define TIMER_ELAPSED g_elapsed
-#else
-#define TIMER_START
-#define TIMER_END
-#define TIMER_ELAPSED ((sqlite_uint64)0)
-#endif
-
-/*
-** If we compile with the SQLITE_TEST macro set, then the following block
-** of code will give us the ability to simulate a disk I/O error. This
-** is used for testing the I/O recovery logic.
-*/
-#ifdef SQLITE_TEST
-SQLITE_API int sqlite3_io_error_hit = 0; /* Total number of I/O Errors */
-SQLITE_API int sqlite3_io_error_hardhit = 0; /* Number of non-benign errors */
-SQLITE_API int sqlite3_io_error_pending = 0; /* Count down to first I/O error */
-SQLITE_API int sqlite3_io_error_persist = 0; /* True if I/O errors persist */
-SQLITE_API int sqlite3_io_error_benign = 0; /* True if errors are benign */
-SQLITE_API int sqlite3_diskfull_pending = 0;
-SQLITE_API int sqlite3_diskfull = 0;
-#define SimulateIOErrorBenign(X) sqlite3_io_error_benign=(X)
-#define SimulateIOError(CODE) \
- if( (sqlite3_io_error_persist && sqlite3_io_error_hit) \
- || sqlite3_io_error_pending-- == 1 ) \
- { local_ioerr(); CODE; }
-static void local_ioerr(){
- IOTRACE(("IOERR\n"));
- sqlite3_io_error_hit++;
- if( !sqlite3_io_error_benign ) sqlite3_io_error_hardhit++;
-}
-#define SimulateDiskfullError(CODE) \
- if( sqlite3_diskfull_pending ){ \
- if( sqlite3_diskfull_pending == 1 ){ \
- local_ioerr(); \
- sqlite3_diskfull = 1; \
- sqlite3_io_error_hit = 1; \
- CODE; \
- }else{ \
- sqlite3_diskfull_pending--; \
- } \
- }
-#else
-#define SimulateIOErrorBenign(X)
-#define SimulateIOError(A)
-#define SimulateDiskfullError(A)
-#endif
-
-/*
-** When testing, keep a count of the number of open files.
-*/
-#ifdef SQLITE_TEST
-SQLITE_API int sqlite3_open_file_count = 0;
-#define OpenCounter(X) sqlite3_open_file_count+=(X)
-#else
-#define OpenCounter(X)
-#endif
-
-#endif /* !defined(_OS_COMMON_H_) */
-
-/************** End of os_common.h *******************************************/
-/************** Continuing where we left off in os_unix.c ********************/
-
-/*
-** Define various macros that are missing from some systems.
-*/
-#ifndef O_LARGEFILE
-# define O_LARGEFILE 0
-#endif
-#ifdef SQLITE_DISABLE_LFS
-# undef O_LARGEFILE
-# define O_LARGEFILE 0
-#endif
-#ifndef O_NOFOLLOW
-# define O_NOFOLLOW 0
-#endif
-#ifndef O_BINARY
-# define O_BINARY 0
-#endif
-
-/*
-** The DJGPP compiler environment looks mostly like Unix, but it
-** lacks the fcntl() system call. So redefine fcntl() to be something
-** that always succeeds. This means that locking does not occur under
-** DJGPP. But it is DOS - what did you expect?
-*/
-#ifdef __DJGPP__
-# define fcntl(A,B,C) 0
-#endif
-
-/*
-** The threadid macro resolves to the thread-id or to 0. Used for
-** testing and debugging only.
-*/
-#if SQLITE_THREADSAFE
-#define threadid pthread_self()
-#else
-#define threadid 0
-#endif
-
-
-/*
-** Helper functions to obtain and relinquish the global mutex. The
-** global mutex is used to protect the unixOpenCnt, unixLockInfo and
-** vxworksFileId objects used by this file, all of which may be
-** shared by multiple threads.
-**
-** Function unixMutexHeld() is used to assert() that the global mutex
-** is held when required. This function is only used as part of assert()
-** statements. e.g.
-**
-** unixEnterMutex()
-** assert( unixMutexHeld() );
-** unixEnterLeave()
-*/
-static void unixEnterMutex(void){
- sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
-}
-static void unixLeaveMutex(void){
- sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
-}
-#ifdef SQLITE_DEBUG
-static int unixMutexHeld(void) {
- return sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
-}
-#endif
-
-
-#ifdef SQLITE_DEBUG
-/*
-** Helper function for printing out trace information from debugging
-** binaries. This returns the string represetation of the supplied
-** integer lock-type.
-*/
-static const char *locktypeName(int locktype){
- switch( locktype ){
- case NO_LOCK: return "NONE";
- case SHARED_LOCK: return "SHARED";
- case RESERVED_LOCK: return "RESERVED";
- case PENDING_LOCK: return "PENDING";
- case EXCLUSIVE_LOCK: return "EXCLUSIVE";
- }
- return "ERROR";
-}
-#endif
-
-#ifdef SQLITE_LOCK_TRACE
-/*
-** Print out information about all locking operations.
-**
-** This routine is used for troubleshooting locks on multithreaded
-** platforms. Enable by compiling with the -DSQLITE_LOCK_TRACE
-** command-line option on the compiler. This code is normally
-** turned off.
-*/
-static int lockTrace(int fd, int op, struct flock *p){
- char *zOpName, *zType;
- int s;
- int savedErrno;
- if( op==F_GETLK ){
- zOpName = "GETLK";
- }else if( op==F_SETLK ){
- zOpName = "SETLK";
- }else{
- s = fcntl(fd, op, p);
- sqlite3DebugPrintf("fcntl unknown %d %d %d\n", fd, op, s);
- return s;
- }
- if( p->l_type==F_RDLCK ){
- zType = "RDLCK";
- }else if( p->l_type==F_WRLCK ){
- zType = "WRLCK";
- }else if( p->l_type==F_UNLCK ){
- zType = "UNLCK";
- }else{
- assert( 0 );
- }
- assert( p->l_whence==SEEK_SET );
- s = fcntl(fd, op, p);
- savedErrno = errno;
- sqlite3DebugPrintf("fcntl %d %d %s %s %d %d %d %d\n",
- threadid, fd, zOpName, zType, (int)p->l_start, (int)p->l_len,
- (int)p->l_pid, s);
- if( s==(-1) && op==F_SETLK && (p->l_type==F_RDLCK || p->l_type==F_WRLCK) ){
- struct flock l2;
- l2 = *p;
- fcntl(fd, F_GETLK, &l2);
- if( l2.l_type==F_RDLCK ){
- zType = "RDLCK";
- }else if( l2.l_type==F_WRLCK ){
- zType = "WRLCK";
- }else if( l2.l_type==F_UNLCK ){
- zType = "UNLCK";
- }else{
- assert( 0 );
- }
- sqlite3DebugPrintf("fcntl-failure-reason: %s %d %d %d\n",
- zType, (int)l2.l_start, (int)l2.l_len, (int)l2.l_pid);
- }
- errno = savedErrno;
- return s;
-}
-#define fcntl lockTrace
-#endif /* SQLITE_LOCK_TRACE */
-
-
-
-/*
-** This routine translates a standard POSIX errno code into something
-** useful to the clients of the sqlite3 functions. Specifically, it is
-** intended to translate a variety of "try again" errors into SQLITE_BUSY
-** and a variety of "please close the file descriptor NOW" errors into
-** SQLITE_IOERR
-**
-** Errors during initialization of locks, or file system support for locks,
-** should handle ENOLCK, ENOTSUP, EOPNOTSUPP separately.
-*/
-static int sqliteErrorFromPosixError(int posixError, int sqliteIOErr) {
- switch (posixError) {
- case 0:
- return SQLITE_OK;
-
- case EAGAIN:
- case ETIMEDOUT:
- case EBUSY:
- case EINTR:
- case ENOLCK:
- /* random NFS retry error, unless during file system support
- * introspection, in which it actually means what it says */
- return SQLITE_BUSY;
-
- case EACCES:
- /* EACCES is like EAGAIN during locking operations, but not any other time*/
- if( (sqliteIOErr == SQLITE_IOERR_LOCK) ||
- (sqliteIOErr == SQLITE_IOERR_UNLOCK) ||
- (sqliteIOErr == SQLITE_IOERR_RDLOCK) ||
- (sqliteIOErr == SQLITE_IOERR_CHECKRESERVEDLOCK) ){
- return SQLITE_BUSY;
- }
- /* else fall through */
- case EPERM:
- return SQLITE_PERM;
-
- case EDEADLK:
- return SQLITE_IOERR_BLOCKED;
-
-#if EOPNOTSUPP!=ENOTSUP
- case EOPNOTSUPP:
- /* something went terribly awry, unless during file system support
- * introspection, in which it actually means what it says */
-#endif
-#ifdef ENOTSUP
- case ENOTSUP:
- /* invalid fd, unless during file system support introspection, in which
- * it actually means what it says */
-#endif
- case EIO:
- case EBADF:
- case EINVAL:
- case ENOTCONN:
- case ENODEV:
- case ENXIO:
- case ENOENT:
- case ESTALE:
- case ENOSYS:
- /* these should force the client to close the file and reconnect */
-
- default:
- return sqliteIOErr;
- }
-}
-
-
-
-/******************************************************************************
-****************** Begin Unique File ID Utility Used By VxWorks ***************
-**
-** On most versions of unix, we can get a unique ID for a file by concatenating
-** the device number and the inode number. But this does not work on VxWorks.
-** On VxWorks, a unique file id must be based on the canonical filename.
-**
-** A pointer to an instance of the following structure can be used as a
-** unique file ID in VxWorks. Each instance of this structure contains
-** a copy of the canonical filename. There is also a reference count.
-** The structure is reclaimed when the number of pointers to it drops to
-** zero.
-**
-** There are never very many files open at one time and lookups are not
-** a performance-critical path, so it is sufficient to put these
-** structures on a linked list.
-*/
-struct vxworksFileId {
- struct vxworksFileId *pNext; /* Next in a list of them all */
- int nRef; /* Number of references to this one */
- int nName; /* Length of the zCanonicalName[] string */
- char *zCanonicalName; /* Canonical filename */
-};
-
-#if OS_VXWORKS
-/*
-** All unique filenames are held on a linked list headed by this
-** variable:
-*/
-static struct vxworksFileId *vxworksFileList = 0;
-
-/*
-** Simplify a filename into its canonical form
-** by making the following changes:
-**
-** * removing any trailing and duplicate /
-** * convert /./ into just /
-** * convert /A/../ where A is any simple name into just /
-**
-** Changes are made in-place. Return the new name length.
-**
-** The original filename is in z[0..n-1]. Return the number of
-** characters in the simplified name.
-*/
-static int vxworksSimplifyName(char *z, int n){
- int i, j;
- while( n>1 && z[n-1]=='/' ){ n--; }
- for(i=j=0; i<n; i++){
- if( z[i]=='/' ){
- if( z[i+1]=='/' ) continue;
- if( z[i+1]=='.' && i+2<n && z[i+2]=='/' ){
- i += 1;
- continue;
- }
- if( z[i+1]=='.' && i+3<n && z[i+2]=='.' && z[i+3]=='/' ){
- while( j>0 && z[j-1]!='/' ){ j--; }
- if( j>0 ){ j--; }
- i += 2;
- continue;
- }
- }
- z[j++] = z[i];
- }
- z[j] = 0;
- return j;
-}
-
-/*
-** Find a unique file ID for the given absolute pathname. Return
-** a pointer to the vxworksFileId object. This pointer is the unique
-** file ID.
-**
-** The nRef field of the vxworksFileId object is incremented before
-** the object is returned. A new vxworksFileId object is created
-** and added to the global list if necessary.
-**
-** If a memory allocation error occurs, return NULL.
-*/
-static struct vxworksFileId *vxworksFindFileId(const char *zAbsoluteName){
- struct vxworksFileId *pNew; /* search key and new file ID */
- struct vxworksFileId *pCandidate; /* For looping over existing file IDs */
- int n; /* Length of zAbsoluteName string */
-
- assert( zAbsoluteName[0]=='/' );
- n = (int)strlen(zAbsoluteName);
- pNew = sqlite3_malloc( sizeof(*pNew) + (n+1) );
- if( pNew==0 ) return 0;
- pNew->zCanonicalName = (char*)&pNew[1];
- memcpy(pNew->zCanonicalName, zAbsoluteName, n+1);
- n = vxworksSimplifyName(pNew->zCanonicalName, n);
-
- /* Search for an existing entry that matching the canonical name.
- ** If found, increment the reference count and return a pointer to
- ** the existing file ID.
- */
- unixEnterMutex();
- for(pCandidate=vxworksFileList; pCandidate; pCandidate=pCandidate->pNext){
- if( pCandidate->nName==n
- && memcmp(pCandidate->zCanonicalName, pNew->zCanonicalName, n)==0
- ){
- sqlite3_free(pNew);
- pCandidate->nRef++;
- unixLeaveMutex();
- return pCandidate;
- }
- }
-
- /* No match was found. We will make a new file ID */
- pNew->nRef = 1;
- pNew->nName = n;
- pNew->pNext = vxworksFileList;
- vxworksFileList = pNew;
- unixLeaveMutex();
- return pNew;
-}
-
-/*
-** Decrement the reference count on a vxworksFileId object. Free
-** the object when the reference count reaches zero.
-*/
-static void vxworksReleaseFileId(struct vxworksFileId *pId){
- unixEnterMutex();
- assert( pId->nRef>0 );
- pId->nRef--;
- if( pId->nRef==0 ){
- struct vxworksFileId **pp;
- for(pp=&vxworksFileList; *pp && *pp!=pId; pp = &((*pp)->pNext)){}
- assert( *pp==pId );
- *pp = pId->pNext;
- sqlite3_free(pId);
- }
- unixLeaveMutex();
-}
-#endif /* OS_VXWORKS */
-/*************** End of Unique File ID Utility Used By VxWorks ****************
-******************************************************************************/
-
-
-/******************************************************************************
-*************************** Posix Advisory Locking ****************************
-**
-** POSIX advisory locks are broken by design. ANSI STD 1003.1 (1996)
-** section 6.5.2.2 lines 483 through 490 specify that when a process
-** sets or clears a lock, that operation overrides any prior locks set
-** by the same process. It does not explicitly say so, but this implies
-** that it overrides locks set by the same process using a different
-** file descriptor. Consider this test case:
-**
-** int fd1 = open("./file1", O_RDWR|O_CREAT, 0644);
-** int fd2 = open("./file2", O_RDWR|O_CREAT, 0644);
-**
-** Suppose ./file1 and ./file2 are really the same file (because
-** one is a hard or symbolic link to the other) then if you set
-** an exclusive lock on fd1, then try to get an exclusive lock
-** on fd2, it works. I would have expected the second lock to
-** fail since there was already a lock on the file due to fd1.
-** But not so. Since both locks came from the same process, the
-** second overrides the first, even though they were on different
-** file descriptors opened on different file names.
-**
-** This means that we cannot use POSIX locks to synchronize file access
-** among competing threads of the same process. POSIX locks will work fine
-** to synchronize access for threads in separate processes, but not
-** threads within the same process.
-**
-** To work around the problem, SQLite has to manage file locks internally
-** on its own. Whenever a new database is opened, we have to find the
-** specific inode of the database file (the inode is determined by the
-** st_dev and st_ino fields of the stat structure that fstat() fills in)
-** and check for locks already existing on that inode. When locks are
-** created or removed, we have to look at our own internal record of the
-** locks to see if another thread has previously set a lock on that same
-** inode.
-**
-** (Aside: The use of inode numbers as unique IDs does not work on VxWorks.
-** For VxWorks, we have to use the alternative unique ID system based on
-** canonical filename and implemented in the previous division.)
-**
-** The sqlite3_file structure for POSIX is no longer just an integer file
-** descriptor. It is now a structure that holds the integer file
-** descriptor and a pointer to a structure that describes the internal
-** locks on the corresponding inode. There is one locking structure
-** per inode, so if the same inode is opened twice, both unixFile structures
-** point to the same locking structure. The locking structure keeps
-** a reference count (so we will know when to delete it) and a "cnt"
-** field that tells us its internal lock status. cnt==0 means the
-** file is unlocked. cnt==-1 means the file has an exclusive lock.
-** cnt>0 means there are cnt shared locks on the file.
-**
-** Any attempt to lock or unlock a file first checks the locking
-** structure. The fcntl() system call is only invoked to set a
-** POSIX lock if the internal lock structure transitions between
-** a locked and an unlocked state.
-**
-** But wait: there are yet more problems with POSIX advisory locks.
-**
-** If you close a file descriptor that points to a file that has locks,
-** all locks on that file that are owned by the current process are
-** released. To work around this problem, each unixFile structure contains
-** a pointer to an unixOpenCnt structure. There is one unixOpenCnt structure
-** per open inode, which means that multiple unixFile can point to a single
-** unixOpenCnt. When an attempt is made to close an unixFile, if there are
-** other unixFile open on the same inode that are holding locks, the call
-** to close() the file descriptor is deferred until all of the locks clear.
-** The unixOpenCnt structure keeps a list of file descriptors that need to
-** be closed and that list is walked (and cleared) when the last lock
-** clears.
-**
-** Yet another problem: LinuxThreads do not play well with posix locks.
-**
-** Many older versions of linux use the LinuxThreads library which is
-** not posix compliant. Under LinuxThreads, a lock created by thread
-** A cannot be modified or overridden by a different thread B.
-** Only thread A can modify the lock. Locking behavior is correct
-** if the appliation uses the newer Native Posix Thread Library (NPTL)
-** on linux - with NPTL a lock created by thread A can override locks
-** in thread B. But there is no way to know at compile-time which
-** threading library is being used. So there is no way to know at
-** compile-time whether or not thread A can override locks on thread B.
-** We have to do a run-time check to discover the behavior of the
-** current process.
-**
-** On systems where thread A is unable to modify locks created by
-** thread B, we have to keep track of which thread created each
-** lock. Hence there is an extra field in the key to the unixLockInfo
-** structure to record this information. And on those systems it
-** is illegal to begin a transaction in one thread and finish it
-** in another. For this latter restriction, there is no work-around.
-** It is a limitation of LinuxThreads.
-*/
-
-/*
-** Set or check the unixFile.tid field. This field is set when an unixFile
-** is first opened. All subsequent uses of the unixFile verify that the
-** same thread is operating on the unixFile. Some operating systems do
-** not allow locks to be overridden by other threads and that restriction
-** means that sqlite3* database handles cannot be moved from one thread
-** to another while locks are held.
-**
-** Version 3.3.1 (2006-01-15): unixFile can be moved from one thread to
-** another as long as we are running on a system that supports threads
-** overriding each others locks (which is now the most common behavior)
-** or if no locks are held. But the unixFile.pLock field needs to be
-** recomputed because its key includes the thread-id. See the
-** transferOwnership() function below for additional information
-*/
-#if SQLITE_THREADSAFE && defined(__linux__)
-# define SET_THREADID(X) (X)->tid = pthread_self()
-# define CHECK_THREADID(X) (threadsOverrideEachOthersLocks==0 && \
- !pthread_equal((X)->tid, pthread_self()))
-#else
-# define SET_THREADID(X)
-# define CHECK_THREADID(X) 0
-#endif
-
-/*
-** An instance of the following structure serves as the key used
-** to locate a particular unixOpenCnt structure given its inode. This
-** is the same as the unixLockKey except that the thread ID is omitted.
-*/
-struct unixFileId {
- dev_t dev; /* Device number */
-#if OS_VXWORKS
- struct vxworksFileId *pId; /* Unique file ID for vxworks. */
-#else
- ino_t ino; /* Inode number */
-#endif
-};
-
-/*
-** An instance of the following structure serves as the key used
-** to locate a particular unixLockInfo structure given its inode.
-**
-** If threads cannot override each others locks (LinuxThreads), then we
-** set the unixLockKey.tid field to the thread ID. If threads can override
-** each others locks (Posix and NPTL) then tid is always set to zero.
-** tid is omitted if we compile without threading support or on an OS
-** other than linux.
-*/
-struct unixLockKey {
- struct unixFileId fid; /* Unique identifier for the file */
-#if SQLITE_THREADSAFE && defined(__linux__)
- pthread_t tid; /* Thread ID of lock owner. Zero if not using LinuxThreads */
-#endif
-};
-
-/*
-** An instance of the following structure is allocated for each open
-** inode. Or, on LinuxThreads, there is one of these structures for
-** each inode opened by each thread.
-**
-** A single inode can have multiple file descriptors, so each unixFile
-** structure contains a pointer to an instance of this object and this
-** object keeps a count of the number of unixFile pointing to it.
-*/
-struct unixLockInfo {
- struct unixLockKey lockKey; /* The lookup key */
- int cnt; /* Number of SHARED locks held */
- int locktype; /* One of SHARED_LOCK, RESERVED_LOCK etc. */
- int nRef; /* Number of pointers to this structure */
- struct unixLockInfo *pNext; /* List of all unixLockInfo objects */
- struct unixLockInfo *pPrev; /* .... doubly linked */
-};
-
-/*
-** An instance of the following structure is allocated for each open
-** inode. This structure keeps track of the number of locks on that
-** inode. If a close is attempted against an inode that is holding
-** locks, the close is deferred until all locks clear by adding the
-** file descriptor to be closed to the pending list.
-**
-** TODO: Consider changing this so that there is only a single file
-** descriptor for each open file, even when it is opened multiple times.
-** The close() system call would only occur when the last database
-** using the file closes.
-*/
-struct unixOpenCnt {
- struct unixFileId fileId; /* The lookup key */
- int nRef; /* Number of pointers to this structure */
- int nLock; /* Number of outstanding locks */
- UnixUnusedFd *pUnused; /* Unused file descriptors to close */
-#if OS_VXWORKS
- sem_t *pSem; /* Named POSIX semaphore */
- char aSemName[MAX_PATHNAME+2]; /* Name of that semaphore */
-#endif
- struct unixOpenCnt *pNext, *pPrev; /* List of all unixOpenCnt objects */
-};
-
-/*
-** Lists of all unixLockInfo and unixOpenCnt objects. These used to be hash
-** tables. But the number of objects is rarely more than a dozen and
-** never exceeds a few thousand. And lookup is not on a critical
-** path so a simple linked list will suffice.
-*/
-static struct unixLockInfo *lockList = 0;
-static struct unixOpenCnt *openList = 0;
-
-/*
-** This variable remembers whether or not threads can override each others
-** locks.
-**
-** 0: No. Threads cannot override each others locks. (LinuxThreads)
-** 1: Yes. Threads can override each others locks. (Posix & NLPT)
-** -1: We don't know yet.
-**
-** On some systems, we know at compile-time if threads can override each
-** others locks. On those systems, the SQLITE_THREAD_OVERRIDE_LOCK macro
-** will be set appropriately. On other systems, we have to check at
-** runtime. On these latter systems, SQLTIE_THREAD_OVERRIDE_LOCK is
-** undefined.
-**
-** This variable normally has file scope only. But during testing, we make
-** it a global so that the test code can change its value in order to verify
-** that the right stuff happens in either case.
-*/
-#if SQLITE_THREADSAFE && defined(__linux__)
-# ifndef SQLITE_THREAD_OVERRIDE_LOCK
-# define SQLITE_THREAD_OVERRIDE_LOCK -1
-# endif
-# ifdef SQLITE_TEST
-int threadsOverrideEachOthersLocks = SQLITE_THREAD_OVERRIDE_LOCK;
-# else
-static int threadsOverrideEachOthersLocks = SQLITE_THREAD_OVERRIDE_LOCK;
-# endif
-#endif
-
-/*
-** This structure holds information passed into individual test
-** threads by the testThreadLockingBehavior() routine.
-*/
-struct threadTestData {
- int fd; /* File to be locked */
- struct flock lock; /* The locking operation */
- int result; /* Result of the locking operation */
-};
-
-#if SQLITE_THREADSAFE && defined(__linux__)
-/*
-** This function is used as the main routine for a thread launched by
-** testThreadLockingBehavior(). It tests whether the shared-lock obtained
-** by the main thread in testThreadLockingBehavior() conflicts with a
-** hypothetical write-lock obtained by this thread on the same file.
-**
-** The write-lock is not actually acquired, as this is not possible if
-** the file is open in read-only mode (see ticket #3472).
-*/
-static void *threadLockingTest(void *pArg){
- struct threadTestData *pData = (struct threadTestData*)pArg;
- pData->result = fcntl(pData->fd, F_GETLK, &pData->lock);
- return pArg;
-}
-#endif /* SQLITE_THREADSAFE && defined(__linux__) */
-
-
-#if SQLITE_THREADSAFE && defined(__linux__)
-/*
-** This procedure attempts to determine whether or not threads
-** can override each others locks then sets the
-** threadsOverrideEachOthersLocks variable appropriately.
-*/
-static void testThreadLockingBehavior(int fd_orig){
- int fd;
- int rc;
- struct threadTestData d;
- struct flock l;
- pthread_t t;
-
- fd = dup(fd_orig);
- if( fd<0 ) return;
- memset(&l, 0, sizeof(l));
- l.l_type = F_RDLCK;
- l.l_len = 1;
- l.l_start = 0;
- l.l_whence = SEEK_SET;
- rc = fcntl(fd_orig, F_SETLK, &l);
- if( rc!=0 ) return;
- memset(&d, 0, sizeof(d));
- d.fd = fd;
- d.lock = l;
- d.lock.l_type = F_WRLCK;
- if( pthread_create(&t, 0, threadLockingTest, &d)==0 ){
- pthread_join(t, 0);
- }
- close(fd);
- if( d.result!=0 ) return;
- threadsOverrideEachOthersLocks = (d.lock.l_type==F_UNLCK);
-}
-#endif /* SQLITE_THREADSAFE && defined(__linux__) */
-
-/*
-** Release a unixLockInfo structure previously allocated by findLockInfo().
-**
-** The mutex entered using the unixEnterMutex() function must be held
-** when this function is called.
-*/
-static void releaseLockInfo(struct unixLockInfo *pLock){
- assert( unixMutexHeld() );
- if( pLock ){
- pLock->nRef--;
- if( pLock->nRef==0 ){
- if( pLock->pPrev ){
- assert( pLock->pPrev->pNext==pLock );
- pLock->pPrev->pNext = pLock->pNext;
- }else{
- assert( lockList==pLock );
- lockList = pLock->pNext;
- }
- if( pLock->pNext ){
- assert( pLock->pNext->pPrev==pLock );
- pLock->pNext->pPrev = pLock->pPrev;
- }
- sqlite3_free(pLock);
- }
- }
-}
-
-/*
-** Release a unixOpenCnt structure previously allocated by findLockInfo().
-**
-** The mutex entered using the unixEnterMutex() function must be held
-** when this function is called.
-*/
-static void releaseOpenCnt(struct unixOpenCnt *pOpen){
- assert( unixMutexHeld() );
- if( pOpen ){
- pOpen->nRef--;
- if( pOpen->nRef==0 ){
- if( pOpen->pPrev ){
- assert( pOpen->pPrev->pNext==pOpen );
- pOpen->pPrev->pNext = pOpen->pNext;
- }else{
- assert( openList==pOpen );
- openList = pOpen->pNext;
- }
- if( pOpen->pNext ){
- assert( pOpen->pNext->pPrev==pOpen );
- pOpen->pNext->pPrev = pOpen->pPrev;
- }
-#if SQLITE_THREADSAFE && defined(__linux__)
- assert( !pOpen->pUnused || threadsOverrideEachOthersLocks==0 );
-#endif
-
- /* If pOpen->pUnused is not null, then memory and file-descriptors
- ** are leaked.
- **
- ** This will only happen if, under Linuxthreads, the user has opened
- ** a transaction in one thread, then attempts to close the database
- ** handle from another thread (without first unlocking the db file).
- ** This is a misuse. */
- sqlite3_free(pOpen);
- }
- }
-}
-
-/*
-** Given a file descriptor, locate unixLockInfo and unixOpenCnt structures that
-** describes that file descriptor. Create new ones if necessary. The
-** return values might be uninitialized if an error occurs.
-**
-** The mutex entered using the unixEnterMutex() function must be held
-** when this function is called.
-**
-** Return an appropriate error code.
-*/
-static int findLockInfo(
- unixFile *pFile, /* Unix file with file desc used in the key */
- struct unixLockInfo **ppLock, /* Return the unixLockInfo structure here */
- struct unixOpenCnt **ppOpen /* Return the unixOpenCnt structure here */
-){
- int rc; /* System call return code */
- int fd; /* The file descriptor for pFile */
- struct unixLockKey lockKey; /* Lookup key for the unixLockInfo structure */
- struct unixFileId fileId; /* Lookup key for the unixOpenCnt struct */
- struct stat statbuf; /* Low-level file information */
- struct unixLockInfo *pLock = 0;/* Candidate unixLockInfo object */
- struct unixOpenCnt *pOpen; /* Candidate unixOpenCnt object */
-
- assert( unixMutexHeld() );
-
- /* Get low-level information about the file that we can used to
- ** create a unique name for the file.
- */
- fd = pFile->h;
- rc = fstat(fd, &statbuf);
- if( rc!=0 ){
- pFile->lastErrno = errno;
-#ifdef EOVERFLOW
- if( pFile->lastErrno==EOVERFLOW ) return SQLITE_NOLFS;
-#endif
- return SQLITE_IOERR;
- }
-
-#ifdef __APPLE__
- /* On OS X on an msdos filesystem, the inode number is reported
- ** incorrectly for zero-size files. See ticket #3260. To work
- ** around this problem (we consider it a bug in OS X, not SQLite)
- ** we always increase the file size to 1 by writing a single byte
- ** prior to accessing the inode number. The one byte written is
- ** an ASCII 'S' character which also happens to be the first byte
- ** in the header of every SQLite database. In this way, if there
- ** is a race condition such that another thread has already populated
- ** the first page of the database, no damage is done.
- */
- if( statbuf.st_size==0 ){
- rc = write(fd, "S", 1);
- if( rc!=1 ){
- return SQLITE_IOERR;
- }
- rc = fstat(fd, &statbuf);
- if( rc!=0 ){
- pFile->lastErrno = errno;
- return SQLITE_IOERR;
- }
- }
-#endif
-
- memset(&lockKey, 0, sizeof(lockKey));
- lockKey.fid.dev = statbuf.st_dev;
-#if OS_VXWORKS
- lockKey.fid.pId = pFile->pId;
-#else
- lockKey.fid.ino = statbuf.st_ino;
-#endif
-#if SQLITE_THREADSAFE && defined(__linux__)
- if( threadsOverrideEachOthersLocks<0 ){
- testThreadLockingBehavior(fd);
- }
- lockKey.tid = threadsOverrideEachOthersLocks ? 0 : pthread_self();
-#endif
- fileId = lockKey.fid;
- if( ppLock!=0 ){
- pLock = lockList;
- while( pLock && memcmp(&lockKey, &pLock->lockKey, sizeof(lockKey)) ){
- pLock = pLock->pNext;
- }
- if( pLock==0 ){
- pLock = sqlite3_malloc( sizeof(*pLock) );
- if( pLock==0 ){
- rc = SQLITE_NOMEM;
- goto exit_findlockinfo;
- }
- pLock->lockKey = lockKey;
- pLock->nRef = 1;
- pLock->cnt = 0;
- pLock->locktype = 0;
- pLock->pNext = lockList;
- pLock->pPrev = 0;
- if( lockList ) lockList->pPrev = pLock;
- lockList = pLock;
- }else{
- pLock->nRef++;
- }
- *ppLock = pLock;
- }
- if( ppOpen!=0 ){
- pOpen = openList;
- while( pOpen && memcmp(&fileId, &pOpen->fileId, sizeof(fileId)) ){
- pOpen = pOpen->pNext;
- }
- if( pOpen==0 ){
- pOpen = sqlite3_malloc( sizeof(*pOpen) );
- if( pOpen==0 ){
- releaseLockInfo(pLock);
- rc = SQLITE_NOMEM;
- goto exit_findlockinfo;
- }
- memset(pOpen, 0, sizeof(*pOpen));
- pOpen->fileId = fileId;
- pOpen->nRef = 1;
- pOpen->pNext = openList;
- if( openList ) openList->pPrev = pOpen;
- openList = pOpen;
- }else{
- pOpen->nRef++;
- }
- *ppOpen = pOpen;
- }
-
-exit_findlockinfo:
- return rc;
-}
-
-/*
-** If we are currently in a different thread than the thread that the
-** unixFile argument belongs to, then transfer ownership of the unixFile
-** over to the current thread.
-**
-** A unixFile is only owned by a thread on systems that use LinuxThreads.
-**
-** Ownership transfer is only allowed if the unixFile is currently unlocked.
-** If the unixFile is locked and an ownership is wrong, then return
-** SQLITE_MISUSE. SQLITE_OK is returned if everything works.
-*/
-#if SQLITE_THREADSAFE && defined(__linux__)
-static int transferOwnership(unixFile *pFile){
- int rc;
- pthread_t hSelf;
- if( threadsOverrideEachOthersLocks ){
- /* Ownership transfers not needed on this system */
- return SQLITE_OK;
- }
- hSelf = pthread_self();
- if( pthread_equal(pFile->tid, hSelf) ){
- /* We are still in the same thread */
- OSTRACE1("No-transfer, same thread\n");
- return SQLITE_OK;
- }
- if( pFile->locktype!=NO_LOCK ){
- /* We cannot change ownership while we are holding a lock! */
- return SQLITE_MISUSE;
- }
- OSTRACE4("Transfer ownership of %d from %d to %d\n",
- pFile->h, pFile->tid, hSelf);
- pFile->tid = hSelf;
- if (pFile->pLock != NULL) {
- releaseLockInfo(pFile->pLock);
- rc = findLockInfo(pFile, &pFile->pLock, 0);
- OSTRACE5("LOCK %d is now %s(%s,%d)\n", pFile->h,
- locktypeName(pFile->locktype),
- locktypeName(pFile->pLock->locktype), pFile->pLock->cnt);
- return rc;
- } else {
- return SQLITE_OK;
- }
-}
-#else /* if not SQLITE_THREADSAFE */
- /* On single-threaded builds, ownership transfer is a no-op */
-# define transferOwnership(X) SQLITE_OK
-#endif /* SQLITE_THREADSAFE */
-
-
-/*
-** This routine checks if there is a RESERVED lock held on the specified
-** file by this or any other process. If such a lock is held, set *pResOut
-** to a non-zero value otherwise *pResOut is set to zero. The return value
-** is set to SQLITE_OK unless an I/O error occurs during lock checking.
-*/
-static int unixCheckReservedLock(sqlite3_file *id, int *pResOut){
- int rc = SQLITE_OK;
- int reserved = 0;
- unixFile *pFile = (unixFile*)id;
-
- SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; );
-
- assert( pFile );
- unixEnterMutex(); /* Because pFile->pLock is shared across threads */
-
- /* Check if a thread in this process holds such a lock */
- if( pFile->pLock->locktype>SHARED_LOCK ){
- reserved = 1;
- }
-
- /* Otherwise see if some other process holds it.
- */
-#ifndef __DJGPP__
- if( !reserved ){
- struct flock lock;
- lock.l_whence = SEEK_SET;
- lock.l_start = RESERVED_BYTE;
- lock.l_len = 1;
- lock.l_type = F_WRLCK;
- if (-1 == fcntl(pFile->h, F_GETLK, &lock)) {
- int tErrno = errno;
- rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_CHECKRESERVEDLOCK);
- pFile->lastErrno = tErrno;
- } else if( lock.l_type!=F_UNLCK ){
- reserved = 1;
- }
- }
-#endif
-
- unixLeaveMutex();
- OSTRACE4("TEST WR-LOCK %d %d %d\n", pFile->h, rc, reserved);
-
- *pResOut = reserved;
- return rc;
-}
-
-/*
-** Perform a file locking operation on a range of bytes in a file.
-** The "op" parameter should be one of F_RDLCK, F_WRLCK, or F_UNLCK.
-** Return 0 on success or -1 for failure. On failure, write the error
-** code into *pErrcode.
-**
-** If the SQLITE_WHOLE_FILE_LOCKING bit is clear, then only lock
-** the range of bytes on the locking page between SHARED_FIRST and
-** SHARED_SIZE. If SQLITE_WHOLE_FILE_LOCKING is set, then lock all
-** bytes from 0 up to but not including PENDING_BYTE, and all bytes
-** that follow SHARED_FIRST.
-**
-** In other words, of SQLITE_WHOLE_FILE_LOCKING if false (the historical
-** default case) then only lock a small range of bytes from SHARED_FIRST
-** through SHARED_FIRST+SHARED_SIZE-1. But if SQLITE_WHOLE_FILE_LOCKING is
-** true then lock every byte in the file except for PENDING_BYTE and
-** RESERVED_BYTE.
-**
-** SQLITE_WHOLE_FILE_LOCKING=true overlaps SQLITE_WHOLE_FILE_LOCKING=false
-** and so the locking schemes are compatible. One type of lock will
-** effectively exclude the other type. The reason for using the
-** SQLITE_WHOLE_FILE_LOCKING=true is that by indicating the full range
-** of bytes to be read or written, we give hints to NFS to help it
-** maintain cache coherency. On the other hand, whole file locking
-** is slower, so we don't want to use it except for NFS.
-*/
-static int rangeLock(unixFile *pFile, int op, int *pErrcode){
- struct flock lock;
- int rc;
- lock.l_type = op;
- lock.l_start = SHARED_FIRST;
- lock.l_whence = SEEK_SET;
- if( (pFile->fileFlags & SQLITE_WHOLE_FILE_LOCKING)==0 ){
- lock.l_len = SHARED_SIZE;
- rc = fcntl(pFile->h, F_SETLK, &lock);
- *pErrcode = errno;
- }else{
- lock.l_len = 0;
- rc = fcntl(pFile->h, F_SETLK, &lock);
- *pErrcode = errno;
- if( NEVER(op==F_UNLCK) || rc!=(-1) ){
- lock.l_start = 0;
- lock.l_len = PENDING_BYTE;
- rc = fcntl(pFile->h, F_SETLK, &lock);
- if( ALWAYS(op!=F_UNLCK) && rc==(-1) ){
- *pErrcode = errno;
- lock.l_type = F_UNLCK;
- lock.l_start = SHARED_FIRST;
- lock.l_len = 0;
- fcntl(pFile->h, F_SETLK, &lock);
- }
- }
- }
- return rc;
-}
-
-/*
-** Lock the file with the lock specified by parameter locktype - one
-** of the following:
-**
-** (1) SHARED_LOCK
-** (2) RESERVED_LOCK
-** (3) PENDING_LOCK
-** (4) EXCLUSIVE_LOCK
-**
-** Sometimes when requesting one lock state, additional lock states
-** are inserted in between. The locking might fail on one of the later
-** transitions leaving the lock state different from what it started but
-** still short of its goal. The following chart shows the allowed
-** transitions and the inserted intermediate states:
-**
-** UNLOCKED -> SHARED
-** SHARED -> RESERVED
-** SHARED -> (PENDING) -> EXCLUSIVE
-** RESERVED -> (PENDING) -> EXCLUSIVE
-** PENDING -> EXCLUSIVE
-**
-** This routine will only increase a lock. Use the sqlite3OsUnlock()
-** routine to lower a locking level.
-*/
-static int unixLock(sqlite3_file *id, int locktype){
- /* The following describes the implementation of the various locks and
- ** lock transitions in terms of the POSIX advisory shared and exclusive
- ** lock primitives (called read-locks and write-locks below, to avoid
- ** confusion with SQLite lock names). The algorithms are complicated
- ** slightly in order to be compatible with windows systems simultaneously
- ** accessing the same database file, in case that is ever required.
- **
- ** Symbols defined in os.h indentify the 'pending byte' and the 'reserved
- ** byte', each single bytes at well known offsets, and the 'shared byte
- ** range', a range of 510 bytes at a well known offset.
- **
- ** To obtain a SHARED lock, a read-lock is obtained on the 'pending
- ** byte'. If this is successful, a random byte from the 'shared byte
- ** range' is read-locked and the lock on the 'pending byte' released.
- **
- ** A process may only obtain a RESERVED lock after it has a SHARED lock.
- ** A RESERVED lock is implemented by grabbing a write-lock on the
- ** 'reserved byte'.
- **
- ** A process may only obtain a PENDING lock after it has obtained a
- ** SHARED lock. A PENDING lock is implemented by obtaining a write-lock
- ** on the 'pending byte'. This ensures that no new SHARED locks can be
- ** obtained, but existing SHARED locks are allowed to persist. A process
- ** does not have to obtain a RESERVED lock on the way to a PENDING lock.
- ** This property is used by the algorithm for rolling back a journal file
- ** after a crash.
- **
- ** An EXCLUSIVE lock, obtained after a PENDING lock is held, is
- ** implemented by obtaining a write-lock on the entire 'shared byte
- ** range'. Since all other locks require a read-lock on one of the bytes
- ** within this range, this ensures that no other locks are held on the
- ** database.
- **
- ** The reason a single byte cannot be used instead of the 'shared byte
- ** range' is that some versions of windows do not support read-locks. By
- ** locking a random byte from a range, concurrent SHARED locks may exist
- ** even if the locking primitive used is always a write-lock.
- */
- int rc = SQLITE_OK;
- unixFile *pFile = (unixFile*)id;
- struct unixLockInfo *pLock = pFile->pLock;
- struct flock lock;
- int s = 0;
- int tErrno;
-
- assert( pFile );
- OSTRACE7("LOCK %d %s was %s(%s,%d) pid=%d\n", pFile->h,
- locktypeName(locktype), locktypeName(pFile->locktype),
- locktypeName(pLock->locktype), pLock->cnt , getpid());
-
- /* If there is already a lock of this type or more restrictive on the
- ** unixFile, do nothing. Don't use the end_lock: exit path, as
- ** unixEnterMutex() hasn't been called yet.
- */
- if( pFile->locktype>=locktype ){
- OSTRACE3("LOCK %d %s ok (already held)\n", pFile->h,
- locktypeName(locktype));
- return SQLITE_OK;
- }
-
- /* Make sure the locking sequence is correct.
- ** (1) We never move from unlocked to anything higher than shared lock.
- ** (2) SQLite never explicitly requests a pendig lock.
- ** (3) A shared lock is always held when a reserve lock is requested.
- */
- assert( pFile->locktype!=NO_LOCK || locktype==SHARED_LOCK );
- assert( locktype!=PENDING_LOCK );
- assert( locktype!=RESERVED_LOCK || pFile->locktype==SHARED_LOCK );
-
- /* This mutex is needed because pFile->pLock is shared across threads
- */
- unixEnterMutex();
-
- /* Make sure the current thread owns the pFile.
- */
- rc = transferOwnership(pFile);
- if( rc!=SQLITE_OK ){
- unixLeaveMutex();
- return rc;
- }
- pLock = pFile->pLock;
-
- /* If some thread using this PID has a lock via a different unixFile*
- ** handle that precludes the requested lock, return BUSY.
- */
- if( (pFile->locktype!=pLock->locktype &&
- (pLock->locktype>=PENDING_LOCK || locktype>SHARED_LOCK))
- ){
- rc = SQLITE_BUSY;
- goto end_lock;
- }
-
- /* If a SHARED lock is requested, and some thread using this PID already
- ** has a SHARED or RESERVED lock, then increment reference counts and
- ** return SQLITE_OK.
- */
- if( locktype==SHARED_LOCK &&
- (pLock->locktype==SHARED_LOCK || pLock->locktype==RESERVED_LOCK) ){
- assert( locktype==SHARED_LOCK );
- assert( pFile->locktype==0 );
- assert( pLock->cnt>0 );
- pFile->locktype = SHARED_LOCK;
- pLock->cnt++;
- pFile->pOpen->nLock++;
- goto end_lock;
- }
-
-
- /* A PENDING lock is needed before acquiring a SHARED lock and before
- ** acquiring an EXCLUSIVE lock. For the SHARED lock, the PENDING will
- ** be released.
- */
- lock.l_len = 1L;
- lock.l_whence = SEEK_SET;
- if( locktype==SHARED_LOCK
- || (locktype==EXCLUSIVE_LOCK && pFile->locktype<PENDING_LOCK)
- ){
- lock.l_type = (locktype==SHARED_LOCK?F_RDLCK:F_WRLCK);
- lock.l_start = PENDING_BYTE;
- s = fcntl(pFile->h, F_SETLK, &lock);
- if( s==(-1) ){
- tErrno = errno;
- rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK);
- if( IS_LOCK_ERROR(rc) ){
- pFile->lastErrno = tErrno;
- }
- goto end_lock;
- }
- }
-
-
- /* If control gets to this point, then actually go ahead and make
- ** operating system calls for the specified lock.
- */
- if( locktype==SHARED_LOCK ){
- assert( pLock->cnt==0 );
- assert( pLock->locktype==0 );
-
- /* Now get the read-lock */
- s = rangeLock(pFile, F_RDLCK, &tErrno);
-
- /* Drop the temporary PENDING lock */
- lock.l_start = PENDING_BYTE;
- lock.l_len = 1L;
- lock.l_type = F_UNLCK;
- if( fcntl(pFile->h, F_SETLK, &lock)!=0 ){
- if( s != -1 ){
- /* This could happen with a network mount */
- tErrno = errno;
- rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK);
- if( IS_LOCK_ERROR(rc) ){
- pFile->lastErrno = tErrno;
- }
- goto end_lock;
- }
- }
- if( s==(-1) ){
- rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK);
- if( IS_LOCK_ERROR(rc) ){
- pFile->lastErrno = tErrno;
- }
- }else{
- pFile->locktype = SHARED_LOCK;
- pFile->pOpen->nLock++;
- pLock->cnt = 1;
- }
- }else if( locktype==EXCLUSIVE_LOCK && pLock->cnt>1 ){
- /* We are trying for an exclusive lock but another thread in this
- ** same process is still holding a shared lock. */
- rc = SQLITE_BUSY;
- }else{
- /* The request was for a RESERVED or EXCLUSIVE lock. It is
- ** assumed that there is a SHARED or greater lock on the file
- ** already.
- */
- assert( 0!=pFile->locktype );
- lock.l_type = F_WRLCK;
- switch( locktype ){
- case RESERVED_LOCK:
- lock.l_start = RESERVED_BYTE;
- s = fcntl(pFile->h, F_SETLK, &lock);
- tErrno = errno;
- break;
- case EXCLUSIVE_LOCK:
- s = rangeLock(pFile, F_WRLCK, &tErrno);
- break;
- default:
- assert(0);
- }
- if( s==(-1) ){
- rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK);
- if( IS_LOCK_ERROR(rc) ){
- pFile->lastErrno = tErrno;
- }
- }
- }
-
-
-#ifndef NDEBUG
- /* Set up the transaction-counter change checking flags when
- ** transitioning from a SHARED to a RESERVED lock. The change
- ** from SHARED to RESERVED marks the beginning of a normal
- ** write operation (not a hot journal rollback).
- */
- if( rc==SQLITE_OK
- && pFile->locktype<=SHARED_LOCK
- && locktype==RESERVED_LOCK
- ){
- pFile->transCntrChng = 0;
- pFile->dbUpdate = 0;
- pFile->inNormalWrite = 1;
- }
-#endif
-
-
- if( rc==SQLITE_OK ){
- pFile->locktype = locktype;
- pLock->locktype = locktype;
- }else if( locktype==EXCLUSIVE_LOCK ){
- pFile->locktype = PENDING_LOCK;
- pLock->locktype = PENDING_LOCK;
- }
-
-end_lock:
- unixLeaveMutex();
- OSTRACE4("LOCK %d %s %s\n", pFile->h, locktypeName(locktype),
- rc==SQLITE_OK ? "ok" : "failed");
- return rc;
-}
-
-/*
-** Close all file descriptors accumuated in the unixOpenCnt->pUnused list.
-** If all such file descriptors are closed without error, the list is
-** cleared and SQLITE_OK returned.
-**
-** Otherwise, if an error occurs, then successfully closed file descriptor
-** entries are removed from the list, and SQLITE_IOERR_CLOSE returned.
-** not deleted and SQLITE_IOERR_CLOSE returned.
-*/
-static int closePendingFds(unixFile *pFile){
- int rc = SQLITE_OK;
- struct unixOpenCnt *pOpen = pFile->pOpen;
- UnixUnusedFd *pError = 0;
- UnixUnusedFd *p;
- UnixUnusedFd *pNext;
- for(p=pOpen->pUnused; p; p=pNext){
- pNext = p->pNext;
- if( close(p->fd) ){
- pFile->lastErrno = errno;
- rc = SQLITE_IOERR_CLOSE;
- p->pNext = pError;
- pError = p;
- }else{
- sqlite3_free(p);
- }
- }
- pOpen->pUnused = pError;
- return rc;
-}
-
-/*
-** Add the file descriptor used by file handle pFile to the corresponding
-** pUnused list.
-*/
-static void setPendingFd(unixFile *pFile){
- struct unixOpenCnt *pOpen = pFile->pOpen;
- UnixUnusedFd *p = pFile->pUnused;
- p->pNext = pOpen->pUnused;
- pOpen->pUnused = p;
- pFile->h = -1;
- pFile->pUnused = 0;
-}
-
-/*
-** Lower the locking level on file descriptor pFile to locktype. locktype
-** must be either NO_LOCK or SHARED_LOCK.
-**
-** If the locking level of the file descriptor is already at or below
-** the requested locking level, this routine is a no-op.
-*/
-static int unixUnlock(sqlite3_file *id, int locktype){
- unixFile *pFile = (unixFile*)id; /* The open file */
- struct unixLockInfo *pLock; /* Structure describing current lock state */
- struct flock lock; /* Information passed into fcntl() */
- int rc = SQLITE_OK; /* Return code from this interface */
- int h; /* The underlying file descriptor */
- int tErrno; /* Error code from system call errors */
-
- assert( pFile );
- OSTRACE7("UNLOCK %d %d was %d(%d,%d) pid=%d\n", pFile->h, locktype,
- pFile->locktype, pFile->pLock->locktype, pFile->pLock->cnt, getpid());
-
- assert( locktype<=SHARED_LOCK );
- if( pFile->locktype<=locktype ){
- return SQLITE_OK;
- }
- if( CHECK_THREADID(pFile) ){
- return SQLITE_MISUSE;
- }
- unixEnterMutex();
- h = pFile->h;
- pLock = pFile->pLock;
- assert( pLock->cnt!=0 );
- if( pFile->locktype>SHARED_LOCK ){
- assert( pLock->locktype==pFile->locktype );
- SimulateIOErrorBenign(1);
- SimulateIOError( h=(-1) )
- SimulateIOErrorBenign(0);
-
-#ifndef NDEBUG
- /* When reducing a lock such that other processes can start
- ** reading the database file again, make sure that the
- ** transaction counter was updated if any part of the database
- ** file changed. If the transaction counter is not updated,
- ** other connections to the same file might not realize that
- ** the file has changed and hence might not know to flush their
- ** cache. The use of a stale cache can lead to database corruption.
- */
- assert( pFile->inNormalWrite==0
- || pFile->dbUpdate==0
- || pFile->transCntrChng==1 );
- pFile->inNormalWrite = 0;
-#endif
-
-
- if( locktype==SHARED_LOCK ){
- if( rangeLock(pFile, F_RDLCK, &tErrno)==(-1) ){
- rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_RDLOCK);
- if( IS_LOCK_ERROR(rc) ){
- pFile->lastErrno = tErrno;
- }
- goto end_unlock;
- }
- }
- lock.l_type = F_UNLCK;
- lock.l_whence = SEEK_SET;
- lock.l_start = PENDING_BYTE;
- lock.l_len = 2L; assert( PENDING_BYTE+1==RESERVED_BYTE );
- if( fcntl(h, F_SETLK, &lock)!=(-1) ){
- pLock->locktype = SHARED_LOCK;
- }else{
- tErrno = errno;
- rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK);
- if( IS_LOCK_ERROR(rc) ){
- pFile->lastErrno = tErrno;
- }
- goto end_unlock;
- }
- }
- if( locktype==NO_LOCK ){
- struct unixOpenCnt *pOpen;
-
- /* Decrement the shared lock counter. Release the lock using an
- ** OS call only when all threads in this same process have released
- ** the lock.
- */
- pLock->cnt--;
- if( pLock->cnt==0 ){
- lock.l_type = F_UNLCK;
- lock.l_whence = SEEK_SET;
- lock.l_start = lock.l_len = 0L;
- SimulateIOErrorBenign(1);
- SimulateIOError( h=(-1) )
- SimulateIOErrorBenign(0);
- if( fcntl(h, F_SETLK, &lock)!=(-1) ){
- pLock->locktype = NO_LOCK;
- }else{
- tErrno = errno;
- rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK);
- if( IS_LOCK_ERROR(rc) ){
- pFile->lastErrno = tErrno;
- }
- pLock->locktype = NO_LOCK;
- pFile->locktype = NO_LOCK;
- }
- }
-
- /* Decrement the count of locks against this same file. When the
- ** count reaches zero, close any other file descriptors whose close
- ** was deferred because of outstanding locks.
- */
- pOpen = pFile->pOpen;
- pOpen->nLock--;
- assert( pOpen->nLock>=0 );
- if( pOpen->nLock==0 ){
- int rc2 = closePendingFds(pFile);
- if( rc==SQLITE_OK ){
- rc = rc2;
- }
- }
- }
-
-end_unlock:
- unixLeaveMutex();
- if( rc==SQLITE_OK ) pFile->locktype = locktype;
- return rc;
-}
-
-/*
-** This function performs the parts of the "close file" operation
-** common to all locking schemes. It closes the directory and file
-** handles, if they are valid, and sets all fields of the unixFile
-** structure to 0.
-**
-** It is *not* necessary to hold the mutex when this routine is called,
-** even on VxWorks. A mutex will be acquired on VxWorks by the
-** vxworksReleaseFileId() routine.
-*/
-static int closeUnixFile(sqlite3_file *id){
- unixFile *pFile = (unixFile*)id;
- if( pFile ){
- if( pFile->dirfd>=0 ){
- int err = close(pFile->dirfd);
- if( err ){
- pFile->lastErrno = errno;
- return SQLITE_IOERR_DIR_CLOSE;
- }else{
- pFile->dirfd=-1;
- }
- }
- if( pFile->h>=0 ){
- int err = close(pFile->h);
- if( err ){
- pFile->lastErrno = errno;
- return SQLITE_IOERR_CLOSE;
- }
- }
-#if OS_VXWORKS
- if( pFile->pId ){
- if( pFile->isDelete ){
- unlink(pFile->pId->zCanonicalName);
- }
- vxworksReleaseFileId(pFile->pId);
- pFile->pId = 0;
- }
-#endif
- OSTRACE2("CLOSE %-3d\n", pFile->h);
- OpenCounter(-1);
- sqlite3_free(pFile->pUnused);
- memset(pFile, 0, sizeof(unixFile));
- }
- return SQLITE_OK;
-}
-
-/*
-** Close a file.
-*/
-static int unixClose(sqlite3_file *id){
- int rc = SQLITE_OK;
- if( id ){
- unixFile *pFile = (unixFile *)id;
- unixUnlock(id, NO_LOCK);
- unixEnterMutex();
- if( pFile->pOpen && pFile->pOpen->nLock ){
- /* If there are outstanding locks, do not actually close the file just
- ** yet because that would clear those locks. Instead, add the file
- ** descriptor to pOpen->pUnused list. It will be automatically closed
- ** when the last lock is cleared.
- */
- setPendingFd(pFile);
- }
- releaseLockInfo(pFile->pLock);
- releaseOpenCnt(pFile->pOpen);
- rc = closeUnixFile(id);
- unixLeaveMutex();
- }
- return rc;
-}
-
-/************** End of the posix advisory lock implementation *****************
-******************************************************************************/
-
-/******************************************************************************
-****************************** No-op Locking **********************************
-**
-** Of the various locking implementations available, this is by far the
-** simplest: locking is ignored. No attempt is made to lock the database
-** file for reading or writing.
-**
-** This locking mode is appropriate for use on read-only databases
-** (ex: databases that are burned into CD-ROM, for example.) It can
-** also be used if the application employs some external mechanism to
-** prevent simultaneous access of the same database by two or more
-** database connections. But there is a serious risk of database
-** corruption if this locking mode is used in situations where multiple
-** database connections are accessing the same database file at the same
-** time and one or more of those connections are writing.
-*/
-
-static int nolockCheckReservedLock(sqlite3_file *NotUsed, int *pResOut){
- UNUSED_PARAMETER(NotUsed);
- *pResOut = 0;
- return SQLITE_OK;
-}
-static int nolockLock(sqlite3_file *NotUsed, int NotUsed2){
- UNUSED_PARAMETER2(NotUsed, NotUsed2);
- return SQLITE_OK;
-}
-static int nolockUnlock(sqlite3_file *NotUsed, int NotUsed2){
- UNUSED_PARAMETER2(NotUsed, NotUsed2);
- return SQLITE_OK;
-}
-
-/*
-** Close the file.
-*/
-static int nolockClose(sqlite3_file *id) {
- return closeUnixFile(id);
-}
-
-/******************* End of the no-op lock implementation *********************
-******************************************************************************/
-
-/******************************************************************************
-************************* 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:
-**
-** (1) There is zero concurrency. A single reader blocks all other
-** connections from reading or writing the database.
-**
-** (2) An application crash or power loss can leave stale lock files
-** sitting around that need to be cleared manually.
-**
-** 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.
-*/
-
-/*
-** The file suffix added to the data base filename in order to create the
-** lock file.
-*/
-#define DOTLOCK_SUFFIX ".lock"
-
-/*
-** This routine checks if there is a RESERVED lock held on the specified
-** file by this or any other process. If such a lock is held, set *pResOut
-** to a non-zero value otherwise *pResOut is set to zero. The return value
-** is set to SQLITE_OK unless an I/O error occurs during lock checking.
-**
-** In dotfile locking, either a lock exists or it does not. So in this
-** variation of CheckReservedLock(), *pResOut is set to true if any lock
-** is held on the file and false if the file is unlocked.
-*/
-static int dotlockCheckReservedLock(sqlite3_file *id, int *pResOut) {
- int rc = SQLITE_OK;
- int reserved = 0;
- unixFile *pFile = (unixFile*)id;
-
- SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; );
-
- assert( pFile );
-
- /* Check if a thread in this process holds such a lock */
- if( pFile->locktype>SHARED_LOCK ){
- /* Either this connection or some other connection in the same process
- ** holds a lock on the file. No need to check further. */
- reserved = 1;
- }else{
- /* The lock is held if and only if the lockfile exists */
- const char *zLockFile = (const char*)pFile->lockingContext;
- reserved = access(zLockFile, 0)==0;
- }
- OSTRACE4("TEST WR-LOCK %d %d %d\n", pFile->h, rc, reserved);
- *pResOut = reserved;
- return rc;
-}
-
-/*
-** Lock the file with the lock specified by parameter locktype - one
-** of the following:
-**
-** (1) SHARED_LOCK
-** (2) RESERVED_LOCK
-** (3) PENDING_LOCK
-** (4) EXCLUSIVE_LOCK
-**
-** Sometimes when requesting one lock state, additional lock states
-** are inserted in between. The locking might fail on one of the later
-** transitions leaving the lock state different from what it started but
-** still short of its goal. The following chart shows the allowed
-** transitions and the inserted intermediate states:
-**
-** UNLOCKED -> SHARED
-** SHARED -> RESERVED
-** SHARED -> (PENDING) -> EXCLUSIVE
-** RESERVED -> (PENDING) -> EXCLUSIVE
-** PENDING -> EXCLUSIVE
-**
-** This routine will only increase a lock. Use the sqlite3OsUnlock()
-** routine to lower a locking level.
-**
-** With dotfile locking, we really only support state (4): EXCLUSIVE.
-** But we track the other locking levels internally.
-*/
-static int dotlockLock(sqlite3_file *id, int locktype) {
- unixFile *pFile = (unixFile*)id;
- int fd;
- char *zLockFile = (char *)pFile->lockingContext;
- int rc = SQLITE_OK;
-
-
- /* If we have any lock, then the lock file already exists. All we have
- ** to do is adjust our internal record of the lock level.
- */
- if( pFile->locktype > NO_LOCK ){
- pFile->locktype = locktype;
-#if !OS_VXWORKS
- /* Always update the timestamp on the old file */
- utimes(zLockFile, NULL);
-#endif
- return SQLITE_OK;
- }
-
- /* grab an exclusive lock */
- fd = 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 */
- int tErrno = errno;
- if( EEXIST == tErrno ){
- rc = SQLITE_BUSY;
- } else {
- rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK);
- if( IS_LOCK_ERROR(rc) ){
- pFile->lastErrno = tErrno;
- }
- }
- return rc;
- }
- if( close(fd) ){
- pFile->lastErrno = errno;
- rc = SQLITE_IOERR_CLOSE;
- }
-
- /* got it, set the type and return ok */
- pFile->locktype = locktype;
- return rc;
-}
-
-/*
-** Lower the locking level on file descriptor pFile to locktype. locktype
-** must be either NO_LOCK or SHARED_LOCK.
-**
-** If the locking level of the file descriptor is already at or below
-** the requested locking level, this routine is a no-op.
-**
-** When the locking level reaches NO_LOCK, delete the lock file.
-*/
-static int dotlockUnlock(sqlite3_file *id, int locktype) {
- unixFile *pFile = (unixFile*)id;
- char *zLockFile = (char *)pFile->lockingContext;
-
- assert( pFile );
- OSTRACE5("UNLOCK %d %d was %d pid=%d\n", pFile->h, locktype,
- pFile->locktype, getpid());
- assert( locktype<=SHARED_LOCK );
-
- /* no-op if possible */
- if( pFile->locktype==locktype ){
- return SQLITE_OK;
- }
-
- /* To downgrade to shared, simply update our internal notion of the
- ** lock state. No need to mess with the file on disk.
- */
- if( locktype==SHARED_LOCK ){
- pFile->locktype = SHARED_LOCK;
- return SQLITE_OK;
- }
-
- /* To fully unlock the database, delete the lock file */
- assert( locktype==NO_LOCK );
- if( unlink(zLockFile) ){
- int rc = 0;
- int tErrno = errno;
- if( ENOENT != tErrno ){
- rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK);
- }
- if( IS_LOCK_ERROR(rc) ){
- pFile->lastErrno = tErrno;
- }
- return rc;
- }
- pFile->locktype = NO_LOCK;
- return SQLITE_OK;
-}
-
-/*
-** Close a file. Make sure the lock has been released before closing.
-*/
-static int dotlockClose(sqlite3_file *id) {
- int rc;
- if( id ){
- unixFile *pFile = (unixFile*)id;
- dotlockUnlock(id, NO_LOCK);
- sqlite3_free(pFile->lockingContext);
- }
- rc = closeUnixFile(id);
- return rc;
-}
-/****************** End of the dot-file lock implementation *******************
-******************************************************************************/
-
-/******************************************************************************
-************************** Begin flock Locking ********************************
-**
-** Use the flock() system call to do file locking.
-**
-** flock() locking is like dot-file locking in that the various
-** fine-grain locking levels supported by SQLite are collapsed into
-** a single exclusive lock. In other words, SHARED, RESERVED, and
-** PENDING locks are the same thing as an EXCLUSIVE lock. SQLite
-** still works when you do this, but concurrency is reduced since
-** only a single process can be reading the database at a time.
-**
-** Omit this section if SQLITE_ENABLE_LOCKING_STYLE is turned off or if
-** compiling for VXWORKS.
-*/
-#if SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORKS
-
-/*
-** This routine checks if there is a RESERVED lock held on the specified
-** file by this or any other process. If such a lock is held, set *pResOut
-** to a non-zero value otherwise *pResOut is set to zero. The return value
-** is set to SQLITE_OK unless an I/O error occurs during lock checking.
-*/
-static int flockCheckReservedLock(sqlite3_file *id, int *pResOut){
- int rc = SQLITE_OK;
- int reserved = 0;
- unixFile *pFile = (unixFile*)id;
-
- SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; );
-
- assert( pFile );
-
- /* Check if a thread in this process holds such a lock */
- if( pFile->locktype>SHARED_LOCK ){
- reserved = 1;
- }
-
- /* Otherwise see if some other process holds it. */
- if( !reserved ){
- /* attempt to get the lock */
- int lrc = flock(pFile->h, LOCK_EX | LOCK_NB);
- if( !lrc ){
- /* got the lock, unlock it */
- lrc = flock(pFile->h, LOCK_UN);
- if ( lrc ) {
- int tErrno = errno;
- /* unlock failed with an error */
- lrc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK);
- if( IS_LOCK_ERROR(lrc) ){
- pFile->lastErrno = tErrno;
- rc = lrc;
- }
- }
- } else {
- int tErrno = errno;
- reserved = 1;
- /* someone else might have it reserved */
- lrc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK);
- if( IS_LOCK_ERROR(lrc) ){
- pFile->lastErrno = tErrno;
- rc = lrc;
- }
- }
- }
- OSTRACE4("TEST WR-LOCK %d %d %d\n", pFile->h, rc, reserved);
-
-#ifdef SQLITE_IGNORE_FLOCK_LOCK_ERRORS
- if( (rc & SQLITE_IOERR) == SQLITE_IOERR ){
- rc = SQLITE_OK;
- reserved=1;
- }
-#endif /* SQLITE_IGNORE_FLOCK_LOCK_ERRORS */
- *pResOut = reserved;
- return rc;
-}
-
-/*
-** Lock the file with the lock specified by parameter locktype - one
-** of the following:
-**
-** (1) SHARED_LOCK
-** (2) RESERVED_LOCK
-** (3) PENDING_LOCK
-** (4) EXCLUSIVE_LOCK
-**
-** Sometimes when requesting one lock state, additional lock states
-** are inserted in between. The locking might fail on one of the later
-** transitions leaving the lock state different from what it started but
-** still short of its goal. The following chart shows the allowed
-** transitions and the inserted intermediate states:
-**
-** UNLOCKED -> SHARED
-** SHARED -> RESERVED
-** SHARED -> (PENDING) -> EXCLUSIVE
-** RESERVED -> (PENDING) -> EXCLUSIVE
-** PENDING -> EXCLUSIVE
-**
-** flock() only really support EXCLUSIVE locks. We track intermediate
-** lock states in the sqlite3_file structure, but all locks SHARED or
-** above are really EXCLUSIVE locks and exclude all other processes from
-** access the file.
-**
-** This routine will only increase a lock. Use the sqlite3OsUnlock()
-** routine to lower a locking level.
-*/
-static int flockLock(sqlite3_file *id, int locktype) {
- int rc = SQLITE_OK;
- unixFile *pFile = (unixFile*)id;
-
- assert( pFile );
-
- /* if we already have a lock, it is exclusive.
- ** Just adjust level and punt on outta here. */
- if (pFile->locktype > NO_LOCK) {
- pFile->locktype = locktype;
- return SQLITE_OK;
- }
-
- /* grab an exclusive lock */
-
- if (flock(pFile->h, LOCK_EX | LOCK_NB)) {
- int tErrno = errno;
- /* didn't get, must be busy */
- rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK);
- if( IS_LOCK_ERROR(rc) ){
- pFile->lastErrno = tErrno;
- }
- } else {
- /* got it, set the type and return ok */
- pFile->locktype = locktype;
- }
- OSTRACE4("LOCK %d %s %s\n", pFile->h, locktypeName(locktype),
- rc==SQLITE_OK ? "ok" : "failed");
-#ifdef SQLITE_IGNORE_FLOCK_LOCK_ERRORS
- if( (rc & SQLITE_IOERR) == SQLITE_IOERR ){
- rc = SQLITE_BUSY;
- }
-#endif /* SQLITE_IGNORE_FLOCK_LOCK_ERRORS */
- return rc;
-}
-
-
-/*
-** Lower the locking level on file descriptor pFile to locktype. locktype
-** must be either NO_LOCK or SHARED_LOCK.
-**
-** If the locking level of the file descriptor is already at or below
-** the requested locking level, this routine is a no-op.
-*/
-static int flockUnlock(sqlite3_file *id, int locktype) {
- unixFile *pFile = (unixFile*)id;
-
- assert( pFile );
- OSTRACE5("UNLOCK %d %d was %d pid=%d\n", pFile->h, locktype,
- pFile->locktype, getpid());
- assert( locktype<=SHARED_LOCK );
-
- /* no-op if possible */
- if( pFile->locktype==locktype ){
- return SQLITE_OK;
- }
-
- /* shared can just be set because we always have an exclusive */
- if (locktype==SHARED_LOCK) {
- pFile->locktype = locktype;
- return SQLITE_OK;
- }
-
- /* no, really, unlock. */
- int rc = flock(pFile->h, LOCK_UN);
- if (rc) {
- int r, tErrno = errno;
- r = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK);
- if( IS_LOCK_ERROR(r) ){
- pFile->lastErrno = tErrno;
- }
-#ifdef SQLITE_IGNORE_FLOCK_LOCK_ERRORS
- if( (r & SQLITE_IOERR) == SQLITE_IOERR ){
- r = SQLITE_BUSY;
- }
-#endif /* SQLITE_IGNORE_FLOCK_LOCK_ERRORS */
-
- return r;
- } else {
- pFile->locktype = NO_LOCK;
- return SQLITE_OK;
- }
-}
-
-/*
-** Close a file.
-*/
-static int flockClose(sqlite3_file *id) {
- if( id ){
- flockUnlock(id, NO_LOCK);
- }
- return closeUnixFile(id);
-}
-
-#endif /* SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORK */
-
-/******************* End of the flock lock implementation *********************
-******************************************************************************/
-
-/******************************************************************************
-************************ Begin Named Semaphore Locking ************************
-**
-** Named semaphore locking is only supported on VxWorks.
-**
-** Semaphore locking is like dot-lock and flock in that it really only
-** supports EXCLUSIVE locking. Only a single process can read or write
-** the database file at a time. This reduces potential concurrency, but
-** makes the lock implementation much easier.
-*/
-#if OS_VXWORKS
-
-/*
-** This routine checks if there is a RESERVED lock held on the specified
-** file by this or any other process. If such a lock is held, set *pResOut
-** to a non-zero value otherwise *pResOut is set to zero. The return value
-** is set to SQLITE_OK unless an I/O error occurs during lock checking.
-*/
-static int semCheckReservedLock(sqlite3_file *id, int *pResOut) {
- int rc = SQLITE_OK;
- int reserved = 0;
- unixFile *pFile = (unixFile*)id;
-
- SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; );
-
- assert( pFile );
-
- /* Check if a thread in this process holds such a lock */
- if( pFile->locktype>SHARED_LOCK ){
- reserved = 1;
- }
-
- /* Otherwise see if some other process holds it. */
- if( !reserved ){
- sem_t *pSem = pFile->pOpen->pSem;
- struct stat statBuf;
-
- if( sem_trywait(pSem)==-1 ){
- int tErrno = errno;
- if( EAGAIN != tErrno ){
- rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_CHECKRESERVEDLOCK);
- pFile->lastErrno = tErrno;
- } else {
- /* someone else has the lock when we are in NO_LOCK */
- reserved = (pFile->locktype < SHARED_LOCK);
- }
- }else{
- /* we could have it if we want it */
- sem_post(pSem);
- }
- }
- OSTRACE4("TEST WR-LOCK %d %d %d\n", pFile->h, rc, reserved);
-
- *pResOut = reserved;
- return rc;
-}
-
-/*
-** Lock the file with the lock specified by parameter locktype - one
-** of the following:
-**
-** (1) SHARED_LOCK
-** (2) RESERVED_LOCK
-** (3) PENDING_LOCK
-** (4) EXCLUSIVE_LOCK
-**
-** Sometimes when requesting one lock state, additional lock states
-** are inserted in between. The locking might fail on one of the later
-** transitions leaving the lock state different from what it started but
-** still short of its goal. The following chart shows the allowed
-** transitions and the inserted intermediate states:
-**
-** UNLOCKED -> SHARED
-** SHARED -> RESERVED
-** SHARED -> (PENDING) -> EXCLUSIVE
-** RESERVED -> (PENDING) -> EXCLUSIVE
-** PENDING -> EXCLUSIVE
-**
-** Semaphore locks only really support EXCLUSIVE locks. We track intermediate
-** lock states in the sqlite3_file structure, but all locks SHARED or
-** above are really EXCLUSIVE locks and exclude all other processes from
-** access the file.
-**
-** This routine will only increase a lock. Use the sqlite3OsUnlock()
-** routine to lower a locking level.
-*/
-static int semLock(sqlite3_file *id, int locktype) {
- unixFile *pFile = (unixFile*)id;
- int fd;
- sem_t *pSem = pFile->pOpen->pSem;
- int rc = SQLITE_OK;
-
- /* if we already have a lock, it is exclusive.
- ** Just adjust level and punt on outta here. */
- if (pFile->locktype > NO_LOCK) {
- pFile->locktype = locktype;
- rc = SQLITE_OK;
- goto sem_end_lock;
- }
-
- /* lock semaphore now but bail out when already locked. */
- if( sem_trywait(pSem)==-1 ){
- rc = SQLITE_BUSY;
- goto sem_end_lock;
- }
-
- /* got it, set the type and return ok */
- pFile->locktype = locktype;
-
- sem_end_lock:
- return rc;
-}
-
-/*
-** Lower the locking level on file descriptor pFile to locktype. locktype
-** must be either NO_LOCK or SHARED_LOCK.
-**
-** If the locking level of the file descriptor is already at or below
-** the requested locking level, this routine is a no-op.
-*/
-static int semUnlock(sqlite3_file *id, int locktype) {
- unixFile *pFile = (unixFile*)id;
- sem_t *pSem = pFile->pOpen->pSem;
-
- assert( pFile );
- assert( pSem );
- OSTRACE5("UNLOCK %d %d was %d pid=%d\n", pFile->h, locktype,
- pFile->locktype, getpid());
- assert( locktype<=SHARED_LOCK );
-
- /* no-op if possible */
- if( pFile->locktype==locktype ){
- return SQLITE_OK;
- }
-
- /* shared can just be set because we always have an exclusive */
- if (locktype==SHARED_LOCK) {
- pFile->locktype = locktype;
- return SQLITE_OK;
- }
-
- /* no, really unlock. */
- if ( sem_post(pSem)==-1 ) {
- int rc, tErrno = errno;
- rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK);
- if( IS_LOCK_ERROR(rc) ){
- pFile->lastErrno = tErrno;
- }
- return rc;
- }
- pFile->locktype = NO_LOCK;
- return SQLITE_OK;
-}
-
-/*
- ** Close a file.
- */
-static int semClose(sqlite3_file *id) {
- if( id ){
- unixFile *pFile = (unixFile*)id;
- semUnlock(id, NO_LOCK);
- assert( pFile );
- unixEnterMutex();
- releaseLockInfo(pFile->pLock);
- releaseOpenCnt(pFile->pOpen);
- unixLeaveMutex();
- closeUnixFile(id);
- }
- return SQLITE_OK;
-}
-
-#endif /* OS_VXWORKS */
-/*
-** Named semaphore locking is only available on VxWorks.
-**
-*************** End of the named semaphore lock implementation ****************
-******************************************************************************/
-
-
-/******************************************************************************
-*************************** Begin AFP Locking *********************************
-**
-** AFP is the Apple Filing Protocol. AFP is a network filesystem found
-** on Apple Macintosh computers - both OS9 and OSX.
-**
-** Third-party implementations of AFP are available. But this code here
-** only works on OSX.
-*/
-
-#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE
-/*
-** The afpLockingContext structure contains all afp lock specific state
-*/
-typedef struct afpLockingContext afpLockingContext;
-struct afpLockingContext {
- unsigned long long sharedByte;
- const char *dbPath; /* Name of the open file */
-};
-
-struct ByteRangeLockPB2
-{
- unsigned long long offset; /* offset to first byte to lock */
- unsigned long long length; /* nbr of bytes to lock */
- unsigned long long retRangeStart; /* nbr of 1st byte locked if successful */
- unsigned char unLockFlag; /* 1 = unlock, 0 = lock */
- unsigned char startEndFlag; /* 1=rel to end of fork, 0=rel to start */
- int fd; /* file desc to assoc this lock with */
-};
-
-#define afpfsByteRangeLock2FSCTL _IOWR('z', 23, struct ByteRangeLockPB2)
-
-/*
-** This is a utility for setting or clearing a bit-range lock on an
-** AFP filesystem.
-**
-** Return SQLITE_OK on success, SQLITE_BUSY on failure.
-*/
-static int afpSetLock(
- const char *path, /* Name of the file to be locked or unlocked */
- unixFile *pFile, /* Open file descriptor on path */
- unsigned long long offset, /* First byte to be locked */
- unsigned long long length, /* Number of bytes to lock */
- int setLockFlag /* True to set lock. False to clear lock */
-){
- struct ByteRangeLockPB2 pb;
- int err;
-
- pb.unLockFlag = setLockFlag ? 0 : 1;
- pb.startEndFlag = 0;
- pb.offset = offset;
- pb.length = length;
- pb.fd = pFile->h;
-
- OSTRACE6("AFPSETLOCK [%s] for %d%s in range %llx:%llx\n",
- (setLockFlag?"ON":"OFF"), pFile->h, (pb.fd==-1?"[testval-1]":""),
- offset, length);
- err = fsctl(path, afpfsByteRangeLock2FSCTL, &pb, 0);
- if ( err==-1 ) {
- int rc;
- int tErrno = errno;
- OSTRACE4("AFPSETLOCK failed to fsctl() '%s' %d %s\n",
- path, tErrno, strerror(tErrno));
-#ifdef SQLITE_IGNORE_AFP_LOCK_ERRORS
- rc = SQLITE_BUSY;
-#else
- rc = sqliteErrorFromPosixError(tErrno,
- setLockFlag ? SQLITE_IOERR_LOCK : SQLITE_IOERR_UNLOCK);
-#endif /* SQLITE_IGNORE_AFP_LOCK_ERRORS */
- if( IS_LOCK_ERROR(rc) ){
- pFile->lastErrno = tErrno;
- }
- return rc;
- } else {
- return SQLITE_OK;
- }
-}
-
-/*
-** This routine checks if there is a RESERVED lock held on the specified
-** file by this or any other process. If such a lock is held, set *pResOut
-** to a non-zero value otherwise *pResOut is set to zero. The return value
-** is set to SQLITE_OK unless an I/O error occurs during lock checking.
-*/
-static int afpCheckReservedLock(sqlite3_file *id, int *pResOut){
- int rc = SQLITE_OK;
- int reserved = 0;
- unixFile *pFile = (unixFile*)id;
-
- SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; );
-
- assert( pFile );
- afpLockingContext *context = (afpLockingContext *) pFile->lockingContext;
-
- /* Check if a thread in this process holds such a lock */
- if( pFile->locktype>SHARED_LOCK ){
- reserved = 1;
- }
-
- /* Otherwise see if some other process holds it.
- */
- if( !reserved ){
- /* lock the RESERVED byte */
- int lrc = afpSetLock(context->dbPath, pFile, RESERVED_BYTE, 1,1);
- if( SQLITE_OK==lrc ){
- /* if we succeeded in taking the reserved lock, unlock it to restore
- ** the original state */
- lrc = afpSetLock(context->dbPath, pFile, RESERVED_BYTE, 1, 0);
- } else {
- /* if we failed to get the lock then someone else must have it */
- reserved = 1;
- }
- if( IS_LOCK_ERROR(lrc) ){
- rc=lrc;
- }
- }
-
- OSTRACE4("TEST WR-LOCK %d %d %d\n", pFile->h, rc, reserved);
-
- *pResOut = reserved;
- return rc;
-}
-
-/*
-** Lock the file with the lock specified by parameter locktype - one
-** of the following:
-**
-** (1) SHARED_LOCK
-** (2) RESERVED_LOCK
-** (3) PENDING_LOCK
-** (4) EXCLUSIVE_LOCK
-**
-** Sometimes when requesting one lock state, additional lock states
-** are inserted in between. The locking might fail on one of the later
-** transitions leaving the lock state different from what it started but
-** still short of its goal. The following chart shows the allowed
-** transitions and the inserted intermediate states:
-**
-** UNLOCKED -> SHARED
-** SHARED -> RESERVED
-** SHARED -> (PENDING) -> EXCLUSIVE
-** RESERVED -> (PENDING) -> EXCLUSIVE
-** PENDING -> EXCLUSIVE
-**
-** This routine will only increase a lock. Use the sqlite3OsUnlock()
-** routine to lower a locking level.
-*/
-static int afpLock(sqlite3_file *id, int locktype){
- int rc = SQLITE_OK;
- unixFile *pFile = (unixFile*)id;
- afpLockingContext *context = (afpLockingContext *) pFile->lockingContext;
-
- assert( pFile );
- OSTRACE5("LOCK %d %s was %s pid=%d\n", pFile->h,
- locktypeName(locktype), locktypeName(pFile->locktype), getpid());
-
- /* If there is already a lock of this type or more restrictive on the
- ** unixFile, do nothing. Don't use the afp_end_lock: exit path, as
- ** unixEnterMutex() hasn't been called yet.
- */
- if( pFile->locktype>=locktype ){
- OSTRACE3("LOCK %d %s ok (already held)\n", pFile->h,
- locktypeName(locktype));
- return SQLITE_OK;
- }
-
- /* Make sure the locking sequence is correct
- */
- assert( pFile->locktype!=NO_LOCK || locktype==SHARED_LOCK );
- assert( locktype!=PENDING_LOCK );
- assert( locktype!=RESERVED_LOCK || pFile->locktype==SHARED_LOCK );
-
- /* This mutex is needed because pFile->pLock is shared across threads
- */
- unixEnterMutex();
-
- /* Make sure the current thread owns the pFile.
- */
- rc = transferOwnership(pFile);
- if( rc!=SQLITE_OK ){
- unixLeaveMutex();
- return rc;
- }
-
- /* A PENDING lock is needed before acquiring a SHARED lock and before
- ** acquiring an EXCLUSIVE lock. For the SHARED lock, the PENDING will
- ** be released.
- */
- if( locktype==SHARED_LOCK
- || (locktype==EXCLUSIVE_LOCK && pFile->locktype<PENDING_LOCK)
- ){
- int failed;
- failed = afpSetLock(context->dbPath, pFile, PENDING_BYTE, 1, 1);
- if (failed) {
- rc = failed;
- goto afp_end_lock;
- }
- }
-
- /* If control gets to this point, then actually go ahead and make
- ** operating system calls for the specified lock.
- */
- if( locktype==SHARED_LOCK ){
- int lk, lrc1, lrc2, lrc1Errno;
-
- /* Now get the read-lock SHARED_LOCK */
- /* note that the quality of the randomness doesn't matter that much */
- lk = random();
- context->sharedByte = (lk & 0x7fffffff)%(SHARED_SIZE - 1);
- lrc1 = afpSetLock(context->dbPath, pFile,
- SHARED_FIRST+context->sharedByte, 1, 1);
- if( IS_LOCK_ERROR(lrc1) ){
- lrc1Errno = pFile->lastErrno;
- }
- /* Drop the temporary PENDING lock */
- lrc2 = afpSetLock(context->dbPath, pFile, PENDING_BYTE, 1, 0);
-
- if( IS_LOCK_ERROR(lrc1) ) {
- pFile->lastErrno = lrc1Errno;
- rc = lrc1;
- goto afp_end_lock;
- } else if( IS_LOCK_ERROR(lrc2) ){
- rc = lrc2;
- goto afp_end_lock;
- } else if( lrc1 != SQLITE_OK ) {
- rc = lrc1;
- } else {
- pFile->locktype = SHARED_LOCK;
- pFile->pOpen->nLock++;
- }
- }else{
- /* The request was for a RESERVED or EXCLUSIVE lock. It is
- ** assumed that there is a SHARED or greater lock on the file
- ** already.
- */
- int failed = 0;
- assert( 0!=pFile->locktype );
- if (locktype >= RESERVED_LOCK && pFile->locktype < RESERVED_LOCK) {
- /* Acquire a RESERVED lock */
- failed = afpSetLock(context->dbPath, pFile, RESERVED_BYTE, 1,1);
- }
- if (!failed && locktype == EXCLUSIVE_LOCK) {
- /* Acquire an EXCLUSIVE lock */
-
- /* Remove the shared lock before trying the range. we'll need to
- ** reestablish the shared lock if we can't get the afpUnlock
- */
- if( !(failed = afpSetLock(context->dbPath, pFile, SHARED_FIRST +
- context->sharedByte, 1, 0)) ){
- int failed2 = SQLITE_OK;
- /* now attemmpt to get the exclusive lock range */
- failed = afpSetLock(context->dbPath, pFile, SHARED_FIRST,
- SHARED_SIZE, 1);
- if( failed && (failed2 = afpSetLock(context->dbPath, pFile,
- SHARED_FIRST + context->sharedByte, 1, 1)) ){
- /* Can't reestablish the shared lock. Sqlite can't deal, this is
- ** a critical I/O error
- */
- rc = ((failed & SQLITE_IOERR) == SQLITE_IOERR) ? failed2 :
- SQLITE_IOERR_LOCK;
- goto afp_end_lock;
- }
- }else{
- rc = failed;
- }
- }
- if( failed ){
- rc = failed;
- }
- }
-
- if( rc==SQLITE_OK ){
- pFile->locktype = locktype;
- }else if( locktype==EXCLUSIVE_LOCK ){
- pFile->locktype = PENDING_LOCK;
- }
-
-afp_end_lock:
- unixLeaveMutex();
- OSTRACE4("LOCK %d %s %s\n", pFile->h, locktypeName(locktype),
- rc==SQLITE_OK ? "ok" : "failed");
- return rc;
-}
-
-/*
-** Lower the locking level on file descriptor pFile to locktype. locktype
-** must be either NO_LOCK or SHARED_LOCK.
-**
-** If the locking level of the file descriptor is already at or below
-** the requested locking level, this routine is a no-op.
-*/
-static int afpUnlock(sqlite3_file *id, int locktype) {
- int rc = SQLITE_OK;
- unixFile *pFile = (unixFile*)id;
- afpLockingContext *pCtx = (afpLockingContext *) pFile->lockingContext;
-
- assert( pFile );
- OSTRACE5("UNLOCK %d %d was %d pid=%d\n", pFile->h, locktype,
- pFile->locktype, getpid());
-
- assert( locktype<=SHARED_LOCK );
- if( pFile->locktype<=locktype ){
- return SQLITE_OK;
- }
- if( CHECK_THREADID(pFile) ){
- return SQLITE_MISUSE;
- }
- unixEnterMutex();
- if( pFile->locktype>SHARED_LOCK ){
-
- if( pFile->locktype==EXCLUSIVE_LOCK ){
- rc = afpSetLock(pCtx->dbPath, pFile, SHARED_FIRST, SHARED_SIZE, 0);
- if( rc==SQLITE_OK && locktype==SHARED_LOCK ){
- /* only re-establish the shared lock if necessary */
- int sharedLockByte = SHARED_FIRST+pCtx->sharedByte;
- rc = afpSetLock(pCtx->dbPath, pFile, sharedLockByte, 1, 1);
- }
- }
- if( rc==SQLITE_OK && pFile->locktype>=PENDING_LOCK ){
- rc = afpSetLock(pCtx->dbPath, pFile, PENDING_BYTE, 1, 0);
- }
- if( rc==SQLITE_OK && pFile->locktype>=RESERVED_LOCK ){
- rc = afpSetLock(pCtx->dbPath, pFile, RESERVED_BYTE, 1, 0);
- }
- }else if( locktype==NO_LOCK ){
- /* clear the shared lock */
- int sharedLockByte = SHARED_FIRST+pCtx->sharedByte;
- rc = afpSetLock(pCtx->dbPath, pFile, sharedLockByte, 1, 0);
- }
-
- if( rc==SQLITE_OK ){
- if( locktype==NO_LOCK ){
- struct unixOpenCnt *pOpen = pFile->pOpen;
- pOpen->nLock--;
- assert( pOpen->nLock>=0 );
- if( pOpen->nLock==0 ){
- rc = closePendingFds(pFile);
- }
- }
- }
- unixLeaveMutex();
- if( rc==SQLITE_OK ){
- pFile->locktype = locktype;
- }
- return rc;
-}
-
-/*
-** Close a file & cleanup AFP specific locking context
-*/
-static int afpClose(sqlite3_file *id) {
- if( id ){
- unixFile *pFile = (unixFile*)id;
- afpUnlock(id, NO_LOCK);
- unixEnterMutex();
- if( pFile->pOpen && pFile->pOpen->nLock ){
- /* If there are outstanding locks, do not actually close the file just
- ** yet because that would clear those locks. Instead, add the file
- ** descriptor to pOpen->aPending. It will be automatically closed when
- ** the last lock is cleared.
- */
- setPendingFd(pFile);
- }
- releaseOpenCnt(pFile->pOpen);
- sqlite3_free(pFile->lockingContext);
- closeUnixFile(id);
- unixLeaveMutex();
- }
- return SQLITE_OK;
-}
-
-#endif /* defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE */
-/*
-** The code above is the AFP lock implementation. The code is specific
-** to MacOSX and does not work on other unix platforms. No alternative
-** is available. If you don't compile for a mac, then the "unix-afp"
-** VFS is not available.
-**
-********************* End of the AFP lock implementation **********************
-******************************************************************************/
-
-
-/******************************************************************************
-**************** Non-locking sqlite3_file methods *****************************
-**
-** The next division contains implementations for all methods of the
-** sqlite3_file object other than the locking methods. The locking
-** methods were defined in divisions above (one locking method per
-** division). Those methods that are common to all locking modes
-** are gather together into this division.
-*/
-
-/*
-** Seek to the offset passed as the second argument, then read cnt
-** bytes into pBuf. Return the number of bytes actually read.
-**
-** NB: If you define USE_PREAD or USE_PREAD64, then it might also
-** be necessary to define _XOPEN_SOURCE to be 500. This varies from
-** one system to another. Since SQLite does not define USE_PREAD
-** any any form by default, we will not attempt to define _XOPEN_SOURCE.
-** See tickets #2741 and #2681.
-**
-** To avoid stomping the errno value on a failed read the lastErrno value
-** is set before returning.
-*/
-static int seekAndRead(unixFile *id, sqlite3_int64 offset, void *pBuf, int cnt){
- int got;
- i64 newOffset;
- TIMER_START;
-#if defined(USE_PREAD)
- got = pread(id->h, pBuf, cnt, offset);
- SimulateIOError( got = -1 );
-#elif defined(USE_PREAD64)
- got = pread64(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;
- }
- return -1;
- }
- got = read(id->h, pBuf, cnt);
-#endif
- TIMER_END;
- if( got<0 ){
- ((unixFile*)id)->lastErrno = errno;
- }
- OSTRACE5("READ %-3d %5d %7lld %llu\n", id->h, got, offset, TIMER_ELAPSED);
- return got;
-}
-
-/*
-** Read data from a file into a buffer. Return SQLITE_OK if all
-** bytes were read successfully and SQLITE_IOERR if anything goes
-** wrong.
-*/
-static int unixRead(
- sqlite3_file *id,
- void *pBuf,
- int amt,
- sqlite3_int64 offset
-){
- unixFile *pFile = (unixFile *)id;
- int got;
- assert( id );
-
- /* If this is a database file (not a journal, master-journal or temp
- ** file), the bytes in the locking range should never be read or written. */
- assert( pFile->pUnused==0
- || offset>=PENDING_BYTE+512
- || offset+amt<=PENDING_BYTE
- );
-
- got = seekAndRead(pFile, offset, pBuf, amt);
- if( got==amt ){
- return SQLITE_OK;
- }else if( got<0 ){
- /* lastErrno set by seekAndRead */
- return SQLITE_IOERR_READ;
- }else{
- pFile->lastErrno = 0; /* not a system error */
- /* Unread parts of the buffer must be zero-filled */
- memset(&((char*)pBuf)[got], 0, amt-got);
- return SQLITE_IOERR_SHORT_READ;
- }
-}
-
-/*
-** Seek to the offset in id->offset then read cnt bytes into pBuf.
-** Return the number of bytes actually read. Update the offset.
-**
-** To avoid stomping the errno value on a failed write the lastErrno value
-** is set before returning.
-*/
-static int seekAndWrite(unixFile *id, i64 offset, const void *pBuf, int cnt){
- int got;
- i64 newOffset;
- TIMER_START;
-#if defined(USE_PREAD)
- got = pwrite(id->h, pBuf, cnt, offset);
-#elif defined(USE_PREAD64)
- got = pwrite64(id->h, pBuf, cnt, offset);
-#else
- newOffset = lseek(id->h, offset, SEEK_SET);
- if( newOffset!=offset ){
- if( newOffset == -1 ){
- ((unixFile*)id)->lastErrno = errno;
- }else{
- ((unixFile*)id)->lastErrno = 0;
- }
- return -1;
- }
- got = write(id->h, pBuf, cnt);
-#endif
- TIMER_END;
- if( got<0 ){
- ((unixFile*)id)->lastErrno = errno;
- }
-
- OSTRACE5("WRITE %-3d %5d %7lld %llu\n", id->h, got, offset, TIMER_ELAPSED);
- return got;
-}
-
-
-/*
-** Write data from a buffer into a file. Return SQLITE_OK on success
-** or some other error code on failure.
-*/
-static int unixWrite(
- sqlite3_file *id,
- const void *pBuf,
- int amt,
- sqlite3_int64 offset
-){
- unixFile *pFile = (unixFile*)id;
- int wrote = 0;
- assert( id );
- assert( amt>0 );
-
- /* If this is a database file (not a journal, master-journal or temp
- ** file), the bytes in the locking range should never be read or written. */
- assert( pFile->pUnused==0
- || offset>=PENDING_BYTE+512
- || offset+amt<=PENDING_BYTE
- );
-
-#ifndef NDEBUG
- /* If we are doing a normal write to a database file (as opposed to
- ** doing a hot-journal rollback or a write to some file other than a
- ** normal database file) then record the fact that the database
- ** has changed. If the transaction counter is modified, record that
- ** fact too.
- */
- if( pFile->inNormalWrite ){
- pFile->dbUpdate = 1; /* The database has been modified */
- if( offset<=24 && offset+amt>=27 ){
- int rc;
- char oldCntr[4];
- SimulateIOErrorBenign(1);
- rc = seekAndRead(pFile, 24, oldCntr, 4);
- SimulateIOErrorBenign(0);
- if( rc!=4 || memcmp(oldCntr, &((char*)pBuf)[24-offset], 4)!=0 ){
- pFile->transCntrChng = 1; /* The transaction counter has changed */
- }
- }
- }
-#endif
-
- while( amt>0 && (wrote = seekAndWrite(pFile, offset, pBuf, amt))>0 ){
- amt -= wrote;
- offset += wrote;
- pBuf = &((char*)pBuf)[wrote];
- }
- SimulateIOError(( wrote=(-1), amt=1 ));
- SimulateDiskfullError(( wrote=0, amt=1 ));
- if( amt>0 ){
- if( wrote<0 ){
- /* lastErrno set by seekAndWrite */
- return SQLITE_IOERR_WRITE;
- }else{
- pFile->lastErrno = 0; /* not a system error */
- return SQLITE_FULL;
- }
- }
- return SQLITE_OK;
-}
-
-#ifdef SQLITE_TEST
-/*
-** Count the number of fullsyncs and normal syncs. This is used to test
-** that syncs and fullsyncs are occurring at the right times.
-*/
-SQLITE_API int sqlite3_sync_count = 0;
-SQLITE_API int sqlite3_fullsync_count = 0;
-#endif
-
-/*
-** We do not trust systems to provide a working fdatasync(). Some do.
-** Others do no. To be safe, we will stick with the (slower) fsync().
-** If you know that your system does support fdatasync() correctly,
-** then simply compile with -Dfdatasync=fdatasync
-*/
-#if !defined(fdatasync) && !defined(__linux__)
-# define fdatasync fsync
-#endif
-
-/*
-** Define HAVE_FULLFSYNC to 0 or 1 depending on whether or not
-** the F_FULLFSYNC macro is defined. F_FULLFSYNC is currently
-** only available on Mac OS X. But that could change.
-*/
-#ifdef F_FULLFSYNC
-# define HAVE_FULLFSYNC 1
-#else
-# define HAVE_FULLFSYNC 0
-#endif
-
-
-/*
-** The fsync() system call does not work as advertised on many
-** unix systems. The following procedure is an attempt to make
-** it work better.
-**
-** The SQLITE_NO_SYNC macro disables all fsync()s. This is useful
-** for testing when we want to run through the test suite quickly.
-** You are strongly advised *not* to deploy with SQLITE_NO_SYNC
-** enabled, however, since with SQLITE_NO_SYNC enabled, an OS crash
-** or power failure will likely corrupt the database file.
-**
-** SQLite sets the dataOnly flag if the size of the file is unchanged.
-** The idea behind dataOnly is that it should only write the file content
-** to disk, not the inode. We only set dataOnly if the file size is
-** unchanged since the file size is part of the inode. However,
-** Ted Ts'o tells us that fdatasync() will also write the inode if the
-** file size has changed. The only real difference between fdatasync()
-** and fsync(), Ted tells us, is that fdatasync() will not flush the
-** inode if the mtime or owner or other inode attributes have changed.
-** We only care about the file size, not the other file attributes, so
-** as far as SQLite is concerned, an fdatasync() is always adequate.
-** So, we always use fdatasync() if it is available, regardless of
-** the value of the dataOnly flag.
-*/
-static int full_fsync(int fd, int fullSync, int dataOnly){
- int rc;
-
- /* The following "ifdef/elif/else/" block has the same structure as
- ** the one below. It is replicated here solely to avoid cluttering
- ** up the real code with the UNUSED_PARAMETER() macros.
- */
-#ifdef SQLITE_NO_SYNC
- UNUSED_PARAMETER(fd);
- UNUSED_PARAMETER(fullSync);
- UNUSED_PARAMETER(dataOnly);
-#elif HAVE_FULLFSYNC
- UNUSED_PARAMETER(dataOnly);
-#else
- UNUSED_PARAMETER(fullSync);
- UNUSED_PARAMETER(dataOnly);
-#endif
-
- /* Record the number of times that we do a normal fsync() and
- ** FULLSYNC. This is used during testing to verify that this procedure
- ** gets called with the correct arguments.
- */
-#ifdef SQLITE_TEST
- if( fullSync ) sqlite3_fullsync_count++;
- sqlite3_sync_count++;
-#endif
-
- /* If we compiled with the SQLITE_NO_SYNC flag, then syncing is a
- ** no-op
- */
-#ifdef SQLITE_NO_SYNC
- rc = SQLITE_OK;
-#elif HAVE_FULLFSYNC
- if( fullSync ){
- rc = fcntl(fd, F_FULLFSYNC, 0);
- }else{
- rc = 1;
- }
- /* If the FULLFSYNC failed, fall back to attempting an fsync().
- ** It shouldn't be possible for fullfsync to fail on the local
- ** file system (on OSX), so failure indicates that FULLFSYNC
- ** isn't supported for this file system. So, attempt an fsync
- ** and (for now) ignore the overhead of a superfluous fcntl call.
- ** It'd be better to detect fullfsync support once and avoid
- ** the fcntl call every time sync is called.
- */
- if( rc ) rc = fsync(fd);
-
-#else
- rc = fdatasync(fd);
-#if OS_VXWORKS
- if( rc==-1 && errno==ENOTSUP ){
- rc = fsync(fd);
- }
-#endif /* OS_VXWORKS */
-#endif /* ifdef SQLITE_NO_SYNC elif HAVE_FULLFSYNC */
-
- if( OS_VXWORKS && rc!= -1 ){
- rc = 0;
- }
- return rc;
-}
-
-/*
-** Make sure all writes to a particular file are committed to disk.
-**
-** If dataOnly==0 then both the file itself and its metadata (file
-** size, access time, etc) are synced. If dataOnly!=0 then only the
-** file data is synced.
-**
-** Under Unix, also make sure that the directory entry for the file
-** has been created by fsync-ing the directory that contains the file.
-** If we do not do this and we encounter a power failure, the directory
-** entry for the journal might not exist after we reboot. The next
-** SQLite to access the file will not know that the journal exists (because
-** the directory entry for the journal was never created) and the transaction
-** will not roll back - possibly leading to database corruption.
-*/
-static int unixSync(sqlite3_file *id, int flags){
- int rc;
- unixFile *pFile = (unixFile*)id;
-
- int isDataOnly = (flags&SQLITE_SYNC_DATAONLY);
- int isFullsync = (flags&0x0F)==SQLITE_SYNC_FULL;
-
- /* Check that one of SQLITE_SYNC_NORMAL or FULL was passed */
- assert((flags&0x0F)==SQLITE_SYNC_NORMAL
- || (flags&0x0F)==SQLITE_SYNC_FULL
- );
-
- /* Unix cannot, but some systems may return SQLITE_FULL from here. This
- ** line is to test that doing so does not cause any problems.
- */
- SimulateDiskfullError( return SQLITE_FULL );
-
- assert( pFile );
- OSTRACE2("SYNC %-3d\n", pFile->h);
- rc = full_fsync(pFile->h, isFullsync, isDataOnly);
- SimulateIOError( rc=1 );
- if( rc ){
- pFile->lastErrno = errno;
- return SQLITE_IOERR_FSYNC;
- }
- if( pFile->dirfd>=0 ){
- int err;
- OSTRACE4("DIRSYNC %-3d (have_fullfsync=%d fullsync=%d)\n", pFile->dirfd,
- HAVE_FULLFSYNC, isFullsync);
-#ifndef SQLITE_DISABLE_DIRSYNC
- /* The directory sync is only attempted if full_fsync is
- ** turned off or unavailable. If a full_fsync occurred above,
- ** then the directory sync is superfluous.
- */
- if( (!HAVE_FULLFSYNC || !isFullsync) && full_fsync(pFile->dirfd,0,0) ){
- /*
- ** We have received multiple reports of fsync() returning
- ** errors when applied to directories on certain file systems.
- ** A failed directory sync is not a big deal. So it seems
- ** better to ignore the error. Ticket #1657
- */
- /* pFile->lastErrno = errno; */
- /* return SQLITE_IOERR; */
- }
-#endif
- err = close(pFile->dirfd); /* Only need to sync once, so close the */
- if( err==0 ){ /* directory when we are done */
- pFile->dirfd = -1;
- }else{
- pFile->lastErrno = errno;
- rc = SQLITE_IOERR_DIR_CLOSE;
- }
- }
- return rc;
-}
-
-/*
-** Truncate an open file to a specified size
-*/
-static int unixTruncate(sqlite3_file *id, i64 nByte){
- int rc;
- assert( id );
- SimulateIOError( return SQLITE_IOERR_TRUNCATE );
- rc = ftruncate(((unixFile*)id)->h, (off_t)nByte);
- if( rc ){
- ((unixFile*)id)->lastErrno = errno;
- return SQLITE_IOERR_TRUNCATE;
- }else{
- return SQLITE_OK;
- }
-}
-
-/*
-** Determine the current size of a file in bytes
-*/
-static int unixFileSize(sqlite3_file *id, i64 *pSize){
- int rc;
- struct stat buf;
- assert( id );
- rc = fstat(((unixFile*)id)->h, &buf);
- SimulateIOError( rc=1 );
- if( rc!=0 ){
- ((unixFile*)id)->lastErrno = errno;
- return SQLITE_IOERR_FSTAT;
- }
- *pSize = buf.st_size;
-
- /* When opening a zero-size database, the findLockInfo() procedure
- ** writes a single byte into that file in order to work around a bug
- ** in the OS-X msdos filesystem. In order to avoid problems with upper
- ** layers, we need to report this file size as zero even though it is
- ** really 1. Ticket #3260.
- */
- if( *pSize==1 ) *pSize = 0;
-
-
- return SQLITE_OK;
-}
-
-#if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__)
-/*
-** Handler for proxy-locking file-control verbs. Defined below in the
-** proxying locking division.
-*/
-static int proxyFileControl(sqlite3_file*,int,void*);
-#endif
-
-
-/*
-** Information and control of an open file handle.
-*/
-static int unixFileControl(sqlite3_file *id, int op, void *pArg){
- switch( op ){
- case SQLITE_FCNTL_LOCKSTATE: {
- *(int*)pArg = ((unixFile*)id)->locktype;
- return SQLITE_OK;
- }
- case SQLITE_LAST_ERRNO: {
- *(int*)pArg = ((unixFile*)id)->lastErrno;
- return SQLITE_OK;
- }
-#ifndef NDEBUG
- /* The pager calls this method to signal that it has done
- ** a rollback and that the database is therefore unchanged and
- ** it hence it is OK for the transaction change counter to be
- ** unchanged.
- */
- case SQLITE_FCNTL_DB_UNCHANGED: {
- ((unixFile*)id)->dbUpdate = 0;
- return SQLITE_OK;
- }
-#endif
-#if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__)
- case SQLITE_SET_LOCKPROXYFILE:
- case SQLITE_GET_LOCKPROXYFILE: {
- return proxyFileControl(id,op,pArg);
- }
-#endif /* SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) */
- }
- return SQLITE_ERROR;
-}
-
-/*
-** Return the sector size in bytes of the underlying block device for
-** the specified file. This is almost always 512 bytes, but may be
-** larger for some devices.
-**
-** SQLite code assumes this function cannot fail. It also assumes that
-** if two files are created in the same file-system directory (i.e.
-** 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);
- return SQLITE_DEFAULT_SECTOR_SIZE;
-}
-
-/*
-** Return the device characteristics for the file. This is always 0 for unix.
-*/
-static int unixDeviceCharacteristics(sqlite3_file *NotUsed){
- UNUSED_PARAMETER(NotUsed);
- return 0;
-}
-
-/*
-** Here ends the implementation of all sqlite3_file methods.
-**
-********************** End sqlite3_file Methods *******************************
-******************************************************************************/
-
-/*
-** This division contains definitions of sqlite3_io_methods objects that
-** implement various file locking strategies. It also contains definitions
-** of "finder" functions. A finder-function is used to locate the appropriate
-** sqlite3_io_methods object for a particular database file. The pAppData
-** field of the sqlite3_vfs VFS objects are initialized to be pointers to
-** the correct finder-function for that VFS.
-**
-** Most finder functions return a pointer to a fixed sqlite3_io_methods
-** object. The only interesting finder-function is autolockIoFinder, which
-** looks at the filesystem type and tries to guess the best locking
-** strategy from that.
-**
-** For finder-funtion F, two objects are created:
-**
-** (1) The real finder-function named "FImpt()".
-**
-** (2) A constant pointer to this function named just "F".
-**
-**
-** A pointer to the F pointer is used as the pAppData value for VFS
-** objects. We have to do this instead of letting pAppData point
-** directly at the finder-function since C90 rules prevent a void*
-** from be cast into a function pointer.
-**
-**
-** Each instance of this macro generates two objects:
-**
-** * A constant sqlite3_io_methods object call METHOD that has locking
-** methods CLOSE, LOCK, UNLOCK, CKRESLOCK.
-**
-** * An I/O method finder function called FINDER that returns a pointer
-** to the METHOD object in the previous bullet.
-*/
-#define IOMETHODS(FINDER, METHOD, CLOSE, LOCK, UNLOCK, CKLOCK) \
-static const sqlite3_io_methods METHOD = { \
- 1, /* iVersion */ \
- CLOSE, /* xClose */ \
- unixRead, /* xRead */ \
- unixWrite, /* xWrite */ \
- unixTruncate, /* xTruncate */ \
- unixSync, /* xSync */ \
- unixFileSize, /* xFileSize */ \
- LOCK, /* xLock */ \
- UNLOCK, /* xUnlock */ \
- CKLOCK, /* xCheckReservedLock */ \
- unixFileControl, /* xFileControl */ \
- unixSectorSize, /* xSectorSize */ \
- unixDeviceCharacteristics /* xDeviceCapabilities */ \
-}; \
-static const sqlite3_io_methods *FINDER##Impl(const char *z, unixFile *p){ \
- UNUSED_PARAMETER(z); UNUSED_PARAMETER(p); \
- return &METHOD; \
-} \
-static const sqlite3_io_methods *(*const FINDER)(const char*,unixFile *p) \
- = FINDER##Impl;
-
-/*
-** Here are all of the sqlite3_io_methods objects for each of the
-** locking strategies. Functions that return pointers to these methods
-** are also created.
-*/
-IOMETHODS(
- posixIoFinder, /* Finder function name */
- posixIoMethods, /* sqlite3_io_methods object name */
- unixClose, /* xClose method */
- unixLock, /* xLock method */
- unixUnlock, /* xUnlock method */
- unixCheckReservedLock /* xCheckReservedLock method */
-)
-IOMETHODS(
- nolockIoFinder, /* Finder function name */
- nolockIoMethods, /* sqlite3_io_methods object name */
- nolockClose, /* xClose method */
- nolockLock, /* xLock method */
- nolockUnlock, /* xUnlock method */
- nolockCheckReservedLock /* xCheckReservedLock method */
-)
-IOMETHODS(
- dotlockIoFinder, /* Finder function name */
- dotlockIoMethods, /* sqlite3_io_methods object name */
- dotlockClose, /* xClose method */
- dotlockLock, /* xLock method */
- dotlockUnlock, /* xUnlock method */
- dotlockCheckReservedLock /* xCheckReservedLock method */
-)
-
-#if SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORKS
-IOMETHODS(
- flockIoFinder, /* Finder function name */
- flockIoMethods, /* sqlite3_io_methods object name */
- flockClose, /* xClose method */
- flockLock, /* xLock method */
- flockUnlock, /* xUnlock method */
- flockCheckReservedLock /* xCheckReservedLock method */
-)
-#endif
-
-#if OS_VXWORKS
-IOMETHODS(
- semIoFinder, /* Finder function name */
- semIoMethods, /* sqlite3_io_methods object name */
- semClose, /* xClose method */
- semLock, /* xLock method */
- semUnlock, /* xUnlock method */
- semCheckReservedLock /* xCheckReservedLock method */
-)
-#endif
-
-#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE
-IOMETHODS(
- afpIoFinder, /* Finder function name */
- afpIoMethods, /* sqlite3_io_methods object name */
- afpClose, /* xClose method */
- afpLock, /* xLock method */
- afpUnlock, /* xUnlock method */
- afpCheckReservedLock /* xCheckReservedLock method */
-)
-#endif
-
-/*
-** The "Whole File Locking" finder returns the same set of methods as
-** the posix locking finder. But it also sets the SQLITE_WHOLE_FILE_LOCKING
-** flag to force the posix advisory locks to cover the whole file instead
-** of just a small span of bytes near the 1GiB boundary. Whole File Locking
-** is useful on NFS-mounted files since it helps NFS to maintain cache
-** coherency. But it is a detriment to other filesystems since it runs
-** slower.
-*/
-static const sqlite3_io_methods *posixWflIoFinderImpl(const char*z, unixFile*p){
- UNUSED_PARAMETER(z);
- p->fileFlags = SQLITE_WHOLE_FILE_LOCKING;
- return &posixIoMethods;
-}
-static const sqlite3_io_methods
- *(*const posixWflIoFinder)(const char*,unixFile *p) = posixWflIoFinderImpl;
-
-/*
-** The proxy locking method is a "super-method" in the sense that it
-** opens secondary file descriptors for the conch and lock files and
-** it uses proxy, dot-file, AFP, and flock() locking methods on those
-** secondary files. For this reason, the division that implements
-** proxy locking is located much further down in the file. But we need
-** to go ahead and define the sqlite3_io_methods and finder function
-** for proxy locking here. So we forward declare the I/O methods.
-*/
-#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE
-static int proxyClose(sqlite3_file*);
-static int proxyLock(sqlite3_file*, int);
-static int proxyUnlock(sqlite3_file*, int);
-static int proxyCheckReservedLock(sqlite3_file*, int*);
-IOMETHODS(
- proxyIoFinder, /* Finder function name */
- proxyIoMethods, /* sqlite3_io_methods object name */
- proxyClose, /* xClose method */
- proxyLock, /* xLock method */
- proxyUnlock, /* xUnlock method */
- proxyCheckReservedLock /* xCheckReservedLock method */
-)
-#endif
-
-
-#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE
-/*
-** This "finder" function attempts to determine the best locking strategy
-** for the database file "filePath". It then returns the sqlite3_io_methods
-** object that implements that strategy.
-**
-** This is for MacOSX only.
-*/
-static const sqlite3_io_methods *autolockIoFinderImpl(
- const char *filePath, /* name of the database file */
- unixFile *pNew /* open file object for the database file */
-){
- static const struct Mapping {
- const char *zFilesystem; /* Filesystem type name */
- const sqlite3_io_methods *pMethods; /* Appropriate locking method */
- } aMap[] = {
- { "hfs", &posixIoMethods },
- { "ufs", &posixIoMethods },
- { "afpfs", &afpIoMethods },
-#ifdef SQLITE_ENABLE_AFP_LOCKING_SMB
- { "smbfs", &afpIoMethods },
-#else
- { "smbfs", &flockIoMethods },
-#endif
- { "webdav", &nolockIoMethods },
- { 0, 0 }
- };
- int i;
- struct statfs fsInfo;
- struct flock lockInfo;
-
- if( !filePath ){
- /* If filePath==NULL that means we are dealing with a transient file
- ** that does not need to be locked. */
- return &nolockIoMethods;
- }
- if( statfs(filePath, &fsInfo) != -1 ){
- if( fsInfo.f_flags & MNT_RDONLY ){
- return &nolockIoMethods;
- }
- for(i=0; aMap[i].zFilesystem; i++){
- if( strcmp(fsInfo.f_fstypename, aMap[i].zFilesystem)==0 ){
- return aMap[i].pMethods;
- }
- }
- }
-
- /* Default case. Handles, amongst others, "nfs".
- ** Test byte-range lock using fcntl(). If the call succeeds,
- ** assume that the file-system supports POSIX style locks.
- */
- lockInfo.l_len = 1;
- lockInfo.l_start = 0;
- lockInfo.l_whence = SEEK_SET;
- lockInfo.l_type = F_RDLCK;
- if( fcntl(pNew->h, F_GETLK, &lockInfo)!=-1 ) {
- pNew->fileFlags = SQLITE_WHOLE_FILE_LOCKING;
- return &posixIoMethods;
- }else{
- return &dotlockIoMethods;
- }
-}
-static const sqlite3_io_methods
- *(*const autolockIoFinder)(const char*,unixFile*) = autolockIoFinderImpl;
-
-#endif /* defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE */
-
-#if OS_VXWORKS && SQLITE_ENABLE_LOCKING_STYLE
-/*
-** This "finder" function attempts to determine the best locking strategy
-** for the database file "filePath". It then returns the sqlite3_io_methods
-** object that implements that strategy.
-**
-** This is for VXWorks only.
-*/
-static const sqlite3_io_methods *autolockIoFinderImpl(
- const char *filePath, /* name of the database file */
- unixFile *pNew /* the open file object */
-){
- struct flock lockInfo;
-
- if( !filePath ){
- /* If filePath==NULL that means we are dealing with a transient file
- ** that does not need to be locked. */
- return &nolockIoMethods;
- }
-
- /* Test if fcntl() is supported and use POSIX style locks.
- ** Otherwise fall back to the named semaphore method.
- */
- lockInfo.l_len = 1;
- lockInfo.l_start = 0;
- lockInfo.l_whence = SEEK_SET;
- lockInfo.l_type = F_RDLCK;
- if( fcntl(pNew->h, F_GETLK, &lockInfo)!=-1 ) {
- return &posixIoMethods;
- }else{
- return &semIoMethods;
- }
-}
-static const sqlite3_io_methods
- *(*const autolockIoFinder)(const char*,unixFile*) = autolockIoFinderImpl;
-
-#endif /* OS_VXWORKS && SQLITE_ENABLE_LOCKING_STYLE */
-
-/*
-** An abstract type for a pointer to a IO method finder function:
-*/
-typedef const sqlite3_io_methods *(*finder_type)(const char*,unixFile*);
-
-
-/****************************************************************************
-**************************** sqlite3_vfs methods ****************************
-**
-** This division contains the implementation of methods on the
-** sqlite3_vfs object.
-*/
-
-/*
-** Initialize the contents of the unixFile structure pointed to by pId.
-*/
-static int fillInUnixFile(
- sqlite3_vfs *pVfs, /* Pointer to vfs object */
- int h, /* Open file descriptor of file being opened */
- int dirfd, /* Directory file descriptor */
- 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 */
-){
- const sqlite3_io_methods *pLockingStyle;
- unixFile *pNew = (unixFile *)pId;
- int rc = SQLITE_OK;
-
- assert( pNew->pLock==NULL );
- assert( pNew->pOpen==NULL );
-
- /* Parameter isDelete is only used on vxworks. Express this explicitly
- ** here to prevent compiler warnings about unused parameters.
- */
- UNUSED_PARAMETER(isDelete);
-
- OSTRACE3("OPEN %-3d %s\n", h, zFilename);
- pNew->h = h;
- pNew->dirfd = dirfd;
- SET_THREADID(pNew);
- pNew->fileFlags = 0;
-
-#if OS_VXWORKS
- pNew->pId = vxworksFindFileId(zFilename);
- if( pNew->pId==0 ){
- noLock = 1;
- rc = SQLITE_NOMEM;
- }
-#endif
-
- if( noLock ){
- pLockingStyle = &nolockIoMethods;
- }else{
- pLockingStyle = (**(finder_type*)pVfs->pAppData)(zFilename, pNew);
-#if SQLITE_ENABLE_LOCKING_STYLE
- /* Cache zFilename in the locking context (AFP and dotlock override) for
- ** proxyLock activation is possible (remote proxy is based on db name)
- ** zFilename remains valid until file is closed, to support */
- pNew->lockingContext = (void*)zFilename;
-#endif
- }
-
- if( pLockingStyle == &posixIoMethods ){
- unixEnterMutex();
- rc = findLockInfo(pNew, &pNew->pLock, &pNew->pOpen);
- if( rc!=SQLITE_OK ){
- /* If an error occured in findLockInfo(), close the file descriptor
- ** immediately, before releasing the mutex. findLockInfo() may fail
- ** in two scenarios:
- **
- ** (a) A call to fstat() failed.
- ** (b) A malloc failed.
- **
- ** Scenario (b) may only occur if the process is holding no other
- ** file descriptors open on the same file. If there were other file
- ** descriptors on this file, then no malloc would be required by
- ** findLockInfo(). If this is the case, it is quite safe to close
- ** handle h - as it is guaranteed that no posix locks will be released
- ** by doing so.
- **
- ** If scenario (a) caused the error then things are not so safe. The
- ** implicit assumption here is that if fstat() fails, things are in
- ** such bad shape that dropping a lock or two doesn't matter much.
- */
- close(h);
- h = -1;
- }
- unixLeaveMutex();
- }
-
-#if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__)
- else if( pLockingStyle == &afpIoMethods ){
- /* AFP locking uses the file path so it needs to be included in
- ** the afpLockingContext.
- */
- afpLockingContext *pCtx;
- pNew->lockingContext = pCtx = sqlite3_malloc( sizeof(*pCtx) );
- if( pCtx==0 ){
- rc = SQLITE_NOMEM;
- }else{
- /* NB: zFilename exists and remains valid until the file is closed
- ** according to requirement F11141. So we do not need to make a
- ** copy of the filename. */
- pCtx->dbPath = zFilename;
- srandomdev();
- unixEnterMutex();
- rc = findLockInfo(pNew, NULL, &pNew->pOpen);
- unixLeaveMutex();
- }
- }
-#endif
-
- else if( pLockingStyle == &dotlockIoMethods ){
- /* Dotfile locking uses the file path so it needs to be included in
- ** the dotlockLockingContext
- */
- char *zLockFile;
- int nFilename;
- nFilename = (int)strlen(zFilename) + 6;
- zLockFile = (char *)sqlite3_malloc(nFilename);
- if( zLockFile==0 ){
- rc = SQLITE_NOMEM;
- }else{
- sqlite3_snprintf(nFilename, zLockFile, "%s" DOTLOCK_SUFFIX, zFilename);
- }
- pNew->lockingContext = zLockFile;
- }
-
-#if OS_VXWORKS
- else if( pLockingStyle == &semIoMethods ){
- /* Named semaphore locking uses the file path so it needs to be
- ** included in the semLockingContext
- */
- unixEnterMutex();
- rc = findLockInfo(pNew, &pNew->pLock, &pNew->pOpen);
- if( (rc==SQLITE_OK) && (pNew->pOpen->pSem==NULL) ){
- char *zSemName = pNew->pOpen->aSemName;
- int n;
- sqlite3_snprintf(MAX_PATHNAME, zSemName, "/%s.sem",
- pNew->pId->zCanonicalName);
- for( n=1; zSemName[n]; n++ )
- if( zSemName[n]=='/' ) zSemName[n] = '_';
- pNew->pOpen->pSem = sem_open(zSemName, O_CREAT, 0666, 1);
- if( pNew->pOpen->pSem == SEM_FAILED ){
- rc = SQLITE_NOMEM;
- pNew->pOpen->aSemName[0] = '\0';
- }
- }
- unixLeaveMutex();
- }
-#endif
-
- pNew->lastErrno = 0;
-#if OS_VXWORKS
- if( rc!=SQLITE_OK ){
- unlink(zFilename);
- isDelete = 0;
- }
- pNew->isDelete = isDelete;
-#endif
- if( rc!=SQLITE_OK ){
- if( dirfd>=0 ) close(dirfd); /* silent leak if fail, already in error */
- if( h>=0 ) close(h);
- }else{
- pNew->pMethod = pLockingStyle;
- OpenCounter(+1);
- }
- return rc;
-}
-
-/*
-** Open a file descriptor to the directory containing file zFilename.
-** If successful, *pFd is set to the opened file descriptor and
-** SQLITE_OK is returned. If an error occurs, either SQLITE_NOMEM
-** or SQLITE_CANTOPEN is returned and *pFd is set to an undefined
-** value.
-**
-** If SQLITE_OK is returned, the caller is responsible for closing
-** the file descriptor *pFd using close().
-*/
-static int openDirectory(const char *zFilename, int *pFd){
- int ii;
- int fd = -1;
- char zDirname[MAX_PATHNAME+1];
-
- sqlite3_snprintf(MAX_PATHNAME, zDirname, "%s", zFilename);
- for(ii=(int)strlen(zDirname); ii>1 && zDirname[ii]!='/'; ii--);
- if( ii>0 ){
- zDirname[ii] = '\0';
- fd = open(zDirname, O_RDONLY|O_BINARY, 0);
- if( fd>=0 ){
-#ifdef FD_CLOEXEC
- fcntl(fd, F_SETFD, fcntl(fd, F_GETFD, 0) | FD_CLOEXEC);
-#endif
- OSTRACE3("OPENDIR %-3d %s\n", fd, zDirname);
- }
- }
- *pFd = fd;
- return (fd>=0?SQLITE_OK:SQLITE_CANTOPEN);
-}
-
-/*
-** Create a temporary file name in zBuf. zBuf must be allocated
-** by the calling process and must be big enough to hold at least
-** pVfs->mxPathname bytes.
-*/
-static int getTempname(int nBuf, char *zBuf){
- static const char *azDirs[] = {
- 0,
- 0,
- "/var/tmp",
- "/usr/tmp",
- "/tmp",
- ".",
- };
- static const unsigned char zChars[] =
- "abcdefghijklmnopqrstuvwxyz"
- "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
- "0123456789";
- unsigned int i, j;
- struct stat buf;
- const char *zDir = ".";
-
- /* 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
- ** function failing.
- */
- SimulateIOError( return SQLITE_IOERR );
-
- azDirs[0] = sqlite3_temp_directory;
- if (NULL == azDirs[1]) {
- azDirs[1] = getenv("TMPDIR");
- }
-
- for(i=0; i<sizeof(azDirs)/sizeof(azDirs[0]); i++){
- if( azDirs[i]==0 ) continue;
- if( stat(azDirs[i], &buf) ) continue;
- if( !S_ISDIR(buf.st_mode) ) continue;
- if( access(azDirs[i], 07) ) continue;
- zDir = azDirs[i];
- break;
- }
-
- /* 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 ){
- return SQLITE_ERROR;
- }
-
- do{
- sqlite3_snprintf(nBuf-17, 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;
- }while( access(zBuf,0)==0 );
- return SQLITE_OK;
-}
-
-#if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__)
-/*
-** Routine to transform a unixFile into a proxy-locking unixFile.
-** Implementation in the proxy-lock division, but used by unixOpen()
-** if SQLITE_PREFER_PROXY_LOCKING is defined.
-*/
-static int proxyTransformUnixFile(unixFile*, const char*);
-#endif
-
-/*
-** Search for an unused file descriptor that was opened on the database
-** file (not a journal or master-journal file) identified by pathname
-** zPath with SQLITE_OPEN_XXX flags matching those passed as the second
-** argument to this function.
-**
-** Such a file descriptor may exist if a database connection was closed
-** but the associated file descriptor could not be closed because some
-** other file descriptor open on the same file is holding a file-lock.
-** Refer to comments in the unixClose() function and the lengthy comment
-** describing "Posix Advisory Locking" at the start of this file for
-** further details. Also, ticket #4018.
-**
-** If a suitable file descriptor is found, then it is returned. If no
-** such file descriptor is located, -1 is returned.
-*/
-static UnixUnusedFd *findReusableFd(const char *zPath, int flags){
- UnixUnusedFd *pUnused = 0;
-
- /* Do not search for an unused file descriptor on vxworks. Not because
- ** vxworks would not benefit from the change (it might, we're not sure),
- ** but because no way to test it is currently available. It is better
- ** not to risk breaking vxworks support for the sake of such an obscure
- ** feature. */
-#if !OS_VXWORKS
- struct stat sStat; /* Results of stat() call */
-
- /* A stat() call may fail for various reasons. If this happens, it is
- ** almost certain that an open() call on the same path will also fail.
- ** For this reason, if an error occurs in the stat() call here, it is
- ** ignored and -1 is returned. The caller will try to open a new file
- ** descriptor on the same path, fail, and return an error to SQLite.
- **
- ** Even if a subsequent open() call does succeed, the consequences of
- ** not searching for a resusable file descriptor are not dire. */
- if( 0==stat(zPath, &sStat) ){
- struct unixOpenCnt *pO;
- struct unixFileId id;
- id.dev = sStat.st_dev;
- id.ino = sStat.st_ino;
-
- unixEnterMutex();
- for(pO=openList; pO && memcmp(&id, &pO->fileId, sizeof(id)); pO=pO->pNext);
- if( pO ){
- UnixUnusedFd **pp;
- for(pp=&pO->pUnused; *pp && (*pp)->flags!=flags; pp=&((*pp)->pNext));
- pUnused = *pp;
- if( pUnused ){
- *pp = pUnused->pNext;
- }
- }
- unixLeaveMutex();
- }
-#endif /* if !OS_VXWORKS */
- return pUnused;
-}
-
-/*
-** Open the file zPath.
-**
-** Previously, the SQLite OS layer used three functions in place of this
-** one:
-**
-** sqlite3OsOpenReadWrite();
-** sqlite3OsOpenReadOnly();
-** sqlite3OsOpenExclusive();
-**
-** These calls correspond to the following combinations of flags:
-**
-** ReadWrite() -> (READWRITE | CREATE)
-** ReadOnly() -> (READONLY)
-** OpenExclusive() -> (READWRITE | CREATE | EXCLUSIVE)
-**
-** The old OpenExclusive() accepted a boolean argument - "delFlag". If
-** true, the file was configured to be automatically deleted when the
-** file handle closed. To achieve the same effect using this new
-** interface, add the DELETEONCLOSE flag to those specified above for
-** OpenExclusive().
-*/
-static int unixOpen(
- sqlite3_vfs *pVfs, /* The VFS for which this is the xOpen method */
- const char *zPath, /* Pathname of file to be opened */
- sqlite3_file *pFile, /* The file descriptor to be filled in */
- int flags, /* Input flags to control the opening */
- int *pOutFlags /* Output flags returned to SQLite core */
-){
- unixFile *p = (unixFile *)pFile;
- int fd = -1; /* File descriptor returned by open() */
- int dirfd = -1; /* Directory file descriptor */
- int openFlags = 0; /* Flags to pass to open() */
- int eType = flags&0xFFFFFF00; /* Type of file to open */
- int noLock; /* True to omit locking primitives */
- int rc = SQLITE_OK; /* Function Return Code */
-
- int isExclusive = (flags & SQLITE_OPEN_EXCLUSIVE);
- int isDelete = (flags & SQLITE_OPEN_DELETEONCLOSE);
- int isCreate = (flags & SQLITE_OPEN_CREATE);
- int isReadonly = (flags & SQLITE_OPEN_READONLY);
- int isReadWrite = (flags & SQLITE_OPEN_READWRITE);
-
- /* If creating a master or main-file journal, this function will open
- ** a file-descriptor on the directory too. The first time unixSync()
- ** is called the directory file descriptor will be fsync()ed and close()d.
- */
- int isOpenDirectory = (isCreate &&
- (eType==SQLITE_OPEN_MASTER_JOURNAL || eType==SQLITE_OPEN_MAIN_JOURNAL)
- );
-
- /* 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];
- const char *zName = zPath;
-
- /* Check the following statements are true:
- **
- ** (a) Exactly one of the READWRITE and READONLY flags must be set, and
- ** (b) if CREATE is set, then READWRITE must also be set, and
- ** (c) if EXCLUSIVE is set, then CREATE must also be set.
- ** (d) if DELETEONCLOSE is set, then CREATE must also be set.
- */
- assert((isReadonly==0 || isReadWrite==0) && (isReadWrite || isReadonly));
- assert(isCreate==0 || isReadWrite);
- assert(isExclusive==0 || isCreate);
- assert(isDelete==0 || isCreate);
-
- /* The main DB, main journal, and master journal are never automatically
- ** deleted. Nor are they ever temporary files. */
- assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MAIN_DB );
- assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MAIN_JOURNAL );
- assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MASTER_JOURNAL );
-
- /* Assert that the upper layer has set one of the "file-type" flags. */
- assert( eType==SQLITE_OPEN_MAIN_DB || eType==SQLITE_OPEN_TEMP_DB
- || eType==SQLITE_OPEN_MAIN_JOURNAL || eType==SQLITE_OPEN_TEMP_JOURNAL
- || eType==SQLITE_OPEN_SUBJOURNAL || eType==SQLITE_OPEN_MASTER_JOURNAL
- || eType==SQLITE_OPEN_TRANSIENT_DB
- );
-
- memset(p, 0, sizeof(unixFile));
-
- if( eType==SQLITE_OPEN_MAIN_DB ){
- UnixUnusedFd *pUnused;
- pUnused = findReusableFd(zName, flags);
- if( pUnused ){
- fd = pUnused->fd;
- }else{
- pUnused = sqlite3_malloc(sizeof(*pUnused));
- if( !pUnused ){
- return SQLITE_NOMEM;
- }
- }
- p->pUnused = pUnused;
- }else if( !zName ){
- /* If zName is NULL, the upper layer is requesting a temp file. */
- assert(isDelete && !isOpenDirectory);
- rc = getTempname(MAX_PATHNAME+1, zTmpname);
- if( rc!=SQLITE_OK ){
- return rc;
- }
- zName = zTmpname;
- }
-
- /* Determine the value of the flags parameter passed to POSIX function
- ** open(). These must be calculated even if open() is not called, as
- ** they may be stored as part of the file handle and used by the
- ** 'conch file' locking functions later on. */
- if( isReadonly ) openFlags |= O_RDONLY;
- if( isReadWrite ) openFlags |= O_RDWR;
- if( isCreate ) openFlags |= O_CREAT;
- if( isExclusive ) openFlags |= (O_EXCL|O_NOFOLLOW);
- openFlags |= (O_LARGEFILE|O_BINARY);
-
- if( fd<0 ){
- mode_t openMode = (isDelete?0600:SQLITE_DEFAULT_FILE_PERMISSIONS);
- fd = open(zName, openFlags, openMode);
- OSTRACE4("OPENX %-3d %s 0%o\n", fd, zName, openFlags);
- if( fd<0 && errno!=EISDIR && isReadWrite && !isExclusive ){
- /* Failed to open the file for read/write access. Try read-only. */
- flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE);
- openFlags &= ~(O_RDWR|O_CREAT);
- flags |= SQLITE_OPEN_READONLY;
- openFlags |= O_RDONLY;
- fd = open(zName, openFlags, openMode);
- }
- if( fd<0 ){
- rc = SQLITE_CANTOPEN;
- goto open_finished;
- }
- }
- assert( fd>=0 );
- if( pOutFlags ){
- *pOutFlags = flags;
- }
-
- if( p->pUnused ){
- p->pUnused->fd = fd;
- p->pUnused->flags = flags;
- }
-
- if( isDelete ){
-#if OS_VXWORKS
- zPath = zName;
-#else
- unlink(zName);
-#endif
- }
-#if SQLITE_ENABLE_LOCKING_STYLE
- else{
- p->openFlags = openFlags;
- }
-#endif
-
- if( isOpenDirectory ){
- rc = openDirectory(zPath, &dirfd);
- if( rc!=SQLITE_OK ){
- /* It is safe to close fd at this point, because it is guaranteed not
- ** to be open on a database file. If it were open on a database file,
- ** it would not be safe to close as this would release any locks held
- ** on the file by this process. */
- assert( eType!=SQLITE_OPEN_MAIN_DB );
- close(fd); /* silently leak if fail, already in error */
- goto open_finished;
- }
- }
-
-#ifdef FD_CLOEXEC
- fcntl(fd, F_SETFD, fcntl(fd, F_GETFD, 0) | FD_CLOEXEC);
-#endif
-
- noLock = eType!=SQLITE_OPEN_MAIN_DB;
-
-#if SQLITE_PREFER_PROXY_LOCKING
- if( zPath!=NULL && !noLock && pVfs->xOpen ){
- char *envforce = getenv("SQLITE_FORCE_PROXY_LOCKING");
- int useProxy = 0;
-
- /* SQLITE_FORCE_PROXY_LOCKING==1 means force always use proxy, 0 means
- ** never use proxy, NULL means use proxy for non-local files only. */
- if( envforce!=NULL ){
- useProxy = atoi(envforce)>0;
- }else{
- struct statfs fsInfo;
- if( statfs(zPath, &fsInfo) == -1 ){
- /* In theory, the close(fd) call is sub-optimal. If the file opened
- ** with fd is a database file, and there are other connections open
- ** on that file that are currently holding advisory locks on it,
- ** then the call to close() will cancel those locks. In practice,
- ** we're assuming that statfs() doesn't fail very often. At least
- ** not while other file descriptors opened by the same process on
- ** the same file are working. */
- p->lastErrno = errno;
- if( dirfd>=0 ){
- close(dirfd); /* silently leak if fail, in error */
- }
- close(fd); /* silently leak if fail, in error */
- rc = SQLITE_IOERR_ACCESS;
- goto open_finished;
- }
- useProxy = !(fsInfo.f_flags&MNT_LOCAL);
- }
- if( useProxy ){
- rc = fillInUnixFile(pVfs, fd, dirfd, pFile, zPath, noLock, isDelete);
- if( rc==SQLITE_OK ){
- rc = proxyTransformUnixFile((unixFile*)pFile, ":auto:");
- }
- goto open_finished;
- }
- }
-#endif
-
- rc = fillInUnixFile(pVfs, fd, dirfd, pFile, zPath, noLock, isDelete);
-open_finished:
- if( rc!=SQLITE_OK ){
- sqlite3_free(p->pUnused);
- }
- return rc;
-}
-
-
-/*
-** Delete the file at zPath. If the dirSync argument is true, fsync()
-** the directory after deleting the file.
-*/
-static int unixDelete(
- sqlite3_vfs *NotUsed, /* VFS containing this as the xDelete method */
- const char *zPath, /* Name of file to be deleted */
- int dirSync /* If true, fsync() directory after deleting file */
-){
- int rc = SQLITE_OK;
- UNUSED_PARAMETER(NotUsed);
- SimulateIOError(return SQLITE_IOERR_DELETE);
- unlink(zPath);
-#ifndef SQLITE_DISABLE_DIRSYNC
- if( dirSync ){
- int fd;
- rc = openDirectory(zPath, &fd);
- if( rc==SQLITE_OK ){
-#if OS_VXWORKS
- if( fsync(fd)==-1 )
-#else
- if( fsync(fd) )
-#endif
- {
- rc = SQLITE_IOERR_DIR_FSYNC;
- }
- if( close(fd)&&!rc ){
- rc = SQLITE_IOERR_DIR_CLOSE;
- }
- }
- }
-#endif
- return rc;
-}
-
-/*
-** Test the existance of or access permissions of file zPath. The
-** test performed depends on the value of flags:
-**
-** SQLITE_ACCESS_EXISTS: Return 1 if the file exists
-** SQLITE_ACCESS_READWRITE: Return 1 if the file is read and writable.
-** SQLITE_ACCESS_READONLY: Return 1 if the file is readable.
-**
-** Otherwise return 0.
-*/
-static int unixAccess(
- sqlite3_vfs *NotUsed, /* The VFS containing this xAccess method */
- const char *zPath, /* Path of the file to examine */
- int flags, /* What do we want to learn about the zPath file? */
- int *pResOut /* Write result boolean here */
-){
- int amode = 0;
- UNUSED_PARAMETER(NotUsed);
- SimulateIOError( return SQLITE_IOERR_ACCESS; );
- switch( flags ){
- case SQLITE_ACCESS_EXISTS:
- amode = F_OK;
- break;
- case SQLITE_ACCESS_READWRITE:
- amode = W_OK|R_OK;
- break;
- case SQLITE_ACCESS_READ:
- amode = R_OK;
- break;
-
- default:
- assert(!"Invalid flags argument");
- }
- *pResOut = (access(zPath, amode)==0);
- return SQLITE_OK;
-}
-
-
-/*
-** Turn a relative pathname into a full pathname. The relative path
-** is stored as a nul-terminated string in the buffer pointed to by
-** zPath.
-**
-** zOut points to a buffer of at least sqlite3_vfs.mxPathname bytes
-** (in this case, MAX_PATHNAME bytes). The full-path is written to
-** this buffer before returning.
-*/
-static int unixFullPathname(
- sqlite3_vfs *pVfs, /* Pointer to vfs object */
- const char *zPath, /* Possibly relative input path */
- int nOut, /* Size of output buffer in bytes */
- char *zOut /* Output buffer */
-){
-
- /* 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
- ** function failing. This function could fail if, for example, the
- ** current working directory has been unlinked.
- */
- SimulateIOError( return SQLITE_ERROR );
-
- assert( pVfs->mxPathname==MAX_PATHNAME );
- UNUSED_PARAMETER(pVfs);
-
- zOut[nOut-1] = '\0';
- if( zPath[0]=='/' ){
- sqlite3_snprintf(nOut, zOut, "%s", zPath);
- }else{
- int nCwd;
- if( getcwd(zOut, nOut-1)==0 ){
- return SQLITE_CANTOPEN;
- }
- nCwd = (int)strlen(zOut);
- sqlite3_snprintf(nOut-nCwd, &zOut[nCwd], "/%s", zPath);
- }
- return SQLITE_OK;
-}
-
-
-#ifndef SQLITE_OMIT_LOAD_EXTENSION
-/*
-** Interfaces for opening a shared library, finding entry points
-** within the shared library, and closing the shared library.
-*/
-#include <dlfcn.h>
-static void *unixDlOpen(sqlite3_vfs *NotUsed, const char *zFilename){
- UNUSED_PARAMETER(NotUsed);
- return dlopen(zFilename, RTLD_NOW | RTLD_GLOBAL);
-}
-
-/*
-** SQLite calls this function immediately after a call to unixDlSym() or
-** unixDlOpen() fails (returns a null pointer). If a more detailed error
-** message is available, it is written to zBufOut. If no error message
-** is available, zBufOut is left unmodified and SQLite uses a default
-** error message.
-*/
-static void unixDlError(sqlite3_vfs *NotUsed, int nBuf, char *zBufOut){
- char *zErr;
- UNUSED_PARAMETER(NotUsed);
- unixEnterMutex();
- zErr = dlerror();
- if( zErr ){
- sqlite3_snprintf(nBuf, zBufOut, "%s", zErr);
- }
- unixLeaveMutex();
-}
-static void (*unixDlSym(sqlite3_vfs *NotUsed, void *p, const char*zSym))(void){
- /*
- ** GCC with -pedantic-errors says that C90 does not allow a void* to be
- ** cast into a pointer to a function. And yet the library dlsym() routine
- ** returns a void* which is really a pointer to a function. So how do we
- ** use dlsym() with -pedantic-errors?
- **
- ** Variable x below is defined to be a pointer to a function taking
- ** parameters void* and const char* and returning a pointer to a function.
- ** We initialize x by assigning it a pointer to the dlsym() function.
- ** (That assignment requires a cast.) Then we call the function that
- ** x points to.
- **
- ** This work-around is unlikely to work correctly on any system where
- ** you really cannot cast a function pointer into void*. But then, on the
- ** other hand, dlsym() will not work on such a system either, so we have
- ** not really lost anything.
- */
- void (*(*x)(void*,const char*))(void);
- UNUSED_PARAMETER(NotUsed);
- x = (void(*(*)(void*,const char*))(void))dlsym;
- return (*x)(p, zSym);
-}
-static void unixDlClose(sqlite3_vfs *NotUsed, void *pHandle){
- UNUSED_PARAMETER(NotUsed);
- dlclose(pHandle);
-}
-#else /* if SQLITE_OMIT_LOAD_EXTENSION is defined: */
- #define unixDlOpen 0
- #define unixDlError 0
- #define unixDlSym 0
- #define unixDlClose 0
-#endif
-
-/*
-** Write nBuf bytes of random data to the supplied buffer zBuf.
-*/
-static int unixRandomness(sqlite3_vfs *NotUsed, int nBuf, char *zBuf){
- UNUSED_PARAMETER(NotUsed);
- assert((size_t)nBuf>=(sizeof(time_t)+sizeof(int)));
-
- /* We have to initialize zBuf to prevent valgrind from reporting
- ** errors. The reports issued by valgrind are incorrect - we would
- ** prefer that the randomness be increased by making use of the
- ** uninitialized space in zBuf - but valgrind errors tend to worry
- ** some users. Rather than argue, it seems easier just to initialize
- ** the whole array and silence valgrind, even if that means less randomness
- ** in the random seed.
- **
- ** When testing, initializing zBuf[] to zero is all we do. That means
- ** that we always use the same random number sequence. This makes the
- ** tests repeatable.
- */
- memset(zBuf, 0, nBuf);
-#if !defined(SQLITE_TEST)
- {
- int pid, fd;
- fd = open("/dev/urandom", O_RDONLY);
- if( fd<0 ){
- time_t t;
- time(&t);
- memcpy(zBuf, &t, sizeof(t));
- pid = getpid();
- memcpy(&zBuf[sizeof(t)], &pid, sizeof(pid));
- assert( sizeof(t)+sizeof(pid)<=(size_t)nBuf );
- nBuf = sizeof(t) + sizeof(pid);
- }else{
- nBuf = read(fd, zBuf, nBuf);
- close(fd);
- }
- }
-#endif
- return nBuf;
-}
-
-
-/*
-** Sleep for a little while. Return the amount of time slept.
-** The argument is the number of microseconds we want to sleep.
-** The return value is the number of microseconds of sleep actually
-** requested from the underlying operating system, a number which
-** might be greater than or equal to the argument, but not less
-** than the argument.
-*/
-static int unixSleep(sqlite3_vfs *NotUsed, int microseconds){
-#if OS_VXWORKS
- struct timespec sp;
-
- sp.tv_sec = microseconds / 1000000;
- sp.tv_nsec = (microseconds % 1000000) * 1000;
- nanosleep(&sp, NULL);
- UNUSED_PARAMETER(NotUsed);
- return microseconds;
-#elif defined(HAVE_USLEEP) && HAVE_USLEEP
- usleep(microseconds);
- UNUSED_PARAMETER(NotUsed);
- return microseconds;
-#else
- int seconds = (microseconds+999999)/1000000;
- sleep(seconds);
- UNUSED_PARAMETER(NotUsed);
- return seconds*1000000;
-#endif
-}
-
-/*
-** The following variable, if set to a non-zero value, is interpreted as
-** the number of seconds since 1970 and is used to set the result of
-** sqlite3OsCurrentTime() during testing.
-*/
-#ifdef SQLITE_TEST
-SQLITE_API int sqlite3_current_time = 0; /* Fake system time in seconds since 1970. */
-#endif
-
-/*
-** Find the current time (in Universal Coordinated Time). Write the
-** current time and date as a Julian Day number into *prNow and
-** return 0. Return 1 if the time and date cannot be found.
-*/
-static int unixCurrentTime(sqlite3_vfs *NotUsed, double *prNow){
-#if defined(SQLITE_OMIT_FLOATING_POINT)
- time_t t;
- time(&t);
- *prNow = (((sqlite3_int64)t)/8640 + 24405875)/10;
-#elif defined(NO_GETTOD)
- time_t t;
- time(&t);
- *prNow = t/86400.0 + 2440587.5;
-#elif OS_VXWORKS
- struct timespec sNow;
- clock_gettime(CLOCK_REALTIME, &sNow);
- *prNow = 2440587.5 + sNow.tv_sec/86400.0 + sNow.tv_nsec/86400000000000.0;
-#else
- struct timeval sNow;
- gettimeofday(&sNow, 0);
- *prNow = 2440587.5 + sNow.tv_sec/86400.0 + sNow.tv_usec/86400000000.0;
-#endif
-
-#ifdef SQLITE_TEST
- if( sqlite3_current_time ){
- *prNow = sqlite3_current_time/86400.0 + 2440587.5;
- }
-#endif
- UNUSED_PARAMETER(NotUsed);
- return 0;
-}
-
-/*
-** We added the xGetLastError() method with the intention of providing
-** better low-level error messages when operating-system problems come up
-** during SQLite operation. But so far, none of that has been implemented
-** in the core. So this routine is never called. For now, it is merely
-** a place-holder.
-*/
-static int unixGetLastError(sqlite3_vfs *NotUsed, int NotUsed2, char *NotUsed3){
- UNUSED_PARAMETER(NotUsed);
- UNUSED_PARAMETER(NotUsed2);
- UNUSED_PARAMETER(NotUsed3);
- return 0;
-}
-
-/*
-************************ End of sqlite3_vfs methods ***************************
-******************************************************************************/
-
-/******************************************************************************
-************************** Begin Proxy Locking ********************************
-**
-** Proxy locking is a "uber-locking-method" in this sense: It uses the
-** other locking methods on secondary lock files. Proxy locking is a
-** meta-layer over top of the primitive locking implemented above. For
-** this reason, the division that implements of proxy locking is deferred
-** until late in the file (here) after all of the other I/O methods have
-** been defined - so that the primitive locking methods are available
-** as services to help with the implementation of proxy locking.
-**
-****
-**
-** The default locking schemes in SQLite use byte-range locks on the
-** database file to coordinate safe, concurrent access by multiple readers
-** and writers [http://sqlite.org/lockingv3.html]. The five file locking
-** states (UNLOCKED, PENDING, SHARED, RESERVED, EXCLUSIVE) are implemented
-** as POSIX read & write locks over fixed set of locations (via fsctl),
-** on AFP and SMB only exclusive byte-range locks are available via fsctl
-** with _IOWR('z', 23, struct ByteRangeLockPB2) to track the same 5 states.
-** To simulate a F_RDLCK on the shared range, on AFP a randomly selected
-** address in the shared range is taken for a SHARED lock, the entire
-** shared range is taken for an EXCLUSIVE lock):
-**
-** PENDING_BYTE 0x40000000
-** RESERVED_BYTE 0x40000001
-** SHARED_RANGE 0x40000002 -> 0x40000200
-**
-** This works well on the local file system, but shows a nearly 100x
-** slowdown in read performance on AFP because the AFP client disables
-** the read cache when byte-range locks are present. Enabling the read
-** cache exposes a cache coherency problem that is present on all OS X
-** supported network file systems. NFS and AFP both observe the
-** close-to-open semantics for ensuring cache coherency
-** [http://nfs.sourceforge.net/#faq_a8], which does not effectively
-** address the requirements for concurrent database access by multiple
-** readers and writers
-** [http://www.nabble.com/SQLite-on-NFS-cache-coherency-td15655701.html].
-**
-** To address the performance and cache coherency issues, proxy file locking
-** changes the way database access is controlled by limiting access to a
-** single host at a time and moving file locks off of the database file
-** and onto a proxy file on the local file system.
-**
-**
-** Using proxy locks
-** -----------------
-**
-** C APIs
-**
-** sqlite3_file_control(db, dbname, SQLITE_SET_LOCKPROXYFILE,
-** <proxy_path> | ":auto:");
-** sqlite3_file_control(db, dbname, SQLITE_GET_LOCKPROXYFILE, &<proxy_path>);
-**
-**
-** SQL pragmas
-**
-** PRAGMA [database.]lock_proxy_file=<proxy_path> | :auto:
-** PRAGMA [database.]lock_proxy_file
-**
-** Specifying ":auto:" means that if there is a conch file with a matching
-** host ID in it, the proxy path in the conch file will be used, otherwise
-** a proxy path based on the user's temp dir
-** (via confstr(_CS_DARWIN_USER_TEMP_DIR,...)) will be used and the
-** actual proxy file name is generated from the name and path of the
-** database file. For example:
-**
-** For database path "/Users/me/foo.db"
-** The lock path will be "<tmpdir>/sqliteplocks/_Users_me_foo.db:auto:")
-**
-** Once a lock proxy is configured for a database connection, it can not
-** be removed, however it may be switched to a different proxy path via
-** the above APIs (assuming the conch file is not being held by another
-** connection or process).
-**
-**
-** How proxy locking works
-** -----------------------
-**
-** Proxy file locking relies primarily on two new supporting files:
-**
-** * conch file to limit access to the database file to a single host
-** at a time
-**
-** * proxy file to act as a proxy for the advisory locks normally
-** taken on the database
-**
-** The conch file - to use a proxy file, sqlite must first "hold the conch"
-** by taking an sqlite-style shared lock on the conch file, reading the
-** contents and comparing the host's unique host ID (see below) and lock
-** proxy path against the values stored in the conch. The conch file is
-** stored in the same directory as the database file and the file name
-** is patterned after the database file name as ".<databasename>-conch".
-** If the conch file does not exist, or it's contents do not match the
-** host ID and/or proxy path, then the lock is escalated to an exclusive
-** lock and the conch file contents is updated with the host ID and proxy
-** path and the lock is downgraded to a shared lock again. If the conch
-** is held by another process (with a shared lock), the exclusive lock
-** will fail and SQLITE_BUSY is returned.
-**
-** The proxy file - a single-byte file used for all advisory file locks
-** normally taken on the database file. This allows for safe sharing
-** of the database file for multiple readers and writers on the same
-** host (the conch ensures that they all use the same local lock file).
-**
-** There is a third file - the host ID file - used as a persistent record
-** of a unique identifier for the host, a 128-byte unique host id file
-** in the path defined by the HOSTIDPATH macro (default value is
-** /Library/Caches/.com.apple.sqliteConchHostId).
-**
-** Requesting the lock proxy does not immediately take the conch, it is
-** only taken when the first request to lock database file is made.
-** This matches the semantics of the traditional locking behavior, where
-** opening a connection to a database file does not take a lock on it.
-** The shared lock and an open file descriptor are maintained until
-** the connection to the database is closed.
-**
-** The proxy file and the lock file are never deleted so they only need
-** to be created the first time they are used.
-**
-** Configuration options
-** ---------------------
-**
-** SQLITE_PREFER_PROXY_LOCKING
-**
-** Database files accessed on non-local file systems are
-** automatically configured for proxy locking, lock files are
-** named automatically using the same logic as
-** PRAGMA lock_proxy_file=":auto:"
-**
-** SQLITE_PROXY_DEBUG
-**
-** Enables the logging of error messages during host id file
-** retrieval and creation
-**
-** HOSTIDPATH
-**
-** Overrides the default host ID file path location
-**
-** LOCKPROXYDIR
-**
-** Overrides the default directory used for lock proxy files that
-** are named automatically via the ":auto:" setting
-**
-** SQLITE_DEFAULT_PROXYDIR_PERMISSIONS
-**
-** Permissions to use when creating a directory for storing the
-** lock proxy files, only used when LOCKPROXYDIR is not set.
-**
-**
-** As mentioned above, when compiled with SQLITE_PREFER_PROXY_LOCKING,
-** setting the environment variable SQLITE_FORCE_PROXY_LOCKING to 1 will
-** force proxy locking to be used for every database file opened, and 0
-** will force automatic proxy locking to be disabled for all database
-** files (explicity calling the SQLITE_SET_LOCKPROXYFILE pragma or
-** sqlite_file_control API is not affected by SQLITE_FORCE_PROXY_LOCKING).
-*/
-
-/*
-** Proxy locking is only available on MacOSX
-*/
-#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE
-
-#ifdef SQLITE_TEST
-/* simulate multiple hosts by creating unique hostid file paths */
-SQLITE_API int sqlite3_hostid_num = 0;
-#endif
-
-/*
-** The proxyLockingContext has the path and file structures for the remote
-** and local proxy files in it
-*/
-typedef struct proxyLockingContext proxyLockingContext;
-struct proxyLockingContext {
- unixFile *conchFile; /* Open conch file */
- char *conchFilePath; /* Name of the conch file */
- unixFile *lockProxy; /* Open proxy lock file */
- char *lockProxyPath; /* Name of the proxy lock file */
- char *dbPath; /* Name of the open file */
- int conchHeld; /* True if the conch is currently held */
- void *oldLockingContext; /* Original lockingcontext to restore on close */
- sqlite3_io_methods const *pOldMethod; /* Original I/O methods for close */
-};
-
-/* HOSTIDLEN and CONCHLEN both include space for the string
-** terminating nul
-*/
-#define HOSTIDLEN 128
-#define CONCHLEN (MAXPATHLEN+HOSTIDLEN+1)
-#ifndef HOSTIDPATH
-# define HOSTIDPATH "/Library/Caches/.com.apple.sqliteConchHostId"
-#endif
-
-/* basically a copy of unixRandomness with different
-** test behavior built in */
-static int proxyGenerateHostID(char *pHostID){
- int pid, fd, len;
- unsigned char *key = (unsigned char *)pHostID;
-
- memset(key, 0, HOSTIDLEN);
- len = 0;
- fd = open("/dev/urandom", O_RDONLY);
- if( fd>=0 ){
- len = read(fd, key, HOSTIDLEN);
- close(fd); /* silently leak the fd if it fails */
- }
- if( len < HOSTIDLEN ){
- time_t t;
- time(&t);
- memcpy(key, &t, sizeof(t));
- pid = getpid();
- memcpy(&key[sizeof(t)], &pid, sizeof(pid));
- }
-
-#ifdef MAKE_PRETTY_HOSTID
- {
- int i;
- /* filter the bytes into printable ascii characters and NUL terminate */
- key[(HOSTIDLEN-1)] = 0x00;
- for( i=0; i<(HOSTIDLEN-1); i++ ){
- unsigned char pa = key[i]&0x7F;
- if( pa<0x20 ){
- key[i] = (key[i]&0x80 == 0x80) ? pa+0x40 : pa+0x20;
- }else if( pa==0x7F ){
- key[i] = (key[i]&0x80 == 0x80) ? pa=0x20 : pa+0x7E;
- }
- }
- }
-#endif
- return SQLITE_OK;
-}
-
-/* writes the host id path to path, path should be an pre-allocated buffer
-** with enough space for a path
-*/
-static void proxyGetHostIDPath(char *path, size_t len){
- strlcpy(path, HOSTIDPATH, len);
-#ifdef SQLITE_TEST
- if( sqlite3_hostid_num>0 ){
- char suffix[2] = "1";
- suffix[0] = suffix[0] + sqlite3_hostid_num;
- strlcat(path, suffix, len);
- }
-#endif
- OSTRACE3("GETHOSTIDPATH %s pid=%d\n", path, getpid());
-}
-
-/* get the host ID from a sqlite hostid file stored in the
-** user-specific tmp directory, create the ID if it's not there already
-*/
-static int proxyGetHostID(char *pHostID, int *pError){
- int fd;
- char path[MAXPATHLEN];
- size_t len;
- int rc=SQLITE_OK;
-
- proxyGetHostIDPath(path, MAXPATHLEN);
- /* try to create the host ID file, if it already exists read the contents */
- fd = open(path, O_CREAT|O_WRONLY|O_EXCL, 0644);
- if( fd<0 ){
- int err=errno;
-
- if( err!=EEXIST ){
-#ifdef SQLITE_PROXY_DEBUG /* set the sqlite error message instead */
- fprintf(stderr, "sqlite error creating host ID file %s: %s\n",
- path, strerror(err));
-#endif
- return SQLITE_PERM;
- }
- /* couldn't create the file, read it instead */
- fd = open(path, O_RDONLY|O_EXCL);
- if( fd<0 ){
-#ifdef SQLITE_PROXY_DEBUG /* set the sqlite error message instead */
- int err = errno;
- fprintf(stderr, "sqlite error opening host ID file %s: %s\n",
- path, strerror(err));
-#endif
- return SQLITE_PERM;
- }
- len = pread(fd, pHostID, HOSTIDLEN, 0);
- if( len<0 ){
- *pError = errno;
- rc = SQLITE_IOERR_READ;
- }else if( len<HOSTIDLEN ){
- *pError = 0;
- rc = SQLITE_IOERR_SHORT_READ;
- }
- close(fd); /* silently leak the fd if it fails */
- OSTRACE3("GETHOSTID read %s pid=%d\n", pHostID, getpid());
- return rc;
- }else{
- /* we're creating the host ID file (use a random string of bytes) */
- proxyGenerateHostID(pHostID);
- len = pwrite(fd, pHostID, HOSTIDLEN, 0);
- if( len<0 ){
- *pError = errno;
- rc = SQLITE_IOERR_WRITE;
- }else if( len<HOSTIDLEN ){
- *pError = 0;
- rc = SQLITE_IOERR_WRITE;
- }
- close(fd); /* silently leak the fd if it fails */
- OSTRACE3("GETHOSTID wrote %s pid=%d\n", pHostID, getpid());
- return rc;
- }
-}
-
-static int proxyGetLockPath(const char *dbPath, char *lPath, size_t maxLen){
- int len;
- int dbLen;
- int i;
-
-#ifdef LOCKPROXYDIR
- len = strlcpy(lPath, LOCKPROXYDIR, maxLen);
-#else
-# ifdef _CS_DARWIN_USER_TEMP_DIR
- {
- confstr(_CS_DARWIN_USER_TEMP_DIR, lPath, maxLen);
- len = strlcat(lPath, "sqliteplocks", maxLen);
- if( mkdir(lPath, SQLITE_DEFAULT_PROXYDIR_PERMISSIONS) ){
- /* if mkdir fails, handle as lock file creation failure */
-# ifdef SQLITE_DEBUG
- int err = errno;
- if( err!=EEXIST ){
- fprintf(stderr, "proxyGetLockPath: mkdir(%s,0%o) error %d %s\n", lPath,
- SQLITE_DEFAULT_PROXYDIR_PERMISSIONS, err, strerror(err));
- }
-# endif
- }else{
- OSTRACE3("GETLOCKPATH mkdir %s pid=%d\n", lPath, getpid());
- }
-
- }
-# else
- len = strlcpy(lPath, "/tmp/", maxLen);
-# endif
-#endif
-
- if( lPath[len-1]!='/' ){
- len = strlcat(lPath, "/", maxLen);
- }
-
- /* transform the db path to a unique cache name */
- dbLen = (int)strlen(dbPath);
- for( i=0; i<dbLen && (i+len+7)<maxLen; i++){
- char c = dbPath[i];
- lPath[i+len] = (c=='/')?'_':c;
- }
- lPath[i+len]='\0';
- strlcat(lPath, ":auto:", maxLen);
- return SQLITE_OK;
-}
-
-/*
-** Create a new VFS file descriptor (stored in memory obtained from
-** sqlite3_malloc) and open the file named "path" in the file descriptor.
-**
-** The caller is responsible not only for closing the file descriptor
-** but also for freeing the memory associated with the file descriptor.
-*/
-static int proxyCreateUnixFile(const char *path, unixFile **ppFile) {
- unixFile *pNew;
- int flags = SQLITE_OPEN_MAIN_DB|SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE;
- int rc = SQLITE_OK;
- sqlite3_vfs dummyVfs;
-
- pNew = (unixFile *)sqlite3_malloc(sizeof(unixFile));
- if( !pNew ){
- return SQLITE_NOMEM;
- }
- memset(pNew, 0, sizeof(unixFile));
-
- /* Call unixOpen() to open the proxy file. The flags passed to unixOpen()
- ** suggest that the file being opened is a "main database". This is
- ** necessary as other file types do not necessarily support locking. It
- ** is better to use unixOpen() instead of opening the file directly with
- ** open(), as unixOpen() sets up the various mechanisms required to
- ** make sure a call to close() does not cause the system to discard
- ** POSIX locks prematurely.
- **
- ** It is important that the xOpen member of the VFS object passed to
- ** unixOpen() is NULL. This tells unixOpen() may try to open a proxy-file
- ** for the proxy-file (creating a potential infinite loop).
- */
- dummyVfs.pAppData = (void*)&autolockIoFinder;
- dummyVfs.xOpen = 0;
- rc = unixOpen(&dummyVfs, path, (sqlite3_file *)pNew, flags, &flags);
- if( rc==SQLITE_OK && (flags&SQLITE_OPEN_READONLY) ){
- pNew->pMethod->xClose((sqlite3_file *)pNew);
- rc = SQLITE_CANTOPEN;
- }
-
- if( rc!=SQLITE_OK ){
- sqlite3_free(pNew);
- pNew = 0;
- }
-
- *ppFile = pNew;
- return rc;
-}
-
-/* takes the conch by taking a shared lock and read the contents conch, if
-** lockPath is non-NULL, the host ID and lock file path must match. A NULL
-** lockPath means that the lockPath in the conch file will be used if the
-** host IDs match, or a new lock path will be generated automatically
-** and written to the conch file.
-*/
-static int proxyTakeConch(unixFile *pFile){
- proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext;
-
- if( pCtx->conchHeld>0 ){
- return SQLITE_OK;
- }else{
- unixFile *conchFile = pCtx->conchFile;
- char testValue[CONCHLEN];
- char conchValue[CONCHLEN];
- char lockPath[MAXPATHLEN];
- char *tLockPath = NULL;
- int rc = SQLITE_OK;
- int readRc = SQLITE_OK;
- int syncPerms = 0;
-
- OSTRACE4("TAKECONCH %d for %s pid=%d\n", conchFile->h,
- (pCtx->lockProxyPath ? pCtx->lockProxyPath : ":auto:"), getpid());
-
- rc = conchFile->pMethod->xLock((sqlite3_file*)conchFile, SHARED_LOCK);
- if( rc==SQLITE_OK ){
- int pError = 0;
- memset(testValue, 0, CONCHLEN); /* conch is fixed size */
- rc = proxyGetHostID(testValue, &pError);
- if( (rc&0xff)==SQLITE_IOERR ){
- pFile->lastErrno = pError;
- }
- if( pCtx->lockProxyPath ){
- strlcpy(&testValue[HOSTIDLEN], pCtx->lockProxyPath, MAXPATHLEN);
- }
- }
- if( rc!=SQLITE_OK ){
- goto end_takeconch;
- }
-
- readRc = unixRead((sqlite3_file *)conchFile, conchValue, CONCHLEN, 0);
- if( readRc!=SQLITE_IOERR_SHORT_READ ){
- if( readRc!=SQLITE_OK ){
- if( (rc&0xff)==SQLITE_IOERR ){
- pFile->lastErrno = conchFile->lastErrno;
- }
- rc = readRc;
- goto end_takeconch;
- }
- /* if the conch has data compare the contents */
- if( !pCtx->lockProxyPath ){
- /* for auto-named local lock file, just check the host ID and we'll
- ** use the local lock file path that's already in there */
- if( !memcmp(testValue, conchValue, HOSTIDLEN) ){
- tLockPath = (char *)&conchValue[HOSTIDLEN];
- goto end_takeconch;
- }
- }else{
- /* we've got the conch if conchValue matches our path and host ID */
- if( !memcmp(testValue, conchValue, CONCHLEN) ){
- goto end_takeconch;
- }
- }
- }else{
- /* a short read means we're "creating" the conch (even though it could
- ** have been user-intervention), if we acquire the exclusive lock,
- ** we'll try to match the current on-disk permissions of the database
- */
- syncPerms = 1;
- }
-
- /* either conch was emtpy or didn't match */
- if( !pCtx->lockProxyPath ){
- proxyGetLockPath(pCtx->dbPath, lockPath, MAXPATHLEN);
- tLockPath = lockPath;
- strlcpy(&testValue[HOSTIDLEN], lockPath, MAXPATHLEN);
- }
-
- /* update conch with host and path (this will fail if other process
- ** has a shared lock already) */
- rc = conchFile->pMethod->xLock((sqlite3_file*)conchFile, EXCLUSIVE_LOCK);
- if( rc==SQLITE_OK ){
- rc = unixWrite((sqlite3_file *)conchFile, testValue, CONCHLEN, 0);
- if( rc==SQLITE_OK && syncPerms ){
- struct stat buf;
- int err = fstat(pFile->h, &buf);
- if( err==0 ){
- /* try to match the database file permissions, ignore failure */
-#ifndef SQLITE_PROXY_DEBUG
- fchmod(conchFile->h, buf.st_mode);
-#else
- if( fchmod(conchFile->h, buf.st_mode)!=0 ){
- int code = errno;
- fprintf(stderr, "fchmod %o FAILED with %d %s\n",
- buf.st_mode, code, strerror(code));
- } else {
- fprintf(stderr, "fchmod %o SUCCEDED\n",buf.st_mode);
- }
- }else{
- int code = errno;
- fprintf(stderr, "STAT FAILED[%d] with %d %s\n",
- err, code, strerror(code));
-#endif
- }
- }
- }
- conchFile->pMethod->xUnlock((sqlite3_file*)conchFile, SHARED_LOCK);
-
-end_takeconch:
- OSTRACE2("TRANSPROXY: CLOSE %d\n", pFile->h);
- if( rc==SQLITE_OK && pFile->openFlags ){
- if( pFile->h>=0 ){
-#ifdef STRICT_CLOSE_ERROR
- if( close(pFile->h) ){
- pFile->lastErrno = errno;
- return SQLITE_IOERR_CLOSE;
- }
-#else
- close(pFile->h); /* silently leak fd if fail */
-#endif
- }
- pFile->h = -1;
- int fd = open(pCtx->dbPath, pFile->openFlags,
- SQLITE_DEFAULT_FILE_PERMISSIONS);
- OSTRACE2("TRANSPROXY: OPEN %d\n", fd);
- if( fd>=0 ){
- pFile->h = fd;
- }else{
- rc=SQLITE_CANTOPEN; /* SQLITE_BUSY? proxyTakeConch called
- during locking */
- }
- }
- if( rc==SQLITE_OK && !pCtx->lockProxy ){
- char *path = tLockPath ? tLockPath : pCtx->lockProxyPath;
- /* ACS: Need to make a copy of path sometimes */
- rc = proxyCreateUnixFile(path, &pCtx->lockProxy);
- }
- if( rc==SQLITE_OK ){
- pCtx->conchHeld = 1;
-
- if( tLockPath ){
- pCtx->lockProxyPath = sqlite3DbStrDup(0, tLockPath);
- if( pCtx->lockProxy->pMethod == &afpIoMethods ){
- ((afpLockingContext *)pCtx->lockProxy->lockingContext)->dbPath =
- pCtx->lockProxyPath;
- }
- }
- } else {
- conchFile->pMethod->xUnlock((sqlite3_file*)conchFile, NO_LOCK);
- }
- OSTRACE3("TAKECONCH %d %s\n", conchFile->h, rc==SQLITE_OK?"ok":"failed");
- return rc;
- }
-}
-
-/*
-** If pFile holds a lock on a conch file, then release that lock.
-*/
-static int proxyReleaseConch(unixFile *pFile){
- int rc; /* Subroutine return code */
- proxyLockingContext *pCtx; /* The locking context for the proxy lock */
- unixFile *conchFile; /* Name of the conch file */
-
- pCtx = (proxyLockingContext *)pFile->lockingContext;
- conchFile = pCtx->conchFile;
- OSTRACE4("RELEASECONCH %d for %s pid=%d\n", conchFile->h,
- (pCtx->lockProxyPath ? pCtx->lockProxyPath : ":auto:"),
- getpid());
- pCtx->conchHeld = 0;
- rc = conchFile->pMethod->xUnlock((sqlite3_file*)conchFile, NO_LOCK);
- OSTRACE3("RELEASECONCH %d %s\n", conchFile->h,
- (rc==SQLITE_OK ? "ok" : "failed"));
- return rc;
-}
-
-/*
-** Given the name of a database file, compute the name of its conch file.
-** Store the conch filename in memory obtained from sqlite3_malloc().
-** Make *pConchPath point to the new name. Return SQLITE_OK on success
-** or SQLITE_NOMEM if unable to obtain memory.
-**
-** The caller is responsible for ensuring that the allocated memory
-** space is eventually freed.
-**
-** *pConchPath is set to NULL if a memory allocation error occurs.
-*/
-static int proxyCreateConchPathname(char *dbPath, char **pConchPath){
- int i; /* Loop counter */
- int len = (int)strlen(dbPath); /* Length of database filename - dbPath */
- char *conchPath; /* buffer in which to construct conch name */
-
- /* Allocate space for the conch filename and initialize the name to
- ** the name of the original database file. */
- *pConchPath = conchPath = (char *)sqlite3_malloc(len + 8);
- if( conchPath==0 ){
- return SQLITE_NOMEM;
- }
- memcpy(conchPath, dbPath, len+1);
-
- /* now insert a "." before the last / character */
- for( i=(len-1); i>=0; i-- ){
- if( conchPath[i]=='/' ){
- i++;
- break;
- }
- }
- conchPath[i]='.';
- while ( i<len ){
- conchPath[i+1]=dbPath[i];
- i++;
- }
-
- /* append the "-conch" suffix to the file */
- memcpy(&conchPath[i+1], "-conch", 7);
- assert( (int)strlen(conchPath) == len+7 );
-
- return SQLITE_OK;
-}
-
-
-/* Takes a fully configured proxy locking-style unix file and switches
-** the local lock file path
-*/
-static int switchLockProxyPath(unixFile *pFile, const char *path) {
- proxyLockingContext *pCtx = (proxyLockingContext*)pFile->lockingContext;
- char *oldPath = pCtx->lockProxyPath;
- int rc = SQLITE_OK;
-
- if( pFile->locktype!=NO_LOCK ){
- return SQLITE_BUSY;
- }
-
- /* nothing to do if the path is NULL, :auto: or matches the existing path */
- if( !path || path[0]=='\0' || !strcmp(path, ":auto:") ||
- (oldPath && !strncmp(oldPath, path, MAXPATHLEN)) ){
- return SQLITE_OK;
- }else{
- unixFile *lockProxy = pCtx->lockProxy;
- pCtx->lockProxy=NULL;
- pCtx->conchHeld = 0;
- if( lockProxy!=NULL ){
- rc=lockProxy->pMethod->xClose((sqlite3_file *)lockProxy);
- if( rc ) return rc;
- sqlite3_free(lockProxy);
- }
- sqlite3_free(oldPath);
- pCtx->lockProxyPath = sqlite3DbStrDup(0, path);
- }
-
- return rc;
-}
-
-/*
-** pFile is a file that has been opened by a prior xOpen call. dbPath
-** is a string buffer at least MAXPATHLEN+1 characters in size.
-**
-** This routine find the filename associated with pFile and writes it
-** int dbPath.
-*/
-static int proxyGetDbPathForUnixFile(unixFile *pFile, char *dbPath){
-#if defined(__APPLE__)
- if( pFile->pMethod == &afpIoMethods ){
- /* afp style keeps a reference to the db path in the filePath field
- ** of the struct */
- assert( (int)strlen((char*)pFile->lockingContext)<=MAXPATHLEN );
- strcpy(dbPath, ((afpLockingContext *)pFile->lockingContext)->dbPath);
- }else
-#endif
- if( pFile->pMethod == &dotlockIoMethods ){
- /* dot lock style uses the locking context to store the dot lock
- ** file path */
- int len = strlen((char *)pFile->lockingContext) - strlen(DOTLOCK_SUFFIX);
- memcpy(dbPath, (char *)pFile->lockingContext, len + 1);
- }else{
- /* all other styles use the locking context to store the db file path */
- assert( strlen((char*)pFile->lockingContext)<=MAXPATHLEN );
- strcpy(dbPath, (char *)pFile->lockingContext);
- }
- return SQLITE_OK;
-}
-
-/*
-** Takes an already filled in unix file and alters it so all file locking
-** will be performed on the local proxy lock file. The following fields
-** are preserved in the locking context so that they can be restored and
-** the unix structure properly cleaned up at close time:
-** ->lockingContext
-** ->pMethod
-*/
-static int proxyTransformUnixFile(unixFile *pFile, const char *path) {
- proxyLockingContext *pCtx;
- char dbPath[MAXPATHLEN+1]; /* Name of the database file */
- char *lockPath=NULL;
- int rc = SQLITE_OK;
-
- if( pFile->locktype!=NO_LOCK ){
- return SQLITE_BUSY;
- }
- proxyGetDbPathForUnixFile(pFile, dbPath);
- if( !path || path[0]=='\0' || !strcmp(path, ":auto:") ){
- lockPath=NULL;
- }else{
- lockPath=(char *)path;
- }
-
- OSTRACE4("TRANSPROXY %d for %s pid=%d\n", pFile->h,
- (lockPath ? lockPath : ":auto:"), getpid());
-
- pCtx = sqlite3_malloc( sizeof(*pCtx) );
- if( pCtx==0 ){
- return SQLITE_NOMEM;
- }
- memset(pCtx, 0, sizeof(*pCtx));
-
- rc = proxyCreateConchPathname(dbPath, &pCtx->conchFilePath);
- if( rc==SQLITE_OK ){
- rc = proxyCreateUnixFile(pCtx->conchFilePath, &pCtx->conchFile);
- }
- if( rc==SQLITE_OK && lockPath ){
- pCtx->lockProxyPath = sqlite3DbStrDup(0, lockPath);
- }
-
- if( rc==SQLITE_OK ){
- /* all memory is allocated, proxys are created and assigned,
- ** switch the locking context and pMethod then return.
- */
- pCtx->dbPath = sqlite3DbStrDup(0, dbPath);
- pCtx->oldLockingContext = pFile->lockingContext;
- pFile->lockingContext = pCtx;
- pCtx->pOldMethod = pFile->pMethod;
- pFile->pMethod = &proxyIoMethods;
- }else{
- if( pCtx->conchFile ){
- rc = pCtx->conchFile->pMethod->xClose((sqlite3_file *)pCtx->conchFile);
- if( rc ) return rc;
- sqlite3_free(pCtx->conchFile);
- }
- sqlite3_free(pCtx->conchFilePath);
- sqlite3_free(pCtx);
- }
- OSTRACE3("TRANSPROXY %d %s\n", pFile->h,
- (rc==SQLITE_OK ? "ok" : "failed"));
- return rc;
-}
-
-
-/*
-** This routine handles sqlite3_file_control() calls that are specific
-** to proxy locking.
-*/
-static int proxyFileControl(sqlite3_file *id, int op, void *pArg){
- switch( op ){
- case SQLITE_GET_LOCKPROXYFILE: {
- unixFile *pFile = (unixFile*)id;
- if( pFile->pMethod == &proxyIoMethods ){
- proxyLockingContext *pCtx = (proxyLockingContext*)pFile->lockingContext;
- proxyTakeConch(pFile);
- if( pCtx->lockProxyPath ){
- *(const char **)pArg = pCtx->lockProxyPath;
- }else{
- *(const char **)pArg = ":auto: (not held)";
- }
- } else {
- *(const char **)pArg = NULL;
- }
- return SQLITE_OK;
- }
- case SQLITE_SET_LOCKPROXYFILE: {
- unixFile *pFile = (unixFile*)id;
- int rc = SQLITE_OK;
- int isProxyStyle = (pFile->pMethod == &proxyIoMethods);
- if( pArg==NULL || (const char *)pArg==0 ){
- if( isProxyStyle ){
- /* turn off proxy locking - not supported */
- rc = SQLITE_ERROR /*SQLITE_PROTOCOL? SQLITE_MISUSE?*/;
- }else{
- /* turn off proxy locking - already off - NOOP */
- rc = SQLITE_OK;
- }
- }else{
- const char *proxyPath = (const char *)pArg;
- if( isProxyStyle ){
- proxyLockingContext *pCtx =
- (proxyLockingContext*)pFile->lockingContext;
- if( !strcmp(pArg, ":auto:")
- || (pCtx->lockProxyPath &&
- !strncmp(pCtx->lockProxyPath, proxyPath, MAXPATHLEN))
- ){
- rc = SQLITE_OK;
- }else{
- rc = switchLockProxyPath(pFile, proxyPath);
- }
- }else{
- /* turn on proxy file locking */
- rc = proxyTransformUnixFile(pFile, proxyPath);
- }
- }
- return rc;
- }
- default: {
- assert( 0 ); /* The call assures that only valid opcodes are sent */
- }
- }
- /*NOTREACHED*/
- return SQLITE_ERROR;
-}
-
-/*
-** Within this division (the proxying locking implementation) the procedures
-** above this point are all utilities. The lock-related methods of the
-** proxy-locking sqlite3_io_method object follow.
-*/
-
-
-/*
-** This routine checks if there is a RESERVED lock held on the specified
-** file by this or any other process. If such a lock is held, set *pResOut
-** to a non-zero value otherwise *pResOut is set to zero. The return value
-** is set to SQLITE_OK unless an I/O error occurs during lock checking.
-*/
-static int proxyCheckReservedLock(sqlite3_file *id, int *pResOut) {
- unixFile *pFile = (unixFile*)id;
- int rc = proxyTakeConch(pFile);
- if( rc==SQLITE_OK ){
- proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext;
- unixFile *proxy = pCtx->lockProxy;
- return proxy->pMethod->xCheckReservedLock((sqlite3_file*)proxy, pResOut);
- }
- return rc;
-}
-
-/*
-** Lock the file with the lock specified by parameter locktype - one
-** of the following:
-**
-** (1) SHARED_LOCK
-** (2) RESERVED_LOCK
-** (3) PENDING_LOCK
-** (4) EXCLUSIVE_LOCK
-**
-** Sometimes when requesting one lock state, additional lock states
-** are inserted in between. The locking might fail on one of the later
-** transitions leaving the lock state different from what it started but
-** still short of its goal. The following chart shows the allowed
-** transitions and the inserted intermediate states:
-**
-** UNLOCKED -> SHARED
-** SHARED -> RESERVED
-** SHARED -> (PENDING) -> EXCLUSIVE
-** RESERVED -> (PENDING) -> EXCLUSIVE
-** PENDING -> EXCLUSIVE
-**
-** This routine will only increase a lock. Use the sqlite3OsUnlock()
-** routine to lower a locking level.
-*/
-static int proxyLock(sqlite3_file *id, int locktype) {
- unixFile *pFile = (unixFile*)id;
- int rc = proxyTakeConch(pFile);
- if( rc==SQLITE_OK ){
- proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext;
- unixFile *proxy = pCtx->lockProxy;
- rc = proxy->pMethod->xLock((sqlite3_file*)proxy, locktype);
- pFile->locktype = proxy->locktype;
- }
- return rc;
-}
-
-
-/*
-** Lower the locking level on file descriptor pFile to locktype. locktype
-** must be either NO_LOCK or SHARED_LOCK.
-**
-** If the locking level of the file descriptor is already at or below
-** the requested locking level, this routine is a no-op.
-*/
-static int proxyUnlock(sqlite3_file *id, int locktype) {
- unixFile *pFile = (unixFile*)id;
- int rc = proxyTakeConch(pFile);
- if( rc==SQLITE_OK ){
- proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext;
- unixFile *proxy = pCtx->lockProxy;
- rc = proxy->pMethod->xUnlock((sqlite3_file*)proxy, locktype);
- pFile->locktype = proxy->locktype;
- }
- return rc;
-}
-
-/*
-** Close a file that uses proxy locks.
-*/
-static int proxyClose(sqlite3_file *id) {
- if( id ){
- unixFile *pFile = (unixFile*)id;
- proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext;
- unixFile *lockProxy = pCtx->lockProxy;
- unixFile *conchFile = pCtx->conchFile;
- int rc = SQLITE_OK;
-
- if( lockProxy ){
- rc = lockProxy->pMethod->xUnlock((sqlite3_file*)lockProxy, NO_LOCK);
- if( rc ) return rc;
- rc = lockProxy->pMethod->xClose((sqlite3_file*)lockProxy);
- if( rc ) return rc;
- sqlite3_free(lockProxy);
- pCtx->lockProxy = 0;
- }
- if( conchFile ){
- if( pCtx->conchHeld ){
- rc = proxyReleaseConch(pFile);
- if( rc ) return rc;
- }
- rc = conchFile->pMethod->xClose((sqlite3_file*)conchFile);
- if( rc ) return rc;
- sqlite3_free(conchFile);
- }
- sqlite3_free(pCtx->lockProxyPath);
- sqlite3_free(pCtx->conchFilePath);
- sqlite3_free(pCtx->dbPath);
- /* restore the original locking context and pMethod then close it */
- pFile->lockingContext = pCtx->oldLockingContext;
- pFile->pMethod = pCtx->pOldMethod;
- sqlite3_free(pCtx);
- return pFile->pMethod->xClose(id);
- }
- return SQLITE_OK;
-}
-
-
-
-#endif /* defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE */
-/*
-** The proxy locking style is intended for use with AFP filesystems.
-** And since AFP is only supported on MacOSX, the proxy locking is also
-** restricted to MacOSX.
-**
-**
-******************* End of the proxy lock implementation **********************
-******************************************************************************/
-
-/*
-** Initialize the operating system interface.
-**
-** This routine registers all VFS implementations for unix-like operating
-** systems. This routine, and the sqlite3_os_end() routine that follows,
-** should be the only routines in this file that are visible from other
-** files.
-**
-** This routine is called once during SQLite initialization and by a
-** single thread. The memory allocation and mutex subsystems have not
-** necessarily been initialized when this routine is called, and so they
-** should not be used.
-*/
-SQLITE_API int sqlite3_os_init(void){
- /*
- ** The following macro defines an initializer for an sqlite3_vfs object.
- ** The name of the VFS is NAME. The pAppData is a pointer to a pointer
- ** to the "finder" function. (pAppData is a pointer to a pointer because
- ** silly C90 rules prohibit a void* from being cast to a function pointer
- ** and so we have to go through the intermediate pointer to avoid problems
- ** when compiling with -pedantic-errors on GCC.)
- **
- ** The FINDER parameter to this macro is the name of the pointer to the
- ** finder-function. The finder-function returns a pointer to the
- ** sqlite_io_methods object that implements the desired locking
- ** behaviors. See the division above that contains the IOMETHODS
- ** macro for addition information on finder-functions.
- **
- ** Most finders simply return a pointer to a fixed sqlite3_io_methods
- ** object. But the "autolockIoFinder" available on MacOSX does a little
- ** more than that; it looks at the filesystem type that hosts the
- ** database file and tries to choose an locking method appropriate for
- ** that filesystem time.
- */
- #define UNIXVFS(VFSNAME, FINDER) { \
- 1, /* iVersion */ \
- sizeof(unixFile), /* szOsFile */ \
- MAX_PATHNAME, /* mxPathname */ \
- 0, /* pNext */ \
- VFSNAME, /* zName */ \
- (void*)&FINDER, /* pAppData */ \
- unixOpen, /* xOpen */ \
- unixDelete, /* xDelete */ \
- unixAccess, /* xAccess */ \
- unixFullPathname, /* xFullPathname */ \
- unixDlOpen, /* xDlOpen */ \
- unixDlError, /* xDlError */ \
- unixDlSym, /* xDlSym */ \
- unixDlClose, /* xDlClose */ \
- unixRandomness, /* xRandomness */ \
- unixSleep, /* xSleep */ \
- unixCurrentTime, /* xCurrentTime */ \
- unixGetLastError /* xGetLastError */ \
- }
-
- /*
- ** All default VFSes for unix are contained in the following array.
- **
- ** Note that the sqlite3_vfs.pNext field of the VFS object is modified
- ** by the SQLite core when the VFS is registered. So the following
- ** array cannot be const.
- */
- static sqlite3_vfs aVfs[] = {
-#if SQLITE_ENABLE_LOCKING_STYLE && (OS_VXWORKS || defined(__APPLE__))
- UNIXVFS("unix", autolockIoFinder ),
-#else
- UNIXVFS("unix", posixIoFinder ),
-#endif
- UNIXVFS("unix-none", nolockIoFinder ),
- UNIXVFS("unix-dotfile", dotlockIoFinder ),
- UNIXVFS("unix-wfl", posixWflIoFinder ),
-#if OS_VXWORKS
- UNIXVFS("unix-namedsem", semIoFinder ),
-#endif
-#if SQLITE_ENABLE_LOCKING_STYLE
- UNIXVFS("unix-posix", posixIoFinder ),
-#if !OS_VXWORKS
- UNIXVFS("unix-flock", flockIoFinder ),
-#endif
-#endif
-#if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__)
- UNIXVFS("unix-afp", afpIoFinder ),
- UNIXVFS("unix-proxy", proxyIoFinder ),
-#endif
- };
- unsigned int i; /* Loop counter */
-
- /* Register all VFSes defined in the aVfs[] array */
- for(i=0; i<(sizeof(aVfs)/sizeof(sqlite3_vfs)); i++){
- sqlite3_vfs_register(&aVfs[i], i==0);
- }
- return SQLITE_OK;
-}
-
-/*
-** Shutdown the operating system interface.
-**
-** Some operating systems might need to do some cleanup in this routine,
-** to release dynamically allocated objects. But not on unix.
-** This routine is a no-op for unix.
-*/
-SQLITE_API int sqlite3_os_end(void){
- return SQLITE_OK;
-}
-
-#endif /* SQLITE_OS_UNIX */
-
-/************** End of os_unix.c *********************************************/
-/************** Begin file os_win.c ******************************************/
-/*
-** 2004 May 22
-**
-** 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 code that is specific to windows.
-*/
-#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 <winbase.h>
-
-#ifdef __CYGWIN__
-# include <sys/cygwin.h>
-#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 in the middle of os_win.c ****************/
-/************** Begin file os_common.h ***************************************/
-/*
-** 2004 May 22
-**
-** 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 macros and a little bit of code that is common to
-** all of the platform-specific files (os_*.c) and is #included into those
-** files.
-**
-** This file should be #included by the os_*.c files only. It is not a
-** general purpose header file.
-**
-** $Id: os_common.h,v 1.38 2009/02/24 18:40:50 danielk1977 Exp $
-*/
-#ifndef _OS_COMMON_H_
-#define _OS_COMMON_H_
-
-/*
-** At least two bugs have slipped in because we changed the MEMORY_DEBUG
-** macro to SQLITE_DEBUG and some older makefiles have not yet made the
-** switch. The following code should catch this problem at compile-time.
-*/
-#ifdef MEMORY_DEBUG
-# error "The MEMORY_DEBUG macro is obsolete. Use SQLITE_DEBUG instead."
-#endif
-
-#ifdef SQLITE_DEBUG
-SQLITE_PRIVATE int sqlite3OSTrace = 0;
-#define OSTRACE1(X) if( sqlite3OSTrace ) sqlite3DebugPrintf(X)
-#define OSTRACE2(X,Y) if( sqlite3OSTrace ) sqlite3DebugPrintf(X,Y)
-#define OSTRACE3(X,Y,Z) if( sqlite3OSTrace ) sqlite3DebugPrintf(X,Y,Z)
-#define OSTRACE4(X,Y,Z,A) if( sqlite3OSTrace ) sqlite3DebugPrintf(X,Y,Z,A)
-#define OSTRACE5(X,Y,Z,A,B) if( sqlite3OSTrace ) sqlite3DebugPrintf(X,Y,Z,A,B)
-#define OSTRACE6(X,Y,Z,A,B,C) \
- if(sqlite3OSTrace) sqlite3DebugPrintf(X,Y,Z,A,B,C)
-#define OSTRACE7(X,Y,Z,A,B,C,D) \
- if(sqlite3OSTrace) sqlite3DebugPrintf(X,Y,Z,A,B,C,D)
-#else
-#define OSTRACE1(X)
-#define OSTRACE2(X,Y)
-#define OSTRACE3(X,Y,Z)
-#define OSTRACE4(X,Y,Z,A)
-#define OSTRACE5(X,Y,Z,A,B)
-#define OSTRACE6(X,Y,Z,A,B,C)
-#define OSTRACE7(X,Y,Z,A,B,C,D)
-#endif
-
-/*
-** Macros for performance tracing. Normally turned off. Only works
-** on i486 hardware.
-*/
-#ifdef SQLITE_PERFORMANCE_TRACE
-
-/*
-** hwtime.h contains inline assembler code for implementing
-** high-performance timing routines.
-*/
-/************** Include hwtime.h in the middle of os_common.h ****************/
-/************** Begin file hwtime.h ******************************************/
-/*
-** 2008 May 27
-**
-** 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 inline asm code for retrieving "high-performance"
-** counters for x86 class CPUs.
-**
-** $Id: hwtime.h,v 1.3 2008/08/01 14:33:15 shane Exp $
-*/
-#ifndef _HWTIME_H_
-#define _HWTIME_H_
-
-/*
-** The following routine only works on pentium-class (or newer) processors.
-** It uses the RDTSC opcode to read the cycle count value out of the
-** processor and returns that value. This can be used for high-res
-** profiling.
-*/
-#if (defined(__GNUC__) || defined(_MSC_VER)) && \
- (defined(i386) || defined(__i386__) || defined(_M_IX86))
-
- #if defined(__GNUC__)
-
- __inline__ sqlite_uint64 sqlite3Hwtime(void){
- unsigned int lo, hi;
- __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
- return (sqlite_uint64)hi << 32 | lo;
- }
-
- #elif defined(_MSC_VER)
-
- __declspec(naked) __inline sqlite_uint64 __cdecl sqlite3Hwtime(void){
- __asm {
- rdtsc
- ret ; return value at EDX:EAX
- }
- }
-
- #endif
-
-#elif (defined(__GNUC__) && defined(__x86_64__))
-
- __inline__ sqlite_uint64 sqlite3Hwtime(void){
- unsigned long val;
- __asm__ __volatile__ ("rdtsc" : "=A" (val));
- return val;
- }
-
-#elif (defined(__GNUC__) && defined(__ppc__))
-
- __inline__ sqlite_uint64 sqlite3Hwtime(void){
- unsigned long long retval;
- unsigned long junk;
- __asm__ __volatile__ ("\n\
- 1: mftbu %1\n\
- mftb %L0\n\
- mftbu %0\n\
- cmpw %0,%1\n\
- bne 1b"
- : "=r" (retval), "=r" (junk));
- return retval;
- }
-
-#else
-
- #error Need implementation of sqlite3Hwtime() for your platform.
-
- /*
- ** To compile without implementing sqlite3Hwtime() for your platform,
- ** you can remove the above #error and use the following
- ** stub function. You will lose timing support for many
- ** of the debugging and testing utilities, but it should at
- ** least compile and run.
- */
-SQLITE_PRIVATE sqlite_uint64 sqlite3Hwtime(void){ return ((sqlite_uint64)0); }
-
-#endif
-
-#endif /* !defined(_HWTIME_H_) */
-
-/************** End of hwtime.h **********************************************/
-/************** Continuing where we left off in os_common.h ******************/
-
-static sqlite_uint64 g_start;
-static sqlite_uint64 g_elapsed;
-#define TIMER_START g_start=sqlite3Hwtime()
-#define TIMER_END g_elapsed=sqlite3Hwtime()-g_start
-#define TIMER_ELAPSED g_elapsed
-#else
-#define TIMER_START
-#define TIMER_END
-#define TIMER_ELAPSED ((sqlite_uint64)0)
-#endif
-
-/*
-** If we compile with the SQLITE_TEST macro set, then the following block
-** of code will give us the ability to simulate a disk I/O error. This
-** is used for testing the I/O recovery logic.
-*/
-#ifdef SQLITE_TEST
-SQLITE_API int sqlite3_io_error_hit = 0; /* Total number of I/O Errors */
-SQLITE_API int sqlite3_io_error_hardhit = 0; /* Number of non-benign errors */
-SQLITE_API int sqlite3_io_error_pending = 0; /* Count down to first I/O error */
-SQLITE_API int sqlite3_io_error_persist = 0; /* True if I/O errors persist */
-SQLITE_API int sqlite3_io_error_benign = 0; /* True if errors are benign */
-SQLITE_API int sqlite3_diskfull_pending = 0;
-SQLITE_API int sqlite3_diskfull = 0;
-#define SimulateIOErrorBenign(X) sqlite3_io_error_benign=(X)
-#define SimulateIOError(CODE) \
- if( (sqlite3_io_error_persist && sqlite3_io_error_hit) \
- || sqlite3_io_error_pending-- == 1 ) \
- { local_ioerr(); CODE; }
-static void local_ioerr(){
- IOTRACE(("IOERR\n"));
- sqlite3_io_error_hit++;
- if( !sqlite3_io_error_benign ) sqlite3_io_error_hardhit++;
-}
-#define SimulateDiskfullError(CODE) \
- if( sqlite3_diskfull_pending ){ \
- if( sqlite3_diskfull_pending == 1 ){ \
- local_ioerr(); \
- sqlite3_diskfull = 1; \
- sqlite3_io_error_hit = 1; \
- CODE; \
- }else{ \
- sqlite3_diskfull_pending--; \
- } \
- }
-#else
-#define SimulateIOErrorBenign(X)
-#define SimulateIOError(A)
-#define SimulateDiskfullError(A)
-#endif
-
-/*
-** When testing, keep a count of the number of open files.
-*/
-#ifdef SQLITE_TEST
-SQLITE_API int sqlite3_open_file_count = 0;
-#define OpenCounter(X) sqlite3_open_file_count+=(X)
-#else
-#define OpenCounter(X)
-#endif
-
-#endif /* !defined(_OS_COMMON_H_) */
-
-/************** End of os_common.h *******************************************/
-/************** Continuing where we left off in os_win.c *********************/
-
-/*
-** 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 GetDiskFreeSpaceW() 0
-#endif
-
-/*
-** WinCE lacks native support for file locking so we have to fake it
-** with some code of our own.
-*/
-#if SQLITE_OS_WINCE
-typedef struct winceLock {
- int nReaders; /* Number of reader locks obtained */
- BOOL bPending; /* Indicates a pending lock has been obtained */
- BOOL bReserved; /* Indicates a reserved lock has been obtained */
- BOOL bExclusive; /* Indicates an exclusive lock has been obtained */
-} winceLock;
-#endif
-
-/*
-** The winFile structure is a subclass of sqlite3_file* specific to the win32
-** portability layer.
-*/
-typedef struct winFile winFile;
-struct winFile {
- const sqlite3_io_methods *pMethod;/* Must be first */
- HANDLE h; /* Handle for accessing the file */
- unsigned char locktype; /* Type of lock currently held on this file */
- short sharedLockByte; /* Randomly chosen byte used as a shared lock */
- DWORD lastErrno; /* The Windows errno from the last I/O error */
- DWORD sectorSize; /* Sector size of the device file is on */
-#if SQLITE_OS_WINCE
- WCHAR *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 */
- winceLock *shared; /* Global shared lock memory for the file */
-#endif
-};
-
-/*
-** 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
-** or WinNT.
-**
-** 0: Operating system unknown.
-** 1: Operating system is Win95.
-** 2: Operating system is WinNT.
-**
-** In order to facilitate testing on a WinNT system, the test fixture
-** can manually set this value to 1 to emulate Win98 behavior.
-*/
-#ifdef SQLITE_TEST
-SQLITE_API int sqlite3_os_type = 0;
-#else
-static int sqlite3_os_type = 0;
-#endif
-
-/*
-** Return true (non-zero) if we are running under WinNT, Win2K, WinXP,
-** or WinCE. Return false (zero) for Win95, Win98, or WinME.
-**
-** Here is an interesting observation: Win95, Win98, and WinME lack
-** the LockFileEx() API. But we can still statically link against that
-** API as long as we don't call it when running Win95/98/ME. A call to
-** this routine is used to determine if the host is Win95/98/ME or
-** WinNT/2K/XP so that we will know whether or not we can safely call
-** the LockFileEx() API.
-*/
-#if SQLITE_OS_WINCE
-# define isNT() (1)
-#else
- static int isNT(void){
- if( sqlite3_os_type==0 ){
- OSVERSIONINFO sInfo;
- sInfo.dwOSVersionInfoSize = sizeof(sInfo);
- GetVersionEx(&sInfo);
- sqlite3_os_type = sInfo.dwPlatformId==VER_PLATFORM_WIN32_NT ? 2 : 1;
- }
- return sqlite3_os_type==2;
- }
-#endif /* SQLITE_OS_WINCE */
-
-/*
-** 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){
- int nChar;
- WCHAR *zWideFilename;
-
- nChar = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0);
- zWideFilename = malloc( nChar*sizeof(zWideFilename[0]) );
- if( zWideFilename==0 ){
- return 0;
- }
- nChar = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, zWideFilename, nChar);
- if( nChar==0 ){
- free(zWideFilename);
- zWideFilename = 0;
- }
- return zWideFilename;
-}
-
-/*
-** Convert microsoft unicode to UTF-8. Space to hold the returned string is
-** obtained from malloc().
-*/
-static char *unicodeToUtf8(const WCHAR *zWideFilename){
- int nByte;
- char *zFilename;
-
- nByte = WideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, 0, 0, 0, 0);
- zFilename = malloc( nByte );
- if( zFilename==0 ){
- return 0;
- }
- nByte = WideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, zFilename, nByte,
- 0, 0);
- if( nByte == 0 ){
- free(zFilename);
- zFilename = 0;
- }
- return zFilename;
-}
-
-/*
-** 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.
-*/
-static WCHAR *mbcsToUnicode(const char *zFilename){
- int nByte;
- WCHAR *zMbcsFilename;
- int codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP;
-
- nByte = MultiByteToWideChar(codepage, 0, zFilename, -1, NULL,0)*sizeof(WCHAR);
- zMbcsFilename = malloc( nByte*sizeof(zMbcsFilename[0]) );
- if( zMbcsFilename==0 ){
- return 0;
- }
- nByte = MultiByteToWideChar(codepage, 0, zFilename, -1, zMbcsFilename, nByte);
- if( nByte==0 ){
- free(zMbcsFilename);
- zMbcsFilename = 0;
- }
- return zMbcsFilename;
-}
-
-/*
-** Convert microsoft unicode to multibyte character string, based on the
-** user's Ansi codepage.
-**
-** Space to hold the returned string is obtained from
-** malloc().
-*/
-static char *unicodeToMbcs(const WCHAR *zWideFilename){
- int nByte;
- char *zFilename;
- int codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP;
-
- nByte = WideCharToMultiByte(codepage, 0, zWideFilename, -1, 0, 0, 0, 0);
- zFilename = malloc( nByte );
- if( zFilename==0 ){
- return 0;
- }
- nByte = WideCharToMultiByte(codepage, 0, zWideFilename, -1, zFilename, nByte,
- 0, 0);
- if( nByte == 0 ){
- free(zFilename);
- zFilename = 0;
- }
- return zFilename;
-}
-
-/*
-** Convert multibyte character string to UTF-8. Space to hold the
-** returned string is obtained from malloc().
-*/
-SQLITE_API char *sqlite3_win32_mbcs_to_utf8(const char *zFilename){
- char *zFilenameUtf8;
- WCHAR *zTmpWide;
-
- zTmpWide = mbcsToUnicode(zFilename);
- if( zTmpWide==0 ){
- return 0;
- }
- zFilenameUtf8 = unicodeToUtf8(zTmpWide);
- free(zTmpWide);
- return zFilenameUtf8;
-}
-
-/*
-** Convert UTF-8 to multibyte character string. Space to hold the
-** returned string is obtained from malloc().
-*/
-static char *utf8ToMbcs(const char *zFilename){
- char *zFilenameMbcs;
- WCHAR *zTmpWide;
-
- zTmpWide = utf8ToUnicode(zFilename);
- if( zTmpWide==0 ){
- return 0;
- }
- zFilenameMbcs = unicodeToMbcs(zTmpWide);
- free(zTmpWide);
- return zFilenameMbcs;
-}
-
-#if SQLITE_OS_WINCE
-/*************************************************************************
-** This section contains code for WinCE only.
-*/
-/*
-** WindowsCE does not have a localtime() function. So create a
-** substitute.
-*/
-struct tm *__cdecl localtime(const time_t *t)
-{
- static struct tm y;
- FILETIME uTm, lTm;
- SYSTEMTIME pTm;
- sqlite3_int64 t64;
- t64 = *t;
- t64 = (t64 + 11644473600)*10000000;
- uTm.dwLowDateTime = (DWORD)(t64 & 0xFFFFFFFF);
- uTm.dwHighDateTime= (DWORD)(t64 >> 32);
- FileTimeToLocalFileTime(&uTm,&lTm);
- FileTimeToSystemTime(&lTm,&pTm);
- y.tm_year = pTm.wYear - 1900;
- y.tm_mon = pTm.wMonth - 1;
- y.tm_wday = pTm.wDayOfWeek;
- y.tm_mday = pTm.wDay;
- y.tm_hour = pTm.wHour;
- y.tm_min = pTm.wMinute;
- y.tm_sec = pTm.wSecond;
- 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)]
-
-/*
-** Acquire a lock on the handle h
-*/
-static void winceMutexAcquire(HANDLE h){
- DWORD dwErr;
- do {
- dwErr = WaitForSingleObject(h, INFINITE);
- } while (dwErr != WAIT_OBJECT_0 && dwErr != WAIT_ABANDONED);
-}
-/*
-** Release a lock acquired by winceMutexAcquire()
-*/
-#define winceMutexRelease(h) ReleaseMutex(h)
-
-/*
-** Create the mutex and shared memory used for locking in the file
-** descriptor pFile
-*/
-static BOOL winceCreateLock(const char *zFilename, winFile *pFile){
- WCHAR *zTok;
- WCHAR *zName = utf8ToUnicode(zFilename);
- BOOL bInit = TRUE;
-
- /* Initialize the local lockdata */
- ZeroMemory(&pFile->local, sizeof(pFile->local));
-
- /* Replace the backslashes from the filename and lowercase it
- ** to derive a mutex name. */
- zTok = CharLowerW(zName);
- for (;*zTok;zTok++){
- if (*zTok == '\\') *zTok = '_';
- }
-
- /* Create/open the named mutex */
- pFile->hMutex = CreateMutexW(NULL, FALSE, zName);
- if (!pFile->hMutex){
- pFile->lastErrno = GetLastError();
- free(zName);
- return FALSE;
- }
-
- /* Acquire the mutex before continuing */
- winceMutexAcquire(pFile->hMutex);
-
- /* Since the names of named mutexes, semaphores, file mappings etc are
- ** 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);
-
- /* Set a flag that indicates we're the first to create the memory so it
- ** must be zero-initialized */
- if (GetLastError() == ERROR_ALREADY_EXISTS){
- bInit = FALSE;
- }
-
- free(zName);
-
- /* If we succeeded in making the shared memory handle, map it. */
- if (pFile->hShared){
- pFile->shared = (winceLock*)MapViewOfFile(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();
- CloseHandle(pFile->hShared);
- pFile->hShared = NULL;
- }
- }
-
- /* If shared memory could not be created, then close the mutex and fail */
- if (pFile->hShared == NULL){
- winceMutexRelease(pFile->hMutex);
- CloseHandle(pFile->hMutex);
- pFile->hMutex = NULL;
- return FALSE;
- }
-
- /* Initialize the shared memory if we're supposed to */
- if (bInit) {
- ZeroMemory(pFile->shared, sizeof(winceLock));
- }
-
- winceMutexRelease(pFile->hMutex);
- return TRUE;
-}
-
-/*
-** Destroy the part of winFile that deals with wince locks
-*/
-static void winceDestroyLock(winFile *pFile){
- if (pFile->hMutex){
- /* Acquire the mutex */
- winceMutexAcquire(pFile->hMutex);
-
- /* The following blocks should probably assert in debug mode, but they
- are to cleanup in case any locks remained open */
- if (pFile->local.nReaders){
- pFile->shared->nReaders --;
- }
- if (pFile->local.bReserved){
- pFile->shared->bReserved = FALSE;
- }
- if (pFile->local.bPending){
- pFile->shared->bPending = FALSE;
- }
- if (pFile->local.bExclusive){
- pFile->shared->bExclusive = FALSE;
- }
-
- /* De-reference and close our copy of the shared memory handle */
- UnmapViewOfFile(pFile->shared);
- CloseHandle(pFile->hShared);
-
- /* Done with the mutex */
- winceMutexRelease(pFile->hMutex);
- CloseHandle(pFile->hMutex);
- pFile->hMutex = NULL;
- }
-}
-
-/*
-** An implementation of the LockFile() API of windows for wince
-*/
-static BOOL winceLockFile(
- HANDLE *phFile,
- DWORD dwFileOffsetLow,
- DWORD dwFileOffsetHigh,
- DWORD nNumberOfBytesToLockLow,
- DWORD nNumberOfBytesToLockHigh
-){
- winFile *pFile = HANDLE_TO_WINFILE(phFile);
- BOOL bReturn = FALSE;
-
- UNUSED_PARAMETER(dwFileOffsetHigh);
- UNUSED_PARAMETER(nNumberOfBytesToLockHigh);
-
- if (!pFile->hMutex) return TRUE;
- winceMutexAcquire(pFile->hMutex);
-
- /* Wanting an exclusive lock? */
- if (dwFileOffsetLow == (DWORD)SHARED_FIRST
- && nNumberOfBytesToLockLow == (DWORD)SHARED_SIZE){
- if (pFile->shared->nReaders == 0 && pFile->shared->bExclusive == 0){
- pFile->shared->bExclusive = TRUE;
- pFile->local.bExclusive = TRUE;
- bReturn = TRUE;
- }
- }
-
- /* Want a read-only lock? */
- else if (dwFileOffsetLow == (DWORD)SHARED_FIRST &&
- nNumberOfBytesToLockLow == 1){
- if (pFile->shared->bExclusive == 0){
- pFile->local.nReaders ++;
- if (pFile->local.nReaders == 1){
- pFile->shared->nReaders ++;
- }
- bReturn = TRUE;
- }
- }
-
- /* Want a pending lock? */
- else if (dwFileOffsetLow == (DWORD)PENDING_BYTE && nNumberOfBytesToLockLow == 1){
- /* If no pending lock has been acquired, then acquire it */
- if (pFile->shared->bPending == 0) {
- pFile->shared->bPending = TRUE;
- pFile->local.bPending = TRUE;
- bReturn = TRUE;
- }
- }
-
- /* Want a reserved lock? */
- else if (dwFileOffsetLow == (DWORD)RESERVED_BYTE && nNumberOfBytesToLockLow == 1){
- if (pFile->shared->bReserved == 0) {
- pFile->shared->bReserved = TRUE;
- pFile->local.bReserved = TRUE;
- bReturn = TRUE;
- }
- }
-
- winceMutexRelease(pFile->hMutex);
- return bReturn;
-}
-
-/*
-** An implementation of the UnlockFile API of windows for wince
-*/
-static BOOL winceUnlockFile(
- HANDLE *phFile,
- DWORD dwFileOffsetLow,
- DWORD dwFileOffsetHigh,
- DWORD nNumberOfBytesToUnlockLow,
- DWORD nNumberOfBytesToUnlockHigh
-){
- winFile *pFile = HANDLE_TO_WINFILE(phFile);
- BOOL bReturn = FALSE;
-
- UNUSED_PARAMETER(dwFileOffsetHigh);
- UNUSED_PARAMETER(nNumberOfBytesToUnlockHigh);
-
- if (!pFile->hMutex) return TRUE;
- winceMutexAcquire(pFile->hMutex);
-
- /* Releasing a reader lock or an exclusive lock */
- if (dwFileOffsetLow == (DWORD)SHARED_FIRST){
- /* Did we have an exclusive lock? */
- if (pFile->local.bExclusive){
- assert(nNumberOfBytesToUnlockLow == (DWORD)SHARED_SIZE);
- pFile->local.bExclusive = FALSE;
- pFile->shared->bExclusive = FALSE;
- bReturn = TRUE;
- }
-
- /* Did we just have a reader lock? */
- else if (pFile->local.nReaders){
- assert(nNumberOfBytesToUnlockLow == (DWORD)SHARED_SIZE || nNumberOfBytesToUnlockLow == 1);
- pFile->local.nReaders --;
- if (pFile->local.nReaders == 0)
- {
- pFile->shared->nReaders --;
- }
- bReturn = TRUE;
- }
- }
-
- /* Releasing a pending lock */
- else if (dwFileOffsetLow == (DWORD)PENDING_BYTE && nNumberOfBytesToUnlockLow == 1){
- if (pFile->local.bPending){
- pFile->local.bPending = FALSE;
- pFile->shared->bPending = FALSE;
- bReturn = TRUE;
- }
- }
- /* Releasing a reserved lock */
- else if (dwFileOffsetLow == (DWORD)RESERVED_BYTE && nNumberOfBytesToUnlockLow == 1){
- if (pFile->local.bReserved) {
- pFile->local.bReserved = FALSE;
- pFile->shared->bReserved = FALSE;
- bReturn = TRUE;
- }
- }
-
- winceMutexRelease(pFile->hMutex);
- return bReturn;
-}
-
-/*
-** An implementation of the LockFileEx() API of windows for wince
-*/
-static BOOL winceLockFileEx(
- HANDLE *phFile,
- DWORD dwFlags,
- DWORD dwReserved,
- DWORD nNumberOfBytesToLockLow,
- DWORD nNumberOfBytesToLockHigh,
- LPOVERLAPPED lpOverlapped
-){
- UNUSED_PARAMETER(dwReserved);
- UNUSED_PARAMETER(nNumberOfBytesToLockHigh);
-
- /* If the caller wants a shared read lock, forward this call
- ** to winceLockFile */
- if (lpOverlapped->Offset == (DWORD)SHARED_FIRST &&
- dwFlags == 1 &&
- nNumberOfBytesToLockLow == (DWORD)SHARED_SIZE){
- return winceLockFile(phFile, SHARED_FIRST, 0, 1, 0);
- }
- return FALSE;
-}
-/*
-** End of the special code for wince
-*****************************************************************************/
-#endif /* SQLITE_OS_WINCE */
-
-/*****************************************************************************
-** The next group of routines implement the I/O methods specified
-** by the sqlite3_io_methods object.
-******************************************************************************/
-
-/*
-** 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
-** 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
-** giving up and returning an error.
-*/
-#define MX_CLOSE_ATTEMPT 3
-static int winClose(sqlite3_file *id){
- int rc, cnt = 0;
- winFile *pFile = (winFile*)id;
-
- assert( id!=0 );
- OSTRACE2("CLOSE %d\n", pFile->h);
- do{
- rc = CloseHandle(pFile->h);
- }while( rc==0 && ++cnt < MX_CLOSE_ATTEMPT && (Sleep(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
- && cnt++ < WINCE_DELETION_ATTEMPTS
- ){
- Sleep(100); /* Wait a little before trying again */
- }
- free(pFile->zDeleteOnClose);
- }
-#endif
- OpenCounter(-1);
- return rc ? SQLITE_OK : SQLITE_IOERR;
-}
-
-/*
-** Some microsoft compilers lack this definition.
-*/
-#ifndef INVALID_SET_FILE_POINTER
-# define INVALID_SET_FILE_POINTER ((DWORD)-1)
-#endif
-
-/*
-** Read data from a file into a buffer. Return SQLITE_OK if all
-** bytes were read successfully and SQLITE_IOERR if anything goes
-** wrong.
-*/
-static int winRead(
- sqlite3_file *id, /* File to read from */
- void *pBuf, /* Write content into this buffer */
- int amt, /* Number of bytes to read */
- sqlite3_int64 offset /* Begin reading at this offset */
-){
- LONG upperBits = (LONG)((offset>>32) & 0x7fffffff);
- LONG lowerBits = (LONG)(offset & 0xffffffff);
- DWORD rc;
- winFile *pFile = (winFile*)id;
- DWORD error;
- DWORD got;
-
- assert( id!=0 );
- SimulateIOError(return SQLITE_IOERR_READ);
- OSTRACE3("READ %d lock=%d\n", pFile->h, pFile->locktype);
- rc = SetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN);
- if( rc==INVALID_SET_FILE_POINTER && (error=GetLastError())!=NO_ERROR ){
- pFile->lastErrno = error;
- return SQLITE_FULL;
- }
- if( !ReadFile(pFile->h, pBuf, amt, &got, 0) ){
- pFile->lastErrno = GetLastError();
- return SQLITE_IOERR_READ;
- }
- if( got==(DWORD)amt ){
- return SQLITE_OK;
- }else{
- /* Unread parts of the buffer must be zero-filled */
- memset(&((char*)pBuf)[got], 0, amt-got);
- return SQLITE_IOERR_SHORT_READ;
- }
-}
-
-/*
-** Write data from a buffer into a file. Return SQLITE_OK on success
-** or some other error code on failure.
-*/
-static int winWrite(
- sqlite3_file *id, /* File to write into */
- const void *pBuf, /* The bytes to be written */
- int amt, /* Number of bytes to write */
- sqlite3_int64 offset /* Offset into the file to begin writing at */
-){
- LONG upperBits = (LONG)((offset>>32) & 0x7fffffff);
- LONG lowerBits = (LONG)(offset & 0xffffffff);
- DWORD rc;
- winFile *pFile = (winFile*)id;
- DWORD error;
- DWORD wrote = 0;
-
- assert( id!=0 );
- SimulateIOError(return SQLITE_IOERR_WRITE);
- SimulateDiskfullError(return SQLITE_FULL);
- OSTRACE3("WRITE %d lock=%d\n", pFile->h, pFile->locktype);
- rc = SetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN);
- if( rc==INVALID_SET_FILE_POINTER && (error=GetLastError())!=NO_ERROR ){
- pFile->lastErrno = error;
- return SQLITE_FULL;
- }
- assert( amt>0 );
- while(
- amt>0
- && (rc = WriteFile(pFile->h, pBuf, amt, &wrote, 0))!=0
- && wrote>0
- ){
- amt -= wrote;
- pBuf = &((char*)pBuf)[wrote];
- }
- if( !rc || amt>(int)wrote ){
- pFile->lastErrno = GetLastError();
- return SQLITE_FULL;
- }
- return SQLITE_OK;
-}
-
-/*
-** Truncate an open file to a specified size
-*/
-static int winTruncate(sqlite3_file *id, sqlite3_int64 nByte){
- LONG upperBits = (LONG)((nByte>>32) & 0x7fffffff);
- LONG lowerBits = (LONG)(nByte & 0xffffffff);
- DWORD rc;
- winFile *pFile = (winFile*)id;
- DWORD error;
-
- assert( id!=0 );
- OSTRACE3("TRUNCATE %d %lld\n", pFile->h, nByte);
- SimulateIOError(return SQLITE_IOERR_TRUNCATE);
- rc = SetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN);
- if( rc==INVALID_SET_FILE_POINTER && (error=GetLastError())!=NO_ERROR ){
- pFile->lastErrno = error;
- return SQLITE_IOERR_TRUNCATE;
- }
- /* SetEndOfFile will fail if nByte is negative */
- if( !SetEndOfFile(pFile->h) ){
- pFile->lastErrno = GetLastError();
- return SQLITE_IOERR_TRUNCATE;
- }
- return SQLITE_OK;
-}
-
-#ifdef SQLITE_TEST
-/*
-** Count the number of fullsyncs and normal syncs. This is used to test
-** that syncs and fullsyncs are occuring at the right times.
-*/
-SQLITE_API int sqlite3_sync_count = 0;
-SQLITE_API int sqlite3_fullsync_count = 0;
-#endif
-
-/*
-** Make sure all writes to a particular file are committed to disk.
-*/
-static int winSync(sqlite3_file *id, int flags){
-#ifndef SQLITE_NO_SYNC
- winFile *pFile = (winFile*)id;
-
- assert( id!=0 );
- OSTRACE3("SYNC %d lock=%d\n", pFile->h, pFile->locktype);
-#else
- UNUSED_PARAMETER(id);
-#endif
-#ifndef SQLITE_TEST
- UNUSED_PARAMETER(flags);
-#else
- if( flags & SQLITE_SYNC_FULL ){
- sqlite3_fullsync_count++;
- }
- sqlite3_sync_count++;
-#endif
- /* If we compiled with the SQLITE_NO_SYNC flag, then syncing is a
- ** no-op
- */
-#ifdef SQLITE_NO_SYNC
- return SQLITE_OK;
-#else
- if( FlushFileBuffers(pFile->h) ){
- return SQLITE_OK;
- }else{
- pFile->lastErrno = GetLastError();
- return SQLITE_IOERR;
- }
-#endif
-}
-
-/*
-** Determine the current size of a file in bytes
-*/
-static int winFileSize(sqlite3_file *id, sqlite3_int64 *pSize){
- DWORD upperBits;
- DWORD lowerBits;
- winFile *pFile = (winFile*)id;
- DWORD error;
-
- assert( id!=0 );
- SimulateIOError(return SQLITE_IOERR_FSTAT);
- lowerBits = GetFileSize(pFile->h, &upperBits);
- if( (lowerBits == INVALID_FILE_SIZE)
- && ((error = GetLastError()) != NO_ERROR) )
- {
- pFile->lastErrno = error;
- return SQLITE_IOERR_FSTAT;
- }
- *pSize = (((sqlite3_int64)upperBits)<<32) + lowerBits;
- return SQLITE_OK;
-}
-
-/*
-** LOCKFILE_FAIL_IMMEDIATELY is undefined on some Windows systems.
-*/
-#ifndef LOCKFILE_FAIL_IMMEDIATELY
-# define LOCKFILE_FAIL_IMMEDIATELY 1
-#endif
-
-/*
-** Acquire a reader lock.
-** Different API routines are called depending on whether or not this
-** is Win95 or WinNT.
-*/
-static int getReadLock(winFile *pFile){
- int res;
- if( isNT() ){
- OVERLAPPED ovlp;
- ovlp.Offset = SHARED_FIRST;
- ovlp.OffsetHigh = 0;
- ovlp.hEvent = 0;
- res = LockFileEx(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
- }else{
- 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);
-#endif
- }
- if( res == 0 ){
- pFile->lastErrno = GetLastError();
- }
- return res;
-}
-
-/*
-** Undo a readlock
-*/
-static int unlockReadLock(winFile *pFile){
- int res;
- if( isNT() ){
- res = UnlockFile(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);
-#endif
- }
- if( res == 0 ){
- pFile->lastErrno = GetLastError();
- }
- return res;
-}
-
-/*
-** Lock the file with the lock specified by parameter locktype - one
-** of the following:
-**
-** (1) SHARED_LOCK
-** (2) RESERVED_LOCK
-** (3) PENDING_LOCK
-** (4) EXCLUSIVE_LOCK
-**
-** Sometimes when requesting one lock state, additional lock states
-** are inserted in between. The locking might fail on one of the later
-** transitions leaving the lock state different from what it started but
-** still short of its goal. The following chart shows the allowed
-** transitions and the inserted intermediate states:
-**
-** UNLOCKED -> SHARED
-** SHARED -> RESERVED
-** SHARED -> (PENDING) -> EXCLUSIVE
-** RESERVED -> (PENDING) -> EXCLUSIVE
-** PENDING -> EXCLUSIVE
-**
-** This routine will only increase a lock. The winUnlock() routine
-** erases all locks at once and returns us immediately to locking level 0.
-** It is not possible to lower the locking level one step at a time. You
-** must go straight to locking level 0.
-*/
-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 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;
-
- assert( id!=0 );
- OSTRACE5("LOCK %d %d was %d(%d)\n",
- pFile->h, locktype, pFile->locktype, pFile->sharedLockByte);
-
- /* If there is already a lock of this type or more restrictive on the
- ** OsFile, do nothing. Don't use the end_lock: exit path, as
- ** sqlite3OsEnterMutex() hasn't been called yet.
- */
- if( pFile->locktype>=locktype ){
- return SQLITE_OK;
- }
-
- /* Make sure the locking sequence is correct
- */
- assert( pFile->locktype!=NO_LOCK || locktype==SHARED_LOCK );
- assert( locktype!=PENDING_LOCK );
- assert( locktype!=RESERVED_LOCK || pFile->locktype==SHARED_LOCK );
-
- /* Lock the PENDING_LOCK byte if we need to acquire a PENDING lock or
- ** a SHARED lock. If we are acquiring a SHARED lock, the acquisition of
- ** the PENDING_LOCK byte is temporary.
- */
- newLocktype = pFile->locktype;
- if( (pFile->locktype==NO_LOCK)
- || ( (locktype==EXCLUSIVE_LOCK)
- && (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.
- */
- OSTRACE2("could not get a PENDING lock. cnt=%d\n", cnt);
- Sleep(1);
- }
- gotPendingLock = res;
- if( !res ){
- error = GetLastError();
- }
- }
-
- /* Acquire a shared lock
- */
- if( locktype==SHARED_LOCK && res ){
- assert( pFile->locktype==NO_LOCK );
- res = getReadLock(pFile);
- if( res ){
- newLocktype = SHARED_LOCK;
- }else{
- error = GetLastError();
- }
- }
-
- /* Acquire a RESERVED lock
- */
- if( locktype==RESERVED_LOCK && res ){
- assert( pFile->locktype==SHARED_LOCK );
- res = LockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
- if( res ){
- newLocktype = RESERVED_LOCK;
- }else{
- error = GetLastError();
- }
- }
-
- /* Acquire a PENDING lock
- */
- if( locktype==EXCLUSIVE_LOCK && res ){
- newLocktype = PENDING_LOCK;
- gotPendingLock = 0;
- }
-
- /* Acquire an EXCLUSIVE lock
- */
- if( locktype==EXCLUSIVE_LOCK && res ){
- assert( pFile->locktype>=SHARED_LOCK );
- res = unlockReadLock(pFile);
- OSTRACE2("unreadlock = %d\n", res);
- res = LockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
- if( res ){
- newLocktype = EXCLUSIVE_LOCK;
- }else{
- error = GetLastError();
- OSTRACE2("error-code = %d\n", error);
- getReadLock(pFile);
- }
- }
-
- /* If we are holding a PENDING lock that ought to be released, then
- ** release it now.
- */
- if( gotPendingLock && locktype==SHARED_LOCK ){
- UnlockFile(pFile->h, PENDING_BYTE, 0, 1, 0);
- }
-
- /* Update the state of the lock has held in the file descriptor then
- ** return the appropriate result code.
- */
- if( res ){
- rc = SQLITE_OK;
- }else{
- OSTRACE4("LOCK FAILED %d trying for %d but got %d\n", pFile->h,
- locktype, newLocktype);
- pFile->lastErrno = error;
- rc = SQLITE_BUSY;
- }
- pFile->locktype = (u8)newLocktype;
- return rc;
-}
-
-/*
-** This routine checks if there is a RESERVED lock held on the specified
-** file by this or any other process. If such a lock is held, return
-** non-zero, otherwise zero.
-*/
-static int winCheckReservedLock(sqlite3_file *id, int *pResOut){
- int rc;
- winFile *pFile = (winFile*)id;
-
- assert( id!=0 );
- if( pFile->locktype>=RESERVED_LOCK ){
- rc = 1;
- OSTRACE3("TEST WR-LOCK %d %d (local)\n", pFile->h, rc);
- }else{
- rc = LockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
- if( rc ){
- UnlockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
- }
- rc = !rc;
- OSTRACE3("TEST WR-LOCK %d %d (remote)\n", pFile->h, rc);
- }
- *pResOut = rc;
- return SQLITE_OK;
-}
-
-/*
-** Lower the locking level on file descriptor id to locktype. locktype
-** must be either NO_LOCK or SHARED_LOCK.
-**
-** If the locking level of the file descriptor is already at or below
-** the requested locking level, this routine is a no-op.
-**
-** It is not possible for this routine to fail if the second argument
-** is NO_LOCK. If the second argument is SHARED_LOCK then this routine
-** might return SQLITE_IOERR;
-*/
-static int winUnlock(sqlite3_file *id, int locktype){
- int type;
- winFile *pFile = (winFile*)id;
- int rc = SQLITE_OK;
- assert( pFile!=0 );
- assert( locktype<=SHARED_LOCK );
- OSTRACE5("UNLOCK %d to %d was %d(%d)\n", pFile->h, locktype,
- pFile->locktype, pFile->sharedLockByte);
- type = pFile->locktype;
- if( type>=EXCLUSIVE_LOCK ){
- UnlockFile(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 = SQLITE_IOERR_UNLOCK;
- }
- }
- if( type>=RESERVED_LOCK ){
- UnlockFile(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);
- }
- pFile->locktype = (u8)locktype;
- return rc;
-}
-
-/*
-** Control and query of the open file handle.
-*/
-static int winFileControl(sqlite3_file *id, int op, void *pArg){
- switch( op ){
- case SQLITE_FCNTL_LOCKSTATE: {
- *(int*)pArg = ((winFile*)id)->locktype;
- return SQLITE_OK;
- }
- case SQLITE_LAST_ERRNO: {
- *(int*)pArg = (int)((winFile*)id)->lastErrno;
- return SQLITE_OK;
- }
- }
- return SQLITE_ERROR;
-}
-
-/*
-** Return the sector size in bytes of the underlying block device for
-** the specified file. This is almost always 512 bytes, but may be
-** larger for some devices.
-**
-** SQLite code assumes this function cannot fail. It also assumes that
-** if two files are created in the same file-system directory (i.e.
-** a database and its journal file) that the sector size will be the
-** same for both.
-*/
-static int winSectorSize(sqlite3_file *id){
- assert( id!=0 );
- return (int)(((winFile*)id)->sectorSize);
-}
-
-/*
-** Return a vector of device characteristics.
-*/
-static int winDeviceCharacteristics(sqlite3_file *id){
- UNUSED_PARAMETER(id);
- return 0;
-}
-
-/*
-** This vector defines all the methods that can operate on an
-** sqlite3_file for win32.
-*/
-static const sqlite3_io_methods winIoMethod = {
- 1, /* iVersion */
- winClose,
- winRead,
- winWrite,
- winTruncate,
- winSync,
- winFileSize,
- winLock,
- winUnlock,
- winCheckReservedLock,
- winFileControl,
- winSectorSize,
- winDeviceCharacteristics
-};
-
-/***************************************************************************
-** Here ends the I/O methods that form the sqlite3_io_methods object.
-**
-** The next block of code implements the VFS methods.
-****************************************************************************/
-
-/*
-** Convert a UTF-8 filename into whatever form the underlying
-** operating system wants filenames in. Space to hold the result
-** is obtained from malloc and must be freed by the calling
-** function.
-*/
-static void *convertUtf8Filename(const char *zFilename){
- void *zConverted = 0;
- if( isNT() ){
- zConverted = utf8ToUnicode(zFilename);
-/* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed.
-*/
-#if SQLITE_OS_WINCE==0
- }else{
- zConverted = utf8ToMbcs(zFilename);
-#endif
- }
- /* caller will handle out of memory */
- return zConverted;
-}
-
-/*
-** Create a temporary file name in zBuf. zBuf must be big enough to
-** hold at pVfs->mxPathname characters.
-*/
-static int getTempname(int nBuf, char *zBuf){
- static char zChars[] =
- "abcdefghijklmnopqrstuvwxyz"
- "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
- "0123456789";
- size_t i, j;
- char zTempPath[MAX_PATH+1];
- if( sqlite3_temp_directory ){
- sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", sqlite3_temp_directory);
- }else if( isNT() ){
- char *zMulti;
- WCHAR zWidePath[MAX_PATH];
- GetTempPathW(MAX_PATH-30, zWidePath);
- zMulti = unicodeToUtf8(zWidePath);
- if( zMulti ){
- sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", zMulti);
- free(zMulti);
- }else{
- return SQLITE_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,
-** 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);
- zUtf8 = sqlite3_win32_mbcs_to_utf8(zMbcsPath);
- if( zUtf8 ){
- sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", zUtf8);
- free(zUtf8);
- }else{
- return SQLITE_NOMEM;
- }
-#endif
- }
- for(i=sqlite3Strlen30(zTempPath); i>0 && zTempPath[i-1]=='\\'; i--){}
- zTempPath[i] = 0;
- sqlite3_snprintf(nBuf-30, zBuf,
- "%s\\"SQLITE_TEMP_FILE_PREFIX, zTempPath);
- j = sqlite3Strlen30(zBuf);
- sqlite3_randomness(20, &zBuf[j]);
- for(i=0; i<20; i++, j++){
- zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
- }
- zBuf[j] = 0;
- OSTRACE2("TEMP FILENAME: %s\n", zBuf);
- return SQLITE_OK;
-}
-
-/*
-** The return value of getLastErrorMsg
-** 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){
- DWORD error = GetLastError();
-
-#if SQLITE_OS_WINCE
- sqlite3_snprintf(nBuf, zBuf, "OsError 0x%x (%u)", error, error);
-#else
- /* FormatMessage returns 0 on failure. Otherwise it
- ** returns the number of TCHARs written to the output
- ** buffer, excluding the terminating null char.
- */
- if (!FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM,
- NULL,
- error,
- 0,
- zBuf,
- nBuf-1,
- 0))
- {
- sqlite3_snprintf(nBuf, zBuf, "OsError 0x%x (%u)", error, error);
- }
-#endif
-
- return 0;
-}
-
-/*
-** Open a file.
-*/
-static int winOpen(
- sqlite3_vfs *pVfs, /* Not used */
- const char *zName, /* Name of the file (UTF-8) */
- sqlite3_file *id, /* Write the SQLite file handle here */
- int flags, /* Open mode flags */
- int *pOutFlags /* Status return flags */
-){
- HANDLE h;
- DWORD dwDesiredAccess;
- DWORD dwShareMode;
- DWORD dwCreationDisposition;
- DWORD dwFlagsAndAttributes = 0;
-#if SQLITE_OS_WINCE
- int isTemp = 0;
-#endif
- winFile *pFile = (winFile*)id;
- void *zConverted; /* Filename in OS encoding */
- const char *zUtf8Name = zName; /* Filename in UTF-8 encoding */
- char zTmpname[MAX_PATH+1]; /* Buffer used to create temp filename */
-
- assert( id!=0 );
- UNUSED_PARAMETER(pVfs);
-
- /* If the second argument to this function is NULL, generate a
- ** temporary file name to use
- */
- if( !zUtf8Name ){
- int rc = getTempname(MAX_PATH+1, zTmpname);
- if( rc!=SQLITE_OK ){
- return rc;
- }
- zUtf8Name = zTmpname;
- }
-
- /* Convert the filename to the system encoding. */
- zConverted = convertUtf8Filename(zUtf8Name);
- if( zConverted==0 ){
- return SQLITE_NOMEM;
- }
-
- if( flags & SQLITE_OPEN_READWRITE ){
- dwDesiredAccess = GENERIC_READ | GENERIC_WRITE;
- }else{
- dwDesiredAccess = GENERIC_READ;
- }
- /* SQLITE_OPEN_EXCLUSIVE is used to make sure that a new file is
- ** created. SQLite doesn't use it to indicate "exclusive access"
- ** as it is usually understood.
- */
- assert(!(flags & SQLITE_OPEN_EXCLUSIVE) || (flags & SQLITE_OPEN_CREATE));
- if( flags & SQLITE_OPEN_EXCLUSIVE ){
- /* Creates a new file, only if it does not already exist. */
- /* If the file exists, it fails. */
- dwCreationDisposition = CREATE_NEW;
- }else if( flags & SQLITE_OPEN_CREATE ){
- /* Open existing file, or create if it doesn't exist */
- dwCreationDisposition = OPEN_ALWAYS;
- }else{
- /* Opens a file, only if it exists. */
- dwCreationDisposition = OPEN_EXISTING;
- }
- dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
- if( flags & SQLITE_OPEN_DELETEONCLOSE ){
-#if SQLITE_OS_WINCE
- dwFlagsAndAttributes = FILE_ATTRIBUTE_HIDDEN;
- isTemp = 1;
-#else
- dwFlagsAndAttributes = FILE_ATTRIBUTE_TEMPORARY
- | FILE_ATTRIBUTE_HIDDEN
- | FILE_FLAG_DELETE_ON_CLOSE;
-#endif
- }else{
- dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL;
- }
- /* Reports from the internet are that performance is always
- ** better if FILE_FLAG_RANDOM_ACCESS is used. Ticket #2699. */
-#if SQLITE_OS_WINCE
- dwFlagsAndAttributes |= FILE_FLAG_RANDOM_ACCESS;
-#endif
- if( isNT() ){
- h = CreateFileW((WCHAR*)zConverted,
- dwDesiredAccess,
- dwShareMode,
- NULL,
- dwCreationDisposition,
- dwFlagsAndAttributes,
- NULL
- );
-/* 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,
-** it's important to not reference them for WINCE builds.
-*/
-#if SQLITE_OS_WINCE==0
- }else{
- h = CreateFileA((char*)zConverted,
- dwDesiredAccess,
- dwShareMode,
- NULL,
- dwCreationDisposition,
- dwFlagsAndAttributes,
- NULL
- );
-#endif
- }
- if( h==INVALID_HANDLE_VALUE ){
- free(zConverted);
- if( flags & SQLITE_OPEN_READWRITE ){
- return winOpen(pVfs, zName, id,
- ((flags|SQLITE_OPEN_READONLY)&~SQLITE_OPEN_READWRITE), pOutFlags);
- }else{
- return SQLITE_CANTOPEN;
- }
- }
- if( pOutFlags ){
- if( flags & SQLITE_OPEN_READWRITE ){
- *pOutFlags = SQLITE_OPEN_READWRITE;
- }else{
- *pOutFlags = SQLITE_OPEN_READONLY;
- }
- }
- memset(pFile, 0, sizeof(*pFile));
- pFile->pMethod = &winIoMethod;
- pFile->h = h;
- pFile->lastErrno = NO_ERROR;
- pFile->sectorSize = getSectorSize(pVfs, zUtf8Name);
-#if SQLITE_OS_WINCE
- if( (flags & (SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_DB)) ==
- (SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_DB)
- && !winceCreateLock(zName, pFile)
- ){
- CloseHandle(h);
- free(zConverted);
- return SQLITE_CANTOPEN;
- }
- if( isTemp ){
- pFile->zDeleteOnClose = zConverted;
- }else
-#endif
- {
- free(zConverted);
- }
- OpenCounter(+1);
- return SQLITE_OK;
-}
-
-/*
-** Delete the named file.
-**
-** 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
-** file open, we will be unable to delete it. To work around this
-** problem, we delay 100 milliseconds and try to delete again. Up
-** to MX_DELETION_ATTEMPTs deletion attempts are run before giving
-** up and returning an error.
-*/
-#define MX_DELETION_ATTEMPTS 5
-static int winDelete(
- sqlite3_vfs *pVfs, /* Not used on win32 */
- const char *zFilename, /* Name of file to delete */
- int syncDir /* Not used on win32 */
-){
- int cnt = 0;
- DWORD rc;
- DWORD error = 0;
- void *zConverted = convertUtf8Filename(zFilename);
- UNUSED_PARAMETER(pVfs);
- UNUSED_PARAMETER(syncDir);
- if( zConverted==0 ){
- return SQLITE_NOMEM;
- }
- SimulateIOError(return SQLITE_IOERR_DELETE);
- if( isNT() ){
- do{
- DeleteFileW(zConverted);
- }while( ( ((rc = GetFileAttributesW(zConverted)) != INVALID_FILE_ATTRIBUTES)
- || ((error = GetLastError()) == ERROR_ACCESS_DENIED))
- && (++cnt < MX_DELETION_ATTEMPTS)
- && (Sleep(100), 1) );
-/* 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,
-** it's important to not reference them for WINCE builds.
-*/
-#if SQLITE_OS_WINCE==0
- }else{
- do{
- DeleteFileA(zConverted);
- }while( ( ((rc = GetFileAttributesA(zConverted)) != INVALID_FILE_ATTRIBUTES)
- || ((error = GetLastError()) == ERROR_ACCESS_DENIED))
- && (++cnt < MX_DELETION_ATTEMPTS)
- && (Sleep(100), 1) );
-#endif
- }
- free(zConverted);
- OSTRACE2("DELETE \"%s\"\n", zFilename);
- return ( (rc == INVALID_FILE_ATTRIBUTES)
- && (error == ERROR_FILE_NOT_FOUND)) ? SQLITE_OK : SQLITE_IOERR_DELETE;
-}
-
-/*
-** Check the existance and status of a file.
-*/
-static int winAccess(
- sqlite3_vfs *pVfs, /* Not used on win32 */
- const char *zFilename, /* Name of file to check */
- int flags, /* Type of test to make on this file */
- int *pResOut /* OUT: Result */
-){
- DWORD attr;
- int rc = 0;
- void *zConverted = convertUtf8Filename(zFilename);
- UNUSED_PARAMETER(pVfs);
- if( zConverted==0 ){
- return SQLITE_NOMEM;
- }
- if( isNT() ){
- attr = GetFileAttributesW((WCHAR*)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,
-** it's important to not reference them for WINCE builds.
-*/
-#if SQLITE_OS_WINCE==0
- }else{
- attr = GetFileAttributesA((char*)zConverted);
-#endif
- }
- free(zConverted);
- switch( flags ){
- case SQLITE_ACCESS_READ:
- case SQLITE_ACCESS_EXISTS:
- rc = attr!=INVALID_FILE_ATTRIBUTES;
- break;
- case SQLITE_ACCESS_READWRITE:
- rc = (attr & FILE_ATTRIBUTE_READONLY)==0;
- break;
- default:
- assert(!"Invalid flags argument");
- }
- *pResOut = rc;
- return SQLITE_OK;
-}
-
-
-/*
-** Turn a relative pathname into a full pathname. Write the full
-** pathname into zOut[]. zOut[] will be at least pVfs->mxPathname
-** bytes in size.
-*/
-static int winFullPathname(
- sqlite3_vfs *pVfs, /* Pointer to vfs object */
- const char *zRelative, /* Possibly relative input path */
- int nFull, /* Size of output buffer in bytes */
- char *zFull /* Output buffer */
-){
-
-#if defined(__CYGWIN__)
- UNUSED_PARAMETER(nFull);
- cygwin_conv_to_full_win32_path(zRelative, zFull);
- return SQLITE_OK;
-#endif
-
-#if SQLITE_OS_WINCE
- UNUSED_PARAMETER(nFull);
- /* WinCE has no concept of a relative pathname, or so I am told. */
- sqlite3_snprintf(pVfs->mxPathname, zFull, "%s", zRelative);
- return SQLITE_OK;
-#endif
-
-#if !SQLITE_OS_WINCE && !defined(__CYGWIN__)
- int nByte;
- void *zConverted;
- char *zOut;
- UNUSED_PARAMETER(nFull);
- zConverted = convertUtf8Filename(zRelative);
- if( isNT() ){
- WCHAR *zTemp;
- nByte = GetFullPathNameW((WCHAR*)zConverted, 0, 0, 0) + 3;
- zTemp = malloc( nByte*sizeof(zTemp[0]) );
- if( zTemp==0 ){
- free(zConverted);
- return SQLITE_NOMEM;
- }
- GetFullPathNameW((WCHAR*)zConverted, nByte, zTemp, 0);
- free(zConverted);
- zOut = unicodeToUtf8(zTemp);
- 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,
-** 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]) );
- if( zTemp==0 ){
- free(zConverted);
- return SQLITE_NOMEM;
- }
- GetFullPathNameA((char*)zConverted, nByte, zTemp, 0);
- free(zConverted);
- zOut = sqlite3_win32_mbcs_to_utf8(zTemp);
- free(zTemp);
-#endif
- }
- if( zOut ){
- sqlite3_snprintf(pVfs->mxPathname, zFull, "%s", zOut);
- free(zOut);
- return SQLITE_OK;
- }else{
- return SQLITE_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.
- */
- rc = winFullPathname(pVfs, zRelative, MAX_PATH, zFullpath);
- 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
-** within the shared library, and closing the shared library.
-*/
-/*
-** Interfaces for opening a shared library, finding entry points
-** within the shared library, and closing the shared library.
-*/
-static void *winDlOpen(sqlite3_vfs *pVfs, const char *zFilename){
- HANDLE h;
- void *zConverted = convertUtf8Filename(zFilename);
- UNUSED_PARAMETER(pVfs);
- if( zConverted==0 ){
- return 0;
- }
- if( isNT() ){
- h = LoadLibraryW((WCHAR*)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,
-** it's important to not reference them for WINCE builds.
-*/
-#if SQLITE_OS_WINCE==0
- }else{
- h = LoadLibraryA((char*)zConverted);
-#endif
- }
- free(zConverted);
- return (void*)h;
-}
-static void winDlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){
- UNUSED_PARAMETER(pVfs);
- getLastErrorMsg(nBuf, zBufOut);
-}
-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
-}
-void winDlClose(sqlite3_vfs *pVfs, void *pHandle){
- UNUSED_PARAMETER(pVfs);
- FreeLibrary((HANDLE)pHandle);
-}
-#else /* if SQLITE_OMIT_LOAD_EXTENSION is defined: */
- #define winDlOpen 0
- #define winDlError 0
- #define winDlSym 0
- #define winDlClose 0
-#endif
-
-
-/*
-** Write up to nBuf bytes of randomness into zBuf.
-*/
-static int winRandomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
- int n = 0;
- UNUSED_PARAMETER(pVfs);
-#if defined(SQLITE_TEST)
- n = nBuf;
- memset(zBuf, 0, nBuf);
-#else
- if( sizeof(SYSTEMTIME)<=nBuf-n ){
- SYSTEMTIME x;
- GetSystemTime(&x);
- memcpy(&zBuf[n], &x, sizeof(x));
- n += sizeof(x);
- }
- if( sizeof(DWORD)<=nBuf-n ){
- DWORD pid = GetCurrentProcessId();
- memcpy(&zBuf[n], &pid, sizeof(pid));
- n += sizeof(pid);
- }
- if( sizeof(DWORD)<=nBuf-n ){
- DWORD cnt = GetTickCount();
- memcpy(&zBuf[n], &cnt, sizeof(cnt));
- n += sizeof(cnt);
- }
- if( sizeof(LARGE_INTEGER)<=nBuf-n ){
- LARGE_INTEGER i;
- QueryPerformanceCounter(&i);
- memcpy(&zBuf[n], &i, sizeof(i));
- n += sizeof(i);
- }
-#endif
- return n;
-}
-
-
-/*
-** Sleep for a little while. Return the amount of time slept.
-*/
-static int winSleep(sqlite3_vfs *pVfs, int microsec){
- Sleep((microsec+999)/1000);
- UNUSED_PARAMETER(pVfs);
- return ((microsec+999)/1000)*1000;
-}
-
-/*
-** The following variable, if set to a non-zero value, becomes the result
-** returned from sqlite3OsCurrentTime(). This is used for testing.
-*/
-#ifdef SQLITE_TEST
-SQLITE_API int sqlite3_current_time = 0;
-#endif
-
-/*
-** Find the current time (in Universal Coordinated Time). Write the
-** current time and date as a Julian Day number into *prNow and
-** return 0. Return 1 if the time and date cannot be found.
-*/
-int winCurrentTime(sqlite3_vfs *pVfs, double *prNow){
- FILETIME ft;
- /* FILETIME structure is a 64-bit value representing the number of
- 100-nanosecond intervals since January 1, 1601 (= JD 2305813.5).
- */
- sqlite3_int64 timeW; /* Whole days */
- sqlite3_int64 timeF; /* Fractional Days */
-
- /* Number of 100-nanosecond intervals in a single day */
- static const sqlite3_int64 ntuPerDay =
- 10000000*(sqlite3_int64)86400;
-
- /* Number of 100-nanosecond intervals in half of a day */
- static const sqlite3_int64 ntuPerHalfDay =
- 10000000*(sqlite3_int64)43200;
-
- /* 2^32 - to avoid use of LL and warnings in gcc */
- static const sqlite3_int64 max32BitValue =
- (sqlite3_int64)2000000000 + (sqlite3_int64)2000000000 + (sqlite3_int64)294967296;
-
-#if SQLITE_OS_WINCE
- SYSTEMTIME time;
- GetSystemTime(&time);
- /* if SystemTimeToFileTime() fails, it returns zero. */
- if (!SystemTimeToFileTime(&time,&ft)){
- return 1;
- }
-#else
- GetSystemTimeAsFileTime( &ft );
-#endif
- UNUSED_PARAMETER(pVfs);
- timeW = (((sqlite3_int64)ft.dwHighDateTime)*max32BitValue) + (sqlite3_int64)ft.dwLowDateTime;
- timeF = timeW % ntuPerDay; /* fractional days (100-nanoseconds) */
- timeW = timeW / ntuPerDay; /* whole days */
- timeW = timeW + 2305813; /* add whole days (from 2305813.5) */
- timeF = timeF + ntuPerHalfDay; /* add half a day (from 2305813.5) */
- timeW = timeW + (timeF/ntuPerDay); /* add whole day if half day made one */
- timeF = timeF % ntuPerDay; /* compute new fractional days */
- *prNow = (double)timeW + ((double)timeF / (double)ntuPerDay);
-#ifdef SQLITE_TEST
- if( sqlite3_current_time ){
- *prNow = ((double)sqlite3_current_time + (double)43200) / (double)86400 + (double)2440587;
- }
-#endif
- return 0;
-}
-
-/*
-** 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
-** 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
-** describing the last IO error to have occurred within the calling
-** thread.
-**
-** If the error message is too large for the supplied buffer,
-** it should be truncated. The return value of xGetLastError
-** is zero if the error message fits in the buffer, or non-zero
-** otherwise (if the message was truncated). If non-zero is returned,
-** then it is not necessary to include the nul-terminator character
-** in the output buffer.
-**
-** Not supplying an error message will have no adverse effect
-** on SQLite. It is fine to have an implementation that never
-** returns an error message:
-**
-** int xGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
-** assert(zBuf[0]=='\0');
-** return 0;
-** }
-**
-** However if an error message is supplied, it will be incorporated
-** by sqlite into the error message available to the user using
-** sqlite3_errmsg(), possibly making IO errors easier to debug.
-*/
-static int winGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
- UNUSED_PARAMETER(pVfs);
- return getLastErrorMsg(nBuf, zBuf);
-}
-
-/*
-** Initialize and deinitialize the operating system interface.
-*/
-SQLITE_API int sqlite3_os_init(void){
- static sqlite3_vfs winVfs = {
- 1, /* iVersion */
- sizeof(winFile), /* szOsFile */
- MAX_PATH, /* mxPathname */
- 0, /* pNext */
- "win32", /* zName */
- 0, /* pAppData */
-
- winOpen, /* xOpen */
- winDelete, /* xDelete */
- winAccess, /* xAccess */
- winFullPathname, /* xFullPathname */
- winDlOpen, /* xDlOpen */
- winDlError, /* xDlError */
- winDlSym, /* xDlSym */
- winDlClose, /* xDlClose */
- winRandomness, /* xRandomness */
- winSleep, /* xSleep */
- winCurrentTime, /* xCurrentTime */
- winGetLastError /* xGetLastError */
- };
-
- sqlite3_vfs_register(&winVfs, 1);
- return SQLITE_OK;
-}
-SQLITE_API int sqlite3_os_end(void){
- return SQLITE_OK;
-}
-
-#endif /* SQLITE_OS_WIN */
-
-/************** End of os_win.c **********************************************/
-/************** Begin file bitvec.c ******************************************/
-/*
-** 2008 February 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 implements an object that represents a fixed-length
-** bitmap. Bits are numbered starting with 1.
-**
-** A bitmap is used to record which pages of a database file have been
-** journalled during a transaction, or which pages have the "dont-write"
-** property. Usually only a few pages are meet either condition.
-** So the bitmap is usually sparse and has low cardinality.
-** But sometimes (for example when during a DROP of a large table) most
-** or all of the pages in a database can get journalled. In those cases,
-** the bitmap becomes dense with high cardinality. The algorithm needs
-** to handle both cases well.
-**
-** The size of the bitmap is fixed when the object is created.
-**
-** All bits are clear when the bitmap is created. Individual bits
-** may be set or cleared one at a time.
-**
-** Test operations are about 100 times more common that set operations.
-** Clear operations are exceedingly rare. There are usually between
-** 5 and 500 set operations per Bitvec object, though the number of sets can
-** sometimes grow into tens of thousands or larger. The size of the
-** Bitvec object is the number of pages in the database file at the
-** start of a transaction, and is thus usually less than a few thousand,
-** but can be as large as 2 billion for a really big database.
-**
-** @(#) $Id: bitvec.c,v 1.17 2009/07/25 17:33:26 drh Exp $
-*/
-
-/* Size of the Bitvec structure in bytes. */
-#define BITVEC_SZ (sizeof(void*)*128) /* 512 on 32bit. 1024 on 64bit */
-
-/* Round the union size down to the nearest pointer boundary, since that's how
-** it will be aligned within the Bitvec struct. */
-#define BITVEC_USIZE (((BITVEC_SZ-(3*sizeof(u32)))/sizeof(Bitvec*))*sizeof(Bitvec*))
-
-/* Type of the array "element" for the bitmap representation.
-** Should be a power of 2, and ideally, evenly divide into BITVEC_USIZE.
-** Setting this to the "natural word" size of your CPU may improve
-** performance. */
-#define BITVEC_TELEM u8
-/* Size, in bits, of the bitmap element. */
-#define BITVEC_SZELEM 8
-/* Number of elements in a bitmap array. */
-#define BITVEC_NELEM (BITVEC_USIZE/sizeof(BITVEC_TELEM))
-/* Number of bits in the bitmap array. */
-#define BITVEC_NBIT (BITVEC_NELEM*BITVEC_SZELEM)
-
-/* Number of u32 values in hash table. */
-#define BITVEC_NINT (BITVEC_USIZE/sizeof(u32))
-/* Maximum number of entries in hash table before
-** sub-dividing and re-hashing. */
-#define BITVEC_MXHASH (BITVEC_NINT/2)
-/* Hashing function for the aHash representation.
-** Empirical testing showed that the *37 multiplier
-** (an arbitrary prime)in the hash function provided
-** no fewer collisions than the no-op *1. */
-#define BITVEC_HASH(X) (((X)*1)%BITVEC_NINT)
-
-#define BITVEC_NPTR (BITVEC_USIZE/sizeof(Bitvec *))
-
-
-/*
-** A bitmap is an instance of the following structure.
-**
-** This bitmap records the existance of zero or more bits
-** with values between 1 and iSize, inclusive.
-**
-** There are three possible representations of the bitmap.
-** If iSize<=BITVEC_NBIT, then Bitvec.u.aBitmap[] is a straight
-** bitmap. The least significant bit is bit 1.
-**
-** If iSize>BITVEC_NBIT and iDivisor==0 then Bitvec.u.aHash[] is
-** a hash table that will hold up to BITVEC_MXHASH distinct values.
-**
-** Otherwise, the value i is redirected into one of BITVEC_NPTR
-** sub-bitmaps pointed to by Bitvec.u.apSub[]. Each subbitmap
-** handles up to iDivisor separate values of i. apSub[0] holds
-** values between 1 and iDivisor. apSub[1] holds values between
-** iDivisor+1 and 2*iDivisor. apSub[N] holds values between
-** N*iDivisor+1 and (N+1)*iDivisor. Each subbitmap is normalized
-** to hold deal with values between 1 and iDivisor.
-*/
-struct Bitvec {
- u32 iSize; /* Maximum bit index. Max iSize is 4,294,967,296. */
- u32 nSet; /* Number of bits that are set - only valid for aHash
- ** element. Max is BITVEC_NINT. For BITVEC_SZ of 512,
- ** this would be 125. */
- u32 iDivisor; /* Number of bits handled by each apSub[] entry. */
- /* Should >=0 for apSub element. */
- /* Max iDivisor is max(u32) / BITVEC_NPTR + 1. */
- /* For a BITVEC_SZ of 512, this would be 34,359,739. */
- union {
- BITVEC_TELEM aBitmap[BITVEC_NELEM]; /* Bitmap representation */
- u32 aHash[BITVEC_NINT]; /* Hash table representation */
- Bitvec *apSub[BITVEC_NPTR]; /* Recursive representation */
- } u;
-};
-
-/*
-** Create a new bitmap object able to handle bits between 0 and iSize,
-** inclusive. Return a pointer to the new object. Return NULL if
-** malloc fails.
-*/
-SQLITE_PRIVATE Bitvec *sqlite3BitvecCreate(u32 iSize){
- Bitvec *p;
- assert( sizeof(*p)==BITVEC_SZ );
- p = sqlite3MallocZero( sizeof(*p) );
- if( p ){
- p->iSize = iSize;
- }
- return p;
-}
-
-/*
-** Check to see if the i-th bit is set. Return true or false.
-** If p is NULL (if the bitmap has not been created) or if
-** i is out of range, then return false.
-*/
-SQLITE_PRIVATE int sqlite3BitvecTest(Bitvec *p, u32 i){
- if( p==0 ) return 0;
- if( i>p->iSize || i==0 ) return 0;
- i--;
- while( p->iDivisor ){
- u32 bin = i/p->iDivisor;
- i = i%p->iDivisor;
- p = p->u.apSub[bin];
- if (!p) {
- return 0;
- }
- }
- if( p->iSize<=BITVEC_NBIT ){
- return (p->u.aBitmap[i/BITVEC_SZELEM] & (1<<(i&(BITVEC_SZELEM-1))))!=0;
- } else{
- u32 h = BITVEC_HASH(i++);
- while( p->u.aHash[h] ){
- if( p->u.aHash[h]==i ) return 1;
- h = (h+1) % BITVEC_NINT;
- }
- return 0;
- }
-}
-
-/*
-** Set the i-th bit. Return 0 on success and an error code if
-** anything goes wrong.
-**
-** This routine might cause sub-bitmaps to be allocated. Failing
-** to get the memory needed to hold the sub-bitmap is the only
-** that can go wrong with an insert, assuming p and i are valid.
-**
-** The calling function must ensure that p is a valid Bitvec object
-** and that the value for "i" is within range of the Bitvec object.
-** Otherwise the behavior is undefined.
-*/
-SQLITE_PRIVATE int sqlite3BitvecSet(Bitvec *p, u32 i){
- u32 h;
- if( p==0 ) return SQLITE_OK;
- assert( i>0 );
- assert( i<=p->iSize );
- i--;
- while((p->iSize > BITVEC_NBIT) && p->iDivisor) {
- u32 bin = i/p->iDivisor;
- i = i%p->iDivisor;
- if( p->u.apSub[bin]==0 ){
- p->u.apSub[bin] = sqlite3BitvecCreate( p->iDivisor );
- if( p->u.apSub[bin]==0 ) return SQLITE_NOMEM;
- }
- p = p->u.apSub[bin];
- }
- if( p->iSize<=BITVEC_NBIT ){
- p->u.aBitmap[i/BITVEC_SZELEM] |= 1 << (i&(BITVEC_SZELEM-1));
- return SQLITE_OK;
- }
- h = BITVEC_HASH(i++);
- /* if there wasn't a hash collision, and this doesn't */
- /* completely fill the hash, then just add it without */
- /* worring about sub-dividing and re-hashing. */
- if( !p->u.aHash[h] ){
- if (p->nSet<(BITVEC_NINT-1)) {
- goto bitvec_set_end;
- } else {
- goto bitvec_set_rehash;
- }
- }
- /* there was a collision, check to see if it's already */
- /* in hash, if not, try to find a spot for it */
- do {
- if( p->u.aHash[h]==i ) return SQLITE_OK;
- h++;
- if( h>=BITVEC_NINT ) h = 0;
- } while( p->u.aHash[h] );
- /* we didn't find it in the hash. h points to the first */
- /* available free spot. check to see if this is going to */
- /* make our hash too "full". */
-bitvec_set_rehash:
- if( p->nSet>=BITVEC_MXHASH ){
- unsigned int j;
- int rc;
- u32 *aiValues = sqlite3StackAllocRaw(0, sizeof(p->u.aHash));
- if( aiValues==0 ){
- return SQLITE_NOMEM;
- }else{
- memcpy(aiValues, p->u.aHash, sizeof(p->u.aHash));
- memset(p->u.apSub, 0, sizeof(p->u.apSub));
- p->iDivisor = (p->iSize + BITVEC_NPTR - 1)/BITVEC_NPTR;
- rc = sqlite3BitvecSet(p, i);
- for(j=0; j<BITVEC_NINT; j++){
- if( aiValues[j] ) rc |= sqlite3BitvecSet(p, aiValues[j]);
- }
- sqlite3StackFree(0, aiValues);
- return rc;
- }
- }
-bitvec_set_end:
- p->nSet++;
- p->u.aHash[h] = i;
- return SQLITE_OK;
-}
-
-/*
-** Clear the i-th bit.
-**
-** pBuf must be a pointer to at least BITVEC_SZ bytes of temporary storage
-** that BitvecClear can use to rebuilt its hash table.
-*/
-SQLITE_PRIVATE void sqlite3BitvecClear(Bitvec *p, u32 i, void *pBuf){
- if( p==0 ) return;
- assert( i>0 );
- i--;
- while( p->iDivisor ){
- u32 bin = i/p->iDivisor;
- i = i%p->iDivisor;
- p = p->u.apSub[bin];
- if (!p) {
- return;
- }
- }
- if( p->iSize<=BITVEC_NBIT ){
- p->u.aBitmap[i/BITVEC_SZELEM] &= ~(1 << (i&(BITVEC_SZELEM-1)));
- }else{
- unsigned int j;
- u32 *aiValues = pBuf;
- memcpy(aiValues, p->u.aHash, sizeof(p->u.aHash));
- memset(p->u.aHash, 0, sizeof(p->u.aHash));
- p->nSet = 0;
- for(j=0; j<BITVEC_NINT; j++){
- if( aiValues[j] && aiValues[j]!=(i+1) ){
- u32 h = BITVEC_HASH(aiValues[j]-1);
- p->nSet++;
- while( p->u.aHash[h] ){
- h++;
- if( h>=BITVEC_NINT ) h = 0;
- }
- p->u.aHash[h] = aiValues[j];
- }
- }
- }
-}
-
-/*
-** Destroy a bitmap object. Reclaim all memory used.
-*/
-SQLITE_PRIVATE void sqlite3BitvecDestroy(Bitvec *p){
- if( p==0 ) return;
- if( p->iDivisor ){
- unsigned int i;
- for(i=0; i<BITVEC_NPTR; i++){
- sqlite3BitvecDestroy(p->u.apSub[i]);
- }
- }
- sqlite3_free(p);
-}
-
-/*
-** Return the value of the iSize parameter specified when Bitvec *p
-** was created.
-*/
-SQLITE_PRIVATE u32 sqlite3BitvecSize(Bitvec *p){
- return p->iSize;
-}
-
-#ifndef SQLITE_OMIT_BUILTIN_TEST
-/*
-** Let V[] be an array of unsigned characters sufficient to hold
-** up to N bits. Let I be an integer between 0 and N. 0<=I<N.
-** Then the following macros can be used to set, clear, or test
-** individual bits within V.
-*/
-#define SETBIT(V,I) V[I>>3] |= (1<<(I&7))
-#define CLEARBIT(V,I) V[I>>3] &= ~(1<<(I&7))
-#define TESTBIT(V,I) (V[I>>3]&(1<<(I&7)))!=0
-
-/*
-** This routine runs an extensive test of the Bitvec code.
-**
-** The input is an array of integers that acts as a program
-** to test the Bitvec. The integers are opcodes followed
-** by 0, 1, or 3 operands, depending on the opcode. Another
-** opcode follows immediately after the last operand.
-**
-** There are 6 opcodes numbered from 0 through 5. 0 is the
-** "halt" opcode and causes the test to end.
-**
-** 0 Halt and return the number of errors
-** 1 N S X Set N bits beginning with S and incrementing by X
-** 2 N S X Clear N bits beginning with S and incrementing by X
-** 3 N Set N randomly chosen bits
-** 4 N Clear N randomly chosen bits
-** 5 N S X Set N bits from S increment X in array only, not in bitvec
-**
-** The opcodes 1 through 4 perform set and clear operations are performed
-** on both a Bitvec object and on a linear array of bits obtained from malloc.
-** Opcode 5 works on the linear array only, not on the Bitvec.
-** Opcode 5 is used to deliberately induce a fault in order to
-** confirm that error detection works.
-**
-** At the conclusion of the test the linear array is compared
-** against the Bitvec object. If there are any differences,
-** an error is returned. If they are the same, zero is returned.
-**
-** If a memory allocation error occurs, return -1.
-*/
-SQLITE_PRIVATE int sqlite3BitvecBuiltinTest(int sz, int *aOp){
- Bitvec *pBitvec = 0;
- unsigned char *pV = 0;
- int rc = -1;
- int i, nx, pc, op;
- void *pTmpSpace;
-
- /* Allocate the Bitvec to be tested and a linear array of
- ** bits to act as the reference */
- pBitvec = sqlite3BitvecCreate( sz );
- pV = sqlite3_malloc( (sz+7)/8 + 1 );
- pTmpSpace = sqlite3_malloc(BITVEC_SZ);
- if( pBitvec==0 || pV==0 || pTmpSpace==0 ) goto bitvec_end;
- memset(pV, 0, (sz+7)/8 + 1);
-
- /* NULL pBitvec tests */
- sqlite3BitvecSet(0, 1);
- sqlite3BitvecClear(0, 1, pTmpSpace);
-
- /* Run the program */
- pc = 0;
- while( (op = aOp[pc])!=0 ){
- switch( op ){
- case 1:
- case 2:
- case 5: {
- nx = 4;
- i = aOp[pc+2] - 1;
- aOp[pc+2] += aOp[pc+3];
- break;
- }
- case 3:
- case 4:
- default: {
- nx = 2;
- sqlite3_randomness(sizeof(i), &i);
- break;
- }
- }
- if( (--aOp[pc+1]) > 0 ) nx = 0;
- pc += nx;
- i = (i & 0x7fffffff)%sz;
- if( (op & 1)!=0 ){
- SETBIT(pV, (i+1));
- if( op!=5 ){
- if( sqlite3BitvecSet(pBitvec, i+1) ) goto bitvec_end;
- }
- }else{
- CLEARBIT(pV, (i+1));
- sqlite3BitvecClear(pBitvec, i+1, pTmpSpace);
- }
- }
-
- /* Test to make sure the linear array exactly matches the
- ** Bitvec object. Start with the assumption that they do
- ** match (rc==0). Change rc to non-zero if a discrepancy
- ** is found.
- */
- rc = sqlite3BitvecTest(0,0) + sqlite3BitvecTest(pBitvec, sz+1)
- + sqlite3BitvecTest(pBitvec, 0)
- + (sqlite3BitvecSize(pBitvec) - sz);
- for(i=1; i<=sz; i++){
- if( (TESTBIT(pV,i))!=sqlite3BitvecTest(pBitvec,i) ){
- rc = i;
- break;
- }
- }
-
- /* Free allocated structure */
-bitvec_end:
- sqlite3_free(pTmpSpace);
- sqlite3_free(pV);
- sqlite3BitvecDestroy(pBitvec);
- return rc;
-}
-#endif /* SQLITE_OMIT_BUILTIN_TEST */
-
-/************** End of bitvec.c **********************************************/
-/************** Begin file pcache.c ******************************************/
-/*
-** 2008 August 05
-**
-** 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 that page cache.
-**
-** @(#) $Id: pcache.c,v 1.47 2009/07/25 11:46:49 danielk1977 Exp $
-*/
-
-/*
-** A complete page cache is an instance of this structure.
-*/
-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 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 */
- int (*xStress)(void*,PgHdr*); /* Call to try make a page clean */
- void *pStress; /* Argument to xStress */
- sqlite3_pcache *pCache; /* Pluggable cache module */
- PgHdr *pPage1; /* Reference to page 1 */
-};
-
-/*
-** Some of the assert() macros in this code are too expensive to run
-** even during normal debugging. Use them only rarely on long-running
-** tests. Enable the expensive asserts using the
-** -DSQLITE_ENABLE_EXPENSIVE_ASSERT=1 compile-time option.
-*/
-#ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT
-# define expensive_assert(X) assert(X)
-#else
-# define expensive_assert(X)
-#endif
-
-/********************************** Linked List Management ********************/
-
-#if !defined(NDEBUG) && defined(SQLITE_ENABLE_EXPENSIVE_ASSERT)
-/*
-** Check that the pCache->pSynced variable is set correctly. If it
-** is not, either fail an assert or return zero. Otherwise, return
-** non-zero. This is only used in debugging builds, as follows:
-**
-** expensive_assert( pcacheCheckSynced(pCache) );
-*/
-static int pcacheCheckSynced(PCache *pCache){
- PgHdr *p;
- for(p=pCache->pDirtyTail; p!=pCache->pSynced; p=p->pDirtyPrev){
- assert( p->nRef || (p->flags&PGHDR_NEED_SYNC) );
- }
- return (p==0 || p->nRef || (p->flags&PGHDR_NEED_SYNC)==0);
-}
-#endif /* !NDEBUG && SQLITE_ENABLE_EXPENSIVE_ASSERT */
-
-/*
-** Remove page pPage from the list of dirty pages.
-*/
-static void pcacheRemoveFromDirtyList(PgHdr *pPage){
- PCache *p = pPage->pCache;
-
- assert( pPage->pDirtyNext || pPage==p->pDirtyTail );
- assert( pPage->pDirtyPrev || pPage==p->pDirty );
-
- /* Update the PCache1.pSynced variable if necessary. */
- if( p->pSynced==pPage ){
- PgHdr *pSynced = pPage->pDirtyPrev;
- while( pSynced && (pSynced->flags&PGHDR_NEED_SYNC) ){
- pSynced = pSynced->pDirtyPrev;
- }
- p->pSynced = pSynced;
- }
-
- if( pPage->pDirtyNext ){
- pPage->pDirtyNext->pDirtyPrev = pPage->pDirtyPrev;
- }else{
- assert( pPage==p->pDirtyTail );
- p->pDirtyTail = pPage->pDirtyPrev;
- }
- if( pPage->pDirtyPrev ){
- pPage->pDirtyPrev->pDirtyNext = pPage->pDirtyNext;
- }else{
- assert( pPage==p->pDirty );
- p->pDirty = pPage->pDirtyNext;
- }
- pPage->pDirtyNext = 0;
- pPage->pDirtyPrev = 0;
-
- expensive_assert( pcacheCheckSynced(p) );
-}
-
-/*
-** Add page pPage to the head of the dirty list (PCache1.pDirty is set to
-** pPage).
-*/
-static void pcacheAddToDirtyList(PgHdr *pPage){
- PCache *p = pPage->pCache;
-
- assert( pPage->pDirtyNext==0 && pPage->pDirtyPrev==0 && p->pDirty!=pPage );
-
- pPage->pDirtyNext = p->pDirty;
- if( pPage->pDirtyNext ){
- assert( pPage->pDirtyNext->pDirtyPrev==0 );
- pPage->pDirtyNext->pDirtyPrev = pPage;
- }
- p->pDirty = pPage;
- if( !p->pDirtyTail ){
- p->pDirtyTail = pPage;
- }
- if( !p->pSynced && 0==(pPage->flags&PGHDR_NEED_SYNC) ){
- p->pSynced = pPage;
- }
- expensive_assert( pcacheCheckSynced(p) );
-}
-
-/*
-** Wrapper around the pluggable caches xUnpin method. If the cache is
-** being used for an in-memory database, this function is a no-op.
-*/
-static void pcacheUnpin(PgHdr *p){
- PCache *pCache = p->pCache;
- if( pCache->bPurgeable ){
- if( p->pgno==1 ){
- pCache->pPage1 = 0;
- }
- sqlite3GlobalConfig.pcache.xUnpin(pCache->pCache, p, 0);
- }
-}
-
-/*************************************************** General Interfaces ******
-**
-** Initialize and shutdown the page cache subsystem. Neither of these
-** functions are threadsafe.
-*/
-SQLITE_PRIVATE int sqlite3PcacheInitialize(void){
- if( sqlite3GlobalConfig.pcache.xInit==0 ){
- sqlite3PCacheSetDefault();
- }
- return sqlite3GlobalConfig.pcache.xInit(sqlite3GlobalConfig.pcache.pArg);
-}
-SQLITE_PRIVATE void sqlite3PcacheShutdown(void){
- if( sqlite3GlobalConfig.pcache.xShutdown ){
- sqlite3GlobalConfig.pcache.xShutdown(sqlite3GlobalConfig.pcache.pArg);
- }
-}
-
-/*
-** Return the size in bytes of a PCache object.
-*/
-SQLITE_PRIVATE int sqlite3PcacheSize(void){ return sizeof(PCache); }
-
-/*
-** Create a new PCache object. Storage space to hold the object
-** has already been allocated and is passed in as the p pointer.
-** The caller discovers how much space needs to be allocated by
-** calling sqlite3PcacheSize().
-*/
-SQLITE_PRIVATE void sqlite3PcacheOpen(
- int szPage, /* Size of every page */
- int szExtra, /* Extra space associated with each page */
- int bPurgeable, /* True if pages are on backing store */
- int (*xStress)(void*,PgHdr*),/* Call to try to make pages clean */
- void *pStress, /* Argument to xStress */
- PCache *p /* Preallocated space for the PCache */
-){
- memset(p, 0, sizeof(PCache));
- p->szPage = szPage;
- p->szExtra = szExtra;
- p->bPurgeable = bPurgeable;
- p->xStress = xStress;
- p->pStress = pStress;
- p->nMax = 100;
-}
-
-/*
-** Change the page size for PCache object. The caller must ensure that there
-** are no outstanding page references when this function is called.
-*/
-SQLITE_PRIVATE void sqlite3PcacheSetPageSize(PCache *pCache, int szPage){
- assert( pCache->nRef==0 && pCache->pDirty==0 );
- if( pCache->pCache ){
- sqlite3GlobalConfig.pcache.xDestroy(pCache->pCache);
- pCache->pCache = 0;
- }
- pCache->szPage = szPage;
-}
-
-/*
-** Try to obtain a page from the cache.
-*/
-SQLITE_PRIVATE int sqlite3PcacheFetch(
- PCache *pCache, /* Obtain the page from this cache */
- Pgno pgno, /* Page number to obtain */
- int createFlag, /* If true, create page if it does not exist already */
- PgHdr **ppPage /* Write the page here */
-){
- PgHdr *pPage = 0;
- int eCreate;
-
- assert( pCache!=0 );
- assert( createFlag==1 || createFlag==0 );
- assert( pgno>0 );
-
- /* If the pluggable cache (sqlite3_pcache*) has not been allocated,
- ** allocate it now.
- */
- if( !pCache->pCache && createFlag ){
- sqlite3_pcache *p;
- int nByte;
- nByte = pCache->szPage + pCache->szExtra + sizeof(PgHdr);
- p = sqlite3GlobalConfig.pcache.xCreate(nByte, pCache->bPurgeable);
- if( !p ){
- return SQLITE_NOMEM;
- }
- sqlite3GlobalConfig.pcache.xCachesize(p, pCache->nMax);
- pCache->pCache = p;
- }
-
- eCreate = createFlag * (1 + (!pCache->bPurgeable || !pCache->pDirty));
- if( pCache->pCache ){
- pPage = sqlite3GlobalConfig.pcache.xFetch(pCache->pCache, pgno, eCreate);
- }
-
- if( !pPage && eCreate==1 ){
- PgHdr *pPg;
-
- /* Find a dirty page to write-out and recycle. First try to find a
- ** page that does not require a journal-sync (one with PGHDR_NEED_SYNC
- ** cleared), but if that is not possible settle for any other
- ** unreferenced dirty page.
- */
- expensive_assert( pcacheCheckSynced(pCache) );
- for(pPg=pCache->pSynced;
- pPg && (pPg->nRef || (pPg->flags&PGHDR_NEED_SYNC));
- pPg=pPg->pDirtyPrev
- );
- if( !pPg ){
- for(pPg=pCache->pDirtyTail; pPg && pPg->nRef; pPg=pPg->pDirtyPrev);
- }
- if( pPg ){
- int rc;
- rc = pCache->xStress(pCache->pStress, pPg);
- if( rc!=SQLITE_OK && rc!=SQLITE_BUSY ){
- return rc;
- }
- }
-
- pPage = sqlite3GlobalConfig.pcache.xFetch(pCache->pCache, pgno, 2);
- }
-
- if( pPage ){
- if( !pPage->pData ){
- memset(pPage, 0, sizeof(PgHdr) + pCache->szExtra);
- pPage->pExtra = (void*)&pPage[1];
- pPage->pData = (void *)&((char *)pPage)[sizeof(PgHdr) + pCache->szExtra];
- pPage->pCache = pCache;
- pPage->pgno = pgno;
- }
- assert( pPage->pCache==pCache );
- assert( pPage->pgno==pgno );
- assert( pPage->pExtra==(void *)&pPage[1] );
-
- if( 0==pPage->nRef ){
- pCache->nRef++;
- }
- pPage->nRef++;
- if( pgno==1 ){
- pCache->pPage1 = pPage;
- }
- }
- *ppPage = pPage;
- return (pPage==0 && eCreate) ? SQLITE_NOMEM : SQLITE_OK;
-}
-
-/*
-** Decrement the reference count on a page. If the page is clean and the
-** reference count drops to 0, then it is made elible for recycling.
-*/
-SQLITE_PRIVATE void sqlite3PcacheRelease(PgHdr *p){
- assert( p->nRef>0 );
- p->nRef--;
- if( p->nRef==0 ){
- PCache *pCache = p->pCache;
- pCache->nRef--;
- if( (p->flags&PGHDR_DIRTY)==0 ){
- pcacheUnpin(p);
- }else{
- /* Move the page to the head of the dirty list. */
- pcacheRemoveFromDirtyList(p);
- pcacheAddToDirtyList(p);
- }
- }
-}
-
-/*
-** Increase the reference count of a supplied page by 1.
-*/
-SQLITE_PRIVATE void sqlite3PcacheRef(PgHdr *p){
- assert(p->nRef>0);
- p->nRef++;
-}
-
-/*
-** Drop a page from the cache. There must be exactly one reference to the
-** page. This function deletes that reference, so after it returns the
-** page pointed to by p is invalid.
-*/
-SQLITE_PRIVATE void sqlite3PcacheDrop(PgHdr *p){
- PCache *pCache;
- assert( p->nRef==1 );
- if( p->flags&PGHDR_DIRTY ){
- pcacheRemoveFromDirtyList(p);
- }
- pCache = p->pCache;
- pCache->nRef--;
- if( p->pgno==1 ){
- pCache->pPage1 = 0;
- }
- sqlite3GlobalConfig.pcache.xUnpin(pCache->pCache, p, 1);
-}
-
-/*
-** Make sure the page is marked as dirty. If it isn't dirty already,
-** make it so.
-*/
-SQLITE_PRIVATE void sqlite3PcacheMakeDirty(PgHdr *p){
- p->flags &= ~PGHDR_DONT_WRITE;
- assert( p->nRef>0 );
- if( 0==(p->flags & PGHDR_DIRTY) ){
- p->flags |= PGHDR_DIRTY;
- pcacheAddToDirtyList( p);
- }
-}
-
-/*
-** Make sure the page is marked as clean. If it isn't clean already,
-** make it so.
-*/
-SQLITE_PRIVATE void sqlite3PcacheMakeClean(PgHdr *p){
- if( (p->flags & PGHDR_DIRTY) ){
- pcacheRemoveFromDirtyList(p);
- p->flags &= ~(PGHDR_DIRTY|PGHDR_NEED_SYNC);
- if( p->nRef==0 ){
- pcacheUnpin(p);
- }
- }
-}
-
-/*
-** Make every page in the cache clean.
-*/
-SQLITE_PRIVATE void sqlite3PcacheCleanAll(PCache *pCache){
- PgHdr *p;
- while( (p = pCache->pDirty)!=0 ){
- sqlite3PcacheMakeClean(p);
- }
-}
-
-/*
-** Clear the PGHDR_NEED_SYNC flag from all dirty pages.
-*/
-SQLITE_PRIVATE void sqlite3PcacheClearSyncFlags(PCache *pCache){
- PgHdr *p;
- for(p=pCache->pDirty; p; p=p->pDirtyNext){
- p->flags &= ~PGHDR_NEED_SYNC;
- }
- pCache->pSynced = pCache->pDirtyTail;
-}
-
-/*
-** Change the page number of page p to newPgno.
-*/
-SQLITE_PRIVATE 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);
- p->pgno = newPgno;
- if( (p->flags&PGHDR_DIRTY) && (p->flags&PGHDR_NEED_SYNC) ){
- pcacheRemoveFromDirtyList(p);
- pcacheAddToDirtyList(p);
- }
-}
-
-/*
-** Drop every cache entry whose page number is greater than "pgno". The
-** caller must ensure that there are no outstanding references to any pages
-** other than page 1 with a page number greater than pgno.
-**
-** If there is a reference to page 1 and the pgno parameter passed to this
-** function is 0, then the data area associated with page 1 is zeroed, but
-** the page object is not dropped.
-*/
-SQLITE_PRIVATE void sqlite3PcacheTruncate(PCache *pCache, Pgno pgno){
- if( pCache->pCache ){
- PgHdr *p;
- PgHdr *pNext;
- for(p=pCache->pDirty; p; p=pNext){
- pNext = p->pDirtyNext;
- if( p->pgno>pgno ){
- assert( p->flags&PGHDR_DIRTY );
- sqlite3PcacheMakeClean(p);
- }
- }
- if( pgno==0 && pCache->pPage1 ){
- memset(pCache->pPage1->pData, 0, pCache->szPage);
- pgno = 1;
- }
- sqlite3GlobalConfig.pcache.xTruncate(pCache->pCache, pgno+1);
- }
-}
-
-/*
-** Close a cache.
-*/
-SQLITE_PRIVATE void sqlite3PcacheClose(PCache *pCache){
- if( pCache->pCache ){
- sqlite3GlobalConfig.pcache.xDestroy(pCache->pCache);
- }
-}
-
-/*
-** Discard the contents of the cache.
-*/
-SQLITE_PRIVATE void sqlite3PcacheClear(PCache *pCache){
- sqlite3PcacheTruncate(pCache, 0);
-}
-
-/*
-** Merge two lists of pages connected by pDirty and in pgno order.
-** Do not both fixing the pDirtyPrev pointers.
-*/
-static PgHdr *pcacheMergeDirtyList(PgHdr *pA, PgHdr *pB){
- PgHdr result, *pTail;
- pTail = &result;
- while( pA && pB ){
- if( pA->pgno<pB->pgno ){
- pTail->pDirty = pA;
- pTail = pA;
- pA = pA->pDirty;
- }else{
- pTail->pDirty = pB;
- pTail = pB;
- pB = pB->pDirty;
- }
- }
- if( pA ){
- pTail->pDirty = pA;
- }else if( pB ){
- pTail->pDirty = pB;
- }else{
- pTail->pDirty = 0;
- }
- return result.pDirty;
-}
-
-/*
-** Sort the list of pages in accending order by pgno. Pages are
-** connected by pDirty pointers. The pDirtyPrev pointers are
-** corrupted by this sort.
-**
-** Since there cannot be more than 2^31 distinct pages in a database,
-** there cannot be more than 31 buckets required by the merge sorter.
-** One extra bucket is added to catch overflow in case something
-** ever changes to make the previous sentence incorrect.
-*/
-#define N_SORT_BUCKET 32
-static PgHdr *pcacheSortDirtyList(PgHdr *pIn){
- PgHdr *a[N_SORT_BUCKET], *p;
- int i;
- memset(a, 0, sizeof(a));
- while( pIn ){
- p = pIn;
- pIn = p->pDirty;
- p->pDirty = 0;
- for(i=0; ALWAYS(i<N_SORT_BUCKET-1); i++){
- if( a[i]==0 ){
- a[i] = p;
- break;
- }else{
- p = pcacheMergeDirtyList(a[i], p);
- a[i] = 0;
- }
- }
- if( NEVER(i==N_SORT_BUCKET-1) ){
- /* To get here, there need to be 2^(N_SORT_BUCKET) elements in
- ** the input list. But that is impossible.
- */
- a[i] = pcacheMergeDirtyList(a[i], p);
- }
- }
- p = a[0];
- for(i=1; i<N_SORT_BUCKET; i++){
- p = pcacheMergeDirtyList(p, a[i]);
- }
- return p;
-}
-
-/*
-** Return a list of all dirty pages in the cache, sorted by page number.
-*/
-SQLITE_PRIVATE PgHdr *sqlite3PcacheDirtyList(PCache *pCache){
- PgHdr *p;
- for(p=pCache->pDirty; p; p=p->pDirtyNext){
- p->pDirty = p->pDirtyNext;
- }
- return pcacheSortDirtyList(pCache->pDirty);
-}
-
-/*
-** Return the total number of referenced pages held by the cache.
-*/
-SQLITE_PRIVATE int sqlite3PcacheRefCount(PCache *pCache){
- return pCache->nRef;
-}
-
-/*
-** Return the number of references to the page supplied as an argument.
-*/
-SQLITE_PRIVATE int sqlite3PcachePageRefcount(PgHdr *p){
- return p->nRef;
-}
-
-/*
-** Return the total number of pages in the cache.
-*/
-SQLITE_PRIVATE int sqlite3PcachePagecount(PCache *pCache){
- int nPage = 0;
- if( pCache->pCache ){
- nPage = sqlite3GlobalConfig.pcache.xPagecount(pCache->pCache);
- }
- return nPage;
-}
-
-#ifdef SQLITE_TEST
-/*
-** Get the suggested cache-size value.
-*/
-SQLITE_PRIVATE int sqlite3PcacheGetCachesize(PCache *pCache){
- return pCache->nMax;
-}
-#endif
-
-/*
-** Set the suggested cache-size value.
-*/
-SQLITE_PRIVATE void sqlite3PcacheSetCachesize(PCache *pCache, int mxPage){
- pCache->nMax = mxPage;
- if( pCache->pCache ){
- sqlite3GlobalConfig.pcache.xCachesize(pCache->pCache, mxPage);
- }
-}
-
-#if defined(SQLITE_CHECK_PAGES) || defined(SQLITE_DEBUG)
-/*
-** For all dirty pages currently in the cache, invoke the specified
-** callback. This is only used if the SQLITE_CHECK_PAGES macro is
-** defined.
-*/
-SQLITE_PRIVATE void sqlite3PcacheIterateDirty(PCache *pCache, void (*xIter)(PgHdr *)){
- PgHdr *pDirty;
- for(pDirty=pCache->pDirty; pDirty; pDirty=pDirty->pDirtyNext){
- xIter(pDirty);
- }
-}
-#endif
-
-/************** End of pcache.c **********************************************/
-/************** Begin file pcache1.c *****************************************/
-/*
-** 2008 November 05
-**
-** 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 the default page cache implementation (the
-** sqlite3_pcache interface). It also contains part of the implementation
-** of the SQLITE_CONFIG_PAGECACHE and sqlite3_release_memory() features.
-** If the default page cache implementation is overriden, then neither of
-** these two features are available.
-**
-** @(#) $Id: pcache1.c,v 1.19 2009/07/17 11:44:07 drh Exp $
-*/
-
-
-typedef struct PCache1 PCache1;
-typedef struct PgHdr1 PgHdr1;
-typedef struct PgFreeslot PgFreeslot;
-
-/* Pointers to structures of this type are cast and returned as
-** opaque sqlite3_pcache* handles
-*/
-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.
- ** The global mutex must be held when accessing nMax.
- */
- int szPage; /* Size of allocated pages in bytes */
- int bPurgeable; /* True if cache is purgeable */
- unsigned int nMin; /* Minimum number of pages reserved */
- unsigned int nMax; /* Configured "cache_size" value */
-
- /* Hash table of all pages. The following variables may only be accessed
- ** when the accessor is holding the global mutex (see pcache1EnterMutex()
- ** and pcache1LeaveMutex()).
- */
- unsigned int nRecyclable; /* Number of pages in the LRU list */
- unsigned int nPage; /* Total number of pages in apHash */
- unsigned int nHash; /* Number of slots in apHash[] */
- PgHdr1 **apHash; /* Hash table for fast lookup by key */
-
- unsigned int iMaxKey; /* Largest key seen since xTruncate() */
-};
-
-/*
-** 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).
-*/
-struct PgHdr1 {
- unsigned int iKey; /* Key value (page number) */
- PgHdr1 *pNext; /* Next in hash table chain */
- PCache1 *pCache; /* Cache that currently owns this page */
- PgHdr1 *pLruNext; /* Next in LRU list of unpinned pages */
- PgHdr1 *pLruPrev; /* Previous in LRU list of unpinned pages */
-};
-
-/*
-** Free slots in the allocator used to divide up the buffer provided using
-** the SQLITE_CONFIG_PAGECACHE mechanism.
-*/
-struct PgFreeslot {
- PgFreeslot *pNext; /* Next free slot */
-};
-
-/*
-** Global data used by this cache.
-*/
-static SQLITE_WSD struct PCacheGlobal {
- sqlite3_mutex *mutex; /* static mutex MUTEX_STATIC_LRU */
-
- int nMaxPage; /* Sum of nMaxPage for purgeable caches */
- int nMinPage; /* Sum of nMinPage for purgeable caches */
- int nCurrentPage; /* Number of purgeable pages allocated */
- PgHdr1 *pLruHead, *pLruTail; /* LRU list of unpinned pages */
-
- /* Variables related to SQLITE_CONFIG_PAGECACHE settings. */
- int szSlot; /* Size of each free slot */
- void *pStart, *pEnd; /* Bounds of pagecache malloc range */
- PgFreeslot *pFree; /* Free page blocks */
- int isInit; /* True if initialized */
-} pcache1_g;
-
-/*
-** All code in this file should access the global structure above via the
-** alias "pcache1". This ensures that the WSD emulation is used when
-** compiling for systems that do not support real WSD.
-*/
-#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 global LRU mutex.
-*/
-#define pcache1EnterMutex() sqlite3_mutex_enter(pcache1.mutex)
-#define pcache1LeaveMutex() sqlite3_mutex_leave(pcache1.mutex)
-
-/******************************************************************************/
-/******** Page Allocation/SQLITE_CONFIG_PCACHE Related Functions **************/
-
-/*
-** This function is called during initialization if a static buffer is
-** supplied to use for the page-cache by passing the SQLITE_CONFIG_PAGECACHE
-** verb to sqlite3_config(). Parameter pBuf points to an allocation large
-** enough to contain 'n' buffers of 'sz' bytes each.
-*/
-SQLITE_PRIVATE void sqlite3PCacheBufferSetup(void *pBuf, int sz, int n){
- if( pcache1.isInit ){
- PgFreeslot *p;
- sz = ROUNDDOWN8(sz);
- pcache1.szSlot = sz;
- pcache1.pStart = pBuf;
- pcache1.pFree = 0;
- while( n-- ){
- p = (PgFreeslot*)pBuf;
- p->pNext = pcache1.pFree;
- pcache1.pFree = p;
- pBuf = (void*)&((char*)pBuf)[sz];
- }
- pcache1.pEnd = pBuf;
- }
-}
-
-/*
-** Malloc function used within this file to allocate space from the buffer
-** configured using sqlite3_config(SQLITE_CONFIG_PAGECACHE) option. If no
-** such buffer exists or there is no space left in it, this function falls
-** back to sqlite3Malloc().
-*/
-static void *pcache1Alloc(int nByte){
- void *p;
- assert( sqlite3_mutex_held(pcache1.mutex) );
- if( nByte<=pcache1.szSlot && pcache1.pFree ){
- assert( pcache1.isInit );
- p = (PgHdr1 *)pcache1.pFree;
- pcache1.pFree = pcache1.pFree->pNext;
- sqlite3StatusSet(SQLITE_STATUS_PAGECACHE_SIZE, nByte);
- sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_USED, 1);
- }else{
-
- /* Allocate a new buffer using sqlite3Malloc. Before doing so, exit the
- ** global pcache mutex and unlock the pager-cache object pCache. This is
- ** so that if the attempt to allocate a new buffer causes the the
- ** configured soft-heap-limit to be breached, it will be possible to
- ** reclaim memory from this pager-cache.
- */
- pcache1LeaveMutex();
- p = sqlite3Malloc(nByte);
- pcache1EnterMutex();
- if( p ){
- int sz = sqlite3MallocSize(p);
- sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_OVERFLOW, sz);
- }
- }
- return p;
-}
-
-/*
-** Free an allocated buffer obtained from pcache1Alloc().
-*/
-static void pcache1Free(void *p){
- assert( sqlite3_mutex_held(pcache1.mutex) );
- if( p==0 ) return;
- if( p>=pcache1.pStart && p<pcache1.pEnd ){
- PgFreeslot *pSlot;
- sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_USED, -1);
- pSlot = (PgFreeslot*)p;
- pSlot->pNext = pcache1.pFree;
- pcache1.pFree = pSlot;
- }else{
- int iSize = sqlite3MallocSize(p);
- sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_OVERFLOW, -iSize);
- sqlite3_free(p);
- }
-}
-
-/*
-** Allocate a new page object initially associated with cache pCache.
-*/
-static PgHdr1 *pcache1AllocPage(PCache1 *pCache){
- int nByte = sizeof(PgHdr1) + pCache->szPage;
- void *pPg = pcache1Alloc(nByte);
- PgHdr1 *p;
- if( pPg ){
- p = PAGE_TO_PGHDR1(pCache, pPg);
- if( pCache->bPurgeable ){
- pcache1.nCurrentPage++;
- }
- }else{
- p = 0;
- }
- return p;
-}
-
-/*
-** Free a page object allocated by pcache1AllocPage().
-**
-** The pointer is allowed to be NULL, which is prudent. But it turns out
-** that the current implementation happens to never call this routine
-** with a NULL pointer, so we mark the NULL test with ALWAYS().
-*/
-static void pcache1FreePage(PgHdr1 *p){
- if( ALWAYS(p) ){
- if( p->pCache->bPurgeable ){
- pcache1.nCurrentPage--;
- }
- pcache1Free(PGHDR1_TO_PAGE(p));
- }
-}
-
-/*
-** Malloc function used by SQLite to obtain space from the buffer configured
-** using sqlite3_config(SQLITE_CONFIG_PAGECACHE) option. If no such buffer
-** exists, this function falls back to sqlite3Malloc().
-*/
-SQLITE_PRIVATE void *sqlite3PageMalloc(int sz){
- void *p;
- pcache1EnterMutex();
- p = pcache1Alloc(sz);
- pcache1LeaveMutex();
- return p;
-}
-
-/*
-** Free an allocated buffer obtained from sqlite3PageMalloc().
-*/
-SQLITE_PRIVATE void sqlite3PageFree(void *p){
- pcache1EnterMutex();
- pcache1Free(p);
- pcache1LeaveMutex();
-}
-
-/******************************************************************************/
-/******** General Implementation Functions ************************************/
-
-/*
-** This function is used to resize the hash table used by the cache passed
-** as the first argument.
-**
-** The global mutex must be held when this function is called.
-*/
-static int pcache1ResizeHash(PCache1 *p){
- PgHdr1 **apNew;
- unsigned int nNew;
- unsigned int i;
-
- assert( sqlite3_mutex_held(pcache1.mutex) );
-
- nNew = p->nHash*2;
- if( nNew<256 ){
- nNew = 256;
- }
-
- pcache1LeaveMutex();
- if( p->nHash ){ sqlite3BeginBenignMalloc(); }
- apNew = (PgHdr1 **)sqlite3_malloc(sizeof(PgHdr1 *)*nNew);
- if( p->nHash ){ sqlite3EndBenignMalloc(); }
- pcache1EnterMutex();
- if( apNew ){
- memset(apNew, 0, sizeof(PgHdr1 *)*nNew);
- for(i=0; i<p->nHash; i++){
- PgHdr1 *pPage;
- PgHdr1 *pNext = p->apHash[i];
- while( (pPage = pNext)!=0 ){
- unsigned int h = pPage->iKey % nNew;
- pNext = pPage->pNext;
- pPage->pNext = apNew[h];
- apNew[h] = pPage;
- }
- }
- sqlite3_free(p->apHash);
- p->apHash = apNew;
- p->nHash = nNew;
- }
-
- return (p->apHash ? SQLITE_OK : SQLITE_NOMEM);
-}
-
-/*
-** This function is used internally to remove the page pPage from the
-** global LRU list, if is part of it. If pPage is not part of the global
-** LRU list, then this function is a no-op.
-**
-** The global mutex must be held when this function is called.
-*/
-static void pcache1PinPage(PgHdr1 *pPage){
- assert( sqlite3_mutex_held(pcache1.mutex) );
- if( pPage && (pPage->pLruNext || pPage==pcache1.pLruTail) ){
- if( pPage->pLruPrev ){
- pPage->pLruPrev->pLruNext = pPage->pLruNext;
- }
- if( pPage->pLruNext ){
- pPage->pLruNext->pLruPrev = pPage->pLruPrev;
- }
- if( pcache1.pLruHead==pPage ){
- pcache1.pLruHead = pPage->pLruNext;
- }
- if( pcache1.pLruTail==pPage ){
- pcache1.pLruTail = pPage->pLruPrev;
- }
- pPage->pLruNext = 0;
- pPage->pLruPrev = 0;
- pPage->pCache->nRecyclable--;
- }
-}
-
-
-/*
-** Remove the page supplied as an argument from the hash table
-** (PCache1.apHash structure) that it is currently stored in.
-**
-** The global mutex must be held when this function is called.
-*/
-static void pcache1RemoveFromHash(PgHdr1 *pPage){
- unsigned int h;
- PCache1 *pCache = pPage->pCache;
- PgHdr1 **pp;
-
- h = pPage->iKey % pCache->nHash;
- for(pp=&pCache->apHash[h]; (*pp)!=pPage; pp=&(*pp)->pNext);
- *pp = (*pp)->pNext;
-
- pCache->nPage--;
-}
-
-/*
-** If there are currently more than pcache.nMaxPage pages allocated, try
-** to recycle pages to reduce the number allocated to pcache.nMaxPage.
-*/
-static void pcache1EnforceMaxPage(void){
- assert( sqlite3_mutex_held(pcache1.mutex) );
- while( pcache1.nCurrentPage>pcache1.nMaxPage && pcache1.pLruTail ){
- PgHdr1 *p = pcache1.pLruTail;
- pcache1PinPage(p);
- pcache1RemoveFromHash(p);
- pcache1FreePage(p);
- }
-}
-
-/*
-** Discard all pages from cache pCache with a page number (key value)
-** greater than or equal to iLimit. Any pinned pages that meet this
-** criteria are unpinned before they are discarded.
-**
-** The global mutex must be held when this function is called.
-*/
-static void pcache1TruncateUnsafe(
- PCache1 *pCache,
- unsigned int iLimit
-){
- TESTONLY( unsigned int nPage = 0; ) /* Used to assert pCache->nPage is correct */
- unsigned int h;
- assert( sqlite3_mutex_held(pcache1.mutex) );
- for(h=0; h<pCache->nHash; h++){
- PgHdr1 **pp = &pCache->apHash[h];
- PgHdr1 *pPage;
- while( (pPage = *pp)!=0 ){
- if( pPage->iKey>=iLimit ){
- pCache->nPage--;
- *pp = pPage->pNext;
- pcache1PinPage(pPage);
- pcache1FreePage(pPage);
- }else{
- pp = &pPage->pNext;
- TESTONLY( nPage++; )
- }
- }
- }
- assert( pCache->nPage==nPage );
-}
-
-/******************************************************************************/
-/******** sqlite3_pcache Methods **********************************************/
-
-/*
-** Implementation of the sqlite3_pcache.xInit method.
-*/
-static int pcache1Init(void *NotUsed){
- UNUSED_PARAMETER(NotUsed);
- assert( pcache1.isInit==0 );
- memset(&pcache1, 0, sizeof(pcache1));
- if( sqlite3GlobalConfig.bCoreMutex ){
- pcache1.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU);
- }
- pcache1.isInit = 1;
- return SQLITE_OK;
-}
-
-/*
-** Implementation of the sqlite3_pcache.xShutdown method.
-** Note that the static mutex allocated in xInit does
-** not need to be freed.
-*/
-static void pcache1Shutdown(void *NotUsed){
- UNUSED_PARAMETER(NotUsed);
- assert( pcache1.isInit!=0 );
- memset(&pcache1, 0, sizeof(pcache1));
-}
-
-/*
-** Implementation of the sqlite3_pcache.xCreate method.
-**
-** Allocate a new cache.
-*/
-static sqlite3_pcache *pcache1Create(int szPage, int bPurgeable){
- PCache1 *pCache;
-
- pCache = (PCache1 *)sqlite3_malloc(sizeof(PCache1));
- if( pCache ){
- memset(pCache, 0, sizeof(PCache1));
- pCache->szPage = szPage;
- pCache->bPurgeable = (bPurgeable ? 1 : 0);
- if( bPurgeable ){
- pCache->nMin = 10;
- pcache1EnterMutex();
- pcache1.nMinPage += pCache->nMin;
- pcache1LeaveMutex();
- }
- }
- return (sqlite3_pcache *)pCache;
-}
-
-/*
-** Implementation of the sqlite3_pcache.xCachesize method.
-**
-** Configure the cache_size limit for a cache.
-*/
-static void pcache1Cachesize(sqlite3_pcache *p, int nMax){
- PCache1 *pCache = (PCache1 *)p;
- if( pCache->bPurgeable ){
- pcache1EnterMutex();
- pcache1.nMaxPage += (nMax - pCache->nMax);
- pCache->nMax = nMax;
- pcache1EnforceMaxPage();
- pcache1LeaveMutex();
- }
-}
-
-/*
-** Implementation of the sqlite3_pcache.xPagecount method.
-*/
-static int pcache1Pagecount(sqlite3_pcache *p){
- int n;
- pcache1EnterMutex();
- n = ((PCache1 *)p)->nPage;
- pcache1LeaveMutex();
- return n;
-}
-
-/*
-** Implementation of the sqlite3_pcache.xFetch method.
-**
-** Fetch a page by key value.
-**
-** Whether or not a new page may be allocated by this function depends on
-** the value of the createFlag argument. 0 means do not allocate a new
-** page. 1 means allocate a new page if space is easily available. 2
-** means to try really hard to allocate a new page.
-**
-** 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.
-**
-** 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).
-**
-** 1. Regardless of the value of createFlag, the cache is searched for a
-** copy of the requested page. If one is found, it is returned.
-**
-** 2. If createFlag==0 and the page is not already in the cache, NULL is
-** returned.
-**
-** 3. If createFlag is 1, and the page is not already in the cache,
-** and if either of the following are true, return NULL:
-**
-** (a) the number of pages pinned by the cache is greater than
-** PCache1.nMax, or
-** (b) the number of pages pinned by the cache is greater than
-** the sum of nMax for all purgeable caches, less the sum of
-** nMin for all other purgeable caches.
-**
-** 4. If none of the first three conditions apply and the cache is marked
-** as purgeable, and if one of the following is true:
-**
-** (a) The number of pages allocated for the cache is already
-** PCache1.nMax, or
-**
-** (b) The number of pages allocated for all purgeable caches is
-** already equal to or greater than the sum of nMax for all
-** purgeable caches,
-**
-** then attempt to recycle a page from the LRU list. If it is the right
-** size, return the recycled buffer. Otherwise, free the buffer and
-** proceed to step 5.
-**
-** 5. Otherwise, allocate and return a new page buffer.
-*/
-static void *pcache1Fetch(sqlite3_pcache *p, unsigned int iKey, int createFlag){
- unsigned int nPinned;
- PCache1 *pCache = (PCache1 *)p;
- PgHdr1 *pPage = 0;
-
- assert( pCache->bPurgeable || createFlag!=1 );
- pcache1EnterMutex();
- if( createFlag==1 ) sqlite3BeginBenignMalloc();
-
- /* Search the hash table for an existing entry. */
- if( pCache->nHash>0 ){
- unsigned int h = iKey % pCache->nHash;
- for(pPage=pCache->apHash[h]; pPage&&pPage->iKey!=iKey; pPage=pPage->pNext);
- }
-
- if( pPage || createFlag==0 ){
- pcache1PinPage(pPage);
- goto fetch_out;
- }
-
- /* Step 3 of header comment. */
- nPinned = pCache->nPage - pCache->nRecyclable;
- if( createFlag==1 && (
- nPinned>=(pcache1.nMaxPage+pCache->nMin-pcache1.nMinPage)
- || nPinned>=(pCache->nMax * 9 / 10)
- )){
- goto fetch_out;
- }
-
- if( pCache->nPage>=pCache->nHash && pcache1ResizeHash(pCache) ){
- goto fetch_out;
- }
-
- /* Step 4. Try to recycle a page buffer if appropriate. */
- if( pCache->bPurgeable && pcache1.pLruTail && (
- (pCache->nPage+1>=pCache->nMax) || pcache1.nCurrentPage>=pcache1.nMaxPage
- )){
- pPage = pcache1.pLruTail;
- pcache1RemoveFromHash(pPage);
- pcache1PinPage(pPage);
- if( pPage->pCache->szPage!=pCache->szPage ){
- pcache1FreePage(pPage);
- pPage = 0;
- }else{
- pcache1.nCurrentPage -= (pPage->pCache->bPurgeable - pCache->bPurgeable);
- }
- }
-
- /* Step 5. If a usable page buffer has still not been found,
- ** attempt to allocate a new one.
- */
- if( !pPage ){
- pPage = pcache1AllocPage(pCache);
- }
-
- if( pPage ){
- unsigned int h = iKey % pCache->nHash;
- pCache->nPage++;
- pPage->iKey = iKey;
- pPage->pNext = pCache->apHash[h];
- pPage->pCache = pCache;
- pPage->pLruPrev = 0;
- pPage->pLruNext = 0;
- *(void **)(PGHDR1_TO_PAGE(pPage)) = 0;
- pCache->apHash[h] = pPage;
- }
-
-fetch_out:
- if( pPage && iKey>pCache->iMaxKey ){
- pCache->iMaxKey = iKey;
- }
- if( createFlag==1 ) sqlite3EndBenignMalloc();
- pcache1LeaveMutex();
- return (pPage ? PGHDR1_TO_PAGE(pPage) : 0);
-}
-
-
-/*
-** Implementation of the sqlite3_pcache.xUnpin method.
-**
-** Mark a page as unpinned (eligible for asynchronous recycling).
-*/
-static void pcache1Unpin(sqlite3_pcache *p, void *pPg, int reuseUnlikely){
- PCache1 *pCache = (PCache1 *)p;
- PgHdr1 *pPage = PAGE_TO_PGHDR1(pCache, pPg);
-
- assert( pPage->pCache==pCache );
- pcache1EnterMutex();
-
- /* It is an error to call this function if the page is already
- ** part of the global LRU list.
- */
- assert( pPage->pLruPrev==0 && pPage->pLruNext==0 );
- assert( pcache1.pLruHead!=pPage && pcache1.pLruTail!=pPage );
-
- if( reuseUnlikely || pcache1.nCurrentPage>pcache1.nMaxPage ){
- pcache1RemoveFromHash(pPage);
- pcache1FreePage(pPage);
- }else{
- /* Add the page to the global LRU list. Normally, the page is added to
- ** the head of the list (last page to be recycled). However, if the
- ** reuseUnlikely flag passed to this function is true, the page is added
- ** to the tail of the list (first page to be recycled).
- */
- if( pcache1.pLruHead ){
- pcache1.pLruHead->pLruPrev = pPage;
- pPage->pLruNext = pcache1.pLruHead;
- pcache1.pLruHead = pPage;
- }else{
- pcache1.pLruTail = pPage;
- pcache1.pLruHead = pPage;
- }
- pCache->nRecyclable++;
- }
-
- pcache1LeaveMutex();
-}
-
-/*
-** Implementation of the sqlite3_pcache.xRekey method.
-*/
-static void pcache1Rekey(
- sqlite3_pcache *p,
- void *pPg,
- unsigned int iOld,
- unsigned int iNew
-){
- PCache1 *pCache = (PCache1 *)p;
- PgHdr1 *pPage = PAGE_TO_PGHDR1(pCache, pPg);
- PgHdr1 **pp;
- unsigned int h;
- assert( pPage->iKey==iOld );
- assert( pPage->pCache==pCache );
-
- pcache1EnterMutex();
-
- h = iOld%pCache->nHash;
- pp = &pCache->apHash[h];
- while( (*pp)!=pPage ){
- pp = &(*pp)->pNext;
- }
- *pp = pPage->pNext;
-
- h = iNew%pCache->nHash;
- pPage->iKey = iNew;
- pPage->pNext = pCache->apHash[h];
- pCache->apHash[h] = pPage;
-
- /* The xRekey() interface is only used to move pages earlier in the
- ** database file (in order to move all free pages to the end of the
- ** file where they can be truncated off.) Hence, it is not possible
- ** for the new page number to be greater than the largest previously
- ** fetched page. But we retain the following test in case xRekey()
- ** begins to be used in different ways in the future.
- */
- if( NEVER(iNew>pCache->iMaxKey) ){
- pCache->iMaxKey = iNew;
- }
-
- pcache1LeaveMutex();
-}
-
-/*
-** Implementation of the sqlite3_pcache.xTruncate method.
-**
-** Discard all unpinned pages in the cache with a page number equal to
-** or greater than parameter iLimit. Any pinned pages with a page number
-** equal to or greater than iLimit are implicitly unpinned.
-*/
-static void pcache1Truncate(sqlite3_pcache *p, unsigned int iLimit){
- PCache1 *pCache = (PCache1 *)p;
- pcache1EnterMutex();
- if( iLimit<=pCache->iMaxKey ){
- pcache1TruncateUnsafe(pCache, iLimit);
- pCache->iMaxKey = iLimit-1;
- }
- pcache1LeaveMutex();
-}
-
-/*
-** Implementation of the sqlite3_pcache.xDestroy method.
-**
-** Destroy a cache allocated using pcache1Create().
-*/
-static void pcache1Destroy(sqlite3_pcache *p){
- PCache1 *pCache = (PCache1 *)p;
- pcache1EnterMutex();
- pcache1TruncateUnsafe(pCache, 0);
- pcache1.nMaxPage -= pCache->nMax;
- pcache1.nMinPage -= pCache->nMin;
- pcache1EnforceMaxPage();
- pcache1LeaveMutex();
- sqlite3_free(pCache->apHash);
- sqlite3_free(pCache);
-}
-
-/*
-** This function is called during initialization (sqlite3_initialize()) to
-** install the default pluggable cache module, assuming the user has not
-** already provided an alternative.
-*/
-SQLITE_PRIVATE void sqlite3PCacheSetDefault(void){
- static sqlite3_pcache_methods defaultMethods = {
- 0, /* pArg */
- pcache1Init, /* xInit */
- pcache1Shutdown, /* xShutdown */
- pcache1Create, /* xCreate */
- pcache1Cachesize, /* xCachesize */
- pcache1Pagecount, /* xPagecount */
- pcache1Fetch, /* xFetch */
- pcache1Unpin, /* xUnpin */
- pcache1Rekey, /* xRekey */
- pcache1Truncate, /* xTruncate */
- pcache1Destroy /* xDestroy */
- };
- sqlite3_config(SQLITE_CONFIG_PCACHE, &defaultMethods);
-}
-
-#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
-/*
-** This function is called to free superfluous dynamically allocated memory
-** held by the pager system. Memory in use by any SQLite pager allocated
-** by the current thread may be sqlite3_free()ed.
-**
-** nReq is the number of bytes of memory required. Once this much has
-** been released, the function returns. The return value is the total number
-** of bytes of memory released.
-*/
-SQLITE_PRIVATE int sqlite3PcacheReleaseMemory(int nReq){
- int nFree = 0;
- if( pcache1.pStart==0 ){
- PgHdr1 *p;
- pcache1EnterMutex();
- while( (nReq<0 || nFree<nReq) && (p=pcache1.pLruTail) ){
- nFree += sqlite3MallocSize(PGHDR1_TO_PAGE(p));
- pcache1PinPage(p);
- pcache1RemoveFromHash(p);
- pcache1FreePage(p);
- }
- pcache1LeaveMutex();
- }
- return nFree;
-}
-#endif /* SQLITE_ENABLE_MEMORY_MANAGEMENT */
-
-#ifdef SQLITE_TEST
-/*
-** This function is used by test procedures to inspect the internal state
-** of the global cache.
-*/
-SQLITE_PRIVATE void sqlite3PcacheStats(
- int *pnCurrent, /* OUT: Total number of pages cached */
- int *pnMax, /* OUT: Global maximum cache size */
- int *pnMin, /* OUT: Sum of PCache1.nMin for purgeable caches */
- int *pnRecyclable /* OUT: Total number of pages available for recycling */
-){
- PgHdr1 *p;
- int nRecyclable = 0;
- for(p=pcache1.pLruHead; p; p=p->pLruNext){
- nRecyclable++;
- }
- *pnCurrent = pcache1.nCurrentPage;
- *pnMax = pcache1.nMaxPage;
- *pnMin = pcache1.nMinPage;
- *pnRecyclable = nRecyclable;
-}
-#endif
-
-/************** End of pcache1.c *********************************************/
-/************** Begin file rowset.c ******************************************/
-/*
-** 2008 December 3
-**
-** 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 module implements an object we call a "RowSet".
-**
-** The RowSet object is a collection of rowids. Rowids
-** are inserted into the RowSet in an arbitrary order. Inserts
-** can be intermixed with tests to see if a given rowid has been
-** previously inserted into the RowSet.
-**
-** After all inserts are finished, it is possible to extract the
-** elements of the RowSet in sorted order. Once this extraction
-** process has started, no new elements may be inserted.
-**
-** Hence, the primitive operations for a RowSet are:
-**
-** CREATE
-** INSERT
-** TEST
-** SMALLEST
-** DESTROY
-**
-** The CREATE and DESTROY primitives are the constructor and destructor,
-** obviously. The INSERT primitive adds a new element to the RowSet.
-** TEST checks to see if an element is already in the RowSet. SMALLEST
-** extracts the least value from the RowSet.
-**
-** The INSERT primitive might allocate additional memory. Memory is
-** allocated in chunks so most INSERTs do no allocation. There is an
-** upper bound on the size of allocated memory. No memory is freed
-** until DESTROY.
-**
-** The TEST primitive includes a "batch" number. The TEST primitive
-** will only see elements that were inserted before the last change
-** in the batch number. In other words, if an INSERT occurs between
-** two TESTs where the TESTs have the same batch nubmer, then the
-** value added by the INSERT will not be visible to the second TEST.
-** The initial batch number is zero, so if the very first TEST contains
-** a non-zero batch number, it will see all prior INSERTs.
-**
-** No INSERTs may occurs after a SMALLEST. An assertion will fail if
-** that is attempted.
-**
-** The cost of an INSERT is roughly constant. (Sometime new memory
-** has to be allocated on an INSERT.) The cost of a TEST with a new
-** batch number is O(NlogN) where N is the number of elements in the RowSet.
-** The cost of a TEST using the same batch number is O(logN). The cost
-** of the first SMALLEST is O(NlogN). Second and subsequent SMALLEST
-** primitives are constant time. The cost of DESTROY is O(N).
-**
-** There is an added cost of O(N) when switching between TEST and
-** SMALLEST primitives.
-**
-** $Id: rowset.c,v 1.7 2009/05/22 01:00:13 drh Exp $
-*/
-
-
-/*
-** Target size for allocation chunks.
-*/
-#define ROWSET_ALLOCATION_SIZE 1024
-
-/*
-** The number of rowset entries per allocation chunk.
-*/
-#define ROWSET_ENTRY_PER_CHUNK \
- ((ROWSET_ALLOCATION_SIZE-8)/sizeof(struct RowSetEntry))
-
-/*
-** Each entry in a RowSet is an instance of the following object.
-*/
-struct RowSetEntry {
- i64 v; /* ROWID value for this entry */
- struct RowSetEntry *pRight; /* Right subtree (larger entries) or list */
- struct RowSetEntry *pLeft; /* Left subtree (smaller entries) */
-};
-
-/*
-** RowSetEntry objects are allocated in large chunks (instances of the
-** following structure) to reduce memory allocation overhead. The
-** chunks are kept on a linked list so that they can be deallocated
-** when the RowSet is destroyed.
-*/
-struct RowSetChunk {
- struct RowSetChunk *pNextChunk; /* Next chunk on list of them all */
- struct RowSetEntry aEntry[ROWSET_ENTRY_PER_CHUNK]; /* Allocated entries */
-};
-
-/*
-** A RowSet in an instance of the following structure.
-**
-** A typedef of this structure if found in sqliteInt.h.
-*/
-struct RowSet {
- struct RowSetChunk *pChunk; /* List of all chunk allocations */
- sqlite3 *db; /* The database connection */
- struct RowSetEntry *pEntry; /* List of entries using pRight */
- struct RowSetEntry *pLast; /* Last entry on the pEntry list */
- struct RowSetEntry *pFresh; /* Source of new entry objects */
- struct RowSetEntry *pTree; /* Binary tree of entries */
- u16 nFresh; /* Number of objects on pFresh */
- u8 isSorted; /* True if pEntry is sorted */
- u8 iBatch; /* Current insert batch */
-};
-
-/*
-** Turn bulk memory into a RowSet object. N bytes of memory
-** are available at pSpace. The db pointer is used as a memory context
-** for any subsequent allocations that need to occur.
-** Return a pointer to the new RowSet object.
-**
-** It must be the case that N is sufficient to make a Rowset. If not
-** an assertion fault occurs.
-**
-** If N is larger than the minimum, use the surplus as an initial
-** allocation of entries available to be filled.
-*/
-SQLITE_PRIVATE RowSet *sqlite3RowSetInit(sqlite3 *db, void *pSpace, unsigned int N){
- RowSet *p;
- assert( N >= ROUND8(sizeof(*p)) );
- p = pSpace;
- p->pChunk = 0;
- p->db = db;
- p->pEntry = 0;
- p->pLast = 0;
- p->pTree = 0;
- p->pFresh = (struct RowSetEntry*)(ROUND8(sizeof(*p)) + (char*)p);
- p->nFresh = (u16)((N - ROUND8(sizeof(*p)))/sizeof(struct RowSetEntry));
- p->isSorted = 1;
- p->iBatch = 0;
- return p;
-}
-
-/*
-** Deallocate all chunks from a RowSet. This frees all memory that
-** the RowSet has allocated over its lifetime. This routine is
-** the destructor for the RowSet.
-*/
-SQLITE_PRIVATE void sqlite3RowSetClear(RowSet *p){
- struct RowSetChunk *pChunk, *pNextChunk;
- for(pChunk=p->pChunk; pChunk; pChunk = pNextChunk){
- pNextChunk = pChunk->pNextChunk;
- sqlite3DbFree(p->db, pChunk);
- }
- p->pChunk = 0;
- p->nFresh = 0;
- p->pEntry = 0;
- p->pLast = 0;
- p->pTree = 0;
- p->isSorted = 1;
-}
-
-/*
-** Insert a new value into a RowSet.
-**
-** The mallocFailed flag of the database connection is set if a
-** memory allocation fails.
-*/
-SQLITE_PRIVATE void sqlite3RowSetInsert(RowSet *p, i64 rowid){
- struct RowSetEntry *pEntry; /* The new entry */
- struct RowSetEntry *pLast; /* The last prior entry */
- assert( p!=0 );
- if( p->nFresh==0 ){
- struct RowSetChunk *pNew;
- pNew = sqlite3DbMallocRaw(p->db, sizeof(*pNew));
- if( pNew==0 ){
- return;
- }
- pNew->pNextChunk = p->pChunk;
- p->pChunk = pNew;
- p->pFresh = pNew->aEntry;
- p->nFresh = ROWSET_ENTRY_PER_CHUNK;
- }
- pEntry = p->pFresh++;
- p->nFresh--;
- pEntry->v = rowid;
- pEntry->pRight = 0;
- pLast = p->pLast;
- if( pLast ){
- if( p->isSorted && rowid<=pLast->v ){
- p->isSorted = 0;
- }
- pLast->pRight = pEntry;
- }else{
- assert( p->pEntry==0 ); /* Fires if INSERT after SMALLEST */
- p->pEntry = pEntry;
- }
- p->pLast = pEntry;
-}
-
-/*
-** Merge two lists of RowSetEntry objects. Remove duplicates.
-**
-** The input lists are connected via pRight pointers and are
-** assumed to each already be in sorted order.
-*/
-static struct RowSetEntry *rowSetMerge(
- struct RowSetEntry *pA, /* First sorted list to be merged */
- struct RowSetEntry *pB /* Second sorted list to be merged */
-){
- struct RowSetEntry head;
- struct RowSetEntry *pTail;
-
- pTail = &head;
- while( pA && pB ){
- assert( pA->pRight==0 || pA->v<=pA->pRight->v );
- assert( pB->pRight==0 || pB->v<=pB->pRight->v );
- if( pA->v<pB->v ){
- pTail->pRight = pA;
- pA = pA->pRight;
- pTail = pTail->pRight;
- }else if( pB->v<pA->v ){
- pTail->pRight = pB;
- pB = pB->pRight;
- pTail = pTail->pRight;
- }else{
- pA = pA->pRight;
- }
- }
- if( pA ){
- assert( pA->pRight==0 || pA->v<=pA->pRight->v );
- pTail->pRight = pA;
- }else{
- assert( pB==0 || pB->pRight==0 || pB->v<=pB->pRight->v );
- pTail->pRight = pB;
- }
- return head.pRight;
-}
-
-/*
-** Sort all elements on the pEntry list of the RowSet into ascending order.
-*/
-static void rowSetSort(RowSet *p){
- unsigned int i;
- struct RowSetEntry *pEntry;
- struct RowSetEntry *aBucket[40];
-
- assert( p->isSorted==0 );
- memset(aBucket, 0, sizeof(aBucket));
- while( p->pEntry ){
- pEntry = p->pEntry;
- p->pEntry = pEntry->pRight;
- pEntry->pRight = 0;
- for(i=0; aBucket[i]; i++){
- pEntry = rowSetMerge(aBucket[i], pEntry);
- aBucket[i] = 0;
- }
- aBucket[i] = pEntry;
- }
- pEntry = 0;
- for(i=0; i<sizeof(aBucket)/sizeof(aBucket[0]); i++){
- pEntry = rowSetMerge(pEntry, aBucket[i]);
- }
- p->pEntry = pEntry;
- p->pLast = 0;
- p->isSorted = 1;
-}
-
-
-/*
-** The input, pIn, is a binary tree (or subtree) of RowSetEntry objects.
-** Convert this tree into a linked list connected by the pRight pointers
-** and return pointers to the first and last elements of the new list.
-*/
-static void rowSetTreeToList(
- struct RowSetEntry *pIn, /* Root of the input tree */
- struct RowSetEntry **ppFirst, /* Write head of the output list here */
- struct RowSetEntry **ppLast /* Write tail of the output list here */
-){
- assert( pIn!=0 );
- if( pIn->pLeft ){
- struct RowSetEntry *p;
- rowSetTreeToList(pIn->pLeft, ppFirst, &p);
- p->pRight = pIn;
- }else{
- *ppFirst = pIn;
- }
- if( pIn->pRight ){
- rowSetTreeToList(pIn->pRight, &pIn->pRight, ppLast);
- }else{
- *ppLast = pIn;
- }
- assert( (*ppLast)->pRight==0 );
-}
-
-
-/*
-** Convert a sorted list of elements (connected by pRight) into a binary
-** tree with depth of iDepth. A depth of 1 means the tree contains a single
-** node taken from the head of *ppList. A depth of 2 means a tree with
-** three nodes. And so forth.
-**
-** Use as many entries from the input list as required and update the
-** *ppList to point to the unused elements of the list. If the input
-** list contains too few elements, then construct an incomplete tree
-** and leave *ppList set to NULL.
-**
-** Return a pointer to the root of the constructed binary tree.
-*/
-static struct RowSetEntry *rowSetNDeepTree(
- struct RowSetEntry **ppList,
- int iDepth
-){
- struct RowSetEntry *p; /* Root of the new tree */
- struct RowSetEntry *pLeft; /* Left subtree */
- if( *ppList==0 ){
- return 0;
- }
- if( iDepth==1 ){
- p = *ppList;
- *ppList = p->pRight;
- p->pLeft = p->pRight = 0;
- return p;
- }
- pLeft = rowSetNDeepTree(ppList, iDepth-1);
- p = *ppList;
- if( p==0 ){
- return pLeft;
- }
- p->pLeft = pLeft;
- *ppList = p->pRight;
- p->pRight = rowSetNDeepTree(ppList, iDepth-1);
- return p;
-}
-
-/*
-** Convert a sorted list of elements into a binary tree. Make the tree
-** as deep as it needs to be in order to contain the entire list.
-*/
-static struct RowSetEntry *rowSetListToTree(struct RowSetEntry *pList){
- int iDepth; /* Depth of the tree so far */
- struct RowSetEntry *p; /* Current tree root */
- struct RowSetEntry *pLeft; /* Left subtree */
-
- assert( pList!=0 );
- p = pList;
- pList = p->pRight;
- p->pLeft = p->pRight = 0;
- for(iDepth=1; pList; iDepth++){
- pLeft = p;
- p = pList;
- pList = p->pRight;
- p->pLeft = pLeft;
- p->pRight = rowSetNDeepTree(&pList, iDepth);
- }
- return p;
-}
-
-/*
-** Convert the list in p->pEntry into a sorted list if it is not
-** sorted already. If there is a binary tree on p->pTree, then
-** convert it into a list too and merge it into the p->pEntry list.
-*/
-static void rowSetToList(RowSet *p){
- if( !p->isSorted ){
- rowSetSort(p);
- }
- if( p->pTree ){
- struct RowSetEntry *pHead, *pTail;
- rowSetTreeToList(p->pTree, &pHead, &pTail);
- p->pTree = 0;
- p->pEntry = rowSetMerge(p->pEntry, pHead);
- }
-}
-
-/*
-** Extract the smallest element from the RowSet.
-** Write the element into *pRowid. Return 1 on success. Return
-** 0 if the RowSet is already empty.
-**
-** After this routine has been called, the sqlite3RowSetInsert()
-** routine may not be called again.
-*/
-SQLITE_PRIVATE int sqlite3RowSetNext(RowSet *p, i64 *pRowid){
- rowSetToList(p);
- if( p->pEntry ){
- *pRowid = p->pEntry->v;
- p->pEntry = p->pEntry->pRight;
- if( p->pEntry==0 ){
- sqlite3RowSetClear(p);
- }
- return 1;
- }else{
- return 0;
- }
-}
-
-/*
-** Check to see if element iRowid was inserted into the the rowset as
-** part of any insert batch prior to iBatch. Return 1 or 0.
-*/
-SQLITE_PRIVATE int sqlite3RowSetTest(RowSet *pRowSet, u8 iBatch, sqlite3_int64 iRowid){
- struct RowSetEntry *p;
- if( iBatch!=pRowSet->iBatch ){
- if( pRowSet->pEntry ){
- rowSetToList(pRowSet);
- pRowSet->pTree = rowSetListToTree(pRowSet->pEntry);
- pRowSet->pEntry = 0;
- pRowSet->pLast = 0;
- }
- pRowSet->iBatch = iBatch;
- }
- p = pRowSet->pTree;
- while( p ){
- if( p->v<iRowid ){
- p = p->pRight;
- }else if( p->v>iRowid ){
- p = p->pLeft;
- }else{
- return 1;
- }
- }
- return 0;
-}
-
-/************** End of rowset.c **********************************************/
-/************** Begin file pager.c *******************************************/
-/*
-** 2001 September 15
-**
-** 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 is the implementation of the page cache subsystem or "pager".
-**
-** The pager is used to access a database disk file. It implements
-** atomic commit and rollback through the use of a journal file that
-** is separate from the database file. The pager also implements file
-** locking to prevent two processes from writing the same database
-** file simultaneously, or one process from reading the database while
-** another is writing.
-**
-** @(#) $Id: pager.c,v 1.629 2009/08/10 17:48:57 drh Exp $
-*/
-#ifndef SQLITE_OMIT_DISKIO
-
-/*
-** Macros for troubleshooting. Normally turned off
-*/
-#if 0
-int sqlite3PagerTrace=1; /* True to enable tracing */
-#define sqlite3DebugPrintf printf
-#define PAGERTRACE(X) if( sqlite3PagerTrace ){ sqlite3DebugPrintf X; }
-#else
-#define PAGERTRACE(X)
-#endif
-
-/*
-** The following two macros are used within the PAGERTRACE() macros above
-** to print out file-descriptors.
-**
-** PAGERID() takes a pointer to a Pager struct as its argument. The
-** associated file-descriptor is returned. FILEHANDLEID() takes an sqlite3_file
-** struct as its argument.
-*/
-#define PAGERID(p) ((int)(p->fd))
-#define FILEHANDLEID(fd) ((int)fd)
-
-/*
-** The page cache as a whole is always in one of the following
-** states:
-**
-** PAGER_UNLOCK The page cache is not currently reading or
-** writing the database file. There is no
-** data held in memory. This is the initial
-** state.
-**
-** PAGER_SHARED The page cache is reading the database.
-** Writing is not permitted. There can be
-** multiple readers accessing the same database
-** file at the same time.
-**
-** PAGER_RESERVED This process has reserved the database for writing
-** but has not yet made any changes. Only one process
-** at a time can reserve the database. The original
-** database file has not been modified so other
-** processes may still be reading the on-disk
-** database file.
-**
-** PAGER_EXCLUSIVE The page cache is writing the database.
-** Access is exclusive. No other processes or
-** threads can be reading or writing while one
-** process is writing.
-**
-** PAGER_SYNCED The pager moves to this state from PAGER_EXCLUSIVE
-** after all dirty pages have been written to the
-** database file and the file has been synced to
-** disk. All that remains to do is to remove or
-** truncate the journal file and the transaction
-** will be committed.
-**
-** The page cache comes up in PAGER_UNLOCK. The first time a
-** sqlite3PagerGet() occurs, the state transitions to PAGER_SHARED.
-** After all pages have been released using sqlite_page_unref(),
-** the state transitions back to PAGER_UNLOCK. The first time
-** that sqlite3PagerWrite() is called, the state transitions to
-** PAGER_RESERVED. (Note that sqlite3PagerWrite() can only be
-** called on an outstanding page which means that the pager must
-** be in PAGER_SHARED before it transitions to PAGER_RESERVED.)
-** PAGER_RESERVED means that there is an open rollback journal.
-** The transition to PAGER_EXCLUSIVE occurs before any changes
-** are made to the database file, though writes to the rollback
-** journal occurs with just PAGER_RESERVED. After an sqlite3PagerRollback()
-** or sqlite3PagerCommitPhaseTwo(), the state can go back to PAGER_SHARED,
-** or it can stay at PAGER_EXCLUSIVE if we are in exclusive access mode.
-*/
-#define PAGER_UNLOCK 0
-#define PAGER_SHARED 1 /* same as SHARED_LOCK */
-#define PAGER_RESERVED 2 /* same as RESERVED_LOCK */
-#define PAGER_EXCLUSIVE 4 /* same as EXCLUSIVE_LOCK */
-#define PAGER_SYNCED 5
-
-/*
-** A macro used for invoking the codec if there is one
-*/
-#ifdef SQLITE_HAS_CODEC
-# define CODEC1(P,D,N,X,E) \
- if( P->xCodec && P->xCodec(P->pCodec,D,N,X)==0 ){ E; }
-# define CODEC2(P,D,N,X,E,O) \
- if( P->xCodec==0 ){ O=(char*)D; }else \
- if( (O=(char*)(P->xCodec(P->pCodec,D,N,X)))==0 ){ E; }
-#else
-# define CODEC1(P,D,N,X,E) /* NO-OP */
-# define CODEC2(P,D,N,X,E,O) O=(char*)D
-#endif
-
-/*
-** The maximum allowed sector size. 64KiB. If the xSectorsize() method
-** returns a value larger than this, then MAX_SECTOR_SIZE is used instead.
-** This could conceivably cause corruption following a power failure on
-** such a system. This is currently an undocumented limit.
-*/
-#define MAX_SECTOR_SIZE 0x10000
-
-/*
-** An instance of the following structure is allocated for each active
-** savepoint and statement transaction in the system. All such structures
-** are stored in the Pager.aSavepoint[] array, which is allocated and
-** resized using sqlite3Realloc().
-**
-** When a savepoint is created, the PagerSavepoint.iHdrOffset field is
-** set to 0. If a journal-header is written into the main journal while
-** the savepoint is active, then iHdrOffset is set to the byte offset
-** immediately following the last journal record written into the main
-** journal before the journal-header. This is required during savepoint
-** rollback (see pagerPlaybackSavepoint()).
-*/
-typedef struct PagerSavepoint PagerSavepoint;
-struct PagerSavepoint {
- i64 iOffset; /* Starting offset in main journal */
- i64 iHdrOffset; /* See above */
- Bitvec *pInSavepoint; /* Set of pages in this savepoint */
- Pgno nOrig; /* Original number of pages in file */
- Pgno iSubRec; /* Index of first record in sub-journal */
-};
-
-/*
-** A open page cache is an instance of the following structure.
-**
-** errCode
-**
-** Pager.errCode may be set to SQLITE_IOERR, SQLITE_CORRUPT, or
-** or SQLITE_FULL. Once one of the first three errors occurs, it persists
-** and is returned as the result of every major pager API call. The
-** SQLITE_FULL return code is slightly different. It persists only until the
-** next successful rollback is performed on the pager cache. Also,
-** SQLITE_FULL does not affect the sqlite3PagerGet() and sqlite3PagerLookup()
-** APIs, they may still be used successfully.
-**
-** dbSizeValid, dbSize, dbOrigSize, dbFileSize
-**
-** Managing the size of the database file in pages is a little complicated.
-** The variable Pager.dbSize contains the number of pages that the database
-** image currently contains. As the database image grows or shrinks this
-** variable is updated. The variable Pager.dbFileSize contains the number
-** of pages in the database file. This may be different from Pager.dbSize
-** if some pages have been appended to the database image but not yet written
-** out from the cache to the actual file on disk. Or if the image has been
-** truncated by an incremental-vacuum operation. The Pager.dbOrigSize variable
-** contains the number of pages in the database image when the current
-** transaction was opened. The contents of all three of these variables is
-** only guaranteed to be correct if the boolean Pager.dbSizeValid is true.
-**
-** TODO: Under what conditions is dbSizeValid set? Cleared?
-**
-** changeCountDone
-**
-** This boolean variable is used to make sure that the change-counter
-** (the 4-byte header field at byte offset 24 of the database file) is
-** not updated more often than necessary.
-**
-** It is set to true when the change-counter field is updated, which
-** can only happen if an exclusive lock is held on the database file.
-** It is cleared (set to false) whenever an exclusive lock is
-** relinquished on the database file. Each time a transaction is committed,
-** The changeCountDone flag is inspected. If it is true, the work of
-** updating the change-counter is omitted for the current transaction.
-**
-** This mechanism means that when running in exclusive mode, a connection
-** need only update the change-counter once, for the first transaction
-** committed.
-**
-** dbModified
-**
-** The dbModified flag is set whenever a database page is dirtied.
-** It is cleared at the end of each transaction.
-**
-** It is used when committing or otherwise ending a transaction. If
-** the dbModified flag is clear then less work has to be done.
-**
-** journalStarted
-**
-** This flag is set whenever the the main journal is synced.
-**
-** The point of this flag is that it must be set after the
-** first journal header in a journal file has been synced to disk.
-** After this has happened, new pages appended to the database
-** do not need the PGHDR_NEED_SYNC flag set, as they do not need
-** to wait for a journal sync before they can be written out to
-** the database file (see function pager_write()).
-**
-** setMaster
-**
-** This variable is used to ensure that the master journal file name
-** (if any) is only written into the journal file once.
-**
-** When committing a transaction, the master journal file name (if any)
-** may be written into the journal file while the pager is still in
-** PAGER_RESERVED state (see CommitPhaseOne() for the action). It
-** then attempts to upgrade to an exclusive lock. If this attempt
-** fails, then SQLITE_BUSY may be returned to the user and the user
-** may attempt to commit the transaction again later (calling
-** CommitPhaseOne() again). This flag is used to ensure that the
-** master journal name is only written to the journal file the first
-** time CommitPhaseOne() is called.
-**
-** doNotSync
-**
-** This variable is set and cleared by sqlite3PagerWrite().
-**
-** needSync
-**
-** TODO: It might be easier to set this variable in writeJournalHdr()
-** and writeMasterJournal() only. Change its meaning to "unsynced data
-** has been written to the journal".
-**
-** subjInMemory
-**
-** This is a boolean variable. If true, then any required sub-journal
-** is opened as an in-memory journal file. If false, then in-memory
-** sub-journals are only used for in-memory pager files.
-*/
-struct Pager {
- sqlite3_vfs *pVfs; /* OS functions to use for IO */
- u8 exclusiveMode; /* Boolean. True if locking_mode==EXCLUSIVE */
- u8 journalMode; /* On of the PAGER_JOURNALMODE_* values */
- u8 useJournal; /* Use a rollback journal on this file */
- u8 noReadlock; /* Do not bother to obtain readlocks */
- u8 noSync; /* Do not sync the journal if true */
- u8 fullSync; /* Do extra syncs of the journal for robustness */
- u8 sync_flags; /* One of SYNC_NORMAL or SYNC_FULL */
- u8 tempFile; /* zFilename is a temporary file */
- u8 readOnly; /* True for a read-only database */
- u8 memDb; /* True to inhibit all file I/O */
-
- /* The following block contains those class members that are dynamically
- ** modified during normal operations. The other variables in this structure
- ** are either constant throughout the lifetime of the pager, or else
- ** used to store configuration parameters that affect the way the pager
- ** operates.
- **
- ** The 'state' variable is described in more detail along with the
- ** descriptions of the values it may take - PAGER_UNLOCK etc. Many of the
- ** other variables in this block are described in the comment directly
- ** above this class definition.
- */
- u8 state; /* PAGER_UNLOCK, _SHARED, _RESERVED, etc. */
- u8 dbModified; /* True if there are any changes to the Db */
- u8 needSync; /* True if an fsync() is needed on the journal */
- u8 journalStarted; /* True if header of journal is synced */
- u8 changeCountDone; /* Set after incrementing the change-counter */
- u8 setMaster; /* True if a m-j name has been written to jrnl */
- u8 doNotSync; /* Boolean. While true, do not spill the cache */
- u8 dbSizeValid; /* Set when dbSize is correct */
- u8 subjInMemory; /* True to use in-memory sub-journals */
- Pgno dbSize; /* Number of pages in the database */
- Pgno dbOrigSize; /* dbSize before the current transaction */
- Pgno dbFileSize; /* Number of pages in the database file */
- int errCode; /* One of several kinds of errors */
- int nRec; /* Pages journalled since last j-header written */
- u32 cksumInit; /* Quasi-random value added to every checksum */
- u32 nSubRec; /* Number of records written to sub-journal */
- Bitvec *pInJournal; /* One bit for each page in the database file */
- sqlite3_file *fd; /* File descriptor for database */
- sqlite3_file *jfd; /* File descriptor for main journal */
- sqlite3_file *sjfd; /* File descriptor for sub-journal */
- i64 journalOff; /* Current write offset in the journal file */
- i64 journalHdr; /* Byte offset to previous journal header */
- PagerSavepoint *aSavepoint; /* Array of active savepoints */
- int nSavepoint; /* Number of elements in aSavepoint[] */
- char dbFileVers[16]; /* Changes whenever database file changes */
- u32 sectorSize; /* Assumed sector size during rollback */
-
- u16 nExtra; /* Add this many bytes to each in-memory page */
- i16 nReserve; /* Number of unused bytes at end of each page */
- u32 vfsFlags; /* Flags for sqlite3_vfs.xOpen() */
- int pageSize; /* Number of bytes in a page */
- Pgno mxPgno; /* Maximum allowed size of the database */
- char *zFilename; /* Name of the database file */
- char *zJournal; /* Name of the journal file */
- int (*xBusyHandler)(void*); /* Function to call when busy */
- void *pBusyHandlerArg; /* Context argument for xBusyHandler */
-#ifdef SQLITE_TEST
- int nHit, nMiss; /* Cache hits and missing */
- int nRead, nWrite; /* Database pages read/written */
-#endif
- void (*xReiniter)(DbPage*); /* Call this routine when reloading pages */
-#ifdef SQLITE_HAS_CODEC
- void *(*xCodec)(void*,void*,Pgno,int); /* Routine for en/decoding data */
- void (*xCodecSizeChng)(void*,int,int); /* Notify of page size changes */
- void (*xCodecFree)(void*); /* Destructor for the codec */
- void *pCodec; /* First argument to xCodec... methods */
-#endif
- char *pTmpSpace; /* Pager.pageSize bytes of space for tmp use */
- i64 journalSizeLimit; /* Size limit for persistent journal files */
- PCache *pPCache; /* Pointer to page cache object */
- sqlite3_backup *pBackup; /* Pointer to list of ongoing backup processes */
-};
-
-/*
-** The following global variables hold counters used for
-** testing purposes only. These variables do not exist in
-** a non-testing build. These variables are not thread-safe.
-*/
-#ifdef SQLITE_TEST
-SQLITE_API int sqlite3_pager_readdb_count = 0; /* Number of full pages read from DB */
-SQLITE_API int sqlite3_pager_writedb_count = 0; /* Number of full pages written to DB */
-SQLITE_API int sqlite3_pager_writej_count = 0; /* Number of pages written to journal */
-# define PAGER_INCR(v) v++
-#else
-# define PAGER_INCR(v)
-#endif
-
-
-
-/*
-** Journal files begin with the following magic string. The data
-** was obtained from /dev/random. It is used only as a sanity check.
-**
-** Since version 2.8.0, the journal format contains additional sanity
-** checking information. If the power fails while the journal is being
-** written, semi-random garbage data might appear in the journal
-** file after power is restored. If an attempt is then made
-** to roll the journal back, the database could be corrupted. The additional
-** sanity checking data is an attempt to discover the garbage in the
-** journal and ignore it.
-**
-** The sanity checking information for the new journal format consists
-** of a 32-bit checksum on each page of data. The checksum covers both
-** the page number and the pPager->pageSize bytes of data for the page.
-** This cksum is initialized to a 32-bit random value that appears in the
-** journal file right after the header. The random initializer is important,
-** because garbage data that appears at the end of a journal is likely
-** data that was once in other files that have now been deleted. If the
-** garbage data came from an obsolete journal file, the checksums might
-** be correct. But by initializing the checksum to random value which
-** is different for every journal, we minimize that risk.
-*/
-static const unsigned char aJournalMagic[] = {
- 0xd9, 0xd5, 0x05, 0xf9, 0x20, 0xa1, 0x63, 0xd7,
-};
-
-/*
-** The size of the of each page record in the journal is given by
-** the following macro.
-*/
-#define JOURNAL_PG_SZ(pPager) ((pPager->pageSize) + 8)
-
-/*
-** The journal header size for this pager. This is usually the same
-** size as a single disk sector. See also setSectorSize().
-*/
-#define JOURNAL_HDR_SZ(pPager) (pPager->sectorSize)
-
-/*
-** The macro MEMDB is true if we are dealing with an in-memory database.
-** We do this as a macro so that if the SQLITE_OMIT_MEMORYDB macro is set,
-** the value of MEMDB will be a constant and the compiler will optimize
-** out code that would never execute.
-*/
-#ifdef SQLITE_OMIT_MEMORYDB
-# define MEMDB 0
-#else
-# define MEMDB pPager->memDb
-#endif
-
-/*
-** The maximum legal page number is (2^31 - 1).
-*/
-#define PAGER_MAX_PGNO 2147483647
-
-#ifndef NDEBUG
-/*
-** Usage:
-**
-** assert( assert_pager_state(pPager) );
-*/
-static int assert_pager_state(Pager *pPager){
-
- /* A temp-file is always in PAGER_EXCLUSIVE or PAGER_SYNCED state. */
- assert( pPager->tempFile==0 || pPager->state>=PAGER_EXCLUSIVE );
-
- /* The changeCountDone flag is always set for temp-files */
- assert( pPager->tempFile==0 || pPager->changeCountDone );
-
- return 1;
-}
-#endif
-
-/*
-** Return true if it is necessary to write page *pPg into the sub-journal.
-** A page needs to be written into the sub-journal if there exists one
-** or more open savepoints for which:
-**
-** * The page-number is less than or equal to PagerSavepoint.nOrig, and
-** * The bit corresponding to the page-number is not set in
-** PagerSavepoint.pInSavepoint.
-*/
-static int subjRequiresPage(PgHdr *pPg){
- Pgno pgno = pPg->pgno;
- Pager *pPager = pPg->pPager;
- int i;
- for(i=0; i<pPager->nSavepoint; i++){
- PagerSavepoint *p = &pPager->aSavepoint[i];
- if( p->nOrig>=pgno && 0==sqlite3BitvecTest(p->pInSavepoint, pgno) ){
- return 1;
- }
- }
- return 0;
-}
-
-/*
-** Return true if the page is already in the journal file.
-*/
-static int pageInJournal(PgHdr *pPg){
- return sqlite3BitvecTest(pPg->pPager->pInJournal, pPg->pgno);
-}
-
-/*
-** Read a 32-bit integer from the given file descriptor. Store the integer
-** that is read in *pRes. Return SQLITE_OK if everything worked, or an
-** error code is something goes wrong.
-**
-** All values are stored on disk as big-endian.
-*/
-static int read32bits(sqlite3_file *fd, i64 offset, u32 *pRes){
- unsigned char ac[4];
- int rc = sqlite3OsRead(fd, ac, sizeof(ac), offset);
- if( rc==SQLITE_OK ){
- *pRes = sqlite3Get4byte(ac);
- }
- return rc;
-}
-
-/*
-** Write a 32-bit integer into a string buffer in big-endian byte order.
-*/
-#define put32bits(A,B) sqlite3Put4byte((u8*)A,B)
-
-/*
-** Write a 32-bit integer into the given file descriptor. Return SQLITE_OK
-** on success or an error code is something goes wrong.
-*/
-static int write32bits(sqlite3_file *fd, i64 offset, u32 val){
- char ac[4];
- put32bits(ac, val);
- return sqlite3OsWrite(fd, ac, 4, offset);
-}
-
-/*
-** The argument to this macro is a file descriptor (type sqlite3_file*).
-** Return 0 if it is not open, or non-zero (but not 1) if it is.
-**
-** This is so that expressions can be written as:
-**
-** if( isOpen(pPager->jfd) ){ ...
-**
-** instead of
-**
-** if( pPager->jfd->pMethods ){ ...
-*/
-#define isOpen(pFd) ((pFd)->pMethods)
-
-/*
-** If file pFd is open, call sqlite3OsUnlock() on it.
-*/
-static int osUnlock(sqlite3_file *pFd, int eLock){
- if( !isOpen(pFd) ){
- return SQLITE_OK;
- }
- return sqlite3OsUnlock(pFd, eLock);
-}
-
-/*
-** This function determines whether or not the atomic-write optimization
-** can be used with this pager. The optimization can be used if:
-**
-** (a) the value returned by OsDeviceCharacteristics() indicates that
-** a database page may be written atomically, and
-** (b) the value returned by OsSectorSize() is less than or equal
-** to the page size.
-**
-** The optimization is also always enabled for temporary files. It is
-** an error to call this function if pPager is opened on an in-memory
-** database.
-**
-** If the optimization cannot be used, 0 is returned. If it can be used,
-** then the value returned is the size of the journal file when it
-** contains rollback data for exactly one page.
-*/
-#ifdef SQLITE_ENABLE_ATOMIC_WRITE
-static int jrnlBufferSize(Pager *pPager){
- assert( !MEMDB );
- if( !pPager->tempFile ){
- int dc; /* Device characteristics */
- int nSector; /* Sector size */
- int szPage; /* Page size */
-
- assert( isOpen(pPager->fd) );
- dc = sqlite3OsDeviceCharacteristics(pPager->fd);
- nSector = pPager->sectorSize;
- szPage = pPager->pageSize;
-
- assert(SQLITE_IOCAP_ATOMIC512==(512>>8));
- assert(SQLITE_IOCAP_ATOMIC64K==(65536>>8));
- if( 0==(dc&(SQLITE_IOCAP_ATOMIC|(szPage>>8)) || nSector>szPage) ){
- return 0;
- }
- }
-
- return JOURNAL_HDR_SZ(pPager) + JOURNAL_PG_SZ(pPager);
-}
-#endif
-
-/*
-** If SQLITE_CHECK_PAGES is defined then we do some sanity checking
-** on the cache using a hash function. This is used for testing
-** and debugging only.
-*/
-#ifdef SQLITE_CHECK_PAGES
-/*
-** Return a 32-bit hash of the page data for pPage.
-*/
-static u32 pager_datahash(int nByte, unsigned char *pData){
- u32 hash = 0;
- int i;
- for(i=0; i<nByte; i++){
- hash = (hash*1039) + pData[i];
- }
- return hash;
-}
-static u32 pager_pagehash(PgHdr *pPage){
- return pager_datahash(pPage->pPager->pageSize, (unsigned char *)pPage->pData);
-}
-static void pager_set_pagehash(PgHdr *pPage){
- pPage->pageHash = pager_pagehash(pPage);
-}
-
-/*
-** The CHECK_PAGE macro takes a PgHdr* as an argument. If SQLITE_CHECK_PAGES
-** is defined, and NDEBUG is not defined, an assert() statement checks
-** that the page is either dirty or still matches the calculated page-hash.
-*/
-#define CHECK_PAGE(x) checkPage(x)
-static void checkPage(PgHdr *pPg){
- Pager *pPager = pPg->pPager;
- assert( !pPg->pageHash || pPager->errCode
- || (pPg->flags&PGHDR_DIRTY) || pPg->pageHash==pager_pagehash(pPg) );
-}
-
-#else
-#define pager_datahash(X,Y) 0
-#define pager_pagehash(X) 0
-#define CHECK_PAGE(x)
-#endif /* SQLITE_CHECK_PAGES */
-
-/*
-** When this is called the journal file for pager pPager must be open.
-** This function attempts to read a master journal file name from the
-** end of the file and, if successful, copies it into memory supplied
-** by the caller. See comments above writeMasterJournal() for the format
-** used to store a master journal file name at the end of a journal file.
-**
-** zMaster must point to a buffer of at least nMaster bytes allocated by
-** the caller. This should be sqlite3_vfs.mxPathname+1 (to ensure there is
-** enough space to write the master journal name). If the master journal
-** name in the journal is longer than nMaster bytes (including a
-** nul-terminator), then this is handled as if no master journal name
-** were present in the journal.
-**
-** If a master journal file name is present at the end of the journal
-** file, then it is copied into the buffer pointed to by zMaster. A
-** nul-terminator byte is appended to the buffer following the master
-** journal file name.
-**
-** If it is determined that no master journal file name is present
-** zMaster[0] is set to 0 and SQLITE_OK returned.
-**
-** If an error occurs while reading from the journal file, an SQLite
-** error code is returned.
-*/
-static int readMasterJournal(sqlite3_file *pJrnl, char *zMaster, u32 nMaster){
- int rc; /* Return code */
- u32 len; /* Length in bytes of master journal name */
- i64 szJ; /* Total size in bytes of journal file pJrnl */
- u32 cksum; /* MJ checksum value read from journal */
- u32 u; /* Unsigned loop counter */
- unsigned char aMagic[8]; /* A buffer to hold the magic header */
- zMaster[0] = '\0';
-
- if( SQLITE_OK!=(rc = sqlite3OsFileSize(pJrnl, &szJ))
- || szJ<16
- || SQLITE_OK!=(rc = read32bits(pJrnl, szJ-16, &len))
- || len>=nMaster
- || SQLITE_OK!=(rc = read32bits(pJrnl, szJ-12, &cksum))
- || SQLITE_OK!=(rc = sqlite3OsRead(pJrnl, aMagic, 8, szJ-8))
- || memcmp(aMagic, aJournalMagic, 8)
- || SQLITE_OK!=(rc = sqlite3OsRead(pJrnl, zMaster, len, szJ-16-len))
- ){
- return rc;
- }
-
- /* See if the checksum matches the master journal name */
- for(u=0; u<len; u++){
- cksum -= zMaster[u];
- }
- if( cksum ){
- /* If the checksum doesn't add up, then one or more of the disk sectors
- ** containing the master journal filename is corrupted. This means
- ** definitely roll back, so just return SQLITE_OK and report a (nul)
- ** master-journal filename.
- */
- len = 0;
- }
- zMaster[len] = '\0';
-
- return SQLITE_OK;
-}
-
-/*
-** Return the offset of the sector boundary at or immediately
-** following the value in pPager->journalOff, assuming a sector
-** size of pPager->sectorSize bytes.
-**
-** i.e for a sector size of 512:
-**
-** Pager.journalOff Return value
-** ---------------------------------------
-** 0 0
-** 512 512
-** 100 512
-** 2000 2048
-**
-*/
-static i64 journalHdrOffset(Pager *pPager){
- i64 offset = 0;
- i64 c = pPager->journalOff;
- if( c ){
- offset = ((c-1)/JOURNAL_HDR_SZ(pPager) + 1) * JOURNAL_HDR_SZ(pPager);
- }
- assert( offset%JOURNAL_HDR_SZ(pPager)==0 );
- assert( offset>=c );
- assert( (offset-c)<JOURNAL_HDR_SZ(pPager) );
- return offset;
-}
-
-/*
-** The journal file must be open when this function is called.
-**
-** This function is a no-op if the journal file has not been written to
-** within the current transaction (i.e. if Pager.journalOff==0).
-**
-** If doTruncate is non-zero or the Pager.journalSizeLimit variable is
-** set to 0, then truncate the journal file to zero bytes in size. Otherwise,
-** zero the 28-byte header at the start of the journal file. In either case,
-** if the pager is not in no-sync mode, sync the journal file immediately
-** after writing or truncating it.
-**
-** If Pager.journalSizeLimit is set to a positive, non-zero value, and
-** following the truncation or zeroing described above the size of the
-** journal file in bytes is larger than this value, then truncate the
-** journal file to Pager.journalSizeLimit bytes. The journal file does
-** not need to be synced following this operation.
-**
-** If an IO error occurs, abandon processing and return the IO error code.
-** Otherwise, return SQLITE_OK.
-*/
-static int zeroJournalHdr(Pager *pPager, int doTruncate){
- int rc = SQLITE_OK; /* Return code */
- assert( isOpen(pPager->jfd) );
- if( pPager->journalOff ){
- const i64 iLimit = pPager->journalSizeLimit; /* Local cache of jsl */
-
- IOTRACE(("JZEROHDR %p\n", pPager))
- if( doTruncate || iLimit==0 ){
- rc = sqlite3OsTruncate(pPager->jfd, 0);
- }else{
- static const char zeroHdr[28] = {0};
- rc = sqlite3OsWrite(pPager->jfd, zeroHdr, sizeof(zeroHdr), 0);
- }
- if( rc==SQLITE_OK && !pPager->noSync ){
- rc = sqlite3OsSync(pPager->jfd, SQLITE_SYNC_DATAONLY|pPager->sync_flags);
- }
-
- /* At this point the transaction is committed but the write lock
- ** is still held on the file. If there is a size limit configured for
- ** the persistent journal and the journal file currently consumes more
- ** space than that limit allows for, truncate it now. There is no need
- ** to sync the file following this operation.
- */
- if( rc==SQLITE_OK && iLimit>0 ){
- i64 sz;
- rc = sqlite3OsFileSize(pPager->jfd, &sz);
- if( rc==SQLITE_OK && sz>iLimit ){
- rc = sqlite3OsTruncate(pPager->jfd, iLimit);
- }
- }
- }
- return rc;
-}
-
-/*
-** The journal file must be open when this routine is called. A journal
-** header (JOURNAL_HDR_SZ bytes) is written into the journal file at the
-** current location.
-**
-** The format for the journal header is as follows:
-** - 8 bytes: Magic identifying journal format.
-** - 4 bytes: Number of records in journal, or -1 no-sync mode is on.
-** - 4 bytes: Random number used for page hash.
-** - 4 bytes: Initial database page count.
-** - 4 bytes: Sector size used by the process that wrote this journal.
-** - 4 bytes: Database page size.
-**
-** Followed by (JOURNAL_HDR_SZ - 28) bytes of unused space.
-*/
-static int writeJournalHdr(Pager *pPager){
- int rc = SQLITE_OK; /* Return code */
- char *zHeader = pPager->pTmpSpace; /* Temporary space used to build header */
- u32 nHeader = pPager->pageSize; /* Size of buffer pointed to by zHeader */
- u32 nWrite; /* Bytes of header sector written */
- int ii; /* Loop counter */
-
- assert( isOpen(pPager->jfd) ); /* Journal file must be open. */
-
- if( nHeader>JOURNAL_HDR_SZ(pPager) ){
- nHeader = JOURNAL_HDR_SZ(pPager);
- }
-
- /* If there are active savepoints and any of them were created
- ** since the most recent journal header was written, update the
- ** PagerSavepoint.iHdrOffset fields now.
- */
- for(ii=0; ii<pPager->nSavepoint; ii++){
- if( pPager->aSavepoint[ii].iHdrOffset==0 ){
- pPager->aSavepoint[ii].iHdrOffset = pPager->journalOff;
- }
- }
-
- pPager->journalHdr = pPager->journalOff = journalHdrOffset(pPager);
-
- /*
- ** Write the nRec Field - the number of page records that follow this
- ** journal header. Normally, zero is written to this value at this time.
- ** After the records are added to the journal (and the journal synced,
- ** if in full-sync mode), the zero is overwritten with the true number
- ** of records (see syncJournal()).
- **
- ** A faster alternative is to write 0xFFFFFFFF to the nRec field. When
- ** reading the journal this value tells SQLite to assume that the
- ** rest of the journal file contains valid page records. This assumption
- ** is dangerous, as if a failure occurred whilst writing to the journal
- ** file it may contain some garbage data. There are two scenarios
- ** where this risk can be ignored:
- **
- ** * When the pager is in no-sync mode. Corruption can follow a
- ** power failure in this case anyway.
- **
- ** * When the SQLITE_IOCAP_SAFE_APPEND flag is set. This guarantees
- ** that garbage data is never appended to the journal file.
- */
- assert( isOpen(pPager->fd) || pPager->noSync );
- if( (pPager->noSync) || (pPager->journalMode==PAGER_JOURNALMODE_MEMORY)
- || (sqlite3OsDeviceCharacteristics(pPager->fd)&SQLITE_IOCAP_SAFE_APPEND)
- ){
- memcpy(zHeader, aJournalMagic, sizeof(aJournalMagic));
- put32bits(&zHeader[sizeof(aJournalMagic)], 0xffffffff);
- }else{
- memset(zHeader, 0, sizeof(aJournalMagic)+4);
- }
-
- /* The random check-hash initialiser */
- sqlite3_randomness(sizeof(pPager->cksumInit), &pPager->cksumInit);
- put32bits(&zHeader[sizeof(aJournalMagic)+4], pPager->cksumInit);
- /* The initial database size */
- put32bits(&zHeader[sizeof(aJournalMagic)+8], pPager->dbOrigSize);
- /* The assumed sector size for this process */
- put32bits(&zHeader[sizeof(aJournalMagic)+12], pPager->sectorSize);
-
- /* The page size */
- put32bits(&zHeader[sizeof(aJournalMagic)+16], pPager->pageSize);
-
- /* Initializing the tail of the buffer is not necessary. Everything
- ** works find if the following memset() is omitted. But initializing
- ** the memory prevents valgrind from complaining, so we are willing to
- ** take the performance hit.
- */
- memset(&zHeader[sizeof(aJournalMagic)+20], 0,
- nHeader-(sizeof(aJournalMagic)+20));
-
- /* In theory, it is only necessary to write the 28 bytes that the
- ** journal header consumes to the journal file here. Then increment the
- ** Pager.journalOff variable by JOURNAL_HDR_SZ so that the next
- ** record is written to the following sector (leaving a gap in the file
- ** that will be implicitly filled in by the OS).
- **
- ** However it has been discovered that on some systems this pattern can
- ** be significantly slower than contiguously writing data to the file,
- ** even if that means explicitly writing data to the block of
- ** (JOURNAL_HDR_SZ - 28) bytes that will not be used. So that is what
- ** is done.
- **
- ** The loop is required here in case the sector-size is larger than the
- ** database page size. Since the zHeader buffer is only Pager.pageSize
- ** bytes in size, more than one call to sqlite3OsWrite() may be required
- ** to populate the entire journal header sector.
- */
- for(nWrite=0; rc==SQLITE_OK&&nWrite<JOURNAL_HDR_SZ(pPager); nWrite+=nHeader){
- IOTRACE(("JHDR %p %lld %d\n", pPager, pPager->journalHdr, nHeader))
- rc = sqlite3OsWrite(pPager->jfd, zHeader, nHeader, pPager->journalOff);
- pPager->journalOff += nHeader;
- }
-
- return rc;
-}
-
-/*
-** The journal file must be open when this is called. A journal header file
-** (JOURNAL_HDR_SZ bytes) is read from the current location in the journal
-** file. The current location in the journal file is given by
-** pPager->journalOff. See comments above function writeJournalHdr() for
-** a description of the journal header format.
-**
-** If the header is read successfully, *pNRec is set to the number of
-** page records following this header and *pDbSize is set to the size of the
-** database before the transaction began, in pages. Also, pPager->cksumInit
-** is set to the value read from the journal header. SQLITE_OK is returned
-** in this case.
-**
-** If the journal header file appears to be corrupted, SQLITE_DONE is
-** returned and *pNRec and *PDbSize are undefined. If JOURNAL_HDR_SZ bytes
-** cannot be read from the journal file an error code is returned.
-*/
-static int readJournalHdr(
- Pager *pPager, /* Pager object */
- int isHot,
- i64 journalSize, /* Size of the open journal file in bytes */
- u32 *pNRec, /* OUT: Value read from the nRec field */
- u32 *pDbSize /* OUT: Value of original database size field */
-){
- int rc; /* Return code */
- unsigned char aMagic[8]; /* A buffer to hold the magic header */
- i64 iHdrOff; /* Offset of journal header being read */
-
- assert( isOpen(pPager->jfd) ); /* Journal file must be open. */
-
- /* Advance Pager.journalOff to the start of the next sector. If the
- ** journal file is too small for there to be a header stored at this
- ** point, return SQLITE_DONE.
- */
- pPager->journalOff = journalHdrOffset(pPager);
- if( pPager->journalOff+JOURNAL_HDR_SZ(pPager) > journalSize ){
- return SQLITE_DONE;
- }
- iHdrOff = pPager->journalOff;
-
- /* Read in the first 8 bytes of the journal header. If they do not match
- ** the magic string found at the start of each journal header, return
- ** SQLITE_DONE. If an IO error occurs, return an error code. Otherwise,
- ** proceed.
- */
- if( isHot || iHdrOff!=pPager->journalHdr ){
- rc = sqlite3OsRead(pPager->jfd, aMagic, sizeof(aMagic), iHdrOff);
- if( rc ){
- return rc;
- }
- if( memcmp(aMagic, aJournalMagic, sizeof(aMagic))!=0 ){
- return SQLITE_DONE;
- }
- }
-
- /* Read the first three 32-bit fields of the journal header: The nRec
- ** field, the checksum-initializer and the database size at the start
- ** of the transaction. Return an error code if anything goes wrong.
- */
- if( SQLITE_OK!=(rc = read32bits(pPager->jfd, iHdrOff+8, pNRec))
- || SQLITE_OK!=(rc = read32bits(pPager->jfd, iHdrOff+12, &pPager->cksumInit))
- || SQLITE_OK!=(rc = read32bits(pPager->jfd, iHdrOff+16, pDbSize))
- ){
- return rc;
- }
-
- if( pPager->journalOff==0 ){
- u32 iPageSize; /* Page-size field of journal header */
- u32 iSectorSize; /* Sector-size field of journal header */
- u16 iPageSize16; /* Copy of iPageSize in 16-bit variable */
-
- /* Read the page-size and sector-size journal header fields. */
- if( SQLITE_OK!=(rc = read32bits(pPager->jfd, iHdrOff+20, &iSectorSize))
- || SQLITE_OK!=(rc = read32bits(pPager->jfd, iHdrOff+24, &iPageSize))
- ){
- return rc;
- }
-
- /* Check that the values read from the page-size and sector-size fields
- ** are within range. To be 'in range', both values need to be a power
- ** of two greater than or equal to 512, and not greater than their
- ** respective compile time maximum limits.
- */
- if( iPageSize<512 || iSectorSize<512
- || iPageSize>SQLITE_MAX_PAGE_SIZE || iSectorSize>MAX_SECTOR_SIZE
- || ((iPageSize-1)&iPageSize)!=0 || ((iSectorSize-1)&iSectorSize)!=0
- ){
- /* If the either the page-size or sector-size in the journal-header is
- ** invalid, then the process that wrote the journal-header must have
- ** crashed before the header was synced. In this case stop reading
- ** the journal file here.
- */
- return SQLITE_DONE;
- }
-
- /* Update the page-size to match the value read from the journal.
- ** Use a testcase() macro to make sure that malloc failure within
- ** PagerSetPagesize() is tested.
- */
- iPageSize16 = (u16)iPageSize;
- rc = sqlite3PagerSetPagesize(pPager, &iPageSize16, -1);
- testcase( rc!=SQLITE_OK );
- assert( rc!=SQLITE_OK || iPageSize16==(u16)iPageSize );
-
- /* Update the assumed sector-size to match the value used by
- ** the process that created this journal. If this journal was
- ** created by a process other than this one, then this routine
- ** is being called from within pager_playback(). The local value
- ** of Pager.sectorSize is restored at the end of that routine.
- */
- pPager->sectorSize = iSectorSize;
- }
-
- pPager->journalOff += JOURNAL_HDR_SZ(pPager);
- return rc;
-}
-
-
-/*
-** Write the supplied master journal name into the journal file for pager
-** pPager at the current location. The master journal name must be the last
-** thing written to a journal file. If the pager is in full-sync mode, the
-** journal file descriptor is advanced to the next sector boundary before
-** anything is written. The format is:
-**
-** + 4 bytes: PAGER_MJ_PGNO.
-** + N bytes: Master journal filename in utf-8.
-** + 4 bytes: N (length of master journal name in bytes, no nul-terminator).
-** + 4 bytes: Master journal name checksum.
-** + 8 bytes: aJournalMagic[].
-**
-** The master journal page checksum is the sum of the bytes in the master
-** journal name, where each byte is interpreted as a signed 8-bit integer.
-**
-** If zMaster is a NULL pointer (occurs for a single database transaction),
-** this call is a no-op.
-*/
-static int writeMasterJournal(Pager *pPager, const char *zMaster){
- int rc; /* Return code */
- int nMaster; /* Length of string zMaster */
- i64 iHdrOff; /* Offset of header in journal file */
- i64 jrnlSize; /* Size of journal file on disk */
- u32 cksum = 0; /* Checksum of string zMaster */
-
- if( !zMaster || pPager->setMaster
- || pPager->journalMode==PAGER_JOURNALMODE_MEMORY
- || pPager->journalMode==PAGER_JOURNALMODE_OFF
- ){
- return SQLITE_OK;
- }
- pPager->setMaster = 1;
- assert( isOpen(pPager->jfd) );
-
- /* Calculate the length in bytes and the checksum of zMaster */
- for(nMaster=0; zMaster[nMaster]; nMaster++){
- cksum += zMaster[nMaster];
- }
-
- /* If in full-sync mode, advance to the next disk sector before writing
- ** the master journal name. This is in case the previous page written to
- ** the journal has already been synced.
- */
- if( pPager->fullSync ){
- pPager->journalOff = journalHdrOffset(pPager);
- }
- iHdrOff = pPager->journalOff;
-
- /* Write the master journal data to the end of the journal file. If
- ** an error occurs, return the error code to the caller.
- */
- if( (0 != (rc = write32bits(pPager->jfd, iHdrOff, PAGER_MJ_PGNO(pPager))))
- || (0 != (rc = sqlite3OsWrite(pPager->jfd, zMaster, nMaster, iHdrOff+4)))
- || (0 != (rc = write32bits(pPager->jfd, iHdrOff+4+nMaster, nMaster)))
- || (0 != (rc = write32bits(pPager->jfd, iHdrOff+4+nMaster+4, cksum)))
- || (0 != (rc = sqlite3OsWrite(pPager->jfd, aJournalMagic, 8, iHdrOff+4+nMaster+8)))
- ){
- return rc;
- }
- pPager->journalOff += (nMaster+20);
- pPager->needSync = !pPager->noSync;
-
- /* If the pager is in peristent-journal mode, then the physical
- ** journal-file may extend past the end of the master-journal name
- ** and 8 bytes of magic data just written to the file. This is
- ** dangerous because the code to rollback a hot-journal file
- ** will not be able to find the master-journal name to determine
- ** whether or not the journal is hot.
- **
- ** Easiest thing to do in this scenario is to truncate the journal
- ** file to the required size.
- */
- if( SQLITE_OK==(rc = sqlite3OsFileSize(pPager->jfd, &jrnlSize))
- && jrnlSize>pPager->journalOff
- ){
- rc = sqlite3OsTruncate(pPager->jfd, pPager->journalOff);
- }
- return rc;
-}
-
-/*
-** Find a page in the hash table given its page number. Return
-** a pointer to the page or NULL if the requested page is not
-** already in memory.
-*/
-static PgHdr *pager_lookup(Pager *pPager, Pgno pgno){
- PgHdr *p; /* Return value */
-
- /* It is not possible for a call to PcacheFetch() with createFlag==0 to
- ** fail, since no attempt to allocate dynamic memory will be made.
- */
- (void)sqlite3PcacheFetch(pPager->pPCache, pgno, 0, &p);
- return p;
-}
-
-/*
-** Unless the pager is in error-state, discard all in-memory pages. If
-** the pager is in error-state, then this call is a no-op.
-**
-** TODO: Why can we not reset the pager while in error state?
-*/
-static void pager_reset(Pager *pPager){
- if( SQLITE_OK==pPager->errCode ){
- sqlite3BackupRestart(pPager->pBackup);
- sqlite3PcacheClear(pPager->pPCache);
- pPager->dbSizeValid = 0;
- }
-}
-
-/*
-** Free all structures in the Pager.aSavepoint[] array and set both
-** Pager.aSavepoint and Pager.nSavepoint to zero. Close the sub-journal
-** if it is open and the pager is not in exclusive mode.
-*/
-static void releaseAllSavepoints(Pager *pPager){
- int ii; /* Iterator for looping through Pager.aSavepoint */
- for(ii=0; ii<pPager->nSavepoint; ii++){
- sqlite3BitvecDestroy(pPager->aSavepoint[ii].pInSavepoint);
- }
- if( !pPager->exclusiveMode || sqlite3IsMemJournal(pPager->sjfd) ){
- sqlite3OsClose(pPager->sjfd);
- }
- sqlite3_free(pPager->aSavepoint);
- pPager->aSavepoint = 0;
- pPager->nSavepoint = 0;
- pPager->nSubRec = 0;
-}
-
-/*
-** Set the bit number pgno in the PagerSavepoint.pInSavepoint
-** bitvecs of all open savepoints. Return SQLITE_OK if successful
-** or SQLITE_NOMEM if a malloc failure occurs.
-*/
-static int addToSavepointBitvecs(Pager *pPager, Pgno pgno){
- int ii; /* Loop counter */
- int rc = SQLITE_OK; /* Result code */
-
- for(ii=0; ii<pPager->nSavepoint; ii++){
- PagerSavepoint *p = &pPager->aSavepoint[ii];
- if( pgno<=p->nOrig ){
- rc |= sqlite3BitvecSet(p->pInSavepoint, pgno);
- testcase( rc==SQLITE_NOMEM );
- assert( rc==SQLITE_OK || rc==SQLITE_NOMEM );
- }
- }
- return rc;
-}
-
-/*
-** Unlock the database file. This function is a no-op if the pager
-** is in exclusive mode.
-**
-** If the pager is currently in error state, discard the contents of
-** the cache and reset the Pager structure internal state. If there is
-** an open journal-file, then the next time a shared-lock is obtained
-** on the pager file (by this or any other process), it will be
-** treated as a hot-journal and rolled back.
-*/
-static void pager_unlock(Pager *pPager){
- if( !pPager->exclusiveMode ){
- int rc; /* Return code */
-
- /* Always close the journal file when dropping the database lock.
- ** Otherwise, another connection with journal_mode=delete might
- ** delete the file out from under us.
- */
- sqlite3OsClose(pPager->jfd);
- sqlite3BitvecDestroy(pPager->pInJournal);
- pPager->pInJournal = 0;
- releaseAllSavepoints(pPager);
-
- /* If the file is unlocked, somebody else might change it. The
- ** values stored in Pager.dbSize etc. might become invalid if
- ** this happens. TODO: Really, this doesn't need to be cleared
- ** until the change-counter check fails in PagerSharedLock().
- */
- pPager->dbSizeValid = 0;
-
- rc = osUnlock(pPager->fd, NO_LOCK);
- if( rc ){
- pPager->errCode = rc;
- }
- IOTRACE(("UNLOCK %p\n", pPager))
-
- /* If Pager.errCode is set, the contents of the pager cache cannot be
- ** trusted. Now that the pager file is unlocked, the contents of the
- ** cache can be discarded and the error code safely cleared.
- */
- if( pPager->errCode ){
- if( rc==SQLITE_OK ){
- pPager->errCode = SQLITE_OK;
- }
- pager_reset(pPager);
- }
-
- pPager->changeCountDone = 0;
- pPager->state = PAGER_UNLOCK;
- }
-}
-
-/*
-** This function should be called when an IOERR, CORRUPT or FULL error
-** may have occurred. The first argument is a pointer to the pager
-** structure, the second the error-code about to be returned by a pager
-** API function. The value returned is a copy of the second argument
-** to this function.
-**
-** If the second argument is SQLITE_IOERR, SQLITE_CORRUPT, or SQLITE_FULL
-** the error becomes persistent. Until the persisten error is cleared,
-** subsequent API calls on this Pager will immediately return the same
-** error code.
-**
-** A persistent error indicates that the contents of the pager-cache
-** cannot be trusted. This state can be cleared by completely discarding
-** the contents of the pager-cache. If a transaction was active when
-** the persistent error occurred, then the rollback journal may need
-** to be replayed to restore the contents of the database file (as if
-** it were a hot-journal).
-*/
-static int pager_error(Pager *pPager, int rc){
- int rc2 = rc & 0xff;
- assert( rc==SQLITE_OK || !MEMDB );
- assert(
- pPager->errCode==SQLITE_FULL ||
- pPager->errCode==SQLITE_OK ||
- (pPager->errCode & 0xff)==SQLITE_IOERR
- );
- if( rc2==SQLITE_FULL || rc2==SQLITE_IOERR ){
- pPager->errCode = rc;
- }
- return rc;
-}
-
-/*
-** Execute a rollback if a transaction is active and unlock the
-** database file.
-**
-** If the pager has already entered the error state, do not attempt
-** the rollback at this time. Instead, pager_unlock() is called. The
-** call to pager_unlock() will discard all in-memory pages, unlock
-** the database file and clear the error state. If this means that
-** there is a hot-journal left in the file-system, the next connection
-** to obtain a shared lock on the pager (which may be this one) will
-** roll it back.
-**
-** If the pager has not already entered the error state, but an IO or
-** malloc error occurs during a rollback, then this will itself cause
-** the pager to enter the error state. Which will be cleared by the
-** call to pager_unlock(), as described above.
-*/
-static void pagerUnlockAndRollback(Pager *pPager){
- if( pPager->errCode==SQLITE_OK && pPager->state>=PAGER_RESERVED ){
- sqlite3BeginBenignMalloc();
- sqlite3PagerRollback(pPager);
- sqlite3EndBenignMalloc();
- }
- pager_unlock(pPager);
-}
-
-/*
-** This routine ends a transaction. A transaction is usually ended by
-** either a COMMIT or a ROLLBACK operation. This routine may be called
-** after rollback of a hot-journal, or if an error occurs while opening
-** the journal file or writing the very first journal-header of a
-** database transaction.
-**
-** If the pager is in PAGER_SHARED or PAGER_UNLOCK state when this
-** routine is called, it is a no-op (returns SQLITE_OK).
-**
-** Otherwise, any active savepoints are released.
-**
-** If the journal file is open, then it is "finalized". Once a journal
-** file has been finalized it is not possible to use it to roll back a
-** transaction. Nor will it be considered to be a hot-journal by this
-** or any other database connection. Exactly how a journal is finalized
-** depends on whether or not the pager is running in exclusive mode and
-** the current journal-mode (Pager.journalMode value), as follows:
-**
-** journalMode==MEMORY
-** Journal file descriptor is simply closed. This destroys an
-** in-memory journal.
-**
-** journalMode==TRUNCATE
-** Journal file is truncated to zero bytes in size.
-**
-** journalMode==PERSIST
-** The first 28 bytes of the journal file are zeroed. This invalidates
-** the first journal header in the file, and hence the entire journal
-** file. An invalid journal file cannot be rolled back.
-**
-** journalMode==DELETE
-** The journal file is closed and deleted using sqlite3OsDelete().
-**
-** If the pager is running in exclusive mode, this method of finalizing
-** the journal file is never used. Instead, if the journalMode is
-** DELETE and the pager is in exclusive mode, the method described under
-** journalMode==PERSIST is used instead.
-**
-** After the journal is finalized, if running in non-exclusive mode, the
-** pager moves to PAGER_SHARED state (and downgrades the lock on the
-** database file accordingly).
-**
-** If the pager is running in exclusive mode and is in PAGER_SYNCED state,
-** it moves to PAGER_EXCLUSIVE. No locks are downgraded when running in
-** exclusive mode.
-**
-** SQLITE_OK is returned if no error occurs. If an error occurs during
-** any of the IO operations to finalize the journal file or unlock the
-** database then the IO error code is returned to the user. If the
-** operation to finalize the journal file fails, then the code still
-** tries to unlock the database file if not in exclusive mode. If the
-** unlock operation fails as well, then the first error code related
-** to the first error encountered (the journal finalization one) is
-** returned.
-*/
-static int pager_end_transaction(Pager *pPager, int hasMaster){
- int rc = SQLITE_OK; /* Error code from journal finalization operation */
- int rc2 = SQLITE_OK; /* Error code from db file unlock operation */
-
- if( pPager->state<PAGER_RESERVED ){
- return SQLITE_OK;
- }
- releaseAllSavepoints(pPager);
-
- assert( isOpen(pPager->jfd) || pPager->pInJournal==0 );
- if( isOpen(pPager->jfd) ){
-
- /* Finalize the journal file. */
- if( sqlite3IsMemJournal(pPager->jfd) ){
- assert( pPager->journalMode==PAGER_JOURNALMODE_MEMORY );
- sqlite3OsClose(pPager->jfd);
- }else if( pPager->journalMode==PAGER_JOURNALMODE_TRUNCATE ){
- if( pPager->journalOff==0 ){
- rc = SQLITE_OK;
- }else{
- rc = sqlite3OsTruncate(pPager->jfd, 0);
- }
- pPager->journalOff = 0;
- pPager->journalStarted = 0;
- }else if( pPager->exclusiveMode
- || pPager->journalMode==PAGER_JOURNALMODE_PERSIST
- ){
- rc = zeroJournalHdr(pPager, hasMaster);
- pager_error(pPager, rc);
- pPager->journalOff = 0;
- pPager->journalStarted = 0;
- }else{
- /* This branch may be executed with Pager.journalMode==MEMORY if
- ** a hot-journal was just rolled back. In this case the journal
- ** file should be closed and deleted. If this connection writes to
- ** the database file, it will do so using an in-memory journal. */
- assert( pPager->journalMode==PAGER_JOURNALMODE_DELETE
- || pPager->journalMode==PAGER_JOURNALMODE_MEMORY
- );
- sqlite3OsClose(pPager->jfd);
- if( !pPager->tempFile ){
- rc = sqlite3OsDelete(pPager->pVfs, pPager->zJournal, 0);
- }
- }
-
-#ifdef SQLITE_CHECK_PAGES
- sqlite3PcacheIterateDirty(pPager->pPCache, pager_set_pagehash);
-#endif
-
- sqlite3PcacheCleanAll(pPager->pPCache);
- sqlite3BitvecDestroy(pPager->pInJournal);
- pPager->pInJournal = 0;
- pPager->nRec = 0;
- }
-
- if( !pPager->exclusiveMode ){
- rc2 = osUnlock(pPager->fd, SHARED_LOCK);
- pPager->state = PAGER_SHARED;
- pPager->changeCountDone = 0;
- }else if( pPager->state==PAGER_SYNCED ){
- pPager->state = PAGER_EXCLUSIVE;
- }
- pPager->setMaster = 0;
- pPager->needSync = 0;
- pPager->dbModified = 0;
-
- /* TODO: Is this optimal? Why is the db size invalidated here
- ** when the database file is not unlocked? */
- pPager->dbOrigSize = 0;
- sqlite3PcacheTruncate(pPager->pPCache, pPager->dbSize);
- if( !MEMDB ){
- pPager->dbSizeValid = 0;
- }
-
- return (rc==SQLITE_OK?rc2:rc);
-}
-
-/*
-** Parameter aData must point to a buffer of pPager->pageSize bytes
-** of data. Compute and return a checksum based ont the contents of the
-** page of data and the current value of pPager->cksumInit.
-**
-** This is not a real checksum. It is really just the sum of the
-** random initial value (pPager->cksumInit) and every 200th byte
-** of the page data, starting with byte offset (pPager->pageSize%200).
-** Each byte is interpreted as an 8-bit unsigned integer.
-**
-** Changing the formula used to compute this checksum results in an
-** incompatible journal file format.
-**
-** If journal corruption occurs due to a power failure, the most likely
-** scenario is that one end or the other of the record will be changed.
-** It is much less likely that the two ends of the journal record will be
-** correct and the middle be corrupt. Thus, this "checksum" scheme,
-** though fast and simple, catches the mostly likely kind of corruption.
-*/
-static u32 pager_cksum(Pager *pPager, const u8 *aData){
- u32 cksum = pPager->cksumInit; /* Checksum value to return */
- int i = pPager->pageSize-200; /* Loop counter */
- while( i>0 ){
- cksum += aData[i];
- i -= 200;
- }
- return cksum;
-}
-
-/*
-** Read a single page from either the journal file (if isMainJrnl==1) or
-** from the sub-journal (if isMainJrnl==0) and playback that page.
-** The page begins at offset *pOffset into the file. The *pOffset
-** value is increased to the start of the next page in the journal.
-**
-** The isMainJrnl flag is true if this is the main rollback journal and
-** false for the statement journal. The main rollback journal uses
-** checksums - the statement journal does not.
-**
-** If the page number of the page record read from the (sub-)journal file
-** is greater than the current value of Pager.dbSize, then playback is
-** skipped and SQLITE_OK is returned.
-**
-** If pDone is not NULL, then it is a record of pages that have already
-** been played back. If the page at *pOffset has already been played back
-** (if the corresponding pDone bit is set) then skip the playback.
-** Make sure the pDone bit corresponding to the *pOffset page is set
-** prior to returning.
-**
-** If the page record is successfully read from the (sub-)journal file
-** and played back, then SQLITE_OK is returned. If an IO error occurs
-** while reading the record from the (sub-)journal file or while writing
-** to the database file, then the IO error code is returned. If data
-** is successfully read from the (sub-)journal file but appears to be
-** corrupted, SQLITE_DONE is returned. Data is considered corrupted in
-** two circumstances:
-**
-** * If the record page-number is illegal (0 or PAGER_MJ_PGNO), or
-** * If the record is being rolled back from the main journal file
-** and the checksum field does not match the record content.
-**
-** Neither of these two scenarios are possible during a savepoint rollback.
-**
-** If this is a savepoint rollback, then memory may have to be dynamically
-** allocated by this function. If this is the case and an allocation fails,
-** SQLITE_NOMEM is returned.
-*/
-static int pager_playback_one_page(
- Pager *pPager, /* The pager being played back */
- int isMainJrnl, /* 1 -> main journal. 0 -> sub-journal. */
- int isUnsync, /* True if reading from unsynced main journal */
- i64 *pOffset, /* Offset of record to playback */
- int isSavepnt, /* True for a savepoint rollback */
- Bitvec *pDone /* Bitvec of pages already played back */
-){
- int rc;
- PgHdr *pPg; /* An existing page in the cache */
- Pgno pgno; /* The page number of a page in journal */
- u32 cksum; /* Checksum used for sanity checking */
- u8 *aData; /* Temporary storage for the page */
- sqlite3_file *jfd; /* The file descriptor for the journal file */
-
- assert( (isMainJrnl&~1)==0 ); /* isMainJrnl is 0 or 1 */
- assert( (isSavepnt&~1)==0 ); /* isSavepnt is 0 or 1 */
- assert( isMainJrnl || pDone ); /* pDone always used on sub-journals */
- assert( isSavepnt || pDone==0 ); /* pDone never used on non-savepoint */
-
- aData = (u8*)pPager->pTmpSpace;
- assert( aData ); /* Temp storage must have already been allocated */
-
- /* Read the page number and page data from the journal or sub-journal
- ** file. Return an error code to the caller if an IO error occurs.
- */
- jfd = isMainJrnl ? pPager->jfd : pPager->sjfd;
- rc = read32bits(jfd, *pOffset, &pgno);
- if( rc!=SQLITE_OK ) return rc;
- rc = sqlite3OsRead(jfd, aData, pPager->pageSize, (*pOffset)+4);
- if( rc!=SQLITE_OK ) return rc;
- *pOffset += pPager->pageSize + 4 + isMainJrnl*4;
-
- /* Sanity checking on the page. This is more important that I originally
- ** thought. If a power failure occurs while the journal is being written,
- ** it could cause invalid data to be written into the journal. We need to
- ** detect this invalid data (with high probability) and ignore it.
- */
- if( pgno==0 || pgno==PAGER_MJ_PGNO(pPager) ){
- assert( !isSavepnt );
- return SQLITE_DONE;
- }
- if( pgno>(Pgno)pPager->dbSize || sqlite3BitvecTest(pDone, pgno) ){
- return SQLITE_OK;
- }
- if( isMainJrnl ){
- rc = read32bits(jfd, (*pOffset)-4, &cksum);
- if( rc ) return rc;
- if( !isSavepnt && pager_cksum(pPager, aData)!=cksum ){
- return SQLITE_DONE;
- }
- }
-
- if( pDone && (rc = sqlite3BitvecSet(pDone, pgno))!=SQLITE_OK ){
- return rc;
- }
-
- assert( pPager->state==PAGER_RESERVED || pPager->state>=PAGER_EXCLUSIVE );
-
- /* If the pager is in RESERVED state, then there must be a copy of this
- ** page in the pager cache. In this case just update the pager cache,
- ** not the database file. The page is left marked dirty in this case.
- **
- ** An exception to the above rule: If the database is in no-sync mode
- ** and a page is moved during an incremental vacuum then the page may
- ** not be in the pager cache. Later: if a malloc() or IO error occurs
- ** during a Movepage() call, then the page may not be in the cache
- ** either. So the condition described in the above paragraph is not
- ** assert()able.
- **
- ** If in EXCLUSIVE state, then we update the pager cache if it exists
- ** and the main file. The page is then marked not dirty.
- **
- ** Ticket #1171: The statement journal might contain page content that is
- ** different from the page content at the start of the transaction.
- ** This occurs when a page is changed prior to the start of a statement
- ** then changed again within the statement. When rolling back such a
- ** statement we must not write to the original database unless we know
- ** for certain that original page contents are synced into the main rollback
- ** journal. Otherwise, a power loss might leave modified data in the
- ** database file without an entry in the rollback journal that can
- ** restore the database to its original form. Two conditions must be
- ** met before writing to the database files. (1) the database must be
- ** locked. (2) we know that the original page content is fully synced
- ** in the main journal either because the page is not in cache or else
- ** the page is marked as needSync==0.
- **
- ** 2008-04-14: When attempting to vacuum a corrupt database file, it
- ** is possible to fail a statement on a database that does not yet exist.
- ** Do not attempt to write if database file has never been opened.
- */
- pPg = pager_lookup(pPager, pgno);
- assert( pPg || !MEMDB );
- PAGERTRACE(("PLAYBACK %d page %d hash(%08x) %s\n",
- PAGERID(pPager), pgno, pager_datahash(pPager->pageSize, aData),
- (isMainJrnl?"main-journal":"sub-journal")
- ));
- if( (pPager->state>=PAGER_EXCLUSIVE)
- && (pPg==0 || 0==(pPg->flags&PGHDR_NEED_SYNC))
- && isOpen(pPager->fd)
- && !isUnsync
- ){
- i64 ofst = (pgno-1)*(i64)pPager->pageSize;
- rc = sqlite3OsWrite(pPager->fd, aData, pPager->pageSize, ofst);
- if( pgno>pPager->dbFileSize ){
- pPager->dbFileSize = pgno;
- }
- if( pPager->pBackup ){
- CODEC1(pPager, aData, pgno, 3, rc=SQLITE_NOMEM);
- sqlite3BackupUpdate(pPager->pBackup, pgno, aData);
- CODEC1(pPager, aData, pgno, 0, rc=SQLITE_NOMEM);
- }
- }else if( !isMainJrnl && pPg==0 ){
- /* If this is a rollback of a savepoint and data was not written to
- ** the database and the page is not in-memory, there is a potential
- ** problem. When the page is next fetched by the b-tree layer, it
- ** will be read from the database file, which may or may not be
- ** current.
- **
- ** There are a couple of different ways this can happen. All are quite
- ** obscure. When running in synchronous mode, this can only happen
- ** if the page is on the free-list at the start of the transaction, then
- ** populated, then moved using sqlite3PagerMovepage().
- **
- ** The solution is to add an in-memory page to the cache containing
- ** the data just read from the sub-journal. Mark the page as dirty
- ** and if the pager requires a journal-sync, then mark the page as
- ** requiring a journal-sync before it is written.
- */
- assert( isSavepnt );
- if( (rc = sqlite3PagerAcquire(pPager, pgno, &pPg, 1))!=SQLITE_OK ){
- return rc;
- }
- pPg->flags &= ~PGHDR_NEED_READ;
- sqlite3PcacheMakeDirty(pPg);
- }
- if( pPg ){
- /* No page should ever be explicitly rolled back that is in use, except
- ** for page 1 which is held in use in order to keep the lock on the
- ** database active. However such a page may be rolled back as a result
- ** of an internal error resulting in an automatic call to
- ** sqlite3PagerRollback().
- */
- void *pData;
- pData = pPg->pData;
- memcpy(pData, aData, pPager->pageSize);
- pPager->xReiniter(pPg);
- if( isMainJrnl && (!isSavepnt || *pOffset<=pPager->journalHdr) ){
- /* If the contents of this page were just restored from the main
- ** journal file, then its content must be as they were when the
- ** transaction was first opened. In this case we can mark the page
- ** as clean, since there will be no need to write it out to the.
- **
- ** There is one exception to this rule. If the page is being rolled
- ** back as part of a savepoint (or statement) rollback from an
- ** unsynced portion of the main journal file, then it is not safe
- ** to mark the page as clean. This is because marking the page as
- ** clean will clear the PGHDR_NEED_SYNC flag. Since the page is
- ** already in the journal file (recorded in Pager.pInJournal) and
- ** the PGHDR_NEED_SYNC flag is cleared, if the page is written to
- ** again within this transaction, it will be marked as dirty but
- ** the PGHDR_NEED_SYNC flag will not be set. It could then potentially
- ** be written out into the database file before its journal file
- ** segment is synced. If a crash occurs during or following this,
- ** database corruption may ensue.
- */
- sqlite3PcacheMakeClean(pPg);
- }
-#ifdef SQLITE_CHECK_PAGES
- pPg->pageHash = pager_pagehash(pPg);
-#endif
- /* If this was page 1, then restore the value of Pager.dbFileVers.
- ** Do this before any decoding. */
- if( pgno==1 ){
- memcpy(&pPager->dbFileVers, &((u8*)pData)[24],sizeof(pPager->dbFileVers));
- }
-
- /* Decode the page just read from disk */
- CODEC1(pPager, pData, pPg->pgno, 3, rc=SQLITE_NOMEM);
- sqlite3PcacheRelease(pPg);
- }
- return rc;
-}
-
-/*
-** Parameter zMaster is the name of a master journal file. A single journal
-** file that referred to the master journal file has just been rolled back.
-** This routine checks if it is possible to delete the master journal file,
-** and does so if it is.
-**
-** Argument zMaster may point to Pager.pTmpSpace. So that buffer is not
-** available for use within this function.
-**
-** When a master journal file is created, it is populated with the names
-** of all of its child journals, one after another, formatted as utf-8
-** encoded text. The end of each child journal file is marked with a
-** nul-terminator byte (0x00). i.e. the entire contents of a master journal
-** file for a transaction involving two databases might be:
-**
-** "/home/bill/a.db-journal\x00/home/bill/b.db-journal\x00"
-**
-** A master journal file may only be deleted once all of its child
-** journals have been rolled back.
-**
-** This function reads the contents of the master-journal file into
-** memory and loops through each of the child journal names. For
-** each child journal, it checks if:
-**
-** * if the child journal exists, and if so
-** * if the child journal contains a reference to master journal
-** file zMaster
-**
-** If a child journal can be found that matches both of the criteria
-** above, this function returns without doing anything. Otherwise, if
-** no such child journal can be found, file zMaster is deleted from
-** the file-system using sqlite3OsDelete().
-**
-** If an IO error within this function, an error code is returned. This
-** function allocates memory by calling sqlite3Malloc(). If an allocation
-** fails, SQLITE_NOMEM is returned. Otherwise, if no IO or malloc errors
-** occur, SQLITE_OK is returned.
-**
-** TODO: This function allocates a single block of memory to load
-** the entire contents of the master journal file. This could be
-** a couple of kilobytes or so - potentially larger than the page
-** size.
-*/
-static int pager_delmaster(Pager *pPager, const char *zMaster){
- sqlite3_vfs *pVfs = pPager->pVfs;
- int rc; /* Return code */
- sqlite3_file *pMaster; /* Malloc'd master-journal file descriptor */
- sqlite3_file *pJournal; /* Malloc'd child-journal file descriptor */
- char *zMasterJournal = 0; /* Contents of master journal file */
- i64 nMasterJournal; /* Size of master journal file */
-
- /* Allocate space for both the pJournal and pMaster file descriptors.
- ** If successful, open the master journal file for reading.
- */
- pMaster = (sqlite3_file *)sqlite3MallocZero(pVfs->szOsFile * 2);
- pJournal = (sqlite3_file *)(((u8 *)pMaster) + pVfs->szOsFile);
- if( !pMaster ){
- rc = SQLITE_NOMEM;
- }else{
- const int flags = (SQLITE_OPEN_READONLY|SQLITE_OPEN_MASTER_JOURNAL);
- rc = sqlite3OsOpen(pVfs, zMaster, pMaster, flags, 0);
- }
- if( rc!=SQLITE_OK ) goto delmaster_out;
-
- rc = sqlite3OsFileSize(pMaster, &nMasterJournal);
- if( rc!=SQLITE_OK ) goto delmaster_out;
-
- if( nMasterJournal>0 ){
- char *zJournal;
- char *zMasterPtr = 0;
- int nMasterPtr = pVfs->mxPathname+1;
-
- /* Load the entire master journal file into space obtained from
- ** sqlite3_malloc() and pointed to by zMasterJournal.
- */
- zMasterJournal = sqlite3Malloc((int)nMasterJournal + nMasterPtr + 1);
- if( !zMasterJournal ){
- rc = SQLITE_NOMEM;
- goto delmaster_out;
- }
- zMasterPtr = &zMasterJournal[nMasterJournal+1];
- rc = sqlite3OsRead(pMaster, zMasterJournal, (int)nMasterJournal, 0);
- if( rc!=SQLITE_OK ) goto delmaster_out;
- zMasterJournal[nMasterJournal] = 0;
-
- zJournal = zMasterJournal;
- while( (zJournal-zMasterJournal)<nMasterJournal ){
- int exists;
- rc = sqlite3OsAccess(pVfs, zJournal, SQLITE_ACCESS_EXISTS, &exists);
- if( rc!=SQLITE_OK ){
- goto delmaster_out;
- }
- if( exists ){
- /* One of the journals pointed to by the master journal exists.
- ** Open it and check if it points at the master journal. If
- ** so, return without deleting the master journal file.
- */
- int c;
- int flags = (SQLITE_OPEN_READONLY|SQLITE_OPEN_MAIN_JOURNAL);
- rc = sqlite3OsOpen(pVfs, zJournal, pJournal, flags, 0);
- if( rc!=SQLITE_OK ){
- goto delmaster_out;
- }
-
- rc = readMasterJournal(pJournal, zMasterPtr, nMasterPtr);
- sqlite3OsClose(pJournal);
- if( rc!=SQLITE_OK ){
- goto delmaster_out;
- }
-
- c = zMasterPtr[0]!=0 && strcmp(zMasterPtr, zMaster)==0;
- if( c ){
- /* We have a match. Do not delete the master journal file. */
- goto delmaster_out;
- }
- }
- zJournal += (sqlite3Strlen30(zJournal)+1);
- }
- }
-
- rc = sqlite3OsDelete(pVfs, zMaster, 0);
-
-delmaster_out:
- if( zMasterJournal ){
- sqlite3_free(zMasterJournal);
- }
- if( pMaster ){
- sqlite3OsClose(pMaster);
- assert( !isOpen(pJournal) );
- }
- sqlite3_free(pMaster);
- return rc;
-}
-
-
-/*
-** This function is used to change the actual size of the database
-** file in the file-system. This only happens when committing a transaction,
-** or rolling back a transaction (including rolling back a hot-journal).
-**
-** If the main database file is not open, or an exclusive lock is not
-** held, this function is a no-op. Otherwise, the size of the file is
-** changed to nPage pages (nPage*pPager->pageSize bytes). If the file
-** on disk is currently larger than nPage pages, then use the VFS
-** xTruncate() method to truncate it.
-**
-** Or, it might might be the case that the file on disk is smaller than
-** nPage pages. Some operating system implementations can get confused if
-** you try to truncate a file to some size that is larger than it
-** currently is, so detect this case and write a single zero byte to
-** the end of the new file instead.
-**
-** If successful, return SQLITE_OK. If an IO error occurs while modifying
-** the database file, return the error code to the caller.
-*/
-static int pager_truncate(Pager *pPager, Pgno nPage){
- int rc = SQLITE_OK;
- if( pPager->state>=PAGER_EXCLUSIVE && isOpen(pPager->fd) ){
- i64 currentSize, newSize;
- /* TODO: Is it safe to use Pager.dbFileSize here? */
- rc = sqlite3OsFileSize(pPager->fd, &currentSize);
- newSize = pPager->pageSize*(i64)nPage;
- if( rc==SQLITE_OK && currentSize!=newSize ){
- if( currentSize>newSize ){
- rc = sqlite3OsTruncate(pPager->fd, newSize);
- }else{
- rc = sqlite3OsWrite(pPager->fd, "", 1, newSize-1);
- }
- if( rc==SQLITE_OK ){
- pPager->dbFileSize = nPage;
- }
- }
- }
- return rc;
-}
-
-/*
-** Set the value of the Pager.sectorSize variable for the given
-** pager based on the value returned by the xSectorSize method
-** of the open database file. The sector size will be used used
-** to determine the size and alignment of journal header and
-** master journal pointers within created journal files.
-**
-** For temporary files the effective sector size is always 512 bytes.
-**
-** Otherwise, for non-temporary files, the effective sector size is
-** the value returned by the xSectorSize() method rounded up to 512 if
-** it is less than 512, or rounded down to MAX_SECTOR_SIZE if it
-** is greater than MAX_SECTOR_SIZE.
-*/
-static void setSectorSize(Pager *pPager){
- assert( isOpen(pPager->fd) || pPager->tempFile );
-
- if( !pPager->tempFile ){
- /* 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<512 ){
- pPager->sectorSize = 512;
- }
- if( pPager->sectorSize>MAX_SECTOR_SIZE ){
- assert( MAX_SECTOR_SIZE>=512 );
- pPager->sectorSize = MAX_SECTOR_SIZE;
- }
-}
-
-/*
-** Playback the journal and thus restore the database file to
-** the state it was in before we started making changes.
-**
-** The journal file format is as follows:
-**
-** (1) 8 byte prefix. A copy of aJournalMagic[].
-** (2) 4 byte big-endian integer which is the number of valid page records
-** in the journal. If this value is 0xffffffff, then compute the
-** number of page records from the journal size.
-** (3) 4 byte big-endian integer which is the initial value for the
-** sanity checksum.
-** (4) 4 byte integer which is the number of pages to truncate the
-** database to during a rollback.
-** (5) 4 byte big-endian integer which is the sector size. The header
-** is this many bytes in size.
-** (6) 4 byte big-endian integer which is the page case.
-** (7) 4 byte integer which is the number of bytes in the master journal
-** name. The value may be zero (indicate that there is no master
-** journal.)
-** (8) N bytes of the master journal name. The name will be nul-terminated
-** and might be shorter than the value read from (5). If the first byte
-** of the name is \000 then there is no master journal. The master
-** journal name is stored in UTF-8.
-** (9) Zero or more pages instances, each as follows:
-** + 4 byte page number.
-** + pPager->pageSize bytes of data.
-** + 4 byte checksum
-**
-** When we speak of the journal header, we mean the first 8 items above.
-** Each entry in the journal is an instance of the 9th item.
-**
-** Call the value from the second bullet "nRec". nRec is the number of
-** valid page entries in the journal. In most cases, you can compute the
-** value of nRec from the size of the journal file. But if a power
-** failure occurred while the journal was being written, it could be the
-** case that the size of the journal file had already been increased but
-** the extra entries had not yet made it safely to disk. In such a case,
-** the value of nRec computed from the file size would be too large. For
-** that reason, we always use the nRec value in the header.
-**
-** If the nRec value is 0xffffffff it means that nRec should be computed
-** from the file size. This value is used when the user selects the
-** no-sync option for the journal. A power failure could lead to corruption
-** in this case. But for things like temporary table (which will be
-** deleted when the power is restored) we don't care.
-**
-** If the file opened as the journal file is not a well-formed
-** journal file then all pages up to the first corrupted page are rolled
-** back (or no pages if the journal header is corrupted). The journal file
-** is then deleted and SQLITE_OK returned, just as if no corruption had
-** been encountered.
-**
-** If an I/O or malloc() error occurs, the journal-file is not deleted
-** and an error code is returned.
-**
-** The isHot parameter indicates that we are trying to rollback a journal
-** that might be a hot journal. Or, it could be that the journal is
-** preserved because of JOURNALMODE_PERSIST or JOURNALMODE_TRUNCATE.
-** If the journal really is hot, reset the pager cache prior rolling
-** back any content. If the journal is merely persistent, no reset is
-** needed.
-*/
-static int pager_playback(Pager *pPager, int isHot){
- sqlite3_vfs *pVfs = pPager->pVfs;
- i64 szJ; /* Size of the journal file in bytes */
- u32 nRec; /* Number of Records in the journal */
- u32 u; /* Unsigned loop counter */
- Pgno mxPg = 0; /* Size of the original file in pages */
- int rc; /* Result code of a subroutine */
- int res = 1; /* Value returned by sqlite3OsAccess() */
- char *zMaster = 0; /* Name of master journal file if any */
- int needPagerReset; /* True to reset page prior to first page rollback */
-
- /* Figure out how many records are in the journal. Abort early if
- ** the journal is empty.
- */
- assert( isOpen(pPager->jfd) );
- rc = sqlite3OsFileSize(pPager->jfd, &szJ);
- if( rc!=SQLITE_OK || szJ==0 ){
- goto end_playback;
- }
-
- /* Read the master journal name from the journal, if it is present.
- ** If a master journal file name is specified, but the file is not
- ** present on disk, then the journal is not hot and does not need to be
- ** played back.
- **
- ** TODO: Technically the following is an error because it assumes that
- ** buffer Pager.pTmpSpace is (mxPathname+1) bytes or larger. i.e. that
- ** (pPager->pageSize >= pPager->pVfs->mxPathname+1). Using os_unix.c,
- ** mxPathname is 512, which is the same as the minimum allowable value
- ** for pageSize.
- */
- zMaster = pPager->pTmpSpace;
- rc = readMasterJournal(pPager->jfd, zMaster, pPager->pVfs->mxPathname+1);
- if( rc==SQLITE_OK && zMaster[0] ){
- rc = sqlite3OsAccess(pVfs, zMaster, SQLITE_ACCESS_EXISTS, &res);
- }
- zMaster = 0;
- if( rc!=SQLITE_OK || !res ){
- goto end_playback;
- }
- pPager->journalOff = 0;
- needPagerReset = isHot;
-
- /* This loop terminates either when a readJournalHdr() or
- ** pager_playback_one_page() call returns SQLITE_DONE or an IO error
- ** occurs.
- */
- while( 1 ){
- int isUnsync = 0;
-
- /* Read the next journal header from the journal file. If there are
- ** not enough bytes left in the journal file for a complete header, or
- ** it is corrupted, then a process must of failed while writing it.
- ** This indicates nothing more needs to be rolled back.
- */
- rc = readJournalHdr(pPager, isHot, szJ, &nRec, &mxPg);
- if( rc!=SQLITE_OK ){
- if( rc==SQLITE_DONE ){
- rc = SQLITE_OK;
- }
- goto end_playback;
- }
-
- /* If nRec is 0xffffffff, then this journal was created by a process
- ** working in no-sync mode. This means that the rest of the journal
- ** file consists of pages, there are no more journal headers. Compute
- ** the value of nRec based on this assumption.
- */
- if( nRec==0xffffffff ){
- assert( pPager->journalOff==JOURNAL_HDR_SZ(pPager) );
- nRec = (int)((szJ - JOURNAL_HDR_SZ(pPager))/JOURNAL_PG_SZ(pPager));
- }
-
- /* If nRec is 0 and this rollback is of a transaction created by this
- ** process and if this is the final header in the journal, then it means
- ** that this part of the journal was being filled but has not yet been
- ** synced to disk. Compute the number of pages based on the remaining
- ** size of the file.
- **
- ** The third term of the test was added to fix ticket #2565.
- ** When rolling back a hot journal, nRec==0 always means that the next
- ** chunk of the journal contains zero pages to be rolled back. But
- ** when doing a ROLLBACK and the nRec==0 chunk is the last chunk in
- ** the journal, it means that the journal might contain additional
- ** pages that need to be rolled back and that the number of pages
- ** should be computed based on the journal file size.
- */
- if( nRec==0 && !isHot &&
- pPager->journalHdr+JOURNAL_HDR_SZ(pPager)==pPager->journalOff ){
- nRec = (int)((szJ - pPager->journalOff) / JOURNAL_PG_SZ(pPager));
- isUnsync = 1;
- }
-
- /* If this is the first header read from the journal, truncate the
- ** database file back to its original size.
- */
- if( pPager->journalOff==JOURNAL_HDR_SZ(pPager) ){
- rc = pager_truncate(pPager, mxPg);
- if( rc!=SQLITE_OK ){
- goto end_playback;
- }
- pPager->dbSize = mxPg;
- }
-
- /* Copy original pages out of the journal and back into the
- ** database file and/or page cache.
- */
- for(u=0; u<nRec; u++){
- if( needPagerReset ){
- pager_reset(pPager);
- needPagerReset = 0;
- }
- rc = pager_playback_one_page(pPager,1,isUnsync,&pPager->journalOff,0,0);
- if( rc!=SQLITE_OK ){
- if( rc==SQLITE_DONE ){
- rc = SQLITE_OK;
- pPager->journalOff = szJ;
- break;
- }else{
- /* If we are unable to rollback, quit and return the error
- ** code. This will cause the pager to enter the error state
- ** so that no further harm will be done. Perhaps the next
- ** process to come along will be able to rollback the database.
- */
- goto end_playback;
- }
- }
- }
- }
- /*NOTREACHED*/
- assert( 0 );
-
-end_playback:
- /* Following a rollback, the database file should be back in its original
- ** state prior to the start of the transaction, so invoke the
- ** 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
- );
-
- /* If this playback is happening automatically as a result of an IO or
- ** malloc error that occurred after the change-counter was updated but
- ** before the transaction was committed, then the change-counter
- ** modification may just have been reverted. If this happens in exclusive
- ** mode, then subsequent transactions performed by the connection will not
- ** update the change-counter at all. This may lead to cache inconsistency
- ** problems for other processes at some point in the future. So, just
- ** in case this has happened, clear the changeCountDone flag now.
- */
- pPager->changeCountDone = pPager->tempFile;
-
- if( rc==SQLITE_OK ){
- zMaster = pPager->pTmpSpace;
- rc = readMasterJournal(pPager->jfd, zMaster, pPager->pVfs->mxPathname+1);
- testcase( rc!=SQLITE_OK );
- }
- if( rc==SQLITE_OK ){
- rc = pager_end_transaction(pPager, zMaster[0]!='\0');
- testcase( rc!=SQLITE_OK );
- }
- if( rc==SQLITE_OK && zMaster[0] && res ){
- /* If there was a master journal and this routine will return success,
- ** see if it is possible to delete the master journal.
- */
- rc = pager_delmaster(pPager, zMaster);
- testcase( rc!=SQLITE_OK );
- }
-
- /* The Pager.sectorSize variable may have been updated while rolling
- ** back a journal created by a process with a different sector size
- ** value. Reset it to the correct value for this process.
- */
- setSectorSize(pPager);
- return rc;
-}
-
-/*
-** Playback savepoint pSavepoint. Or, if pSavepoint==NULL, then playback
-** the entire master journal file. The case pSavepoint==NULL occurs when
-** a ROLLBACK TO command is invoked on a SAVEPOINT that is a transaction
-** savepoint.
-**
-** When pSavepoint is not NULL (meaning a non-transaction savepoint is
-** being rolled back), then the rollback consists of up to three stages,
-** performed in the order specified:
-**
-** * Pages are played back from the main journal starting at byte
-** offset PagerSavepoint.iOffset and continuing to
-** PagerSavepoint.iHdrOffset, or to the end of the main journal
-** file if PagerSavepoint.iHdrOffset is zero.
-**
-** * If PagerSavepoint.iHdrOffset is not zero, then pages are played
-** back starting from the journal header immediately following
-** PagerSavepoint.iHdrOffset to the end of the main journal file.
-**
-** * Pages are then played back from the sub-journal file, starting
-** with the PagerSavepoint.iSubRec and continuing to the end of
-** the journal file.
-**
-** Throughout the rollback process, each time a page is rolled back, the
-** corresponding bit is set in a bitvec structure (variable pDone in the
-** implementation below). This is used to ensure that a page is only
-** rolled back the first time it is encountered in either journal.
-**
-** If pSavepoint is NULL, then pages are only played back from the main
-** journal file. There is no need for a bitvec in this case.
-**
-** In either case, before playback commences the Pager.dbSize variable
-** is reset to the value that it held at the start of the savepoint
-** (or transaction). No page with a page-number greater than this value
-** is played back. If one is encountered it is simply skipped.
-*/
-static int pagerPlaybackSavepoint(Pager *pPager, PagerSavepoint *pSavepoint){
- i64 szJ; /* Effective size of the main journal */
- i64 iHdrOff; /* End of first segment of main-journal records */
- int rc = SQLITE_OK; /* Return code */
- Bitvec *pDone = 0; /* Bitvec to ensure pages played back only once */
-
- assert( pPager->state>=PAGER_SHARED );
-
- /* Allocate a bitvec to use to store the set of pages rolled back */
- if( pSavepoint ){
- pDone = sqlite3BitvecCreate(pSavepoint->nOrig);
- if( !pDone ){
- return SQLITE_NOMEM;
- }
- }
-
- /* Set the database size back to the value it was before the savepoint
- ** being reverted was opened.
- */
- pPager->dbSize = pSavepoint ? pSavepoint->nOrig : pPager->dbOrigSize;
-
- /* Use pPager->journalOff as the effective size of the main rollback
- ** journal. The actual file might be larger than this in
- ** PAGER_JOURNALMODE_TRUNCATE or PAGER_JOURNALMODE_PERSIST. But anything
- ** past pPager->journalOff is off-limits to us.
- */
- szJ = pPager->journalOff;
-
- /* Begin by rolling back records from the main journal starting at
- ** PagerSavepoint.iOffset and continuing to the next journal header.
- ** There might be records in the main journal that have a page number
- ** greater than the current database size (pPager->dbSize) but those
- ** will be skipped automatically. Pages are added to pDone as they
- ** are played back.
- */
- if( pSavepoint ){
- iHdrOff = pSavepoint->iHdrOffset ? pSavepoint->iHdrOffset : szJ;
- pPager->journalOff = pSavepoint->iOffset;
- while( rc==SQLITE_OK && pPager->journalOff<iHdrOff ){
- rc = pager_playback_one_page(pPager, 1, 0, &pPager->journalOff, 1, pDone);
- }
- assert( rc!=SQLITE_DONE );
- }else{
- pPager->journalOff = 0;
- }
-
- /* Continue rolling back records out of the main journal starting at
- ** the first journal header seen and continuing until the effective end
- ** of the main journal file. Continue to skip out-of-range pages and
- ** continue adding pages rolled back to pDone.
- */
- while( rc==SQLITE_OK && pPager->journalOff<szJ ){
- u32 ii; /* Loop counter */
- u32 nJRec = 0; /* Number of Journal Records */
- u32 dummy;
- rc = readJournalHdr(pPager, 0, szJ, &nJRec, &dummy);
- assert( rc!=SQLITE_DONE );
-
- /*
- ** The "pPager->journalHdr+JOURNAL_HDR_SZ(pPager)==pPager->journalOff"
- ** test is related to ticket #2565. See the discussion in the
- ** pager_playback() function for additional information.
- */
- if( nJRec==0
- && pPager->journalHdr+JOURNAL_HDR_SZ(pPager)==pPager->journalOff
- ){
- nJRec = (u32)((szJ - pPager->journalOff)/JOURNAL_PG_SZ(pPager));
- }
- for(ii=0; rc==SQLITE_OK && ii<nJRec && pPager->journalOff<szJ; ii++){
- rc = pager_playback_one_page(pPager, 1, 0, &pPager->journalOff, 1, pDone);
- }
- assert( rc!=SQLITE_DONE );
- }
- assert( rc!=SQLITE_OK || pPager->journalOff==szJ );
-
- /* Finally, rollback pages from the sub-journal. Page that were
- ** previously rolled back out of the main journal (and are hence in pDone)
- ** will be skipped. Out-of-range pages are also skipped.
- */
- if( pSavepoint ){
- u32 ii; /* Loop counter */
- i64 offset = pSavepoint->iSubRec*(4+pPager->pageSize);
- for(ii=pSavepoint->iSubRec; rc==SQLITE_OK && ii<pPager->nSubRec; ii++){
- assert( offset==ii*(4+pPager->pageSize) );
- rc = pager_playback_one_page(pPager, 0, 0, &offset, 1, pDone);
- }
- assert( rc!=SQLITE_DONE );
- }
-
- sqlite3BitvecDestroy(pDone);
- if( rc==SQLITE_OK ){
- pPager->journalOff = szJ;
- }
- return rc;
-}
-
-/*
-** Change the maximum number of in-memory pages that are allowed.
-*/
-SQLITE_PRIVATE void sqlite3PagerSetCachesize(Pager *pPager, int mxPage){
- sqlite3PcacheSetCachesize(pPager->pPCache, mxPage);
-}
-
-/*
-** Adjust the robustness of the database to damage due to OS crashes
-** or power failures by changing the number of syncs()s when writing
-** the rollback journal. There are three levels:
-**
-** OFF sqlite3OsSync() is never called. This is the default
-** for temporary and transient files.
-**
-** NORMAL The journal is synced once before writes begin on the
-** database. This is normally adequate protection, but
-** it is theoretically possible, though very unlikely,
-** that an inopertune power failure could leave the journal
-** in a state which would cause damage to the database
-** when it is rolled back.
-**
-** FULL The journal is synced twice before writes begin on the
-** database (with some additional information - the nRec field
-** of the journal header - being written in between the two
-** syncs). If we assume that writing a
-** single disk sector is atomic, then this mode provides
-** assurance that the journal will not be corrupted to the
-** point of causing damage to the database during rollback.
-**
-** Numeric values associated with these states are OFF==1, NORMAL=2,
-** and FULL=3.
-*/
-#ifndef SQLITE_OMIT_PAGER_PRAGMAS
-SQLITE_PRIVATE void sqlite3PagerSetSafetyLevel(Pager *pPager, int level, int bFullFsync){
- pPager->noSync = (level==1 || pPager->tempFile) ?1:0;
- pPager->fullSync = (level==3 && !pPager->tempFile) ?1:0;
- pPager->sync_flags = (bFullFsync?SQLITE_SYNC_FULL:SQLITE_SYNC_NORMAL);
- if( pPager->noSync ) pPager->needSync = 0;
-}
-#endif
-
-/*
-** The following global variable is incremented whenever the library
-** attempts to open a temporary file. This information is used for
-** testing and analysis only.
-*/
-#ifdef SQLITE_TEST
-SQLITE_API int sqlite3_opentemp_count = 0;
-#endif
-
-/*
-** Open a temporary file.
-**
-** Write the file descriptor into *pFile. Return SQLITE_OK on success
-** or some other error code if we fail. The OS will automatically
-** delete the temporary file when it is closed.
-**
-** The flags passed to the VFS layer xOpen() call are those specified
-** by parameter vfsFlags ORed with the following:
-**
-** SQLITE_OPEN_READWRITE
-** SQLITE_OPEN_CREATE
-** SQLITE_OPEN_EXCLUSIVE
-** SQLITE_OPEN_DELETEONCLOSE
-*/
-static int pagerOpentemp(
- Pager *pPager, /* The pager object */
- sqlite3_file *pFile, /* Write the file descriptor here */
- int vfsFlags /* Flags passed through to the VFS */
-){
- int rc; /* Return code */
-
-#ifdef SQLITE_TEST
- sqlite3_opentemp_count++; /* Used for testing and analysis only */
-#endif
-
- vfsFlags |= SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE |
- SQLITE_OPEN_EXCLUSIVE | SQLITE_OPEN_DELETEONCLOSE;
- rc = sqlite3OsOpen(pPager->pVfs, 0, pFile, vfsFlags, 0);
- assert( rc!=SQLITE_OK || isOpen(pFile) );
- return rc;
-}
-
-/*
-** Set the busy handler function.
-**
-** The pager invokes the busy-handler if sqlite3OsLock() returns
-** SQLITE_BUSY when trying to upgrade from no-lock to a SHARED lock,
-** or when trying to upgrade from a RESERVED lock to an EXCLUSIVE
-** lock. It does *not* invoke the busy handler when upgrading from
-** SHARED to RESERVED, or when upgrading from SHARED to EXCLUSIVE
-** (which occurs during hot-journal rollback). Summary:
-**
-** Transition | Invokes xBusyHandler
-** --------------------------------------------------------
-** NO_LOCK -> SHARED_LOCK | Yes
-** SHARED_LOCK -> RESERVED_LOCK | No
-** SHARED_LOCK -> EXCLUSIVE_LOCK | No
-** RESERVED_LOCK -> EXCLUSIVE_LOCK | Yes
-**
-** If the busy-handler callback returns non-zero, the lock is
-** retried. If it returns zero, then the SQLITE_BUSY error is
-** returned to the caller of the pager API function.
-*/
-SQLITE_PRIVATE void sqlite3PagerSetBusyhandler(
- Pager *pPager, /* Pager object */
- int (*xBusyHandler)(void *), /* Pointer to busy-handler function */
- void *pBusyHandlerArg /* Argument to pass to xBusyHandler */
-){
- pPager->xBusyHandler = xBusyHandler;
- pPager->pBusyHandlerArg = pBusyHandlerArg;
-}
-
-/*
-** Report the current page size and number of reserved bytes back
-** to the codec.
-*/
-#ifdef SQLITE_HAS_CODEC
-static void pagerReportSize(Pager *pPager){
- if( pPager->xCodecSizeChng ){
- pPager->xCodecSizeChng(pPager->pCodec, pPager->pageSize,
- (int)pPager->nReserve);
- }
-}
-#else
-# define pagerReportSize(X) /* No-op if we do not support a codec */
-#endif
-
-/*
-** Change the page size used by the Pager object. The new page size
-** is passed in *pPageSize.
-**
-** If the pager is in the error state when this function is called, it
-** is a no-op. The value returned is the error state error code (i.e.
-** one of SQLITE_IOERR, SQLITE_CORRUPT or SQLITE_FULL).
-**
-** Otherwise, if all of the following are true:
-**
-** * the new page size (value of *pPageSize) is valid (a power
-** of two between 512 and SQLITE_MAX_PAGE_SIZE, inclusive), and
-**
-** * there are no outstanding page references, and
-**
-** * the database is either not an in-memory database or it is
-** an in-memory database that currently consists of zero pages.
-**
-** then the pager object page size is set to *pPageSize.
-**
-** If the page size is changed, then this function uses sqlite3PagerMalloc()
-** to obtain a new Pager.pTmpSpace buffer. If this allocation attempt
-** fails, SQLITE_NOMEM is returned and the page size remains unchanged.
-** In all other cases, SQLITE_OK is returned.
-**
-** If the page size is not changed, either because one of the enumerated
-** conditions above is not true, the pager was in error state when this
-** function was called, or because the memory allocation attempt failed,
-** then *pPageSize is set to the old, retained page size before returning.
-*/
-SQLITE_PRIVATE int sqlite3PagerSetPagesize(Pager *pPager, u16 *pPageSize, int nReserve){
- int rc = pPager->errCode;
-
- if( rc==SQLITE_OK ){
- u16 pageSize = *pPageSize;
- assert( pageSize==0 || (pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE) );
- if( (pPager->memDb==0 || pPager->dbSize==0)
- && sqlite3PcacheRefCount(pPager->pPCache)==0
- && pageSize && pageSize!=pPager->pageSize
- ){
- char *pNew = (char *)sqlite3PageMalloc(pageSize);
- if( !pNew ){
- rc = SQLITE_NOMEM;
- }else{
- pager_reset(pPager);
- pPager->pageSize = pageSize;
- sqlite3PageFree(pPager->pTmpSpace);
- pPager->pTmpSpace = pNew;
- sqlite3PcacheSetPageSize(pPager->pPCache, pageSize);
- }
- }
- *pPageSize = (u16)pPager->pageSize;
- if( nReserve<0 ) nReserve = pPager->nReserve;
- assert( nReserve>=0 && nReserve<1000 );
- pPager->nReserve = (i16)nReserve;
- pagerReportSize(pPager);
- }
- return rc;
-}
-
-/*
-** Return a pointer to the "temporary page" buffer held internally
-** by the pager. This is a buffer that is big enough to hold the
-** entire content of a database page. This buffer is used internally
-** during rollback and will be overwritten whenever a rollback
-** occurs. But other modules are free to use it too, as long as
-** no rollbacks are happening.
-*/
-SQLITE_PRIVATE void *sqlite3PagerTempSpace(Pager *pPager){
- return pPager->pTmpSpace;
-}
-
-/*
-** Attempt to set the maximum database page count if mxPage is positive.
-** Make no changes if mxPage is zero or negative. And never reduce the
-** maximum page count below the current size of the database.
-**
-** Regardless of mxPage, return the current maximum page count.
-*/
-SQLITE_PRIVATE int sqlite3PagerMaxPageCount(Pager *pPager, int mxPage){
- if( mxPage>0 ){
- pPager->mxPgno = mxPage;
- }
- sqlite3PagerPagecount(pPager, 0);
- return pPager->mxPgno;
-}
-
-/*
-** The following set of routines are used to disable the simulated
-** I/O error mechanism. These routines are used to avoid simulated
-** errors in places where we do not care about errors.
-**
-** Unless -DSQLITE_TEST=1 is used, these routines are all no-ops
-** and generate no code.
-*/
-#ifdef SQLITE_TEST
-SQLITE_API extern int sqlite3_io_error_pending;
-SQLITE_API extern int sqlite3_io_error_hit;
-static int saved_cnt;
-void disable_simulated_io_errors(void){
- saved_cnt = sqlite3_io_error_pending;
- sqlite3_io_error_pending = -1;
-}
-void enable_simulated_io_errors(void){
- sqlite3_io_error_pending = saved_cnt;
-}
-#else
-# define disable_simulated_io_errors()
-# define enable_simulated_io_errors()
-#endif
-
-/*
-** Read the first N bytes from the beginning of the file into memory
-** that pDest points to.
-**
-** If the pager was opened on a transient file (zFilename==""), or
-** opened on a file less than N bytes in size, the output buffer is
-** zeroed and SQLITE_OK returned. The rationale for this is that this
-** function is used to read database headers, and a new transient or
-** zero sized database has a header than consists entirely of zeroes.
-**
-** If any IO error apart from SQLITE_IOERR_SHORT_READ is encountered,
-** the error code is returned to the caller and the contents of the
-** output buffer undefined.
-*/
-SQLITE_PRIVATE int sqlite3PagerReadFileheader(Pager *pPager, int N, unsigned char *pDest){
- int rc = SQLITE_OK;
- memset(pDest, 0, N);
- assert( isOpen(pPager->fd) || pPager->tempFile );
- if( isOpen(pPager->fd) ){
- IOTRACE(("DBHDR %p 0 %d\n", pPager, N))
- rc = sqlite3OsRead(pPager->fd, pDest, N, 0);
- if( rc==SQLITE_IOERR_SHORT_READ ){
- rc = SQLITE_OK;
- }
- }
- return rc;
-}
-
-/*
-** Return the total number of pages in the database file associated
-** with pPager. Normally, this is calculated as (<db file size>/<page-size>).
-** However, if the file is between 1 and <page-size> bytes in size, then
-** this is considered a 1 page file.
-**
-** If the pager is in error state when this function is called, then the
-** error state error code is returned and *pnPage left unchanged. Or,
-** if the file system has to be queried for the size of the file and
-** the query attempt returns an IO error, the IO error code is returned
-** and *pnPage is left unchanged.
-**
-** Otherwise, if everything is successful, then SQLITE_OK is returned
-** and *pnPage is set to the number of pages in the database.
-*/
-SQLITE_PRIVATE int sqlite3PagerPagecount(Pager *pPager, int *pnPage){
- Pgno nPage; /* Value to return via *pnPage */
-
- /* If the pager is already in the error state, return the error code. */
- if( pPager->errCode ){
- return pPager->errCode;
- }
-
- /* Determine the number of pages in the file. Store this in nPage. */
- if( pPager->dbSizeValid ){
- nPage = pPager->dbSize;
- }else{
- int rc; /* Error returned by OsFileSize() */
- i64 n = 0; /* File size in bytes returned by OsFileSize() */
-
- assert( isOpen(pPager->fd) || pPager->tempFile );
- if( isOpen(pPager->fd) && (0 != (rc = sqlite3OsFileSize(pPager->fd, &n))) ){
- pager_error(pPager, rc);
- return rc;
- }
- if( n>0 && n<pPager->pageSize ){
- nPage = 1;
- }else{
- nPage = (Pgno)(n / pPager->pageSize);
- }
- if( pPager->state!=PAGER_UNLOCK ){
- pPager->dbSize = nPage;
- pPager->dbFileSize = nPage;
- pPager->dbSizeValid = 1;
- }
- }
-
- /* If the current number of pages in the file is greater than the
- ** configured maximum pager number, increase the allowed limit so
- ** that the file can be read.
- */
- if( nPage>pPager->mxPgno ){
- pPager->mxPgno = (Pgno)nPage;
- }
-
- /* Set the output variable and return SQLITE_OK */
- if( pnPage ){
- *pnPage = nPage;
- }
- return SQLITE_OK;
-}
-
-
-/*
-** Try to obtain a lock of type locktype on the database file. If
-** a similar or greater lock is already held, this function is a no-op
-** (returning SQLITE_OK immediately).
-**
-** Otherwise, attempt to obtain the lock using sqlite3OsLock(). Invoke
-** the busy callback if the lock is currently not available. Repeat
-** until the busy callback returns false or until the attempt to
-** obtain the lock succeeds.
-**
-** Return SQLITE_OK on success and an error code if we cannot obtain
-** the lock. If the lock is obtained successfully, set the Pager.state
-** variable to locktype before returning.
-*/
-static int pager_wait_on_lock(Pager *pPager, int locktype){
- int rc; /* Return code */
-
- /* The OS lock values must be the same as the Pager lock values */
- assert( PAGER_SHARED==SHARED_LOCK );
- assert( PAGER_RESERVED==RESERVED_LOCK );
- assert( PAGER_EXCLUSIVE==EXCLUSIVE_LOCK );
-
- /* If the file is currently unlocked then the size must be unknown */
- assert( pPager->state>=PAGER_SHARED || pPager->dbSizeValid==0 );
-
- /* Check that this is either a no-op (because the requested lock is
- ** already held, or one of the transistions that the busy-handler
- ** may be invoked during, according to the comment above
- ** sqlite3PagerSetBusyhandler().
- */
- assert( (pPager->state>=locktype)
- || (pPager->state==PAGER_UNLOCK && locktype==PAGER_SHARED)
- || (pPager->state==PAGER_RESERVED && locktype==PAGER_EXCLUSIVE)
- );
-
- if( pPager->state>=locktype ){
- rc = SQLITE_OK;
- }else{
- do {
- rc = sqlite3OsLock(pPager->fd, locktype);
- }while( rc==SQLITE_BUSY && pPager->xBusyHandler(pPager->pBusyHandlerArg) );
- if( rc==SQLITE_OK ){
- pPager->state = (u8)locktype;
- IOTRACE(("LOCK %p %d\n", pPager, locktype))
- }
- }
- return rc;
-}
-
-/*
-** Function assertTruncateConstraint(pPager) checks that one of the
-** following is true for all dirty pages currently in the page-cache:
-**
-** a) The page number is less than or equal to the size of the
-** current database image, in pages, OR
-**
-** b) if the page content were written at this time, it would not
-** be necessary to write the current content out to the sub-journal
-** (as determined by function subjRequiresPage()).
-**
-** If the condition asserted by this function were not true, and the
-** dirty page were to be discarded from the cache via the pagerStress()
-** routine, pagerStress() would not write the current page content to
-** the database file. If a savepoint transaction were rolled back after
-** this happened, the correct behaviour would be to restore the current
-** content of the page. However, since this content is not present in either
-** the database file or the portion of the rollback journal and
-** sub-journal rolled back the content could not be restored and the
-** database image would become corrupt. It is therefore fortunate that
-** this circumstance cannot arise.
-*/
-#if defined(SQLITE_DEBUG)
-static void assertTruncateConstraintCb(PgHdr *pPg){
- assert( pPg->flags&PGHDR_DIRTY );
- assert( !subjRequiresPage(pPg) || pPg->pgno<=pPg->pPager->dbSize );
-}
-static void assertTruncateConstraint(Pager *pPager){
- sqlite3PcacheIterateDirty(pPager->pPCache, assertTruncateConstraintCb);
-}
-#else
-# define assertTruncateConstraint(pPager)
-#endif
-
-/*
-** Truncate the in-memory database file image to nPage pages. This
-** function does not actually modify the database file on disk. It
-** just sets the internal state of the pager object so that the
-** truncation will be done when the current transaction is committed.
-*/
-SQLITE_PRIVATE void sqlite3PagerTruncateImage(Pager *pPager, Pgno nPage){
- assert( pPager->dbSizeValid );
- assert( pPager->dbSize>=nPage );
- assert( pPager->state>=PAGER_RESERVED );
- pPager->dbSize = nPage;
- assertTruncateConstraint(pPager);
-}
-
-/*
-** Shutdown the page cache. Free all memory and close all files.
-**
-** If a transaction was in progress when this routine is called, that
-** transaction is rolled back. All outstanding pages are invalidated
-** and their memory is freed. Any attempt to use a page associated
-** with this page cache after this function returns will likely
-** result in a coredump.
-**
-** This function always succeeds. If a transaction is active an attempt
-** is made to roll it back. If an error occurs during the rollback
-** a hot journal may be left in the filesystem but no error is returned
-** to the caller.
-*/
-SQLITE_PRIVATE int sqlite3PagerClose(Pager *pPager){
- disable_simulated_io_errors();
- sqlite3BeginBenignMalloc();
- pPager->errCode = 0;
- pPager->exclusiveMode = 0;
- pager_reset(pPager);
- if( MEMDB ){
- pager_unlock(pPager);
- }else{
- /* Set Pager.journalHdr to -1 for the benefit of the pager_playback()
- ** call which may be made from within pagerUnlockAndRollback(). If it
- ** is not -1, then the unsynced portion of an open journal file may
- ** be played back into the database. If a power failure occurs while
- ** this is happening, the database may become corrupt.
- */
- pPager->journalHdr = -1;
- pagerUnlockAndRollback(pPager);
- }
- sqlite3EndBenignMalloc();
- enable_simulated_io_errors();
- PAGERTRACE(("CLOSE %d\n", PAGERID(pPager)));
- IOTRACE(("CLOSE %p\n", pPager))
- sqlite3OsClose(pPager->fd);
- sqlite3PageFree(pPager->pTmpSpace);
- sqlite3PcacheClose(pPager->pPCache);
-
-#ifdef SQLITE_HAS_CODEC
- if( pPager->xCodecFree ) pPager->xCodecFree(pPager->pCodec);
-#endif
-
- assert( !pPager->aSavepoint && !pPager->pInJournal );
- assert( !isOpen(pPager->jfd) && !isOpen(pPager->sjfd) );
-
- sqlite3_free(pPager);
- return SQLITE_OK;
-}
-
-#if !defined(NDEBUG) || defined(SQLITE_TEST)
-/*
-** Return the page number for page pPg.
-*/
-SQLITE_PRIVATE Pgno sqlite3PagerPagenumber(DbPage *pPg){
- return pPg->pgno;
-}
-#endif
-
-/*
-** Increment the reference count for page pPg.
-*/
-SQLITE_PRIVATE void sqlite3PagerRef(DbPage *pPg){
- sqlite3PcacheRef(pPg);
-}
-
-/*
-** Sync the journal. In other words, make sure all the pages that have
-** been written to the journal have actually reached the surface of the
-** disk and can be restored in the event of a hot-journal rollback.
-**
-** If the Pager.needSync flag is not set, then this function is a
-** no-op. Otherwise, the actions required depend on the journal-mode
-** and the device characteristics of the the file-system, as follows:
-**
-** * If the journal file is an in-memory journal file, no action need
-** be taken.
-**
-** * Otherwise, if the device does not support the SAFE_APPEND property,
-** then the nRec field of the most recently written journal header
-** is updated to contain the number of journal records that have
-** been written following it. If the pager is operating in full-sync
-** mode, then the journal file is synced before this field is updated.
-**
-** * If the device does not support the SEQUENTIAL property, then
-** journal file is synced.
-**
-** Or, in pseudo-code:
-**
-** if( NOT <in-memory journal> ){
-** if( NOT SAFE_APPEND ){
-** if( <full-sync mode> ) xSync(<journal file>);
-** <update nRec field>
-** }
-** if( NOT SEQUENTIAL ) xSync(<journal file>);
-** }
-**
-** The Pager.needSync flag is never be set for temporary files, or any
-** file operating in no-sync mode (Pager.noSync set to non-zero).
-**
-** If successful, this routine clears the PGHDR_NEED_SYNC flag of every
-** page currently held in memory before returning SQLITE_OK. If an IO
-** error is encountered, then the IO error code is returned to the caller.
-*/
-static int syncJournal(Pager *pPager){
- if( pPager->needSync ){
- assert( !pPager->tempFile );
- if( pPager->journalMode!=PAGER_JOURNALMODE_MEMORY ){
- int rc; /* Return code */
- const int iDc = sqlite3OsDeviceCharacteristics(pPager->fd);
- assert( isOpen(pPager->jfd) );
-
- if( 0==(iDc&SQLITE_IOCAP_SAFE_APPEND) ){
- /* This block deals with an obscure problem. If the last connection
- ** that wrote to this database was operating in persistent-journal
- ** mode, then the journal file may at this point actually be larger
- ** than Pager.journalOff bytes. If the next thing in the journal
- ** file happens to be a journal-header (written as part of the
- ** previous connections transaction), and a crash or power-failure
- ** occurs after nRec is updated but before this connection writes
- ** anything else to the journal file (or commits/rolls back its
- ** transaction), then SQLite may become confused when doing the
- ** hot-journal rollback following recovery. It may roll back all
- ** of this connections data, then proceed to rolling back the old,
- ** out-of-date data that follows it. Database corruption.
- **
- ** To work around this, if the journal file does appear to contain
- ** a valid header following Pager.journalOff, then write a 0x00
- ** byte to the start of it to prevent it from being recognized.
- **
- ** Variable iNextHdrOffset is set to the offset at which this
- ** problematic header will occur, if it exists. aMagic is used
- ** as a temporary buffer to inspect the first couple of bytes of
- ** the potential journal header.
- */
- i64 iNextHdrOffset;
- u8 aMagic[8];
- u8 zHeader[sizeof(aJournalMagic)+4];
-
- memcpy(zHeader, aJournalMagic, sizeof(aJournalMagic));
- put32bits(&zHeader[sizeof(aJournalMagic)], pPager->nRec);
-
- iNextHdrOffset = journalHdrOffset(pPager);
- rc = sqlite3OsRead(pPager->jfd, aMagic, 8, iNextHdrOffset);
- if( rc==SQLITE_OK && 0==memcmp(aMagic, aJournalMagic, 8) ){
- static const u8 zerobyte = 0;
- rc = sqlite3OsWrite(pPager->jfd, &zerobyte, 1, iNextHdrOffset);
- }
- if( rc!=SQLITE_OK && rc!=SQLITE_IOERR_SHORT_READ ){
- return rc;
- }
-
- /* Write the nRec value into the journal file header. If in
- ** full-synchronous mode, sync the journal first. This ensures that
- ** all data has really hit the disk before nRec is updated to mark
- ** it as a candidate for rollback.
- **
- ** This is not required if the persistent media supports the
- ** SAFE_APPEND property. Because in this case it is not possible
- ** for garbage data to be appended to the file, the nRec field
- ** is populated with 0xFFFFFFFF when the journal header is written
- ** and never needs to be updated.
- */
- if( pPager->fullSync && 0==(iDc&SQLITE_IOCAP_SEQUENTIAL) ){
- PAGERTRACE(("SYNC journal of %d\n", PAGERID(pPager)));
- IOTRACE(("JSYNC %p\n", pPager))
- rc = sqlite3OsSync(pPager->jfd, pPager->sync_flags);
- if( rc!=SQLITE_OK ) return rc;
- }
- IOTRACE(("JHDR %p %lld\n", pPager, pPager->journalHdr));
- rc = sqlite3OsWrite(
- pPager->jfd, zHeader, sizeof(zHeader), pPager->journalHdr
- );
- if( rc!=SQLITE_OK ) return rc;
- }
- if( 0==(iDc&SQLITE_IOCAP_SEQUENTIAL) ){
- PAGERTRACE(("SYNC journal of %d\n", PAGERID(pPager)));
- IOTRACE(("JSYNC %p\n", pPager))
- rc = sqlite3OsSync(pPager->jfd, pPager->sync_flags|
- (pPager->sync_flags==SQLITE_SYNC_FULL?SQLITE_SYNC_DATAONLY:0)
- );
- if( rc!=SQLITE_OK ) return rc;
- }
- }
-
- /* The journal file was just successfully synced. Set Pager.needSync
- ** to zero and clear the PGHDR_NEED_SYNC flag on all pagess.
- */
- pPager->needSync = 0;
- pPager->journalStarted = 1;
- sqlite3PcacheClearSyncFlags(pPager->pPCache);
- }
-
- return SQLITE_OK;
-}
-
-/*
-** The argument is the first in a linked list of dirty pages connected
-** by the PgHdr.pDirty pointer. This function writes each one of the
-** in-memory pages in the list to the database file. The argument may
-** be NULL, representing an empty list. In this case this function is
-** a no-op.
-**
-** The pager must hold at least a RESERVED lock when this function
-** is called. Before writing anything to the database file, this lock
-** is upgraded to an EXCLUSIVE lock. If the lock cannot be obtained,
-** SQLITE_BUSY is returned and no data is written to the database file.
-**
-** If the pager is a temp-file pager and the actual file-system file
-** is not yet open, it is created and opened before any data is
-** written out.
-**
-** Once the lock has been upgraded and, if necessary, the file opened,
-** the pages are written out to the database file in list order. Writing
-** a page is skipped if it meets either of the following criteria:
-**
-** * The page number is greater than Pager.dbSize, or
-** * The PGHDR_DONT_WRITE flag is set on the page.
-**
-** If writing out a page causes the database file to grow, Pager.dbFileSize
-** is updated accordingly. If page 1 is written out, then the value cached
-** in Pager.dbFileVers[] is updated to match the new value stored in
-** the database file.
-**
-** If everything is successful, SQLITE_OK is returned. If an IO error
-** occurs, an IO error code is returned. Or, if the EXCLUSIVE lock cannot
-** be obtained, SQLITE_BUSY is returned.
-*/
-static int pager_write_pagelist(PgHdr *pList){
- Pager *pPager; /* Pager object */
- int rc; /* Return code */
-
- if( NEVER(pList==0) ) return SQLITE_OK;
- pPager = pList->pPager;
-
- /* At this point there may be either a RESERVED or EXCLUSIVE lock on the
- ** database file. If there is already an EXCLUSIVE lock, the following
- ** call is a no-op.
- **
- ** Moving the lock from RESERVED to EXCLUSIVE actually involves going
- ** through an intermediate state PENDING. A PENDING lock prevents new
- ** readers from attaching to the database but is unsufficient for us to
- ** write. The idea of a PENDING lock is to prevent new readers from
- ** coming in while we wait for existing readers to clear.
- **
- ** While the pager is in the RESERVED state, the original database file
- ** is unchanged and we can rollback without having to playback the
- ** journal into the original database file. Once we transition to
- ** EXCLUSIVE, it means the database file has been changed and any rollback
- ** will require a journal playback.
- */
- assert( pPager->state>=PAGER_RESERVED );
- rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK);
-
- /* If the file is a temp-file has not yet been opened, open it now. It
- ** is not possible for rc to be other than SQLITE_OK if this branch
- ** is taken, as pager_wait_on_lock() is a no-op for temp-files.
- */
- if( !isOpen(pPager->fd) ){
- assert( pPager->tempFile && rc==SQLITE_OK );
- rc = pagerOpentemp(pPager, pPager->fd, pPager->vfsFlags);
- }
-
- while( rc==SQLITE_OK && pList ){
- Pgno pgno = pList->pgno;
-
- /* If there are dirty pages in the page cache with page numbers greater
- ** than Pager.dbSize, this means sqlite3PagerTruncateImage() was called to
- ** make the file smaller (presumably by auto-vacuum code). Do not write
- ** any such pages to the file.
- **
- ** Also, do not write out any page that has the PGHDR_DONT_WRITE flag
- ** set (set by sqlite3PagerDontWrite()).
- */
- if( pgno<=pPager->dbSize && 0==(pList->flags&PGHDR_DONT_WRITE) ){
- i64 offset = (pgno-1)*(i64)pPager->pageSize; /* Offset to write */
- char *pData; /* Data to write */
-
- /* Encode the database */
- CODEC2(pPager, pList->pData, pgno, 6, return SQLITE_NOMEM, pData);
-
- /* Write out the page data. */
- rc = sqlite3OsWrite(pPager->fd, pData, pPager->pageSize, offset);
-
- /* If page 1 was just written, update Pager.dbFileVers to match
- ** the value now stored in the database file. If writing this
- ** page caused the database file to grow, update dbFileSize.
- */
- if( pgno==1 ){
- memcpy(&pPager->dbFileVers, &pData[24], sizeof(pPager->dbFileVers));
- }
- if( pgno>pPager->dbFileSize ){
- pPager->dbFileSize = pgno;
- }
-
- /* Update any backup objects copying the contents of this pager. */
- sqlite3BackupUpdate(pPager->pBackup, pgno, (u8*)pList->pData);
-
- PAGERTRACE(("STORE %d page %d hash(%08x)\n",
- PAGERID(pPager), pgno, pager_pagehash(pList)));
- IOTRACE(("PGOUT %p %d\n", pPager, pgno));
- PAGER_INCR(sqlite3_pager_writedb_count);
- PAGER_INCR(pPager->nWrite);
- }else{
- PAGERTRACE(("NOSTORE %d page %d\n", PAGERID(pPager), pgno));
- }
-#ifdef SQLITE_CHECK_PAGES
- pList->pageHash = pager_pagehash(pList);
-#endif
- pList = pList->pDirty;
- }
-
- return rc;
-}
-
-/*
-** Append a record of the current state of page pPg to the sub-journal.
-** It is the callers responsibility to use subjRequiresPage() to check
-** that it is really required before calling this function.
-**
-** If successful, set the bit corresponding to pPg->pgno in the bitvecs
-** for all open savepoints before returning.
-**
-** This function returns SQLITE_OK if everything is successful, an IO
-** error code if the attempt to write to the sub-journal fails, or
-** SQLITE_NOMEM if a malloc fails while setting a bit in a savepoint
-** bitvec.
-*/
-static int subjournalPage(PgHdr *pPg){
- int rc = SQLITE_OK;
- Pager *pPager = pPg->pPager;
- if( isOpen(pPager->sjfd) ){
- void *pData = pPg->pData;
- i64 offset = pPager->nSubRec*(4+pPager->pageSize);
- char *pData2;
-
- CODEC2(pPager, pData, pPg->pgno, 7, return SQLITE_NOMEM, pData2);
- PAGERTRACE(("STMT-JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno));
-
- assert( pageInJournal(pPg) || pPg->pgno>pPager->dbOrigSize );
- rc = write32bits(pPager->sjfd, offset, pPg->pgno);
- if( rc==SQLITE_OK ){
- rc = sqlite3OsWrite(pPager->sjfd, pData2, pPager->pageSize, offset+4);
- }
- }
- if( rc==SQLITE_OK ){
- pPager->nSubRec++;
- assert( pPager->nSavepoint>0 );
- rc = addToSavepointBitvecs(pPager, pPg->pgno);
- }
- return rc;
-}
-
-
-/*
-** This function is called by the pcache layer when it has reached some
-** soft memory limit. The first argument is a pointer to a Pager object
-** (cast as a void*). The pager is always 'purgeable' (not an in-memory
-** database). The second argument is a reference to a page that is
-** currently dirty but has no outstanding references. The page
-** is always associated with the Pager object passed as the first
-** argument.
-**
-** The job of this function is to make pPg clean by writing its contents
-** out to the database file, if possible. This may involve syncing the
-** journal file.
-**
-** If successful, sqlite3PcacheMakeClean() is called on the page and
-** SQLITE_OK returned. If an IO error occurs while trying to make the
-** page clean, the IO error code is returned. If the page cannot be
-** made clean for some other reason, but no error occurs, then SQLITE_OK
-** is returned by sqlite3PcacheMakeClean() is not called.
-*/
-static int pagerStress(void *p, PgHdr *pPg){
- Pager *pPager = (Pager *)p;
- int rc = SQLITE_OK;
-
- assert( pPg->pPager==pPager );
- assert( pPg->flags&PGHDR_DIRTY );
-
- /* The doNotSync flag is set by the sqlite3PagerWrite() function while it
- ** is journalling a set of two or more database pages that are stored
- ** on the same disk sector. Syncing the journal is not allowed while
- ** this is happening as it is important that all members of such a
- ** set of pages are synced to disk together. So, if the page this function
- ** is trying to make clean will require a journal sync and the doNotSync
- ** flag is set, return without doing anything. The pcache layer will
- ** just have to go ahead and allocate a new page buffer instead of
- ** reusing pPg.
- **
- ** Similarly, if the pager has already entered the error state, do not
- ** try to write the contents of pPg to disk.
- */
- if( NEVER(pPager->errCode)
- || (pPager->doNotSync && pPg->flags&PGHDR_NEED_SYNC)
- ){
- return SQLITE_OK;
- }
-
- /* Sync the journal file if required. */
- if( pPg->flags&PGHDR_NEED_SYNC ){
- rc = syncJournal(pPager);
- if( rc==SQLITE_OK && pPager->fullSync &&
- !(pPager->journalMode==PAGER_JOURNALMODE_MEMORY) &&
- !(sqlite3OsDeviceCharacteristics(pPager->fd)&SQLITE_IOCAP_SAFE_APPEND)
- ){
- pPager->nRec = 0;
- rc = writeJournalHdr(pPager);
- }
- }
-
- /* If the page number of this page is larger than the current size of
- ** the database image, it may need to be written to the sub-journal.
- ** This is because the call to pager_write_pagelist() below will not
- ** actually write data to the file in this case.
- **
- ** Consider the following sequence of events:
- **
- ** BEGIN;
- ** <journal page X>
- ** <modify page X>
- ** SAVEPOINT sp;
- ** <shrink database file to Y pages>
- ** pagerStress(page X)
- ** ROLLBACK TO sp;
- **
- ** If (X>Y), then when pagerStress is called page X will not be written
- ** out to the database file, but will be dropped from the cache. Then,
- ** following the "ROLLBACK TO sp" statement, reading page X will read
- ** data from the database file. This will be the copy of page X as it
- ** was when the transaction started, not as it was when "SAVEPOINT sp"
- ** was executed.
- **
- ** The solution is to write the current data for page X into the
- ** sub-journal file now (if it is not already there), so that it will
- ** be restored to its current value when the "ROLLBACK TO sp" is
- ** executed.
- */
- if( NEVER(
- rc==SQLITE_OK && pPg->pgno>pPager->dbSize && subjRequiresPage(pPg)
- ) ){
- rc = subjournalPage(pPg);
- }
-
- /* Write the contents of the page out to the database file. */
- if( rc==SQLITE_OK ){
- pPg->pDirty = 0;
- rc = pager_write_pagelist(pPg);
- }
-
- /* Mark the page as clean. */
- if( rc==SQLITE_OK ){
- PAGERTRACE(("STRESS %d page %d\n", PAGERID(pPager), pPg->pgno));
- sqlite3PcacheMakeClean(pPg);
- }
-
- return pager_error(pPager, rc);
-}
-
-
-/*
-** Allocate and initialize a new Pager object and put a pointer to it
-** in *ppPager. The pager should eventually be freed by passing it
-** to sqlite3PagerClose().
-**
-** The zFilename argument is the path to the database file to open.
-** If zFilename is NULL then a randomly-named temporary file is created
-** and used as the file to be cached. Temporary files are be deleted
-** automatically when they are closed. If zFilename is ":memory:" then
-** all information is held in cache. It is never written to disk.
-** This can be used to implement an in-memory database.
-**
-** The nExtra parameter specifies the number of bytes of space allocated
-** along with each page reference. This space is available to the user
-** via the sqlite3PagerGetExtra() API.
-**
-** The flags argument is used to specify properties that affect the
-** operation of the pager. It should be passed some bitwise combination
-** of the PAGER_OMIT_JOURNAL and PAGER_NO_READLOCK flags.
-**
-** The vfsFlags parameter is a bitmask to pass to the flags parameter
-** of the xOpen() method of the supplied VFS when opening files.
-**
-** If the pager object is allocated and the specified file opened
-** successfully, SQLITE_OK is returned and *ppPager set to point to
-** the new pager object. If an error occurs, *ppPager is set to NULL
-** and error code returned. This function may return SQLITE_NOMEM
-** (sqlite3Malloc() is used to allocate memory), SQLITE_CANTOPEN or
-** various SQLITE_IO_XXX errors.
-*/
-SQLITE_PRIVATE int sqlite3PagerOpen(
- sqlite3_vfs *pVfs, /* The virtual file system to use */
- Pager **ppPager, /* OUT: Return the Pager structure here */
- const char *zFilename, /* Name of the database file to open */
- int nExtra, /* Extra bytes append to each in-memory page */
- int flags, /* flags controlling this file */
- int vfsFlags, /* flags passed through to sqlite3_vfs.xOpen() */
- void (*xReinit)(DbPage*) /* Function to reinitialize pages */
-){
- u8 *pPtr;
- Pager *pPager = 0; /* Pager object to allocate and return */
- int rc = SQLITE_OK; /* Return code */
- int tempFile = 0; /* True for temp files (incl. in-memory files) */
- int memDb = 0; /* True if this is an in-memory file */
- int readOnly = 0; /* True if this is a read-only file */
- int journalFileSize; /* Bytes to allocate for each journal fd */
- char *zPathname = 0; /* Full path to database file */
- int nPathname = 0; /* Number of bytes in zPathname */
- int useJournal = (flags & PAGER_OMIT_JOURNAL)==0; /* False to omit journal */
- int noReadlock = (flags & PAGER_NO_READLOCK)!=0; /* True to omit read-lock */
- int pcacheSize = sqlite3PcacheSize(); /* Bytes to allocate for PCache */
- u16 szPageDflt = SQLITE_DEFAULT_PAGE_SIZE; /* Default page size */
-
- /* Figure out how much space is required for each journal file-handle
- ** (there are two of them, the main journal and the sub-journal). This
- ** is the maximum space required for an in-memory journal file handle
- ** and a regular journal file-handle. Note that a "regular journal-handle"
- ** may be a wrapper capable of caching the first portion of the journal
- ** file in memory to implement the atomic-write optimization (see
- ** source file journal.c).
- */
- if( sqlite3JournalSize(pVfs)>sqlite3MemJournalSize() ){
- journalFileSize = ROUND8(sqlite3JournalSize(pVfs));
- }else{
- journalFileSize = ROUND8(sqlite3MemJournalSize());
- }
-
- /* Set the output variable to NULL in case an error occurs. */
- *ppPager = 0;
-
- /* Compute and store the full pathname in an allocated buffer pointed
- ** to by zPathname, length nPathname. Or, if this is a temporary file,
- ** leave both nPathname and zPathname set to 0.
- */
- if( zFilename && zFilename[0] ){
- nPathname = pVfs->mxPathname+1;
- zPathname = sqlite3Malloc(nPathname*2);
- if( zPathname==0 ){
- return SQLITE_NOMEM;
- }
-#ifndef SQLITE_OMIT_MEMORYDB
- if( strcmp(zFilename,":memory:")==0 ){
- memDb = 1;
- zPathname[0] = 0;
- }else
-#endif
- {
- zPathname[0] = 0; /* Make sure initialized even if FullPathname() fails */
- rc = sqlite3OsFullPathname(pVfs, zFilename, nPathname, zPathname);
- }
-
- nPathname = sqlite3Strlen30(zPathname);
- 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
- ** bytes in length. This means the database cannot be opened,
- ** as it will not be possible to open the journal file or even
- ** check for a hot-journal before reading.
- */
- rc = SQLITE_CANTOPEN;
- }
- if( rc!=SQLITE_OK ){
- sqlite3_free(zPathname);
- return rc;
- }
- }
-
- /* Allocate memory for the Pager structure, PCache object, the
- ** three file descriptors, the database file name and the journal
- ** file name. The layout in memory is as follows:
- **
- ** Pager object (sizeof(Pager) bytes)
- ** PCache object (sqlite3PcacheSize() bytes)
- ** Database file handle (pVfs->szOsFile bytes)
- ** Sub-journal file handle (journalFileSize bytes)
- ** Main journal file handle (journalFileSize bytes)
- ** Database file name (nPathname+1 bytes)
- ** Journal file name (nPathname+8+1 bytes)
- */
- pPtr = (u8 *)sqlite3MallocZero(
- ROUND8(sizeof(*pPager)) + /* Pager structure */
- ROUND8(pcacheSize) + /* PCache object */
- ROUND8(pVfs->szOsFile) + /* The main db file */
- journalFileSize * 2 + /* The two journal files */
- nPathname + 1 + /* zFilename */
- nPathname + 8 + 1 /* zJournal */
- );
- assert( EIGHT_BYTE_ALIGNMENT(SQLITE_INT_TO_PTR(journalFileSize)) );
- if( !pPtr ){
- sqlite3_free(zPathname);
- return SQLITE_NOMEM;
- }
- pPager = (Pager*)(pPtr);
- pPager->pPCache = (PCache*)(pPtr += ROUND8(sizeof(*pPager)));
- pPager->fd = (sqlite3_file*)(pPtr += ROUND8(pcacheSize));
- pPager->sjfd = (sqlite3_file*)(pPtr += ROUND8(pVfs->szOsFile));
- pPager->jfd = (sqlite3_file*)(pPtr += journalFileSize);
- pPager->zFilename = (char*)(pPtr += journalFileSize);
- assert( EIGHT_BYTE_ALIGNMENT(pPager->jfd) );
-
- /* Fill in the Pager.zFilename and Pager.zJournal buffers, if required. */
- if( zPathname ){
- pPager->zJournal = (char*)(pPtr += nPathname + 1);
- memcpy(pPager->zFilename, zPathname, nPathname);
- memcpy(pPager->zJournal, zPathname, nPathname);
- memcpy(&pPager->zJournal[nPathname], "-journal", 8);
- if( pPager->zFilename[0]==0 ) pPager->zJournal[0] = 0;
- sqlite3_free(zPathname);
- }
- pPager->pVfs = pVfs;
- pPager->vfsFlags = vfsFlags;
-
- /* Open the pager file.
- */
- if( zFilename && zFilename[0] && !memDb ){
- int fout = 0; /* VFS flags returned by xOpen() */
- rc = sqlite3OsOpen(pVfs, pPager->zFilename, pPager->fd, vfsFlags, &fout);
- readOnly = (fout&SQLITE_OPEN_READONLY);
-
- /* If the file was successfully opened for read/write access,
- ** choose a default page size in case we have to create the
- ** database file. The default page size is the maximum of:
- **
- ** + SQLITE_DEFAULT_PAGE_SIZE,
- ** + The value returned by sqlite3OsSectorSize()
- ** + The largest page size that can be written atomically.
- */
- if( rc==SQLITE_OK && !readOnly ){
- setSectorSize(pPager);
- assert(SQLITE_DEFAULT_PAGE_SIZE<=SQLITE_MAX_DEFAULT_PAGE_SIZE);
- if( szPageDflt<pPager->sectorSize ){
- if( pPager->sectorSize>SQLITE_MAX_DEFAULT_PAGE_SIZE ){
- szPageDflt = SQLITE_MAX_DEFAULT_PAGE_SIZE;
- }else{
- szPageDflt = (u16)pPager->sectorSize;
- }
- }
-#ifdef SQLITE_ENABLE_ATOMIC_WRITE
- {
- int iDc = sqlite3OsDeviceCharacteristics(pPager->fd);
- int ii;
- assert(SQLITE_IOCAP_ATOMIC512==(512>>8));
- assert(SQLITE_IOCAP_ATOMIC64K==(65536>>8));
- assert(SQLITE_MAX_DEFAULT_PAGE_SIZE<=65536);
- for(ii=szPageDflt; ii<=SQLITE_MAX_DEFAULT_PAGE_SIZE; ii=ii*2){
- if( iDc&(SQLITE_IOCAP_ATOMIC|(ii>>8)) ){
- szPageDflt = ii;
- }
- }
- }
-#endif
- }
- }else{
- /* If a temporary file is requested, it is not opened immediately.
- ** In this case we accept the default page size and delay actually
- ** opening the file until the first call to OsWrite().
- **
- ** This branch is also run for an in-memory database. An in-memory
- ** database is the same as a temp-file that is never written out to
- ** disk and uses an in-memory rollback journal.
- */
- tempFile = 1;
- pPager->state = PAGER_EXCLUSIVE;
- readOnly = (vfsFlags&SQLITE_OPEN_READONLY);
- }
-
- /* The following call to PagerSetPagesize() serves to set the value of
- ** Pager.pageSize and to allocate the Pager.pTmpSpace buffer.
- */
- if( rc==SQLITE_OK ){
- assert( pPager->memDb==0 );
- rc = sqlite3PagerSetPagesize(pPager, &szPageDflt, -1);
- testcase( rc!=SQLITE_OK );
- }
-
- /* If an error occurred in either of the blocks above, free the
- ** Pager structure and close the file.
- */
- if( rc!=SQLITE_OK ){
- assert( !pPager->pTmpSpace );
- sqlite3OsClose(pPager->fd);
- sqlite3_free(pPager);
- return rc;
- }
-
- /* Initialize the PCache object. */
- assert( nExtra<1000 );
- nExtra = ROUND8(nExtra);
- sqlite3PcacheOpen(szPageDflt, nExtra, !memDb,
- !memDb?pagerStress:0, (void *)pPager, pPager->pPCache);
-
- PAGERTRACE(("OPEN %d %s\n", FILEHANDLEID(pPager->fd), pPager->zFilename));
- IOTRACE(("OPEN %p %s\n", pPager, pPager->zFilename))
-
- pPager->useJournal = (u8)useJournal;
- pPager->noReadlock = (noReadlock && readOnly) ?1:0;
- /* pPager->stmtOpen = 0; */
- /* pPager->stmtInUse = 0; */
- /* pPager->nRef = 0; */
- pPager->dbSizeValid = (u8)memDb;
- /* pPager->stmtSize = 0; */
- /* pPager->stmtJSize = 0; */
- /* pPager->nPage = 0; */
- pPager->mxPgno = SQLITE_MAX_PAGE_COUNT;
- /* pPager->state = PAGER_UNLOCK; */
- assert( pPager->state == (tempFile ? PAGER_EXCLUSIVE : PAGER_UNLOCK) );
- /* pPager->errMask = 0; */
- pPager->tempFile = (u8)tempFile;
- assert( tempFile==PAGER_LOCKINGMODE_NORMAL
- || tempFile==PAGER_LOCKINGMODE_EXCLUSIVE );
- assert( PAGER_LOCKINGMODE_EXCLUSIVE==1 );
- pPager->exclusiveMode = (u8)tempFile;
- pPager->changeCountDone = pPager->tempFile;
- pPager->memDb = (u8)memDb;
- pPager->readOnly = (u8)readOnly;
- /* pPager->needSync = 0; */
- assert( useJournal || pPager->tempFile );
- pPager->noSync = pPager->tempFile;
- pPager->fullSync = pPager->noSync ?0:1;
- pPager->sync_flags = SQLITE_SYNC_NORMAL;
- /* pPager->pFirst = 0; */
- /* pPager->pFirstSynced = 0; */
- /* pPager->pLast = 0; */
- pPager->nExtra = (u16)nExtra;
- pPager->journalSizeLimit = SQLITE_DEFAULT_JOURNAL_SIZE_LIMIT;
- assert( isOpen(pPager->fd) || tempFile );
- setSectorSize(pPager);
- if( !useJournal ){
- pPager->journalMode = PAGER_JOURNALMODE_OFF;
- }else if( memDb ){
- pPager->journalMode = PAGER_JOURNALMODE_MEMORY;
- }
- /* pPager->xBusyHandler = 0; */
- /* pPager->pBusyHandlerArg = 0; */
- pPager->xReiniter = xReinit;
- /* memset(pPager->aHash, 0, sizeof(pPager->aHash)); */
- *ppPager = pPager;
- return SQLITE_OK;
-}
-
-
-
-/*
-** This function is called after transitioning from PAGER_UNLOCK to
-** PAGER_SHARED state. It tests if there is a hot journal present in
-** the file-system for the given pager. A hot journal is one that
-** needs to be played back. According to this function, a hot-journal
-** file exists if the following criteria are met:
-**
-** * The journal file exists in the file system, and
-** * No process holds a RESERVED or greater lock on the database file, and
-** * The database file itself is greater than 0 bytes in size, and
-** * The first byte of the journal file exists and is not 0x00.
-**
-** If the current size of the database file is 0 but a journal file
-** exists, that is probably an old journal left over from a prior
-** database with the same name. In this case the journal file is
-** just deleted using OsDelete, *pExists is set to 0 and SQLITE_OK
-** is returned.
-**
-** This routine does not check if there is a master journal filename
-** at the end of the file. If there is, and that master journal file
-** does not exist, then the journal file is not really hot. In this
-** case this routine will return a false-positive. The pager_playback()
-** routine will discover that the journal file is not really hot and
-** will not roll it back.
-**
-** If a hot-journal file is found to exist, *pExists is set to 1 and
-** SQLITE_OK returned. If no hot-journal file is present, *pExists is
-** set to 0 and SQLITE_OK returned. If an IO error occurs while trying
-** to determine whether or not a hot-journal file exists, the IO error
-** code is returned and the value of *pExists is undefined.
-*/
-static int hasHotJournal(Pager *pPager, int *pExists){
- sqlite3_vfs * const pVfs = pPager->pVfs;
- int rc; /* Return code */
- int exists; /* True if a journal file is present */
-
- assert( pPager!=0 );
- assert( pPager->useJournal );
- assert( isOpen(pPager->fd) );
- assert( !isOpen(pPager->jfd) );
- assert( pPager->state <= PAGER_SHARED );
-
- *pExists = 0;
- rc = sqlite3OsAccess(pVfs, pPager->zJournal, SQLITE_ACCESS_EXISTS, &exists);
- if( rc==SQLITE_OK && exists ){
- int locked; /* True if some process holds a RESERVED lock */
-
- /* Race condition here: Another process might have been holding the
- ** the RESERVED lock and have a journal open at the sqlite3OsAccess()
- ** call above, but then delete the journal and drop the lock before
- ** we get to the following sqlite3OsCheckReservedLock() call. If that
- ** is the case, this routine might think there is a hot journal when
- ** in fact there is none. This results in a false-positive which will
- ** be dealt with by the playback routine. Ticket #3883.
- */
- rc = sqlite3OsCheckReservedLock(pPager->fd, &locked);
- if( rc==SQLITE_OK && !locked ){
- int nPage;
-
- /* Check the size of the database file. If it consists of 0 pages,
- ** then delete the journal file. See the header comment above for
- ** the reasoning here. Delete the obsolete journal file under
- ** a RESERVED lock to avoid race conditions and to avoid violating
- ** [H33020].
- */
- rc = sqlite3PagerPagecount(pPager, &nPage);
- if( rc==SQLITE_OK ){
- if( nPage==0 ){
- sqlite3BeginBenignMalloc();
- if( sqlite3OsLock(pPager->fd, RESERVED_LOCK)==SQLITE_OK ){
- sqlite3OsDelete(pVfs, pPager->zJournal, 0);
- sqlite3OsUnlock(pPager->fd, SHARED_LOCK);
- }
- sqlite3EndBenignMalloc();
- }else{
- /* The journal file exists and no other connection has a reserved
- ** or greater lock on the database file. Now check that there is
- ** at least one non-zero bytes at the start of the journal file.
- ** If there is, then we consider this journal to be hot. If not,
- ** it can be ignored.
- */
- int f = SQLITE_OPEN_READONLY|SQLITE_OPEN_MAIN_JOURNAL;
- rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, f, &f);
- if( rc==SQLITE_OK ){
- u8 first = 0;
- rc = sqlite3OsRead(pPager->jfd, (void *)&first, 1, 0);
- if( rc==SQLITE_IOERR_SHORT_READ ){
- rc = SQLITE_OK;
- }
- sqlite3OsClose(pPager->jfd);
- *pExists = (first!=0);
- }else if( rc==SQLITE_CANTOPEN ){
- /* If we cannot open the rollback journal file in order to see if
- ** its has a zero header, that might be due to an I/O error, or
- ** it might be due to the race condition described above and in
- ** ticket #3883. Either way, assume that the journal is hot.
- ** This might be a false positive. But if it is, then the
- ** automatic journal playback and recovery mechanism will deal
- ** with it under an EXCLUSIVE lock where we do not need to
- ** worry so much with race conditions.
- */
- *pExists = 1;
- rc = SQLITE_OK;
- }
- }
- }
- }
- }
-
- return rc;
-}
-
-/*
-** Read the content for page pPg out of the database file and into
-** pPg->pData. A shared lock or greater must be held on the database
-** file before this function is called.
-**
-** If page 1 is read, then the value of Pager.dbFileVers[] is set to
-** the value read from the database file.
-**
-** If an IO error occurs, then the IO error is returned to the caller.
-** Otherwise, SQLITE_OK is returned.
-*/
-static int readDbPage(PgHdr *pPg){
- Pager *pPager = pPg->pPager; /* Pager object associated with page pPg */
- Pgno pgno = pPg->pgno; /* Page number to read */
- int rc; /* Return code */
- i64 iOffset; /* Byte offset of file to read from */
-
- assert( pPager->state>=PAGER_SHARED && !MEMDB );
- assert( isOpen(pPager->fd) );
-
- if( NEVER(!isOpen(pPager->fd)) ){
- assert( pPager->tempFile );
- memset(pPg->pData, 0, pPager->pageSize);
- return SQLITE_OK;
- }
- iOffset = (pgno-1)*(i64)pPager->pageSize;
- rc = sqlite3OsRead(pPager->fd, pPg->pData, pPager->pageSize, iOffset);
- if( rc==SQLITE_IOERR_SHORT_READ ){
- rc = SQLITE_OK;
- }
- if( pgno==1 ){
- u8 *dbFileVers = &((u8*)pPg->pData)[24];
- memcpy(&pPager->dbFileVers, dbFileVers, sizeof(pPager->dbFileVers));
- }
- CODEC1(pPager, pPg->pData, pgno, 3, rc = SQLITE_NOMEM);
-
- PAGER_INCR(sqlite3_pager_readdb_count);
- PAGER_INCR(pPager->nRead);
- IOTRACE(("PGIN %p %d\n", pPager, pgno));
- PAGERTRACE(("FETCH %d page %d hash(%08x)\n",
- PAGERID(pPager), pgno, pager_pagehash(pPg)));
-
- return rc;
-}
-
-/*
-** This function is called to obtain a shared lock on the database file.
-** It is illegal to call sqlite3PagerAcquire() until after this function
-** has been successfully called. If a shared-lock is already held when
-** this function is called, it is a no-op.
-**
-** The following operations are also performed by this function.
-**
-** 1) If the pager is currently in PAGER_UNLOCK state (no lock held
-** on the database file), then an attempt is made to obtain a
-** SHARED lock on the database file. Immediately after obtaining
-** the SHARED lock, the file-system is checked for a hot-journal,
-** which is played back if present. Following any hot-journal
-** rollback, the contents of the cache are validated by checking
-** the 'change-counter' field of the database file header and
-** discarded if they are found to be invalid.
-**
-** 2) If the pager is running in exclusive-mode, and there are currently
-** no outstanding references to any pages, and is in the error state,
-** then an attempt is made to clear the error state by discarding
-** the contents of the page cache and rolling back any open journal
-** file.
-**
-** If the operation described by (2) above is not attempted, and if the
-** pager is in an error state other than SQLITE_FULL when this is called,
-** the error state error code is returned. It is permitted to read the
-** database when in SQLITE_FULL error state.
-**
-** Otherwise, if everything is successful, SQLITE_OK is returned. If an
-** IO error occurs while locking the database, checking for a hot-journal
-** file or rolling back a journal file, the IO error code is returned.
-*/
-SQLITE_PRIVATE int sqlite3PagerSharedLock(Pager *pPager){
- int rc = SQLITE_OK; /* Return code */
- int isErrorReset = 0; /* True if recovering from error state */
-
- /* This routine is only called from b-tree and only when there are no
- ** outstanding pages */
- assert( sqlite3PcacheRefCount(pPager->pPCache)==0 );
- if( NEVER(MEMDB && pPager->errCode) ){ return pPager->errCode; }
-
- /* If this database is in an error-state, now is a chance to clear
- ** the error. Discard the contents of the pager-cache and rollback
- ** any hot journal in the file-system.
- */
- if( pPager->errCode ){
- if( isOpen(pPager->jfd) || pPager->zJournal ){
- isErrorReset = 1;
- }
- pPager->errCode = SQLITE_OK;
- pager_reset(pPager);
- }
-
- if( pPager->state==PAGER_UNLOCK || isErrorReset ){
- sqlite3_vfs * const pVfs = pPager->pVfs;
- int isHotJournal = 0;
- assert( !MEMDB );
- assert( sqlite3PcacheRefCount(pPager->pPCache)==0 );
- if( pPager->noReadlock ){
- assert( pPager->readOnly );
- pPager->state = PAGER_SHARED;
- }else{
- rc = pager_wait_on_lock(pPager, SHARED_LOCK);
- if( rc!=SQLITE_OK ){
- assert( pPager->state==PAGER_UNLOCK );
- return pager_error(pPager, rc);
- }
- }
- assert( pPager->state>=SHARED_LOCK );
-
- /* If a journal file exists, and there is no RESERVED lock on the
- ** database file, then it either needs to be played back or deleted.
- */
- if( !isErrorReset ){
- assert( pPager->state <= PAGER_SHARED );
- rc = hasHotJournal(pPager, &isHotJournal);
- if( rc!=SQLITE_OK ){
- goto failed;
- }
- }
- if( isErrorReset || isHotJournal ){
- /* Get an EXCLUSIVE lock on the database file. At this point it is
- ** important that a RESERVED lock is not obtained on the way to the
- ** EXCLUSIVE lock. If it were, another process might open the
- ** database file, detect the RESERVED lock, and conclude that the
- ** database is safe to read while this process is still rolling the
- ** hot-journal back.
- **
- ** Because the intermediate RESERVED lock is not requested, any
- ** other process attempting to access the database file will get to
- ** this point in the code and fail to obtain its own EXCLUSIVE lock
- ** on the database file.
- */
- if( pPager->state<EXCLUSIVE_LOCK ){
- rc = sqlite3OsLock(pPager->fd, EXCLUSIVE_LOCK);
- if( rc!=SQLITE_OK ){
- rc = pager_error(pPager, rc);
- goto failed;
- }
- pPager->state = PAGER_EXCLUSIVE;
- }
-
- /* Open the journal for read/write access. This is because in
- ** exclusive-access mode the file descriptor will be kept open and
- ** possibly used for a transaction later on. On some systems, the
- ** OsTruncate() call used in exclusive-access mode also requires
- ** a read/write file handle.
- */
- if( !isOpen(pPager->jfd) ){
- int res;
- rc = sqlite3OsAccess(pVfs,pPager->zJournal,SQLITE_ACCESS_EXISTS,&res);
- if( rc==SQLITE_OK ){
- if( res ){
- int fout = 0;
- int f = SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_JOURNAL;
- assert( !pPager->tempFile );
- rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, f, &fout);
- assert( rc!=SQLITE_OK || isOpen(pPager->jfd) );
- if( rc==SQLITE_OK && fout&SQLITE_OPEN_READONLY ){
- rc = SQLITE_CANTOPEN;
- sqlite3OsClose(pPager->jfd);
- }
- }else{
- /* If the journal does not exist, it usually means that some
- ** other connection managed to get in and roll it back before
- ** this connection obtained the exclusive lock above. Or, it
- ** may mean that the pager was in the error-state when this
- ** function was called and the journal file does not exist. */
- rc = pager_end_transaction(pPager, 0);
- }
- }
- }
- if( rc!=SQLITE_OK ){
- goto failed;
- }
-
- /* TODO: Why are these cleared here? Is it necessary? */
- pPager->journalStarted = 0;
- pPager->journalOff = 0;
- pPager->setMaster = 0;
- pPager->journalHdr = 0;
-
- /* Playback and delete the journal. Drop the database write
- ** lock and reacquire the read lock. Purge the cache before
- ** playing back the hot-journal so that we don't end up with
- ** an inconsistent cache.
- */
- if( isOpen(pPager->jfd) ){
- rc = pager_playback(pPager, 1);
- if( rc!=SQLITE_OK ){
- rc = pager_error(pPager, rc);
- goto failed;
- }
- }
- assert( (pPager->state==PAGER_SHARED)
- || (pPager->exclusiveMode && pPager->state>PAGER_SHARED)
- );
- }
-
- if( pPager->pBackup || sqlite3PcachePagecount(pPager->pPCache)>0 ){
- /* The shared-lock has just been acquired on the database file
- ** and there are already pages in the cache (from a previous
- ** read or write transaction). Check to see if the database
- ** has been modified. If the database has changed, flush the
- ** cache.
- **
- ** Database changes is detected by looking at 15 bytes beginning
- ** at offset 24 into the file. The first 4 of these 16 bytes are
- ** a 32-bit counter that is incremented with each change. The
- ** other bytes change randomly with each file change when
- ** a codec is in use.
- **
- ** There is a vanishingly small chance that a change will not be
- ** detected. The chance of an undetected change is so small that
- ** it can be neglected.
- */
- char dbFileVers[sizeof(pPager->dbFileVers)];
- sqlite3PagerPagecount(pPager, 0);
-
- if( pPager->errCode ){
- rc = pPager->errCode;
- goto failed;
- }
-
- assert( pPager->dbSizeValid );
- if( pPager->dbSize>0 ){
- IOTRACE(("CKVERS %p %d\n", pPager, sizeof(dbFileVers)));
- rc = sqlite3OsRead(pPager->fd, &dbFileVers, sizeof(dbFileVers), 24);
- if( rc!=SQLITE_OK ){
- goto failed;
- }
- }else{
- memset(dbFileVers, 0, sizeof(dbFileVers));
- }
-
- if( memcmp(pPager->dbFileVers, dbFileVers, sizeof(dbFileVers))!=0 ){
- pager_reset(pPager);
- }
- }
- assert( pPager->exclusiveMode || pPager->state==PAGER_SHARED );
- }
-
- failed:
- if( rc!=SQLITE_OK ){
- /* pager_unlock() is a no-op for exclusive mode and in-memory databases. */
- pager_unlock(pPager);
- }
- return rc;
-}
-
-/*
-** If the reference count has reached zero, rollback any active
-** transaction and unlock the pager.
-**
-** Except, in locking_mode=EXCLUSIVE when there is nothing to in
-** the rollback journal, the unlock is not performed and there is
-** nothing to rollback, so this routine is a no-op.
-*/
-static void pagerUnlockIfUnused(Pager *pPager){
- if( (sqlite3PcacheRefCount(pPager->pPCache)==0)
- && (!pPager->exclusiveMode || pPager->journalOff>0)
- ){
- pagerUnlockAndRollback(pPager);
- }
-}
-
-/*
-** Acquire a reference to page number pgno in pager pPager (a page
-** reference has type DbPage*). If the requested reference is
-** successfully obtained, it is copied to *ppPage and SQLITE_OK returned.
-**
-** If the requested page is already in the cache, it is returned.
-** Otherwise, a new page object is allocated and populated with data
-** read from the database file. In some cases, the pcache module may
-** choose not to allocate a new page object and may reuse an existing
-** object with no outstanding references.
-**
-** The extra data appended to a page is always initialized to zeros the
-** first time a page is loaded into memory. If the page requested is
-** already in the cache when this function is called, then the extra
-** data is left as it was when the page object was last used.
-**
-** If the database image is smaller than the requested page or if a
-** non-zero value is passed as the noContent parameter and the
-** requested page is not already stored in the cache, then no
-** actual disk read occurs. In this case the memory image of the
-** page is initialized to all zeros.
-**
-** If noContent is true, it means that we do not care about the contents
-** of the page. This occurs in two seperate scenarios:
-**
-** a) When reading a free-list leaf page from the database, and
-**
-** b) When a savepoint is being rolled back and we need to load
-** a new page into the cache to populate with the data read
-** from the savepoint journal.
-**
-** If noContent is true, then the data returned is zeroed instead of
-** being read from the database. Additionally, the bits corresponding
-** to pgno in Pager.pInJournal (bitvec of pages already written to the
-** journal file) and the PagerSavepoint.pInSavepoint bitvecs of any open
-** savepoints are set. This means if the page is made writable at any
-** point in the future, using a call to sqlite3PagerWrite(), its contents
-** will not be journaled. This saves IO.
-**
-** The acquisition might fail for several reasons. In all cases,
-** an appropriate error code is returned and *ppPage is set to NULL.
-**
-** See also sqlite3PagerLookup(). Both this routine and Lookup() attempt
-** to find a page in the in-memory cache first. If the page is not already
-** in memory, this routine goes to disk to read it in whereas Lookup()
-** just returns 0. This routine acquires a read-lock the first time it
-** has to go to disk, and could also playback an old journal if necessary.
-** Since Lookup() never goes to disk, it never has to deal with locks
-** or journal files.
-*/
-SQLITE_PRIVATE int sqlite3PagerAcquire(
- Pager *pPager, /* The pager open on the database file */
- Pgno pgno, /* Page number to fetch */
- DbPage **ppPage, /* Write a pointer to the page here */
- int noContent /* Do not bother reading content from disk if true */
-){
- int rc;
- PgHdr *pPg;
-
- assert( assert_pager_state(pPager) );
- assert( pPager->state>PAGER_UNLOCK );
-
- if( pgno==0 ){
- return SQLITE_CORRUPT_BKPT;
- }
-
- /* If the pager is in the error state, return an error immediately.
- ** Otherwise, request the page from the PCache layer. */
- if( pPager->errCode!=SQLITE_OK && pPager->errCode!=SQLITE_FULL ){
- rc = pPager->errCode;
- }else{
- rc = sqlite3PcacheFetch(pPager->pPCache, pgno, 1, ppPage);
- }
-
- if( rc!=SQLITE_OK ){
- /* Either the call to sqlite3PcacheFetch() returned an error or the
- ** pager was already in the error-state when this function was called.
- ** Set pPg to 0 and jump to the exception handler. */
- pPg = 0;
- goto pager_acquire_err;
- }
- assert( (*ppPage)->pgno==pgno );
- assert( (*ppPage)->pPager==pPager || (*ppPage)->pPager==0 );
-
- if( (*ppPage)->pPager ){
- /* In this case the pcache already contains an initialized copy of
- ** the page. Return without further ado. */
- assert( pgno<=PAGER_MAX_PGNO && pgno!=PAGER_MJ_PGNO(pPager) );
- PAGER_INCR(pPager->nHit);
- return SQLITE_OK;
-
- }else{
- /* The pager cache has created a new page. Its content needs to
- ** be initialized. */
- int nMax;
-
- PAGER_INCR(pPager->nMiss);
- pPg = *ppPage;
- pPg->pPager = pPager;
-
- /* The maximum page number is 2^31. Return SQLITE_CORRUPT if a page
- ** number greater than this, or the unused locking-page, is requested. */
- if( pgno>PAGER_MAX_PGNO || pgno==PAGER_MJ_PGNO(pPager) ){
- rc = SQLITE_CORRUPT_BKPT;
- goto pager_acquire_err;
- }
-
- rc = sqlite3PagerPagecount(pPager, &nMax);
- if( rc!=SQLITE_OK ){
- goto pager_acquire_err;
- }
-
- if( nMax<(int)pgno || MEMDB || noContent ){
- if( pgno>pPager->mxPgno ){
- rc = SQLITE_FULL;
- goto pager_acquire_err;
- }
- if( noContent ){
- /* Failure to set the bits in the InJournal bit-vectors is benign.
- ** It merely means that we might do some extra work to journal a
- ** page that does not need to be journaled. Nevertheless, be sure
- ** to test the case where a malloc error occurs while trying to set
- ** a bit in a bit vector.
- */
- sqlite3BeginBenignMalloc();
- if( pgno<=pPager->dbOrigSize ){
- TESTONLY( rc = ) sqlite3BitvecSet(pPager->pInJournal, pgno);
- testcase( rc==SQLITE_NOMEM );
- }
- TESTONLY( rc = ) addToSavepointBitvecs(pPager, pgno);
- testcase( rc==SQLITE_NOMEM );
- sqlite3EndBenignMalloc();
- }else{
- memset(pPg->pData, 0, pPager->pageSize);
- }
- IOTRACE(("ZERO %p %d\n", pPager, pgno));
- }else{
- assert( pPg->pPager==pPager );
- rc = readDbPage(pPg);
- if( rc!=SQLITE_OK ){
- goto pager_acquire_err;
- }
- }
-#ifdef SQLITE_CHECK_PAGES
- pPg->pageHash = pager_pagehash(pPg);
-#endif
- }
-
- return SQLITE_OK;
-
-pager_acquire_err:
- assert( rc!=SQLITE_OK );
- if( pPg ){
- sqlite3PcacheDrop(pPg);
- }
- pagerUnlockIfUnused(pPager);
-
- *ppPage = 0;
- return rc;
-}
-
-/*
-** Acquire a page if it is already in the in-memory cache. Do
-** not read the page from disk. Return a pointer to the page,
-** or 0 if the page is not in cache. Also, return 0 if the
-** pager is in PAGER_UNLOCK state when this function is called,
-** or if the pager is in an error state other than SQLITE_FULL.
-**
-** See also sqlite3PagerGet(). The difference between this routine
-** and sqlite3PagerGet() is that _get() will go to the disk and read
-** in the page if the page is not already in cache. This routine
-** returns NULL if the page is not in cache or if a disk I/O error
-** has ever happened.
-*/
-SQLITE_PRIVATE DbPage *sqlite3PagerLookup(Pager *pPager, Pgno pgno){
- PgHdr *pPg = 0;
- assert( pPager!=0 );
- assert( pgno!=0 );
- assert( pPager->pPCache!=0 );
- assert( pPager->state > PAGER_UNLOCK );
- sqlite3PcacheFetch(pPager->pPCache, pgno, 0, &pPg);
- return pPg;
-}
-
-/*
-** Release a page reference.
-**
-** If the number of references to the page drop to zero, then the
-** page is added to the LRU list. When all references to all pages
-** are released, a rollback occurs and the lock on the database is
-** removed.
-*/
-SQLITE_PRIVATE void sqlite3PagerUnref(DbPage *pPg){
- if( pPg ){
- Pager *pPager = pPg->pPager;
- sqlite3PcacheRelease(pPg);
- pagerUnlockIfUnused(pPager);
- }
-}
-
-/*
-** If the main journal file has already been opened, ensure that the
-** sub-journal file is open too. If the main journal is not open,
-** this function is a no-op.
-**
-** SQLITE_OK is returned if everything goes according to plan.
-** An SQLITE_IOERR_XXX error code is returned if a call to
-** sqlite3OsOpen() fails.
-*/
-static int openSubJournal(Pager *pPager){
- int rc = SQLITE_OK;
- if( isOpen(pPager->jfd) && !isOpen(pPager->sjfd) ){
- if( pPager->journalMode==PAGER_JOURNALMODE_MEMORY || pPager->subjInMemory ){
- sqlite3MemJournalOpen(pPager->sjfd);
- }else{
- rc = pagerOpentemp(pPager, pPager->sjfd, SQLITE_OPEN_SUBJOURNAL);
- }
- }
- return rc;
-}
-
-/*
-** This function is called at the start of every write transaction.
-** There must already be a RESERVED or EXCLUSIVE lock on the database
-** file when this routine is called.
-**
-** Open the journal file for pager pPager and write a journal header
-** to the start of it. If there are active savepoints, open the sub-journal
-** as well. This function is only used when the journal file is being
-** opened to write a rollback log for a transaction. It is not used
-** when opening a hot journal file to roll it back.
-**
-** If the journal file is already open (as it may be in exclusive mode),
-** then this function just writes a journal header to the start of the
-** already open file.
-**
-** Whether or not the journal file is opened by this function, the
-** Pager.pInJournal bitvec structure is allocated.
-**
-** Return SQLITE_OK if everything is successful. Otherwise, return
-** SQLITE_NOMEM if the attempt to allocate Pager.pInJournal fails, or
-** an IO error code if opening or writing the journal file fails.
-*/
-static int pager_open_journal(Pager *pPager){
- int rc = SQLITE_OK; /* Return code */
- sqlite3_vfs * const pVfs = pPager->pVfs; /* Local cache of vfs pointer */
-
- assert( pPager->state>=PAGER_RESERVED );
- assert( pPager->useJournal );
- assert( pPager->journalMode!=PAGER_JOURNALMODE_OFF );
- assert( pPager->pInJournal==0 );
-
- /* If already in the error state, this function is a no-op. But on
- ** the other hand, this routine is never called if we are already in
- ** an error state. */
- if( NEVER(pPager->errCode) ) return pPager->errCode;
-
- /* TODO: Is it really possible to get here with dbSizeValid==0? If not,
- ** the call to PagerPagecount() can be removed.
- */
- testcase( pPager->dbSizeValid==0 );
- sqlite3PagerPagecount(pPager, 0);
-
- pPager->pInJournal = sqlite3BitvecCreate(pPager->dbSize);
- if( pPager->pInJournal==0 ){
- return SQLITE_NOMEM;
- }
-
- /* Open the journal file if it is not already open. */
- if( !isOpen(pPager->jfd) ){
- if( pPager->journalMode==PAGER_JOURNALMODE_MEMORY ){
- sqlite3MemJournalOpen(pPager->jfd);
- }else{
- const int flags = /* VFS flags to open journal file */
- SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|
- (pPager->tempFile ?
- (SQLITE_OPEN_DELETEONCLOSE|SQLITE_OPEN_TEMP_JOURNAL):
- (SQLITE_OPEN_MAIN_JOURNAL)
- );
-#ifdef SQLITE_ENABLE_ATOMIC_WRITE
- rc = sqlite3JournalOpen(
- pVfs, pPager->zJournal, pPager->jfd, flags, jrnlBufferSize(pPager)
- );
-#else
- rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, flags, 0);
-#endif
- }
- assert( rc!=SQLITE_OK || isOpen(pPager->jfd) );
- }
-
-
- /* Write the first journal header to the journal file and open
- ** the sub-journal if necessary.
- */
- if( rc==SQLITE_OK ){
- /* TODO: Check if all of these are really required. */
- pPager->dbOrigSize = pPager->dbSize;
- pPager->journalStarted = 0;
- pPager->needSync = 0;
- pPager->nRec = 0;
- pPager->journalOff = 0;
- pPager->setMaster = 0;
- pPager->journalHdr = 0;
- rc = writeJournalHdr(pPager);
- }
- if( rc==SQLITE_OK && pPager->nSavepoint ){
- rc = openSubJournal(pPager);
- }
-
- if( rc!=SQLITE_OK ){
- sqlite3BitvecDestroy(pPager->pInJournal);
- pPager->pInJournal = 0;
- }
- return rc;
-}
-
-/*
-** Begin a write-transaction on the specified pager object. If a
-** write-transaction has already been opened, this function is a no-op.
-**
-** If the exFlag argument is false, then acquire at least a RESERVED
-** lock on the database file. If exFlag is true, then acquire at least
-** an EXCLUSIVE lock. If such a lock is already held, no locking
-** functions need be called.
-**
-** If this is not a temporary or in-memory file and, the journal file is
-** opened if it has not been already. For a temporary file, the opening
-** of the journal file is deferred until there is an actual need to
-** write to the journal. TODO: Why handle temporary files differently?
-**
-** If the journal file is opened (or if it is already open), then a
-** journal-header is written to the start of it.
-**
-** If the subjInMemory argument is non-zero, then any sub-journal opened
-** within this transaction will be opened as an in-memory file. This
-** has no effect if the sub-journal is already opened (as it may be when
-** running in exclusive mode) or if the transaction does not require a
-** sub-journal. If the subjInMemory argument is zero, then any required
-** sub-journal is implemented in-memory if pPager is an in-memory database,
-** or using a temporary file otherwise.
-*/
-SQLITE_PRIVATE int sqlite3PagerBegin(Pager *pPager, int exFlag, int subjInMemory){
- int rc = SQLITE_OK;
- assert( pPager->state!=PAGER_UNLOCK );
- pPager->subjInMemory = (u8)subjInMemory;
- if( pPager->state==PAGER_SHARED ){
- assert( pPager->pInJournal==0 );
- assert( !MEMDB && !pPager->tempFile );
-
- /* Obtain a RESERVED lock on the database file. If the exFlag parameter
- ** is true, then immediately upgrade this to an EXCLUSIVE lock. The
- ** busy-handler callback can be used when upgrading to the EXCLUSIVE
- ** lock, but not when obtaining the RESERVED lock.
- */
- rc = sqlite3OsLock(pPager->fd, RESERVED_LOCK);
- if( rc==SQLITE_OK ){
- pPager->state = PAGER_RESERVED;
- if( exFlag ){
- rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK);
- }
- }
-
- /* If the required locks were successfully obtained, open the journal
- ** file and write the first journal-header to it.
- */
- if( rc==SQLITE_OK && pPager->journalMode!=PAGER_JOURNALMODE_OFF ){
- rc = pager_open_journal(pPager);
- }
- }else if( isOpen(pPager->jfd) && pPager->journalOff==0 ){
- /* This happens when the pager was in exclusive-access mode the last
- ** time a (read or write) transaction was successfully concluded
- ** by this connection. Instead of deleting the journal file it was
- ** kept open and either was truncated to 0 bytes or its header was
- ** overwritten with zeros.
- */
- assert( pPager->nRec==0 );
- assert( pPager->dbOrigSize==0 );
- assert( pPager->pInJournal==0 );
- rc = pager_open_journal(pPager);
- }
-
- PAGERTRACE(("TRANSACTION %d\n", PAGERID(pPager)));
- assert( !isOpen(pPager->jfd) || pPager->journalOff>0 || rc!=SQLITE_OK );
- if( rc!=SQLITE_OK ){
- assert( !pPager->dbModified );
- /* Ignore any IO error that occurs within pager_end_transaction(). The
- ** purpose of this call is to reset the internal state of the pager
- ** sub-system. It doesn't matter if the journal-file is not properly
- ** finalized at this point (since it is not a valid journal file anyway).
- */
- pager_end_transaction(pPager, 0);
- }
- return rc;
-}
-
-/*
-** Mark a single data page as writeable. The page is written into the
-** main journal or sub-journal as required. If the page is written into
-** one of the journals, the corresponding bit is set in the
-** Pager.pInJournal bitvec and the PagerSavepoint.pInSavepoint bitvecs
-** of any open savepoints as appropriate.
-*/
-static int pager_write(PgHdr *pPg){
- void *pData = pPg->pData;
- Pager *pPager = pPg->pPager;
- int rc = SQLITE_OK;
-
- /* This routine is not called unless a transaction has already been
- ** started.
- */
- assert( pPager->state>=PAGER_RESERVED );
-
- /* If an error has been previously detected, we should not be
- ** calling this routine. Repeat the error for robustness.
- */
- if( NEVER(pPager->errCode) ) return pPager->errCode;
-
- /* Higher-level routines never call this function if database is not
- ** writable. But check anyway, just for robustness. */
- if( NEVER(pPager->readOnly) ) return SQLITE_PERM;
-
- assert( !pPager->setMaster );
-
- CHECK_PAGE(pPg);
-
- /* Mark the page as dirty. If the page has already been written
- ** to the journal then we can return right away.
- */
- sqlite3PcacheMakeDirty(pPg);
- if( pageInJournal(pPg) && !subjRequiresPage(pPg) ){
- pPager->dbModified = 1;
- }else{
-
- /* If we get this far, it means that the page needs to be
- ** written to the transaction journal or the ckeckpoint journal
- ** or both.
- **
- ** Higher level routines should have already started a transaction,
- ** which means they have acquired the necessary locks and opened
- ** a rollback journal. Double-check to makes sure this is the case.
- */
- rc = sqlite3PagerBegin(pPager, 0, pPager->subjInMemory);
- if( NEVER(rc!=SQLITE_OK) ){
- return rc;
- }
- if( !isOpen(pPager->jfd) && pPager->journalMode!=PAGER_JOURNALMODE_OFF ){
- assert( pPager->useJournal );
- rc = pager_open_journal(pPager);
- if( rc!=SQLITE_OK ) return rc;
- }
- pPager->dbModified = 1;
-
- /* The transaction journal now exists and we have a RESERVED or an
- ** EXCLUSIVE lock on the main database file. Write the current page to
- ** the transaction journal if it is not there already.
- */
- if( !pageInJournal(pPg) && isOpen(pPager->jfd) ){
- if( pPg->pgno<=pPager->dbOrigSize ){
- u32 cksum;
- char *pData2;
-
- /* We should never write to the journal file the page that
- ** contains the database locks. The following assert verifies
- ** that we do not. */
- assert( pPg->pgno!=PAGER_MJ_PGNO(pPager) );
- CODEC2(pPager, pData, pPg->pgno, 7, return SQLITE_NOMEM, pData2);
- cksum = pager_cksum(pPager, (u8*)pData2);
- rc = write32bits(pPager->jfd, pPager->journalOff, pPg->pgno);
- if( rc==SQLITE_OK ){
- rc = sqlite3OsWrite(pPager->jfd, pData2, pPager->pageSize,
- pPager->journalOff + 4);
- pPager->journalOff += pPager->pageSize+4;
- }
- if( rc==SQLITE_OK ){
- rc = write32bits(pPager->jfd, pPager->journalOff, cksum);
- pPager->journalOff += 4;
- }
- IOTRACE(("JOUT %p %d %lld %d\n", pPager, pPg->pgno,
- pPager->journalOff, pPager->pageSize));
- PAGER_INCR(sqlite3_pager_writej_count);
- PAGERTRACE(("JOURNAL %d page %d needSync=%d hash(%08x)\n",
- PAGERID(pPager), pPg->pgno,
- ((pPg->flags&PGHDR_NEED_SYNC)?1:0), pager_pagehash(pPg)));
-
- /* Even if an IO or diskfull error occurred while journalling the
- ** page in the block above, set the need-sync flag for the page.
- ** Otherwise, when the transaction is rolled back, the logic in
- ** playback_one_page() will think that the page needs to be restored
- ** in the database file. And if an IO error occurs while doing so,
- ** then corruption may follow.
- */
- if( !pPager->noSync ){
- pPg->flags |= PGHDR_NEED_SYNC;
- pPager->needSync = 1;
- }
-
- /* An error has occurred writing to the journal file. The
- ** transaction will be rolled back by the layer above.
- */
- if( rc!=SQLITE_OK ){
- return rc;
- }
-
- pPager->nRec++;
- assert( pPager->pInJournal!=0 );
- rc = sqlite3BitvecSet(pPager->pInJournal, pPg->pgno);
- testcase( rc==SQLITE_NOMEM );
- assert( rc==SQLITE_OK || rc==SQLITE_NOMEM );
- rc |= addToSavepointBitvecs(pPager, pPg->pgno);
- if( rc!=SQLITE_OK ){
- assert( rc==SQLITE_NOMEM );
- return rc;
- }
- }else{
- if( !pPager->journalStarted && !pPager->noSync ){
- pPg->flags |= PGHDR_NEED_SYNC;
- pPager->needSync = 1;
- }
- PAGERTRACE(("APPEND %d page %d needSync=%d\n",
- PAGERID(pPager), pPg->pgno,
- ((pPg->flags&PGHDR_NEED_SYNC)?1:0)));
- }
- }
-
- /* If the statement journal is open and the page is not in it,
- ** then write the current page to the statement journal. Note that
- ** the statement journal format differs from the standard journal format
- ** in that it omits the checksums and the header.
- */
- if( subjRequiresPage(pPg) ){
- rc = subjournalPage(pPg);
- }
- }
-
- /* Update the database size and return.
- */
- assert( pPager->state>=PAGER_SHARED );
- if( pPager->dbSize<pPg->pgno ){
- pPager->dbSize = pPg->pgno;
- }
- return rc;
-}
-
-/*
-** Mark a data page as writeable. This routine must be called before
-** making changes to a page. The caller must check the return value
-** of this function and be careful not to change any page data unless
-** this routine returns SQLITE_OK.
-**
-** The difference between this function and pager_write() is that this
-** function also deals with the special case where 2 or more pages
-** fit on a single disk sector. In this case all co-resident pages
-** must have been written to the journal file before returning.
-**
-** If an error occurs, SQLITE_NOMEM or an IO error code is returned
-** as appropriate. Otherwise, SQLITE_OK.
-*/
-SQLITE_PRIVATE int sqlite3PagerWrite(DbPage *pDbPage){
- int rc = SQLITE_OK;
-
- PgHdr *pPg = pDbPage;
- Pager *pPager = pPg->pPager;
- Pgno nPagePerSector = (pPager->sectorSize/pPager->pageSize);
-
- if( nPagePerSector>1 ){
- Pgno nPageCount; /* Total number of pages in database file */
- Pgno pg1; /* First page of the sector pPg is located on. */
- int nPage; /* Number of pages starting at pg1 to journal */
- int ii; /* Loop counter */
- int needSync = 0; /* True if any page has PGHDR_NEED_SYNC */
-
- /* Set the doNotSync flag to 1. This is because we cannot allow a journal
- ** header to be written between the pages journaled by this function.
- */
- assert( !MEMDB );
- assert( pPager->doNotSync==0 );
- pPager->doNotSync = 1;
-
- /* This trick assumes that both the page-size and sector-size are
- ** an integer power of 2. It sets variable pg1 to the identifier
- ** of the first page of the sector pPg is located on.
- */
- pg1 = ((pPg->pgno-1) & ~(nPagePerSector-1)) + 1;
-
- sqlite3PagerPagecount(pPager, (int *)&nPageCount);
- if( pPg->pgno>nPageCount ){
- nPage = (pPg->pgno - pg1)+1;
- }else if( (pg1+nPagePerSector-1)>nPageCount ){
- nPage = nPageCount+1-pg1;
- }else{
- nPage = nPagePerSector;
- }
- assert(nPage>0);
- assert(pg1<=pPg->pgno);
- assert((pg1+nPage)>pPg->pgno);
-
- for(ii=0; ii<nPage && rc==SQLITE_OK; ii++){
- Pgno pg = pg1+ii;
- PgHdr *pPage;
- if( pg==pPg->pgno || !sqlite3BitvecTest(pPager->pInJournal, pg) ){
- if( pg!=PAGER_MJ_PGNO(pPager) ){
- rc = sqlite3PagerGet(pPager, pg, &pPage);
- if( rc==SQLITE_OK ){
- rc = pager_write(pPage);
- if( pPage->flags&PGHDR_NEED_SYNC ){
- needSync = 1;
- assert(pPager->needSync);
- }
- sqlite3PagerUnref(pPage);
- }
- }
- }else if( (pPage = pager_lookup(pPager, pg))!=0 ){
- if( pPage->flags&PGHDR_NEED_SYNC ){
- needSync = 1;
- }
- sqlite3PagerUnref(pPage);
- }
- }
-
- /* If the PGHDR_NEED_SYNC flag is set for any of the nPage pages
- ** starting at pg1, then it needs to be set for all of them. Because
- ** writing to any of these nPage pages may damage the others, the
- ** journal file must contain sync()ed copies of all of them
- ** before any of them can be written out to the database file.
- */
- if( rc==SQLITE_OK && needSync ){
- assert( !MEMDB && pPager->noSync==0 );
- for(ii=0; ii<nPage; ii++){
- PgHdr *pPage = pager_lookup(pPager, pg1+ii);
- if( pPage ){
- pPage->flags |= PGHDR_NEED_SYNC;
- sqlite3PagerUnref(pPage);
- }
- }
- assert(pPager->needSync);
- }
-
- assert( pPager->doNotSync==1 );
- pPager->doNotSync = 0;
- }else{
- rc = pager_write(pDbPage);
- }
- return rc;
-}
-
-/*
-** Return TRUE if the page given in the argument was previously passed
-** to sqlite3PagerWrite(). In other words, return TRUE if it is ok
-** to change the content of the page.
-*/
-#ifndef NDEBUG
-SQLITE_PRIVATE int sqlite3PagerIswriteable(DbPage *pPg){
- return pPg->flags&PGHDR_DIRTY;
-}
-#endif
-
-/*
-** A call to this routine tells the pager that it is not necessary to
-** write the information on page pPg back to the disk, even though
-** that page might be marked as dirty. This happens, for example, when
-** the page has been added as a leaf of the freelist and so its
-** content no longer matters.
-**
-** The overlying software layer calls this routine when all of the data
-** on the given page is unused. The pager marks the page as clean so
-** that it does not get written to disk.
-**
-** Tests show that this optimization can quadruple the speed of large
-** DELETE operations.
-*/
-SQLITE_PRIVATE void sqlite3PagerDontWrite(PgHdr *pPg){
- Pager *pPager = pPg->pPager;
- if( (pPg->flags&PGHDR_DIRTY) && pPager->nSavepoint==0 ){
- PAGERTRACE(("DONT_WRITE page %d of %d\n", pPg->pgno, PAGERID(pPager)));
- IOTRACE(("CLEAN %p %d\n", pPager, pPg->pgno))
- pPg->flags |= PGHDR_DONT_WRITE;
-#ifdef SQLITE_CHECK_PAGES
- pPg->pageHash = pager_pagehash(pPg);
-#endif
- }
-}
-
-/*
-** This routine is called to increment the value of the database file
-** change-counter, stored as a 4-byte big-endian integer starting at
-** byte offset 24 of the pager file.
-**
-** If the isDirectMode flag is zero, then this is done by calling
-** sqlite3PagerWrite() on page 1, then modifying the contents of the
-** page data. In this case the file will be updated when the current
-** transaction is committed.
-**
-** The isDirectMode flag may only be non-zero if the library was compiled
-** with the SQLITE_ENABLE_ATOMIC_WRITE macro defined. In this case,
-** if isDirect is non-zero, then the database file is updated directly
-** by writing an updated version of page 1 using a call to the
-** sqlite3OsWrite() function.
-*/
-static int pager_incr_changecounter(Pager *pPager, int isDirectMode){
- int rc = SQLITE_OK;
-
- /* Declare and initialize constant integer 'isDirect'. If the
- ** atomic-write optimization is enabled in this build, then isDirect
- ** is initialized to the value passed as the isDirectMode parameter
- ** to this function. Otherwise, it is always set to zero.
- **
- ** The idea is that if the atomic-write optimization is not
- ** enabled at compile time, the compiler can omit the tests of
- ** 'isDirect' below, as well as the block enclosed in the
- ** "if( isDirect )" condition.
- */
-#ifndef SQLITE_ENABLE_ATOMIC_WRITE
-# define DIRECT_MODE 0
- assert( isDirectMode==0 );
- UNUSED_PARAMETER(isDirectMode);
-#else
-# define DIRECT_MODE isDirectMode
-#endif
-
- assert( pPager->state>=PAGER_RESERVED );
- if( !pPager->changeCountDone && ALWAYS(pPager->dbSize>0) ){
- PgHdr *pPgHdr; /* Reference to page 1 */
- u32 change_counter; /* Initial value of change-counter field */
-
- assert( !pPager->tempFile && isOpen(pPager->fd) );
-
- /* Open page 1 of the file for writing. */
- rc = sqlite3PagerGet(pPager, 1, &pPgHdr);
- assert( pPgHdr==0 || rc==SQLITE_OK );
-
- /* If page one was fetched successfully, and this function is not
- ** operating in direct-mode, make page 1 writable. When not in
- ** direct mode, page 1 is always held in cache and hence the PagerGet()
- ** above is always successful - hence the ALWAYS on rc==SQLITE_OK.
- */
- if( !DIRECT_MODE && ALWAYS(rc==SQLITE_OK) ){
- rc = sqlite3PagerWrite(pPgHdr);
- }
-
- if( rc==SQLITE_OK ){
- /* Increment the value just read and write it back to byte 24. */
- change_counter = sqlite3Get4byte((u8*)pPager->dbFileVers);
- change_counter++;
- put32bits(((char*)pPgHdr->pData)+24, change_counter);
-
- /* If running in direct mode, write the contents of page 1 to the file. */
- if( DIRECT_MODE ){
- const void *zBuf = pPgHdr->pData;
- assert( pPager->dbFileSize>0 );
- rc = sqlite3OsWrite(pPager->fd, zBuf, pPager->pageSize, 0);
- if( rc==SQLITE_OK ){
- pPager->changeCountDone = 1;
- }
- }else{
- pPager->changeCountDone = 1;
- }
- }
-
- /* Release the page reference. */
- sqlite3PagerUnref(pPgHdr);
- }
- return rc;
-}
-
-/*
-** Sync the pager file to disk. This is a no-op for in-memory files
-** or pages with the Pager.noSync flag set.
-**
-** If successful, or called on a pager for which it is a no-op, this
-** function returns SQLITE_OK. Otherwise, an IO error code is returned.
-*/
-SQLITE_PRIVATE int sqlite3PagerSync(Pager *pPager){
- int rc; /* Return code */
- assert( !MEMDB );
- if( pPager->noSync ){
- rc = SQLITE_OK;
- }else{
- rc = sqlite3OsSync(pPager->fd, pPager->sync_flags);
- }
- return rc;
-}
-
-/*
-** Sync the database file for the pager pPager. zMaster points to the name
-** of a master journal file that should be written into the individual
-** journal file. zMaster may be NULL, which is interpreted as no master
-** journal (a single database transaction).
-**
-** This routine ensures that:
-**
-** * The database file change-counter is updated,
-** * the journal is synced (unless the atomic-write optimization is used),
-** * all dirty pages are written to the database file,
-** * the database file is truncated (if required), and
-** * the database file synced.
-**
-** The only thing that remains to commit the transaction is to finalize
-** (delete, truncate or zero the first part of) the journal file (or
-** delete the master journal file if specified).
-**
-** Note that if zMaster==NULL, this does not overwrite a previous value
-** passed to an sqlite3PagerCommitPhaseOne() call.
-**
-** If the final parameter - noSync - is true, then the database file itself
-** is not synced. The caller must call sqlite3PagerSync() directly to
-** sync the database file before calling CommitPhaseTwo() to delete the
-** journal file in this case.
-*/
-SQLITE_PRIVATE int sqlite3PagerCommitPhaseOne(
- Pager *pPager, /* Pager object */
- const char *zMaster, /* If not NULL, the master journal name */
- int noSync /* True to omit the xSync on the db file */
-){
- int rc = SQLITE_OK; /* Return code */
-
- /* The dbOrigSize is never set if journal_mode=OFF */
- assert( pPager->journalMode!=PAGER_JOURNALMODE_OFF || pPager->dbOrigSize==0 );
-
- /* If a prior error occurred, this routine should not be called. ROLLBACK
- ** is the appropriate response to an error, not COMMIT. Guard against
- ** coding errors by repeating the prior error. */
- if( NEVER(pPager->errCode) ) return pPager->errCode;
-
- PAGERTRACE(("DATABASE SYNC: File=%s zMaster=%s nSize=%d\n",
- pPager->zFilename, zMaster, pPager->dbSize));
-
- if( MEMDB && pPager->dbModified ){
- /* If this is an in-memory db, or no pages have been written to, or this
- ** function has already been called, it is mostly a no-op. However, any
- ** backup in progress needs to be restarted.
- */
- sqlite3BackupRestart(pPager->pBackup);
- }else if( pPager->state!=PAGER_SYNCED && pPager->dbModified ){
-
- /* The following block updates the change-counter. Exactly how it
- ** does this depends on whether or not the atomic-update optimization
- ** was enabled at compile time, and if this transaction meets the
- ** runtime criteria to use the operation:
- **
- ** * The file-system supports the atomic-write property for
- ** blocks of size page-size, and
- ** * This commit is not part of a multi-file transaction, and
- ** * Exactly one page has been modified and store in the journal file.
- **
- ** If the optimization was not enabled at compile time, then the
- ** pager_incr_changecounter() function is called to update the change
- ** counter in 'indirect-mode'. If the optimization is compiled in but
- ** is not applicable to this transaction, call sqlite3JournalCreate()
- ** to make sure the journal file has actually been created, then call
- ** pager_incr_changecounter() to update the change-counter in indirect
- ** mode.
- **
- ** Otherwise, if the optimization is both enabled and applicable,
- ** then call pager_incr_changecounter() to update the change-counter
- ** in 'direct' mode. In this case the journal file will never be
- ** created for this transaction.
- */
-#ifdef SQLITE_ENABLE_ATOMIC_WRITE
- PgHdr *pPg;
- assert( isOpen(pPager->jfd) || pPager->journalMode==PAGER_JOURNALMODE_OFF );
- if( !zMaster && isOpen(pPager->jfd)
- && pPager->journalOff==jrnlBufferSize(pPager)
- && pPager->dbSize>=pPager->dbFileSize
- && (0==(pPg = sqlite3PcacheDirtyList(pPager->pPCache)) || 0==pPg->pDirty)
- ){
- /* Update the db file change counter via the direct-write method. The
- ** following call will modify the in-memory representation of page 1
- ** to include the updated change counter and then write page 1
- ** directly to the database file. Because of the atomic-write
- ** property of the host file-system, this is safe.
- */
- rc = pager_incr_changecounter(pPager, 1);
- }else{
- rc = sqlite3JournalCreate(pPager->jfd);
- if( rc==SQLITE_OK ){
- rc = pager_incr_changecounter(pPager, 0);
- }
- }
-#else
- rc = pager_incr_changecounter(pPager, 0);
-#endif
- if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
-
- /* If this transaction has made the database smaller, then all pages
- ** being discarded by the truncation must be written to the journal
- ** file. This can only happen in auto-vacuum mode.
- **
- ** Before reading the pages with page numbers larger than the
- ** current value of Pager.dbSize, set dbSize back to the value
- ** that it took at the start of the transaction. Otherwise, the
- ** calls to sqlite3PagerGet() return zeroed pages instead of
- ** reading data from the database file.
- **
- ** When journal_mode==OFF the dbOrigSize is always zero, so this
- ** block never runs if journal_mode=OFF.
- */
-#ifndef SQLITE_OMIT_AUTOVACUUM
- if( pPager->dbSize<pPager->dbOrigSize
- && ALWAYS(pPager->journalMode!=PAGER_JOURNALMODE_OFF)
- ){
- Pgno i; /* Iterator variable */
- const Pgno iSkip = PAGER_MJ_PGNO(pPager); /* Pending lock page */
- const Pgno dbSize = pPager->dbSize; /* Database image size */
- pPager->dbSize = pPager->dbOrigSize;
- for( i=dbSize+1; i<=pPager->dbOrigSize; i++ ){
- if( !sqlite3BitvecTest(pPager->pInJournal, i) && i!=iSkip ){
- PgHdr *pPage; /* Page to journal */
- rc = sqlite3PagerGet(pPager, i, &pPage);
- if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
- rc = sqlite3PagerWrite(pPage);
- sqlite3PagerUnref(pPage);
- if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
- }
- }
- pPager->dbSize = dbSize;
- }
-#endif
-
- /* Write the master journal name into the journal file. If a master
- ** journal file name has already been written to the journal file,
- ** or if zMaster is NULL (no master journal), then this call is a no-op.
- */
- rc = writeMasterJournal(pPager, zMaster);
- if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
-
- /* Sync the journal file. If the atomic-update optimization is being
- ** used, this call will not create the journal file or perform any
- ** real IO.
- */
- rc = syncJournal(pPager);
- if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
-
- /* Write all dirty pages to the database file. */
- rc = pager_write_pagelist(sqlite3PcacheDirtyList(pPager->pPCache));
- if( rc!=SQLITE_OK ){
- assert( rc!=SQLITE_IOERR_BLOCKED );
- goto commit_phase_one_exit;
- }
- sqlite3PcacheCleanAll(pPager->pPCache);
-
- /* If the file on disk is not the same size as the database image,
- ** then use pager_truncate to grow or shrink the file here.
- */
- if( pPager->dbSize!=pPager->dbFileSize ){
- Pgno nNew = pPager->dbSize - (pPager->dbSize==PAGER_MJ_PGNO(pPager));
- assert( pPager->state>=PAGER_EXCLUSIVE );
- rc = pager_truncate(pPager, nNew);
- if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
- }
-
- /* Finally, sync the database file. */
- if( !pPager->noSync && !noSync ){
- rc = sqlite3OsSync(pPager->fd, pPager->sync_flags);
- }
- IOTRACE(("DBSYNC %p\n", pPager))
-
- pPager->state = PAGER_SYNCED;
- }
-
-commit_phase_one_exit:
- return rc;
-}
-
-
-/*
-** When this function is called, the database file has been completely
-** updated to reflect the changes made by the current transaction and
-** synced to disk. The journal file still exists in the file-system
-** though, and if a failure occurs at this point it will eventually
-** be used as a hot-journal and the current transaction rolled back.
-**
-** This function finalizes the journal file, either by deleting,
-** truncating or partially zeroing it, so that it cannot be used
-** for hot-journal rollback. Once this is done the transaction is
-** irrevocably committed.
-**
-** If an error occurs, an IO error code is returned and the pager
-** moves into the error state. Otherwise, SQLITE_OK is returned.
-*/
-SQLITE_PRIVATE int sqlite3PagerCommitPhaseTwo(Pager *pPager){
- int rc = SQLITE_OK; /* Return code */
-
- /* This routine should not be called if a prior error has occurred.
- ** But if (due to a coding error elsewhere in the system) it does get
- ** called, just return the same error code without doing anything. */
- if( NEVER(pPager->errCode) ) return pPager->errCode;
-
- /* This function should not be called if the pager is not in at least
- ** PAGER_RESERVED state. And indeed SQLite never does this. But it is
- ** nice to have this defensive test here anyway.
- */
- if( NEVER(pPager->state<PAGER_RESERVED) ) return SQLITE_ERROR;
-
- /* An optimization. If the database was not actually modified during
- ** this transaction, the pager is running in exclusive-mode and is
- ** using persistent journals, then this function is a no-op.
- **
- ** The start of the journal file currently contains a single journal
- ** header with the nRec field set to 0. If such a journal is used as
- ** a hot-journal during hot-journal rollback, 0 changes will be made
- ** to the database file. So there is no need to zero the journal
- ** header. Since the pager is in exclusive mode, there is no need
- ** to drop any locks either.
- */
- if( pPager->dbModified==0 && pPager->exclusiveMode
- && pPager->journalMode==PAGER_JOURNALMODE_PERSIST
- ){
- assert( pPager->journalOff==JOURNAL_HDR_SZ(pPager) );
- return SQLITE_OK;
- }
-
- PAGERTRACE(("COMMIT %d\n", PAGERID(pPager)));
- assert( pPager->state==PAGER_SYNCED || MEMDB || !pPager->dbModified );
- rc = pager_end_transaction(pPager, pPager->setMaster);
- return pager_error(pPager, rc);
-}
-
-/*
-** Rollback all changes. The database falls back to PAGER_SHARED mode.
-**
-** This function performs two tasks:
-**
-** 1) It rolls back the journal file, restoring all database file and
-** in-memory cache pages to the state they were in when the transaction
-** was opened, and
-** 2) It finalizes the journal file, so that it is not used for hot
-** rollback at any point in the future.
-**
-** subject to the following qualifications:
-**
-** * If the journal file is not yet open when this function is called,
-** then only (2) is performed. In this case there is no journal file
-** to roll back.
-**
-** * If in an error state other than SQLITE_FULL, then task (1) is
-** performed. If successful, task (2). Regardless of the outcome
-** of either, the error state error code is returned to the caller
-** (i.e. either SQLITE_IOERR or SQLITE_CORRUPT).
-**
-** * If the pager is in PAGER_RESERVED state, then attempt (1). Whether
-** or not (1) is succussful, also attempt (2). If successful, return
-** SQLITE_OK. Otherwise, enter the error state and return the first
-** error code encountered.
-**
-** In this case there is no chance that the database was written to.
-** So is safe to finalize the journal file even if the playback
-** (operation 1) failed. However the pager must enter the error state
-** as the contents of the in-memory cache are now suspect.
-**
-** * Finally, if in PAGER_EXCLUSIVE state, then attempt (1). Only
-** attempt (2) if (1) is successful. Return SQLITE_OK if successful,
-** otherwise enter the error state and return the error code from the
-** failing operation.
-**
-** In this case the database file may have been written to. So if the
-** playback operation did not succeed it would not be safe to finalize
-** the journal file. It needs to be left in the file-system so that
-** some other process can use it to restore the database state (by
-** hot-journal rollback).
-*/
-SQLITE_PRIVATE int sqlite3PagerRollback(Pager *pPager){
- int rc = SQLITE_OK; /* Return code */
- PAGERTRACE(("ROLLBACK %d\n", PAGERID(pPager)));
- if( !pPager->dbModified || !isOpen(pPager->jfd) ){
- rc = pager_end_transaction(pPager, pPager->setMaster);
- }else if( pPager->errCode && pPager->errCode!=SQLITE_FULL ){
- if( pPager->state>=PAGER_EXCLUSIVE ){
- pager_playback(pPager, 0);
- }
- rc = pPager->errCode;
- }else{
- if( pPager->state==PAGER_RESERVED ){
- int rc2;
- rc = pager_playback(pPager, 0);
- rc2 = pager_end_transaction(pPager, pPager->setMaster);
- if( rc==SQLITE_OK ){
- rc = rc2;
- }
- }else{
- rc = pager_playback(pPager, 0);
- }
-
- if( !MEMDB ){
- pPager->dbSizeValid = 0;
- }
-
- /* 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.
- */
- rc = pager_error(pPager, rc);
- }
- return rc;
-}
-
-/*
-** Return TRUE if the database file is opened read-only. Return FALSE
-** if the database is (in theory) writable.
-*/
-SQLITE_PRIVATE u8 sqlite3PagerIsreadonly(Pager *pPager){
- return pPager->readOnly;
-}
-
-/*
-** Return the number of references to the pager.
-*/
-SQLITE_PRIVATE int sqlite3PagerRefcount(Pager *pPager){
- return sqlite3PcacheRefCount(pPager->pPCache);
-}
-
-/*
-** Return the number of references to the specified page.
-*/
-SQLITE_PRIVATE int sqlite3PagerPageRefcount(DbPage *pPage){
- return sqlite3PcachePageRefcount(pPage);
-}
-
-#ifdef SQLITE_TEST
-/*
-** This routine is used for testing and analysis only.
-*/
-SQLITE_PRIVATE int *sqlite3PagerStats(Pager *pPager){
- static int a[11];
- a[0] = sqlite3PcacheRefCount(pPager->pPCache);
- a[1] = sqlite3PcachePagecount(pPager->pPCache);
- a[2] = sqlite3PcacheGetCachesize(pPager->pPCache);
- a[3] = pPager->dbSizeValid ? (int) pPager->dbSize : -1;
- a[4] = pPager->state;
- a[5] = pPager->errCode;
- a[6] = pPager->nHit;
- a[7] = pPager->nMiss;
- a[8] = 0; /* Used to be pPager->nOvfl */
- a[9] = pPager->nRead;
- a[10] = pPager->nWrite;
- return a;
-}
-#endif
-
-/*
-** Return true if this is an in-memory pager.
-*/
-SQLITE_PRIVATE int sqlite3PagerIsMemdb(Pager *pPager){
- return MEMDB;
-}
-
-/*
-** Check that there are at least nSavepoint savepoints open. If there are
-** currently less than nSavepoints open, then open one or more savepoints
-** to make up the difference. If the number of savepoints is already
-** equal to nSavepoint, then this function is a no-op.
-**
-** If a memory allocation fails, SQLITE_NOMEM is returned. If an error
-** occurs while opening the sub-journal file, then an IO error code is
-** returned. Otherwise, SQLITE_OK.
-*/
-SQLITE_PRIVATE int sqlite3PagerOpenSavepoint(Pager *pPager, int nSavepoint){
- int rc = SQLITE_OK; /* Return code */
- int nCurrent = pPager->nSavepoint; /* Current number of savepoints */
-
- if( nSavepoint>nCurrent && pPager->useJournal ){
- int ii; /* Iterator variable */
- PagerSavepoint *aNew; /* New Pager.aSavepoint array */
-
- /* Either there is no active journal or the sub-journal is open or
- ** the journal is always stored in memory */
- assert( pPager->nSavepoint==0 || isOpen(pPager->sjfd) ||
- pPager->journalMode==PAGER_JOURNALMODE_MEMORY );
-
- /* Grow the Pager.aSavepoint array using realloc(). Return SQLITE_NOMEM
- ** if the allocation fails. Otherwise, zero the new portion in case a
- ** malloc failure occurs while populating it in the for(...) loop below.
- */
- aNew = (PagerSavepoint *)sqlite3Realloc(
- pPager->aSavepoint, sizeof(PagerSavepoint)*nSavepoint
- );
- if( !aNew ){
- return SQLITE_NOMEM;
- }
- memset(&aNew[nCurrent], 0, (nSavepoint-nCurrent) * sizeof(PagerSavepoint));
- pPager->aSavepoint = aNew;
- pPager->nSavepoint = nSavepoint;
-
- /* Populate the PagerSavepoint structures just allocated. */
- for(ii=nCurrent; ii<nSavepoint; ii++){
- assert( pPager->dbSizeValid );
- aNew[ii].nOrig = pPager->dbSize;
- if( isOpen(pPager->jfd) && ALWAYS(pPager->journalOff>0) ){
- aNew[ii].iOffset = pPager->journalOff;
- }else{
- aNew[ii].iOffset = JOURNAL_HDR_SZ(pPager);
- }
- aNew[ii].iSubRec = pPager->nSubRec;
- aNew[ii].pInSavepoint = sqlite3BitvecCreate(pPager->dbSize);
- if( !aNew[ii].pInSavepoint ){
- return SQLITE_NOMEM;
- }
- }
-
- /* Open the sub-journal, if it is not already opened. */
- rc = openSubJournal(pPager);
- assertTruncateConstraint(pPager);
- }
-
- return rc;
-}
-
-/*
-** This function is called to rollback or release (commit) a savepoint.
-** The savepoint to release or rollback need not be the most recently
-** created savepoint.
-**
-** Parameter op is always either SAVEPOINT_ROLLBACK or SAVEPOINT_RELEASE.
-** If it is SAVEPOINT_RELEASE, then release and destroy the savepoint with
-** index iSavepoint. If it is SAVEPOINT_ROLLBACK, then rollback all changes
-** that have occurred since the specified savepoint was created.
-**
-** The savepoint to rollback or release is identified by parameter
-** iSavepoint. A value of 0 means to operate on the outermost savepoint
-** (the first created). A value of (Pager.nSavepoint-1) means operate
-** on the most recently created savepoint. If iSavepoint is greater than
-** (Pager.nSavepoint-1), then this function is a no-op.
-**
-** If a negative value is passed to this function, then the current
-** transaction is rolled back. This is different to calling
-** sqlite3PagerRollback() because this function does not terminate
-** the transaction or unlock the database, it just restores the
-** contents of the database to its original state.
-**
-** In any case, all savepoints with an index greater than iSavepoint
-** are destroyed. If this is a release operation (op==SAVEPOINT_RELEASE),
-** then savepoint iSavepoint is also destroyed.
-**
-** This function may return SQLITE_NOMEM if a memory allocation fails,
-** or an IO error code if an IO error occurs while rolling back a
-** savepoint. If no errors occur, SQLITE_OK is returned.
-*/
-SQLITE_PRIVATE int sqlite3PagerSavepoint(Pager *pPager, int op, int iSavepoint){
- int rc = SQLITE_OK;
-
- assert( op==SAVEPOINT_RELEASE || op==SAVEPOINT_ROLLBACK );
- assert( iSavepoint>=0 || op==SAVEPOINT_ROLLBACK );
-
- if( iSavepoint<pPager->nSavepoint ){
- int ii; /* Iterator variable */
- int nNew; /* Number of remaining savepoints after this op. */
-
- /* Figure out how many savepoints will still be active after this
- ** operation. Store this value in nNew. Then free resources associated
- ** with any savepoints that are destroyed by this operation.
- */
- nNew = iSavepoint + (op==SAVEPOINT_ROLLBACK);
- for(ii=nNew; ii<pPager->nSavepoint; ii++){
- sqlite3BitvecDestroy(pPager->aSavepoint[ii].pInSavepoint);
- }
- pPager->nSavepoint = nNew;
-
- /* If this is a rollback operation, playback the specified savepoint.
- ** If this is a temp-file, it is possible that the journal file has
- ** not yet been opened. In this case there have been no changes to
- ** the database file, so the playback operation can be skipped.
- */
- if( op==SAVEPOINT_ROLLBACK && isOpen(pPager->jfd) ){
- PagerSavepoint *pSavepoint = (nNew==0)?0:&pPager->aSavepoint[nNew-1];
- rc = pagerPlaybackSavepoint(pPager, pSavepoint);
- assert(rc!=SQLITE_DONE);
- }
-
- /* If this is a release of the outermost savepoint, truncate
- ** the sub-journal to zero bytes in size. */
- if( nNew==0 && op==SAVEPOINT_RELEASE && isOpen(pPager->sjfd) ){
- assert( rc==SQLITE_OK );
- rc = sqlite3OsTruncate(pPager->sjfd, 0);
- pPager->nSubRec = 0;
- }
- }
- return rc;
-}
-
-/*
-** Return the full pathname of the database file.
-*/
-SQLITE_PRIVATE const char *sqlite3PagerFilename(Pager *pPager){
- return pPager->zFilename;
-}
-
-/*
-** Return the VFS structure for the pager.
-*/
-SQLITE_PRIVATE const sqlite3_vfs *sqlite3PagerVfs(Pager *pPager){
- return pPager->pVfs;
-}
-
-/*
-** Return the file handle for the database file associated
-** with the pager. This might return NULL if the file has
-** not yet been opened.
-*/
-SQLITE_PRIVATE sqlite3_file *sqlite3PagerFile(Pager *pPager){
- return pPager->fd;
-}
-
-/*
-** Return the full pathname of the journal file.
-*/
-SQLITE_PRIVATE const char *sqlite3PagerJournalname(Pager *pPager){
- return pPager->zJournal;
-}
-
-/*
-** Return true if fsync() calls are disabled for this pager. Return FALSE
-** if fsync()s are executed normally.
-*/
-SQLITE_PRIVATE int sqlite3PagerNosync(Pager *pPager){
- return pPager->noSync;
-}
-
-#ifdef SQLITE_HAS_CODEC
-/*
-** Set or retrieve the codec for this pager
-*/
-static void sqlite3PagerSetCodec(
- Pager *pPager,
- void *(*xCodec)(void*,void*,Pgno,int),
- void (*xCodecSizeChng)(void*,int,int),
- void (*xCodecFree)(void*),
- void *pCodec
-){
- if( pPager->xCodecFree ) pPager->xCodecFree(pPager->pCodec);
- pPager->xCodec = xCodec;
- pPager->xCodecSizeChng = xCodecSizeChng;
- pPager->xCodecFree = xCodecFree;
- pPager->pCodec = pCodec;
- pagerReportSize(pPager);
-}
-static void *sqlite3PagerGetCodec(Pager *pPager){
- return pPager->pCodec;
-}
-#endif
-
-#ifndef SQLITE_OMIT_AUTOVACUUM
-/*
-** Move the page pPg to location pgno in the file.
-**
-** There must be no references to the page previously located at
-** pgno (which we call pPgOld) though that page is allowed to be
-** in cache. If the page previously located at pgno is not already
-** in the rollback journal, it is not put there by by this routine.
-**
-** References to the page pPg remain valid. Updating any
-** meta-data associated with pPg (i.e. data stored in the nExtra bytes
-** allocated along with the page) is the responsibility of the caller.
-**
-** A transaction must be active when this routine is called. It used to be
-** required that a statement transaction was not active, but this restriction
-** has been removed (CREATE INDEX needs to move a page when a statement
-** transaction is active).
-**
-** If the fourth argument, isCommit, is non-zero, then this page is being
-** moved as part of a database reorganization just before the transaction
-** is being committed. In this case, it is guaranteed that the database page
-** pPg refers to will not be written to again within this transaction.
-**
-** This function may return SQLITE_NOMEM or an IO error code if an error
-** occurs. Otherwise, it returns SQLITE_OK.
-*/
-SQLITE_PRIVATE int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno, int isCommit){
- PgHdr *pPgOld; /* The page being overwritten. */
- Pgno needSyncPgno = 0; /* Old value of pPg->pgno, if sync is required */
- int rc; /* Return code */
- Pgno origPgno; /* The original page number */
-
- assert( pPg->nRef>0 );
-
- /* If the page being moved is dirty and has not been saved by the latest
- ** savepoint, then save the current contents of the page into the
- ** sub-journal now. This is required to handle the following scenario:
- **
- ** BEGIN;
- ** <journal page X, then modify it in memory>
- ** SAVEPOINT one;
- ** <Move page X to location Y>
- ** ROLLBACK TO one;
- **
- ** If page X were not written to the sub-journal here, it would not
- ** be possible to restore its contents when the "ROLLBACK TO one"
- ** statement were is processed.
- **
- ** subjournalPage() may need to allocate space to store pPg->pgno into
- ** one or more savepoint bitvecs. This is the reason this function
- ** may return SQLITE_NOMEM.
- */
- if( pPg->flags&PGHDR_DIRTY
- && subjRequiresPage(pPg)
- && SQLITE_OK!=(rc = subjournalPage(pPg))
- ){
- return rc;
- }
-
- PAGERTRACE(("MOVE %d page %d (needSync=%d) moves to %d\n",
- PAGERID(pPager), pPg->pgno, (pPg->flags&PGHDR_NEED_SYNC)?1:0, pgno));
- IOTRACE(("MOVE %p %d %d\n", pPager, pPg->pgno, pgno))
-
- /* If the journal needs to be sync()ed before page pPg->pgno can
- ** be written to, store pPg->pgno in local variable needSyncPgno.
- **
- ** If the isCommit flag is set, there is no need to remember that
- ** the journal needs to be sync()ed before database page pPg->pgno
- ** can be written to. The caller has already promised not to write to it.
- */
- if( (pPg->flags&PGHDR_NEED_SYNC) && !isCommit ){
- needSyncPgno = pPg->pgno;
- assert( pageInJournal(pPg) || pPg->pgno>pPager->dbOrigSize );
- assert( pPg->flags&PGHDR_DIRTY );
- assert( pPager->needSync );
- }
-
- /* If the cache contains a page with page-number pgno, remove it
- ** from its hash chain. Also, if the PgHdr.needSync was set for
- ** page pgno before the 'move' operation, it needs to be retained
- ** for the page moved there.
- */
- pPg->flags &= ~PGHDR_NEED_SYNC;
- pPgOld = pager_lookup(pPager, pgno);
- assert( !pPgOld || pPgOld->nRef==1 );
- if( pPgOld ){
- pPg->flags |= (pPgOld->flags&PGHDR_NEED_SYNC);
- sqlite3PcacheDrop(pPgOld);
- }
-
- origPgno = pPg->pgno;
- sqlite3PcacheMove(pPg, pgno);
- sqlite3PcacheMakeDirty(pPg);
- pPager->dbModified = 1;
-
- if( needSyncPgno ){
- /* If needSyncPgno is non-zero, then the journal file needs to be
- ** sync()ed before any data is written to database file page needSyncPgno.
- ** Currently, no such page exists in the page-cache and the
- ** "is journaled" bitvec flag has been set. This needs to be remedied by
- ** loading the page into the pager-cache and setting the PgHdr.needSync
- ** flag.
- **
- ** If the attempt to load the page into the page-cache fails, (due
- ** to a malloc() or IO failure), clear the bit in the pInJournal[]
- ** array. Otherwise, if the page is loaded and written again in
- ** this transaction, it may be written to the database file before
- ** it is synced into the journal file. This way, it may end up in
- ** the journal file twice, but that is not a problem.
- **
- ** The sqlite3PagerGet() call may cause the journal to sync. So make
- ** sure the Pager.needSync flag is set too.
- */
- PgHdr *pPgHdr;
- assert( pPager->needSync );
- rc = sqlite3PagerGet(pPager, needSyncPgno, &pPgHdr);
- if( rc!=SQLITE_OK ){
- if( needSyncPgno<=pPager->dbOrigSize ){
- assert( pPager->pTmpSpace!=0 );
- sqlite3BitvecClear(pPager->pInJournal, needSyncPgno, pPager->pTmpSpace);
- }
- return rc;
- }
- pPager->needSync = 1;
- assert( pPager->noSync==0 && !MEMDB );
- pPgHdr->flags |= PGHDR_NEED_SYNC;
- sqlite3PcacheMakeDirty(pPgHdr);
- sqlite3PagerUnref(pPgHdr);
- }
-
- /*
- ** For an in-memory database, make sure the original page continues
- ** to exist, in case the transaction needs to roll back. We allocate
- ** the page now, instead of at rollback, because we can better deal
- ** with an out-of-memory error now. Ticket #3761.
- */
- if( MEMDB ){
- DbPage *pNew;
- rc = sqlite3PagerAcquire(pPager, origPgno, &pNew, 1);
- if( rc!=SQLITE_OK ){
- sqlite3PcacheMove(pPg, origPgno);
- return rc;
- }
- sqlite3PagerUnref(pNew);
- }
-
- return SQLITE_OK;
-}
-#endif
-
-/*
-** Return a pointer to the data for the specified page.
-*/
-SQLITE_PRIVATE void *sqlite3PagerGetData(DbPage *pPg){
- assert( pPg->nRef>0 || pPg->pPager->memDb );
- return pPg->pData;
-}
-
-/*
-** Return a pointer to the Pager.nExtra bytes of "extra" space
-** allocated along with the specified page.
-*/
-SQLITE_PRIVATE void *sqlite3PagerGetExtra(DbPage *pPg){
- return pPg->pExtra;
-}
-
-/*
-** Get/set the locking-mode for this pager. Parameter eMode must be one
-** of PAGER_LOCKINGMODE_QUERY, PAGER_LOCKINGMODE_NORMAL or
-** PAGER_LOCKINGMODE_EXCLUSIVE. If the parameter is not _QUERY, then
-** the locking-mode is set to the value specified.
-**
-** The returned value is either PAGER_LOCKINGMODE_NORMAL or
-** PAGER_LOCKINGMODE_EXCLUSIVE, indicating the current (possibly updated)
-** locking-mode.
-*/
-SQLITE_PRIVATE int sqlite3PagerLockingMode(Pager *pPager, int eMode){
- assert( eMode==PAGER_LOCKINGMODE_QUERY
- || eMode==PAGER_LOCKINGMODE_NORMAL
- || eMode==PAGER_LOCKINGMODE_EXCLUSIVE );
- assert( PAGER_LOCKINGMODE_QUERY<0 );
- assert( PAGER_LOCKINGMODE_NORMAL>=0 && PAGER_LOCKINGMODE_EXCLUSIVE>=0 );
- if( eMode>=0 && !pPager->tempFile ){
- pPager->exclusiveMode = (u8)eMode;
- }
- return (int)pPager->exclusiveMode;
-}
-
-/*
-** Get/set the journal-mode for this pager. Parameter eMode must be one of:
-**
-** PAGER_JOURNALMODE_QUERY
-** PAGER_JOURNALMODE_DELETE
-** PAGER_JOURNALMODE_TRUNCATE
-** PAGER_JOURNALMODE_PERSIST
-** PAGER_JOURNALMODE_OFF
-** PAGER_JOURNALMODE_MEMORY
-**
-** If the parameter is not _QUERY, then the journal_mode is set to the
-** value specified if the change is allowed. The change is disallowed
-** for the following reasons:
-**
-** * An in-memory database can only have its journal_mode set to _OFF
-** or _MEMORY.
-**
-** * The journal mode may not be changed while a transaction is active.
-**
-** The returned indicate the current (possibly updated) journal-mode.
-*/
-SQLITE_PRIVATE int sqlite3PagerJournalMode(Pager *pPager, int eMode){
- assert( eMode==PAGER_JOURNALMODE_QUERY
- || eMode==PAGER_JOURNALMODE_DELETE
- || eMode==PAGER_JOURNALMODE_TRUNCATE
- || eMode==PAGER_JOURNALMODE_PERSIST
- || eMode==PAGER_JOURNALMODE_OFF
- || eMode==PAGER_JOURNALMODE_MEMORY );
- assert( PAGER_JOURNALMODE_QUERY<0 );
- if( eMode>=0
- && (!MEMDB || eMode==PAGER_JOURNALMODE_MEMORY
- || eMode==PAGER_JOURNALMODE_OFF)
- && !pPager->dbModified
- && (!isOpen(pPager->jfd) || 0==pPager->journalOff)
- ){
- if( isOpen(pPager->jfd) ){
- sqlite3OsClose(pPager->jfd);
- }
- pPager->journalMode = (u8)eMode;
- }
- return (int)pPager->journalMode;
-}
-
-/*
-** Get/set the size-limit used for persistent journal files.
-**
-** Setting the size limit to -1 means no limit is enforced.
-** An attempt to set a limit smaller than -1 is a no-op.
-*/
-SQLITE_PRIVATE i64 sqlite3PagerJournalSizeLimit(Pager *pPager, i64 iLimit){
- if( iLimit>=-1 ){
- pPager->journalSizeLimit = iLimit;
- }
- return pPager->journalSizeLimit;
-}
-
-/*
-** Return a pointer to the pPager->pBackup variable. The backup module
-** in backup.c maintains the content of this variable. This module
-** uses it opaquely as an argument to sqlite3BackupRestart() and
-** sqlite3BackupUpdate() only.
-*/
-SQLITE_PRIVATE sqlite3_backup **sqlite3PagerBackupPtr(Pager *pPager){
- return &pPager->pBackup;
-}
-
-#endif /* SQLITE_OMIT_DISKIO */
-
-/************** End of pager.c ***********************************************/
-/************** Begin file btmutex.c *****************************************/
-/*
-** 2007 August 27
-**
-** 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.
-**
-*************************************************************************
-**
-** $Id: btmutex.c,v 1.17 2009/07/20 12:33:33 drh Exp $
-**
-** This file contains code used to implement mutexes on Btree objects.
-** This code really belongs in btree.c. But btree.c is getting too
-** big and we want to break it down some. This packaged seemed like
-** a good breakout.
-*/
-/************** Include btreeInt.h in the middle of btmutex.c ****************/
-/************** Begin file btreeInt.h ****************************************/
-/*
-** 2004 April 6
-**
-** 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.
-**
-*************************************************************************
-** $Id: btreeInt.h,v 1.52 2009/07/15 17:25:46 drh Exp $
-**
-** This file implements a external (disk-based) database using BTrees.
-** For a detailed discussion of BTrees, refer to
-**
-** Donald E. Knuth, THE ART OF COMPUTER PROGRAMMING, Volume 3:
-** "Sorting And Searching", pages 473-480. Addison-Wesley
-** Publishing Company, Reading, Massachusetts.
-**
-** The basic idea is that each page of the file contains N database
-** entries and N+1 pointers to subpages.
-**
-** ----------------------------------------------------------------
-** | Ptr(0) | Key(0) | Ptr(1) | Key(1) | ... | Key(N-1) | Ptr(N) |
-** ----------------------------------------------------------------
-**
-** All of the keys on the page that Ptr(0) points to have values less
-** than Key(0). All of the keys on page Ptr(1) and its subpages have
-** values greater than Key(0) and less than Key(1). All of the keys
-** on Ptr(N) and its subpages have values greater than Key(N-1). And
-** so forth.
-**
-** Finding a particular key requires reading O(log(M)) pages from the
-** disk where M is the number of entries in the tree.
-**
-** In this implementation, a single file can hold one or more separate
-** BTrees. Each BTree is identified by the index of its root page. The
-** key and data for any entry are combined to form the "payload". A
-** fixed amount of payload can be carried directly on the database
-** page. If the payload is larger than the preset amount then surplus
-** bytes are stored on overflow pages. The payload for an entry
-** and the preceding pointer are combined to form a "Cell". Each
-** page has a small header which contains the Ptr(N) pointer and other
-** information such as the size of key and data.
-**
-** FORMAT DETAILS
-**
-** The file is divided into pages. The first page is called page 1,
-** the second is page 2, and so forth. A page number of zero indicates
-** "no such page". The page size can be anything between 512 and 65536.
-** Each page can be either a btree page, a freelist page or an overflow
-** page.
-**
-** The first page is always a btree page. The first 100 bytes of the first
-** page contain a special header (the "file header") that describes the file.
-** The format of the file header is as follows:
-**
-** OFFSET SIZE DESCRIPTION
-** 0 16 Header string: "SQLite format 3\000"
-** 16 2 Page size in bytes.
-** 18 1 File format write version
-** 19 1 File format read version
-** 20 1 Bytes of unused space at the end of each page
-** 21 1 Max embedded payload fraction
-** 22 1 Min embedded payload fraction
-** 23 1 Min leaf payload fraction
-** 24 4 File change counter
-** 28 4 Reserved for future use
-** 32 4 First freelist page
-** 36 4 Number of freelist pages in the file
-** 40 60 15 4-byte meta values passed to higher layers
-**
-** 40 4 Schema cookie
-** 44 4 File format of schema layer
-** 48 4 Size of page cache
-** 52 4 Largest root-page (auto/incr_vacuum)
-** 56 4 1=UTF-8 2=UTF16le 3=UTF16be
-** 60 4 User version
-** 64 4 Incremental vacuum mode
-** 68 4 unused
-** 72 4 unused
-** 76 4 unused
-**
-** All of the integer values are big-endian (most significant byte first).
-**
-** The file change counter is incremented when the database is changed
-** This counter allows other processes to know when the file has changed
-** and thus when they need to flush their cache.
-**
-** The max embedded payload fraction is the amount of the total usable
-** space in a page that can be consumed by a single cell for standard
-** B-tree (non-LEAFDATA) tables. A value of 255 means 100%. The default
-** is to limit the maximum cell size so that at least 4 cells will fit
-** on one page. Thus the default max embedded payload fraction is 64.
-**
-** If the payload for a cell is larger than the max payload, then extra
-** payload is spilled to overflow pages. Once an overflow page is allocated,
-** as many bytes as possible are moved into the overflow pages without letting
-** the cell size drop below the min embedded payload fraction.
-**
-** The min leaf payload fraction is like the min embedded payload fraction
-** except that it applies to leaf nodes in a LEAFDATA tree. The maximum
-** payload fraction for a LEAFDATA tree is always 100% (or 255) and it
-** not specified in the header.
-**
-** Each btree pages is divided into three sections: The header, the
-** cell pointer array, and the cell content area. Page 1 also has a 100-byte
-** file header that occurs before the page header.
-**
-** |----------------|
-** | file header | 100 bytes. Page 1 only.
-** |----------------|
-** | page header | 8 bytes for leaves. 12 bytes for interior nodes
-** |----------------|
-** | cell pointer | | 2 bytes per cell. Sorted order.
-** | array | | Grows downward
-** | | v
-** |----------------|
-** | unallocated |
-** | space |
-** |----------------| ^ Grows upwards
-** | cell content | | Arbitrary order interspersed with freeblocks.
-** | area | | and free space fragments.
-** |----------------|
-**
-** The page headers looks like this:
-**
-** OFFSET SIZE DESCRIPTION
-** 0 1 Flags. 1: intkey, 2: zerodata, 4: leafdata, 8: leaf
-** 1 2 byte offset to the first freeblock
-** 3 2 number of cells on this page
-** 5 2 first byte of the cell content area
-** 7 1 number of fragmented free bytes
-** 8 4 Right child (the Ptr(N) value). Omitted on leaves.
-**
-** The flags define the format of this btree page. The leaf flag means that
-** this page has no children. The zerodata flag means that this page carries
-** only keys and no data. The intkey flag means that the key is a integer
-** which is stored in the key size entry of the cell header rather than in
-** the payload area.
-**
-** The cell pointer array begins on the first byte after the page header.
-** The cell pointer array contains zero or more 2-byte numbers which are
-** offsets from the beginning of the page to the cell content in the cell
-** content area. The cell pointers occur in sorted order. The system strives
-** to keep free space after the last cell pointer so that new cells can
-** be easily added without having to defragment the page.
-**
-** Cell content is stored at the very end of the page and grows toward the
-** beginning of the page.
-**
-** Unused space within the cell content area is collected into a linked list of
-** freeblocks. Each freeblock is at least 4 bytes in size. The byte offset
-** to the first freeblock is given in the header. Freeblocks occur in
-** increasing order. Because a freeblock must be at least 4 bytes in size,
-** any group of 3 or fewer unused bytes in the cell content area cannot
-** exist on the freeblock chain. A group of 3 or fewer free bytes is called
-** a fragment. The total number of bytes in all fragments is recorded.
-** in the page header at offset 7.
-**
-** SIZE DESCRIPTION
-** 2 Byte offset of the next freeblock
-** 2 Bytes in this freeblock
-**
-** Cells are of variable length. Cells are stored in the cell content area at
-** the end of the page. Pointers to the cells are in the cell pointer array
-** that immediately follows the page header. Cells is not necessarily
-** contiguous or in order, but cell pointers are contiguous and in order.
-**
-** Cell content makes use of variable length integers. A variable
-** length integer is 1 to 9 bytes where the lower 7 bits of each
-** byte are used. The integer consists of all bytes that have bit 8 set and
-** the first byte with bit 8 clear. The most significant byte of the integer
-** appears first. A variable-length integer may not be more than 9 bytes long.
-** As a special case, all 8 bytes of the 9th byte are used as data. This
-** allows a 64-bit integer to be encoded in 9 bytes.
-**
-** 0x00 becomes 0x00000000
-** 0x7f becomes 0x0000007f
-** 0x81 0x00 becomes 0x00000080
-** 0x82 0x00 becomes 0x00000100
-** 0x80 0x7f becomes 0x0000007f
-** 0x8a 0x91 0xd1 0xac 0x78 becomes 0x12345678
-** 0x81 0x81 0x81 0x81 0x01 becomes 0x10204081
-**
-** Variable length integers are used for rowids and to hold the number of
-** bytes of key and data in a btree cell.
-**
-** The content of a cell looks like this:
-**
-** SIZE DESCRIPTION
-** 4 Page number of the left child. Omitted if leaf flag is set.
-** var Number of bytes of data. Omitted if the zerodata flag is set.
-** var Number of bytes of key. Or the key itself if intkey flag is set.
-** * Payload
-** 4 First page of the overflow chain. Omitted if no overflow
-**
-** Overflow pages form a linked list. Each page except the last is completely
-** filled with data (pagesize - 4 bytes). The last page can have as little
-** as 1 byte of data.
-**
-** SIZE DESCRIPTION
-** 4 Page number of next overflow page
-** * Data
-**
-** Freelist pages come in two subtypes: trunk pages and leaf pages. The
-** file header points to the first in a linked list of trunk page. Each trunk
-** page points to multiple leaf pages. The content of a leaf page is
-** unspecified. A trunk page looks like this:
-**
-** SIZE DESCRIPTION
-** 4 Page number of next trunk page
-** 4 Number of leaf pointers on this page
-** * zero or more pages numbers of leaves
-*/
-
-
-/* The following value is the maximum cell size assuming a maximum page
-** size give above.
-*/
-#define MX_CELL_SIZE(pBt) (pBt->pageSize-8)
-
-/* The maximum number of cells on a single page of the database. This
-** assumes a minimum cell size of 6 bytes (4 bytes for the cell itself
-** plus 2 bytes for the index to the cell in the page header). Such
-** small cells will be rare, but they are possible.
-*/
-#define MX_CELL(pBt) ((pBt->pageSize-8)/6)
-
-/* Forward declarations */
-typedef struct MemPage MemPage;
-typedef struct BtLock BtLock;
-
-/*
-** This is a magic string that appears at the beginning of every
-** SQLite database in order to identify the file as a real database.
-**
-** You can change this value at compile-time by specifying a
-** -DSQLITE_FILE_HEADER="..." on the compiler command-line. The
-** header must be exactly 16 bytes including the zero-terminator so
-** the string itself should be 15 characters long. If you change
-** the header, then your custom library will not be able to read
-** databases generated by the standard tools and the standard tools
-** will not be able to read databases created by your custom library.
-*/
-#ifndef SQLITE_FILE_HEADER /* 123456789 123456 */
-# define SQLITE_FILE_HEADER "SQLite format 3"
-#endif
-
-/*
-** Page type flags. An ORed combination of these flags appear as the
-** first byte of on-disk image of every BTree page.
-*/
-#define PTF_INTKEY 0x01
-#define PTF_ZERODATA 0x02
-#define PTF_LEAFDATA 0x04
-#define PTF_LEAF 0x08
-
-/*
-** As each page of the file is loaded into memory, an instance of the following
-** structure is appended and initialized to zero. This structure stores
-** information about the page that is decoded from the raw file page.
-**
-** The pParent field points back to the parent page. This allows us to
-** walk up the BTree from any leaf to the root. Care must be taken to
-** unref() the parent page pointer when this page is no longer referenced.
-** The pageDestructor() routine handles that chore.
-**
-** Access to all fields of this structure is controlled by the mutex
-** stored in MemPage.pBt->mutex.
-*/
-struct MemPage {
- u8 isInit; /* True if previously initialized. MUST BE FIRST! */
- u8 nOverflow; /* Number of overflow cell bodies in aCell[] */
- u8 intKey; /* True if intkey flag is set */
- u8 leaf; /* True if leaf flag is set */
- 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 */
- 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 */
- u16 nFree; /* Number of free bytes on the page */
- u16 nCell; /* Number of cells on this page, local and ovfl */
- u16 maskPage; /* Mask for page offset */
- struct _OvflCell { /* Cells that will not fit on aData[] */
- u8 *pCell; /* Pointers to the body of the overflow cell */
- u16 idx; /* Insert this cell before idx-th non-overflow cell */
- } aOvfl[5];
- BtShared *pBt; /* Pointer to BtShared that this page is part of */
- u8 *aData; /* Pointer to disk image of the page data */
- DbPage *pDbPage; /* Pager page handle */
- Pgno pgno; /* Page number for this page */
-};
-
-/*
-** The in-memory image of a disk page has the auxiliary information appended
-** to the end. EXTRA_SIZE is the number of bytes of space needed to hold
-** that extra information.
-*/
-#define EXTRA_SIZE sizeof(MemPage)
-
-/*
-** A linked list of the following structures is stored at BtShared.pLock.
-** Locks are added (or upgraded from READ_LOCK to WRITE_LOCK) when a cursor
-** is opened on the table with root page BtShared.iTable. Locks are removed
-** from this list when a transaction is committed or rolled back, or when
-** a btree handle is closed.
-*/
-struct BtLock {
- Btree *pBtree; /* Btree handle holding this lock */
- Pgno iTable; /* Root page of table */
- u8 eLock; /* READ_LOCK or WRITE_LOCK */
- BtLock *pNext; /* Next in BtShared.pLock list */
-};
-
-/* Candidate values for BtLock.eLock */
-#define READ_LOCK 1
-#define WRITE_LOCK 2
-
-/* A Btree handle
-**
-** A database connection contains a pointer to an instance of
-** this object for every database file that it has open. This structure
-** is opaque to the database connection. The database connection cannot
-** see the internals of this structure and only deals with pointers to
-** this structure.
-**
-** For some database files, the same underlying database cache might be
-** shared between multiple connections. In that case, each contection
-** has it own pointer to this object. But each instance of this object
-** points to the same BtShared object. The database cache and the
-** schema associated with the database file are all contained within
-** the BtShared object.
-**
-** All fields in this structure are accessed under sqlite3.mutex.
-** The pBt pointer itself may not be changed while there exists cursors
-** in the referenced BtShared that point back to this Btree since those
-** cursors have to do go through this Btree to find their BtShared and
-** they often do so without holding sqlite3.mutex.
-*/
-struct Btree {
- sqlite3 *db; /* The database connection holding this btree */
- BtShared *pBt; /* Sharable content of this btree */
- u8 inTrans; /* TRANS_NONE, TRANS_READ or TRANS_WRITE */
- u8 sharable; /* True if we can share pBt with another db */
- u8 locked; /* True if db currently has pBt locked */
- int wantToLock; /* Number of nested calls to sqlite3BtreeEnter() */
- int nBackup; /* Number of backup operations reading this btree */
- Btree *pNext; /* List of other sharable Btrees from the same db */
- Btree *pPrev; /* Back pointer of the same list */
-#ifndef SQLITE_OMIT_SHARED_CACHE
- BtLock lock; /* Object used to lock page 1 */
-#endif
-};
-
-/*
-** Btree.inTrans may take one of the following values.
-**
-** If the shared-data extension is enabled, there may be multiple users
-** of the Btree structure. At most one of these may open a write transaction,
-** but any number may have active read transactions.
-*/
-#define TRANS_NONE 0
-#define TRANS_READ 1
-#define TRANS_WRITE 2
-
-/*
-** An instance of this object represents a single database file.
-**
-** A single database file can be in use as 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
-** to this one BtShared object. BtShared.nRef is the number of
-** connections currently sharing this database file.
-**
-** Fields in this structure are accessed under the BtShared.mutex
-** mutex, except for nRef and pNext which are accessed under the
-** global SQLITE_MUTEX_STATIC_MASTER mutex. The pPager field
-** may not be modified once it is initially set as long as nRef>0.
-** The pSchema field may be set once under BtShared.mutex and
-** thereafter is unchanged as long as nRef>0.
-**
-** isPending:
-**
-** If a BtShared client fails to obtain a write-lock on a database
-** table (because there exists one or more read-locks on the table),
-** the shared-cache enters 'pending-lock' state and isPending is
-** set to true.
-**
-** The shared-cache leaves the 'pending lock' state when either of
-** the following occur:
-**
-** 1) The current writer (BtShared.pWriter) concludes its transaction, OR
-** 2) The number of locks held by other connections drops to zero.
-**
-** while in the 'pending-lock' state, no connection may start a new
-** transaction.
-**
-** This feature is included to help prevent writer-starvation.
-*/
-struct BtShared {
- Pager *pPager; /* The page cache */
- 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 */
-#ifndef SQLITE_OMIT_AUTOVACUUM
- u8 autoVacuum; /* True if auto-vacuum is enabled */
- u8 incrVacuum; /* True if incr-vacuum is enabled */
-#endif
- u16 pageSize; /* Total number of bytes on a page */
- u16 usableSize; /* Number of usable bytes on each page */
- 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 */
- u16 minLeaf; /* Minimum local payload in a LEAFDATA table */
- u8 inTransaction; /* Transaction state */
- int nTransaction; /* Number of open transactions (read + write) */
- void *pSchema; /* Pointer to space allocated by sqlite3BtreeSchema() */
- void (*xFreeSchema)(void*); /* Destructor for BtShared.pSchema */
- sqlite3_mutex *mutex; /* Non-recursive mutex required to access this struct */
- Bitvec *pHasContent; /* Set of pages moved to free-list this transaction */
-#ifndef SQLITE_OMIT_SHARED_CACHE
- int nRef; /* Number of references to this structure */
- 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 */
-};
-
-/*
-** An instance of the following structure is used to hold information
-** about a cell. The parseCellPtr() function fills in this structure
-** based on information extract from the raw disk page.
-*/
-typedef struct CellInfo CellInfo;
-struct CellInfo {
- u8 *pCell; /* Pointer to the start of cell content */
- i64 nKey; /* The key for INTKEY tables, or number of bytes in key */
- u32 nData; /* Number of bytes of data */
- u32 nPayload; /* Total amount of payload */
- u16 nHeader; /* Size of the cell content header in bytes */
- u16 nLocal; /* Amount of payload held locally */
- u16 iOverflow; /* Offset to overflow page number. Zero if no overflow */
- u16 nSize; /* Size of the cell content on the main b-tree page */
-};
-
-/*
-** Maximum depth of an SQLite B-Tree structure. Any B-Tree deeper than
-** this will be declared corrupt. This value is calculated based on a
-** maximum database size of 2^31 pages a minimum fanout of 2 for a
-** root-node and 3 for all other internal nodes.
-**
-** If a tree that appears to be taller than this is encountered, it is
-** assumed that the database is corrupt.
-*/
-#define BTCURSOR_MAX_DEPTH 20
-
-/*
-** A cursor is a pointer to a particular entry within a particular
-** b-tree within a database file.
-**
-** The entry is identified by its MemPage and the index in
-** MemPage.aCell[] of the entry.
-**
-** When a single database file can shared by two more database connections,
-** but cursors cannot be shared. Each cursor is associated with a
-** particular database connection identified BtCursor.pBtree.db.
-**
-** Fields in this structure are accessed under the BtShared.mutex
-** found at self->pBt->mutex.
-*/
-struct BtCursor {
- Btree *pBtree; /* The Btree to which this cursor belongs */
- BtShared *pBt; /* The BtShared this cursor points to */
- BtCursor *pNext, *pPrev; /* Forms a linked list of all cursors */
- struct KeyInfo *pKeyInfo; /* Argument passed to comparison function */
- Pgno pgnoRoot; /* The root page of this tree */
- sqlite3_int64 cachedRowid; /* Next rowid cache. 0 means not valid */
- CellInfo info; /* A parse of the cell we are pointing at */
- u8 wrFlag; /* True if writable */
- u8 atLast; /* Cursor pointing to the last entry */
- u8 validNKey; /* True if info.nKey is valid */
- u8 eState; /* One of the CURSOR_XXX constants (see below) */
- void *pKey; /* Saved key that was cursor's last known position */
- i64 nKey; /* Size of pKey, or last integer key */
- int skipNext; /* Prev() is noop if negative. Next() is noop if positive */
-#ifndef SQLITE_OMIT_INCRBLOB
- u8 isIncrblobHandle; /* True if this cursor is an incr. io handle */
- Pgno *aOverflow; /* Cache of overflow page locations */
-#endif
- i16 iPage; /* Index of current page in apPage */
- MemPage *apPage[BTCURSOR_MAX_DEPTH]; /* Pages from root to current page */
- u16 aiIdx[BTCURSOR_MAX_DEPTH]; /* Current index in apPage[i] */
-};
-
-/*
-** Potential values for BtCursor.eState.
-**
-** CURSOR_VALID:
-** Cursor points to a valid entry. getPayload() etc. may be called.
-**
-** CURSOR_INVALID:
-** Cursor does not point to a valid entry. This can happen (for example)
-** because the table is empty or because BtreeCursorFirst() has not been
-** called.
-**
-** CURSOR_REQUIRESEEK:
-** The table that this cursor was opened on still exists, but has been
-** modified since the cursor was last used. The cursor position is saved
-** in variables BtCursor.pKey and BtCursor.nKey. When a cursor is in
-** this state, restoreCursorPosition() can be called to attempt to
-** seek the cursor to the saved position.
-**
-** CURSOR_FAULT:
-** A unrecoverable error (an I/O error or a malloc failure) has occurred
-** on a different connection that shares the BtShared cache with this
-** cursor. The error has left the cache in an inconsistent state.
-** Do nothing else with this cursor. Any attempt to use the cursor
-** should return the error code stored in BtCursor.skip
-*/
-#define CURSOR_INVALID 0
-#define CURSOR_VALID 1
-#define CURSOR_REQUIRESEEK 2
-#define CURSOR_FAULT 3
-
-/*
-** The database page the PENDING_BYTE occupies. This page is never used.
-*/
-# define PENDING_BYTE_PAGE(pBt) PAGER_MJ_PGNO(pBt)
-
-/*
-** These macros define the location of the pointer-map entry for a
-** database page. The first argument to each is the number of usable
-** bytes on each page of the database (often 1024). The second is the
-** page number to look up in the pointer map.
-**
-** PTRMAP_PAGENO returns the database page number of the pointer-map
-** page that stores the required pointer. PTRMAP_PTROFFSET returns
-** the offset of the requested map entry.
-**
-** If the pgno argument passed to PTRMAP_PAGENO is a pointer-map page,
-** then pgno is returned. So (pgno==PTRMAP_PAGENO(pgsz, pgno)) can be
-** used to test if pgno is a pointer-map page. PTRMAP_ISPAGE implements
-** this test.
-*/
-#define PTRMAP_PAGENO(pBt, pgno) ptrmapPageno(pBt, pgno)
-#define PTRMAP_PTROFFSET(pgptrmap, pgno) (5*(pgno-pgptrmap-1))
-#define PTRMAP_ISPAGE(pBt, pgno) (PTRMAP_PAGENO((pBt),(pgno))==(pgno))
-
-/*
-** The pointer map is a lookup table that identifies the parent page for
-** each child page in the database file. The parent page is the page that
-** contains a pointer to the child. Every page in the database contains
-** 0 or 1 parent pages. (In this context 'database page' refers
-** to any page that is not part of the pointer map itself.) Each pointer map
-** entry consists of a single byte 'type' and a 4 byte parent page number.
-** The PTRMAP_XXX identifiers below are the valid types.
-**
-** The purpose of the pointer map is to facility moving pages from one
-** position in the file to another as part of autovacuum. When a page
-** is moved, the pointer in its parent must be updated to point to the
-** new location. The pointer map is used to locate the parent page quickly.
-**
-** PTRMAP_ROOTPAGE: The database page is a root-page. The page-number is not
-** used in this case.
-**
-** PTRMAP_FREEPAGE: The database page is an unused (free) page. The page-number
-** is not used in this case.
-**
-** PTRMAP_OVERFLOW1: The database page is the first page in a list of
-** overflow pages. The page number identifies the page that
-** contains the cell with a pointer to this overflow page.
-**
-** PTRMAP_OVERFLOW2: The database page is the second or later page in a list of
-** overflow pages. The page-number identifies the previous
-** page in the overflow page list.
-**
-** PTRMAP_BTREE: The database page is a non-root btree page. The page number
-** identifies the parent page in the btree.
-*/
-#define PTRMAP_ROOTPAGE 1
-#define PTRMAP_FREEPAGE 2
-#define PTRMAP_OVERFLOW1 3
-#define PTRMAP_OVERFLOW2 4
-#define PTRMAP_BTREE 5
-
-/* A bunch of assert() statements to check the transaction state variables
-** of handle p (type Btree*) are internally consistent.
-*/
-#define btreeIntegrity(p) \
- assert( p->pBt->inTransaction!=TRANS_NONE || p->pBt->nTransaction==0 ); \
- assert( p->pBt->inTransaction>=p->inTrans );
-
-
-/*
-** The ISAUTOVACUUM macro is used within balance_nonroot() to determine
-** if the database supports auto-vacuum or not. Because it is used
-** within an expression that is an argument to another macro
-** (sqliteMallocRaw), it is not possible to use conditional compilation.
-** So, this macro is defined instead.
-*/
-#ifndef SQLITE_OMIT_AUTOVACUUM
-#define ISAUTOVACUUM (pBt->autoVacuum)
-#else
-#define ISAUTOVACUUM 0
-#endif
-
-
-/*
-** This structure is passed around through all the sanity checking routines
-** in order to keep track of some global state information.
-*/
-typedef struct IntegrityCk IntegrityCk;
-struct IntegrityCk {
- BtShared *pBt; /* The tree being checked out */
- Pager *pPager; /* The associated pager. Also accessible by pBt->pPager */
- Pgno nPage; /* Number of pages in the database */
- int *anRef; /* Number of times each page is referenced */
- int mxErr; /* Stop accumulating errors when this reaches zero */
- int nErr; /* Number of messages written to zErrMsg so far */
- int mallocFailed; /* A memory allocation error has occurred */
- StrAccum errMsg; /* Accumulate the error message text here */
-};
-
-/*
-** 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))
-#define get4byte sqlite3Get4byte
-#define put4byte sqlite3Put4byte
-
-/************** End of btreeInt.h ********************************************/
-/************** Continuing where we left off in btmutex.c ********************/
-#ifndef SQLITE_OMIT_SHARED_CACHE
-#if SQLITE_THREADSAFE
-
-/*
-** Obtain the BtShared mutex associated with B-Tree handle p. Also,
-** set BtShared.db to the database handle associated with p and the
-** p->locked boolean to true.
-*/
-static void lockBtreeMutex(Btree *p){
- assert( p->locked==0 );
- assert( sqlite3_mutex_notheld(p->pBt->mutex) );
- assert( sqlite3_mutex_held(p->db->mutex) );
-
- sqlite3_mutex_enter(p->pBt->mutex);
- p->pBt->db = p->db;
- p->locked = 1;
-}
-
-/*
-** Release the BtShared mutex associated with B-Tree handle p and
-** clear the p->locked boolean.
-*/
-static void unlockBtreeMutex(Btree *p){
- assert( p->locked==1 );
- assert( sqlite3_mutex_held(p->pBt->mutex) );
- assert( sqlite3_mutex_held(p->db->mutex) );
- assert( p->db==p->pBt->db );
-
- sqlite3_mutex_leave(p->pBt->mutex);
- p->locked = 0;
-}
-
-/*
-** Enter a mutex on the given BTree object.
-**
-** If the object is not sharable, then no mutex is ever required
-** and this routine is a no-op. The underlying mutex is non-recursive.
-** But we keep a reference count in Btree.wantToLock so the behavior
-** of this interface is recursive.
-**
-** To avoid deadlocks, multiple Btrees are locked in the same order
-** by all database connections. The p->pNext is a list of other
-** Btrees belonging to the same database connection as the p Btree
-** which need to be locked after p. If we cannot get a lock on
-** p, then first unlock all of the others on p->pNext, then wait
-** for the lock to become available on p, then relock all of the
-** subsequent Btrees that desire a lock.
-*/
-SQLITE_PRIVATE void sqlite3BtreeEnter(Btree *p){
- Btree *pLater;
-
- /* Some basic sanity checking on the Btree. The list of Btrees
- ** connected by pNext and pPrev should be in sorted order by
- ** Btree.pBt value. All elements of the list should belong to
- ** the same connection. Only shared Btrees are on the list. */
- assert( p->pNext==0 || p->pNext->pBt>p->pBt );
- assert( p->pPrev==0 || p->pPrev->pBt<p->pBt );
- assert( p->pNext==0 || p->pNext->db==p->db );
- assert( p->pPrev==0 || p->pPrev->db==p->db );
- assert( p->sharable || (p->pNext==0 && p->pPrev==0) );
-
- /* Check for locking consistency */
- assert( !p->locked || p->wantToLock>0 );
- assert( p->sharable || p->wantToLock==0 );
-
- /* We should already hold a lock on the database connection */
- assert( sqlite3_mutex_held(p->db->mutex) );
-
- /* Unless the database is sharable and unlocked, then BtShared.db
- ** should already be set correctly. */
- assert( (p->locked==0 && p->sharable) || p->pBt->db==p->db );
-
- if( !p->sharable ) return;
- p->wantToLock++;
- if( p->locked ) return;
-
- /* In most cases, we should be able to acquire the lock we
- ** want without having to go throught the ascending lock
- ** procedure that follows. Just be sure not to block.
- */
- if( sqlite3_mutex_try(p->pBt->mutex)==SQLITE_OK ){
- p->pBt->db = p->db;
- p->locked = 1;
- return;
- }
-
- /* To avoid deadlock, first release all locks with a larger
- ** BtShared address. Then acquire our lock. Then reacquire
- ** the other BtShared locks that we used to hold in ascending
- ** order.
- */
- for(pLater=p->pNext; pLater; pLater=pLater->pNext){
- assert( pLater->sharable );
- assert( pLater->pNext==0 || pLater->pNext->pBt>pLater->pBt );
- assert( !pLater->locked || pLater->wantToLock>0 );
- if( pLater->locked ){
- unlockBtreeMutex(pLater);
- }
- }
- lockBtreeMutex(p);
- for(pLater=p->pNext; pLater; pLater=pLater->pNext){
- if( pLater->wantToLock ){
- lockBtreeMutex(pLater);
- }
- }
-}
-
-/*
-** Exit the recursive mutex on a Btree.
-*/
-SQLITE_PRIVATE void sqlite3BtreeLeave(Btree *p){
- if( p->sharable ){
- assert( p->wantToLock>0 );
- p->wantToLock--;
- if( p->wantToLock==0 ){
- unlockBtreeMutex(p);
- }
- }
-}
-
-#ifndef NDEBUG
-/*
-** Return true if the BtShared mutex is held on the btree, or if the
-** B-Tree is not marked as sharable.
-**
-** This routine is used only from within assert() statements.
-*/
-SQLITE_PRIVATE int sqlite3BtreeHoldsMutex(Btree *p){
- assert( p->sharable==0 || p->locked==0 || p->wantToLock>0 );
- assert( p->sharable==0 || p->locked==0 || p->db==p->pBt->db );
- assert( p->sharable==0 || p->locked==0 || sqlite3_mutex_held(p->pBt->mutex) );
- assert( p->sharable==0 || p->locked==0 || sqlite3_mutex_held(p->db->mutex) );
-
- return (p->sharable==0 || p->locked);
-}
-#endif
-
-
-#ifndef SQLITE_OMIT_INCRBLOB
-/*
-** Enter and leave a mutex on a Btree given a cursor owned by that
-** Btree. These entry points are used by incremental I/O and can be
-** omitted if that module is not used.
-*/
-SQLITE_PRIVATE void sqlite3BtreeEnterCursor(BtCursor *pCur){
- sqlite3BtreeEnter(pCur->pBtree);
-}
-SQLITE_PRIVATE void sqlite3BtreeLeaveCursor(BtCursor *pCur){
- sqlite3BtreeLeave(pCur->pBtree);
-}
-#endif /* SQLITE_OMIT_INCRBLOB */
-
-
-/*
-** Enter the mutex on every Btree associated with a database
-** connection. This is needed (for example) prior to parsing
-** a statement since we will be comparing table and column names
-** against all schemas and we do not want those schemas being
-** reset out from under us.
-**
-** There is a corresponding leave-all procedures.
-**
-** Enter the mutexes in accending order by BtShared pointer address
-** to avoid the possibility of deadlock when two threads with
-** two or more btrees in common both try to lock all their btrees
-** at the same instant.
-*/
-SQLITE_PRIVATE void sqlite3BtreeEnterAll(sqlite3 *db){
- int i;
- Btree *p, *pLater;
- assert( sqlite3_mutex_held(db->mutex) );
- for(i=0; i<db->nDb; i++){
- p = db->aDb[i].pBt;
- assert( !p || (p->locked==0 && p->sharable) || p->pBt->db==p->db );
- if( p && p->sharable ){
- p->wantToLock++;
- if( !p->locked ){
- assert( p->wantToLock==1 );
- while( p->pPrev ) p = p->pPrev;
- /* Reason for ALWAYS: There must be at least on unlocked Btree in
- ** the chain. Otherwise the !p->locked test above would have failed */
- while( p->locked && ALWAYS(p->pNext) ) p = p->pNext;
- for(pLater = p->pNext; pLater; pLater=pLater->pNext){
- if( pLater->locked ){
- unlockBtreeMutex(pLater);
- }
- }
- while( p ){
- lockBtreeMutex(p);
- p = p->pNext;
- }
- }
- }
- }
-}
-SQLITE_PRIVATE void sqlite3BtreeLeaveAll(sqlite3 *db){
- int i;
- Btree *p;
- assert( sqlite3_mutex_held(db->mutex) );
- for(i=0; i<db->nDb; i++){
- p = db->aDb[i].pBt;
- if( p && p->sharable ){
- assert( p->wantToLock>0 );
- p->wantToLock--;
- if( p->wantToLock==0 ){
- unlockBtreeMutex(p);
- }
- }
- }
-}
-
-#ifndef NDEBUG
-/*
-** Return true if the current thread holds the database connection
-** mutex and all required BtShared mutexes.
-**
-** This routine is used inside assert() statements only.
-*/
-SQLITE_PRIVATE int sqlite3BtreeHoldsAllMutexes(sqlite3 *db){
- int i;
- if( !sqlite3_mutex_held(db->mutex) ){
- return 0;
- }
- for(i=0; i<db->nDb; i++){
- Btree *p;
- p = db->aDb[i].pBt;
- if( p && p->sharable &&
- (p->wantToLock==0 || !sqlite3_mutex_held(p->pBt->mutex)) ){
- return 0;
- }
- }
- return 1;
-}
-#endif /* NDEBUG */
-
-/*
-** Add a new Btree pointer to a BtreeMutexArray.
-** if the pointer can possibly be shared with
-** another database connection.
-**
-** The pointers are kept in sorted order by pBtree->pBt. That
-** way when we go to enter all the mutexes, we can enter them
-** in order without every having to backup and retry and without
-** worrying about deadlock.
-**
-** The number of shared btrees will always be small (usually 0 or 1)
-** so an insertion sort is an adequate algorithm here.
-*/
-SQLITE_PRIVATE void sqlite3BtreeMutexArrayInsert(BtreeMutexArray *pArray, Btree *pBtree){
- int i, j;
- BtShared *pBt;
- if( pBtree==0 || pBtree->sharable==0 ) return;
-#ifndef NDEBUG
- {
- for(i=0; i<pArray->nMutex; i++){
- assert( pArray->aBtree[i]!=pBtree );
- }
- }
-#endif
- assert( pArray->nMutex>=0 );
- assert( pArray->nMutex<ArraySize(pArray->aBtree)-1 );
- pBt = pBtree->pBt;
- for(i=0; i<pArray->nMutex; i++){
- assert( pArray->aBtree[i]!=pBtree );
- if( pArray->aBtree[i]->pBt>pBt ){
- for(j=pArray->nMutex; j>i; j--){
- pArray->aBtree[j] = pArray->aBtree[j-1];
- }
- pArray->aBtree[i] = pBtree;
- pArray->nMutex++;
- return;
- }
- }
- pArray->aBtree[pArray->nMutex++] = pBtree;
-}
-
-/*
-** Enter the mutex of every btree in the array. This routine is
-** called at the beginning of sqlite3VdbeExec(). The mutexes are
-** exited at the end of the same function.
-*/
-SQLITE_PRIVATE void sqlite3BtreeMutexArrayEnter(BtreeMutexArray *pArray){
- int i;
- for(i=0; i<pArray->nMutex; i++){
- Btree *p = pArray->aBtree[i];
- /* Some basic sanity checking */
- assert( i==0 || pArray->aBtree[i-1]->pBt<p->pBt );
- assert( !p->locked || p->wantToLock>0 );
-
- /* We should already hold a lock on the database connection */
- assert( sqlite3_mutex_held(p->db->mutex) );
-
- /* The Btree is sharable because only sharable Btrees are entered
- ** into the array in the first place. */
- assert( p->sharable );
-
- p->wantToLock++;
- if( !p->locked ){
- lockBtreeMutex(p);
- }
- }
-}
-
-/*
-** Leave the mutex of every btree in the group.
-*/
-SQLITE_PRIVATE void sqlite3BtreeMutexArrayLeave(BtreeMutexArray *pArray){
- int i;
- for(i=0; i<pArray->nMutex; i++){
- Btree *p = pArray->aBtree[i];
- /* Some basic sanity checking */
- assert( i==0 || pArray->aBtree[i-1]->pBt<p->pBt );
- assert( p->locked );
- assert( p->wantToLock>0 );
-
- /* We should already hold a lock on the database connection */
- assert( sqlite3_mutex_held(p->db->mutex) );
-
- p->wantToLock--;
- if( p->wantToLock==0 ){
- unlockBtreeMutex(p);
- }
- }
-}
-
-#else
-SQLITE_PRIVATE void sqlite3BtreeEnter(Btree *p){
- p->pBt->db = p->db;
-}
-SQLITE_PRIVATE void sqlite3BtreeEnterAll(sqlite3 *db){
- int i;
- for(i=0; i<db->nDb; i++){
- Btree *p = db->aDb[i].pBt;
- if( p ){
- p->pBt->db = p->db;
- }
- }
-}
-#endif /* if SQLITE_THREADSAFE */
-#endif /* ifndef SQLITE_OMIT_SHARED_CACHE */
-
-/************** End of btmutex.c *********************************************/
-/************** Begin file btree.c *******************************************/
-/*
-** 2004 April 6
-**
-** 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.
-**
-*************************************************************************
-** $Id: btree.c,v 1.705 2009/08/10 03:57:58 shane Exp $
-**
-** This file implements a external (disk-based) database using BTrees.
-** See the header comment on "btreeInt.h" for additional information.
-** Including a description of file format and an overview of operation.
-*/
-
-/*
-** The header string that appears at the beginning of every
-** SQLite database.
-*/
-static const char zMagicHeader[] = SQLITE_FILE_HEADER;
-
-/*
-** Set this global variable to 1 to enable tracing using the TRACE
-** macro.
-*/
-#if 0
-int sqlite3BtreeTrace=1; /* True to enable tracing */
-# define TRACE(X) if(sqlite3BtreeTrace){printf X;fflush(stdout);}
-#else
-# define TRACE(X)
-#endif
-
-
-
-#ifndef SQLITE_OMIT_SHARED_CACHE
-/*
-** A list of BtShared objects that are eligible for participation
-** in shared cache. This variable has file scope during normal builds,
-** but the test harness needs to access it so we make it global for
-** test builds.
-**
-** Access to this variable is protected by SQLITE_MUTEX_STATIC_MASTER.
-*/
-#ifdef SQLITE_TEST
-SQLITE_PRIVATE BtShared *SQLITE_WSD sqlite3SharedCacheList = 0;
-#else
-static BtShared *SQLITE_WSD sqlite3SharedCacheList = 0;
-#endif
-#endif /* SQLITE_OMIT_SHARED_CACHE */
-
-#ifndef SQLITE_OMIT_SHARED_CACHE
-/*
-** Enable or disable the shared pager and schema features.
-**
-** This routine has no effect on existing database connections.
-** The shared cache setting effects only future calls to
-** sqlite3_open(), sqlite3_open16(), or sqlite3_open_v2().
-*/
-SQLITE_API int sqlite3_enable_shared_cache(int enable){
- sqlite3GlobalConfig.sharedCacheEnabled = enable;
- return SQLITE_OK;
-}
-#endif
-
-
-
-#ifdef SQLITE_OMIT_SHARED_CACHE
- /*
- ** The functions querySharedCacheTableLock(), setSharedCacheTableLock(),
- ** and clearAllSharedCacheTableLocks()
- ** manipulate entries in the BtShared.pLock linked list used to store
- ** shared-cache table level locks. If the library is compiled with the
- ** shared-cache feature disabled, then there is only ever one user
- ** of each BtShared structure and so this locking is not necessary.
- ** So define the lock related functions as no-ops.
- */
- #define querySharedCacheTableLock(a,b,c) SQLITE_OK
- #define setSharedCacheTableLock(a,b,c) SQLITE_OK
- #define clearAllSharedCacheTableLocks(a)
- #define downgradeAllSharedCacheTableLocks(a)
- #define hasSharedCacheTableLock(a,b,c,d) 1
- #define hasReadConflicts(a, b) 0
-#endif
-
-#ifndef SQLITE_OMIT_SHARED_CACHE
-
-#ifdef SQLITE_DEBUG
-/*
-** This function is only used as part of an assert() statement. It checks
-** that connection p holds the required locks to read or write to the
-** b-tree with root page iRoot. If so, true is returned. Otherwise, false.
-** For example, when writing to a table b-tree with root-page iRoot via
-** Btree connection pBtree:
-**
-** assert( hasSharedCacheTableLock(pBtree, iRoot, 0, WRITE_LOCK) );
-**
-** When writing to an index b-tree that resides in a sharable database, the
-** caller should have first obtained a lock specifying the root page of
-** the corresponding table b-tree. This makes things a bit more complicated,
-** as this module treats each b-tree as a separate structure. To determine
-** the table b-tree corresponding to the index b-tree being written, this
-** function has to search through the database schema.
-**
-** Instead of a lock on the b-tree rooted at page iRoot, the caller may
-** hold a write-lock on the schema table (root page 1). This is also
-** acceptable.
-*/
-static int hasSharedCacheTableLock(
- Btree *pBtree, /* Handle that must hold lock */
- Pgno iRoot, /* Root page of b-tree */
- int isIndex, /* True if iRoot is the root of an index b-tree */
- int eLockType /* Required lock type (READ_LOCK or WRITE_LOCK) */
-){
- Schema *pSchema = (Schema *)pBtree->pBt->pSchema;
- Pgno iTab = 0;
- BtLock *pLock;
-
- /* If this b-tree database is not shareable, or if the client is reading
- ** and has the read-uncommitted flag set, then no lock is required.
- ** In these cases return true immediately. If the client is reading
- ** or writing an index b-tree, but the schema is not loaded, then return
- ** true also. In this case the lock is required, but it is too difficult
- ** to check if the client actually holds it. This doesn't happen very
- ** often. */
- if( (pBtree->sharable==0)
- || (eLockType==READ_LOCK && (pBtree->db->flags & SQLITE_ReadUncommitted))
- || (isIndex && (!pSchema || (pSchema->flags&DB_SchemaLoaded)==0 ))
- ){
- return 1;
- }
-
- /* Figure out the root-page that the lock should be held on. For table
- ** b-trees, this is just the root page of the b-tree being read or
- ** written. For index b-trees, it is the root page of the associated
- ** table. */
- if( isIndex ){
- HashElem *p;
- for(p=sqliteHashFirst(&pSchema->idxHash); p; p=sqliteHashNext(p)){
- Index *pIdx = (Index *)sqliteHashData(p);
- if( pIdx->tnum==(int)iRoot ){
- iTab = pIdx->pTable->tnum;
- }
- }
- }else{
- iTab = iRoot;
- }
-
- /* Search for the required lock. Either a write-lock on root-page iTab, a
- ** write-lock on the schema table, or (if the client is reading) a
- ** read-lock on iTab will suffice. Return 1 if any of these are found. */
- for(pLock=pBtree->pBt->pLock; pLock; pLock=pLock->pNext){
- if( pLock->pBtree==pBtree
- && (pLock->iTable==iTab || (pLock->eLock==WRITE_LOCK && pLock->iTable==1))
- && pLock->eLock>=eLockType
- ){
- return 1;
- }
- }
-
- /* Failed to find the required lock. */
- return 0;
-}
-
-/*
-** This function is also used as part of assert() statements only. It
-** returns true if there exist one or more cursors open on the table
-** with root page iRoot that do not belong to either connection pBtree
-** or some other connection that has the read-uncommitted flag set.
-**
-** For example, before writing to page iRoot:
-**
-** assert( !hasReadConflicts(pBtree, iRoot) );
-*/
-static int hasReadConflicts(Btree *pBtree, Pgno iRoot){
- BtCursor *p;
- for(p=pBtree->pBt->pCursor; p; p=p->pNext){
- if( p->pgnoRoot==iRoot
- && p->pBtree!=pBtree
- && 0==(p->pBtree->db->flags & SQLITE_ReadUncommitted)
- ){
- return 1;
- }
- }
- return 0;
-}
-#endif /* #ifdef SQLITE_DEBUG */
-
-/*
-** Query to see if btree handle p may obtain a lock of type eLock
-** (READ_LOCK or WRITE_LOCK) on the table with root-page iTab. Return
-** SQLITE_OK if the lock may be obtained (by calling
-** setSharedCacheTableLock()), or SQLITE_LOCKED if not.
-*/
-static int querySharedCacheTableLock(Btree *p, Pgno iTab, u8 eLock){
- BtShared *pBt = p->pBt;
- BtLock *pIter;
-
- assert( sqlite3BtreeHoldsMutex(p) );
- assert( eLock==READ_LOCK || eLock==WRITE_LOCK );
- assert( p->db!=0 );
- assert( !(p->db->flags&SQLITE_ReadUncommitted)||eLock==WRITE_LOCK||iTab==1 );
-
- /* If requesting a write-lock, then the Btree must have an open write
- ** transaction on this file. And, obviously, for this to be so there
- ** must be an open write transaction on the file itself.
- */
- assert( eLock==READ_LOCK || (p==pBt->pWriter && p->inTrans==TRANS_WRITE) );
- assert( eLock==READ_LOCK || pBt->inTransaction==TRANS_WRITE );
-
- /* This is a no-op if the shared-cache is not enabled */
- if( !p->sharable ){
- return SQLITE_OK;
- }
-
- /* If some other connection is holding an exclusive lock, the
- ** requested lock may not be obtained.
- */
- if( pBt->pWriter!=p && pBt->isExclusive ){
- sqlite3ConnectionBlocked(p->db, pBt->pWriter->db);
- return SQLITE_LOCKED_SHAREDCACHE;
- }
-
- for(pIter=pBt->pLock; pIter; pIter=pIter->pNext){
- /* The condition (pIter->eLock!=eLock) in the following if(...)
- ** statement is a simplification of:
- **
- ** (eLock==WRITE_LOCK || pIter->eLock==WRITE_LOCK)
- **
- ** since we know that if eLock==WRITE_LOCK, then no other connection
- ** may hold a WRITE_LOCK on any table in this file (since there can
- ** only be a single writer).
- */
- assert( pIter->eLock==READ_LOCK || pIter->eLock==WRITE_LOCK );
- assert( eLock==READ_LOCK || pIter->pBtree==p || pIter->eLock==READ_LOCK);
- if( pIter->pBtree!=p && pIter->iTable==iTab && pIter->eLock!=eLock ){
- sqlite3ConnectionBlocked(p->db, pIter->pBtree->db);
- if( eLock==WRITE_LOCK ){
- assert( p==pBt->pWriter );
- pBt->isPending = 1;
- }
- return SQLITE_LOCKED_SHAREDCACHE;
- }
- }
- return SQLITE_OK;
-}
-#endif /* !SQLITE_OMIT_SHARED_CACHE */
-
-#ifndef SQLITE_OMIT_SHARED_CACHE
-/*
-** Add a lock on the table with root-page iTable to the shared-btree used
-** by Btree handle p. Parameter eLock must be either READ_LOCK or
-** WRITE_LOCK.
-**
-** This function assumes the following:
-**
-** (a) The specified b-tree connection handle is connected to a sharable
-** b-tree database (one with the BtShared.sharable) flag set, and
-**
-** (b) No other b-tree connection handle holds a lock that conflicts
-** with the requested lock (i.e. querySharedCacheTableLock() has
-** already been called and returned SQLITE_OK).
-**
-** SQLITE_OK is returned if the lock is added successfully. SQLITE_NOMEM
-** is returned if a malloc attempt fails.
-*/
-static int setSharedCacheTableLock(Btree *p, Pgno iTable, u8 eLock){
- BtShared *pBt = p->pBt;
- BtLock *pLock = 0;
- BtLock *pIter;
-
- assert( sqlite3BtreeHoldsMutex(p) );
- assert( eLock==READ_LOCK || eLock==WRITE_LOCK );
- assert( p->db!=0 );
-
- /* A connection with the read-uncommitted flag set will never try to
- ** obtain a read-lock using this function. The only read-lock obtained
- ** by a connection in read-uncommitted mode is on the sqlite_master
- ** table, and that lock is obtained in BtreeBeginTrans(). */
- assert( 0==(p->db->flags&SQLITE_ReadUncommitted) || eLock==WRITE_LOCK );
-
- /* This function should only be called on a sharable b-tree after it
- ** has been determined that no other b-tree holds a conflicting lock. */
- assert( p->sharable );
- assert( SQLITE_OK==querySharedCacheTableLock(p, iTable, eLock) );
-
- /* First search the list for an existing lock on this table. */
- for(pIter=pBt->pLock; pIter; pIter=pIter->pNext){
- if( pIter->iTable==iTable && pIter->pBtree==p ){
- pLock = pIter;
- break;
- }
- }
-
- /* If the above search did not find a BtLock struct associating Btree p
- ** with table iTable, allocate one and link it into the list.
- */
- if( !pLock ){
- pLock = (BtLock *)sqlite3MallocZero(sizeof(BtLock));
- if( !pLock ){
- return SQLITE_NOMEM;
- }
- pLock->iTable = iTable;
- pLock->pBtree = p;
- pLock->pNext = pBt->pLock;
- pBt->pLock = pLock;
- }
-
- /* Set the BtLock.eLock variable to the maximum of the current lock
- ** and the requested lock. This means if a write-lock was already held
- ** and a read-lock requested, we don't incorrectly downgrade the lock.
- */
- assert( WRITE_LOCK>READ_LOCK );
- if( eLock>pLock->eLock ){
- pLock->eLock = eLock;
- }
-
- return SQLITE_OK;
-}
-#endif /* !SQLITE_OMIT_SHARED_CACHE */
-
-#ifndef SQLITE_OMIT_SHARED_CACHE
-/*
-** Release all the table locks (locks obtained via calls to
-** the setSharedCacheTableLock() procedure) held by Btree handle p.
-**
-** This function assumes that handle p has an open read or write
-** transaction. If it does not, then the BtShared.isPending variable
-** may be incorrectly cleared.
-*/
-static void clearAllSharedCacheTableLocks(Btree *p){
- BtShared *pBt = p->pBt;
- BtLock **ppIter = &pBt->pLock;
-
- assert( sqlite3BtreeHoldsMutex(p) );
- assert( p->sharable || 0==*ppIter );
- assert( p->inTrans>0 );
-
- while( *ppIter ){
- BtLock *pLock = *ppIter;
- assert( pBt->isExclusive==0 || pBt->pWriter==pLock->pBtree );
- assert( pLock->pBtree->inTrans>=pLock->eLock );
- if( pLock->pBtree==p ){
- *ppIter = pLock->pNext;
- assert( pLock->iTable!=1 || pLock==&p->lock );
- if( pLock->iTable!=1 ){
- sqlite3_free(pLock);
- }
- }else{
- ppIter = &pLock->pNext;
- }
- }
-
- assert( pBt->isPending==0 || pBt->pWriter );
- if( pBt->pWriter==p ){
- pBt->pWriter = 0;
- pBt->isExclusive = 0;
- pBt->isPending = 0;
- }else if( pBt->nTransaction==2 ){
- /* This function is called when connection 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.
- **
- ** If there is not currently a writer, then BtShared.isPending must
- ** be zero already. So this next line is harmless in that case.
- */
- pBt->isPending = 0;
- }
-}
-
-/*
-** This function changes all write-locks held by connection p to read-locks.
-*/
-static void downgradeAllSharedCacheTableLocks(Btree *p){
- BtShared *pBt = p->pBt;
- if( pBt->pWriter==p ){
- BtLock *pLock;
- pBt->pWriter = 0;
- pBt->isExclusive = 0;
- pBt->isPending = 0;
- for(pLock=pBt->pLock; pLock; pLock=pLock->pNext){
- assert( pLock->eLock==READ_LOCK || pLock->pBtree==p );
- pLock->eLock = READ_LOCK;
- }
- }
-}
-
-#endif /* SQLITE_OMIT_SHARED_CACHE */
-
-static void releasePage(MemPage *pPage); /* Forward reference */
-
-/*
-** Verify that the cursor holds a mutex on the BtShared
-*/
-#ifndef NDEBUG
-static int cursorHoldsMutex(BtCursor *p){
- return sqlite3_mutex_held(p->pBt->mutex);
-}
-#endif
-
-
-#ifndef SQLITE_OMIT_INCRBLOB
-/*
-** Invalidate the overflow page-list cache for cursor pCur, if any.
-*/
-static void invalidateOverflowCache(BtCursor *pCur){
- assert( cursorHoldsMutex(pCur) );
- sqlite3_free(pCur->aOverflow);
- pCur->aOverflow = 0;
-}
-
-/*
-** Invalidate the overflow page-list cache for all cursors opened
-** on the shared btree structure pBt.
-*/
-static void invalidateAllOverflowCache(BtShared *pBt){
- BtCursor *p;
- assert( sqlite3_mutex_held(pBt->mutex) );
- for(p=pBt->pCursor; p; p=p->pNext){
- invalidateOverflowCache(p);
- }
-}
-
-/*
-** This function is called before modifying the contents of a table
-** b-tree to invalidate any incrblob cursors that are open on the
-** row or one of the rows being modified.
-**
-** If argument isClearTable is true, then the entire contents of the
-** table is about to be deleted. In this case invalidate all incrblob
-** cursors open on any row within the table with root-page pgnoRoot.
-**
-** Otherwise, if argument isClearTable is false, then the row with
-** rowid iRow is being replaced or deleted. In this case invalidate
-** only those incrblob cursors open on this specific row.
-*/
-static void invalidateIncrblobCursors(
- Btree *pBtree, /* The database file to check */
- i64 iRow, /* The rowid that might be changing */
- int isClearTable /* True if all rows are being deleted */
-){
- BtCursor *p;
- BtShared *pBt = pBtree->pBt;
- assert( sqlite3BtreeHoldsMutex(pBtree) );
- for(p=pBt->pCursor; p; p=p->pNext){
- if( p->isIncrblobHandle && (isClearTable || p->info.nKey==iRow) ){
- p->eState = CURSOR_INVALID;
- }
- }
-}
-
-#else
- #define invalidateOverflowCache(x)
- #define invalidateAllOverflowCache(x)
- #define invalidateIncrblobCursors(x,y,z)
-#endif
-
-/*
-** Set bit pgno of the BtShared.pHasContent bitvec. This is called
-** when a page that previously contained data becomes a free-list leaf
-** page.
-**
-** The BtShared.pHasContent bitvec exists to work around an obscure
-** bug caused by the interaction of two useful IO optimizations surrounding
-** free-list leaf pages:
-**
-** 1) When all data is deleted from a page and the page becomes
-** a free-list leaf page, the page is not written to the database
-** (as free-list leaf pages contain no meaningful data). Sometimes
-** such a page is not even journalled (as it will not be modified,
-** why bother journalling it?).
-**
-** 2) When a free-list leaf page is reused, its content is not read
-** from the database or written to the journal file (why should it
-** be, if it is not at all meaningful?).
-**
-** By themselves, these optimizations work fine and provide a handy
-** performance boost to bulk delete or insert operations. However, if
-** a page is moved to the free-list and then reused within the same
-** transaction, a problem comes up. If the page is not journalled when
-** it is moved to the free-list and it is also not journalled when it
-** is extracted from the free-list and reused, then the original data
-** may be lost. In the event of a rollback, it may not be possible
-** to restore the database to its original configuration.
-**
-** The solution is the BtShared.pHasContent bitvec. Whenever a page is
-** moved to become a free-list leaf page, the corresponding bit is
-** set in the bitvec. Whenever a leaf page is extracted from the free-list,
-** optimization 2 above is ommitted if the corresponding bit is already
-** set in BtShared.pHasContent. The contents of the bitvec are cleared
-** at the end of every transaction.
-*/
-static int btreeSetHasContent(BtShared *pBt, Pgno pgno){
- int rc = SQLITE_OK;
- if( !pBt->pHasContent ){
- int nPage = 100;
- sqlite3PagerPagecount(pBt->pPager, &nPage);
- /* If sqlite3PagerPagecount() fails there is no harm because the
- ** nPage variable is unchanged from its default value of 100 */
- pBt->pHasContent = sqlite3BitvecCreate((u32)nPage);
- if( !pBt->pHasContent ){
- rc = SQLITE_NOMEM;
- }
- }
- if( rc==SQLITE_OK && pgno<=sqlite3BitvecSize(pBt->pHasContent) ){
- rc = sqlite3BitvecSet(pBt->pHasContent, pgno);
- }
- return rc;
-}
-
-/*
-** Query the BtShared.pHasContent vector.
-**
-** This function is called when a free-list leaf page is removed from the
-** free-list for reuse. It returns false if it is safe to retrieve the
-** page from the pager layer with the 'no-content' flag set. True otherwise.
-*/
-static int btreeGetHasContent(BtShared *pBt, Pgno pgno){
- Bitvec *p = pBt->pHasContent;
- return (p && (pgno>sqlite3BitvecSize(p) || sqlite3BitvecTest(p, pgno)));
-}
-
-/*
-** Clear (destroy) the BtShared.pHasContent bitvec. This should be
-** invoked at the conclusion of each write-transaction.
-*/
-static void btreeClearHasContent(BtShared *pBt){
- sqlite3BitvecDestroy(pBt->pHasContent);
- pBt->pHasContent = 0;
-}
-
-/*
-** Save the current cursor position in the variables BtCursor.nKey
-** and BtCursor.pKey. The cursor's state is set to CURSOR_REQUIRESEEK.
-**
-** The caller must ensure that the cursor is valid (has eState==CURSOR_VALID)
-** prior to calling this routine.
-*/
-static int saveCursorPosition(BtCursor *pCur){
- int rc;
-
- assert( CURSOR_VALID==pCur->eState );
- assert( 0==pCur->pKey );
- assert( cursorHoldsMutex(pCur) );
-
- rc = sqlite3BtreeKeySize(pCur, &pCur->nKey);
- assert( rc==SQLITE_OK ); /* KeySize() cannot fail */
-
- /* If this is an intKey table, then the above call to BtreeKeySize()
- ** stores the integer key in pCur->nKey. In this case this value is
- ** all that is required. Otherwise, if pCur is not open on an intKey
- ** table, then malloc space for and store the pCur->nKey bytes of key
- ** data.
- */
- if( 0==pCur->apPage[0]->intKey ){
- void *pKey = sqlite3Malloc( (int)pCur->nKey );
- if( pKey ){
- rc = sqlite3BtreeKey(pCur, 0, (int)pCur->nKey, pKey);
- if( rc==SQLITE_OK ){
- pCur->pKey = pKey;
- }else{
- sqlite3_free(pKey);
- }
- }else{
- rc = SQLITE_NOMEM;
- }
- }
- assert( !pCur->apPage[0]->intKey || !pCur->pKey );
-
- if( rc==SQLITE_OK ){
- int i;
- for(i=0; i<=pCur->iPage; i++){
- releasePage(pCur->apPage[i]);
- pCur->apPage[i] = 0;
- }
- pCur->iPage = -1;
- pCur->eState = CURSOR_REQUIRESEEK;
- }
-
- invalidateOverflowCache(pCur);
- return rc;
-}
-
-/*
-** Save the positions of all cursors except pExcept open on the table
-** with root-page iRoot. Usually, this is called just before cursor
-** pExcept is used to modify the table (BtreeDelete() or BtreeInsert()).
-*/
-static int saveAllCursors(BtShared *pBt, Pgno iRoot, BtCursor *pExcept){
- BtCursor *p;
- assert( sqlite3_mutex_held(pBt->mutex) );
- assert( pExcept==0 || pExcept->pBt==pBt );
- for(p=pBt->pCursor; p; p=p->pNext){
- if( p!=pExcept && (0==iRoot || p->pgnoRoot==iRoot) &&
- p->eState==CURSOR_VALID ){
- int rc = saveCursorPosition(p);
- if( SQLITE_OK!=rc ){
- return rc;
- }
- }
- }
- return SQLITE_OK;
-}
-
-/*
-** Clear the current cursor position.
-*/
-SQLITE_PRIVATE void sqlite3BtreeClearCursor(BtCursor *pCur){
- assert( cursorHoldsMutex(pCur) );
- sqlite3_free(pCur->pKey);
- pCur->pKey = 0;
- pCur->eState = CURSOR_INVALID;
-}
-
-/*
-** In this version of BtreeMoveto, pKey is a packed index record
-** such as is generated by the OP_MakeRecord opcode. Unpack the
-** record and then call BtreeMovetoUnpacked() to do the work.
-*/
-static int btreeMoveto(
- BtCursor *pCur, /* Cursor open on the btree to be searched */
- const void *pKey, /* Packed key if the btree is an index */
- i64 nKey, /* Integer key for tables. Size of pKey for indices */
- int bias, /* Bias search to the high end */
- int *pRes /* Write search results here */
-){
- int rc; /* Status code */
- UnpackedRecord *pIdxKey; /* Unpacked index key */
- char aSpace[150]; /* Temp space for pIdxKey - to avoid a malloc */
-
- if( pKey ){
- assert( nKey==(i64)(int)nKey );
- pIdxKey = sqlite3VdbeRecordUnpack(pCur->pKeyInfo, (int)nKey, pKey,
- aSpace, sizeof(aSpace));
- if( pIdxKey==0 ) return SQLITE_NOMEM;
- }else{
- pIdxKey = 0;
- }
- rc = sqlite3BtreeMovetoUnpacked(pCur, pIdxKey, nKey, bias, pRes);
- if( pKey ){
- sqlite3VdbeDeleteUnpackedRecord(pIdxKey);
- }
- return rc;
-}
-
-/*
-** Restore the cursor to the position it was in (or as close to as possible)
-** when saveCursorPosition() was called. Note that this call deletes the
-** saved position info stored by saveCursorPosition(), so there can be
-** at most one effective restoreCursorPosition() call after each
-** saveCursorPosition().
-*/
-static int btreeRestoreCursorPosition(BtCursor *pCur){
- int rc;
- assert( cursorHoldsMutex(pCur) );
- assert( pCur->eState>=CURSOR_REQUIRESEEK );
- if( pCur->eState==CURSOR_FAULT ){
- return pCur->skipNext;
- }
- pCur->eState = CURSOR_INVALID;
- rc = btreeMoveto(pCur, pCur->pKey, pCur->nKey, 0, &pCur->skipNext);
- if( rc==SQLITE_OK ){
- sqlite3_free(pCur->pKey);
- pCur->pKey = 0;
- assert( pCur->eState==CURSOR_VALID || pCur->eState==CURSOR_INVALID );
- }
- return rc;
-}
-
-#define restoreCursorPosition(p) \
- (p->eState>=CURSOR_REQUIRESEEK ? \
- btreeRestoreCursorPosition(p) : \
- SQLITE_OK)
-
-/*
-** Determine whether or not a cursor has moved from the position it
-** was last placed at. Cursors can move when the row they are pointing
-** at is deleted out from under them.
-**
-** This routine returns an error code if something goes wrong. The
-** integer *pHasMoved is set to one if the cursor has moved and 0 if not.
-*/
-SQLITE_PRIVATE int sqlite3BtreeCursorHasMoved(BtCursor *pCur, int *pHasMoved){
- int rc;
-
- rc = restoreCursorPosition(pCur);
- if( rc ){
- *pHasMoved = 1;
- return rc;
- }
- if( pCur->eState!=CURSOR_VALID || pCur->skipNext!=0 ){
- *pHasMoved = 1;
- }else{
- *pHasMoved = 0;
- }
- return SQLITE_OK;
-}
-
-#ifndef SQLITE_OMIT_AUTOVACUUM
-/*
-** Given a page number of a regular database page, return the page
-** number for the pointer-map page that contains the entry for the
-** input page number.
-*/
-static Pgno ptrmapPageno(BtShared *pBt, Pgno pgno){
- int nPagesPerMapPage;
- Pgno iPtrMap, ret;
- assert( sqlite3_mutex_held(pBt->mutex) );
- nPagesPerMapPage = (pBt->usableSize/5)+1;
- iPtrMap = (pgno-2)/nPagesPerMapPage;
- ret = (iPtrMap*nPagesPerMapPage) + 2;
- if( ret==PENDING_BYTE_PAGE(pBt) ){
- ret++;
- }
- return ret;
-}
-
-/*
-** Write an entry into the pointer map.
-**
-** This routine updates the pointer map entry for page number 'key'
-** so that it maps to type 'eType' and parent page number 'pgno'.
-**
-** If *pRC is initially non-zero (non-SQLITE_OK) then this routine is
-** a no-op. If an error occurs, the appropriate error code is written
-** into *pRC.
-*/
-static void ptrmapPut(BtShared *pBt, Pgno key, u8 eType, Pgno parent, int *pRC){
- DbPage *pDbPage; /* The pointer map page */
- u8 *pPtrmap; /* The pointer map data */
- Pgno iPtrmap; /* The pointer map page number */
- int offset; /* Offset in pointer map page */
- int rc; /* Return code from subfunctions */
-
- if( *pRC ) return;
-
- assert( sqlite3_mutex_held(pBt->mutex) );
- /* The master-journal page number must never be used as a pointer map page */
- assert( 0==PTRMAP_ISPAGE(pBt, PENDING_BYTE_PAGE(pBt)) );
-
- assert( pBt->autoVacuum );
- if( key==0 ){
- *pRC = SQLITE_CORRUPT_BKPT;
- return;
- }
- iPtrmap = PTRMAP_PAGENO(pBt, key);
- rc = sqlite3PagerGet(pBt->pPager, iPtrmap, &pDbPage);
- if( rc!=SQLITE_OK ){
- *pRC = rc;
- return;
- }
- offset = PTRMAP_PTROFFSET(iPtrmap, key);
- if( offset<0 ){
- *pRC = SQLITE_CORRUPT_BKPT;
- goto ptrmap_exit;
- }
- pPtrmap = (u8 *)sqlite3PagerGetData(pDbPage);
-
- if( eType!=pPtrmap[offset] || get4byte(&pPtrmap[offset+1])!=parent ){
- TRACE(("PTRMAP_UPDATE: %d->(%d,%d)\n", key, eType, parent));
- *pRC= rc = sqlite3PagerWrite(pDbPage);
- if( rc==SQLITE_OK ){
- pPtrmap[offset] = eType;
- put4byte(&pPtrmap[offset+1], parent);
- }
- }
-
-ptrmap_exit:
- sqlite3PagerUnref(pDbPage);
-}
-
-/*
-** Read an entry from the pointer map.
-**
-** This routine retrieves the pointer map entry for page 'key', writing
-** the type and parent page number to *pEType and *pPgno respectively.
-** An error code is returned if something goes wrong, otherwise SQLITE_OK.
-*/
-static int ptrmapGet(BtShared *pBt, Pgno key, u8 *pEType, Pgno *pPgno){
- DbPage *pDbPage; /* The pointer map page */
- int iPtrmap; /* Pointer map page index */
- u8 *pPtrmap; /* Pointer map page data */
- int offset; /* Offset of entry in pointer map */
- int rc;
-
- assert( sqlite3_mutex_held(pBt->mutex) );
-
- iPtrmap = PTRMAP_PAGENO(pBt, key);
- rc = sqlite3PagerGet(pBt->pPager, iPtrmap, &pDbPage);
- if( rc!=0 ){
- return rc;
- }
- pPtrmap = (u8 *)sqlite3PagerGetData(pDbPage);
-
- offset = PTRMAP_PTROFFSET(iPtrmap, key);
- assert( pEType!=0 );
- *pEType = pPtrmap[offset];
- if( pPgno ) *pPgno = get4byte(&pPtrmap[offset+1]);
-
- sqlite3PagerUnref(pDbPage);
- if( *pEType<1 || *pEType>5 ) return SQLITE_CORRUPT_BKPT;
- return SQLITE_OK;
-}
-
-#else /* if defined SQLITE_OMIT_AUTOVACUUM */
- #define ptrmapPut(w,x,y,z,rc)
- #define ptrmapGet(w,x,y,z) SQLITE_OK
- #define ptrmapPutOvflPtr(x, y, rc)
-#endif
-
-/*
-** Given a btree page and a cell index (0 means the first cell on
-** the page, 1 means the second cell, and so forth) return a pointer
-** to the cell content.
-**
-** 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)])))
-
-/*
-** This a more complex version of findCell() that works for
-** pages that do contain overflow cells.
-*/
-static u8 *findOverflowCell(MemPage *pPage, int iCell){
- int i;
- assert( sqlite3_mutex_held(pPage->pBt->mutex) );
- for(i=pPage->nOverflow-1; i>=0; i--){
- int k;
- struct _OvflCell *pOvfl;
- pOvfl = &pPage->aOvfl[i];
- k = pOvfl->idx;
- if( k<=iCell ){
- if( k==iCell ){
- return pOvfl->pCell;
- }
- iCell--;
- }
- }
- return findCell(pPage, iCell);
-}
-
-/*
-** Parse a cell content block and fill in the CellInfo structure. There
-** are two versions of this function. btreeParseCell() takes a
-** cell index as the second argument and btreeParseCellPtr()
-** takes a pointer to the body of the cell as its second argument.
-**
-** Within this file, the parseCell() macro can be called instead of
-** btreeParseCellPtr(). Using some compilers, this will be faster.
-*/
-static void btreeParseCellPtr(
- MemPage *pPage, /* Page containing the cell */
- u8 *pCell, /* Pointer to the cell text. */
- CellInfo *pInfo /* Fill in this structure */
-){
- u16 n; /* Number bytes in cell content header */
- u32 nPayload; /* Number of bytes of cell payload */
-
- assert( sqlite3_mutex_held(pPage->pBt->mutex) );
-
- pInfo->pCell = pCell;
- assert( pPage->leaf==0 || pPage->leaf==1 );
- n = pPage->childPtrSize;
- assert( n==4-4*pPage->leaf );
- if( pPage->intKey ){
- if( pPage->hasData ){
- n += getVarint32(&pCell[n], nPayload);
- }else{
- nPayload = 0;
- }
- n += getVarint(&pCell[n], (u64*)&pInfo->nKey);
- pInfo->nData = nPayload;
- }else{
- pInfo->nData = 0;
- n += getVarint32(&pCell[n], nPayload);
- pInfo->nKey = nPayload;
- }
- pInfo->nPayload = nPayload;
- pInfo->nHeader = n;
- testcase( nPayload==pPage->maxLocal );
- testcase( nPayload==pPage->maxLocal+1 );
- if( likely(nPayload<=pPage->maxLocal) ){
- /* This is the (easy) common case where the entire payload fits
- ** on the local page. No overflow is required.
- */
- int nSize; /* Total size of cell content in bytes */
- nSize = nPayload + n;
- pInfo->nLocal = (u16)nPayload;
- pInfo->iOverflow = 0;
- if( (nSize & ~3)==0 ){
- nSize = 4; /* Minimum cell size is 4 */
- }
- pInfo->nSize = (u16)nSize;
- }else{
- /* If the payload will not fit completely on the local page, we have
- ** to decide how much to store locally and how much to spill onto
- ** overflow pages. The strategy is to minimize the amount of unused
- ** space on overflow pages while keeping the amount of local storage
- ** in between minLocal and maxLocal.
- **
- ** Warning: changing the way overflow payload is distributed in any
- ** way will result in an incompatible file format.
- */
- int minLocal; /* Minimum amount of payload held locally */
- int maxLocal; /* Maximum amount of payload held locally */
- int surplus; /* Overflow payload available for local storage */
-
- minLocal = pPage->minLocal;
- maxLocal = pPage->maxLocal;
- surplus = minLocal + (nPayload - minLocal)%(pPage->pBt->usableSize - 4);
- testcase( surplus==maxLocal );
- testcase( surplus==maxLocal+1 );
- if( surplus <= maxLocal ){
- pInfo->nLocal = (u16)surplus;
- }else{
- pInfo->nLocal = (u16)minLocal;
- }
- pInfo->iOverflow = (u16)(pInfo->nLocal + n);
- pInfo->nSize = pInfo->iOverflow + 4;
- }
-}
-#define parseCell(pPage, iCell, pInfo) \
- btreeParseCellPtr((pPage), findCell((pPage), (iCell)), (pInfo))
-static void btreeParseCell(
- MemPage *pPage, /* Page containing the cell */
- int iCell, /* The cell index. First cell is 0 */
- CellInfo *pInfo /* Fill in this structure */
-){
- parseCell(pPage, iCell, pInfo);
-}
-
-/*
-** Compute the total number of bytes that a Cell needs in the cell
-** data area of the btree-page. The return number includes the cell
-** data header and the local payload, but not any overflow page or
-** the space used by the cell pointer.
-*/
-static u16 cellSizePtr(MemPage *pPage, u8 *pCell){
- u8 *pIter = &pCell[pPage->childPtrSize];
- u32 nSize;
-
-#ifdef SQLITE_DEBUG
- /* The value returned by this function should always be the same as
- ** the (CellInfo.nSize) value found by doing a full parse of the
- ** cell. If SQLITE_DEBUG is defined, an assert() at the bottom of
- ** this function verifies that this invariant is not violated. */
- CellInfo debuginfo;
- btreeParseCellPtr(pPage, pCell, &debuginfo);
-#endif
-
- if( pPage->intKey ){
- u8 *pEnd;
- if( pPage->hasData ){
- pIter += getVarint32(pIter, nSize);
- }else{
- nSize = 0;
- }
-
- /* pIter now points at the 64-bit integer key value, a variable length
- ** integer. The following block moves pIter to point at the first byte
- ** past the end of the key value. */
- pEnd = &pIter[9];
- while( (*pIter++)&0x80 && pIter<pEnd );
- }else{
- pIter += getVarint32(pIter, nSize);
- }
-
- testcase( nSize==pPage->maxLocal );
- testcase( nSize==pPage->maxLocal+1 );
- if( nSize>pPage->maxLocal ){
- int minLocal = pPage->minLocal;
- nSize = minLocal + (nSize - minLocal) % (pPage->pBt->usableSize - 4);
- testcase( nSize==pPage->maxLocal );
- testcase( nSize==pPage->maxLocal+1 );
- if( nSize>pPage->maxLocal ){
- nSize = minLocal;
- }
- nSize += 4;
- }
- nSize += (u32)(pIter - pCell);
-
- /* The minimum size of any cell is 4 bytes. */
- if( nSize<4 ){
- nSize = 4;
- }
-
- assert( nSize==debuginfo.nSize );
- return (u16)nSize;
-}
-#ifndef NDEBUG
-static u16 cellSize(MemPage *pPage, int iCell){
- return cellSizePtr(pPage, findCell(pPage, iCell));
-}
-#endif
-
-#ifndef SQLITE_OMIT_AUTOVACUUM
-/*
-** If the cell pCell, part of page pPage contains a pointer
-** to an overflow page, insert an entry into the pointer-map
-** for the overflow page.
-*/
-static void ptrmapPutOvflPtr(MemPage *pPage, u8 *pCell, int *pRC){
- CellInfo info;
- if( *pRC ) return;
- assert( pCell!=0 );
- btreeParseCellPtr(pPage, pCell, &info);
- assert( (info.nData+(pPage->intKey?0:info.nKey))==info.nPayload );
- if( info.iOverflow ){
- Pgno ovfl = get4byte(&pCell[info.iOverflow]);
- ptrmapPut(pPage->pBt, ovfl, PTRMAP_OVERFLOW1, pPage->pgno, pRC);
- }
-}
-#endif
-
-
-/*
-** Defragment the page given. All Cells are moved to the
-** end of the page and all free space is collected into one
-** big FreeBlk that occurs in between the header and cell
-** pointer array and the cell content area.
-*/
-static int defragmentPage(MemPage *pPage){
- int i; /* Loop counter */
- int pc; /* Address of a i-th cell */
- int hdr; /* Offset to the page header */
- int size; /* Size of a cell */
- int usableSize; /* Number of usable bytes on a page */
- int cellOffset; /* Offset to the cell pointer array */
- int cbrk; /* Offset to the cell content area */
- int nCell; /* Number of cells on the page */
- unsigned char *data; /* The page data */
- unsigned char *temp; /* Temp area for cell content */
- int iCellFirst; /* First allowable cell index */
- int iCellLast; /* Last possible cell index */
-
-
- assert( sqlite3PagerIswriteable(pPage->pDbPage) );
- assert( pPage->pBt!=0 );
- assert( pPage->pBt->usableSize <= SQLITE_MAX_PAGE_SIZE );
- assert( pPage->nOverflow==0 );
- assert( sqlite3_mutex_held(pPage->pBt->mutex) );
- temp = sqlite3PagerTempSpace(pPage->pBt->pPager);
- data = pPage->aData;
- hdr = pPage->hdrOffset;
- cellOffset = pPage->cellOffset;
- nCell = pPage->nCell;
- assert( nCell==get2byte(&data[hdr+3]) );
- usableSize = pPage->pBt->usableSize;
- cbrk = get2byte(&data[hdr+5]);
- memcpy(&temp[cbrk], &data[cbrk], usableSize - cbrk);
- cbrk = usableSize;
- iCellFirst = cellOffset + 2*nCell;
- iCellLast = usableSize - 4;
- for(i=0; i<nCell; i++){
- u8 *pAddr; /* The i-th cell pointer */
- pAddr = &data[cellOffset + i*2];
- pc = get2byte(pAddr);
- testcase( pc==iCellFirst );
- testcase( pc==iCellLast );
-#if !defined(SQLITE_ENABLE_OVERSIZE_CELL_CHECK)
- /* These conditions have already been verified in btreeInitPage()
- ** if SQLITE_ENABLE_OVERSIZE_CELL_CHECK is defined
- */
- if( pc<iCellFirst || pc>iCellLast ){
- return SQLITE_CORRUPT_BKPT;
- }
-#endif
- assert( pc>=iCellFirst && pc<=iCellLast );
- size = cellSizePtr(pPage, &temp[pc]);
- cbrk -= size;
-#if defined(SQLITE_ENABLE_OVERSIZE_CELL_CHECK)
- if( cbrk<iCellFirst ){
- return SQLITE_CORRUPT_BKPT;
- }
-#else
- if( cbrk<iCellFirst || pc+size>usableSize ){
- return SQLITE_CORRUPT_BKPT;
- }
-#endif
- assert( cbrk+size<=usableSize && cbrk>=iCellFirst );
- testcase( cbrk+size==usableSize );
- testcase( pc+size==usableSize );
- memcpy(&data[cbrk], &temp[pc], size);
- put2byte(pAddr, cbrk);
- }
- assert( cbrk>=iCellFirst );
- put2byte(&data[hdr+5], cbrk);
- data[hdr+1] = 0;
- data[hdr+2] = 0;
- data[hdr+7] = 0;
- memset(&data[iCellFirst], 0, cbrk-iCellFirst);
- assert( sqlite3PagerIswriteable(pPage->pDbPage) );
- if( cbrk-iCellFirst!=pPage->nFree ){
- return SQLITE_CORRUPT_BKPT;
- }
- return SQLITE_OK;
-}
-
-/*
-** Allocate nByte bytes of space from within the B-Tree page passed
-** as the first argument. Write into *pIdx the index into pPage->aData[]
-** of the first byte of allocated space. Return either SQLITE_OK or
-** an error code (usually SQLITE_CORRUPT).
-**
-** The caller guarantees that there is sufficient space to make the
-** allocation. This routine might need to defragment in order to bring
-** all the space together, however. This routine will avoid using
-** the first two bytes past the cell pointer area since presumably this
-** allocation is being made in order to insert a new cell, so we will
-** also end up needing a new cell pointer.
-*/
-static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){
- const int hdr = pPage->hdrOffset; /* Local cache of pPage->hdrOffset */
- u8 * const data = pPage->aData; /* Local cache of pPage->aData */
- int nFrag; /* Number of fragmented bytes on pPage */
- int top; /* First byte of cell content area */
- int gap; /* First byte of gap between cell pointers and cell content */
- int rc; /* Integer return code */
-
- assert( sqlite3PagerIswriteable(pPage->pDbPage) );
- assert( pPage->pBt );
- assert( sqlite3_mutex_held(pPage->pBt->mutex) );
- assert( nByte>=0 ); /* Minimum cell size is 4 */
- assert( pPage->nFree>=nByte );
- assert( pPage->nOverflow==0 );
- assert( nByte<pPage->pBt->usableSize-8 );
-
- nFrag = data[hdr+7];
- assert( pPage->cellOffset == hdr + 12 - 4*pPage->leaf );
- gap = pPage->cellOffset + 2*pPage->nCell;
- top = get2byte(&data[hdr+5]);
- if( gap>top ) return SQLITE_CORRUPT_BKPT;
- testcase( gap+2==top );
- testcase( gap+1==top );
- testcase( gap==top );
-
- if( nFrag>=60 ){
- /* Always defragment highly fragmented pages */
- rc = defragmentPage(pPage);
- if( rc ) return rc;
- top = get2byte(&data[hdr+5]);
- }else if( gap+2<=top ){
- /* Search the freelist looking for a free slot big enough to satisfy
- ** the request. The allocation is made from the first free slot in
- ** the list that is large enough to accomadate it.
- */
- int pc, addr;
- for(addr=hdr+1; (pc = get2byte(&data[addr]))>0; addr=pc){
- int size = get2byte(&data[pc+2]); /* Size of free slot */
- if( size>=nByte ){
- int x = size - nByte;
- testcase( x==4 );
- testcase( x==3 );
- if( x<4 ){
- /* Remove the slot from the free-list. Update the number of
- ** fragmented bytes within the page. */
- memcpy(&data[addr], &data[pc], 2);
- data[hdr+7] = (u8)(nFrag + x);
- }else{
- /* The slot remains on the free-list. Reduce its size to account
- ** for the portion used by the new allocation. */
- put2byte(&data[pc+2], x);
- }
- *pIdx = pc + x;
- return SQLITE_OK;
- }
- }
- }
-
- /* Check to make sure there is enough space in the gap to satisfy
- ** the allocation. If not, defragment.
- */
- testcase( gap+2+nByte==top );
- if( gap+2+nByte>top ){
- rc = defragmentPage(pPage);
- if( rc ) return rc;
- top = get2byte(&data[hdr+5]);
- assert( gap+nByte<=top );
- }
-
-
- /* Allocate memory from the gap in between the cell pointer array
- ** and the cell content area. The btreeInitPage() call has already
- ** validated the freelist. Given that the freelist is valid, there
- ** is no way that the allocation can extend off the end of the page.
- ** The assert() below verifies the previous sentence.
- */
- top -= nByte;
- put2byte(&data[hdr+5], top);
- assert( top+nByte <= pPage->pBt->usableSize );
- *pIdx = top;
- return SQLITE_OK;
-}
-
-/*
-** Return a section of the pPage->aData to the freelist.
-** The first byte of the new free block is pPage->aDisk[start]
-** and the size of the block is "size" bytes.
-**
-** Most of the effort here is involved in coalesing adjacent
-** free blocks into a single big free block.
-*/
-static int freeSpace(MemPage *pPage, int start, int size){
- int addr, pbegin, hdr;
- int iLast; /* Largest possible freeblock offset */
- unsigned char *data = pPage->aData;
-
- assert( pPage->pBt!=0 );
- assert( sqlite3PagerIswriteable(pPage->pDbPage) );
- assert( start>=pPage->hdrOffset+6+pPage->childPtrSize );
- assert( (start + size)<=pPage->pBt->usableSize );
- assert( sqlite3_mutex_held(pPage->pBt->mutex) );
- assert( size>=0 ); /* Minimum cell size is 4 */
-
-#ifdef SQLITE_SECURE_DELETE
- /* Overwrite deleted information with zeros when the SECURE_DELETE
- ** option is enabled at compile-time */
- memset(&data[start], 0, size);
-#endif
-
- /* Add the space back into the linked list of freeblocks. Note that
- ** even though the freeblock list was checked by btreeInitPage(),
- ** btreeInitPage() did not detect overlapping cells or
- ** freeblocks that overlapped cells. Nor does it detect when the
- ** cell content area exceeds the value in the page header. If these
- ** situations arise, then subsequent insert operations might corrupt
- ** the freelist. So we do need to check for corruption while scanning
- ** the freelist.
- */
- hdr = pPage->hdrOffset;
- addr = hdr + 1;
- iLast = pPage->pBt->usableSize - 4;
- assert( start<=iLast );
- while( (pbegin = get2byte(&data[addr]))<start && pbegin>0 ){
- if( pbegin<addr+4 ){
- return SQLITE_CORRUPT_BKPT;
- }
- addr = pbegin;
- }
- if( pbegin>iLast ){
- return SQLITE_CORRUPT_BKPT;
- }
- assert( pbegin>addr || pbegin==0 );
- put2byte(&data[addr], start);
- put2byte(&data[start], pbegin);
- put2byte(&data[start+2], size);
- pPage->nFree = pPage->nFree + (u16)size;
-
- /* Coalesce adjacent free blocks */
- addr = hdr + 1;
- while( (pbegin = get2byte(&data[addr]))>0 ){
- int pnext, psize, x;
- assert( pbegin>addr );
- assert( pbegin<=pPage->pBt->usableSize-4 );
- pnext = get2byte(&data[pbegin]);
- psize = get2byte(&data[pbegin+2]);
- if( pbegin + psize + 3 >= pnext && pnext>0 ){
- int frag = pnext - (pbegin+psize);
- if( (frag<0) || (frag>(int)data[hdr+7]) ){
- return SQLITE_CORRUPT_BKPT;
- }
- data[hdr+7] -= (u8)frag;
- x = get2byte(&data[pnext]);
- put2byte(&data[pbegin], x);
- x = pnext + get2byte(&data[pnext+2]) - pbegin;
- put2byte(&data[pbegin+2], x);
- }else{
- addr = pbegin;
- }
- }
-
- /* If the cell content area begins with a freeblock, remove it. */
- if( data[hdr+1]==data[hdr+5] && data[hdr+2]==data[hdr+6] ){
- int top;
- pbegin = get2byte(&data[hdr+1]);
- memcpy(&data[hdr+1], &data[pbegin], 2);
- top = get2byte(&data[hdr+5]) + get2byte(&data[pbegin+2]);
- put2byte(&data[hdr+5], top);
- }
- assert( sqlite3PagerIswriteable(pPage->pDbPage) );
- return SQLITE_OK;
-}
-
-/*
-** Decode the flags byte (the first byte of the header) for a page
-** and initialize fields of the MemPage structure accordingly.
-**
-** Only the following combinations are supported. Anything different
-** indicates a corrupt database files:
-**
-** PTF_ZERODATA
-** PTF_ZERODATA | PTF_LEAF
-** PTF_LEAFDATA | PTF_INTKEY
-** PTF_LEAFDATA | PTF_INTKEY | PTF_LEAF
-*/
-static int decodeFlags(MemPage *pPage, int flagByte){
- BtShared *pBt; /* A copy of pPage->pBt */
-
- assert( pPage->hdrOffset==(pPage->pgno==1 ? 100 : 0) );
- assert( sqlite3_mutex_held(pPage->pBt->mutex) );
- pPage->leaf = (u8)(flagByte>>3); assert( PTF_LEAF == 1<<3 );
- flagByte &= ~PTF_LEAF;
- pPage->childPtrSize = 4-4*pPage->leaf;
- pBt = pPage->pBt;
- if( flagByte==(PTF_LEAFDATA | PTF_INTKEY) ){
- pPage->intKey = 1;
- pPage->hasData = pPage->leaf;
- pPage->maxLocal = pBt->maxLeaf;
- pPage->minLocal = pBt->minLeaf;
- }else if( flagByte==PTF_ZERODATA ){
- pPage->intKey = 0;
- pPage->hasData = 0;
- pPage->maxLocal = pBt->maxLocal;
- pPage->minLocal = pBt->minLocal;
- }else{
- return SQLITE_CORRUPT_BKPT;
- }
- return SQLITE_OK;
-}
-
-/*
-** Initialize the auxiliary information for a disk block.
-**
-** Return SQLITE_OK on success. If we see that the page does
-** not contain a well-formed database page, then return
-** SQLITE_CORRUPT. Note that a return of SQLITE_OK does not
-** guarantee that the page is well-formed. It only shows that
-** we failed to detect any corruption.
-*/
-static int btreeInitPage(MemPage *pPage){
-
- assert( pPage->pBt!=0 );
- assert( sqlite3_mutex_held(pPage->pBt->mutex) );
- assert( pPage->pgno==sqlite3PagerPagenumber(pPage->pDbPage) );
- assert( pPage == sqlite3PagerGetExtra(pPage->pDbPage) );
- assert( pPage->aData == sqlite3PagerGetData(pPage->pDbPage) );
-
- if( !pPage->isInit ){
- u16 pc; /* Address of a freeblock within pPage->aData[] */
- u8 hdr; /* Offset to beginning of page header */
- u8 *data; /* Equal to pPage->aData */
- BtShared *pBt; /* The main btree structure */
- u16 usableSize; /* Amount of usable space on each page */
- u16 cellOffset; /* Offset from start of page to first cell pointer */
- u16 nFree; /* Number of unused bytes on the page */
- u16 top; /* First byte of the cell content area */
- int iCellFirst; /* First allowable cell or freeblock offset */
- int iCellLast; /* Last possible cell or freeblock offset */
-
- pBt = pPage->pBt;
-
- hdr = pPage->hdrOffset;
- data = pPage->aData;
- if( decodeFlags(pPage, data[hdr]) ) return SQLITE_CORRUPT_BKPT;
- assert( pBt->pageSize>=512 && pBt->pageSize<=32768 );
- pPage->maskPage = pBt->pageSize - 1;
- pPage->nOverflow = 0;
- usableSize = pBt->usableSize;
- pPage->cellOffset = cellOffset = hdr + 12 - 4*pPage->leaf;
- top = get2byte(&data[hdr+5]);
- pPage->nCell = get2byte(&data[hdr+3]);
- if( pPage->nCell>MX_CELL(pBt) ){
- /* To many cells for a single page. The page must be corrupt */
- return SQLITE_CORRUPT_BKPT;
- }
- testcase( pPage->nCell==MX_CELL(pBt) );
-
- /* A malformed database page might cause us to read past the end
- ** of page when parsing a cell.
- **
- ** The following block of code checks early to see if a cell extends
- ** past the end of a page boundary and causes SQLITE_CORRUPT to be
- ** returned if it does.
- */
- iCellFirst = cellOffset + 2*pPage->nCell;
- iCellLast = usableSize - 4;
-#if defined(SQLITE_ENABLE_OVERSIZE_CELL_CHECK)
- {
- int i; /* Index into the cell pointer array */
- int sz; /* Size of a cell */
-
- if( !pPage->leaf ) iCellLast--;
- for(i=0; i<pPage->nCell; i++){
- pc = get2byte(&data[cellOffset+i*2]);
- testcase( pc==iCellFirst );
- testcase( pc==iCellLast );
- if( pc<iCellFirst || pc>iCellLast ){
- return SQLITE_CORRUPT_BKPT;
- }
- sz = cellSizePtr(pPage, &data[pc]);
- testcase( pc+sz==usableSize );
- if( pc+sz>usableSize ){
- return SQLITE_CORRUPT_BKPT;
- }
- }
- if( !pPage->leaf ) iCellLast++;
- }
-#endif
-
- /* Compute the total free space on the page */
- pc = get2byte(&data[hdr+1]);
- nFree = data[hdr+7] + top;
- while( pc>0 ){
- u16 next, size;
- if( pc<iCellFirst || pc>iCellLast ){
- /* Start of free block is off the page */
- return SQLITE_CORRUPT_BKPT;
- }
- next = get2byte(&data[pc]);
- size = get2byte(&data[pc+2]);
- if( (next>0 && next<=pc+size+3) || pc+size>usableSize ){
- /* Free blocks must be in ascending order. And the last byte of
- ** the free-block must lie on the database page. */
- return SQLITE_CORRUPT_BKPT;
- }
- nFree = nFree + size;
- pc = next;
- }
-
- /* At this point, nFree contains the sum of the offset to the start
- ** of the cell-content area plus the number of free bytes within
- ** the cell-content area. If this is greater than the usable-size
- ** of the page, then the page must be corrupted. This check also
- ** serves to verify that the offset to the start of the cell-content
- ** area, according to the page header, lies within the page.
- */
- if( nFree>usableSize ){
- return SQLITE_CORRUPT_BKPT;
- }
- pPage->nFree = (u16)(nFree - iCellFirst);
- pPage->isInit = 1;
- }
- return SQLITE_OK;
-}
-
-/*
-** Set up a raw page so that it looks like a database page holding
-** no entries.
-*/
-static void zeroPage(MemPage *pPage, int flags){
- unsigned char *data = pPage->aData;
- BtShared *pBt = pPage->pBt;
- u8 hdr = pPage->hdrOffset;
- u16 first;
-
- assert( sqlite3PagerPagenumber(pPage->pDbPage)==pPage->pgno );
- assert( sqlite3PagerGetExtra(pPage->pDbPage) == (void*)pPage );
- assert( sqlite3PagerGetData(pPage->pDbPage) == data );
- assert( sqlite3PagerIswriteable(pPage->pDbPage) );
- assert( sqlite3_mutex_held(pBt->mutex) );
- /*memset(&data[hdr], 0, pBt->usableSize - hdr);*/
- data[hdr] = (char)flags;
- first = hdr + 8 + 4*((flags&PTF_LEAF)==0 ?1:0);
- memset(&data[hdr+1], 0, 4);
- data[hdr+7] = 0;
- put2byte(&data[hdr+5], pBt->usableSize);
- pPage->nFree = pBt->usableSize - first;
- decodeFlags(pPage, flags);
- pPage->hdrOffset = hdr;
- pPage->cellOffset = first;
- pPage->nOverflow = 0;
- assert( pBt->pageSize>=512 && pBt->pageSize<=32768 );
- pPage->maskPage = pBt->pageSize - 1;
- pPage->nCell = 0;
- pPage->isInit = 1;
-}
-
-
-/*
-** Convert a DbPage obtained from the pager into a MemPage used by
-** the btree layer.
-*/
-static MemPage *btreePageFromDbPage(DbPage *pDbPage, Pgno pgno, BtShared *pBt){
- MemPage *pPage = (MemPage*)sqlite3PagerGetExtra(pDbPage);
- pPage->aData = sqlite3PagerGetData(pDbPage);
- pPage->pDbPage = pDbPage;
- pPage->pBt = pBt;
- pPage->pgno = pgno;
- pPage->hdrOffset = pPage->pgno==1 ? 100 : 0;
- return pPage;
-}
-
-/*
-** Get a page from the pager. Initialize the MemPage.pBt and
-** MemPage.aData elements if needed.
-**
-** If the noContent flag is set, it means that we do not care about
-** the content of the page at this time. So do not go to the disk
-** to fetch the content. Just fill in the content with zeros for now.
-** If in the future we call sqlite3PagerWrite() on this page, that
-** means we have started to be concerned about content and the disk
-** read should occur at that point.
-*/
-static int btreeGetPage(
- BtShared *pBt, /* The btree */
- Pgno pgno, /* Number of the page to fetch */
- MemPage **ppPage, /* Return the page in this parameter */
- int noContent /* Do not load page content if true */
-){
- int rc;
- DbPage *pDbPage;
-
- assert( sqlite3_mutex_held(pBt->mutex) );
- rc = sqlite3PagerAcquire(pBt->pPager, pgno, (DbPage**)&pDbPage, noContent);
- if( rc ) return rc;
- *ppPage = btreePageFromDbPage(pDbPage, pgno, pBt);
- return SQLITE_OK;
-}
-
-/*
-** Retrieve a page from the pager cache. If the requested page is not
-** already in the pager cache return NULL. Initialize the MemPage.pBt and
-** MemPage.aData elements if needed.
-*/
-static MemPage *btreePageLookup(BtShared *pBt, Pgno pgno){
- DbPage *pDbPage;
- assert( sqlite3_mutex_held(pBt->mutex) );
- pDbPage = sqlite3PagerLookup(pBt->pPager, pgno);
- if( pDbPage ){
- return btreePageFromDbPage(pDbPage, pgno, pBt);
- }
- return 0;
-}
-
-/*
-** Return the size of the database file in pages. If there is any kind of
-** error, return ((unsigned int)-1).
-*/
-static Pgno pagerPagecount(BtShared *pBt){
- int nPage = -1;
- int rc;
- assert( pBt->pPage1 );
- rc = sqlite3PagerPagecount(pBt->pPager, &nPage);
- assert( rc==SQLITE_OK || nPage==-1 );
- return (Pgno)nPage;
-}
-
-/*
-** Get a page from the pager and initialize it. This routine is just a
-** convenience wrapper around separate calls to btreeGetPage() and
-** btreeInitPage().
-**
-** If an error occurs, then the value *ppPage is set to is undefined. It
-** may remain unchanged, or it may be set to an invalid value.
-*/
-static int getAndInitPage(
- BtShared *pBt, /* The database file */
- Pgno pgno, /* Number of the page to get */
- MemPage **ppPage /* Write the page pointer here */
-){
- int rc;
- TESTONLY( Pgno iLastPg = pagerPagecount(pBt); )
- assert( sqlite3_mutex_held(pBt->mutex) );
-
- rc = btreeGetPage(pBt, pgno, ppPage, 0);
- if( rc==SQLITE_OK ){
- rc = btreeInitPage(*ppPage);
- if( rc!=SQLITE_OK ){
- releasePage(*ppPage);
- }
- }
-
- /* If the requested page number was either 0 or greater than the page
- ** number of the last page in the database, this function should return
- ** SQLITE_CORRUPT or some other error (i.e. SQLITE_FULL). Check that this
- ** is the case. */
- assert( (pgno>0 && pgno<=iLastPg) || rc!=SQLITE_OK );
- testcase( pgno==0 );
- testcase( pgno==iLastPg );
-
- return rc;
-}
-
-/*
-** Release a MemPage. This should be called once for each prior
-** call to btreeGetPage.
-*/
-static void releasePage(MemPage *pPage){
- if( pPage ){
- assert( pPage->nOverflow==0 || sqlite3PagerPageRefcount(pPage->pDbPage)>1 );
- assert( pPage->aData );
- assert( pPage->pBt );
- assert( sqlite3PagerGetExtra(pPage->pDbPage) == (void*)pPage );
- assert( sqlite3PagerGetData(pPage->pDbPage)==pPage->aData );
- assert( sqlite3_mutex_held(pPage->pBt->mutex) );
- sqlite3PagerUnref(pPage->pDbPage);
- }
-}
-
-/*
-** During a rollback, when the pager reloads information into the cache
-** so that the cache is restored to its original state at the start of
-** the transaction, for each page restored this routine is called.
-**
-** This routine needs to reset the extra data section at the end of the
-** page to agree with the restored data.
-*/
-static void pageReinit(DbPage *pData){
- MemPage *pPage;
- pPage = (MemPage *)sqlite3PagerGetExtra(pData);
- assert( sqlite3PagerPageRefcount(pData)>0 );
- if( pPage->isInit ){
- assert( sqlite3_mutex_held(pPage->pBt->mutex) );
- pPage->isInit = 0;
- if( sqlite3PagerPageRefcount(pData)>1 ){
- /* pPage might not be a btree page; it might be an overflow page
- ** or ptrmap page or a free page. In those cases, the following
- ** call to btreeInitPage() will likely return SQLITE_CORRUPT.
- ** But no harm is done by this. And it is very important that
- ** btreeInitPage() be called on every btree page so we make
- ** the call for every page that comes in for re-initing. */
- btreeInitPage(pPage);
- }
- }
-}
-
-/*
-** Invoke the busy handler for a btree.
-*/
-static int btreeInvokeBusyHandler(void *pArg){
- BtShared *pBt = (BtShared*)pArg;
- assert( pBt->db );
- assert( sqlite3_mutex_held(pBt->db->mutex) );
- return sqlite3InvokeBusyHandler(&pBt->db->busyHandler);
-}
-
-/*
-** Open a database file.
-**
-** zFilename is the name of the database file. If zFilename is NULL
-** a new database with a random name is created. This randomly named
-** database file will be deleted when sqlite3BtreeClose() is called.
-** If zFilename is ":memory:" then an in-memory database is created
-** that is automatically destroyed when it is closed.
-**
-** If the database is already opened in the same database connection
-** and we are in shared cache mode, then the open will fail with an
-** SQLITE_CONSTRAINT error. We cannot allow two or more BtShared
-** objects in the same database connection since doing so will lead
-** to problems with locking.
-*/
-SQLITE_PRIVATE int sqlite3BtreeOpen(
- const char *zFilename, /* Name of the file containing the BTree database */
- sqlite3 *db, /* Associated database handle */
- Btree **ppBtree, /* Pointer to new Btree object written here */
- int flags, /* Options */
- int vfsFlags /* Flags passed through to sqlite3_vfs.xOpen() */
-){
- sqlite3_vfs *pVfs; /* The VFS to use for this btree */
- BtShared *pBt = 0; /* Shared part of btree structure */
- Btree *p; /* Handle to return */
- sqlite3_mutex *mutexOpen = 0; /* Prevents a race condition. Ticket #3537 */
- int rc = SQLITE_OK; /* Result code from this function */
- u8 nReserve; /* Byte of unused space on each page */
- unsigned char zDbHeader[100]; /* Database header content */
-
- /* Set the variable isMemdb to true for an in-memory database, or
- ** false for a file-based database. This symbol is only required if
- ** either of the shared-data or autovacuum features are compiled
- ** into the library.
- */
-#if !defined(SQLITE_OMIT_SHARED_CACHE) || !defined(SQLITE_OMIT_AUTOVACUUM)
- #ifdef SQLITE_OMIT_MEMORYDB
- const int isMemdb = 0;
- #else
- const int isMemdb = zFilename && !strcmp(zFilename, ":memory:");
- #endif
-#endif
-
- assert( db!=0 );
- assert( sqlite3_mutex_held(db->mutex) );
-
- pVfs = db->pVfs;
- p = sqlite3MallocZero(sizeof(Btree));
- if( !p ){
- return SQLITE_NOMEM;
- }
- p->inTrans = TRANS_NONE;
- p->db = db;
-#ifndef SQLITE_OMIT_SHARED_CACHE
- p->lock.pBtree = p;
- p->lock.iTable = 1;
-#endif
-
-#if !defined(SQLITE_OMIT_SHARED_CACHE) && !defined(SQLITE_OMIT_DISKIO)
- /*
- ** If this Btree is a candidate for shared cache, try to find an
- ** existing BtShared object that we can share with
- */
- if( isMemdb==0 && zFilename && zFilename[0] ){
- if( vfsFlags & SQLITE_OPEN_SHAREDCACHE ){
- int nFullPathname = pVfs->mxPathname+1;
- char *zFullPathname = sqlite3Malloc(nFullPathname);
- sqlite3_mutex *mutexShared;
- p->sharable = 1;
- if( !zFullPathname ){
- sqlite3_free(p);
- return SQLITE_NOMEM;
- }
- sqlite3OsFullPathname(pVfs, zFilename, nFullPathname, zFullPathname);
- mutexOpen = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_OPEN);
- sqlite3_mutex_enter(mutexOpen);
- mutexShared = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
- sqlite3_mutex_enter(mutexShared);
- for(pBt=GLOBAL(BtShared*,sqlite3SharedCacheList); pBt; pBt=pBt->pNext){
- assert( pBt->nRef>0 );
- if( 0==strcmp(zFullPathname, sqlite3PagerFilename(pBt->pPager))
- && sqlite3PagerVfs(pBt->pPager)==pVfs ){
- int iDb;
- for(iDb=db->nDb-1; iDb>=0; iDb--){
- Btree *pExisting = db->aDb[iDb].pBt;
- if( pExisting && pExisting->pBt==pBt ){
- sqlite3_mutex_leave(mutexShared);
- sqlite3_mutex_leave(mutexOpen);
- sqlite3_free(zFullPathname);
- sqlite3_free(p);
- return SQLITE_CONSTRAINT;
- }
- }
- p->pBt = pBt;
- pBt->nRef++;
- break;
- }
- }
- sqlite3_mutex_leave(mutexShared);
- sqlite3_free(zFullPathname);
- }
-#ifdef SQLITE_DEBUG
- else{
- /* In debug mode, we mark all persistent databases as sharable
- ** even when they are not. This exercises the locking code and
- ** gives more opportunity for asserts(sqlite3_mutex_held())
- ** statements to find locking problems.
- */
- p->sharable = 1;
- }
-#endif
- }
-#endif
- if( pBt==0 ){
- /*
- ** The following asserts make sure that structures used by the btree are
- ** the right size. This is to guard against size changes that result
- ** when compiling on a different architecture.
- */
- assert( sizeof(i64)==8 || sizeof(i64)==4 );
- assert( sizeof(u64)==8 || sizeof(u64)==4 );
- assert( sizeof(u32)==4 );
- assert( sizeof(u16)==2 );
- assert( sizeof(Pgno)==4 );
-
- pBt = sqlite3MallocZero( sizeof(*pBt) );
- if( pBt==0 ){
- rc = SQLITE_NOMEM;
- goto btree_open_out;
- }
- rc = sqlite3PagerOpen(pVfs, &pBt->pPager, zFilename,
- EXTRA_SIZE, flags, vfsFlags, pageReinit);
- if( rc==SQLITE_OK ){
- rc = sqlite3PagerReadFileheader(pBt->pPager,sizeof(zDbHeader),zDbHeader);
- }
- if( rc!=SQLITE_OK ){
- goto btree_open_out;
- }
- pBt->db = db;
- sqlite3PagerSetBusyhandler(pBt->pPager, btreeInvokeBusyHandler, pBt);
- p->pBt = pBt;
-
- pBt->pCursor = 0;
- pBt->pPage1 = 0;
- pBt->readOnly = sqlite3PagerIsreadonly(pBt->pPager);
- pBt->pageSize = get2byte(&zDbHeader[16]);
- if( pBt->pageSize<512 || pBt->pageSize>SQLITE_MAX_PAGE_SIZE
- || ((pBt->pageSize-1)&pBt->pageSize)!=0 ){
- pBt->pageSize = 0;
-#ifndef SQLITE_OMIT_AUTOVACUUM
- /* If the magic name ":memory:" will create an in-memory database, then
- ** leave the autoVacuum mode at 0 (do not auto-vacuum), even if
- ** SQLITE_DEFAULT_AUTOVACUUM is true. On the other hand, if
- ** SQLITE_OMIT_MEMORYDB has been defined, then ":memory:" is just a
- ** regular file-name. In this case the auto-vacuum applies as per normal.
- */
- if( zFilename && !isMemdb ){
- pBt->autoVacuum = (SQLITE_DEFAULT_AUTOVACUUM ? 1 : 0);
- pBt->incrVacuum = (SQLITE_DEFAULT_AUTOVACUUM==2 ? 1 : 0);
- }
-#endif
- nReserve = 0;
- }else{
- nReserve = zDbHeader[20];
- pBt->pageSizeFixed = 1;
-#ifndef SQLITE_OMIT_AUTOVACUUM
- pBt->autoVacuum = (get4byte(&zDbHeader[36 + 4*4])?1:0);
- pBt->incrVacuum = (get4byte(&zDbHeader[36 + 7*4])?1:0);
-#endif
- }
- rc = sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize, nReserve);
- if( rc ) goto btree_open_out;
- pBt->usableSize = pBt->pageSize - nReserve;
- assert( (pBt->pageSize & 7)==0 ); /* 8-byte alignment of pageSize */
-
-#if !defined(SQLITE_OMIT_SHARED_CACHE) && !defined(SQLITE_OMIT_DISKIO)
- /* Add the new BtShared object to the linked list sharable BtShareds.
- */
- if( p->sharable ){
- sqlite3_mutex *mutexShared;
- pBt->nRef = 1;
- mutexShared = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
- if( SQLITE_THREADSAFE && sqlite3GlobalConfig.bCoreMutex ){
- pBt->mutex = sqlite3MutexAlloc(SQLITE_MUTEX_FAST);
- if( pBt->mutex==0 ){
- rc = SQLITE_NOMEM;
- db->mallocFailed = 0;
- goto btree_open_out;
- }
- }
- sqlite3_mutex_enter(mutexShared);
- pBt->pNext = GLOBAL(BtShared*,sqlite3SharedCacheList);
- GLOBAL(BtShared*,sqlite3SharedCacheList) = pBt;
- sqlite3_mutex_leave(mutexShared);
- }
-#endif
- }
-
-#if !defined(SQLITE_OMIT_SHARED_CACHE) && !defined(SQLITE_OMIT_DISKIO)
- /* If the new Btree uses a sharable pBtShared, then link the new
- ** Btree into the list of all sharable Btrees for the same connection.
- ** The list is kept in ascending order by pBt address.
- */
- if( p->sharable ){
- int i;
- Btree *pSib;
- for(i=0; i<db->nDb; i++){
- if( (pSib = db->aDb[i].pBt)!=0 && pSib->sharable ){
- while( pSib->pPrev ){ pSib = pSib->pPrev; }
- if( p->pBt<pSib->pBt ){
- p->pNext = pSib;
- p->pPrev = 0;
- pSib->pPrev = p;
- }else{
- while( pSib->pNext && pSib->pNext->pBt<p->pBt ){
- pSib = pSib->pNext;
- }
- p->pNext = pSib->pNext;
- p->pPrev = pSib;
- if( p->pNext ){
- p->pNext->pPrev = p;
- }
- pSib->pNext = p;
- }
- break;
- }
- }
- }
-#endif
- *ppBtree = p;
-
-btree_open_out:
- if( rc!=SQLITE_OK ){
- if( pBt && pBt->pPager ){
- sqlite3PagerClose(pBt->pPager);
- }
- sqlite3_free(pBt);
- sqlite3_free(p);
- *ppBtree = 0;
- }
- if( mutexOpen ){
- assert( sqlite3_mutex_held(mutexOpen) );
- sqlite3_mutex_leave(mutexOpen);
- }
- return rc;
-}
-
-/*
-** Decrement the BtShared.nRef counter. When it reaches zero,
-** remove the BtShared structure from the sharing list. Return
-** true if the BtShared.nRef counter reaches zero and return
-** false if it is still positive.
-*/
-static int removeFromSharingList(BtShared *pBt){
-#ifndef SQLITE_OMIT_SHARED_CACHE
- sqlite3_mutex *pMaster;
- BtShared *pList;
- int removed = 0;
-
- assert( sqlite3_mutex_notheld(pBt->mutex) );
- pMaster = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
- sqlite3_mutex_enter(pMaster);
- pBt->nRef--;
- if( pBt->nRef<=0 ){
- if( GLOBAL(BtShared*,sqlite3SharedCacheList)==pBt ){
- GLOBAL(BtShared*,sqlite3SharedCacheList) = pBt->pNext;
- }else{
- pList = GLOBAL(BtShared*,sqlite3SharedCacheList);
- while( ALWAYS(pList) && pList->pNext!=pBt ){
- pList=pList->pNext;
- }
- if( ALWAYS(pList) ){
- pList->pNext = pBt->pNext;
- }
- }
- if( SQLITE_THREADSAFE ){
- sqlite3_mutex_free(pBt->mutex);
- }
- removed = 1;
- }
- sqlite3_mutex_leave(pMaster);
- return removed;
-#else
- return 1;
-#endif
-}
-
-/*
-** Make sure pBt->pTmpSpace points to an allocation of
-** MX_CELL_SIZE(pBt) bytes.
-*/
-static void allocateTempSpace(BtShared *pBt){
- if( !pBt->pTmpSpace ){
- pBt->pTmpSpace = sqlite3PageMalloc( pBt->pageSize );
- }
-}
-
-/*
-** Free the pBt->pTmpSpace allocation
-*/
-static void freeTempSpace(BtShared *pBt){
- sqlite3PageFree( pBt->pTmpSpace);
- pBt->pTmpSpace = 0;
-}
-
-/*
-** Close an open database and invalidate all cursors.
-*/
-SQLITE_PRIVATE int sqlite3BtreeClose(Btree *p){
- BtShared *pBt = p->pBt;
- BtCursor *pCur;
-
- /* Close all cursors opened via this handle. */
- assert( sqlite3_mutex_held(p->db->mutex) );
- sqlite3BtreeEnter(p);
- pCur = pBt->pCursor;
- while( pCur ){
- BtCursor *pTmp = pCur;
- pCur = pCur->pNext;
- if( pTmp->pBtree==p ){
- sqlite3BtreeCloseCursor(pTmp);
- }
- }
-
- /* Rollback any active transaction and free the handle structure.
- ** The call to sqlite3BtreeRollback() drops any table-locks held by
- ** this handle.
- */
- sqlite3BtreeRollback(p);
- sqlite3BtreeLeave(p);
-
- /* If there are still other outstanding references to the shared-btree
- ** structure, return now. The remainder of this procedure cleans
- ** up the shared-btree.
- */
- assert( p->wantToLock==0 && p->locked==0 );
- if( !p->sharable || removeFromSharingList(pBt) ){
- /* The pBt is no longer on the sharing list, so we can access
- ** it without having to hold the mutex.
- **
- ** Clean out and delete the BtShared object.
- */
- assert( !pBt->pCursor );
- sqlite3PagerClose(pBt->pPager);
- if( pBt->xFreeSchema && pBt->pSchema ){
- pBt->xFreeSchema(pBt->pSchema);
- }
- sqlite3_free(pBt->pSchema);
- freeTempSpace(pBt);
- sqlite3_free(pBt);
- }
-
-#ifndef SQLITE_OMIT_SHARED_CACHE
- assert( p->wantToLock==0 );
- assert( p->locked==0 );
- if( p->pPrev ) p->pPrev->pNext = p->pNext;
- if( p->pNext ) p->pNext->pPrev = p->pPrev;
-#endif
-
- sqlite3_free(p);
- return SQLITE_OK;
-}
-
-/*
-** Change the limit on the number of pages allowed in the cache.
-**
-** The maximum number of cache pages is set to the absolute
-** value of mxPage. If mxPage is negative, the pager will
-** operate asynchronously - it will not stop to do fsync()s
-** to insure data is written to the disk surface before
-** continuing. Transactions still work if synchronous is off,
-** and the database cannot be corrupted if this program
-** crashes. But if the operating system crashes or there is
-** an abrupt power failure when synchronous is off, the database
-** could be left in an inconsistent and unrecoverable state.
-** Synchronous is on by default so database corruption is not
-** normally a worry.
-*/
-SQLITE_PRIVATE int sqlite3BtreeSetCacheSize(Btree *p, int mxPage){
- BtShared *pBt = p->pBt;
- assert( sqlite3_mutex_held(p->db->mutex) );
- sqlite3BtreeEnter(p);
- sqlite3PagerSetCachesize(pBt->pPager, mxPage);
- sqlite3BtreeLeave(p);
- return SQLITE_OK;
-}
-
-/*
-** Change the way data is synced to disk in order to increase or decrease
-** how well the database resists damage due to OS crashes and power
-** failures. Level 1 is the same as asynchronous (no syncs() occur and
-** there is a high probability of damage) Level 2 is the default. There
-** is a very low but non-zero probability of damage. Level 3 reduces the
-** probability of damage to near zero but with a write performance reduction.
-*/
-#ifndef SQLITE_OMIT_PAGER_PRAGMAS
-SQLITE_PRIVATE int sqlite3BtreeSetSafetyLevel(Btree *p, int level, int fullSync){
- BtShared *pBt = p->pBt;
- assert( sqlite3_mutex_held(p->db->mutex) );
- sqlite3BtreeEnter(p);
- sqlite3PagerSetSafetyLevel(pBt->pPager, level, fullSync);
- sqlite3BtreeLeave(p);
- return SQLITE_OK;
-}
-#endif
-
-/*
-** Return TRUE if the given btree is set to safety level 1. In other
-** words, return TRUE if no sync() occurs on the disk files.
-*/
-SQLITE_PRIVATE int sqlite3BtreeSyncDisabled(Btree *p){
- BtShared *pBt = p->pBt;
- int rc;
- assert( sqlite3_mutex_held(p->db->mutex) );
- sqlite3BtreeEnter(p);
- assert( pBt && pBt->pPager );
- rc = sqlite3PagerNosync(pBt->pPager);
- sqlite3BtreeLeave(p);
- return rc;
-}
-
-#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) || !defined(SQLITE_OMIT_VACUUM)
-/*
-** Change the default pages size and the number of reserved bytes per page.
-** Or, if the page size has already been fixed, return SQLITE_READONLY
-** without changing anything.
-**
-** The page size must be a power of 2 between 512 and 65536. If the page
-** size supplied does not meet this constraint then the page size is not
-** changed.
-**
-** Page sizes are constrained to be a power of two so that the region
-** of the database file used for locking (beginning at PENDING_BYTE,
-** the first byte past the 1GB boundary, 0x40000000) needs to occur
-** at the beginning of a page.
-**
-** 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
-** and autovacuum mode can no longer be changed.
-*/
-SQLITE_PRIVATE int sqlite3BtreeSetPageSize(Btree *p, int pageSize, int nReserve, int iFix){
- int rc = SQLITE_OK;
- BtShared *pBt = p->pBt;
- assert( nReserve>=-1 && nReserve<=255 );
- sqlite3BtreeEnter(p);
- if( pBt->pageSizeFixed ){
- sqlite3BtreeLeave(p);
- return SQLITE_READONLY;
- }
- if( nReserve<0 ){
- nReserve = pBt->pageSize - pBt->usableSize;
- }
- assert( nReserve>=0 && nReserve<=255 );
- if( pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE &&
- ((pageSize-1)&pageSize)==0 ){
- assert( (pageSize & 7)==0 );
- assert( !pBt->pPage1 && !pBt->pCursor );
- pBt->pageSize = (u16)pageSize;
- freeTempSpace(pBt);
- }
- rc = sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize, nReserve);
- pBt->usableSize = pBt->pageSize - (u16)nReserve;
- if( iFix ) pBt->pageSizeFixed = 1;
- sqlite3BtreeLeave(p);
- return rc;
-}
-
-/*
-** Return the currently defined page size
-*/
-SQLITE_PRIVATE int sqlite3BtreeGetPageSize(Btree *p){
- return p->pBt->pageSize;
-}
-
-/*
-** Return the number of bytes of space at the end of every page that
-** are intentually left unused. This is the "reserved" space that is
-** sometimes used by extensions.
-*/
-SQLITE_PRIVATE int sqlite3BtreeGetReserve(Btree *p){
- int n;
- sqlite3BtreeEnter(p);
- n = p->pBt->pageSize - p->pBt->usableSize;
- sqlite3BtreeLeave(p);
- return n;
-}
-
-/*
-** Set the maximum page count for a database if mxPage is positive.
-** No changes are made if mxPage is 0 or negative.
-** Regardless of the value of mxPage, return the maximum page count.
-*/
-SQLITE_PRIVATE int sqlite3BtreeMaxPageCount(Btree *p, int mxPage){
- int n;
- sqlite3BtreeEnter(p);
- n = sqlite3PagerMaxPageCount(p->pBt->pPager, mxPage);
- sqlite3BtreeLeave(p);
- return n;
-}
-#endif /* !defined(SQLITE_OMIT_PAGER_PRAGMAS) || !defined(SQLITE_OMIT_VACUUM) */
-
-/*
-** Change the 'auto-vacuum' property of the database. If the 'autoVacuum'
-** parameter is non-zero, then auto-vacuum mode is enabled. If zero, it
-** is disabled. The default value for the auto-vacuum property is
-** determined by the SQLITE_DEFAULT_AUTOVACUUM macro.
-*/
-SQLITE_PRIVATE int sqlite3BtreeSetAutoVacuum(Btree *p, int autoVacuum){
-#ifdef SQLITE_OMIT_AUTOVACUUM
- return SQLITE_READONLY;
-#else
- BtShared *pBt = p->pBt;
- int rc = SQLITE_OK;
- u8 av = (u8)autoVacuum;
-
- sqlite3BtreeEnter(p);
- if( pBt->pageSizeFixed && (av ?1:0)!=pBt->autoVacuum ){
- rc = SQLITE_READONLY;
- }else{
- pBt->autoVacuum = av ?1:0;
- pBt->incrVacuum = av==2 ?1:0;
- }
- sqlite3BtreeLeave(p);
- return rc;
-#endif
-}
-
-/*
-** Return the value of the 'auto-vacuum' property. If auto-vacuum is
-** enabled 1 is returned. Otherwise 0.
-*/
-SQLITE_PRIVATE int sqlite3BtreeGetAutoVacuum(Btree *p){
-#ifdef SQLITE_OMIT_AUTOVACUUM
- return BTREE_AUTOVACUUM_NONE;
-#else
- int rc;
- sqlite3BtreeEnter(p);
- rc = (
- (!p->pBt->autoVacuum)?BTREE_AUTOVACUUM_NONE:
- (!p->pBt->incrVacuum)?BTREE_AUTOVACUUM_FULL:
- BTREE_AUTOVACUUM_INCR
- );
- sqlite3BtreeLeave(p);
- return rc;
-#endif
-}
-
-
-/*
-** Get a reference to pPage1 of the database file. This will
-** also acquire a readlock on that file.
-**
-** SQLITE_OK is returned on success. If the file is not a
-** well-formed database file, then SQLITE_CORRUPT is returned.
-** SQLITE_BUSY is returned if the database is locked. SQLITE_NOMEM
-** is returned if we run out of memory.
-*/
-static int lockBtree(BtShared *pBt){
- int rc;
- MemPage *pPage1;
- int nPage;
-
- assert( sqlite3_mutex_held(pBt->mutex) );
- assert( pBt->pPage1==0 );
- rc = sqlite3PagerSharedLock(pBt->pPager);
- if( rc!=SQLITE_OK ) return rc;
- rc = btreeGetPage(pBt, 1, &pPage1, 0);
- if( rc!=SQLITE_OK ) return rc;
-
- /* Do some checking to help insure the file we opened really is
- ** a valid database file.
- */
- rc = sqlite3PagerPagecount(pBt->pPager, &nPage);
- if( rc!=SQLITE_OK ){
- goto page1_init_failed;
- }else if( nPage>0 ){
- int pageSize;
- int usableSize;
- u8 *page1 = pPage1->aData;
- rc = SQLITE_NOTADB;
- if( memcmp(page1, zMagicHeader, 16)!=0 ){
- goto page1_init_failed;
- }
- if( page1[18]>1 ){
- pBt->readOnly = 1;
- }
- if( page1[19]>1 ){
- goto page1_init_failed;
- }
-
- /* The maximum embedded fraction must be exactly 25%. And the minimum
- ** embedded fraction must be 12.5% for both leaf-data and non-leaf-data.
- ** The original design allowed these amounts to vary, but as of
- ** version 3.6.0, we require them to be fixed.
- */
- if( memcmp(&page1[21], "\100\040\040",3)!=0 ){
- goto page1_init_failed;
- }
- pageSize = get2byte(&page1[16]);
- if( ((pageSize-1)&pageSize)!=0 || pageSize<512 ||
- (SQLITE_MAX_PAGE_SIZE<32768 && pageSize>SQLITE_MAX_PAGE_SIZE)
- ){
- goto page1_init_failed;
- }
- assert( (pageSize & 7)==0 );
- usableSize = pageSize - page1[20];
- if( pageSize!=pBt->pageSize ){
- /* After reading the first page of the database assuming a page size
- ** of BtShared.pageSize, we have discovered that the page-size is
- ** actually pageSize. Unlock the database, leave pBt->pPage1 at
- ** zero and return SQLITE_OK. The caller will call this function
- ** again with the correct page-size.
- */
- releasePage(pPage1);
- pBt->usableSize = (u16)usableSize;
- pBt->pageSize = (u16)pageSize;
- freeTempSpace(pBt);
- rc = sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize,
- pageSize-usableSize);
- return rc;
- }
- if( usableSize<480 ){
- goto page1_init_failed;
- }
- pBt->pageSize = (u16)pageSize;
- pBt->usableSize = (u16)usableSize;
-#ifndef SQLITE_OMIT_AUTOVACUUM
- pBt->autoVacuum = (get4byte(&page1[36 + 4*4])?1:0);
- pBt->incrVacuum = (get4byte(&page1[36 + 7*4])?1:0);
-#endif
- }
-
- /* maxLocal is the maximum amount of payload to store locally for
- ** a cell. Make sure it is small enough so that at least minFanout
- ** cells can will fit on one page. We assume a 10-byte page header.
- ** Besides the payload, the cell must store:
- ** 2-byte pointer to the cell
- ** 4-byte child pointer
- ** 9-byte nKey value
- ** 4-byte nData value
- ** 4-byte overflow page pointer
- ** So a cell consists of a 2-byte poiner, a header which is as much as
- ** 17 bytes long, 0 to N bytes of payload, and an optional 4 byte overflow
- ** page pointer.
- */
- pBt->maxLocal = (pBt->usableSize-12)*64/255 - 23;
- pBt->minLocal = (pBt->usableSize-12)*32/255 - 23;
- pBt->maxLeaf = pBt->usableSize - 35;
- pBt->minLeaf = (pBt->usableSize-12)*32/255 - 23;
- assert( pBt->maxLeaf + 23 <= MX_CELL_SIZE(pBt) );
- pBt->pPage1 = pPage1;
- return SQLITE_OK;
-
-page1_init_failed:
- releasePage(pPage1);
- pBt->pPage1 = 0;
- return rc;
-}
-
-/*
-** If there are no outstanding cursors and we are not in the middle
-** of a transaction but there is a read lock on the database, then
-** this routine unrefs the first page of the database file which
-** has the effect of releasing the read lock.
-**
-** If there is a transaction in progress, this routine is a no-op.
-*/
-static void unlockBtreeIfUnused(BtShared *pBt){
- assert( sqlite3_mutex_held(pBt->mutex) );
- assert( pBt->pCursor==0 || pBt->inTransaction>TRANS_NONE );
- if( pBt->inTransaction==TRANS_NONE && pBt->pPage1!=0 ){
- assert( pBt->pPage1->aData );
- assert( sqlite3PagerRefcount(pBt->pPager)==1 );
- assert( pBt->pPage1->aData );
- releasePage(pBt->pPage1);
- pBt->pPage1 = 0;
- }
-}
-
-/*
-** If pBt points to an empty file then convert that empty file
-** into a new empty database by initializing the first page of
-** the database.
-*/
-static int newDatabase(BtShared *pBt){
- MemPage *pP1;
- unsigned char *data;
- int rc;
- int nPage;
-
- assert( sqlite3_mutex_held(pBt->mutex) );
- /* The database size has already been measured and cached, so failure
- ** is impossible here. If the original size measurement failed, then
- ** processing aborts before entering this routine. */
- rc = sqlite3PagerPagecount(pBt->pPager, &nPage);
- if( NEVER(rc!=SQLITE_OK) || nPage>0 ){
- return rc;
- }
- pP1 = pBt->pPage1;
- assert( pP1!=0 );
- data = pP1->aData;
- rc = sqlite3PagerWrite(pP1->pDbPage);
- if( rc ) return rc;
- memcpy(data, zMagicHeader, sizeof(zMagicHeader));
- assert( sizeof(zMagicHeader)==16 );
- put2byte(&data[16], pBt->pageSize);
- data[18] = 1;
- data[19] = 1;
- assert( pBt->usableSize<=pBt->pageSize && pBt->usableSize+255>=pBt->pageSize);
- data[20] = (u8)(pBt->pageSize - pBt->usableSize);
- data[21] = 64;
- data[22] = 32;
- data[23] = 32;
- memset(&data[24], 0, 100-24);
- zeroPage(pP1, PTF_INTKEY|PTF_LEAF|PTF_LEAFDATA );
- pBt->pageSizeFixed = 1;
-#ifndef SQLITE_OMIT_AUTOVACUUM
- assert( pBt->autoVacuum==1 || pBt->autoVacuum==0 );
- assert( pBt->incrVacuum==1 || pBt->incrVacuum==0 );
- put4byte(&data[36 + 4*4], pBt->autoVacuum);
- put4byte(&data[36 + 7*4], pBt->incrVacuum);
-#endif
- return SQLITE_OK;
-}
-
-/*
-** Attempt to start a new transaction. A write-transaction
-** is started if the second argument is nonzero, otherwise a read-
-** transaction. If the second argument is 2 or more and exclusive
-** transaction is started, meaning that no other process is allowed
-** to access the database. A preexisting transaction may not be
-** upgraded to exclusive by calling this routine a second time - the
-** exclusivity flag only works for a new transaction.
-**
-** A write-transaction must be started before attempting any
-** changes to the database. None of the following routines
-** will work unless a transaction is started first:
-**
-** sqlite3BtreeCreateTable()
-** sqlite3BtreeCreateIndex()
-** sqlite3BtreeClearTable()
-** sqlite3BtreeDropTable()
-** sqlite3BtreeInsert()
-** sqlite3BtreeDelete()
-** sqlite3BtreeUpdateMeta()
-**
-** If an initial attempt to acquire the lock fails because of lock contention
-** and the database was previously unlocked, then invoke the busy handler
-** if there is one. But if there was previously a read-lock, do not
-** invoke the busy handler - just return SQLITE_BUSY. SQLITE_BUSY is
-** returned when there is already a read-lock in order to avoid a deadlock.
-**
-** Suppose there are two processes A and B. A has a read lock and B has
-** a reserved lock. B tries to promote to exclusive but is blocked because
-** of A's read lock. A tries to promote to reserved but is blocked by B.
-** One or the other of the two processes must give way or there can be
-** no progress. By returning SQLITE_BUSY and not invoking the busy callback
-** when A already has a read lock, we encourage A to give up and let B
-** proceed.
-*/
-SQLITE_PRIVATE int sqlite3BtreeBeginTrans(Btree *p, int wrflag){
- sqlite3 *pBlock = 0;
- BtShared *pBt = p->pBt;
- int rc = SQLITE_OK;
-
- sqlite3BtreeEnter(p);
- btreeIntegrity(p);
-
- /* If the btree is already in a write-transaction, or it
- ** is already in a read-transaction and a read-transaction
- ** is requested, this is a no-op.
- */
- if( p->inTrans==TRANS_WRITE || (p->inTrans==TRANS_READ && !wrflag) ){
- goto trans_begun;
- }
-
- /* Write transactions are not possible on a read-only database */
- if( pBt->readOnly && wrflag ){
- rc = SQLITE_READONLY;
- goto trans_begun;
- }
-
-#ifndef SQLITE_OMIT_SHARED_CACHE
- /* If another database handle has already opened a write transaction
- ** on this shared-btree structure and a second write transaction is
- ** requested, return SQLITE_LOCKED.
- */
- if( (wrflag && pBt->inTransaction==TRANS_WRITE) || pBt->isPending ){
- pBlock = pBt->pWriter->db;
- }else if( wrflag>1 ){
- BtLock *pIter;
- for(pIter=pBt->pLock; pIter; pIter=pIter->pNext){
- if( pIter->pBtree!=p ){
- pBlock = pIter->pBtree->db;
- break;
- }
- }
- }
- if( pBlock ){
- sqlite3ConnectionBlocked(p->db, pBlock);
- rc = SQLITE_LOCKED_SHAREDCACHE;
- goto trans_begun;
- }
-#endif
-
- /* Any read-only or read-write transaction implies a read-lock on
- ** page 1. So if some other shared-cache client already has a write-lock
- ** on page 1, the transaction cannot be opened. */
- rc = querySharedCacheTableLock(p, MASTER_ROOT, READ_LOCK);
- if( SQLITE_OK!=rc ) goto trans_begun;
-
- do {
- /* Call lockBtree() until either pBt->pPage1 is populated or
- ** lockBtree() returns something other than SQLITE_OK. lockBtree()
- ** may return SQLITE_OK but leave pBt->pPage1 set to 0 if after
- ** reading page 1 it discovers that the page-size of the database
- ** file is not pBt->pageSize. In this case lockBtree() will update
- ** pBt->pageSize to the page-size of the file on disk.
- */
- while( pBt->pPage1==0 && SQLITE_OK==(rc = lockBtree(pBt)) );
-
- if( rc==SQLITE_OK && wrflag ){
- if( pBt->readOnly ){
- rc = SQLITE_READONLY;
- }else{
- rc = sqlite3PagerBegin(pBt->pPager,wrflag>1,sqlite3TempInMemory(p->db));
- if( rc==SQLITE_OK ){
- rc = newDatabase(pBt);
- }
- }
- }
-
- if( rc!=SQLITE_OK ){
- unlockBtreeIfUnused(pBt);
- }
- }while( rc==SQLITE_BUSY && pBt->inTransaction==TRANS_NONE &&
- btreeInvokeBusyHandler(pBt) );
-
- if( rc==SQLITE_OK ){
- if( p->inTrans==TRANS_NONE ){
- pBt->nTransaction++;
-#ifndef SQLITE_OMIT_SHARED_CACHE
- if( p->sharable ){
- assert( p->lock.pBtree==p && p->lock.iTable==1 );
- p->lock.eLock = READ_LOCK;
- p->lock.pNext = pBt->pLock;
- pBt->pLock = &p->lock;
- }
-#endif
- }
- p->inTrans = (wrflag?TRANS_WRITE:TRANS_READ);
- if( p->inTrans>pBt->inTransaction ){
- pBt->inTransaction = p->inTrans;
- }
-#ifndef SQLITE_OMIT_SHARED_CACHE
- if( wrflag ){
- assert( !pBt->pWriter );
- pBt->pWriter = p;
- pBt->isExclusive = (u8)(wrflag>1);
- }
-#endif
- }
-
-
-trans_begun:
- if( rc==SQLITE_OK && wrflag ){
- /* This call makes sure that the pager has the correct number of
- ** open savepoints. If the second parameter is greater than 0 and
- ** the sub-journal is not already open, then it will be opened here.
- */
- rc = sqlite3PagerOpenSavepoint(pBt->pPager, p->db->nSavepoint);
- }
-
- btreeIntegrity(p);
- sqlite3BtreeLeave(p);
- return rc;
-}
-
-#ifndef SQLITE_OMIT_AUTOVACUUM
-
-/*
-** Set the pointer-map entries for all children of page pPage. Also, if
-** pPage contains cells that point to overflow pages, set the pointer
-** map entries for the overflow pages as well.
-*/
-static int setChildPtrmaps(MemPage *pPage){
- int i; /* Counter variable */
- int nCell; /* Number of cells in page pPage */
- int rc; /* Return code */
- BtShared *pBt = pPage->pBt;
- u8 isInitOrig = pPage->isInit;
- Pgno pgno = pPage->pgno;
-
- assert( sqlite3_mutex_held(pPage->pBt->mutex) );
- rc = btreeInitPage(pPage);
- if( rc!=SQLITE_OK ){
- goto set_child_ptrmaps_out;
- }
- nCell = pPage->nCell;
-
- for(i=0; i<nCell; i++){
- u8 *pCell = findCell(pPage, i);
-
- ptrmapPutOvflPtr(pPage, pCell, &rc);
-
- if( !pPage->leaf ){
- Pgno childPgno = get4byte(pCell);
- ptrmapPut(pBt, childPgno, PTRMAP_BTREE, pgno, &rc);
- }
- }
-
- if( !pPage->leaf ){
- Pgno childPgno = get4byte(&pPage->aData[pPage->hdrOffset+8]);
- ptrmapPut(pBt, childPgno, PTRMAP_BTREE, pgno, &rc);
- }
-
-set_child_ptrmaps_out:
- pPage->isInit = isInitOrig;
- return rc;
-}
-
-/*
-** Somewhere on pPage is a pointer to page iFrom. Modify this pointer so
-** that it points to iTo. Parameter eType describes the type of pointer to
-** be modified, as follows:
-**
-** PTRMAP_BTREE: pPage is a btree-page. The pointer points at a child
-** page of pPage.
-**
-** PTRMAP_OVERFLOW1: pPage is a btree-page. The pointer points at an overflow
-** page pointed to by one of the cells on pPage.
-**
-** PTRMAP_OVERFLOW2: pPage is an overflow-page. The pointer points at the next
-** overflow page in the list.
-*/
-static int modifyPagePointer(MemPage *pPage, Pgno iFrom, Pgno iTo, u8 eType){
- assert( sqlite3_mutex_held(pPage->pBt->mutex) );
- assert( sqlite3PagerIswriteable(pPage->pDbPage) );
- if( eType==PTRMAP_OVERFLOW2 ){
- /* The pointer is always the first 4 bytes of the page in this case. */
- if( get4byte(pPage->aData)!=iFrom ){
- return SQLITE_CORRUPT_BKPT;
- }
- put4byte(pPage->aData, iTo);
- }else{
- u8 isInitOrig = pPage->isInit;
- int i;
- int nCell;
-
- btreeInitPage(pPage);
- nCell = pPage->nCell;
-
- for(i=0; i<nCell; i++){
- u8 *pCell = findCell(pPage, i);
- if( eType==PTRMAP_OVERFLOW1 ){
- CellInfo info;
- btreeParseCellPtr(pPage, pCell, &info);
- if( info.iOverflow ){
- if( iFrom==get4byte(&pCell[info.iOverflow]) ){
- put4byte(&pCell[info.iOverflow], iTo);
- break;
- }
- }
- }else{
- if( get4byte(pCell)==iFrom ){
- put4byte(pCell, iTo);
- break;
- }
- }
- }
-
- if( i==nCell ){
- if( eType!=PTRMAP_BTREE ||
- get4byte(&pPage->aData[pPage->hdrOffset+8])!=iFrom ){
- return SQLITE_CORRUPT_BKPT;
- }
- put4byte(&pPage->aData[pPage->hdrOffset+8], iTo);
- }
-
- pPage->isInit = isInitOrig;
- }
- return SQLITE_OK;
-}
-
-
-/*
-** Move the open database page pDbPage to location iFreePage in the
-** database. The pDbPage reference remains valid.
-**
-** The isCommit flag indicates that there is no need to remember that
-** the journal needs to be sync()ed before database page pDbPage->pgno
-** can be written to. The caller has already promised not to write to that
-** page.
-*/
-static int relocatePage(
- BtShared *pBt, /* Btree */
- MemPage *pDbPage, /* Open page to move */
- u8 eType, /* Pointer map 'type' entry for pDbPage */
- Pgno iPtrPage, /* Pointer map 'page-no' entry for pDbPage */
- Pgno iFreePage, /* The location to move pDbPage to */
- int isCommit /* isCommit flag passed to sqlite3PagerMovepage */
-){
- MemPage *pPtrPage; /* The page that contains a pointer to pDbPage */
- Pgno iDbPage = pDbPage->pgno;
- Pager *pPager = pBt->pPager;
- int rc;
-
- assert( eType==PTRMAP_OVERFLOW2 || eType==PTRMAP_OVERFLOW1 ||
- eType==PTRMAP_BTREE || eType==PTRMAP_ROOTPAGE );
- assert( sqlite3_mutex_held(pBt->mutex) );
- assert( pDbPage->pBt==pBt );
-
- /* Move page iDbPage from its current location to page number iFreePage */
- TRACE(("AUTOVACUUM: Moving %d to free page %d (ptr page %d type %d)\n",
- iDbPage, iFreePage, iPtrPage, eType));
- rc = sqlite3PagerMovepage(pPager, pDbPage->pDbPage, iFreePage, isCommit);
- if( rc!=SQLITE_OK ){
- return rc;
- }
- pDbPage->pgno = iFreePage;
-
- /* If pDbPage was a btree-page, then it may have child pages and/or cells
- ** that point to overflow pages. The pointer map entries for all these
- ** pages need to be changed.
- **
- ** If pDbPage is an overflow page, then the first 4 bytes may store a
- ** pointer to a subsequent overflow page. If this is the case, then
- ** the pointer map needs to be updated for the subsequent overflow page.
- */
- if( eType==PTRMAP_BTREE || eType==PTRMAP_ROOTPAGE ){
- rc = setChildPtrmaps(pDbPage);
- if( rc!=SQLITE_OK ){
- return rc;
- }
- }else{
- Pgno nextOvfl = get4byte(pDbPage->aData);
- if( nextOvfl!=0 ){
- ptrmapPut(pBt, nextOvfl, PTRMAP_OVERFLOW2, iFreePage, &rc);
- if( rc!=SQLITE_OK ){
- return rc;
- }
- }
- }
-
- /* Fix the database pointer on page iPtrPage that pointed at iDbPage so
- ** that it points at iFreePage. Also fix the pointer map entry for
- ** iPtrPage.
- */
- if( eType!=PTRMAP_ROOTPAGE ){
- rc = btreeGetPage(pBt, iPtrPage, &pPtrPage, 0);
- if( rc!=SQLITE_OK ){
- return rc;
- }
- rc = sqlite3PagerWrite(pPtrPage->pDbPage);
- if( rc!=SQLITE_OK ){
- releasePage(pPtrPage);
- return rc;
- }
- rc = modifyPagePointer(pPtrPage, iDbPage, iFreePage, eType);
- releasePage(pPtrPage);
- if( rc==SQLITE_OK ){
- ptrmapPut(pBt, iFreePage, eType, iPtrPage, &rc);
- }
- }
- return rc;
-}
-
-/* Forward declaration required by incrVacuumStep(). */
-static int allocateBtreePage(BtShared *, MemPage **, Pgno *, Pgno, u8);
-
-/*
-** Perform a single step of an incremental-vacuum. If successful,
-** return SQLITE_OK. If there is no work to do (and therefore no
-** point in calling this function again), return SQLITE_DONE.
-**
-** More specificly, this function attempts to re-organize the
-** database so that the last page of the file currently in use
-** is no longer in use.
-**
-** If the nFin parameter is non-zero, this function assumes
-** that the caller will keep calling incrVacuumStep() until
-** it returns SQLITE_DONE or an error, and that nFin is the
-** number of pages the database file will contain after this
-** process is complete. If nFin is zero, it is assumed that
-** incrVacuumStep() will be called a finite amount of times
-** which may or may not empty the freelist. A full autovacuum
-** has nFin>0. A "PRAGMA incremental_vacuum" has nFin==0.
-*/
-static int incrVacuumStep(BtShared *pBt, Pgno nFin, Pgno iLastPg){
- Pgno nFreeList; /* Number of pages still on the free-list */
-
- assert( sqlite3_mutex_held(pBt->mutex) );
- assert( iLastPg>nFin );
-
- if( !PTRMAP_ISPAGE(pBt, iLastPg) && iLastPg!=PENDING_BYTE_PAGE(pBt) ){
- int rc;
- u8 eType;
- Pgno iPtrPage;
-
- nFreeList = get4byte(&pBt->pPage1->aData[36]);
- if( nFreeList==0 ){
- return SQLITE_DONE;
- }
-
- rc = ptrmapGet(pBt, iLastPg, &eType, &iPtrPage);
- if( rc!=SQLITE_OK ){
- return rc;
- }
- if( eType==PTRMAP_ROOTPAGE ){
- return SQLITE_CORRUPT_BKPT;
- }
-
- if( eType==PTRMAP_FREEPAGE ){
- if( nFin==0 ){
- /* Remove the page from the files free-list. This is not required
- ** if nFin is non-zero. In that case, the free-list will be
- ** truncated to zero after this function returns, so it doesn't
- ** matter if it still contains some garbage entries.
- */
- Pgno iFreePg;
- MemPage *pFreePg;
- rc = allocateBtreePage(pBt, &pFreePg, &iFreePg, iLastPg, 1);
- if( rc!=SQLITE_OK ){
- return rc;
- }
- assert( iFreePg==iLastPg );
- releasePage(pFreePg);
- }
- } else {
- Pgno iFreePg; /* Index of free page to move pLastPg to */
- MemPage *pLastPg;
-
- rc = btreeGetPage(pBt, iLastPg, &pLastPg, 0);
- if( rc!=SQLITE_OK ){
- return rc;
- }
-
- /* If nFin is zero, this loop runs exactly once and page pLastPg
- ** is swapped with the first free page pulled off the free list.
- **
- ** On the other hand, if nFin is greater than zero, then keep
- ** looping until a free-page located within the first nFin pages
- ** of the file is found.
- */
- do {
- MemPage *pFreePg;
- rc = allocateBtreePage(pBt, &pFreePg, &iFreePg, 0, 0);
- if( rc!=SQLITE_OK ){
- releasePage(pLastPg);
- return rc;
- }
- releasePage(pFreePg);
- }while( nFin!=0 && iFreePg>nFin );
- assert( iFreePg<iLastPg );
-
- rc = sqlite3PagerWrite(pLastPg->pDbPage);
- if( rc==SQLITE_OK ){
- rc = relocatePage(pBt, pLastPg, eType, iPtrPage, iFreePg, nFin!=0);
- }
- releasePage(pLastPg);
- if( rc!=SQLITE_OK ){
- return rc;
- }
- }
- }
-
- if( nFin==0 ){
- iLastPg--;
- while( iLastPg==PENDING_BYTE_PAGE(pBt)||PTRMAP_ISPAGE(pBt, iLastPg) ){
- if( PTRMAP_ISPAGE(pBt, iLastPg) ){
- MemPage *pPg;
- int rc = btreeGetPage(pBt, iLastPg, &pPg, 0);
- if( rc!=SQLITE_OK ){
- return rc;
- }
- rc = sqlite3PagerWrite(pPg->pDbPage);
- releasePage(pPg);
- if( rc!=SQLITE_OK ){
- return rc;
- }
- }
- iLastPg--;
- }
- sqlite3PagerTruncateImage(pBt->pPager, iLastPg);
- }
- return SQLITE_OK;
-}
-
-/*
-** A write-transaction must be opened before calling this function.
-** It performs a single unit of work towards an incremental vacuum.
-**
-** If the incremental vacuum is finished after this function has run,
-** SQLITE_DONE is returned. If it is not finished, but no error occurred,
-** SQLITE_OK is returned. Otherwise an SQLite error code.
-*/
-SQLITE_PRIVATE int sqlite3BtreeIncrVacuum(Btree *p){
- int rc;
- BtShared *pBt = p->pBt;
-
- sqlite3BtreeEnter(p);
- assert( pBt->inTransaction==TRANS_WRITE && p->inTrans==TRANS_WRITE );
- if( !pBt->autoVacuum ){
- rc = SQLITE_DONE;
- }else{
- invalidateAllOverflowCache(pBt);
- rc = incrVacuumStep(pBt, 0, pagerPagecount(pBt));
- }
- sqlite3BtreeLeave(p);
- return rc;
-}
-
-/*
-** This routine is called prior to sqlite3PagerCommit when a transaction
-** is commited for an auto-vacuum database.
-**
-** If SQLITE_OK is returned, then *pnTrunc is set to the number of pages
-** the database file should be truncated to during the commit process.
-** i.e. the database has been reorganized so that only the first *pnTrunc
-** pages are in use.
-*/
-static int autoVacuumCommit(BtShared *pBt){
- int rc = SQLITE_OK;
- Pager *pPager = pBt->pPager;
- VVA_ONLY( int nRef = sqlite3PagerRefcount(pPager) );
-
- assert( sqlite3_mutex_held(pBt->mutex) );
- invalidateAllOverflowCache(pBt);
- assert(pBt->autoVacuum);
- if( !pBt->incrVacuum ){
- Pgno nFin; /* Number of pages in database after autovacuuming */
- Pgno nFree; /* Number of pages on the freelist initially */
- Pgno nPtrmap; /* Number of PtrMap pages to be freed */
- Pgno iFree; /* The next page to be freed */
- int nEntry; /* Number of entries on one ptrmap page */
- Pgno nOrig; /* Database size before freeing */
-
- nOrig = pagerPagecount(pBt);
- if( PTRMAP_ISPAGE(pBt, nOrig) || nOrig==PENDING_BYTE_PAGE(pBt) ){
- /* It is not possible to create a database for which the final page
- ** is either a pointer-map page or the pending-byte page. If one
- ** is encountered, this indicates corruption.
- */
- return SQLITE_CORRUPT_BKPT;
- }
-
- nFree = get4byte(&pBt->pPage1->aData[36]);
- nEntry = pBt->usableSize/5;
- nPtrmap = (nFree-nOrig+PTRMAP_PAGENO(pBt, nOrig)+nEntry)/nEntry;
- nFin = nOrig - nFree - nPtrmap;
- if( nOrig>PENDING_BYTE_PAGE(pBt) && nFin<PENDING_BYTE_PAGE(pBt) ){
- nFin--;
- }
- while( PTRMAP_ISPAGE(pBt, nFin) || nFin==PENDING_BYTE_PAGE(pBt) ){
- nFin--;
- }
- if( nFin>nOrig ) return SQLITE_CORRUPT_BKPT;
-
- for(iFree=nOrig; iFree>nFin && rc==SQLITE_OK; iFree--){
- rc = incrVacuumStep(pBt, nFin, iFree);
- }
- if( (rc==SQLITE_DONE || rc==SQLITE_OK) && nFree>0 ){
- rc = SQLITE_OK;
- rc = sqlite3PagerWrite(pBt->pPage1->pDbPage);
- put4byte(&pBt->pPage1->aData[32], 0);
- put4byte(&pBt->pPage1->aData[36], 0);
- sqlite3PagerTruncateImage(pBt->pPager, nFin);
- }
- if( rc!=SQLITE_OK ){
- sqlite3PagerRollback(pPager);
- }
- }
-
- assert( nRef==sqlite3PagerRefcount(pPager) );
- return rc;
-}
-
-#else /* ifndef SQLITE_OMIT_AUTOVACUUM */
-# define setChildPtrmaps(x) SQLITE_OK
-#endif
-
-/*
-** This routine does the first phase of a two-phase commit. This routine
-** causes a rollback journal to be created (if it does not already exist)
-** and populated with enough information so that if a power loss occurs
-** the database can be restored to its original state by playing back
-** the journal. Then the contents of the journal are flushed out to
-** the disk. After the journal is safely on oxide, the changes to the
-** database are written into the database file and flushed to oxide.
-** At the end of this call, the rollback journal still exists on the
-** disk and we are still holding all locks, so the transaction has not
-** committed. See sqlite3BtreeCommitPhaseTwo() for the second phase of the
-** commit process.
-**
-** This call is a no-op if no write-transaction is currently active on pBt.
-**
-** Otherwise, sync the database file for the btree pBt. zMaster points to
-** the name of a master journal file that should be written into the
-** individual journal file, or is NULL, indicating no master journal file
-** (single database transaction).
-**
-** When this is called, the master journal should already have been
-** created, populated with this journal pointer and synced to disk.
-**
-** Once this is routine has returned, the only thing required to commit
-** the write-transaction for this database file is to delete the journal.
-*/
-SQLITE_PRIVATE int sqlite3BtreeCommitPhaseOne(Btree *p, const char *zMaster){
- int rc = SQLITE_OK;
- if( p->inTrans==TRANS_WRITE ){
- BtShared *pBt = p->pBt;
- sqlite3BtreeEnter(p);
-#ifndef SQLITE_OMIT_AUTOVACUUM
- if( pBt->autoVacuum ){
- rc = autoVacuumCommit(pBt);
- if( rc!=SQLITE_OK ){
- sqlite3BtreeLeave(p);
- return rc;
- }
- }
-#endif
- rc = sqlite3PagerCommitPhaseOne(pBt->pPager, zMaster, 0);
- sqlite3BtreeLeave(p);
- }
- return rc;
-}
-
-/*
-** This function is called from both BtreeCommitPhaseTwo() and BtreeRollback()
-** at the conclusion of a transaction.
-*/
-static void btreeEndTransaction(Btree *p){
- BtShared *pBt = p->pBt;
- BtCursor *pCsr;
- assert( sqlite3BtreeHoldsMutex(p) );
-
- /* Search for a cursor held open by this b-tree connection. If one exists,
- ** then the transaction will be downgraded to a read-only transaction
- ** instead of actually concluded. A subsequent call to CommitPhaseTwo()
- ** or Rollback() will finish the transaction and unlock the database. */
- for(pCsr=pBt->pCursor; pCsr && pCsr->pBtree!=p; pCsr=pCsr->pNext);
- assert( pCsr==0 || p->inTrans>TRANS_NONE );
-
- btreeClearHasContent(pBt);
- if( pCsr ){
- downgradeAllSharedCacheTableLocks(p);
- p->inTrans = TRANS_READ;
- }else{
- /* If the handle had any kind of transaction open, decrement the
- ** transaction count of the shared btree. If the transaction count
- ** reaches 0, set the shared state to TRANS_NONE. The unlockBtreeIfUnused()
- ** call below will unlock the pager. */
- if( p->inTrans!=TRANS_NONE ){
- clearAllSharedCacheTableLocks(p);
- pBt->nTransaction--;
- if( 0==pBt->nTransaction ){
- pBt->inTransaction = TRANS_NONE;
- }
- }
-
- /* Set the current transaction state to TRANS_NONE and unlock the
- ** pager if this call closed the only read or write transaction. */
- p->inTrans = TRANS_NONE;
- unlockBtreeIfUnused(pBt);
- }
-
- btreeIntegrity(p);
-}
-
-/*
-** Commit the transaction currently in progress.
-**
-** This routine implements the second phase of a 2-phase commit. The
-** sqlite3BtreeCommitPhaseOne() routine does the first phase and should
-** be invoked prior to calling this routine. The sqlite3BtreeCommitPhaseOne()
-** routine did all the work of writing information out to disk and flushing the
-** contents so that they are written onto the disk platter. All this
-** routine has to do is delete or truncate or zero the header in the
-** the rollback journal (which causes the transaction to commit) and
-** drop locks.
-**
-** This will release the write lock on the database file. If there
-** are no active cursors, it also releases the read lock.
-*/
-SQLITE_PRIVATE int sqlite3BtreeCommitPhaseTwo(Btree *p){
- BtShared *pBt = p->pBt;
-
- sqlite3BtreeEnter(p);
- btreeIntegrity(p);
-
- /* If the handle has a write-transaction open, commit the shared-btrees
- ** transaction and set the shared state to TRANS_READ.
- */
- if( p->inTrans==TRANS_WRITE ){
- int rc;
- assert( pBt->inTransaction==TRANS_WRITE );
- assert( pBt->nTransaction>0 );
- rc = sqlite3PagerCommitPhaseTwo(pBt->pPager);
- if( rc!=SQLITE_OK ){
- sqlite3BtreeLeave(p);
- return rc;
- }
- pBt->inTransaction = TRANS_READ;
- }
-
- btreeEndTransaction(p);
- sqlite3BtreeLeave(p);
- return SQLITE_OK;
-}
-
-/*
-** Do both phases of a commit.
-*/
-SQLITE_PRIVATE int sqlite3BtreeCommit(Btree *p){
- int rc;
- sqlite3BtreeEnter(p);
- rc = sqlite3BtreeCommitPhaseOne(p, 0);
- if( rc==SQLITE_OK ){
- rc = sqlite3BtreeCommitPhaseTwo(p);
- }
- sqlite3BtreeLeave(p);
- return rc;
-}
-
-#ifndef NDEBUG
-/*
-** Return the number of write-cursors open on this handle. This is for use
-** in assert() expressions, so it is only compiled if NDEBUG is not
-** defined.
-**
-** For the purposes of this routine, a write-cursor is any cursor that
-** is capable of writing to the databse. That means the cursor was
-** originally opened for writing and the cursor has not be disabled
-** by having its state changed to CURSOR_FAULT.
-*/
-static int countWriteCursors(BtShared *pBt){
- BtCursor *pCur;
- int r = 0;
- for(pCur=pBt->pCursor; pCur; pCur=pCur->pNext){
- if( pCur->wrFlag && pCur->eState!=CURSOR_FAULT ) r++;
- }
- return r;
-}
-#endif
-
-/*
-** This routine sets the state to CURSOR_FAULT and the error
-** code to errCode for every cursor on BtShared that pBtree
-** references.
-**
-** Every cursor is tripped, including cursors that belong
-** to other database connections that happen to be sharing
-** the cache with pBtree.
-**
-** This routine gets called when a rollback occurs.
-** All cursors using the same cache must be tripped
-** to prevent them from trying to use the btree after
-** the rollback. The rollback may have deleted tables
-** or moved root pages, so it is not sufficient to
-** save the state of the cursor. The cursor must be
-** invalidated.
-*/
-SQLITE_PRIVATE void sqlite3BtreeTripAllCursors(Btree *pBtree, int errCode){
- BtCursor *p;
- sqlite3BtreeEnter(pBtree);
- for(p=pBtree->pBt->pCursor; p; p=p->pNext){
- int i;
- sqlite3BtreeClearCursor(p);
- p->eState = CURSOR_FAULT;
- p->skipNext = errCode;
- for(i=0; i<=p->iPage; i++){
- releasePage(p->apPage[i]);
- p->apPage[i] = 0;
- }
- }
- sqlite3BtreeLeave(pBtree);
-}
-
-/*
-** Rollback the transaction in progress. All cursors will be
-** invalided by this operation. Any attempt to use a cursor
-** that was open at the beginning of this operation will result
-** in an error.
-**
-** This will release the write lock on the database file. If there
-** are no active cursors, it also releases the read lock.
-*/
-SQLITE_PRIVATE int sqlite3BtreeRollback(Btree *p){
- int rc;
- BtShared *pBt = p->pBt;
- MemPage *pPage1;
-
- sqlite3BtreeEnter(p);
- rc = saveAllCursors(pBt, 0, 0);
-#ifndef SQLITE_OMIT_SHARED_CACHE
- if( rc!=SQLITE_OK ){
- /* This is a horrible situation. An IO or malloc() error occurred whilst
- ** trying to save cursor positions. If this is an automatic rollback (as
- ** the result of a constraint, malloc() failure or IO error) then
- ** the cache may be internally inconsistent (not contain valid trees) so
- ** we cannot simply return the error to the caller. Instead, abort
- ** all queries that may be using any of the cursors that failed to save.
- */
- sqlite3BtreeTripAllCursors(p, rc);
- }
-#endif
- btreeIntegrity(p);
-
- if( p->inTrans==TRANS_WRITE ){
- int rc2;
-
- assert( TRANS_WRITE==pBt->inTransaction );
- rc2 = sqlite3PagerRollback(pBt->pPager);
- if( rc2!=SQLITE_OK ){
- rc = rc2;
- }
-
- /* The rollback may have destroyed the pPage1->aData value. So
- ** call btreeGetPage() on page 1 again to make
- ** sure pPage1->aData is set correctly. */
- if( btreeGetPage(pBt, 1, &pPage1, 0)==SQLITE_OK ){
- releasePage(pPage1);
- }
- assert( countWriteCursors(pBt)==0 );
- pBt->inTransaction = TRANS_READ;
- }
-
- btreeEndTransaction(p);
- sqlite3BtreeLeave(p);
- return rc;
-}
-
-/*
-** Start a statement subtransaction. The subtransaction can can be rolled
-** back independently of the main transaction. You must start a transaction
-** before starting a subtransaction. The subtransaction is ended automatically
-** if the main transaction commits or rolls back.
-**
-** Statement subtransactions are used around individual SQL statements
-** that are contained within a BEGIN...COMMIT block. If a constraint
-** error occurs within the statement, the effect of that one statement
-** can be rolled back without having to rollback the entire transaction.
-**
-** A statement sub-transaction is implemented as an anonymous savepoint. The
-** value passed as the second parameter is the total number of savepoints,
-** including the new anonymous savepoint, open on the B-Tree. i.e. if there
-** are no active savepoints and no other statement-transactions open,
-** iStatement is 1. This anonymous savepoint can be released or rolled back
-** using the sqlite3BtreeSavepoint() function.
-*/
-SQLITE_PRIVATE int sqlite3BtreeBeginStmt(Btree *p, int iStatement){
- int rc;
- BtShared *pBt = p->pBt;
- sqlite3BtreeEnter(p);
- assert( p->inTrans==TRANS_WRITE );
- assert( pBt->readOnly==0 );
- assert( iStatement>0 );
- assert( iStatement>p->db->nSavepoint );
- if( NEVER(p->inTrans!=TRANS_WRITE || pBt->readOnly) ){
- rc = SQLITE_INTERNAL;
- }else{
- assert( pBt->inTransaction==TRANS_WRITE );
- /* At the pager level, a statement transaction is a savepoint with
- ** an index greater than all savepoints created explicitly using
- ** SQL statements. It is illegal to open, release or rollback any
- ** such savepoints while the statement transaction savepoint is active.
- */
- rc = sqlite3PagerOpenSavepoint(pBt->pPager, iStatement);
- }
- sqlite3BtreeLeave(p);
- return rc;
-}
-
-/*
-** The second argument to this function, op, is always SAVEPOINT_ROLLBACK
-** or SAVEPOINT_RELEASE. This function either releases or rolls back the
-** savepoint identified by parameter iSavepoint, depending on the value
-** of op.
-**
-** Normally, iSavepoint is greater than or equal to zero. However, if op is
-** SAVEPOINT_ROLLBACK, then iSavepoint may also be -1. In this case the
-** contents of the entire transaction are rolled back. This is different
-** from a normal transaction rollback, as no locks are released and the
-** transaction remains open.
-*/
-SQLITE_PRIVATE int sqlite3BtreeSavepoint(Btree *p, int op, int iSavepoint){
- int rc = SQLITE_OK;
- if( p && p->inTrans==TRANS_WRITE ){
- BtShared *pBt = p->pBt;
- assert( op==SAVEPOINT_RELEASE || op==SAVEPOINT_ROLLBACK );
- assert( iSavepoint>=0 || (iSavepoint==-1 && op==SAVEPOINT_ROLLBACK) );
- sqlite3BtreeEnter(p);
- rc = sqlite3PagerSavepoint(pBt->pPager, op, iSavepoint);
- if( rc==SQLITE_OK ){
- rc = newDatabase(pBt);
- }
- sqlite3BtreeLeave(p);
- }
- return rc;
-}
-
-/*
-** Create a new cursor for the BTree whose root is on the page
-** iTable. If a read-only cursor is requested, it is assumed that
-** the caller already has at least a read-only transaction open
-** on the database already. If a write-cursor is requested, then
-** the caller is assumed to have an open write transaction.
-**
-** If wrFlag==0, then the cursor can only be used for reading.
-** If wrFlag==1, then the cursor can be used for reading or for
-** writing if other conditions for writing are also met. These
-** are the conditions that must be met in order for writing to
-** be allowed:
-**
-** 1: The cursor must have been opened with wrFlag==1
-**
-** 2: Other database connections that share the same pager cache
-** but which are not in the READ_UNCOMMITTED state may not have
-** cursors open with wrFlag==0 on the same table. Otherwise
-** the changes made by this write cursor would be visible to
-** the read cursors in the other database connection.
-**
-** 3: The database must be writable (not on read-only media)
-**
-** 4: There must be an active transaction.
-**
-** No checking is done to make sure that page iTable really is the
-** root page of a b-tree. If it is not, then the cursor acquired
-** will not work correctly.
-**
-** It is assumed that the sqlite3BtreeCursorSize() bytes of memory
-** pointed to by pCur have been zeroed by the caller.
-*/
-static int btreeCursor(
- Btree *p, /* The btree */
- int iTable, /* Root page of table to open */
- int wrFlag, /* 1 to write. 0 read-only */
- struct KeyInfo *pKeyInfo, /* First arg to comparison function */
- BtCursor *pCur /* Space for new cursor */
-){
- BtShared *pBt = p->pBt; /* Shared b-tree handle */
-
- assert( sqlite3BtreeHoldsMutex(p) );
- assert( wrFlag==0 || wrFlag==1 );
-
- /* The following assert statements verify that if this is a sharable
- ** b-tree database, the connection is holding the required table locks,
- ** and that no other connection has any open cursor that conflicts with
- ** this lock. */
- assert( hasSharedCacheTableLock(p, iTable, pKeyInfo!=0, wrFlag+1) );
- assert( wrFlag==0 || !hasReadConflicts(p, iTable) );
-
- /* Assert that the caller has opened the required transaction. */
- assert( p->inTrans>TRANS_NONE );
- assert( wrFlag==0 || p->inTrans==TRANS_WRITE );
- assert( pBt->pPage1 && pBt->pPage1->aData );
-
- if( NEVER(wrFlag && pBt->readOnly) ){
- return SQLITE_READONLY;
- }
- if( iTable==1 && pagerPagecount(pBt)==0 ){
- return SQLITE_EMPTY;
- }
-
- /* Now that no other errors can occur, finish filling in the BtCursor
- ** variables and link the cursor into the BtShared list. */
- pCur->pgnoRoot = (Pgno)iTable;
- pCur->iPage = -1;
- pCur->pKeyInfo = pKeyInfo;
- pCur->pBtree = p;
- pCur->pBt = pBt;
- pCur->wrFlag = (u8)wrFlag;
- pCur->pNext = pBt->pCursor;
- if( pCur->pNext ){
- pCur->pNext->pPrev = pCur;
- }
- pBt->pCursor = pCur;
- pCur->eState = CURSOR_INVALID;
- pCur->cachedRowid = 0;
- return SQLITE_OK;
-}
-SQLITE_PRIVATE int sqlite3BtreeCursor(
- Btree *p, /* The btree */
- int iTable, /* Root page of table to open */
- int wrFlag, /* 1 to write. 0 read-only */
- struct KeyInfo *pKeyInfo, /* First arg to xCompare() */
- BtCursor *pCur /* Write new cursor here */
-){
- int rc;
- sqlite3BtreeEnter(p);
- rc = btreeCursor(p, iTable, wrFlag, pKeyInfo, pCur);
- sqlite3BtreeLeave(p);
- return rc;
-}
-
-/*
-** Return the size of a BtCursor object in bytes.
-**
-** This interfaces is needed so that users of cursors can preallocate
-** sufficient storage to hold a cursor. The BtCursor object is opaque
-** to users so they cannot do the sizeof() themselves - they must call
-** this routine.
-*/
-SQLITE_PRIVATE int sqlite3BtreeCursorSize(void){
- return sizeof(BtCursor);
-}
-
-/*
-** Set the cached rowid value of every cursor in the same database file
-** as pCur and having the same root page number as pCur. The value is
-** set to iRowid.
-**
-** Only positive rowid values are considered valid for this cache.
-** The cache is initialized to zero, indicating an invalid cache.
-** A btree will work fine with zero or negative rowids. We just cannot
-** cache zero or negative rowids, which means tables that use zero or
-** negative rowids might run a little slower. But in practice, zero
-** or negative rowids are very uncommon so this should not be a problem.
-*/
-SQLITE_PRIVATE void sqlite3BtreeSetCachedRowid(BtCursor *pCur, sqlite3_int64 iRowid){
- BtCursor *p;
- for(p=pCur->pBt->pCursor; p; p=p->pNext){
- if( p->pgnoRoot==pCur->pgnoRoot ) p->cachedRowid = iRowid;
- }
- assert( pCur->cachedRowid==iRowid );
-}
-
-/*
-** Return the cached rowid for the given cursor. A negative or zero
-** return value indicates that the rowid cache is invalid and should be
-** ignored. If the rowid cache has never before been set, then a
-** zero is returned.
-*/
-SQLITE_PRIVATE sqlite3_int64 sqlite3BtreeGetCachedRowid(BtCursor *pCur){
- return pCur->cachedRowid;
-}
-
-/*
-** Close a cursor. The read lock on the database file is released
-** when the last cursor is closed.
-*/
-SQLITE_PRIVATE int sqlite3BtreeCloseCursor(BtCursor *pCur){
- Btree *pBtree = pCur->pBtree;
- if( pBtree ){
- int i;
- BtShared *pBt = pCur->pBt;
- sqlite3BtreeEnter(pBtree);
- sqlite3BtreeClearCursor(pCur);
- if( pCur->pPrev ){
- pCur->pPrev->pNext = pCur->pNext;
- }else{
- pBt->pCursor = pCur->pNext;
- }
- if( pCur->pNext ){
- pCur->pNext->pPrev = pCur->pPrev;
- }
- for(i=0; i<=pCur->iPage; i++){
- releasePage(pCur->apPage[i]);
- }
- unlockBtreeIfUnused(pBt);
- invalidateOverflowCache(pCur);
- /* sqlite3_free(pCur); */
- sqlite3BtreeLeave(pBtree);
- }
- return SQLITE_OK;
-}
-
-/*
-** Make sure the BtCursor* given in the argument has a valid
-** BtCursor.info structure. If it is not already valid, call
-** btreeParseCell() to fill it in.
-**
-** BtCursor.info is a cache of the information in the current cell.
-** Using this cache reduces the number of calls to btreeParseCell().
-**
-** 2007-06-25: There is a bug in some versions of MSVC that cause the
-** compiler to crash when getCellInfo() is implemented as a macro.
-** But there is a measureable speed advantage to using the macro on gcc
-** (when less compiler optimizations like -Os or -O0 are used and the
-** compiler is not doing agressive inlining.) So we use a real function
-** for MSVC and a macro for everything else. Ticket #2457.
-*/
-#ifndef NDEBUG
- static void assertCellInfo(BtCursor *pCur){
- CellInfo info;
- int iPage = pCur->iPage;
- memset(&info, 0, sizeof(info));
- btreeParseCell(pCur->apPage[iPage], pCur->aiIdx[iPage], &info);
- assert( memcmp(&info, &pCur->info, sizeof(info))==0 );
- }
-#else
- #define assertCellInfo(x)
-#endif
-#ifdef _MSC_VER
- /* Use a real function in MSVC to work around bugs in that compiler. */
- static void getCellInfo(BtCursor *pCur){
- if( pCur->info.nSize==0 ){
- int iPage = pCur->iPage;
- btreeParseCell(pCur->apPage[iPage],pCur->aiIdx[iPage],&pCur->info);
- pCur->validNKey = 1;
- }else{
- assertCellInfo(pCur);
- }
- }
-#else /* if not _MSC_VER */
- /* Use a macro in all other compilers so that the function is inlined */
-#define getCellInfo(pCur) \
- if( pCur->info.nSize==0 ){ \
- int iPage = pCur->iPage; \
- btreeParseCell(pCur->apPage[iPage],pCur->aiIdx[iPage],&pCur->info); \
- pCur->validNKey = 1; \
- }else{ \
- assertCellInfo(pCur); \
- }
-#endif /* _MSC_VER */
-
-#ifndef NDEBUG /* The next routine used only within assert() statements */
-/*
-** Return true if the given BtCursor is valid. A valid cursor is one
-** that is currently pointing to a row in a (non-empty) table.
-** This is a verification routine is used only within assert() statements.
-*/
-SQLITE_PRIVATE int sqlite3BtreeCursorIsValid(BtCursor *pCur){
- return pCur && pCur->eState==CURSOR_VALID;
-}
-#endif /* NDEBUG */
-
-/*
-** Set *pSize to the size of the buffer needed to hold the value of
-** the key for the current entry. If the cursor is not pointing
-** to a valid entry, *pSize is set to 0.
-**
-** For a table with the INTKEY flag set, this routine returns the key
-** itself, not the number of bytes in the key.
-**
-** The caller must position the cursor prior to invoking this routine.
-**
-** This routine cannot fail. It always returns SQLITE_OK.
-*/
-SQLITE_PRIVATE int sqlite3BtreeKeySize(BtCursor *pCur, i64 *pSize){
- assert( cursorHoldsMutex(pCur) );
- assert( pCur->eState==CURSOR_INVALID || pCur->eState==CURSOR_VALID );
- if( pCur->eState!=CURSOR_VALID ){
- *pSize = 0;
- }else{
- getCellInfo(pCur);
- *pSize = pCur->info.nKey;
- }
- return SQLITE_OK;
-}
-
-/*
-** Set *pSize to the number of bytes of data in the entry the
-** cursor currently points to.
-**
-** The caller must guarantee that the cursor is pointing to a non-NULL
-** valid entry. In other words, the calling procedure must guarantee
-** that the cursor has Cursor.eState==CURSOR_VALID.
-**
-** Failure is not possible. This function always returns SQLITE_OK.
-** It might just as well be a procedure (returning void) but we continue
-** to return an integer result code for historical reasons.
-*/
-SQLITE_PRIVATE int sqlite3BtreeDataSize(BtCursor *pCur, u32 *pSize){
- assert( cursorHoldsMutex(pCur) );
- assert( pCur->eState==CURSOR_VALID );
- getCellInfo(pCur);
- *pSize = pCur->info.nData;
- return SQLITE_OK;
-}
-
-/*
-** Given the page number of an overflow page in the database (parameter
-** ovfl), this function finds the page number of the next page in the
-** linked list of overflow pages. If possible, it uses the auto-vacuum
-** pointer-map data instead of reading the content of page ovfl to do so.
-**
-** If an error occurs an SQLite error code is returned. Otherwise:
-**
-** The page number of the next overflow page in the linked list is
-** written to *pPgnoNext. If page ovfl is the last page in its linked
-** list, *pPgnoNext is set to zero.
-**
-** If ppPage is not NULL, and a reference to the MemPage object corresponding
-** to page number pOvfl was obtained, then *ppPage is set to point to that
-** reference. It is the responsibility of the caller to call releasePage()
-** on *ppPage to free the reference. In no reference was obtained (because
-** the pointer-map was used to obtain the value for *pPgnoNext), then
-** *ppPage is set to zero.
-*/
-static int getOverflowPage(
- BtShared *pBt, /* The database file */
- Pgno ovfl, /* Current overflow page number */
- MemPage **ppPage, /* OUT: MemPage handle (may be NULL) */
- Pgno *pPgnoNext /* OUT: Next overflow page number */
-){
- Pgno next = 0;
- MemPage *pPage = 0;
- int rc = SQLITE_OK;
-
- assert( sqlite3_mutex_held(pBt->mutex) );
- assert(pPgnoNext);
-
-#ifndef SQLITE_OMIT_AUTOVACUUM
- /* Try to find the next page in the overflow list using the
- ** autovacuum pointer-map pages. Guess that the next page in
- ** the overflow list is page number (ovfl+1). If that guess turns
- ** out to be wrong, fall back to loading the data of page
- ** number ovfl to determine the next page number.
- */
- if( pBt->autoVacuum ){
- Pgno pgno;
- Pgno iGuess = ovfl+1;
- u8 eType;
-
- while( PTRMAP_ISPAGE(pBt, iGuess) || iGuess==PENDING_BYTE_PAGE(pBt) ){
- iGuess++;
- }
-
- if( iGuess<=pagerPagecount(pBt) ){
- rc = ptrmapGet(pBt, iGuess, &eType, &pgno);
- if( rc==SQLITE_OK && eType==PTRMAP_OVERFLOW2 && pgno==ovfl ){
- next = iGuess;
- rc = SQLITE_DONE;
- }
- }
- }
-#endif
-
- assert( next==0 || rc==SQLITE_DONE );
- if( rc==SQLITE_OK ){
- rc = btreeGetPage(pBt, ovfl, &pPage, 0);
- assert( rc==SQLITE_OK || pPage==0 );
- if( rc==SQLITE_OK ){
- next = get4byte(pPage->aData);
- }
- }
-
- *pPgnoNext = next;
- if( ppPage ){
- *ppPage = pPage;
- }else{
- releasePage(pPage);
- }
- return (rc==SQLITE_DONE ? SQLITE_OK : rc);
-}
-
-/*
-** Copy data from a buffer to a page, or from a page to a buffer.
-**
-** pPayload is a pointer to data stored on database page pDbPage.
-** If argument eOp is false, then nByte bytes of data are copied
-** from pPayload to the buffer pointed at by pBuf. If eOp is true,
-** then sqlite3PagerWrite() is called on pDbPage and nByte bytes
-** of data are copied from the buffer pBuf to pPayload.
-**
-** SQLITE_OK is returned on success, otherwise an error code.
-*/
-static int copyPayload(
- void *pPayload, /* Pointer to page data */
- void *pBuf, /* Pointer to buffer */
- int nByte, /* Number of bytes to copy */
- int eOp, /* 0 -> copy from page, 1 -> copy to page */
- DbPage *pDbPage /* Page containing pPayload */
-){
- if( eOp ){
- /* Copy data from buffer to page (a write operation) */
- int rc = sqlite3PagerWrite(pDbPage);
- if( rc!=SQLITE_OK ){
- return rc;
- }
- memcpy(pPayload, pBuf, nByte);
- }else{
- /* Copy data from page to buffer (a read operation) */
- memcpy(pBuf, pPayload, nByte);
- }
- return SQLITE_OK;
-}
-
-/*
-** This function is used to read or overwrite payload information
-** for the entry that the pCur cursor is pointing to. If the eOp
-** parameter is 0, this is a read operation (data copied into
-** buffer pBuf). If it is non-zero, a write (data copied from
-** buffer pBuf).
-**
-** A total of "amt" bytes are read or written beginning at "offset".
-** Data is read to or from the buffer pBuf.
-**
-** The content being read or written might appear on the main page
-** or be scattered out on multiple overflow pages.
-**
-** If the BtCursor.isIncrblobHandle flag is set, and the current
-** cursor entry uses one or more overflow pages, this function
-** allocates space for and lazily popluates the overflow page-list
-** cache array (BtCursor.aOverflow). Subsequent calls use this
-** cache to make seeking to the supplied offset more efficient.
-**
-** Once an overflow page-list cache has been allocated, it may be
-** invalidated if some other cursor writes to the same table, or if
-** the cursor is moved to a different row. Additionally, in auto-vacuum
-** mode, the following events may invalidate an overflow page-list cache.
-**
-** * An incremental vacuum,
-** * A commit in auto_vacuum="full" mode,
-** * Creating a table (may require moving an overflow page).
-*/
-static int accessPayload(
- BtCursor *pCur, /* Cursor pointing to entry to read from */
- u32 offset, /* Begin reading this far into payload */
- u32 amt, /* Read this many bytes */
- unsigned char *pBuf, /* Write the bytes into this buffer */
- int eOp /* zero to read. non-zero to write. */
-){
- unsigned char *aPayload;
- int rc = SQLITE_OK;
- u32 nKey;
- int iIdx = 0;
- MemPage *pPage = pCur->apPage[pCur->iPage]; /* Btree page of current entry */
- BtShared *pBt = pCur->pBt; /* Btree this cursor belongs to */
-
- assert( pPage );
- assert( pCur->eState==CURSOR_VALID );
- assert( pCur->aiIdx[pCur->iPage]<pPage->nCell );
- assert( cursorHoldsMutex(pCur) );
-
- getCellInfo(pCur);
- aPayload = pCur->info.pCell + pCur->info.nHeader;
- nKey = (pPage->intKey ? 0 : (int)pCur->info.nKey);
-
- if( NEVER(offset+amt > nKey+pCur->info.nData)
- || &aPayload[pCur->info.nLocal] > &pPage->aData[pBt->usableSize]
- ){
- /* Trying to read or write past the end of the data is an error */
- return SQLITE_CORRUPT_BKPT;
- }
-
- /* Check if data must be read/written to/from the btree page itself. */
- if( offset<pCur->info.nLocal ){
- int a = amt;
- if( a+offset>pCur->info.nLocal ){
- a = pCur->info.nLocal - offset;
- }
- rc = copyPayload(&aPayload[offset], pBuf, a, eOp, pPage->pDbPage);
- offset = 0;
- pBuf += a;
- amt -= a;
- }else{
- offset -= pCur->info.nLocal;
- }
-
- if( rc==SQLITE_OK && amt>0 ){
- const u32 ovflSize = pBt->usableSize - 4; /* Bytes content per ovfl page */
- Pgno nextPage;
-
- nextPage = get4byte(&aPayload[pCur->info.nLocal]);
-
-#ifndef SQLITE_OMIT_INCRBLOB
- /* If the isIncrblobHandle flag is set and the BtCursor.aOverflow[]
- ** has not been allocated, allocate it now. The array is sized at
- ** one entry for each overflow page in the overflow chain. The
- ** page number of the first overflow page is stored in aOverflow[0],
- ** etc. A value of 0 in the aOverflow[] array means "not yet known"
- ** (the cache is lazily populated).
- */
- if( pCur->isIncrblobHandle && !pCur->aOverflow ){
- int nOvfl = (pCur->info.nPayload-pCur->info.nLocal+ovflSize-1)/ovflSize;
- pCur->aOverflow = (Pgno *)sqlite3MallocZero(sizeof(Pgno)*nOvfl);
- /* nOvfl is always positive. If it were zero, fetchPayload would have
- ** been used instead of this routine. */
- if( ALWAYS(nOvfl) && !pCur->aOverflow ){
- rc = SQLITE_NOMEM;
- }
- }
-
- /* If the overflow page-list cache has been allocated and the
- ** entry for the first required overflow page is valid, skip
- ** directly to it.
- */
- if( pCur->aOverflow && pCur->aOverflow[offset/ovflSize] ){
- iIdx = (offset/ovflSize);
- nextPage = pCur->aOverflow[iIdx];
- offset = (offset%ovflSize);
- }
-#endif
-
- for( ; rc==SQLITE_OK && amt>0 && nextPage; iIdx++){
-
-#ifndef SQLITE_OMIT_INCRBLOB
- /* If required, populate the overflow page-list cache. */
- if( pCur->aOverflow ){
- assert(!pCur->aOverflow[iIdx] || pCur->aOverflow[iIdx]==nextPage);
- pCur->aOverflow[iIdx] = nextPage;
- }
-#endif
-
- if( offset>=ovflSize ){
- /* The only reason to read this page is to obtain the page
- ** number for the next page in the overflow chain. The page
- ** data is not required. So first try to lookup the overflow
- ** page-list cache, if any, then fall back to the getOverflowPage()
- ** function.
- */
-#ifndef SQLITE_OMIT_INCRBLOB
- if( pCur->aOverflow && pCur->aOverflow[iIdx+1] ){
- nextPage = pCur->aOverflow[iIdx+1];
- } else
-#endif
- rc = getOverflowPage(pBt, nextPage, 0, &nextPage);
- offset -= ovflSize;
- }else{
- /* Need to read this page properly. It contains some of the
- ** range of data that is being read (eOp==0) or written (eOp!=0).
- */
- DbPage *pDbPage;
- int a = amt;
- rc = sqlite3PagerGet(pBt->pPager, nextPage, &pDbPage);
- if( rc==SQLITE_OK ){
- aPayload = sqlite3PagerGetData(pDbPage);
- nextPage = get4byte(aPayload);
- if( a + offset > ovflSize ){
- a = ovflSize - offset;
- }
- rc = copyPayload(&aPayload[offset+4], pBuf, a, eOp, pDbPage);
- sqlite3PagerUnref(pDbPage);
- offset = 0;
- amt -= a;
- pBuf += a;
- }
- }
- }
- }
-
- if( rc==SQLITE_OK && amt>0 ){
- return SQLITE_CORRUPT_BKPT;
- }
- return rc;
-}
-
-/*
-** Read part of the key associated with cursor pCur. Exactly
-** "amt" bytes will be transfered into pBuf[]. The transfer
-** begins at "offset".
-**
-** The caller must ensure that pCur is pointing to a valid row
-** in the table.
-**
-** Return SQLITE_OK on success or an error code if anything goes
-** wrong. An error is returned if "offset+amt" is larger than
-** the available payload.
-*/
-SQLITE_PRIVATE int sqlite3BtreeKey(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){
- assert( cursorHoldsMutex(pCur) );
- assert( pCur->eState==CURSOR_VALID );
- assert( pCur->iPage>=0 && pCur->apPage[pCur->iPage] );
- assert( pCur->aiIdx[pCur->iPage]<pCur->apPage[pCur->iPage]->nCell );
- return accessPayload(pCur, offset, amt, (unsigned char*)pBuf, 0);
-}
-
-/*
-** Read part of the data associated with cursor pCur. Exactly
-** "amt" bytes will be transfered into pBuf[]. The transfer
-** begins at "offset".
-**
-** Return SQLITE_OK on success or an error code if anything goes
-** wrong. An error is returned if "offset+amt" is larger than
-** the available payload.
-*/
-SQLITE_PRIVATE int sqlite3BtreeData(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){
- int rc;
-
-#ifndef SQLITE_OMIT_INCRBLOB
- if ( pCur->eState==CURSOR_INVALID ){
- return SQLITE_ABORT;
- }
-#endif
-
- assert( cursorHoldsMutex(pCur) );
- rc = restoreCursorPosition(pCur);
- if( rc==SQLITE_OK ){
- assert( pCur->eState==CURSOR_VALID );
- assert( pCur->iPage>=0 && pCur->apPage[pCur->iPage] );
- assert( pCur->aiIdx[pCur->iPage]<pCur->apPage[pCur->iPage]->nCell );
- rc = accessPayload(pCur, offset, amt, pBuf, 0);
- }
- return rc;
-}
-
-/*
-** Return a pointer to payload information from the entry that the
-** pCur cursor is pointing to. The pointer is to the beginning of
-** the key if skipKey==0 and it points to the beginning of data if
-** skipKey==1. The number of bytes of available key/data is written
-** into *pAmt. If *pAmt==0, then the value returned will not be
-** a valid pointer.
-**
-** This routine is an optimization. It is common for the entire key
-** and data to fit on the local page and for there to be no overflow
-** pages. When that is so, this routine can be used to access the
-** key and data without making a copy. If the key and/or data spills
-** onto overflow pages, then accessPayload() must be used to reassemble
-** the key/data and copy it into a preallocated buffer.
-**
-** The pointer returned by this routine looks directly into the cached
-** page of the database. The data might change or move the next time
-** any btree routine is called.
-*/
-static const unsigned char *fetchPayload(
- BtCursor *pCur, /* Cursor pointing to entry to read from */
- int *pAmt, /* Write the number of available bytes here */
- int skipKey /* read beginning at data if this is true */
-){
- unsigned char *aPayload;
- MemPage *pPage;
- u32 nKey;
- u32 nLocal;
-
- assert( pCur!=0 && pCur->iPage>=0 && pCur->apPage[pCur->iPage]);
- assert( pCur->eState==CURSOR_VALID );
- assert( cursorHoldsMutex(pCur) );
- pPage = pCur->apPage[pCur->iPage];
- assert( pCur->aiIdx[pCur->iPage]<pPage->nCell );
- if( NEVER(pCur->info.nSize==0) ){
- btreeParseCell(pCur->apPage[pCur->iPage], pCur->aiIdx[pCur->iPage],
- &pCur->info);
- }
- aPayload = pCur->info.pCell;
- aPayload += pCur->info.nHeader;
- if( pPage->intKey ){
- nKey = 0;
- }else{
- nKey = (int)pCur->info.nKey;
- }
- if( skipKey ){
- aPayload += nKey;
- nLocal = pCur->info.nLocal - nKey;
- }else{
- nLocal = pCur->info.nLocal;
- assert( nLocal<=nKey );
- }
- *pAmt = nLocal;
- return aPayload;
-}
-
-
-/*
-** For the entry that cursor pCur is point to, return as
-** many bytes of the key or data as are available on the local
-** b-tree page. Write the number of available bytes into *pAmt.
-**
-** The pointer returned is ephemeral. The key/data may move
-** or be destroyed on the next call to any Btree routine,
-** including calls from other threads against the same cache.
-** Hence, a mutex on the BtShared should be held prior to calling
-** this routine.
-**
-** These routines is used to get quick access to key and data
-** in the common case where no overflow pages are used.
-*/
-SQLITE_PRIVATE const void *sqlite3BtreeKeyFetch(BtCursor *pCur, int *pAmt){
- const void *p = 0;
- assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
- assert( cursorHoldsMutex(pCur) );
- if( ALWAYS(pCur->eState==CURSOR_VALID) ){
- p = (const void*)fetchPayload(pCur, pAmt, 0);
- }
- return p;
-}
-SQLITE_PRIVATE const void *sqlite3BtreeDataFetch(BtCursor *pCur, int *pAmt){
- const void *p = 0;
- assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
- assert( cursorHoldsMutex(pCur) );
- if( ALWAYS(pCur->eState==CURSOR_VALID) ){
- p = (const void*)fetchPayload(pCur, pAmt, 1);
- }
- return p;
-}
-
-
-/*
-** Move the cursor down to a new child page. The newPgno argument is the
-** page number of the child page to move to.
-**
-** This function returns SQLITE_CORRUPT if the page-header flags field of
-** the new child page does not match the flags field of the parent (i.e.
-** if an intkey page appears to be the parent of a non-intkey page, or
-** vice-versa).
-*/
-static int moveToChild(BtCursor *pCur, u32 newPgno){
- int rc;
- int i = pCur->iPage;
- MemPage *pNewPage;
- BtShared *pBt = pCur->pBt;
-
- assert( cursorHoldsMutex(pCur) );
- assert( pCur->eState==CURSOR_VALID );
- assert( pCur->iPage<BTCURSOR_MAX_DEPTH );
- if( pCur->iPage>=(BTCURSOR_MAX_DEPTH-1) ){
- return SQLITE_CORRUPT_BKPT;
- }
- rc = getAndInitPage(pBt, newPgno, &pNewPage);
- if( rc ) return rc;
- pCur->apPage[i+1] = pNewPage;
- pCur->aiIdx[i+1] = 0;
- pCur->iPage++;
-
- pCur->info.nSize = 0;
- pCur->validNKey = 0;
- if( pNewPage->nCell<1 || pNewPage->intKey!=pCur->apPage[i]->intKey ){
- return SQLITE_CORRUPT_BKPT;
- }
- return SQLITE_OK;
-}
-
-#ifndef NDEBUG
-/*
-** Page pParent is an internal (non-leaf) tree page. This function
-** asserts that page number iChild is the left-child if the iIdx'th
-** cell in page pParent. Or, if iIdx is equal to the total number of
-** cells in pParent, that page number iChild is the right-child of
-** the page.
-*/
-static void assertParentIndex(MemPage *pParent, int iIdx, Pgno iChild){
- assert( iIdx<=pParent->nCell );
- if( iIdx==pParent->nCell ){
- assert( get4byte(&pParent->aData[pParent->hdrOffset+8])==iChild );
- }else{
- assert( get4byte(findCell(pParent, iIdx))==iChild );
- }
-}
-#else
-# define assertParentIndex(x,y,z)
-#endif
-
-/*
-** Move the cursor up to the parent page.
-**
-** pCur->idx is set to the cell index that contains the pointer
-** to the page we are coming from. If we are coming from the
-** right-most child page then pCur->idx is set to one more than
-** the largest cell index.
-*/
-static void moveToParent(BtCursor *pCur){
- assert( cursorHoldsMutex(pCur) );
- assert( pCur->eState==CURSOR_VALID );
- assert( pCur->iPage>0 );
- assert( pCur->apPage[pCur->iPage] );
- assertParentIndex(
- pCur->apPage[pCur->iPage-1],
- pCur->aiIdx[pCur->iPage-1],
- pCur->apPage[pCur->iPage]->pgno
- );
- releasePage(pCur->apPage[pCur->iPage]);
- pCur->iPage--;
- pCur->info.nSize = 0;
- pCur->validNKey = 0;
-}
-
-/*
-** Move the cursor to point to the root page of its b-tree structure.
-**
-** If the table has a virtual root page, then the cursor is moved to point
-** to the virtual root page instead of the actual root page. A table has a
-** virtual root page when the actual root page contains no cells and a
-** single child page. This can only happen with the table rooted at page 1.
-**
-** If the b-tree structure is empty, the cursor state is set to
-** CURSOR_INVALID. Otherwise, the cursor is set to point to the first
-** cell located on the root (or virtual root) page and the cursor state
-** is set to CURSOR_VALID.
-**
-** If this function returns successfully, it may be assumed that the
-** page-header flags indicate that the [virtual] root-page is the expected
-** kind of b-tree page (i.e. if when opening the cursor the caller did not
-** specify a KeyInfo structure the flags byte is set to 0x05 or 0x0D,
-** indicating a table b-tree, or if the caller did specify a KeyInfo
-** structure the flags byte is set to 0x02 or 0x0A, indicating an index
-** b-tree).
-*/
-static int moveToRoot(BtCursor *pCur){
- MemPage *pRoot;
- int rc = SQLITE_OK;
- Btree *p = pCur->pBtree;
- BtShared *pBt = p->pBt;
-
- assert( cursorHoldsMutex(pCur) );
- assert( CURSOR_INVALID < CURSOR_REQUIRESEEK );
- assert( CURSOR_VALID < CURSOR_REQUIRESEEK );
- assert( CURSOR_FAULT > CURSOR_REQUIRESEEK );
- if( pCur->eState>=CURSOR_REQUIRESEEK ){
- if( pCur->eState==CURSOR_FAULT ){
- assert( pCur->skipNext!=SQLITE_OK );
- return pCur->skipNext;
- }
- sqlite3BtreeClearCursor(pCur);
- }
-
- if( pCur->iPage>=0 ){
- int i;
- for(i=1; i<=pCur->iPage; i++){
- releasePage(pCur->apPage[i]);
- }
- pCur->iPage = 0;
- }else{
- rc = getAndInitPage(pBt, pCur->pgnoRoot, &pCur->apPage[0]);
- if( rc!=SQLITE_OK ){
- pCur->eState = CURSOR_INVALID;
- return rc;
- }
- pCur->iPage = 0;
-
- /* If pCur->pKeyInfo is not NULL, then the caller that opened this cursor
- ** expected to open it on an index b-tree. Otherwise, if pKeyInfo is
- ** NULL, the caller expects a table b-tree. If this is not the case,
- ** return an SQLITE_CORRUPT error. */
- assert( pCur->apPage[0]->intKey==1 || pCur->apPage[0]->intKey==0 );
- if( (pCur->pKeyInfo==0)!=pCur->apPage[0]->intKey ){
- return SQLITE_CORRUPT_BKPT;
- }
- }
-
- /* Assert that the root page is of the correct type. This must be the
- ** case as the call to this function that loaded the root-page (either
- ** this call or a previous invocation) would have detected corruption
- ** if the assumption were not true, and it is not possible for the flags
- ** byte to have been modified while this cursor is holding a reference
- ** to the page. */
- pRoot = pCur->apPage[0];
- assert( pRoot->pgno==pCur->pgnoRoot );
- assert( pRoot->isInit && (pCur->pKeyInfo==0)==pRoot->intKey );
-
- pCur->aiIdx[0] = 0;
- pCur->info.nSize = 0;
- pCur->atLast = 0;
- pCur->validNKey = 0;
-
- if( pRoot->nCell==0 && !pRoot->leaf ){
- Pgno subpage;
- if( pRoot->pgno!=1 ) return SQLITE_CORRUPT_BKPT;
- subpage = get4byte(&pRoot->aData[pRoot->hdrOffset+8]);
- pCur->eState = CURSOR_VALID;
- rc = moveToChild(pCur, subpage);
- }else{
- pCur->eState = ((pRoot->nCell>0)?CURSOR_VALID:CURSOR_INVALID);
- }
- return rc;
-}
-
-/*
-** Move the cursor down to the left-most leaf entry beneath the
-** entry to which it is currently pointing.
-**
-** The left-most leaf is the one with the smallest key - the first
-** in ascending order.
-*/
-static int moveToLeftmost(BtCursor *pCur){
- Pgno pgno;
- int rc = SQLITE_OK;
- MemPage *pPage;
-
- assert( cursorHoldsMutex(pCur) );
- assert( pCur->eState==CURSOR_VALID );
- while( rc==SQLITE_OK && !(pPage = pCur->apPage[pCur->iPage])->leaf ){
- assert( pCur->aiIdx[pCur->iPage]<pPage->nCell );
- pgno = get4byte(findCell(pPage, pCur->aiIdx[pCur->iPage]));
- rc = moveToChild(pCur, pgno);
- }
- return rc;
-}
-
-/*
-** Move the cursor down to the right-most leaf entry beneath the
-** page to which it is currently pointing. Notice the difference
-** between moveToLeftmost() and moveToRightmost(). moveToLeftmost()
-** finds the left-most entry beneath the *entry* whereas moveToRightmost()
-** finds the right-most entry beneath the *page*.
-**
-** The right-most entry is the one with the largest key - the last
-** key in ascending order.
-*/
-static int moveToRightmost(BtCursor *pCur){
- Pgno pgno;
- int rc = SQLITE_OK;
- MemPage *pPage = 0;
-
- assert( cursorHoldsMutex(pCur) );
- assert( pCur->eState==CURSOR_VALID );
- while( rc==SQLITE_OK && !(pPage = pCur->apPage[pCur->iPage])->leaf ){
- pgno = get4byte(&pPage->aData[pPage->hdrOffset+8]);
- pCur->aiIdx[pCur->iPage] = pPage->nCell;
- rc = moveToChild(pCur, pgno);
- }
- if( rc==SQLITE_OK ){
- pCur->aiIdx[pCur->iPage] = pPage->nCell-1;
- pCur->info.nSize = 0;
- pCur->validNKey = 0;
- }
- return rc;
-}
-
-/* Move the cursor to the first entry in the table. Return SQLITE_OK
-** on success. Set *pRes to 0 if the cursor actually points to something
-** or set *pRes to 1 if the table is empty.
-*/
-SQLITE_PRIVATE int sqlite3BtreeFirst(BtCursor *pCur, int *pRes){
- int rc;
-
- assert( cursorHoldsMutex(pCur) );
- assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
- rc = moveToRoot(pCur);
- if( rc==SQLITE_OK ){
- if( pCur->eState==CURSOR_INVALID ){
- assert( pCur->apPage[pCur->iPage]->nCell==0 );
- *pRes = 1;
- rc = SQLITE_OK;
- }else{
- assert( pCur->apPage[pCur->iPage]->nCell>0 );
- *pRes = 0;
- rc = moveToLeftmost(pCur);
- }
- }
- return rc;
-}
-
-/* Move the cursor to the last entry in the table. Return SQLITE_OK
-** on success. Set *pRes to 0 if the cursor actually points to something
-** or set *pRes to 1 if the table is empty.
-*/
-SQLITE_PRIVATE int sqlite3BtreeLast(BtCursor *pCur, int *pRes){
- int rc;
-
- assert( cursorHoldsMutex(pCur) );
- assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
-
- /* If the cursor already points to the last entry, this is a no-op. */
- if( CURSOR_VALID==pCur->eState && pCur->atLast ){
-#ifdef SQLITE_DEBUG
- /* This block serves to assert() that the cursor really does point
- ** to the last entry in the b-tree. */
- int ii;
- for(ii=0; ii<pCur->iPage; ii++){
- assert( pCur->aiIdx[ii]==pCur->apPage[ii]->nCell );
- }
- assert( pCur->aiIdx[pCur->iPage]==pCur->apPage[pCur->iPage]->nCell-1 );
- assert( pCur->apPage[pCur->iPage]->leaf );
-#endif
- return SQLITE_OK;
- }
-
- rc = moveToRoot(pCur);
- if( rc==SQLITE_OK ){
- if( CURSOR_INVALID==pCur->eState ){
- assert( pCur->apPage[pCur->iPage]->nCell==0 );
- *pRes = 1;
- }else{
- assert( pCur->eState==CURSOR_VALID );
- *pRes = 0;
- rc = moveToRightmost(pCur);
- pCur->atLast = rc==SQLITE_OK ?1:0;
- }
- }
- return rc;
-}
-
-/* Move the cursor so that it points to an entry near the key
-** specified by pIdxKey or intKey. Return a success code.
-**
-** For INTKEY tables, the intKey parameter is used. pIdxKey
-** must be NULL. For index tables, pIdxKey is used and intKey
-** is ignored.
-**
-** If an exact match is not found, then the cursor is always
-** left pointing at a leaf page which would hold the entry if it
-** were present. The cursor might point to an entry that comes
-** before or after the key.
-**
-** An integer is written into *pRes which is the result of
-** comparing the key with the entry to which the cursor is
-** pointing. The meaning of the integer written into
-** *pRes is as follows:
-**
-** *pRes<0 The cursor is left pointing at an entry that
-** is smaller than intKey/pIdxKey or if the table is empty
-** and the cursor is therefore left point to nothing.
-**
-** *pRes==0 The cursor is left pointing at an entry that
-** exactly matches intKey/pIdxKey.
-**
-** *pRes>0 The cursor is left pointing at an entry that
-** is larger than intKey/pIdxKey.
-**
-*/
-SQLITE_PRIVATE int sqlite3BtreeMovetoUnpacked(
- BtCursor *pCur, /* The cursor to be moved */
- UnpackedRecord *pIdxKey, /* Unpacked index key */
- i64 intKey, /* The table key */
- int biasRight, /* If true, bias the search to the high end */
- int *pRes /* Write search results here */
-){
- int rc;
-
- assert( cursorHoldsMutex(pCur) );
- assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
- assert( pRes );
- assert( (pIdxKey==0)==(pCur->pKeyInfo==0) );
-
- /* If the cursor is already positioned at the point we are trying
- ** to move to, then just return without doing any work */
- if( pCur->eState==CURSOR_VALID && pCur->validNKey
- && pCur->apPage[0]->intKey
- ){
- if( pCur->info.nKey==intKey ){
- *pRes = 0;
- return SQLITE_OK;
- }
- if( pCur->atLast && pCur->info.nKey<intKey ){
- *pRes = -1;
- return SQLITE_OK;
- }
- }
-
- rc = moveToRoot(pCur);
- if( rc ){
- return rc;
- }
- assert( pCur->apPage[pCur->iPage] );
- assert( pCur->apPage[pCur->iPage]->isInit );
- assert( pCur->apPage[pCur->iPage]->nCell>0 || pCur->eState==CURSOR_INVALID );
- if( pCur->eState==CURSOR_INVALID ){
- *pRes = -1;
- assert( pCur->apPage[pCur->iPage]->nCell==0 );
- return SQLITE_OK;
- }
- assert( pCur->apPage[0]->intKey || pIdxKey );
- for(;;){
- int lwr, upr;
- Pgno chldPg;
- MemPage *pPage = pCur->apPage[pCur->iPage];
- int c;
-
- /* pPage->nCell must be greater than zero. If this is the root-page
- ** the cursor would have been INVALID above and this for(;;) loop
- ** not run. If this is not the root-page, then the moveToChild() routine
- ** would have already detected db corruption. Similarly, pPage must
- ** be the right kind (index or table) of b-tree page. Otherwise
- ** a moveToChild() or moveToRoot() call would have detected corruption. */
- assert( pPage->nCell>0 );
- assert( pPage->intKey==(pIdxKey==0) );
- lwr = 0;
- upr = pPage->nCell-1;
- if( biasRight ){
- pCur->aiIdx[pCur->iPage] = (u16)upr;
- }else{
- pCur->aiIdx[pCur->iPage] = (u16)((upr+lwr)/2);
- }
- for(;;){
- int idx = pCur->aiIdx[pCur->iPage]; /* Index of current cell in pPage */
- u8 *pCell; /* Pointer to current cell in pPage */
-
- pCur->info.nSize = 0;
- pCell = findCell(pPage, idx) + pPage->childPtrSize;
- if( pPage->intKey ){
- i64 nCellKey;
- if( pPage->hasData ){
- u32 dummy;
- pCell += getVarint32(pCell, dummy);
- }
- getVarint(pCell, (u64*)&nCellKey);
- if( nCellKey==intKey ){
- c = 0;
- }else if( nCellKey<intKey ){
- c = -1;
- }else{
- assert( nCellKey>intKey );
- c = +1;
- }
- pCur->validNKey = 1;
- pCur->info.nKey = nCellKey;
- }else{
- /* The maximum supported page-size is 32768 bytes. This means that
- ** the maximum number of record bytes stored on an index B-Tree
- ** page is at most 8198 bytes, which may be stored as a 2-byte
- ** varint. This information is used to attempt to avoid parsing
- ** the entire cell by checking for the cases where the record is
- ** stored entirely within the b-tree page by inspecting the first
- ** 2 bytes of the cell.
- */
- int nCell = pCell[0];
- if( !(nCell & 0x80) && nCell<=pPage->maxLocal ){
- /* 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. */
- c = sqlite3VdbeRecordCompare(nCell, (void*)&pCell[1], pIdxKey);
- }else if( !(pCell[1] & 0x80)
- && (nCell = ((nCell&0x7f)<<7) + pCell[1])<=pPage->maxLocal
- ){
- /* The record-size field is a 2 byte varint and the record
- ** fits entirely on the main b-tree page. */
- c = sqlite3VdbeRecordCompare(nCell, (void*)&pCell[2], pIdxKey);
- }else{
- /* The record flows over onto one or more overflow pages. In
- ** this case the whole cell needs to be parsed, a buffer allocated
- ** and accessPayload() used to retrieve the record into the
- ** buffer before VdbeRecordCompare() can be called. */
- void *pCellKey;
- u8 * const pCellBody = pCell - pPage->childPtrSize;
- btreeParseCellPtr(pPage, pCellBody, &pCur->info);
- nCell = (int)pCur->info.nKey;
- pCellKey = sqlite3Malloc( nCell );
- if( pCellKey==0 ){
- rc = SQLITE_NOMEM;
- goto moveto_finish;
- }
- rc = accessPayload(pCur, 0, nCell, (unsigned char*)pCellKey, 0);
- if( rc ){
- sqlite3_free(pCellKey);
- goto moveto_finish;
- }
- c = sqlite3VdbeRecordCompare(nCell, pCellKey, pIdxKey);
- sqlite3_free(pCellKey);
- }
- }
- if( c==0 ){
- if( pPage->intKey && !pPage->leaf ){
- lwr = idx;
- upr = lwr - 1;
- break;
- }else{
- *pRes = 0;
- rc = SQLITE_OK;
- goto moveto_finish;
- }
- }
- if( c<0 ){
- lwr = idx+1;
- }else{
- upr = idx-1;
- }
- if( lwr>upr ){
- break;
- }
- pCur->aiIdx[pCur->iPage] = (u16)((lwr+upr)/2);
- }
- assert( lwr==upr+1 );
- assert( pPage->isInit );
- if( pPage->leaf ){
- chldPg = 0;
- }else if( lwr>=pPage->nCell ){
- chldPg = get4byte(&pPage->aData[pPage->hdrOffset+8]);
- }else{
- chldPg = get4byte(findCell(pPage, lwr));
- }
- if( chldPg==0 ){
- assert( pCur->aiIdx[pCur->iPage]<pCur->apPage[pCur->iPage]->nCell );
- *pRes = c;
- rc = SQLITE_OK;
- goto moveto_finish;
- }
- pCur->aiIdx[pCur->iPage] = (u16)lwr;
- pCur->info.nSize = 0;
- pCur->validNKey = 0;
- rc = moveToChild(pCur, chldPg);
- if( rc ) goto moveto_finish;
- }
-moveto_finish:
- return rc;
-}
-
-
-/*
-** Return TRUE if the cursor is not pointing at an entry of the table.
-**
-** TRUE will be returned after a call to sqlite3BtreeNext() moves
-** past the last entry in the table or sqlite3BtreePrev() moves past
-** the first entry. TRUE is also returned if the table is empty.
-*/
-SQLITE_PRIVATE int sqlite3BtreeEof(BtCursor *pCur){
- /* TODO: What if the cursor is in CURSOR_REQUIRESEEK but all table entries
- ** have been deleted? This API will need to change to return an error code
- ** as well as the boolean result value.
- */
- return (CURSOR_VALID!=pCur->eState);
-}
-
-/*
-** Advance the cursor to the next entry in the database. If
-** successful then set *pRes=0. If the cursor
-** was already pointing to the last entry in the database before
-** this routine was called, then set *pRes=1.
-*/
-SQLITE_PRIVATE int sqlite3BtreeNext(BtCursor *pCur, int *pRes){
- int rc;
- int idx;
- MemPage *pPage;
-
- assert( cursorHoldsMutex(pCur) );
- rc = restoreCursorPosition(pCur);
- if( rc!=SQLITE_OK ){
- return rc;
- }
- assert( pRes!=0 );
- if( CURSOR_INVALID==pCur->eState ){
- *pRes = 1;
- return SQLITE_OK;
- }
- if( pCur->skipNext>0 ){
- pCur->skipNext = 0;
- *pRes = 0;
- return SQLITE_OK;
- }
- pCur->skipNext = 0;
-
- pPage = pCur->apPage[pCur->iPage];
- idx = ++pCur->aiIdx[pCur->iPage];
- assert( pPage->isInit );
- assert( idx<=pPage->nCell );
-
- pCur->info.nSize = 0;
- pCur->validNKey = 0;
- if( idx>=pPage->nCell ){
- if( !pPage->leaf ){
- rc = moveToChild(pCur, get4byte(&pPage->aData[pPage->hdrOffset+8]));
- if( rc ) return rc;
- rc = moveToLeftmost(pCur);
- *pRes = 0;
- return rc;
- }
- do{
- if( pCur->iPage==0 ){
- *pRes = 1;
- pCur->eState = CURSOR_INVALID;
- return SQLITE_OK;
- }
- moveToParent(pCur);
- pPage = pCur->apPage[pCur->iPage];
- }while( pCur->aiIdx[pCur->iPage]>=pPage->nCell );
- *pRes = 0;
- if( pPage->intKey ){
- rc = sqlite3BtreeNext(pCur, pRes);
- }else{
- rc = SQLITE_OK;
- }
- return rc;
- }
- *pRes = 0;
- if( pPage->leaf ){
- return SQLITE_OK;
- }
- rc = moveToLeftmost(pCur);
- return rc;
-}
-
-
-/*
-** Step the cursor to the back to the previous entry in the database. If
-** successful then set *pRes=0. If the cursor
-** was already pointing to the first entry in the database before
-** this routine was called, then set *pRes=1.
-*/
-SQLITE_PRIVATE int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){
- int rc;
- MemPage *pPage;
-
- assert( cursorHoldsMutex(pCur) );
- rc = restoreCursorPosition(pCur);
- if( rc!=SQLITE_OK ){
- return rc;
- }
- pCur->atLast = 0;
- if( CURSOR_INVALID==pCur->eState ){
- *pRes = 1;
- return SQLITE_OK;
- }
- if( pCur->skipNext<0 ){
- pCur->skipNext = 0;
- *pRes = 0;
- return SQLITE_OK;
- }
- pCur->skipNext = 0;
-
- pPage = pCur->apPage[pCur->iPage];
- assert( pPage->isInit );
- if( !pPage->leaf ){
- int idx = pCur->aiIdx[pCur->iPage];
- rc = moveToChild(pCur, get4byte(findCell(pPage, idx)));
- if( rc ){
- return rc;
- }
- rc = moveToRightmost(pCur);
- }else{
- while( pCur->aiIdx[pCur->iPage]==0 ){
- if( pCur->iPage==0 ){
- pCur->eState = CURSOR_INVALID;
- *pRes = 1;
- return SQLITE_OK;
- }
- moveToParent(pCur);
- }
- pCur->info.nSize = 0;
- pCur->validNKey = 0;
-
- pCur->aiIdx[pCur->iPage]--;
- pPage = pCur->apPage[pCur->iPage];
- if( pPage->intKey && !pPage->leaf ){
- rc = sqlite3BtreePrevious(pCur, pRes);
- }else{
- rc = SQLITE_OK;
- }
- }
- *pRes = 0;
- return rc;
-}
-
-/*
-** Allocate a new page from the database file.
-**
-** The new page is marked as dirty. (In other words, sqlite3PagerWrite()
-** has already been called on the new page.) The new page has also
-** been referenced and the calling routine is responsible for calling
-** sqlite3PagerUnref() on the new page when it is done.
-**
-** SQLITE_OK is returned on success. Any other return value indicates
-** an error. *ppPage and *pPgno are undefined in the event of an error.
-** Do not invoke sqlite3PagerUnref() on *ppPage if an error is returned.
-**
-** If the "nearby" parameter is not 0, then a (feeble) effort is made to
-** locate a page close to the page number "nearby". This can be used in an
-** attempt to keep related pages close to each other in the database file,
-** which in turn can make database access faster.
-**
-** If the "exact" parameter is not 0, and the page-number nearby exists
-** anywhere on the free-list, then it is guarenteed to be returned. This
-** is only used by auto-vacuum databases when allocating a new table.
-*/
-static int allocateBtreePage(
- BtShared *pBt,
- MemPage **ppPage,
- Pgno *pPgno,
- Pgno nearby,
- u8 exact
-){
- MemPage *pPage1;
- int rc;
- u32 n; /* Number of pages on the freelist */
- u32 k; /* Number of leaves on the trunk of the freelist */
- MemPage *pTrunk = 0;
- MemPage *pPrevTrunk = 0;
- Pgno mxPage; /* Total size of the database file */
-
- assert( sqlite3_mutex_held(pBt->mutex) );
- pPage1 = pBt->pPage1;
- mxPage = pagerPagecount(pBt);
- n = get4byte(&pPage1->aData[36]);
- testcase( n==mxPage-1 );
- if( n>=mxPage ){
- return SQLITE_CORRUPT_BKPT;
- }
- if( n>0 ){
- /* There are pages on the freelist. Reuse one of those pages. */
- Pgno iTrunk;
- u8 searchList = 0; /* If the free-list must be searched for 'nearby' */
-
- /* If the 'exact' parameter was true and a query of the pointer-map
- ** shows that the page 'nearby' is somewhere on the free-list, then
- ** the entire-list will be searched for that page.
- */
-#ifndef SQLITE_OMIT_AUTOVACUUM
- if( exact && nearby<=mxPage ){
- u8 eType;
- assert( nearby>0 );
- assert( pBt->autoVacuum );
- rc = ptrmapGet(pBt, nearby, &eType, 0);
- if( rc ) return rc;
- if( eType==PTRMAP_FREEPAGE ){
- searchList = 1;
- }
- *pPgno = nearby;
- }
-#endif
-
- /* Decrement the free-list count by 1. Set iTrunk to the index of the
- ** first free-list trunk page. iPrevTrunk is initially 1.
- */
- rc = sqlite3PagerWrite(pPage1->pDbPage);
- if( rc ) return rc;
- put4byte(&pPage1->aData[36], n-1);
-
- /* The code within this loop is run only once if the 'searchList' variable
- ** is not true. Otherwise, it runs once for each trunk-page on the
- ** free-list until the page 'nearby' is located.
- */
- do {
- pPrevTrunk = pTrunk;
- if( pPrevTrunk ){
- iTrunk = get4byte(&pPrevTrunk->aData[0]);
- }else{
- iTrunk = get4byte(&pPage1->aData[32]);
- }
- testcase( iTrunk==mxPage );
- if( iTrunk>mxPage ){
- rc = SQLITE_CORRUPT_BKPT;
- }else{
- rc = btreeGetPage(pBt, iTrunk, &pTrunk, 0);
- }
- if( rc ){
- pTrunk = 0;
- goto end_allocate_page;
- }
-
- k = get4byte(&pTrunk->aData[4]);
- if( k==0 && !searchList ){
- /* The trunk has no leaves and the list is not being searched.
- ** So extract the trunk page itself and use it as the newly
- ** allocated page */
- assert( pPrevTrunk==0 );
- rc = sqlite3PagerWrite(pTrunk->pDbPage);
- if( rc ){
- goto end_allocate_page;
- }
- *pPgno = iTrunk;
- memcpy(&pPage1->aData[32], &pTrunk->aData[0], 4);
- *ppPage = pTrunk;
- pTrunk = 0;
- TRACE(("ALLOCATE: %d trunk - %d free pages left\n", *pPgno, n-1));
- }else if( k>(u32)(pBt->usableSize/4 - 2) ){
- /* Value of k is out of range. Database corruption */
- rc = SQLITE_CORRUPT_BKPT;
- goto end_allocate_page;
-#ifndef SQLITE_OMIT_AUTOVACUUM
- }else if( searchList && nearby==iTrunk ){
- /* The list is being searched and this trunk page is the page
- ** to allocate, regardless of whether it has leaves.
- */
- assert( *pPgno==iTrunk );
- *ppPage = pTrunk;
- searchList = 0;
- rc = sqlite3PagerWrite(pTrunk->pDbPage);
- if( rc ){
- goto end_allocate_page;
- }
- if( k==0 ){
- if( !pPrevTrunk ){
- memcpy(&pPage1->aData[32], &pTrunk->aData[0], 4);
- }else{
- memcpy(&pPrevTrunk->aData[0], &pTrunk->aData[0], 4);
- }
- }else{
- /* The trunk page is required by the caller but it contains
- ** pointers to free-list leaves. The first leaf becomes a trunk
- ** page in this case.
- */
- MemPage *pNewTrunk;
- Pgno iNewTrunk = get4byte(&pTrunk->aData[8]);
- if( iNewTrunk>mxPage ){
- rc = SQLITE_CORRUPT_BKPT;
- goto end_allocate_page;
- }
- testcase( iNewTrunk==mxPage );
- rc = btreeGetPage(pBt, iNewTrunk, &pNewTrunk, 0);
- if( rc!=SQLITE_OK ){
- goto end_allocate_page;
- }
- rc = sqlite3PagerWrite(pNewTrunk->pDbPage);
- if( rc!=SQLITE_OK ){
- releasePage(pNewTrunk);
- goto end_allocate_page;
- }
- memcpy(&pNewTrunk->aData[0], &pTrunk->aData[0], 4);
- put4byte(&pNewTrunk->aData[4], k-1);
- memcpy(&pNewTrunk->aData[8], &pTrunk->aData[12], (k-1)*4);
- releasePage(pNewTrunk);
- if( !pPrevTrunk ){
- assert( sqlite3PagerIswriteable(pPage1->pDbPage) );
- put4byte(&pPage1->aData[32], iNewTrunk);
- }else{
- rc = sqlite3PagerWrite(pPrevTrunk->pDbPage);
- if( rc ){
- goto end_allocate_page;
- }
- put4byte(&pPrevTrunk->aData[0], iNewTrunk);
- }
- }
- pTrunk = 0;
- TRACE(("ALLOCATE: %d trunk - %d free pages left\n", *pPgno, n-1));
-#endif
- }else if( k>0 ){
- /* Extract a leaf from the trunk */
- u32 closest;
- Pgno iPage;
- unsigned char *aData = pTrunk->aData;
- rc = sqlite3PagerWrite(pTrunk->pDbPage);
- if( rc ){
- goto end_allocate_page;
- }
- if( nearby>0 ){
- u32 i;
- int dist;
- closest = 0;
- dist = get4byte(&aData[8]) - nearby;
- if( dist<0 ) dist = -dist;
- for(i=1; i<k; i++){
- int d2 = get4byte(&aData[8+i*4]) - nearby;
- if( d2<0 ) d2 = -d2;
- if( d2<dist ){
- closest = i;
- dist = d2;
- }
- }
- }else{
- closest = 0;
- }
-
- iPage = get4byte(&aData[8+closest*4]);
- testcase( iPage==mxPage );
- if( iPage>mxPage ){
- rc = SQLITE_CORRUPT_BKPT;
- goto end_allocate_page;
- }
- testcase( iPage==mxPage );
- if( !searchList || iPage==nearby ){
- int noContent;
- *pPgno = iPage;
- TRACE(("ALLOCATE: %d was leaf %d of %d on trunk %d"
- ": %d more free pages\n",
- *pPgno, closest+1, k, pTrunk->pgno, n-1));
- if( closest<k-1 ){
- memcpy(&aData[8+closest*4], &aData[4+k*4], 4);
- }
- put4byte(&aData[4], k-1);
- assert( sqlite3PagerIswriteable(pTrunk->pDbPage) );
- noContent = !btreeGetHasContent(pBt, *pPgno);
- rc = btreeGetPage(pBt, *pPgno, ppPage, noContent);
- if( rc==SQLITE_OK ){
- rc = sqlite3PagerWrite((*ppPage)->pDbPage);
- if( rc!=SQLITE_OK ){
- releasePage(*ppPage);
- }
- }
- searchList = 0;
- }
- }
- releasePage(pPrevTrunk);
- pPrevTrunk = 0;
- }while( searchList );
- }else{
- /* There are no pages on the freelist, so create a new page at the
- ** end of the file */
- int nPage = pagerPagecount(pBt);
- *pPgno = nPage + 1;
-
- if( *pPgno==PENDING_BYTE_PAGE(pBt) ){
- (*pPgno)++;
- }
-
-#ifndef SQLITE_OMIT_AUTOVACUUM
- if( pBt->autoVacuum && PTRMAP_ISPAGE(pBt, *pPgno) ){
- /* If *pPgno refers to a pointer-map page, allocate two new pages
- ** at the end of the file instead of one. The first allocated page
- ** becomes a new pointer-map page, the second is used by the caller.
- */
- MemPage *pPg = 0;
- TRACE(("ALLOCATE: %d from end of file (pointer-map page)\n", *pPgno));
- assert( *pPgno!=PENDING_BYTE_PAGE(pBt) );
- rc = btreeGetPage(pBt, *pPgno, &pPg, 0);
- if( rc==SQLITE_OK ){
- rc = sqlite3PagerWrite(pPg->pDbPage);
- releasePage(pPg);
- }
- if( rc ) return rc;
- (*pPgno)++;
- if( *pPgno==PENDING_BYTE_PAGE(pBt) ){ (*pPgno)++; }
- }
-#endif
-
- assert( *pPgno!=PENDING_BYTE_PAGE(pBt) );
- rc = btreeGetPage(pBt, *pPgno, ppPage, 0);
- if( rc ) return rc;
- rc = sqlite3PagerWrite((*ppPage)->pDbPage);
- if( rc!=SQLITE_OK ){
- releasePage(*ppPage);
- }
- TRACE(("ALLOCATE: %d from end of file\n", *pPgno));
- }
-
- assert( *pPgno!=PENDING_BYTE_PAGE(pBt) );
-
-end_allocate_page:
- releasePage(pTrunk);
- releasePage(pPrevTrunk);
- if( rc==SQLITE_OK ){
- if( sqlite3PagerPageRefcount((*ppPage)->pDbPage)>1 ){
- releasePage(*ppPage);
- return SQLITE_CORRUPT_BKPT;
- }
- (*ppPage)->isInit = 0;
- }else{
- *ppPage = 0;
- }
- return rc;
-}
-
-/*
-** This function is used to add page iPage to the database file free-list.
-** It is assumed that the page is not already a part of the free-list.
-**
-** The value passed as the second argument to this function is optional.
-** If the caller happens to have a pointer to the MemPage object
-** corresponding to page iPage handy, it may pass it as the second value.
-** Otherwise, it may pass NULL.
-**
-** If a pointer to a MemPage object is passed as the second argument,
-** its reference count is not altered by this function.
-*/
-static int freePage2(BtShared *pBt, MemPage *pMemPage, Pgno iPage){
- MemPage *pTrunk = 0; /* Free-list trunk page */
- Pgno iTrunk = 0; /* Page number of free-list trunk page */
- MemPage *pPage1 = pBt->pPage1; /* Local reference to page 1 */
- MemPage *pPage; /* Page being freed. May be NULL. */
- int rc; /* Return Code */
- int nFree; /* Initial number of pages on free-list */
-
- assert( sqlite3_mutex_held(pBt->mutex) );
- assert( iPage>1 );
- assert( !pMemPage || pMemPage->pgno==iPage );
-
- if( pMemPage ){
- pPage = pMemPage;
- sqlite3PagerRef(pPage->pDbPage);
- }else{
- pPage = btreePageLookup(pBt, iPage);
- }
-
- /* Increment the free page count on pPage1 */
- rc = sqlite3PagerWrite(pPage1->pDbPage);
- if( rc ) goto freepage_out;
- nFree = get4byte(&pPage1->aData[36]);
- put4byte(&pPage1->aData[36], nFree+1);
-
-#ifdef SQLITE_SECURE_DELETE
- /* If the SQLITE_SECURE_DELETE compile-time option is enabled, then
- ** always fully overwrite deleted information with zeros.
- */
- if( (!pPage && (rc = btreeGetPage(pBt, iPage, &pPage, 0)))
- || (rc = sqlite3PagerWrite(pPage->pDbPage))
- ){
- goto freepage_out;
- }
- memset(pPage->aData, 0, pPage->pBt->pageSize);
-#endif
-
- /* If the database supports auto-vacuum, write an entry in the pointer-map
- ** to indicate that the page is free.
- */
- if( ISAUTOVACUUM ){
- ptrmapPut(pBt, iPage, PTRMAP_FREEPAGE, 0, &rc);
- if( rc ) goto freepage_out;
- }
-
- /* Now manipulate the actual database free-list structure. There are two
- ** possibilities. If the free-list is currently empty, or if the first
- ** trunk page in the free-list is full, then this page will become a
- ** new free-list trunk page. Otherwise, it will become a leaf of the
- ** first trunk page in the current free-list. This block tests if it
- ** is possible to add the page as a new free-list leaf.
- */
- if( nFree!=0 ){
- u32 nLeaf; /* Initial number of leaf cells on trunk page */
-
- iTrunk = get4byte(&pPage1->aData[32]);
- rc = btreeGetPage(pBt, iTrunk, &pTrunk, 0);
- if( rc!=SQLITE_OK ){
- goto freepage_out;
- }
-
- nLeaf = get4byte(&pTrunk->aData[4]);
- assert( pBt->usableSize>32 );
- if( nLeaf > (u32)pBt->usableSize/4 - 2 ){
- rc = SQLITE_CORRUPT_BKPT;
- goto freepage_out;
- }
- if( nLeaf < (u32)pBt->usableSize/4 - 8 ){
- /* In this case there is room on the trunk page to insert the page
- ** being freed as a new leaf.
- **
- ** Note that the trunk page is not really full until it contains
- ** usableSize/4 - 2 entries, not usableSize/4 - 8 entries as we have
- ** coded. But due to a coding error in versions of SQLite prior to
- ** 3.6.0, databases with freelist trunk pages holding more than
- ** usableSize/4 - 8 entries will be reported as corrupt. In order
- ** to maintain backwards compatibility with older versions of SQLite,
- ** we will continue to restrict the number of entries to usableSize/4 - 8
- ** for now. At some point in the future (once everyone has upgraded
- ** to 3.6.0 or later) we should consider fixing the conditional above
- ** to read "usableSize/4-2" instead of "usableSize/4-8".
- */
- rc = sqlite3PagerWrite(pTrunk->pDbPage);
- if( rc==SQLITE_OK ){
- put4byte(&pTrunk->aData[4], nLeaf+1);
- put4byte(&pTrunk->aData[8+nLeaf*4], iPage);
-#ifndef SQLITE_SECURE_DELETE
- if( pPage ){
- sqlite3PagerDontWrite(pPage->pDbPage);
- }
-#endif
- rc = btreeSetHasContent(pBt, iPage);
- }
- TRACE(("FREE-PAGE: %d leaf on trunk page %d\n",pPage->pgno,pTrunk->pgno));
- goto freepage_out;
- }
- }
-
- /* If control flows to this point, then it was not possible to add the
- ** the page being freed as a leaf page of the first trunk in the free-list.
- ** Possibly because the free-list is empty, or possibly because the
- ** first trunk in the free-list is full. Either way, the page being freed
- ** will become the new first trunk page in the free-list.
- */
- if( pPage==0 && SQLITE_OK!=(rc = btreeGetPage(pBt, iPage, &pPage, 0)) ){
- goto freepage_out;
- }
- rc = sqlite3PagerWrite(pPage->pDbPage);
- if( rc!=SQLITE_OK ){
- goto freepage_out;
- }
- put4byte(pPage->aData, iTrunk);
- put4byte(&pPage->aData[4], 0);
- put4byte(&pPage1->aData[32], iPage);
- TRACE(("FREE-PAGE: %d new trunk page replacing %d\n", pPage->pgno, iTrunk));
-
-freepage_out:
- if( pPage ){
- pPage->isInit = 0;
- }
- releasePage(pPage);
- releasePage(pTrunk);
- return rc;
-}
-static void freePage(MemPage *pPage, int *pRC){
- if( (*pRC)==SQLITE_OK ){
- *pRC = freePage2(pPage->pBt, pPage, pPage->pgno);
- }
-}
-
-/*
-** Free any overflow pages associated with the given Cell.
-*/
-static int clearCell(MemPage *pPage, unsigned char *pCell){
- BtShared *pBt = pPage->pBt;
- CellInfo info;
- Pgno ovflPgno;
- int rc;
- int nOvfl;
- u16 ovflPageSize;
-
- assert( sqlite3_mutex_held(pPage->pBt->mutex) );
- btreeParseCellPtr(pPage, pCell, &info);
- if( info.iOverflow==0 ){
- return SQLITE_OK; /* No overflow pages. Return without doing anything */
- }
- ovflPgno = get4byte(&pCell[info.iOverflow]);
- assert( pBt->usableSize > 4 );
- ovflPageSize = pBt->usableSize - 4;
- nOvfl = (info.nPayload - info.nLocal + ovflPageSize - 1)/ovflPageSize;
- assert( ovflPgno==0 || nOvfl>0 );
- while( nOvfl-- ){
- Pgno iNext = 0;
- MemPage *pOvfl = 0;
- if( ovflPgno<2 || ovflPgno>pagerPagecount(pBt) ){
- /* 0 is not a legal page number and page 1 cannot be an
- ** overflow page. Therefore if ovflPgno<2 or past the end of the
- ** file the database must be corrupt. */
- return SQLITE_CORRUPT_BKPT;
- }
- if( nOvfl ){
- rc = getOverflowPage(pBt, ovflPgno, &pOvfl, &iNext);
- if( rc ) return rc;
- }
- rc = freePage2(pBt, pOvfl, ovflPgno);
- if( pOvfl ){
- sqlite3PagerUnref(pOvfl->pDbPage);
- }
- if( rc ) return rc;
- ovflPgno = iNext;
- }
- return SQLITE_OK;
-}
-
-/*
-** Create the byte sequence used to represent a cell on page pPage
-** and write that byte sequence into pCell[]. Overflow pages are
-** allocated and filled in as necessary. The calling procedure
-** is responsible for making sure sufficient space has been allocated
-** for pCell[].
-**
-** Note that pCell does not necessary need to point to the pPage->aData
-** area. pCell might point to some temporary storage. The cell will
-** be constructed in this temporary area then copied into pPage->aData
-** later.
-*/
-static int fillInCell(
- MemPage *pPage, /* The page that contains the cell */
- unsigned char *pCell, /* Complete text of the cell */
- const void *pKey, i64 nKey, /* The key */
- const void *pData,int nData, /* The data */
- int nZero, /* Extra zero bytes to append to pData */
- int *pnSize /* Write cell size here */
-){
- int nPayload;
- const u8 *pSrc;
- int nSrc, n, rc;
- int spaceLeft;
- MemPage *pOvfl = 0;
- MemPage *pToRelease = 0;
- unsigned char *pPrior;
- unsigned char *pPayload;
- BtShared *pBt = pPage->pBt;
- Pgno pgnoOvfl = 0;
- int nHeader;
- CellInfo info;
-
- assert( sqlite3_mutex_held(pPage->pBt->mutex) );
-
- /* pPage is not necessarily writeable since pCell might be auxiliary
- ** buffer space that is separate from the pPage buffer area */
- assert( pCell<pPage->aData || pCell>=&pPage->aData[pBt->pageSize]
- || sqlite3PagerIswriteable(pPage->pDbPage) );
-
- /* Fill in the header. */
- nHeader = 0;
- if( !pPage->leaf ){
- nHeader += 4;
- }
- if( pPage->hasData ){
- nHeader += putVarint(&pCell[nHeader], nData+nZero);
- }else{
- nData = nZero = 0;
- }
- nHeader += putVarint(&pCell[nHeader], *(u64*)&nKey);
- btreeParseCellPtr(pPage, pCell, &info);
- assert( info.nHeader==nHeader );
- assert( info.nKey==nKey );
- assert( info.nData==(u32)(nData+nZero) );
-
- /* Fill in the payload */
- nPayload = nData + nZero;
- if( pPage->intKey ){
- pSrc = pData;
- nSrc = nData;
- nData = 0;
- }else{
- if( NEVER(nKey>0x7fffffff || pKey==0) ){
- return SQLITE_CORRUPT_BKPT;
- }
- nPayload += (int)nKey;
- pSrc = pKey;
- nSrc = (int)nKey;
- }
- *pnSize = info.nSize;
- spaceLeft = info.nLocal;
- pPayload = &pCell[nHeader];
- pPrior = &pCell[info.iOverflow];
-
- while( nPayload>0 ){
- if( spaceLeft==0 ){
-#ifndef SQLITE_OMIT_AUTOVACUUM
- Pgno pgnoPtrmap = pgnoOvfl; /* Overflow page pointer-map entry page */
- if( pBt->autoVacuum ){
- do{
- pgnoOvfl++;
- } while(
- PTRMAP_ISPAGE(pBt, pgnoOvfl) || pgnoOvfl==PENDING_BYTE_PAGE(pBt)
- );
- }
-#endif
- rc = allocateBtreePage(pBt, &pOvfl, &pgnoOvfl, pgnoOvfl, 0);
-#ifndef SQLITE_OMIT_AUTOVACUUM
- /* If the database supports auto-vacuum, and the second or subsequent
- ** overflow page is being allocated, add an entry to the pointer-map
- ** for that page now.
- **
- ** If this is the first overflow page, then write a partial entry
- ** to the pointer-map. If we write nothing to this pointer-map slot,
- ** then the optimistic overflow chain processing in clearCell()
- ** may misinterpret the uninitialised values and delete the
- ** wrong pages from the database.
- */
- if( pBt->autoVacuum && rc==SQLITE_OK ){
- u8 eType = (pgnoPtrmap?PTRMAP_OVERFLOW2:PTRMAP_OVERFLOW1);
- ptrmapPut(pBt, pgnoOvfl, eType, pgnoPtrmap, &rc);
- if( rc ){
- releasePage(pOvfl);
- }
- }
-#endif
- if( rc ){
- releasePage(pToRelease);
- return rc;
- }
-
- /* If pToRelease is not zero than pPrior points into the data area
- ** of pToRelease. Make sure pToRelease is still writeable. */
- assert( pToRelease==0 || sqlite3PagerIswriteable(pToRelease->pDbPage) );
-
- /* If pPrior is part of the data area of pPage, then make sure pPage
- ** is still writeable */
- assert( pPrior<pPage->aData || pPrior>=&pPage->aData[pBt->pageSize]
- || sqlite3PagerIswriteable(pPage->pDbPage) );
-
- put4byte(pPrior, pgnoOvfl);
- releasePage(pToRelease);
- pToRelease = pOvfl;
- pPrior = pOvfl->aData;
- put4byte(pPrior, 0);
- pPayload = &pOvfl->aData[4];
- spaceLeft = pBt->usableSize - 4;
- }
- n = nPayload;
- if( n>spaceLeft ) n = spaceLeft;
-
- /* If pToRelease is not zero than pPayload points into the data area
- ** of pToRelease. Make sure pToRelease is still writeable. */
- assert( pToRelease==0 || sqlite3PagerIswriteable(pToRelease->pDbPage) );
-
- /* If pPayload is part of the data area of pPage, then make sure pPage
- ** is still writeable */
- assert( pPayload<pPage->aData || pPayload>=&pPage->aData[pBt->pageSize]
- || sqlite3PagerIswriteable(pPage->pDbPage) );
-
- if( nSrc>0 ){
- if( n>nSrc ) n = nSrc;
- assert( pSrc );
- memcpy(pPayload, pSrc, n);
- }else{
- memset(pPayload, 0, n);
- }
- nPayload -= n;
- pPayload += n;
- pSrc += n;
- nSrc -= n;
- spaceLeft -= n;
- if( nSrc==0 ){
- nSrc = nData;
- pSrc = pData;
- }
- }
- releasePage(pToRelease);
- return SQLITE_OK;
-}
-
-/*
-** Remove the i-th cell from pPage. This routine effects pPage only.
-** The cell content is not freed or deallocated. It is assumed that
-** the cell content has been copied someplace else. This routine just
-** removes the reference to the cell from pPage.
-**
-** "sz" must be the number of bytes in the cell.
-*/
-static void dropCell(MemPage *pPage, int idx, int sz, int *pRC){
- int i; /* Loop counter */
- int pc; /* Offset to cell content of cell being deleted */
- u8 *data; /* pPage->aData */
- u8 *ptr; /* Used to move bytes around within data[] */
- int rc; /* The return code */
- int hdr; /* Beginning of the header. 0 most pages. 100 page 1 */
-
- if( *pRC ) return;
-
- assert( idx>=0 && idx<pPage->nCell );
- assert( sz==cellSize(pPage, idx) );
- assert( sqlite3PagerIswriteable(pPage->pDbPage) );
- assert( sqlite3_mutex_held(pPage->pBt->mutex) );
- data = pPage->aData;
- ptr = &data[pPage->cellOffset + 2*idx];
- pc = get2byte(ptr);
- hdr = pPage->hdrOffset;
- testcase( pc==get2byte(&data[hdr+5]) );
- testcase( pc+sz==pPage->pBt->usableSize );
- if( pc < get2byte(&data[hdr+5]) || pc+sz > pPage->pBt->usableSize ){
- *pRC = SQLITE_CORRUPT_BKPT;
- return;
- }
- rc = freeSpace(pPage, pc, sz);
- if( rc ){
- *pRC = rc;
- return;
- }
- for(i=idx+1; i<pPage->nCell; i++, ptr+=2){
- ptr[0] = ptr[2];
- ptr[1] = ptr[3];
- }
- pPage->nCell--;
- put2byte(&data[hdr+3], pPage->nCell);
- pPage->nFree += 2;
-}
-
-/*
-** Insert a new cell on pPage at cell index "i". pCell points to the
-** content of the cell.
-**
-** If the cell content will fit on the page, then put it there. If it
-** will not fit, then make a copy of the cell content into pTemp if
-** pTemp is not null. Regardless of pTemp, allocate a new entry
-** in pPage->aOvfl[] and make it point to the cell content (either
-** in pTemp or the original pCell) and also record its index.
-** Allocating a new entry in pPage->aCell[] implies that
-** pPage->nOverflow is incremented.
-**
-** If nSkip is non-zero, then do not copy the first nSkip bytes of the
-** cell. The caller will overwrite them after this function returns. If
-** nSkip is non-zero, then pCell may not point to an invalid memory location
-** (but pCell+nSkip is always valid).
-*/
-static void insertCell(
- MemPage *pPage, /* Page into which we are copying */
- int i, /* New cell becomes the i-th cell of the page */
- u8 *pCell, /* Content of the new cell */
- int sz, /* Bytes of content in pCell */
- u8 *pTemp, /* Temp storage space for pCell, if needed */
- Pgno iChild, /* If non-zero, replace first 4 bytes with this value */
- int *pRC /* Read and write return code from here */
-){
- int idx; /* Where to write new cell content in data[] */
- int j; /* Loop counter */
- int end; /* First byte past the last cell pointer in data[] */
- int ins; /* Index in data[] where new cell pointer is inserted */
- int cellOffset; /* Address of first cell pointer in data[] */
- u8 *data; /* The content of the whole page */
- u8 *ptr; /* Used for moving information around in data[] */
-
- int nSkip = (iChild ? 4 : 0);
-
- if( *pRC ) return;
-
- assert( i>=0 && i<=pPage->nCell+pPage->nOverflow );
- assert( pPage->nCell<=MX_CELL(pPage->pBt) && MX_CELL(pPage->pBt)<=5460 );
- assert( pPage->nOverflow<=ArraySize(pPage->aOvfl) );
- assert( sz==cellSizePtr(pPage, pCell) );
- assert( sqlite3_mutex_held(pPage->pBt->mutex) );
- if( pPage->nOverflow || sz+2>pPage->nFree ){
- if( pTemp ){
- memcpy(pTemp+nSkip, pCell+nSkip, sz-nSkip);
- pCell = pTemp;
- }
- if( iChild ){
- put4byte(pCell, iChild);
- }
- j = pPage->nOverflow++;
- assert( j<(int)(sizeof(pPage->aOvfl)/sizeof(pPage->aOvfl[0])) );
- pPage->aOvfl[j].pCell = pCell;
- pPage->aOvfl[j].idx = (u16)i;
- }else{
- int rc = sqlite3PagerWrite(pPage->pDbPage);
- if( rc!=SQLITE_OK ){
- *pRC = rc;
- return;
- }
- assert( sqlite3PagerIswriteable(pPage->pDbPage) );
- data = pPage->aData;
- cellOffset = pPage->cellOffset;
- end = cellOffset + 2*pPage->nCell;
- ins = cellOffset + 2*i;
- rc = allocateSpace(pPage, sz, &idx);
- if( rc ){ *pRC = rc; return; }
- /* The allocateSpace() routine guarantees the following two properties
- ** if it returns success */
- assert( idx >= end+2 );
- assert( idx+sz <= pPage->pBt->usableSize );
- pPage->nCell++;
- pPage->nFree -= (u16)(2 + sz);
- memcpy(&data[idx+nSkip], pCell+nSkip, sz-nSkip);
- if( iChild ){
- put4byte(&data[idx], iChild);
- }
- for(j=end, ptr=&data[j]; j>ins; j-=2, ptr-=2){
- ptr[0] = ptr[-2];
- ptr[1] = ptr[-1];
- }
- put2byte(&data[ins], idx);
- put2byte(&data[pPage->hdrOffset+3], pPage->nCell);
-#ifndef SQLITE_OMIT_AUTOVACUUM
- if( pPage->pBt->autoVacuum ){
- /* The cell may contain a pointer to an overflow page. If so, write
- ** the entry for the overflow page into the pointer map.
- */
- ptrmapPutOvflPtr(pPage, pCell, pRC);
- }
-#endif
- }
-}
-
-/*
-** Add a list of cells to a page. The page should be initially empty.
-** The cells are guaranteed to fit on the page.
-*/
-static void assemblePage(
- MemPage *pPage, /* The page to be assemblied */
- int nCell, /* The number of cells to add to this page */
- u8 **apCell, /* Pointers to cell bodies */
- u16 *aSize /* Sizes of the cells */
-){
- int i; /* Loop counter */
- u8 *pCellptr; /* Address of next cell pointer */
- int cellbody; /* Address of next cell body */
- u8 * const data = pPage->aData; /* Pointer to data for pPage */
- const int hdr = pPage->hdrOffset; /* Offset of header on pPage */
- const int nUsable = pPage->pBt->usableSize; /* Usable size of page */
-
- assert( pPage->nOverflow==0 );
- assert( sqlite3_mutex_held(pPage->pBt->mutex) );
- assert( nCell>=0 && nCell<=MX_CELL(pPage->pBt) && MX_CELL(pPage->pBt)<=5460 );
- assert( sqlite3PagerIswriteable(pPage->pDbPage) );
-
- /* Check that the page has just been zeroed by zeroPage() */
- assert( pPage->nCell==0 );
- assert( get2byte(&data[hdr+5])==nUsable );
-
- pCellptr = &data[pPage->cellOffset + nCell*2];
- cellbody = nUsable;
- for(i=nCell-1; i>=0; i--){
- pCellptr -= 2;
- cellbody -= aSize[i];
- put2byte(pCellptr, cellbody);
- memcpy(&data[cellbody], apCell[i], aSize[i]);
- }
- put2byte(&data[hdr+3], nCell);
- put2byte(&data[hdr+5], cellbody);
- pPage->nFree -= (nCell*2 + nUsable - cellbody);
- pPage->nCell = (u16)nCell;
-}
-
-/*
-** The following parameters determine how many adjacent pages get involved
-** in a balancing operation. NN is the number of neighbors on either side
-** of the page that participate in the balancing operation. NB is the
-** total number of pages that participate, including the target page and
-** NN neighbors on either side.
-**
-** The minimum value of NN is 1 (of course). Increasing NN above 1
-** (to 2 or 3) gives a modest improvement in SELECT and DELETE performance
-** in exchange for a larger degradation in INSERT and UPDATE performance.
-** The value of NN appears to give the best results overall.
-*/
-#define NN 1 /* Number of neighbors on either side of pPage */
-#define NB (NN*2+1) /* Total pages involved in the balance */
-
-
-#ifndef SQLITE_OMIT_QUICKBALANCE
-/*
-** This version of balance() handles the common special case where
-** a new entry is being inserted on the extreme right-end of the
-** tree, in other words, when the new entry will become the largest
-** entry in the tree.
-**
-** Instead of trying to balance the 3 right-most leaf pages, just add
-** a new page to the right-hand side and put the one new entry in
-** that page. This leaves the right side of the tree somewhat
-** unbalanced. But odds are that we will be inserting new entries
-** at the end soon afterwards so the nearly empty page will quickly
-** fill up. On average.
-**
-** pPage is the leaf page which is the right-most page in the tree.
-** pParent is its parent. pPage must have a single overflow entry
-** which is also the right-most entry on the page.
-**
-** The pSpace buffer is used to store a temporary copy of the divider
-** cell that will be inserted into pParent. Such a cell consists of a 4
-** byte page number followed by a variable length integer. In other
-** words, at most 13 bytes. Hence the pSpace buffer must be at
-** least 13 bytes in size.
-*/
-static int balance_quick(MemPage *pParent, MemPage *pPage, u8 *pSpace){
- BtShared *const pBt = pPage->pBt; /* B-Tree Database */
- MemPage *pNew; /* Newly allocated page */
- int rc; /* Return Code */
- Pgno pgnoNew; /* Page number of pNew */
-
- assert( sqlite3_mutex_held(pPage->pBt->mutex) );
- assert( sqlite3PagerIswriteable(pParent->pDbPage) );
- assert( pPage->nOverflow==1 );
-
- if( pPage->nCell<=0 ) return SQLITE_CORRUPT_BKPT;
-
- /* Allocate a new page. This page will become the right-sibling of
- ** pPage. Make the parent page writable, so that the new divider cell
- ** may be inserted. If both these operations are successful, proceed.
- */
- rc = allocateBtreePage(pBt, &pNew, &pgnoNew, 0, 0);
-
- if( rc==SQLITE_OK ){
-
- u8 *pOut = &pSpace[4];
- u8 *pCell = pPage->aOvfl[0].pCell;
- u16 szCell = cellSizePtr(pPage, pCell);
- u8 *pStop;
-
- assert( sqlite3PagerIswriteable(pNew->pDbPage) );
- assert( pPage->aData[0]==(PTF_INTKEY|PTF_LEAFDATA|PTF_LEAF) );
- zeroPage(pNew, PTF_INTKEY|PTF_LEAFDATA|PTF_LEAF);
- assemblePage(pNew, 1, &pCell, &szCell);
-
- /* If this is an auto-vacuum database, update the pointer map
- ** with entries for the new page, and any pointer from the
- ** cell on the page to an overflow page. If either of these
- ** operations fails, the return code is set, but the contents
- ** of the parent page are still manipulated by thh code below.
- ** That is Ok, at this point the parent page is guaranteed to
- ** be marked as dirty. Returning an error code will cause a
- ** rollback, undoing any changes made to the parent page.
- */
- if( ISAUTOVACUUM ){
- ptrmapPut(pBt, pgnoNew, PTRMAP_BTREE, pParent->pgno, &rc);
- if( szCell>pNew->minLocal ){
- ptrmapPutOvflPtr(pNew, pCell, &rc);
- }
- }
-
- /* Create a divider cell to insert into pParent. The divider cell
- ** consists of a 4-byte page number (the page number of pPage) and
- ** a variable length key value (which must be the same value as the
- ** largest key on pPage).
- **
- ** To find the largest key value on pPage, first find the right-most
- ** cell on pPage. The first two fields of this cell are the
- ** record-length (a variable length integer at most 32-bits in size)
- ** and the key value (a variable length integer, may have any value).
- ** The first of the while(...) loops below skips over the record-length
- ** field. The second while(...) loop copies the key value from the
- ** cell on pPage into the pSpace buffer.
- */
- pCell = findCell(pPage, pPage->nCell-1);
- pStop = &pCell[9];
- while( (*(pCell++)&0x80) && pCell<pStop );
- pStop = &pCell[9];
- while( ((*(pOut++) = *(pCell++))&0x80) && pCell<pStop );
-
- /* Insert the new divider cell into pParent. */
- insertCell(pParent, pParent->nCell, pSpace, (int)(pOut-pSpace),
- 0, pPage->pgno, &rc);
-
- /* Set the right-child pointer of pParent to point to the new page. */
- put4byte(&pParent->aData[pParent->hdrOffset+8], pgnoNew);
-
- /* Release the reference to the new page. */
- releasePage(pNew);
- }
-
- return rc;
-}
-#endif /* SQLITE_OMIT_QUICKBALANCE */
-
-#if 0
-/*
-** This function does not contribute anything to the operation of SQLite.
-** it is sometimes activated temporarily while debugging code responsible
-** for setting pointer-map entries.
-*/
-static int ptrmapCheckPages(MemPage **apPage, int nPage){
- int i, j;
- for(i=0; i<nPage; i++){
- Pgno n;
- u8 e;
- MemPage *pPage = apPage[i];
- BtShared *pBt = pPage->pBt;
- assert( pPage->isInit );
-
- for(j=0; j<pPage->nCell; j++){
- CellInfo info;
- u8 *z;
-
- z = findCell(pPage, j);
- btreeParseCellPtr(pPage, z, &info);
- if( info.iOverflow ){
- Pgno ovfl = get4byte(&z[info.iOverflow]);
- ptrmapGet(pBt, ovfl, &e, &n);
- assert( n==pPage->pgno && e==PTRMAP_OVERFLOW1 );
- }
- if( !pPage->leaf ){
- Pgno child = get4byte(z);
- ptrmapGet(pBt, child, &e, &n);
- assert( n==pPage->pgno && e==PTRMAP_BTREE );
- }
- }
- if( !pPage->leaf ){
- Pgno child = get4byte(&pPage->aData[pPage->hdrOffset+8]);
- ptrmapGet(pBt, child, &e, &n);
- assert( n==pPage->pgno && e==PTRMAP_BTREE );
- }
- }
- return 1;
-}
-#endif
-
-/*
-** This function is used to copy the contents of the b-tree node stored
-** on page pFrom to page pTo. If page pFrom was not a leaf page, then
-** the pointer-map entries for each child page are updated so that the
-** parent page stored in the pointer map is page pTo. If pFrom contained
-** any cells with overflow page pointers, then the corresponding pointer
-** map entries are also updated so that the parent page is page pTo.
-**
-** If pFrom is currently carrying any overflow cells (entries in the
-** MemPage.aOvfl[] array), they are not copied to pTo.
-**
-** Before returning, page pTo is reinitialized using btreeInitPage().
-**
-** The performance of this function is not critical. It is only used by
-** the balance_shallower() and balance_deeper() procedures, neither of
-** which are called often under normal circumstances.
-*/
-static void copyNodeContent(MemPage *pFrom, MemPage *pTo, int *pRC){
- if( (*pRC)==SQLITE_OK ){
- BtShared * const pBt = pFrom->pBt;
- u8 * const aFrom = pFrom->aData;
- u8 * const aTo = pTo->aData;
- int const iFromHdr = pFrom->hdrOffset;
- int const iToHdr = ((pTo->pgno==1) ? 100 : 0);
- TESTONLY(int rc;)
- int iData;
-
-
- assert( pFrom->isInit );
- assert( pFrom->nFree>=iToHdr );
- assert( get2byte(&aFrom[iFromHdr+5])<=pBt->usableSize );
-
- /* Copy the b-tree node content from page pFrom to page pTo. */
- iData = get2byte(&aFrom[iFromHdr+5]);
- memcpy(&aTo[iData], &aFrom[iData], pBt->usableSize-iData);
- memcpy(&aTo[iToHdr], &aFrom[iFromHdr], pFrom->cellOffset + 2*pFrom->nCell);
-
- /* Reinitialize page pTo so that the contents of the MemPage structure
- ** match the new data. The initialization of pTo "cannot" fail, as the
- ** data copied from pFrom is known to be valid. */
- pTo->isInit = 0;
- TESTONLY(rc = ) btreeInitPage(pTo);
- assert( rc==SQLITE_OK );
-
- /* If this is an auto-vacuum database, update the pointer-map entries
- ** for any b-tree or overflow pages that pTo now contains the pointers to.
- */
- if( ISAUTOVACUUM ){
- *pRC = setChildPtrmaps(pTo);
- }
- }
-}
-
-/*
-** This routine redistributes cells on the iParentIdx'th child of pParent
-** (hereafter "the page") and up to 2 siblings so that all pages have about the
-** same amount of free space. Usually a single sibling on either side of the
-** page are used in the balancing, though both siblings might come from one
-** side if the page is the first or last child of its parent. If the page
-** has fewer than 2 siblings (something which can only happen if the page
-** is a root page or a child of a root page) then all available siblings
-** participate in the balancing.
-**
-** The number of siblings of the page might be increased or decreased by
-** one or two in an effort to keep pages nearly full but not over full.
-**
-** Note that when this routine is called, some of the cells on the page
-** might not actually be stored in MemPage.aData[]. This can happen
-** if the page is overfull. This routine ensures that all cells allocated
-** to the page and its siblings fit into MemPage.aData[] before returning.
-**
-** In the course of balancing the page and its siblings, cells may be
-** inserted into or removed from the parent page (pParent). Doing so
-** may cause the parent page to become overfull or underfull. If this
-** happens, it is the responsibility of the caller to invoke the correct
-** balancing routine to fix this problem (see the balance() routine).
-**
-** If this routine fails for any reason, it might leave the database
-** in a corrupted state. So if this routine fails, the database should
-** be rolled back.
-**
-** The third argument to this function, aOvflSpace, is a pointer to a
-** buffer big enough to hold one page. If while inserting cells into the parent
-** page (pParent) the parent page becomes overfull, this buffer is
-** used to store the parent's overflow cells. Because this function inserts
-** a maximum of four divider cells into the parent page, and the maximum
-** size of a cell stored within an internal node is always less than 1/4
-** of the page-size, the aOvflSpace[] buffer is guaranteed to be large
-** enough for all overflow cells.
-**
-** If aOvflSpace is set to a null pointer, this function returns
-** SQLITE_NOMEM.
-*/
-static int balance_nonroot(
- MemPage *pParent, /* Parent page of siblings being balanced */
- int iParentIdx, /* Index of "the page" in pParent */
- u8 *aOvflSpace, /* page-size bytes of space for parent ovfl */
- int isRoot /* True if pParent is a root-page */
-){
- BtShared *pBt; /* The whole database */
- int nCell = 0; /* Number of cells in apCell[] */
- int nMaxCells = 0; /* Allocated size of apCell, szCell, aFrom. */
- int nNew = 0; /* Number of pages in apNew[] */
- int nOld; /* Number of pages in apOld[] */
- int i, j, k; /* Loop counters */
- int nxDiv; /* Next divider slot in pParent->aCell[] */
- int rc = SQLITE_OK; /* The return code */
- u16 leafCorrection; /* 4 if pPage is a leaf. 0 if not */
- int leafData; /* True if pPage is a leaf of a LEAFDATA tree */
- int usableSpace; /* Bytes in pPage beyond the header */
- int pageFlags; /* Value of pPage->aData[0] */
- int subtotal; /* Subtotal of bytes in cells on one page */
- int iSpace1 = 0; /* First unused byte of aSpace1[] */
- int iOvflSpace = 0; /* First unused byte of aOvflSpace[] */
- int szScratch; /* Size of scratch memory requested */
- MemPage *apOld[NB]; /* pPage and up to two siblings */
- MemPage *apCopy[NB]; /* Private copies of apOld[] pages */
- MemPage *apNew[NB+2]; /* pPage and up to NB siblings after balancing */
- u8 *pRight; /* Location in parent of right-sibling pointer */
- u8 *apDiv[NB-1]; /* Divider cells in pParent */
- int cntNew[NB+2]; /* Index in aCell[] of cell after i-th page */
- int szNew[NB+2]; /* Combined size of cells place on i-th page */
- u8 **apCell = 0; /* All cells begin balanced */
- u16 *szCell; /* Local size of all cells in apCell[] */
- u8 *aSpace1; /* Space for copies of dividers cells */
- Pgno pgno; /* Temp var to store a page number in */
-
- pBt = pParent->pBt;
- assert( sqlite3_mutex_held(pBt->mutex) );
- assert( sqlite3PagerIswriteable(pParent->pDbPage) );
-
-#if 0
- TRACE(("BALANCE: begin page %d child of %d\n", pPage->pgno, pParent->pgno));
-#endif
-
- /* At this point pParent may have at most one overflow cell. And if
- ** this overflow cell is present, it must be the cell with
- ** index iParentIdx. This scenario comes about when this function
- ** is called (indirectly) from sqlite3BtreeDelete().
- */
- assert( pParent->nOverflow==0 || pParent->nOverflow==1 );
- assert( pParent->nOverflow==0 || pParent->aOvfl[0].idx==iParentIdx );
-
- if( !aOvflSpace ){
- return SQLITE_NOMEM;
- }
-
- /* Find the sibling pages to balance. Also locate the cells in pParent
- ** that divide the siblings. An attempt is made to find NN siblings on
- ** either side of pPage. More siblings are taken from one side, however,
- ** if there are fewer than NN siblings on the other side. If pParent
- ** has NB or fewer children then all children of pParent are taken.
- **
- ** This loop also drops the divider cells from the parent page. This
- ** way, the remainder of the function does not have to deal with any
- ** overflow cells in the parent page, since if any existed they will
- ** have already been removed.
- */
- i = pParent->nOverflow + pParent->nCell;
- if( i<2 ){
- nxDiv = 0;
- nOld = i+1;
- }else{
- nOld = 3;
- if( iParentIdx==0 ){
- nxDiv = 0;
- }else if( iParentIdx==i ){
- nxDiv = i-2;
- }else{
- nxDiv = iParentIdx-1;
- }
- i = 2;
- }
- if( (i+nxDiv-pParent->nOverflow)==pParent->nCell ){
- pRight = &pParent->aData[pParent->hdrOffset+8];
- }else{
- pRight = findCell(pParent, i+nxDiv-pParent->nOverflow);
- }
- pgno = get4byte(pRight);
- while( 1 ){
- rc = getAndInitPage(pBt, pgno, &apOld[i]);
- if( rc ){
- memset(apOld, 0, (i+1)*sizeof(MemPage*));
- goto balance_cleanup;
- }
- nMaxCells += 1+apOld[i]->nCell+apOld[i]->nOverflow;
- if( (i--)==0 ) break;
-
- if( i+nxDiv==pParent->aOvfl[0].idx && pParent->nOverflow ){
- apDiv[i] = pParent->aOvfl[0].pCell;
- pgno = get4byte(apDiv[i]);
- szNew[i] = cellSizePtr(pParent, apDiv[i]);
- pParent->nOverflow = 0;
- }else{
- apDiv[i] = findCell(pParent, i+nxDiv-pParent->nOverflow);
- pgno = get4byte(apDiv[i]);
- szNew[i] = cellSizePtr(pParent, apDiv[i]);
-
- /* Drop the cell from the parent page. apDiv[i] still points to
- ** the cell within the parent, even though it has been dropped.
- ** This is safe because dropping a cell only overwrites the first
- ** four bytes of it, and this function does not need the first
- ** four bytes of the divider cell. So the pointer is safe to use
- ** later on.
- **
- ** Unless SQLite is compiled in secure-delete mode. In this case,
- ** the dropCell() routine will overwrite the entire cell with zeroes.
- ** 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. */
-#ifdef SQLITE_SECURE_DELETE
- memcpy(&aOvflSpace[apDiv[i]-pParent->aData], apDiv[i], szNew[i]);
- apDiv[i] = &aOvflSpace[apDiv[i]-pParent->aData];
-#endif
- dropCell(pParent, i+nxDiv-pParent->nOverflow, szNew[i], &rc);
- }
- }
-
- /* Make nMaxCells a multiple of 4 in order to preserve 8-byte
- ** alignment */
- nMaxCells = (nMaxCells + 3)&~3;
-
- /*
- ** Allocate space for memory structures
- */
- k = pBt->pageSize + ROUND8(sizeof(MemPage));
- szScratch =
- nMaxCells*sizeof(u8*) /* apCell */
- + nMaxCells*sizeof(u16) /* szCell */
- + pBt->pageSize /* aSpace1 */
- + k*nOld; /* Page copies (apCopy) */
- apCell = sqlite3ScratchMalloc( szScratch );
- if( apCell==0 ){
- rc = SQLITE_NOMEM;
- goto balance_cleanup;
- }
- szCell = (u16*)&apCell[nMaxCells];
- aSpace1 = (u8*)&szCell[nMaxCells];
- assert( EIGHT_BYTE_ALIGNMENT(aSpace1) );
-
- /*
- ** Load pointers to all cells on sibling pages and the divider cells
- ** into the local apCell[] array. Make copies of the divider cells
- ** into space obtained from aSpace1[] and remove the the divider Cells
- ** from pParent.
- **
- ** If the siblings are on leaf pages, then the child pointers of the
- ** divider cells are stripped from the cells before they are copied
- ** into aSpace1[]. In this way, all cells in apCell[] are without
- ** child pointers. If siblings are not leaves, then all cell in
- ** apCell[] include child pointers. Either way, all cells in apCell[]
- ** are alike.
- **
- ** leafCorrection: 4 if pPage is a leaf. 0 if pPage is not a leaf.
- ** leafData: 1 if pPage holds key+data and pParent holds only keys.
- */
- leafCorrection = apOld[0]->leaf*4;
- leafData = apOld[0]->hasData;
- for(i=0; i<nOld; i++){
- int limit;
-
- /* Before doing anything else, take a copy of the i'th original sibling
- ** The rest of this function will use data from the copies rather
- ** that the original pages since the original pages will be in the
- ** process of being overwritten. */
- MemPage *pOld = apCopy[i] = (MemPage*)&aSpace1[pBt->pageSize + k*i];
- memcpy(pOld, apOld[i], sizeof(MemPage));
- pOld->aData = (void*)&pOld[1];
- memcpy(pOld->aData, apOld[i]->aData, pBt->pageSize);
-
- limit = pOld->nCell+pOld->nOverflow;
- for(j=0; j<limit; j++){
- assert( nCell<nMaxCells );
- apCell[nCell] = findOverflowCell(pOld, j);
- szCell[nCell] = cellSizePtr(pOld, apCell[nCell]);
- nCell++;
- }
- if( i<nOld-1 && !leafData){
- u16 sz = (u16)szNew[i];
- u8 *pTemp;
- assert( nCell<nMaxCells );
- szCell[nCell] = sz;
- pTemp = &aSpace1[iSpace1];
- iSpace1 += sz;
- assert( sz<=pBt->pageSize/4 );
- assert( iSpace1<=pBt->pageSize );
- memcpy(pTemp, apDiv[i], sz);
- apCell[nCell] = pTemp+leafCorrection;
- assert( leafCorrection==0 || leafCorrection==4 );
- szCell[nCell] = szCell[nCell] - leafCorrection;
- if( !pOld->leaf ){
- assert( leafCorrection==0 );
- assert( pOld->hdrOffset==0 );
- /* The right pointer of the child page pOld becomes the left
- ** pointer of the divider cell */
- memcpy(apCell[nCell], &pOld->aData[8], 4);
- }else{
- assert( leafCorrection==4 );
- if( szCell[nCell]<4 ){
- /* Do not allow any cells smaller than 4 bytes. */
- szCell[nCell] = 4;
- }
- }
- nCell++;
- }
- }
-
- /*
- ** Figure out the number of pages needed to hold all nCell cells.
- ** Store this number in "k". Also compute szNew[] which is the total
- ** size of all cells on the i-th page and cntNew[] which is the index
- ** in apCell[] of the cell that divides page i from page i+1.
- ** cntNew[k] should equal nCell.
- **
- ** Values computed by this block:
- **
- ** k: The total number of sibling pages
- ** szNew[i]: Spaced used on the i-th sibling page.
- ** cntNew[i]: Index in apCell[] and szCell[] for the first cell to
- ** the right of the i-th sibling page.
- ** usableSpace: Number of bytes of space available on each sibling.
- **
- */
- usableSpace = pBt->usableSize - 12 + leafCorrection;
- for(subtotal=k=i=0; i<nCell; i++){
- assert( i<nMaxCells );
- subtotal += szCell[i] + 2;
- if( subtotal > usableSpace ){
- szNew[k] = subtotal - szCell[i];
- cntNew[k] = i;
- if( leafData ){ i--; }
- subtotal = 0;
- k++;
- if( k>NB+1 ){ rc = SQLITE_CORRUPT; goto balance_cleanup; }
- }
- }
- szNew[k] = subtotal;
- cntNew[k] = nCell;
- k++;
-
- /*
- ** The packing computed by the previous block is biased toward the siblings
- ** on the left side. The left siblings are always nearly full, while the
- ** right-most sibling might be nearly empty. This block of code attempts
- ** to adjust the packing of siblings to get a better balance.
- **
- ** This adjustment is more than an optimization. The packing above might
- ** be so out of balance as to be illegal. For example, the right-most
- ** sibling might be completely empty. This adjustment is not optional.
- */
- for(i=k-1; i>0; i--){
- int szRight = szNew[i]; /* Size of sibling on the right */
- int szLeft = szNew[i-1]; /* Size of sibling on the left */
- int r; /* Index of right-most cell in left sibling */
- int d; /* Index of first cell to the left of right sibling */
-
- r = cntNew[i-1] - 1;
- d = r + 1 - leafData;
- assert( d<nMaxCells );
- assert( r<nMaxCells );
- while( szRight==0 || szRight+szCell[d]+2<=szLeft-(szCell[r]+2) ){
- szRight += szCell[d] + 2;
- szLeft -= szCell[r] + 2;
- cntNew[i-1]--;
- r = cntNew[i-1] - 1;
- d = r + 1 - leafData;
- }
- szNew[i] = szRight;
- szNew[i-1] = szLeft;
- }
-
- /* 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.
- */
- assert( cntNew[0]>0 || (pParent->pgno==1 && pParent->nCell==0) );
-
- TRACE(("BALANCE: old: %d %d %d ",
- apOld[0]->pgno,
- nOld>=2 ? apOld[1]->pgno : 0,
- nOld>=3 ? apOld[2]->pgno : 0
- ));
-
- /*
- ** Allocate k new pages. Reuse old pages where possible.
- */
- if( apOld[0]->pgno<=1 ){
- rc = SQLITE_CORRUPT;
- goto balance_cleanup;
- }
- pageFlags = apOld[0]->aData[0];
- for(i=0; i<k; i++){
- MemPage *pNew;
- if( i<nOld ){
- pNew = apNew[i] = apOld[i];
- apOld[i] = 0;
- rc = sqlite3PagerWrite(pNew->pDbPage);
- nNew++;
- if( rc ) goto balance_cleanup;
- }else{
- assert( i>0 );
- rc = allocateBtreePage(pBt, &pNew, &pgno, pgno, 0);
- if( rc ) goto balance_cleanup;
- apNew[i] = pNew;
- nNew++;
-
- /* Set the pointer-map entry for the new sibling page. */
- if( ISAUTOVACUUM ){
- ptrmapPut(pBt, pNew->pgno, PTRMAP_BTREE, pParent->pgno, &rc);
- if( rc!=SQLITE_OK ){
- goto balance_cleanup;
- }
- }
- }
- }
-
- /* Free any old pages that were not reused as new pages.
- */
- while( i<nOld ){
- freePage(apOld[i], &rc);
- if( rc ) goto balance_cleanup;
- releasePage(apOld[i]);
- apOld[i] = 0;
- i++;
- }
-
- /*
- ** Put the new pages in accending order. This helps to
- ** keep entries in the disk file in order so that a scan
- ** of the table is a linear scan through the file. That
- ** in turn helps the operating system to deliver pages
- ** from the disk more rapidly.
- **
- ** An O(n^2) insertion sort algorithm is used, but since
- ** n is never more than NB (a small constant), that should
- ** not be a problem.
- **
- ** When NB==3, this one optimization makes the database
- ** about 25% faster for large insertions and deletions.
- */
- for(i=0; i<k-1; i++){
- int minV = apNew[i]->pgno;
- int minI = i;
- for(j=i+1; j<k; j++){
- if( apNew[j]->pgno<(unsigned)minV ){
- minI = j;
- minV = apNew[j]->pgno;
- }
- }
- if( minI>i ){
- int t;
- MemPage *pT;
- t = apNew[i]->pgno;
- pT = apNew[i];
- apNew[i] = apNew[minI];
- apNew[minI] = pT;
- }
- }
- TRACE(("new: %d(%d) %d(%d) %d(%d) %d(%d) %d(%d)\n",
- apNew[0]->pgno, szNew[0],
- nNew>=2 ? apNew[1]->pgno : 0, nNew>=2 ? szNew[1] : 0,
- nNew>=3 ? apNew[2]->pgno : 0, nNew>=3 ? szNew[2] : 0,
- nNew>=4 ? apNew[3]->pgno : 0, nNew>=4 ? szNew[3] : 0,
- nNew>=5 ? apNew[4]->pgno : 0, nNew>=5 ? szNew[4] : 0));
-
- assert( sqlite3PagerIswriteable(pParent->pDbPage) );
- put4byte(pRight, apNew[nNew-1]->pgno);
-
- /*
- ** Evenly distribute the data in apCell[] across the new pages.
- ** Insert divider cells into pParent as necessary.
- */
- j = 0;
- for(i=0; i<nNew; i++){
- /* Assemble the new sibling page. */
- MemPage *pNew = apNew[i];
- assert( j<nMaxCells );
- zeroPage(pNew, pageFlags);
- assemblePage(pNew, cntNew[i]-j, &apCell[j], &szCell[j]);
- assert( pNew->nCell>0 || (nNew==1 && cntNew[0]==0) );
- assert( pNew->nOverflow==0 );
-
- j = cntNew[i];
-
- /* If the sibling page assembled above was not the right-most sibling,
- ** insert a divider cell into the parent page.
- */
- assert( i<nNew-1 || j==nCell );
- if( j<nCell ){
- u8 *pCell;
- u8 *pTemp;
- int sz;
-
- assert( j<nMaxCells );
- pCell = apCell[j];
- sz = szCell[j] + leafCorrection;
- pTemp = &aOvflSpace[iOvflSpace];
- if( !pNew->leaf ){
- memcpy(&pNew->aData[8], pCell, 4);
- }else if( leafData ){
- /* If the tree is a leaf-data tree, and the siblings are leaves,
- ** then there is no divider cell in apCell[]. Instead, the divider
- ** cell consists of the integer key for the right-most cell of
- ** the sibling-page assembled above only.
- */
- CellInfo info;
- j--;
- btreeParseCellPtr(pNew, apCell[j], &info);
- pCell = pTemp;
- sz = 4 + putVarint(&pCell[4], info.nKey);
- pTemp = 0;
- }else{
- pCell -= 4;
- /* Obscure case for non-leaf-data trees: If the cell at pCell was
- ** previously stored on a leaf node, and its reported size was 4
- ** bytes, then it may actually be smaller than this
- ** (see btreeParseCellPtr(), 4 bytes is the minimum size of
- ** any cell). But it is important to pass the correct size to
- ** insertCell(), so reparse the cell now.
- **
- ** Note that this can never happen in an SQLite data file, as all
- ** cells are at least 4 bytes. It only happens in b-trees used
- ** to evaluate "IN (SELECT ...)" and similar clauses.
- */
- if( szCell[j]==4 ){
- assert(leafCorrection==4);
- sz = cellSizePtr(pParent, pCell);
- }
- }
- iOvflSpace += sz;
- assert( sz<=pBt->pageSize/4 );
- assert( iOvflSpace<=pBt->pageSize );
- insertCell(pParent, nxDiv, pCell, sz, pTemp, pNew->pgno, &rc);
- if( rc!=SQLITE_OK ) goto balance_cleanup;
- assert( sqlite3PagerIswriteable(pParent->pDbPage) );
-
- j++;
- nxDiv++;
- }
- }
- assert( j==nCell );
- assert( nOld>0 );
- assert( nNew>0 );
- if( (pageFlags & PTF_LEAF)==0 ){
- u8 *zChild = &apCopy[nOld-1]->aData[8];
- memcpy(&apNew[nNew-1]->aData[8], zChild, 4);
- }
-
- if( isRoot && pParent->nCell==0 && pParent->hdrOffset<=apNew[0]->nFree ){
- /* The root page of the b-tree now contains no cells. The only sibling
- ** page is the right-child of the parent. Copy the contents of the
- ** child page into the parent, decreasing the overall height of the
- ** b-tree structure by one. This is described as the "balance-shallower"
- ** sub-algorithm in some documentation.
- **
- ** If this is an auto-vacuum database, the call to copyNodeContent()
- ** sets all pointer-map entries corresponding to database image pages
- ** for which the pointer is stored within the content being copied.
- **
- ** The second assert below verifies that the child page is defragmented
- ** (it must be, as it was just reconstructed using assemblePage()). This
- ** is important if the parent page happens to be page 1 of the database
- ** image. */
- assert( nNew==1 );
- assert( apNew[0]->nFree ==
- (get2byte(&apNew[0]->aData[5])-apNew[0]->cellOffset-apNew[0]->nCell*2)
- );
- copyNodeContent(apNew[0], pParent, &rc);
- freePage(apNew[0], &rc);
- }else if( ISAUTOVACUUM ){
- /* Fix the pointer-map entries for all the cells that were shifted around.
- ** There are several different types of pointer-map entries that need to
- ** be dealt with by this routine. Some of these have been set already, but
- ** many have not. The following is a summary:
- **
- ** 1) The entries associated with new sibling pages that were not
- ** siblings when this function was called. These have already
- ** been set. We don't need to worry about old siblings that were
- ** moved to the free-list - the freePage() code has taken care
- ** of those.
- **
- ** 2) The pointer-map entries associated with the first overflow
- ** page in any overflow chains used by new divider cells. These
- ** have also already been taken care of by the insertCell() code.
- **
- ** 3) If the sibling pages are not leaves, then the child pages of
- ** cells stored on the sibling pages may need to be updated.
- **
- ** 4) If the sibling pages are not internal intkey nodes, then any
- ** overflow pages used by these cells may need to be updated
- ** (internal intkey nodes never contain pointers to overflow pages).
- **
- ** 5) If the sibling pages are not leaves, then the pointer-map
- ** entries for the right-child pages of each sibling may need
- ** to be updated.
- **
- ** Cases 1 and 2 are dealt with above by other code. The next
- ** block deals with cases 3 and 4 and the one after that, case 5. Since
- ** setting a pointer map entry is a relatively expensive operation, this
- ** code only sets pointer map entries for child or overflow pages that have
- ** actually moved between pages. */
- MemPage *pNew = apNew[0];
- MemPage *pOld = apCopy[0];
- int nOverflow = pOld->nOverflow;
- int iNextOld = pOld->nCell + nOverflow;
- int iOverflow = (nOverflow ? pOld->aOvfl[0].idx : -1);
- j = 0; /* Current 'old' sibling page */
- k = 0; /* Current 'new' sibling page */
- for(i=0; i<nCell; i++){
- int isDivider = 0;
- while( i==iNextOld ){
- /* Cell i is the cell immediately following the last cell on old
- ** sibling page j. If the siblings are not leaf pages of an
- ** intkey b-tree, then cell i was a divider cell. */
- pOld = apCopy[++j];
- iNextOld = i + !leafData + pOld->nCell + pOld->nOverflow;
- if( pOld->nOverflow ){
- nOverflow = pOld->nOverflow;
- iOverflow = i + !leafData + pOld->aOvfl[0].idx;
- }
- isDivider = !leafData;
- }
-
- assert(nOverflow>0 || iOverflow<i );
- assert(nOverflow<2 || pOld->aOvfl[0].idx==pOld->aOvfl[1].idx-1);
- assert(nOverflow<3 || pOld->aOvfl[1].idx==pOld->aOvfl[2].idx-1);
- if( i==iOverflow ){
- isDivider = 1;
- if( (--nOverflow)>0 ){
- iOverflow++;
- }
- }
-
- if( i==cntNew[k] ){
- /* Cell i is the cell immediately following the last cell on new
- ** sibling page k. If the siblings are not leaf pages of an
- ** intkey b-tree, then cell i is a divider cell. */
- pNew = apNew[++k];
- if( !leafData ) continue;
- }
- assert( j<nOld );
- assert( k<nNew );
-
- /* If the cell was originally divider cell (and is not now) or
- ** an overflow cell, or if the cell was located on a different sibling
- ** page before the balancing, then the pointer map entries associated
- ** with any child or overflow pages need to be updated. */
- if( isDivider || pOld->pgno!=pNew->pgno ){
- if( !leafCorrection ){
- ptrmapPut(pBt, get4byte(apCell[i]), PTRMAP_BTREE, pNew->pgno, &rc);
- }
- if( szCell[i]>pNew->minLocal ){
- ptrmapPutOvflPtr(pNew, apCell[i], &rc);
- }
- }
- }
-
- if( !leafCorrection ){
- for(i=0; i<nNew; i++){
- u32 key = get4byte(&apNew[i]->aData[8]);
- ptrmapPut(pBt, key, PTRMAP_BTREE, apNew[i]->pgno, &rc);
- }
- }
-
-#if 0
- /* The ptrmapCheckPages() contains assert() statements that verify that
- ** all pointer map pages are set correctly. This is helpful while
- ** debugging. This is usually disabled because a corrupt database may
- ** cause an assert() statement to fail. */
- ptrmapCheckPages(apNew, nNew);
- ptrmapCheckPages(&pParent, 1);
-#endif
- }
-
- assert( pParent->isInit );
- TRACE(("BALANCE: finished: old=%d new=%d cells=%d\n",
- nOld, nNew, nCell));
-
- /*
- ** Cleanup before returning.
- */
-balance_cleanup:
- sqlite3ScratchFree(apCell);
- for(i=0; i<nOld; i++){
- releasePage(apOld[i]);
- }
- for(i=0; i<nNew; i++){
- releasePage(apNew[i]);
- }
-
- return rc;
-}
-
-
-/*
-** This function is called when the root page of a b-tree structure is
-** overfull (has one or more overflow pages).
-**
-** A new child page is allocated and the contents of the current root
-** page, including overflow cells, are copied into the child. The root
-** page is then overwritten to make it an empty page with the right-child
-** pointer pointing to the new page.
-**
-** Before returning, all pointer-map entries corresponding to pages
-** that the new child-page now contains pointers to are updated. The
-** entry corresponding to the new right-child pointer of the root
-** page is also updated.
-**
-** If successful, *ppChild is set to contain a reference to the child
-** page and SQLITE_OK is returned. In this case the caller is required
-** to call releasePage() on *ppChild exactly once. If an error occurs,
-** an error code is returned and *ppChild is set to 0.
-*/
-static int balance_deeper(MemPage *pRoot, MemPage **ppChild){
- int rc; /* Return value from subprocedures */
- MemPage *pChild = 0; /* Pointer to a new child page */
- Pgno pgnoChild = 0; /* Page number of the new child page */
- BtShared *pBt = pRoot->pBt; /* The BTree */
-
- assert( pRoot->nOverflow>0 );
- assert( sqlite3_mutex_held(pBt->mutex) );
-
- /* Make pRoot, the root page of the b-tree, writable. Allocate a new
- ** page that will become the new right-child of pPage. Copy the contents
- ** of the node stored on pRoot into the new child page.
- */
- rc = sqlite3PagerWrite(pRoot->pDbPage);
- if( rc==SQLITE_OK ){
- rc = allocateBtreePage(pBt,&pChild,&pgnoChild,pRoot->pgno,0);
- copyNodeContent(pRoot, pChild, &rc);
- if( ISAUTOVACUUM ){
- ptrmapPut(pBt, pgnoChild, PTRMAP_BTREE, pRoot->pgno, &rc);
- }
- }
- if( rc ){
- *ppChild = 0;
- releasePage(pChild);
- return rc;
- }
- assert( sqlite3PagerIswriteable(pChild->pDbPage) );
- assert( sqlite3PagerIswriteable(pRoot->pDbPage) );
- assert( pChild->nCell==pRoot->nCell );
-
- TRACE(("BALANCE: copy root %d into %d\n", pRoot->pgno, pChild->pgno));
-
- /* Copy the overflow cells from pRoot to pChild */
- memcpy(pChild->aOvfl, pRoot->aOvfl, pRoot->nOverflow*sizeof(pRoot->aOvfl[0]));
- pChild->nOverflow = pRoot->nOverflow;
-
- /* Zero the contents of pRoot. Then install pChild as the right-child. */
- zeroPage(pRoot, pChild->aData[0] & ~PTF_LEAF);
- put4byte(&pRoot->aData[pRoot->hdrOffset+8], pgnoChild);
-
- *ppChild = pChild;
- return SQLITE_OK;
-}
-
-/*
-** The page that pCur currently points to has just been modified in
-** some way. This function figures out if this modification means the
-** tree needs to be balanced, and if so calls the appropriate balancing
-** routine. Balancing routines are:
-**
-** balance_quick()
-** balance_deeper()
-** balance_nonroot()
-*/
-static int balance(BtCursor *pCur){
- int rc = SQLITE_OK;
- const int nMin = pCur->pBt->usableSize * 2 / 3;
- u8 aBalanceQuickSpace[13];
- u8 *pFree = 0;
-
- TESTONLY( int balance_quick_called = 0 );
- TESTONLY( int balance_deeper_called = 0 );
-
- do {
- int iPage = pCur->iPage;
- MemPage *pPage = pCur->apPage[iPage];
-
- if( iPage==0 ){
- if( pPage->nOverflow ){
- /* The root page of the b-tree is overfull. In this case call the
- ** balance_deeper() function to create a new child for the root-page
- ** and copy the current contents of the root-page to it. The
- ** next iteration of the do-loop will balance the child page.
- */
- assert( (balance_deeper_called++)==0 );
- rc = balance_deeper(pPage, &pCur->apPage[1]);
- if( rc==SQLITE_OK ){
- pCur->iPage = 1;
- pCur->aiIdx[0] = 0;
- pCur->aiIdx[1] = 0;
- assert( pCur->apPage[1]->nOverflow );
- }
- }else{
- break;
- }
- }else if( pPage->nOverflow==0 && pPage->nFree<=nMin ){
- break;
- }else{
- MemPage * const pParent = pCur->apPage[iPage-1];
- int const iIdx = pCur->aiIdx[iPage-1];
-
- rc = sqlite3PagerWrite(pParent->pDbPage);
- if( rc==SQLITE_OK ){
-#ifndef SQLITE_OMIT_QUICKBALANCE
- if( pPage->hasData
- && pPage->nOverflow==1
- && pPage->aOvfl[0].idx==pPage->nCell
- && pParent->pgno!=1
- && pParent->nCell==iIdx
- ){
- /* Call balance_quick() to create a new sibling of pPage on which
- ** to store the overflow cell. balance_quick() inserts a new cell
- ** into pParent, which may cause pParent overflow. If this
- ** happens, the next interation of the do-loop will balance pParent
- ** use either balance_nonroot() or balance_deeper(). Until this
- ** happens, the overflow cell is stored in the aBalanceQuickSpace[]
- ** buffer.
- **
- ** The purpose of the following assert() is to check that only a
- ** single call to balance_quick() is made for each call to this
- ** function. If this were not verified, a subtle bug involving reuse
- ** of the aBalanceQuickSpace[] might sneak in.
- */
- assert( (balance_quick_called++)==0 );
- rc = balance_quick(pParent, pPage, aBalanceQuickSpace);
- }else
-#endif
- {
- /* In this case, call balance_nonroot() to redistribute cells
- ** between pPage and up to 2 of its sibling pages. This involves
- ** modifying the contents of pParent, which may cause pParent to
- ** become overfull or underfull. The next iteration of the do-loop
- ** will balance the parent page to correct this.
- **
- ** If the parent page becomes overfull, the overflow cell or cells
- ** are stored in the pSpace buffer allocated immediately below.
- ** A subsequent iteration of the do-loop will deal with this by
- ** calling balance_nonroot() (balance_deeper() may be called first,
- ** but it doesn't deal with overflow cells - just moves them to a
- ** different page). Once this subsequent call to balance_nonroot()
- ** has completed, it is safe to release the pSpace buffer used by
- ** the previous call, as the overflow cell data will have been
- ** copied either into the body of a database page or into the new
- ** pSpace buffer passed to the latter call to balance_nonroot().
- */
- u8 *pSpace = sqlite3PageMalloc(pCur->pBt->pageSize);
- rc = balance_nonroot(pParent, iIdx, pSpace, iPage==1);
- if( pFree ){
- /* If pFree is not NULL, it points to the pSpace buffer used
- ** by a previous call to balance_nonroot(). Its contents are
- ** now stored either on real database pages or within the
- ** new pSpace buffer, so it may be safely freed here. */
- sqlite3PageFree(pFree);
- }
-
- /* The pSpace buffer will be freed after the next call to
- ** balance_nonroot(), or just before this function returns, whichever
- ** comes first. */
- pFree = pSpace;
- }
- }
-
- pPage->nOverflow = 0;
-
- /* The next iteration of the do-loop balances the parent page. */
- releasePage(pPage);
- pCur->iPage--;
- }
- }while( rc==SQLITE_OK );
-
- if( pFree ){
- sqlite3PageFree(pFree);
- }
- return rc;
-}
-
-
-/*
-** Insert a new record into the BTree. The key is given by (pKey,nKey)
-** and the data is given by (pData,nData). The cursor is used only to
-** define what table the record should be inserted into. The cursor
-** is left pointing at a random location.
-**
-** For an INTKEY table, only the nKey value of the key is used. pKey is
-** ignored. For a ZERODATA table, the pData and nData are both ignored.
-**
-** If the seekResult parameter is non-zero, then a successful call to
-** MovetoUnpacked() to seek cursor pCur to (pKey, nKey) has already
-** been performed. seekResult is the search result returned (a negative
-** number if pCur points at an entry that is smaller than (pKey, nKey), or
-** a positive value if pCur points at an etry that is larger than
-** (pKey, nKey)).
-**
-** If the seekResult parameter is non-zero, then the caller guarantees that
-** cursor pCur is pointing at the existing copy of a row that is to be
-** overwritten. If the seekResult parameter is 0, then cursor pCur may
-** point to any entry or to no entry at all and so this function has to seek
-** the cursor before the new key can be inserted.
-*/
-SQLITE_PRIVATE int sqlite3BtreeInsert(
- BtCursor *pCur, /* Insert data into the table of this cursor */
- const void *pKey, i64 nKey, /* The key of the new record */
- const void *pData, int nData, /* The data of the new record */
- int nZero, /* Number of extra 0 bytes to append to data */
- int appendBias, /* True if this is likely an append */
- int seekResult /* Result of prior MovetoUnpacked() call */
-){
- int rc;
- int loc = seekResult; /* -1: before desired location +1: after */
- int szNew;
- int idx;
- MemPage *pPage;
- Btree *p = pCur->pBtree;
- BtShared *pBt = p->pBt;
- unsigned char *oldCell;
- unsigned char *newCell = 0;
-
- if( pCur->eState==CURSOR_FAULT ){
- assert( pCur->skipNext!=SQLITE_OK );
- return pCur->skipNext;
- }
-
- assert( cursorHoldsMutex(pCur) );
- assert( pCur->wrFlag && pBt->inTransaction==TRANS_WRITE && !pBt->readOnly );
- assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) );
-
- /* Assert that the caller has been consistent. If this cursor was opened
- ** expecting an index b-tree, then the caller should be inserting blob
- ** keys with no associated data. If the cursor was opened expecting an
- ** intkey table, the caller should be inserting integer keys with a
- ** blob of associated data. */
- assert( (pKey==0)==(pCur->pKeyInfo==0) );
-
- /* If this is an insert into a table b-tree, invalidate any incrblob
- ** cursors open on the row being replaced (assuming this is a replace
- ** operation - if it is not, the following is a no-op). */
- if( pCur->pKeyInfo==0 ){
- invalidateIncrblobCursors(p, nKey, 0);
- }
-
- /* Save the positions of any other cursors open on this table.
- **
- ** In some cases, the call to btreeMoveto() below is a no-op. For
- ** example, when inserting data into a table with auto-generated integer
- ** keys, the VDBE layer invokes sqlite3BtreeLast() to figure out the
- ** integer key to use. It then calls this function to actually insert the
- ** data into the intkey B-Tree. In this case btreeMoveto() recognizes
- ** that the cursor is already where it needs to be and returns without
- ** doing any work. To avoid thwarting these optimizations, it is important
- ** not to clear the cursor here.
- */
- rc = saveAllCursors(pBt, pCur->pgnoRoot, pCur);
- if( rc ) return rc;
- if( !loc ){
- rc = btreeMoveto(pCur, pKey, nKey, appendBias, &loc);
- if( rc ) return rc;
- }
- assert( pCur->eState==CURSOR_VALID || (pCur->eState==CURSOR_INVALID && loc) );
-
- pPage = pCur->apPage[pCur->iPage];
- assert( pPage->intKey || nKey>=0 );
- assert( pPage->leaf || !pPage->intKey );
-
- TRACE(("INSERT: table=%d nkey=%lld ndata=%d page=%d %s\n",
- pCur->pgnoRoot, nKey, nData, pPage->pgno,
- loc==0 ? "overwrite" : "new entry"));
- assert( pPage->isInit );
- allocateTempSpace(pBt);
- newCell = pBt->pTmpSpace;
- if( newCell==0 ) return SQLITE_NOMEM;
- rc = fillInCell(pPage, newCell, pKey, nKey, pData, nData, nZero, &szNew);
- if( rc ) goto end_insert;
- assert( szNew==cellSizePtr(pPage, newCell) );
- assert( szNew<=MX_CELL_SIZE(pBt) );
- idx = pCur->aiIdx[pCur->iPage];
- if( loc==0 ){
- u16 szOld;
- assert( idx<pPage->nCell );
- rc = sqlite3PagerWrite(pPage->pDbPage);
- if( rc ){
- goto end_insert;
- }
- oldCell = findCell(pPage, idx);
- if( !pPage->leaf ){
- memcpy(newCell, oldCell, 4);
- }
- szOld = cellSizePtr(pPage, oldCell);
- rc = clearCell(pPage, oldCell);
- dropCell(pPage, idx, szOld, &rc);
- if( rc ) goto end_insert;
- }else if( loc<0 && pPage->nCell>0 ){
- assert( pPage->leaf );
- idx = ++pCur->aiIdx[pCur->iPage];
- }else{
- assert( pPage->leaf );
- }
- insertCell(pPage, idx, newCell, szNew, 0, 0, &rc);
- assert( rc!=SQLITE_OK || pPage->nCell>0 || pPage->nOverflow>0 );
-
- /* If no error has occured and pPage has an overflow cell, call balance()
- ** to redistribute the cells within the tree. Since balance() may move
- ** the cursor, zero the BtCursor.info.nSize and BtCursor.validNKey
- ** variables.
- **
- ** Previous versions of SQLite called moveToRoot() to move the cursor
- ** back to the root page as balance() used to invalidate the contents
- ** of BtCursor.apPage[] and BtCursor.aiIdx[]. Instead of doing that,
- ** set the cursor state to "invalid". This makes common insert operations
- ** slightly faster.
- **
- ** There is a subtle but important optimization here too. When inserting
- ** multiple records into an intkey b-tree using a single cursor (as can
- ** happen while processing an "INSERT INTO ... SELECT" statement), it
- ** is advantageous to leave the cursor pointing to the last entry in
- ** the b-tree if possible. If the cursor is left pointing to the last
- ** entry in the table, and the next row inserted has an integer key
- ** larger than the largest existing key, it is possible to insert the
- ** row without seeking the cursor. This can be a big performance boost.
- */
- pCur->info.nSize = 0;
- pCur->validNKey = 0;
- if( rc==SQLITE_OK && pPage->nOverflow ){
- rc = balance(pCur);
-
- /* Must make sure nOverflow is reset to zero even if the balance()
- ** fails. Internal data structure corruption will result otherwise.
- ** Also, set the cursor state to invalid. This stops saveCursorPosition()
- ** from trying to save the current position of the cursor. */
- pCur->apPage[pCur->iPage]->nOverflow = 0;
- pCur->eState = CURSOR_INVALID;
- }
- assert( pCur->apPage[pCur->iPage]->nOverflow==0 );
-
-end_insert:
- return rc;
-}
-
-/*
-** Delete the entry that the cursor is pointing to. The cursor
-** is left pointing at a arbitrary location.
-*/
-SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur){
- Btree *p = pCur->pBtree;
- BtShared *pBt = p->pBt;
- int rc; /* Return code */
- MemPage *pPage; /* Page to delete cell from */
- unsigned char *pCell; /* Pointer to cell to delete */
- int iCellIdx; /* Index of cell to delete */
- int iCellDepth; /* Depth of node containing pCell */
-
- assert( cursorHoldsMutex(pCur) );
- assert( pBt->inTransaction==TRANS_WRITE );
- assert( !pBt->readOnly );
- assert( pCur->wrFlag );
- assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) );
- assert( !hasReadConflicts(p, pCur->pgnoRoot) );
-
- if( NEVER(pCur->aiIdx[pCur->iPage]>=pCur->apPage[pCur->iPage]->nCell)
- || NEVER(pCur->eState!=CURSOR_VALID)
- ){
- return SQLITE_ERROR; /* Something has gone awry. */
- }
-
- /* If this is a delete operation to remove a row from a table b-tree,
- ** invalidate any incrblob cursors open on the row being deleted. */
- if( pCur->pKeyInfo==0 ){
- invalidateIncrblobCursors(p, pCur->info.nKey, 0);
- }
-
- iCellDepth = pCur->iPage;
- iCellIdx = pCur->aiIdx[iCellDepth];
- pPage = pCur->apPage[iCellDepth];
- pCell = findCell(pPage, iCellIdx);
-
- /* If the page containing the entry to delete is not a leaf page, move
- ** the cursor to the largest entry in the tree that is smaller than
- ** the entry being deleted. This cell will replace the cell being deleted
- ** from the internal node. The 'previous' entry is used for this instead
- ** of the 'next' entry, as the previous entry is always a part of the
- ** sub-tree headed by the child page of the cell being deleted. This makes
- ** balancing the tree following the delete operation easier. */
- if( !pPage->leaf ){
- int notUsed;
- rc = sqlite3BtreePrevious(pCur, &notUsed);
- if( rc ) return rc;
- }
-
- /* Save the positions of any other cursors open on this table before
- ** making any modifications. Make the page containing the entry to be
- ** deleted writable. Then free any overflow pages associated with the
- ** entry and finally remove the cell itself from within the page.
- */
- rc = saveAllCursors(pBt, pCur->pgnoRoot, pCur);
- if( rc ) return rc;
- rc = sqlite3PagerWrite(pPage->pDbPage);
- if( rc ) return rc;
- rc = clearCell(pPage, pCell);
- dropCell(pPage, iCellIdx, cellSizePtr(pPage, pCell), &rc);
- if( rc ) return rc;
-
- /* If the cell deleted was not located on a leaf page, then the cursor
- ** is currently pointing to the largest entry in the sub-tree headed
- ** by the child-page of the cell that was just deleted from an internal
- ** node. The cell from the leaf node needs to be moved to the internal
- ** node to replace the deleted cell. */
- if( !pPage->leaf ){
- MemPage *pLeaf = pCur->apPage[pCur->iPage];
- int nCell;
- Pgno n = pCur->apPage[iCellDepth+1]->pgno;
- unsigned char *pTmp;
-
- pCell = findCell(pLeaf, pLeaf->nCell-1);
- nCell = cellSizePtr(pLeaf, pCell);
- assert( MX_CELL_SIZE(pBt)>=nCell );
-
- allocateTempSpace(pBt);
- pTmp = pBt->pTmpSpace;
-
- rc = sqlite3PagerWrite(pLeaf->pDbPage);
- insertCell(pPage, iCellIdx, pCell-4, nCell+4, pTmp, n, &rc);
- dropCell(pLeaf, pLeaf->nCell-1, nCell, &rc);
- if( rc ) return rc;
- }
-
- /* Balance the tree. If the entry deleted was located on a leaf page,
- ** then the cursor still points to that page. In this case the first
- ** call to balance() repairs the tree, and the if(...) condition is
- ** never true.
- **
- ** Otherwise, if the entry deleted was on an internal node page, then
- ** pCur is pointing to the leaf page from which a cell was removed to
- ** replace the cell deleted from the internal node. This is slightly
- ** tricky as the leaf node may be underfull, and the internal node may
- ** be either under or overfull. In this case run the balancing algorithm
- ** on the leaf node first. If the balance proceeds far enough up the
- ** tree that we can be sure that any problem in the internal node has
- ** been corrected, so be it. Otherwise, after balancing the leaf node,
- ** walk the cursor up the tree to the internal node and balance it as
- ** well. */
- rc = balance(pCur);
- if( rc==SQLITE_OK && pCur->iPage>iCellDepth ){
- while( pCur->iPage>iCellDepth ){
- releasePage(pCur->apPage[pCur->iPage--]);
- }
- rc = balance(pCur);
- }
-
- if( rc==SQLITE_OK ){
- moveToRoot(pCur);
- }
- return rc;
-}
-
-/*
-** Create a new BTree table. Write into *piTable the page
-** number for the root page of the new table.
-**
-** The type of type is determined by the flags parameter. Only the
-** following values of flags are currently in use. Other values for
-** flags might not work:
-**
-** BTREE_INTKEY|BTREE_LEAFDATA Used for SQL tables with rowid keys
-** BTREE_ZERODATA Used for SQL indices
-*/
-static int btreeCreateTable(Btree *p, int *piTable, int flags){
- BtShared *pBt = p->pBt;
- MemPage *pRoot;
- Pgno pgnoRoot;
- int rc;
-
- assert( sqlite3BtreeHoldsMutex(p) );
- assert( pBt->inTransaction==TRANS_WRITE );
- assert( !pBt->readOnly );
-
-#ifdef SQLITE_OMIT_AUTOVACUUM
- rc = allocateBtreePage(pBt, &pRoot, &pgnoRoot, 1, 0);
- if( rc ){
- return rc;
- }
-#else
- if( pBt->autoVacuum ){
- Pgno pgnoMove; /* Move a page here to make room for the root-page */
- MemPage *pPageMove; /* The page to move to. */
-
- /* Creating a new table may probably require moving an existing database
- ** to make room for the new tables root page. In case this page turns
- ** out to be an overflow page, delete all overflow page-map caches
- ** held by open cursors.
- */
- invalidateAllOverflowCache(pBt);
-
- /* Read the value of meta[3] from the database to determine where the
- ** root page of the new table should go. meta[3] is the largest root-page
- ** created so far, so the new root-page is (meta[3]+1).
- */
- sqlite3BtreeGetMeta(p, BTREE_LARGEST_ROOT_PAGE, &pgnoRoot);
- pgnoRoot++;
-
- /* The new root-page may not be allocated on a pointer-map page, or the
- ** PENDING_BYTE page.
- */
- while( pgnoRoot==PTRMAP_PAGENO(pBt, pgnoRoot) ||
- pgnoRoot==PENDING_BYTE_PAGE(pBt) ){
- pgnoRoot++;
- }
- assert( pgnoRoot>=3 );
-
- /* Allocate a page. The page that currently resides at pgnoRoot will
- ** be moved to the allocated page (unless the allocated page happens
- ** to reside at pgnoRoot).
- */
- rc = allocateBtreePage(pBt, &pPageMove, &pgnoMove, pgnoRoot, 1);
- if( rc!=SQLITE_OK ){
- return rc;
- }
-
- if( pgnoMove!=pgnoRoot ){
- /* pgnoRoot is the page that will be used for the root-page of
- ** the new table (assuming an error did not occur). But we were
- ** allocated pgnoMove. If required (i.e. if it was not allocated
- ** by extending the file), the current page at position pgnoMove
- ** is already journaled.
- */
- u8 eType = 0;
- Pgno iPtrPage = 0;
-
- releasePage(pPageMove);
-
- /* Move the page currently at pgnoRoot to pgnoMove. */
- rc = btreeGetPage(pBt, pgnoRoot, &pRoot, 0);
- if( rc!=SQLITE_OK ){
- return rc;
- }
- rc = ptrmapGet(pBt, pgnoRoot, &eType, &iPtrPage);
- if( eType==PTRMAP_ROOTPAGE || eType==PTRMAP_FREEPAGE ){
- rc = SQLITE_CORRUPT_BKPT;
- }
- if( rc!=SQLITE_OK ){
- releasePage(pRoot);
- return rc;
- }
- assert( eType!=PTRMAP_ROOTPAGE );
- assert( eType!=PTRMAP_FREEPAGE );
- rc = relocatePage(pBt, pRoot, eType, iPtrPage, pgnoMove, 0);
- releasePage(pRoot);
-
- /* Obtain the page at pgnoRoot */
- if( rc!=SQLITE_OK ){
- return rc;
- }
- rc = btreeGetPage(pBt, pgnoRoot, &pRoot, 0);
- if( rc!=SQLITE_OK ){
- return rc;
- }
- rc = sqlite3PagerWrite(pRoot->pDbPage);
- if( rc!=SQLITE_OK ){
- releasePage(pRoot);
- return rc;
- }
- }else{
- pRoot = pPageMove;
- }
-
- /* Update the pointer-map and meta-data with the new root-page number. */
- ptrmapPut(pBt, pgnoRoot, PTRMAP_ROOTPAGE, 0, &rc);
- if( rc ){
- releasePage(pRoot);
- return rc;
- }
- rc = sqlite3BtreeUpdateMeta(p, 4, pgnoRoot);
- if( rc ){
- releasePage(pRoot);
- return rc;
- }
-
- }else{
- rc = allocateBtreePage(pBt, &pRoot, &pgnoRoot, 1, 0);
- if( rc ) return rc;
- }
-#endif
- assert( sqlite3PagerIswriteable(pRoot->pDbPage) );
- zeroPage(pRoot, flags | PTF_LEAF);
- sqlite3PagerUnref(pRoot->pDbPage);
- *piTable = (int)pgnoRoot;
- return SQLITE_OK;
-}
-SQLITE_PRIVATE int sqlite3BtreeCreateTable(Btree *p, int *piTable, int flags){
- int rc;
- sqlite3BtreeEnter(p);
- rc = btreeCreateTable(p, piTable, flags);
- sqlite3BtreeLeave(p);
- return rc;
-}
-
-/*
-** Erase the given database page and all its children. Return
-** the page to the freelist.
-*/
-static int clearDatabasePage(
- BtShared *pBt, /* The BTree that contains the table */
- Pgno pgno, /* Page number to clear */
- int freePageFlag, /* Deallocate page if true */
- int *pnChange
-){
- MemPage *pPage;
- int rc;
- unsigned char *pCell;
- int i;
-
- assert( sqlite3_mutex_held(pBt->mutex) );
- if( pgno>pagerPagecount(pBt) ){
- return SQLITE_CORRUPT_BKPT;
- }
-
- rc = getAndInitPage(pBt, pgno, &pPage);
- if( rc ) return rc;
- for(i=0; i<pPage->nCell; i++){
- pCell = findCell(pPage, i);
- if( !pPage->leaf ){
- rc = clearDatabasePage(pBt, get4byte(pCell), 1, pnChange);
- if( rc ) goto cleardatabasepage_out;
- }
- rc = clearCell(pPage, pCell);
- if( rc ) goto cleardatabasepage_out;
- }
- if( !pPage->leaf ){
- rc = clearDatabasePage(pBt, get4byte(&pPage->aData[8]), 1, pnChange);
- if( rc ) goto cleardatabasepage_out;
- }else if( pnChange ){
- assert( pPage->intKey );
- *pnChange += pPage->nCell;
- }
- if( freePageFlag ){
- freePage(pPage, &rc);
- }else if( (rc = sqlite3PagerWrite(pPage->pDbPage))==0 ){
- zeroPage(pPage, pPage->aData[0] | PTF_LEAF);
- }
-
-cleardatabasepage_out:
- releasePage(pPage);
- return rc;
-}
-
-/*
-** Delete all information from a single table in the database. iTable is
-** the page number of the root of the table. After this routine returns,
-** the root page is empty, but still exists.
-**
-** This routine will fail with SQLITE_LOCKED if there are any open
-** read cursors on the table. Open write cursors are moved to the
-** root of the table.
-**
-** If pnChange is not NULL, then table iTable must be an intkey table. The
-** integer value pointed to by pnChange is incremented by the number of
-** entries in the table.
-*/
-SQLITE_PRIVATE int sqlite3BtreeClearTable(Btree *p, int iTable, int *pnChange){
- int rc;
- BtShared *pBt = p->pBt;
- sqlite3BtreeEnter(p);
- assert( p->inTrans==TRANS_WRITE );
-
- /* Invalidate all incrblob cursors open on table iTable (assuming iTable
- ** is the root of a table b-tree - if it is not, the following call is
- ** a no-op). */
- invalidateIncrblobCursors(p, 0, 1);
-
- rc = saveAllCursors(pBt, (Pgno)iTable, 0);
- if( SQLITE_OK==rc ){
- rc = clearDatabasePage(pBt, (Pgno)iTable, 0, pnChange);
- }
- sqlite3BtreeLeave(p);
- return rc;
-}
-
-/*
-** Erase all information in a table and add the root of the table to
-** the freelist. Except, the root of the principle table (the one on
-** page 1) is never added to the freelist.
-**
-** This routine will fail with SQLITE_LOCKED if there are any open
-** cursors on the table.
-**
-** If AUTOVACUUM is enabled and the page at iTable is not the last
-** root page in the database file, then the last root page
-** in the database file is moved into the slot formerly occupied by
-** iTable and that last slot formerly occupied by the last root page
-** is added to the freelist instead of iTable. In this say, all
-** root pages are kept at the beginning of the database file, which
-** is necessary for AUTOVACUUM to work right. *piMoved is set to the
-** page number that used to be the last root page in the file before
-** the move. If no page gets moved, *piMoved is set to 0.
-** The last root page is recorded in meta[3] and the value of
-** meta[3] is updated by this procedure.
-*/
-static int btreeDropTable(Btree *p, Pgno iTable, int *piMoved){
- int rc;
- MemPage *pPage = 0;
- BtShared *pBt = p->pBt;
-
- assert( sqlite3BtreeHoldsMutex(p) );
- assert( p->inTrans==TRANS_WRITE );
-
- /* It is illegal to drop a table if any cursors are open on the
- ** database. This is because in auto-vacuum mode the backend may
- ** need to move another root-page to fill a gap left by the deleted
- ** root page. If an open cursor was using this page a problem would
- ** occur.
- **
- ** This error is caught long before control reaches this point.
- */
- if( NEVER(pBt->pCursor) ){
- sqlite3ConnectionBlocked(p->db, pBt->pCursor->pBtree->db);
- return SQLITE_LOCKED_SHAREDCACHE;
- }
-
- rc = btreeGetPage(pBt, (Pgno)iTable, &pPage, 0);
- if( rc ) return rc;
- rc = sqlite3BtreeClearTable(p, iTable, 0);
- if( rc ){
- releasePage(pPage);
- return rc;
- }
-
- *piMoved = 0;
-
- if( iTable>1 ){
-#ifdef SQLITE_OMIT_AUTOVACUUM
- freePage(pPage, &rc);
- releasePage(pPage);
-#else
- if( pBt->autoVacuum ){
- Pgno maxRootPgno;
- sqlite3BtreeGetMeta(p, BTREE_LARGEST_ROOT_PAGE, &maxRootPgno);
-
- if( iTable==maxRootPgno ){
- /* If the table being dropped is the table with the largest root-page
- ** number in the database, put the root page on the free list.
- */
- freePage(pPage, &rc);
- releasePage(pPage);
- if( rc!=SQLITE_OK ){
- return rc;
- }
- }else{
- /* The table being dropped does not have the largest root-page
- ** number in the database. So move the page that does into the
- ** gap left by the deleted root-page.
- */
- MemPage *pMove;
- releasePage(pPage);
- rc = btreeGetPage(pBt, maxRootPgno, &pMove, 0);
- if( rc!=SQLITE_OK ){
- return rc;
- }
- rc = relocatePage(pBt, pMove, PTRMAP_ROOTPAGE, 0, iTable, 0);
- releasePage(pMove);
- if( rc!=SQLITE_OK ){
- return rc;
- }
- pMove = 0;
- rc = btreeGetPage(pBt, maxRootPgno, &pMove, 0);
- freePage(pMove, &rc);
- releasePage(pMove);
- if( rc!=SQLITE_OK ){
- return rc;
- }
- *piMoved = maxRootPgno;
- }
-
- /* Set the new 'max-root-page' value in the database header. This
- ** is the old value less one, less one more if that happens to
- ** be a root-page number, less one again if that is the
- ** PENDING_BYTE_PAGE.
- */
- maxRootPgno--;
- while( maxRootPgno==PENDING_BYTE_PAGE(pBt)
- || PTRMAP_ISPAGE(pBt, maxRootPgno) ){
- maxRootPgno--;
- }
- assert( maxRootPgno!=PENDING_BYTE_PAGE(pBt) );
-
- rc = sqlite3BtreeUpdateMeta(p, 4, maxRootPgno);
- }else{
- freePage(pPage, &rc);
- releasePage(pPage);
- }
-#endif
- }else{
- /* If sqlite3BtreeDropTable was called on page 1.
- ** This really never should happen except in a corrupt
- ** database.
- */
- zeroPage(pPage, PTF_INTKEY|PTF_LEAF );
- releasePage(pPage);
- }
- return rc;
-}
-SQLITE_PRIVATE int sqlite3BtreeDropTable(Btree *p, int iTable, int *piMoved){
- int rc;
- sqlite3BtreeEnter(p);
- rc = btreeDropTable(p, iTable, piMoved);
- sqlite3BtreeLeave(p);
- return rc;
-}
-
-
-/*
-** This function may only be called if the b-tree connection already
-** has a read or write transaction open on the database.
-**
-** Read the meta-information out of a database file. Meta[0]
-** is the number of free pages currently in the database. Meta[1]
-** through meta[15] are available for use by higher layers. Meta[0]
-** is read-only, the others are read/write.
-**
-** The schema layer numbers meta values differently. At the schema
-** layer (and the SetCookie and ReadCookie opcodes) the number of
-** free pages is not visible. So Cookie[0] is the same as Meta[1].
-*/
-SQLITE_PRIVATE void sqlite3BtreeGetMeta(Btree *p, int idx, u32 *pMeta){
- BtShared *pBt = p->pBt;
-
- sqlite3BtreeEnter(p);
- assert( p->inTrans>TRANS_NONE );
- assert( SQLITE_OK==querySharedCacheTableLock(p, MASTER_ROOT, READ_LOCK) );
- assert( pBt->pPage1 );
- assert( idx>=0 && idx<=15 );
-
- *pMeta = get4byte(&pBt->pPage1->aData[36 + idx*4]);
-
- /* 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;
-#endif
-
- sqlite3BtreeLeave(p);
-}
-
-/*
-** Write meta-information back into the database. Meta[0] is
-** read-only and may not be written.
-*/
-SQLITE_PRIVATE int sqlite3BtreeUpdateMeta(Btree *p, int idx, u32 iMeta){
- BtShared *pBt = p->pBt;
- unsigned char *pP1;
- int rc;
- assert( idx>=1 && idx<=15 );
- sqlite3BtreeEnter(p);
- assert( p->inTrans==TRANS_WRITE );
- assert( pBt->pPage1!=0 );
- pP1 = pBt->pPage1->aData;
- rc = sqlite3PagerWrite(pBt->pPage1->pDbPage);
- if( rc==SQLITE_OK ){
- put4byte(&pP1[36 + idx*4], iMeta);
-#ifndef SQLITE_OMIT_AUTOVACUUM
- if( idx==BTREE_INCR_VACUUM ){
- assert( pBt->autoVacuum || iMeta==0 );
- assert( iMeta==0 || iMeta==1 );
- pBt->incrVacuum = (u8)iMeta;
- }
-#endif
- }
- sqlite3BtreeLeave(p);
- return rc;
-}
-
-#ifndef SQLITE_OMIT_BTREECOUNT
-/*
-** The first argument, pCur, is a cursor opened on some b-tree. Count the
-** number of entries in the b-tree and write the result to *pnEntry.
-**
-** SQLITE_OK is returned if the operation is successfully executed.
-** Otherwise, if an error is encountered (i.e. an IO error or database
-** corruption) an SQLite error code is returned.
-*/
-SQLITE_PRIVATE int sqlite3BtreeCount(BtCursor *pCur, i64 *pnEntry){
- i64 nEntry = 0; /* Value to return in *pnEntry */
- int rc; /* Return code */
- rc = moveToRoot(pCur);
-
- /* Unless an error occurs, the following loop runs one iteration for each
- ** page in the B-Tree structure (not including overflow pages).
- */
- while( rc==SQLITE_OK ){
- int iIdx; /* Index of child node in parent */
- MemPage *pPage; /* Current page of the b-tree */
-
- /* If this is a leaf page or the tree is not an int-key tree, then
- ** this page contains countable entries. Increment the entry counter
- ** accordingly.
- */
- pPage = pCur->apPage[pCur->iPage];
- if( pPage->leaf || !pPage->intKey ){
- nEntry += pPage->nCell;
- }
-
- /* pPage is a leaf node. This loop navigates the cursor so that it
- ** points to the first interior cell that it points to the parent of
- ** the next page in the tree that has not yet been visited. The
- ** pCur->aiIdx[pCur->iPage] value is set to the index of the parent cell
- ** of the page, or to the number of cells in the page if the next page
- ** to visit is the right-child of its parent.
- **
- ** If all pages in the tree have been visited, return SQLITE_OK to the
- ** caller.
- */
- if( pPage->leaf ){
- do {
- if( pCur->iPage==0 ){
- /* All pages of the b-tree have been visited. Return successfully. */
- *pnEntry = nEntry;
- return SQLITE_OK;
- }
- moveToParent(pCur);
- }while ( pCur->aiIdx[pCur->iPage]>=pCur->apPage[pCur->iPage]->nCell );
-
- pCur->aiIdx[pCur->iPage]++;
- pPage = pCur->apPage[pCur->iPage];
- }
-
- /* Descend to the child node of the cell that the cursor currently
- ** points at. This is the right-child if (iIdx==pPage->nCell).
- */
- iIdx = pCur->aiIdx[pCur->iPage];
- if( iIdx==pPage->nCell ){
- rc = moveToChild(pCur, get4byte(&pPage->aData[pPage->hdrOffset+8]));
- }else{
- rc = moveToChild(pCur, get4byte(findCell(pPage, iIdx)));
- }
- }
-
- /* An error has occurred. Return an error code. */
- return rc;
-}
-#endif
-
-/*
-** Return the pager associated with a BTree. This routine is used for
-** testing and debugging only.
-*/
-SQLITE_PRIVATE Pager *sqlite3BtreePager(Btree *p){
- return p->pBt->pPager;
-}
-
-#ifndef SQLITE_OMIT_INTEGRITY_CHECK
-/*
-** Append a message to the error message string.
-*/
-static void checkAppendMsg(
- IntegrityCk *pCheck,
- char *zMsg1,
- const char *zFormat,
- ...
-){
- va_list ap;
- if( !pCheck->mxErr ) return;
- pCheck->mxErr--;
- pCheck->nErr++;
- va_start(ap, zFormat);
- if( pCheck->errMsg.nChar ){
- sqlite3StrAccumAppend(&pCheck->errMsg, "\n", 1);
- }
- if( zMsg1 ){
- sqlite3StrAccumAppend(&pCheck->errMsg, zMsg1, -1);
- }
- sqlite3VXPrintf(&pCheck->errMsg, 1, zFormat, ap);
- va_end(ap);
- if( pCheck->errMsg.mallocFailed ){
- pCheck->mallocFailed = 1;
- }
-}
-#endif /* SQLITE_OMIT_INTEGRITY_CHECK */
-
-#ifndef SQLITE_OMIT_INTEGRITY_CHECK
-/*
-** Add 1 to the reference count for page iPage. If this is the second
-** reference to the page, add an error message to pCheck->zErrMsg.
-** Return 1 if there are 2 ore more references to the page and 0 if
-** if this is the first reference to the page.
-**
-** Also check that the page number is in bounds.
-*/
-static int checkRef(IntegrityCk *pCheck, Pgno iPage, char *zContext){
- if( iPage==0 ) return 1;
- if( iPage>pCheck->nPage ){
- checkAppendMsg(pCheck, zContext, "invalid page number %d", iPage);
- return 1;
- }
- if( pCheck->anRef[iPage]==1 ){
- checkAppendMsg(pCheck, zContext, "2nd reference to page %d", iPage);
- return 1;
- }
- return (pCheck->anRef[iPage]++)>1;
-}
-
-#ifndef SQLITE_OMIT_AUTOVACUUM
-/*
-** Check that the entry in the pointer-map for page iChild maps to
-** page iParent, pointer type ptrType. If not, append an error message
-** to pCheck.
-*/
-static void checkPtrmap(
- IntegrityCk *pCheck, /* Integrity check context */
- Pgno iChild, /* Child page number */
- u8 eType, /* Expected pointer map type */
- Pgno iParent, /* Expected pointer map parent page number */
- char *zContext /* Context description (used for error msg) */
-){
- int rc;
- u8 ePtrmapType;
- Pgno iPtrmapParent;
-
- rc = ptrmapGet(pCheck->pBt, iChild, &ePtrmapType, &iPtrmapParent);
- if( rc!=SQLITE_OK ){
- if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ) pCheck->mallocFailed = 1;
- checkAppendMsg(pCheck, zContext, "Failed to read ptrmap key=%d", iChild);
- return;
- }
-
- if( ePtrmapType!=eType || iPtrmapParent!=iParent ){
- checkAppendMsg(pCheck, zContext,
- "Bad ptr map entry key=%d expected=(%d,%d) got=(%d,%d)",
- iChild, eType, iParent, ePtrmapType, iPtrmapParent);
- }
-}
-#endif
-
-/*
-** Check the integrity of the freelist or of an overflow page list.
-** Verify that the number of pages on the list is N.
-*/
-static void checkList(
- IntegrityCk *pCheck, /* Integrity checking context */
- int isFreeList, /* True for a freelist. False for overflow page list */
- int iPage, /* Page number for first page in the list */
- int N, /* Expected number of pages in the list */
- char *zContext /* Context for error messages */
-){
- int i;
- int expected = N;
- int iFirst = iPage;
- while( N-- > 0 && pCheck->mxErr ){
- DbPage *pOvflPage;
- unsigned char *pOvflData;
- if( iPage<1 ){
- checkAppendMsg(pCheck, zContext,
- "%d of %d pages missing from overflow list starting at %d",
- N+1, expected, iFirst);
- break;
- }
- if( checkRef(pCheck, iPage, zContext) ) break;
- if( sqlite3PagerGet(pCheck->pPager, (Pgno)iPage, &pOvflPage) ){
- checkAppendMsg(pCheck, zContext, "failed to get page %d", iPage);
- break;
- }
- pOvflData = (unsigned char *)sqlite3PagerGetData(pOvflPage);
- if( isFreeList ){
- int n = get4byte(&pOvflData[4]);
-#ifndef SQLITE_OMIT_AUTOVACUUM
- if( pCheck->pBt->autoVacuum ){
- checkPtrmap(pCheck, iPage, PTRMAP_FREEPAGE, 0, zContext);
- }
-#endif
- if( n>pCheck->pBt->usableSize/4-2 ){
- checkAppendMsg(pCheck, zContext,
- "freelist leaf count too big on page %d", iPage);
- N--;
- }else{
- for(i=0; i<n; i++){
- Pgno iFreePage = get4byte(&pOvflData[8+i*4]);
-#ifndef SQLITE_OMIT_AUTOVACUUM
- if( pCheck->pBt->autoVacuum ){
- checkPtrmap(pCheck, iFreePage, PTRMAP_FREEPAGE, 0, zContext);
- }
-#endif
- checkRef(pCheck, iFreePage, zContext);
- }
- N -= n;
- }
- }
-#ifndef SQLITE_OMIT_AUTOVACUUM
- else{
- /* If this database supports auto-vacuum and iPage is not the last
- ** page in this overflow list, check that the pointer-map entry for
- ** the following page matches iPage.
- */
- if( pCheck->pBt->autoVacuum && N>0 ){
- i = get4byte(pOvflData);
- checkPtrmap(pCheck, i, PTRMAP_OVERFLOW2, iPage, zContext);
- }
- }
-#endif
- iPage = get4byte(pOvflData);
- sqlite3PagerUnref(pOvflPage);
- }
-}
-#endif /* SQLITE_OMIT_INTEGRITY_CHECK */
-
-#ifndef SQLITE_OMIT_INTEGRITY_CHECK
-/*
-** Do various sanity checks on a single page of a tree. Return
-** the tree depth. Root pages return 0. Parents of root pages
-** return 1, and so forth.
-**
-** These checks are done:
-**
-** 1. Make sure that cells and freeblocks do not overlap
-** but combine to completely cover the page.
-** NO 2. Make sure cell keys are in order.
-** NO 3. Make sure no key is less than or equal to zLowerBound.
-** NO 4. Make sure no key is greater than or equal to zUpperBound.
-** 5. Check the integrity of overflow pages.
-** 6. Recursively call checkTreePage on all children.
-** 7. Verify that the depth of all children is the same.
-** 8. Make sure this page is at least 33% full or else it is
-** the root of the tree.
-*/
-static int checkTreePage(
- IntegrityCk *pCheck, /* Context for the sanity check */
- int iPage, /* Page number of the page to check */
- char *zParentContext /* Parent context */
-){
- MemPage *pPage;
- int i, rc, depth, d2, pgno, cnt;
- int hdr, cellStart;
- int nCell;
- u8 *data;
- BtShared *pBt;
- int usableSize;
- char zContext[100];
- char *hit = 0;
-
- sqlite3_snprintf(sizeof(zContext), zContext, "Page %d: ", iPage);
-
- /* Check that the page exists
- */
- pBt = pCheck->pBt;
- usableSize = pBt->usableSize;
- if( iPage==0 ) return 0;
- if( checkRef(pCheck, iPage, zParentContext) ) return 0;
- if( (rc = btreeGetPage(pBt, (Pgno)iPage, &pPage, 0))!=0 ){
- checkAppendMsg(pCheck, zContext,
- "unable to get the page. error code=%d", rc);
- return 0;
- }
-
- /* Clear MemPage.isInit to make sure the corruption detection code in
- ** btreeInitPage() is executed. */
- pPage->isInit = 0;
- if( (rc = btreeInitPage(pPage))!=0 ){
- assert( rc==SQLITE_CORRUPT ); /* The only possible error from InitPage */
- checkAppendMsg(pCheck, zContext,
- "btreeInitPage() returns error code %d", rc);
- releasePage(pPage);
- return 0;
- }
-
- /* Check out all the cells.
- */
- depth = 0;
- for(i=0; i<pPage->nCell && pCheck->mxErr; i++){
- u8 *pCell;
- u32 sz;
- CellInfo info;
-
- /* Check payload overflow pages
- */
- sqlite3_snprintf(sizeof(zContext), zContext,
- "On tree page %d cell %d: ", iPage, i);
- pCell = findCell(pPage,i);
- btreeParseCellPtr(pPage, pCell, &info);
- sz = info.nData;
- if( !pPage->intKey ) sz += (int)info.nKey;
- assert( sz==info.nPayload );
- if( (sz>info.nLocal)
- && (&pCell[info.iOverflow]<=&pPage->aData[pBt->usableSize])
- ){
- int nPage = (sz - info.nLocal + usableSize - 5)/(usableSize - 4);
- Pgno pgnoOvfl = get4byte(&pCell[info.iOverflow]);
-#ifndef SQLITE_OMIT_AUTOVACUUM
- if( pBt->autoVacuum ){
- checkPtrmap(pCheck, pgnoOvfl, PTRMAP_OVERFLOW1, iPage, zContext);
- }
-#endif
- checkList(pCheck, 0, pgnoOvfl, nPage, zContext);
- }
-
- /* Check sanity of left child page.
- */
- if( !pPage->leaf ){
- pgno = get4byte(pCell);
-#ifndef SQLITE_OMIT_AUTOVACUUM
- if( pBt->autoVacuum ){
- checkPtrmap(pCheck, pgno, PTRMAP_BTREE, iPage, zContext);
- }
-#endif
- d2 = checkTreePage(pCheck, pgno, zContext);
- if( i>0 && d2!=depth ){
- checkAppendMsg(pCheck, zContext, "Child page depth differs");
- }
- depth = d2;
- }
- }
- if( !pPage->leaf ){
- pgno = get4byte(&pPage->aData[pPage->hdrOffset+8]);
- sqlite3_snprintf(sizeof(zContext), zContext,
- "On page %d at right child: ", iPage);
-#ifndef SQLITE_OMIT_AUTOVACUUM
- if( pBt->autoVacuum ){
- checkPtrmap(pCheck, pgno, PTRMAP_BTREE, iPage, 0);
- }
-#endif
- checkTreePage(pCheck, pgno, zContext);
- }
-
- /* Check for complete coverage of the page
- */
- data = pPage->aData;
- hdr = pPage->hdrOffset;
- hit = sqlite3PageMalloc( pBt->pageSize );
- if( hit==0 ){
- pCheck->mallocFailed = 1;
- }else{
- u16 contentOffset = get2byte(&data[hdr+5]);
- assert( contentOffset<=usableSize ); /* Enforced by btreeInitPage() */
- memset(hit+contentOffset, 0, usableSize-contentOffset);
- memset(hit, 1, contentOffset);
- nCell = get2byte(&data[hdr+3]);
- cellStart = hdr + 12 - 4*pPage->leaf;
- for(i=0; i<nCell; i++){
- int pc = get2byte(&data[cellStart+i*2]);
- u16 size = 1024;
- int j;
- if( pc<=usableSize-4 ){
- size = cellSizePtr(pPage, &data[pc]);
- }
- if( (pc+size-1)>=usableSize ){
- checkAppendMsg(pCheck, 0,
- "Corruption detected in cell %d on page %d",i,iPage,0);
- }else{
- for(j=pc+size-1; j>=pc; j--) hit[j]++;
- }
- }
- i = get2byte(&data[hdr+1]);
- while( i>0 ){
- int size, j;
- assert( i<=usableSize-4 ); /* Enforced by btreeInitPage() */
- size = get2byte(&data[i+2]);
- assert( i+size<=usableSize ); /* Enforced by btreeInitPage() */
- for(j=i+size-1; j>=i; j--) hit[j]++;
- j = get2byte(&data[i]);
- assert( j==0 || j>i+size ); /* Enforced by btreeInitPage() */
- assert( j<=usableSize-4 ); /* Enforced by btreeInitPage() */
- i = j;
- }
- for(i=cnt=0; i<usableSize; i++){
- if( hit[i]==0 ){
- cnt++;
- }else if( hit[i]>1 ){
- checkAppendMsg(pCheck, 0,
- "Multiple uses for byte %d of page %d", i, iPage);
- break;
- }
- }
- if( cnt!=data[hdr+7] ){
- checkAppendMsg(pCheck, 0,
- "Fragmentation of %d bytes reported as %d on page %d",
- cnt, data[hdr+7], iPage);
- }
- }
- sqlite3PageFree(hit);
- releasePage(pPage);
- return depth+1;
-}
-#endif /* SQLITE_OMIT_INTEGRITY_CHECK */
-
-#ifndef SQLITE_OMIT_INTEGRITY_CHECK
-/*
-** This routine does a complete check of the given BTree file. aRoot[] is
-** an array of pages numbers were each page number is the root page of
-** a table. nRoot is the number of entries in aRoot.
-**
-** A read-only or read-write transaction must be opened before calling
-** this function.
-**
-** Write the number of error seen in *pnErr. Except for some memory
-** allocation errors, an error message held in memory obtained from
-** malloc is returned if *pnErr is non-zero. If *pnErr==0 then NULL is
-** returned. If a memory allocation error occurs, NULL is returned.
-*/
-SQLITE_PRIVATE char *sqlite3BtreeIntegrityCheck(
- Btree *p, /* The btree to be checked */
- int *aRoot, /* An array of root pages numbers for individual trees */
- int nRoot, /* Number of entries in aRoot[] */
- int mxErr, /* Stop reporting errors after this many */
- int *pnErr /* Write number of errors seen to this variable */
-){
- Pgno i;
- int nRef;
- IntegrityCk sCheck;
- BtShared *pBt = p->pBt;
- char zErr[100];
-
- sqlite3BtreeEnter(p);
- assert( p->inTrans>TRANS_NONE && pBt->inTransaction>TRANS_NONE );
- nRef = sqlite3PagerRefcount(pBt->pPager);
- sCheck.pBt = pBt;
- sCheck.pPager = pBt->pPager;
- sCheck.nPage = pagerPagecount(sCheck.pBt);
- sCheck.mxErr = mxErr;
- sCheck.nErr = 0;
- sCheck.mallocFailed = 0;
- *pnErr = 0;
- if( sCheck.nPage==0 ){
- sqlite3BtreeLeave(p);
- return 0;
- }
- sCheck.anRef = sqlite3Malloc( (sCheck.nPage+1)*sizeof(sCheck.anRef[0]) );
- if( !sCheck.anRef ){
- *pnErr = 1;
- sqlite3BtreeLeave(p);
- return 0;
- }
- for(i=0; i<=sCheck.nPage; i++){ sCheck.anRef[i] = 0; }
- i = PENDING_BYTE_PAGE(pBt);
- if( i<=sCheck.nPage ){
- sCheck.anRef[i] = 1;
- }
- sqlite3StrAccumInit(&sCheck.errMsg, zErr, sizeof(zErr), 20000);
-
- /* Check the integrity of the freelist
- */
- checkList(&sCheck, 1, get4byte(&pBt->pPage1->aData[32]),
- get4byte(&pBt->pPage1->aData[36]), "Main freelist: ");
-
- /* Check all the tables.
- */
- for(i=0; (int)i<nRoot && sCheck.mxErr; i++){
- if( aRoot[i]==0 ) continue;
-#ifndef SQLITE_OMIT_AUTOVACUUM
- if( pBt->autoVacuum && aRoot[i]>1 ){
- checkPtrmap(&sCheck, aRoot[i], PTRMAP_ROOTPAGE, 0, 0);
- }
-#endif
- checkTreePage(&sCheck, aRoot[i], "List of tree roots: ");
- }
-
- /* Make sure every page in the file is referenced
- */
- for(i=1; i<=sCheck.nPage && sCheck.mxErr; i++){
-#ifdef SQLITE_OMIT_AUTOVACUUM
- if( sCheck.anRef[i]==0 ){
- checkAppendMsg(&sCheck, 0, "Page %d is never used", i);
- }
-#else
- /* If the database supports auto-vacuum, make sure no tables contain
- ** references to pointer-map pages.
- */
- if( sCheck.anRef[i]==0 &&
- (PTRMAP_PAGENO(pBt, i)!=i || !pBt->autoVacuum) ){
- checkAppendMsg(&sCheck, 0, "Page %d is never used", i);
- }
- if( sCheck.anRef[i]!=0 &&
- (PTRMAP_PAGENO(pBt, i)==i && pBt->autoVacuum) ){
- checkAppendMsg(&sCheck, 0, "Pointer map page %d is referenced", i);
- }
-#endif
- }
-
- /* Make sure this analysis did not leave any unref() pages.
- ** This is an internal consistency check; an integrity check
- ** of the integrity check.
- */
- if( NEVER(nRef != sqlite3PagerRefcount(pBt->pPager)) ){
- checkAppendMsg(&sCheck, 0,
- "Outstanding page count goes from %d to %d during this analysis",
- nRef, sqlite3PagerRefcount(pBt->pPager)
- );
- }
-
- /* Clean up and report errors.
- */
- sqlite3BtreeLeave(p);
- sqlite3_free(sCheck.anRef);
- if( sCheck.mallocFailed ){
- sqlite3StrAccumReset(&sCheck.errMsg);
- *pnErr = sCheck.nErr+1;
- return 0;
- }
- *pnErr = sCheck.nErr;
- if( sCheck.nErr==0 ) sqlite3StrAccumReset(&sCheck.errMsg);
- return sqlite3StrAccumFinish(&sCheck.errMsg);
-}
-#endif /* SQLITE_OMIT_INTEGRITY_CHECK */
-
-/*
-** Return the full pathname of the underlying database file.
-**
-** The pager filename is invariant as long as the pager is
-** open so it is safe to access without the BtShared mutex.
-*/
-SQLITE_PRIVATE const char *sqlite3BtreeGetFilename(Btree *p){
- assert( p->pBt->pPager!=0 );
- return sqlite3PagerFilename(p->pBt->pPager);
-}
-
-/*
-** Return the pathname of the journal file for this database. The return
-** value of this routine is the same regardless of whether the journal file
-** has been created or not.
-**
-** The pager journal filename is invariant as long as the pager is
-** open so it is safe to access without the BtShared mutex.
-*/
-SQLITE_PRIVATE const char *sqlite3BtreeGetJournalname(Btree *p){
- assert( p->pBt->pPager!=0 );
- return sqlite3PagerJournalname(p->pBt->pPager);
-}
-
-/*
-** Return non-zero if a transaction is active.
-*/
-SQLITE_PRIVATE int sqlite3BtreeIsInTrans(Btree *p){
- assert( p==0 || sqlite3_mutex_held(p->db->mutex) );
- return (p && (p->inTrans==TRANS_WRITE));
-}
-
-/*
-** Return non-zero if a read (or write) transaction is active.
-*/
-SQLITE_PRIVATE int sqlite3BtreeIsInReadTrans(Btree *p){
- assert( p );
- assert( sqlite3_mutex_held(p->db->mutex) );
- return p->inTrans!=TRANS_NONE;
-}
-
-SQLITE_PRIVATE int sqlite3BtreeIsInBackup(Btree *p){
- assert( p );
- assert( sqlite3_mutex_held(p->db->mutex) );
- return p->nBackup!=0;
-}
-
-/*
-** This function returns a pointer to a blob of memory associated with
-** a single shared-btree. The memory is used by client code for its own
-** purposes (for example, to store a high-level schema associated with
-** the shared-btree). The btree layer manages reference counting issues.
-**
-** The first time this is called on a shared-btree, nBytes bytes of memory
-** are allocated, zeroed, and returned to the caller. For each subsequent
-** call the nBytes parameter is ignored and a pointer to the same blob
-** of memory returned.
-**
-** If the nBytes parameter is 0 and the blob of memory has not yet been
-** allocated, a null pointer is returned. If the blob has already been
-** allocated, it is returned as normal.
-**
-** Just before the shared-btree is closed, the function passed as the
-** xFree argument when the memory allocation was made is invoked on the
-** blob of allocated memory. This function should not call sqlite3_free()
-** on the memory, the btree layer does that.
-*/
-SQLITE_PRIVATE void *sqlite3BtreeSchema(Btree *p, int nBytes, void(*xFree)(void *)){
- BtShared *pBt = p->pBt;
- sqlite3BtreeEnter(p);
- if( !pBt->pSchema && nBytes ){
- pBt->pSchema = sqlite3MallocZero(nBytes);
- pBt->xFreeSchema = xFree;
- }
- sqlite3BtreeLeave(p);
- return pBt->pSchema;
-}
-
-/*
-** Return SQLITE_LOCKED_SHAREDCACHE if another user of the same shared
-** btree as the argument handle holds an exclusive lock on the
-** sqlite_master table. Otherwise SQLITE_OK.
-*/
-SQLITE_PRIVATE int sqlite3BtreeSchemaLocked(Btree *p){
- int rc;
- assert( sqlite3_mutex_held(p->db->mutex) );
- sqlite3BtreeEnter(p);
- rc = querySharedCacheTableLock(p, MASTER_ROOT, READ_LOCK);
- assert( rc==SQLITE_OK || rc==SQLITE_LOCKED_SHAREDCACHE );
- sqlite3BtreeLeave(p);
- return rc;
-}
-
-
-#ifndef SQLITE_OMIT_SHARED_CACHE
-/*
-** Obtain a lock on the table whose root page is iTab. The
-** lock is a write lock if isWritelock is true or a read lock
-** if it is false.
-*/
-SQLITE_PRIVATE int sqlite3BtreeLockTable(Btree *p, int iTab, u8 isWriteLock){
- int rc = SQLITE_OK;
- assert( p->inTrans!=TRANS_NONE );
- if( p->sharable ){
- u8 lockType = READ_LOCK + isWriteLock;
- assert( READ_LOCK+1==WRITE_LOCK );
- assert( isWriteLock==0 || isWriteLock==1 );
-
- sqlite3BtreeEnter(p);
- rc = querySharedCacheTableLock(p, iTab, lockType);
- if( rc==SQLITE_OK ){
- rc = setSharedCacheTableLock(p, iTab, lockType);
- }
- sqlite3BtreeLeave(p);
- }
- return rc;
-}
-#endif
-
-#ifndef SQLITE_OMIT_INCRBLOB
-/*
-** Argument pCsr must be a cursor opened for writing on an
-** INTKEY table currently pointing at a valid table entry.
-** This function modifies the data stored as part of that entry.
-**
-** Only the data content may only be modified, it is not possible to
-** change the length of the data stored. If this function is called with
-** parameters that attempt to write past the end of the existing data,
-** no modifications are made and SQLITE_CORRUPT is returned.
-*/
-SQLITE_PRIVATE int sqlite3BtreePutData(BtCursor *pCsr, u32 offset, u32 amt, void *z){
- int rc;
- assert( cursorHoldsMutex(pCsr) );
- assert( sqlite3_mutex_held(pCsr->pBtree->db->mutex) );
- assert( pCsr->isIncrblobHandle );
-
- rc = restoreCursorPosition(pCsr);
- if( rc!=SQLITE_OK ){
- return rc;
- }
- assert( pCsr->eState!=CURSOR_REQUIRESEEK );
- if( pCsr->eState!=CURSOR_VALID ){
- return SQLITE_ABORT;
- }
-
- /* Check some assumptions:
- ** (a) the cursor is open for writing,
- ** (b) there is a read/write transaction open,
- ** (c) the connection holds a write-lock on the table (if required),
- ** (d) there are no conflicting read-locks, and
- ** (e) the cursor points at a valid row of an intKey table.
- */
- if( !pCsr->wrFlag ){
- return SQLITE_READONLY;
- }
- assert( !pCsr->pBt->readOnly && 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 );
-
- return accessPayload(pCsr, offset, amt, (unsigned char *)z, 1);
-}
-
-/*
-** Set a flag on this cursor to cache the locations of pages from the
-** overflow list for the current row. This is used by cursors opened
-** for incremental blob IO only.
-**
-** This function sets a flag only. The actual page location cache
-** (stored in BtCursor.aOverflow[]) is allocated and used by function
-** accessPayload() (the worker function for sqlite3BtreeData() and
-** sqlite3BtreePutData()).
-*/
-SQLITE_PRIVATE void sqlite3BtreeCacheOverflow(BtCursor *pCur){
- assert( cursorHoldsMutex(pCur) );
- assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
- assert(!pCur->isIncrblobHandle);
- assert(!pCur->aOverflow);
- pCur->isIncrblobHandle = 1;
-}
-#endif
-
-/************** End of btree.c ***********************************************/
-/************** Begin file backup.c ******************************************/
-/*
-** 2009 January 28
-**
-** 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 implementation of the sqlite3_backup_XXX()
-** API functions and the related features.
-**
-** $Id: backup.c,v 1.19 2009/07/06 19:03:13 drh Exp $
-*/
-
-/* Macro to find the minimum of two numeric values.
-*/
-#ifndef MIN
-# define MIN(x,y) ((x)<(y)?(x):(y))
-#endif
-
-/*
-** Structure allocated for each backup operation.
-*/
-struct sqlite3_backup {
- sqlite3* pDestDb; /* Destination database handle */
- Btree *pDest; /* Destination b-tree file */
- u32 iDestSchema; /* Original schema cookie in destination */
- int bDestLocked; /* True once a write-transaction is open on pDest */
-
- Pgno iNext; /* Page number of the next source page to copy */
- sqlite3* pSrcDb; /* Source database handle */
- Btree *pSrc; /* Source b-tree file */
-
- int rc; /* Backup process error code */
-
- /* These two variables are set by every call to backup_step(). They are
- ** read by calls to backup_remaining() and backup_pagecount().
- */
- Pgno nRemaining; /* Number of pages left to copy */
- Pgno nPagecount; /* Total number of pages to copy */
-
- int isAttached; /* True once backup has been registered with pager */
- sqlite3_backup *pNext; /* Next backup associated with source pager */
-};
-
-/*
-** THREAD SAFETY NOTES:
-**
-** Once it has been created using backup_init(), a single sqlite3_backup
-** structure may be accessed via two groups of thread-safe entry points:
-**
-** * Via the sqlite3_backup_XXX() API function backup_step() and
-** backup_finish(). Both these functions obtain the source database
-** handle mutex and the mutex associated with the source BtShared
-** structure, in that order.
-**
-** * Via the BackupUpdate() and BackupRestart() functions, which are
-** invoked by the pager layer to report various state changes in
-** the page cache associated with the source database. The mutex
-** associated with the source database BtShared structure will always
-** be held when either of these functions are invoked.
-**
-** The other sqlite3_backup_XXX() API functions, backup_remaining() and
-** backup_pagecount() are not thread-safe functions. If they are called
-** while some other thread is calling backup_step() or backup_finish(),
-** the values returned may be invalid. There is no way for a call to
-** BackupUpdate() or BackupRestart() to interfere with backup_remaining()
-** or backup_pagecount().
-**
-** Depending on the SQLite configuration, the database handles and/or
-** the Btree objects may have their own mutexes that require locking.
-** Non-sharable Btrees (in-memory databases for example), do not have
-** associated mutexes.
-*/
-
-/*
-** Return a pointer corresponding to database zDb (i.e. "main", "temp")
-** in connection handle pDb. If such a database cannot be found, return
-** a NULL pointer and write an error message to pErrorDb.
-**
-** If the "temp" database is requested, it may need to be opened by this
-** function. If an error occurs while doing so, return 0 and write an
-** error message to pErrorDb.
-*/
-static Btree *findBtree(sqlite3 *pErrorDb, sqlite3 *pDb, const char *zDb){
- int i = sqlite3FindDbName(pDb, zDb);
-
- if( i==1 ){
- Parse *pParse;
- int rc = 0;
- pParse = sqlite3StackAllocZero(pErrorDb, sizeof(*pParse));
- if( pParse==0 ){
- sqlite3Error(pErrorDb, SQLITE_NOMEM, "out of memory");
- rc = SQLITE_NOMEM;
- }else{
- pParse->db = pDb;
- if( sqlite3OpenTempDatabase(pParse) ){
- sqlite3ErrorClear(pParse);
- sqlite3Error(pErrorDb, pParse->rc, "%s", pParse->zErrMsg);
- rc = SQLITE_ERROR;
- }
- sqlite3StackFree(pErrorDb, pParse);
- }
- if( rc ){
- return 0;
- }
- }
-
- if( i<0 ){
- sqlite3Error(pErrorDb, SQLITE_ERROR, "unknown database %s", zDb);
- return 0;
- }
-
- return pDb->aDb[i].pBt;
-}
-
-/*
-** Create an sqlite3_backup process to copy the contents of zSrcDb from
-** connection handle pSrcDb to zDestDb in pDestDb. If successful, return
-** a pointer to the new sqlite3_backup object.
-**
-** If an error occurs, NULL is returned and an error code and error message
-** stored in database handle pDestDb.
-*/
-SQLITE_API sqlite3_backup *sqlite3_backup_init(
- sqlite3* pDestDb, /* Database to write to */
- const char *zDestDb, /* Name of database within pDestDb */
- sqlite3* pSrcDb, /* Database connection to read from */
- const char *zSrcDb /* Name of database within pSrcDb */
-){
- sqlite3_backup *p; /* Value to return */
-
- /* Lock the source database handle. The destination database
- ** handle is not locked in this routine, but it is locked in
- ** sqlite3_backup_step(). The user is required to ensure that no
- ** other thread accesses the destination handle for the duration
- ** of the backup operation. Any attempt to use the destination
- ** database connection while a backup is in progress may cause
- ** a malfunction or a deadlock.
- */
- sqlite3_mutex_enter(pSrcDb->mutex);
- sqlite3_mutex_enter(pDestDb->mutex);
-
- if( pSrcDb==pDestDb ){
- sqlite3Error(
- pDestDb, SQLITE_ERROR, "source and destination must be distinct"
- );
- p = 0;
- }else {
- /* Allocate space for a new sqlite3_backup object */
- p = (sqlite3_backup *)sqlite3_malloc(sizeof(sqlite3_backup));
- if( !p ){
- sqlite3Error(pDestDb, SQLITE_NOMEM, 0);
- }
- }
-
- /* If the allocation succeeded, populate the new object. */
- if( p ){
- memset(p, 0, sizeof(sqlite3_backup));
- p->pSrc = findBtree(pDestDb, pSrcDb, zSrcDb);
- p->pDest = findBtree(pDestDb, pDestDb, zDestDb);
- p->pDestDb = pDestDb;
- p->pSrcDb = pSrcDb;
- p->iNext = 1;
- p->isAttached = 0;
-
- if( 0==p->pSrc || 0==p->pDest ){
- /* One (or both) of the named databases did not exist. An error has
- ** already been written into the pDestDb handle. All that is left
- ** to do here is free the sqlite3_backup structure.
- */
- sqlite3_free(p);
- p = 0;
- }
- }
- if( p ){
- p->pSrc->nBackup++;
- }
-
- sqlite3_mutex_leave(pDestDb->mutex);
- sqlite3_mutex_leave(pSrcDb->mutex);
- return p;
-}
-
-/*
-** Argument rc is an SQLite error code. Return true if this error is
-** considered fatal if encountered during a backup operation. All errors
-** are considered fatal except for SQLITE_BUSY and SQLITE_LOCKED.
-*/
-static int isFatalError(int rc){
- return (rc!=SQLITE_OK && rc!=SQLITE_BUSY && ALWAYS(rc!=SQLITE_LOCKED));
-}
-
-/*
-** Parameter zSrcData points to a buffer containing the data for
-** page iSrcPg from the source database. Copy this data into the
-** destination database.
-*/
-static int backupOnePage(sqlite3_backup *p, Pgno iSrcPg, const u8 *zSrcData){
- Pager * const pDestPager = sqlite3BtreePager(p->pDest);
- const int nSrcPgsz = sqlite3BtreeGetPageSize(p->pSrc);
- int nDestPgsz = sqlite3BtreeGetPageSize(p->pDest);
- const int nCopy = MIN(nSrcPgsz, nDestPgsz);
- const i64 iEnd = (i64)iSrcPg*(i64)nSrcPgsz;
-
- int rc = SQLITE_OK;
- i64 iOff;
-
- assert( p->bDestLocked );
- assert( !isFatalError(p->rc) );
- assert( iSrcPg!=PENDING_BYTE_PAGE(p->pSrc->pBt) );
- assert( zSrcData );
-
- /* Catch the case where the destination is an in-memory database and the
- ** page sizes of the source and destination differ.
- */
- if( nSrcPgsz!=nDestPgsz && sqlite3PagerIsMemdb(sqlite3BtreePager(p->pDest)) ){
- rc = SQLITE_READONLY;
- }
-
- /* This loop runs once for each destination page spanned by the source
- ** page. For each iteration, variable iOff is set to the byte offset
- ** of the destination page.
- */
- for(iOff=iEnd-(i64)nSrcPgsz; rc==SQLITE_OK && iOff<iEnd; iOff+=nDestPgsz){
- DbPage *pDestPg = 0;
- Pgno iDest = (Pgno)(iOff/nDestPgsz)+1;
- if( iDest==PENDING_BYTE_PAGE(p->pDest->pBt) ) continue;
- if( SQLITE_OK==(rc = sqlite3PagerGet(pDestPager, iDest, &pDestPg))
- && SQLITE_OK==(rc = sqlite3PagerWrite(pDestPg))
- ){
- const u8 *zIn = &zSrcData[iOff%nSrcPgsz];
- u8 *zDestData = sqlite3PagerGetData(pDestPg);
- u8 *zOut = &zDestData[iOff%nDestPgsz];
-
- /* Copy the data from the source page into the destination page.
- ** Then clear the Btree layer MemPage.isInit flag. Both this module
- ** and the pager code use this trick (clearing the first byte
- ** of the page 'extra' space to invalidate the Btree layers
- ** cached parse of the page). MemPage.isInit is marked
- ** "MUST BE FIRST" for this purpose.
- */
- memcpy(zOut, zIn, nCopy);
- ((u8 *)sqlite3PagerGetExtra(pDestPg))[0] = 0;
- }
- sqlite3PagerUnref(pDestPg);
- }
-
- return rc;
-}
-
-/*
-** If pFile is currently larger than iSize bytes, then truncate it to
-** exactly iSize bytes. If pFile is not larger than iSize bytes, then
-** this function is a no-op.
-**
-** Return SQLITE_OK if everything is successful, or an SQLite error
-** code if an error occurs.
-*/
-static int backupTruncateFile(sqlite3_file *pFile, i64 iSize){
- i64 iCurrent;
- int rc = sqlite3OsFileSize(pFile, &iCurrent);
- if( rc==SQLITE_OK && iCurrent>iSize ){
- rc = sqlite3OsTruncate(pFile, iSize);
- }
- return rc;
-}
-
-/*
-** Register this backup object with the associated source pager for
-** callbacks when pages are changed or the cache invalidated.
-*/
-static void attachBackupObject(sqlite3_backup *p){
- sqlite3_backup **pp;
- assert( sqlite3BtreeHoldsMutex(p->pSrc) );
- pp = sqlite3PagerBackupPtr(sqlite3BtreePager(p->pSrc));
- p->pNext = *pp;
- *pp = p;
- p->isAttached = 1;
-}
-
-/*
-** Copy nPage pages from the source b-tree to the destination.
-*/
-SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage){
- int rc;
-
- sqlite3_mutex_enter(p->pSrcDb->mutex);
- sqlite3BtreeEnter(p->pSrc);
- if( p->pDestDb ){
- sqlite3_mutex_enter(p->pDestDb->mutex);
- }
-
- rc = p->rc;
- if( !isFatalError(rc) ){
- Pager * const pSrcPager = sqlite3BtreePager(p->pSrc); /* Source pager */
- Pager * const pDestPager = sqlite3BtreePager(p->pDest); /* Dest pager */
- int ii; /* Iterator variable */
- int nSrcPage = -1; /* Size of source db in pages */
- int bCloseTrans = 0; /* True if src db requires unlocking */
-
- /* If the source pager is currently in a write-transaction, return
- ** SQLITE_BUSY immediately.
- */
- if( p->pDestDb && p->pSrc->pBt->inTransaction==TRANS_WRITE ){
- rc = SQLITE_BUSY;
- }else{
- rc = SQLITE_OK;
- }
-
- /* Lock the destination database, if it is not locked already. */
- if( SQLITE_OK==rc && p->bDestLocked==0
- && SQLITE_OK==(rc = sqlite3BtreeBeginTrans(p->pDest, 2))
- ){
- p->bDestLocked = 1;
- sqlite3BtreeGetMeta(p->pDest, BTREE_SCHEMA_VERSION, &p->iDestSchema);
- }
-
- /* If there is no open read-transaction on the source database, open
- ** one now. If a transaction is opened here, then it will be closed
- ** before this function exits.
- */
- if( rc==SQLITE_OK && 0==sqlite3BtreeIsInReadTrans(p->pSrc) ){
- rc = sqlite3BtreeBeginTrans(p->pSrc, 0);
- bCloseTrans = 1;
- }
-
- /* Now that there is a read-lock on the source database, query the
- ** source pager for the number of pages in the database.
- */
- if( rc==SQLITE_OK ){
- rc = sqlite3PagerPagecount(pSrcPager, &nSrcPage);
- }
- for(ii=0; (nPage<0 || ii<nPage) && p->iNext<=(Pgno)nSrcPage && !rc; ii++){
- const Pgno iSrcPg = p->iNext; /* Source page number */
- if( iSrcPg!=PENDING_BYTE_PAGE(p->pSrc->pBt) ){
- DbPage *pSrcPg; /* Source page object */
- rc = sqlite3PagerGet(pSrcPager, iSrcPg, &pSrcPg);
- if( rc==SQLITE_OK ){
- rc = backupOnePage(p, iSrcPg, sqlite3PagerGetData(pSrcPg));
- sqlite3PagerUnref(pSrcPg);
- }
- }
- p->iNext++;
- }
- if( rc==SQLITE_OK ){
- p->nPagecount = nSrcPage;
- p->nRemaining = nSrcPage+1-p->iNext;
- if( p->iNext>(Pgno)nSrcPage ){
- rc = SQLITE_DONE;
- }else if( !p->isAttached ){
- attachBackupObject(p);
- }
- }
-
- /* Update the schema version field in the destination database. This
- ** is to make sure that the schema-version really does change in
- ** the case where the source and destination databases have the
- ** same schema version.
- */
- if( rc==SQLITE_DONE
- && (rc = sqlite3BtreeUpdateMeta(p->pDest,1,p->iDestSchema+1))==SQLITE_OK
- ){
- const int nSrcPagesize = sqlite3BtreeGetPageSize(p->pSrc);
- const int nDestPagesize = sqlite3BtreeGetPageSize(p->pDest);
- int nDestTruncate;
-
- if( p->pDestDb ){
- sqlite3ResetInternalSchema(p->pDestDb, 0);
- }
-
- /* Set nDestTruncate to the final number of pages in the destination
- ** database. The complication here is that the destination page
- ** size may be different to the source page size.
- **
- ** If the source page size is smaller than the destination page size,
- ** round up. In this case the call to sqlite3OsTruncate() below will
- ** fix the size of the file. However it is important to call
- ** sqlite3PagerTruncateImage() here so that any pages in the
- ** destination file that lie beyond the nDestTruncate page mark are
- ** journalled by PagerCommitPhaseOne() before they are destroyed
- ** by the file truncation.
- */
- if( nSrcPagesize<nDestPagesize ){
- int ratio = nDestPagesize/nSrcPagesize;
- nDestTruncate = (nSrcPage+ratio-1)/ratio;
- if( nDestTruncate==(int)PENDING_BYTE_PAGE(p->pDest->pBt) ){
- nDestTruncate--;
- }
- }else{
- nDestTruncate = nSrcPage * (nSrcPagesize/nDestPagesize);
- }
- sqlite3PagerTruncateImage(pDestPager, nDestTruncate);
-
- if( nSrcPagesize<nDestPagesize ){
- /* If the source page-size is smaller than the destination page-size,
- ** two extra things may need to happen:
- **
- ** * The destination may need to be truncated, and
- **
- ** * Data stored on the pages immediately following the
- ** pending-byte page in the source database may need to be
- ** copied into the destination database.
- */
- const i64 iSize = (i64)nSrcPagesize * (i64)nSrcPage;
- sqlite3_file * const pFile = sqlite3PagerFile(pDestPager);
-
- assert( pFile );
- assert( (i64)nDestTruncate*(i64)nDestPagesize >= iSize || (
- nDestTruncate==(int)(PENDING_BYTE_PAGE(p->pDest->pBt)-1)
- && iSize>=PENDING_BYTE && iSize<=PENDING_BYTE+nDestPagesize
- ));
- if( SQLITE_OK==(rc = sqlite3PagerCommitPhaseOne(pDestPager, 0, 1))
- && SQLITE_OK==(rc = backupTruncateFile(pFile, iSize))
- && SQLITE_OK==(rc = sqlite3PagerSync(pDestPager))
- ){
- i64 iOff;
- i64 iEnd = MIN(PENDING_BYTE + nDestPagesize, iSize);
- for(
- iOff=PENDING_BYTE+nSrcPagesize;
- rc==SQLITE_OK && iOff<iEnd;
- iOff+=nSrcPagesize
- ){
- PgHdr *pSrcPg = 0;
- const Pgno iSrcPg = (Pgno)((iOff/nSrcPagesize)+1);
- rc = sqlite3PagerGet(pSrcPager, iSrcPg, &pSrcPg);
- if( rc==SQLITE_OK ){
- u8 *zData = sqlite3PagerGetData(pSrcPg);
- rc = sqlite3OsWrite(pFile, zData, nSrcPagesize, iOff);
- }
- sqlite3PagerUnref(pSrcPg);
- }
- }
- }else{
- rc = sqlite3PagerCommitPhaseOne(pDestPager, 0, 0);
- }
-
- /* Finish committing the transaction to the destination database. */
- if( SQLITE_OK==rc
- && SQLITE_OK==(rc = sqlite3BtreeCommitPhaseTwo(p->pDest))
- ){
- rc = SQLITE_DONE;
- }
- }
-
- /* If bCloseTrans is true, then this function opened a read transaction
- ** on the source database. Close the read transaction here. There is
- ** no need to check the return values of the btree methods here, as
- ** "committing" a read-only transaction cannot fail.
- */
- if( bCloseTrans ){
- TESTONLY( int rc2 );
- TESTONLY( rc2 = ) sqlite3BtreeCommitPhaseOne(p->pSrc, 0);
- TESTONLY( rc2 |= ) sqlite3BtreeCommitPhaseTwo(p->pSrc);
- assert( rc2==SQLITE_OK );
- }
-
- p->rc = rc;
- }
- if( p->pDestDb ){
- sqlite3_mutex_leave(p->pDestDb->mutex);
- }
- sqlite3BtreeLeave(p->pSrc);
- sqlite3_mutex_leave(p->pSrcDb->mutex);
- return rc;
-}
-
-/*
-** Release all resources associated with an sqlite3_backup* handle.
-*/
-SQLITE_API int sqlite3_backup_finish(sqlite3_backup *p){
- sqlite3_backup **pp; /* Ptr to head of pagers backup list */
- sqlite3_mutex *mutex; /* Mutex to protect source database */
- int rc; /* Value to return */
-
- /* Enter the mutexes */
- if( p==0 ) return SQLITE_OK;
- sqlite3_mutex_enter(p->pSrcDb->mutex);
- sqlite3BtreeEnter(p->pSrc);
- mutex = p->pSrcDb->mutex;
- if( p->pDestDb ){
- sqlite3_mutex_enter(p->pDestDb->mutex);
- }
-
- /* Detach this backup from the source pager. */
- if( p->pDestDb ){
- p->pSrc->nBackup--;
- }
- if( p->isAttached ){
- pp = sqlite3PagerBackupPtr(sqlite3BtreePager(p->pSrc));
- while( *pp!=p ){
- pp = &(*pp)->pNext;
- }
- *pp = p->pNext;
- }
-
- /* If a transaction is still open on the Btree, roll it back. */
- sqlite3BtreeRollback(p->pDest);
-
- /* Set the error code of the destination database handle. */
- rc = (p->rc==SQLITE_DONE) ? SQLITE_OK : p->rc;
- sqlite3Error(p->pDestDb, rc, 0);
-
- /* Exit the mutexes and free the backup context structure. */
- if( p->pDestDb ){
- sqlite3_mutex_leave(p->pDestDb->mutex);
- }
- sqlite3BtreeLeave(p->pSrc);
- if( p->pDestDb ){
- sqlite3_free(p);
- }
- sqlite3_mutex_leave(mutex);
- return rc;
-}
-
-/*
-** Return the number of pages still to be backed up as of the most recent
-** call to sqlite3_backup_step().
-*/
-SQLITE_API int sqlite3_backup_remaining(sqlite3_backup *p){
- return p->nRemaining;
-}
-
-/*
-** Return the total number of pages in the source database as of the most
-** recent call to sqlite3_backup_step().
-*/
-SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p){
- return p->nPagecount;
-}
-
-/*
-** This function is called after the contents of page iPage of the
-** source database have been modified. If page iPage has already been
-** copied into the destination database, then the data written to the
-** destination is now invalidated. The destination copy of iPage needs
-** to be updated with the new data before the backup operation is
-** complete.
-**
-** It is assumed that the mutex associated with the BtShared object
-** corresponding to the source database is held when this function is
-** called.
-*/
-SQLITE_PRIVATE void sqlite3BackupUpdate(sqlite3_backup *pBackup, Pgno iPage, const u8 *aData){
- sqlite3_backup *p; /* Iterator variable */
- for(p=pBackup; p; p=p->pNext){
- assert( sqlite3_mutex_held(p->pSrc->pBt->mutex) );
- if( !isFatalError(p->rc) && iPage<p->iNext ){
- /* The backup process p has already copied page iPage. But now it
- ** has been modified by a transaction on the source pager. Copy
- ** the new data into the backup.
- */
- int rc = backupOnePage(p, iPage, aData);
- assert( rc!=SQLITE_BUSY && rc!=SQLITE_LOCKED );
- if( rc!=SQLITE_OK ){
- p->rc = rc;
- }
- }
- }
-}
-
-/*
-** Restart the backup process. This is called when the pager layer
-** detects that the database has been modified by an external database
-** connection. In this case there is no way of knowing which of the
-** pages that have been copied into the destination database are still
-** valid and which are not, so the entire process needs to be restarted.
-**
-** It is assumed that the mutex associated with the BtShared object
-** corresponding to the source database is held when this function is
-** called.
-*/
-SQLITE_PRIVATE void sqlite3BackupRestart(sqlite3_backup *pBackup){
- sqlite3_backup *p; /* Iterator variable */
- for(p=pBackup; p; p=p->pNext){
- assert( sqlite3_mutex_held(p->pSrc->pBt->mutex) );
- p->iNext = 1;
- }
-}
-
-#ifndef SQLITE_OMIT_VACUUM
-/*
-** Copy the complete content of pBtFrom into pBtTo. A transaction
-** must be active for both files.
-**
-** The size of file pTo may be reduced by this operation. If anything
-** goes wrong, the transaction on pTo is rolled back. If successful, the
-** transaction is committed before returning.
-*/
-SQLITE_PRIVATE int sqlite3BtreeCopyFile(Btree *pTo, Btree *pFrom){
- int rc;
- sqlite3_backup b;
- sqlite3BtreeEnter(pTo);
- sqlite3BtreeEnter(pFrom);
-
- /* Set up an sqlite3_backup object. sqlite3_backup.pDestDb must be set
- ** to 0. This is used by the implementations of sqlite3_backup_step()
- ** and sqlite3_backup_finish() to detect that they are being called
- ** from this function, not directly by the user.
- */
- memset(&b, 0, sizeof(b));
- b.pSrcDb = pFrom->db;
- b.pSrc = pFrom;
- b.pDest = pTo;
- b.iNext = 1;
-
- /* 0x7FFFFFFF is the hard limit for the number of pages in a database
- ** file. By passing this as the number of pages to copy to
- ** sqlite3_backup_step(), we can guarantee that the copy finishes
- ** within a single call (unless an error occurs). The assert() statement
- ** checks this assumption - (p->rc) should be set to either SQLITE_DONE
- ** or an error code.
- */
- sqlite3_backup_step(&b, 0x7FFFFFFF);
- assert( b.rc!=SQLITE_OK );
- rc = sqlite3_backup_finish(&b);
- if( rc==SQLITE_OK ){
- pTo->pBt->pageSizeFixed = 0;
- }
-
- sqlite3BtreeLeave(pFrom);
- sqlite3BtreeLeave(pTo);
- return rc;
-}
-#endif /* SQLITE_OMIT_VACUUM */
-
-/************** End of backup.c **********************************************/
-/************** Begin file vdbemem.c *****************************************/
-/*
-** 2004 May 26
-**
-** 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 code use to manipulate "Mem" structure. A "Mem"
-** stores a single value in the VDBE. Mem is an opaque structure visible
-** only within the VDBE. Interface routines refer to a Mem using the
-** name sqlite_value
-**
-** $Id: vdbemem.c,v 1.152 2009/07/22 18:07:41 drh Exp $
-*/
-
-/*
-** 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
-** 'desiredEnc', one of SQLITE_UTF8, SQLITE_UTF16LE or SQLITE_UTF16BE.
-**
-** If pMem is not a string object, or the encoding of the string
-** representation is already stored using the requested encoding, then this
-** routine is a no-op.
-**
-** SQLITE_OK is returned if the conversion is successful (or not required).
-** SQLITE_NOMEM may be returned if a malloc() fails during conversion
-** between formats.
-*/
-SQLITE_PRIVATE int sqlite3VdbeChangeEncoding(Mem *pMem, int desiredEnc){
- int rc;
- assert( (pMem->flags&MEM_RowSet)==0 );
- assert( desiredEnc==SQLITE_UTF8 || desiredEnc==SQLITE_UTF16LE
- || desiredEnc==SQLITE_UTF16BE );
- if( !(pMem->flags&MEM_Str) || pMem->enc==desiredEnc ){
- return SQLITE_OK;
- }
- assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
-#ifdef SQLITE_OMIT_UTF16
- return SQLITE_ERROR;
-#else
-
- /* MemTranslate() may return SQLITE_OK or SQLITE_NOMEM. If NOMEM is returned,
- ** then the encoding of the value may not have changed.
- */
- rc = sqlite3VdbeMemTranslate(pMem, (u8)desiredEnc);
- assert(rc==SQLITE_OK || rc==SQLITE_NOMEM);
- assert(rc==SQLITE_OK || pMem->enc!=desiredEnc);
- assert(rc==SQLITE_NOMEM || pMem->enc==desiredEnc);
- return rc;
-#endif
-}
-
-/*
-** Make sure pMem->z points to a writable allocation of at least
-** n bytes.
-**
-** If the memory cell currently contains string or blob data
-** and the third argument passed to this function is true, the
-** current content of the cell is preserved. Otherwise, it may
-** be discarded.
-**
-** This function sets the MEM_Dyn flag and clears any xDel callback.
-** It also clears MEM_Ephem and MEM_Static. If the preserve flag is
-** not set, Mem.n is zeroed.
-*/
-SQLITE_PRIVATE int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve){
- assert( 1 >=
- ((pMem->zMalloc && pMem->zMalloc==pMem->z) ? 1 : 0) +
- (((pMem->flags&MEM_Dyn)&&pMem->xDel) ? 1 : 0) +
- ((pMem->flags&MEM_Ephem) ? 1 : 0) +
- ((pMem->flags&MEM_Static) ? 1 : 0)
- );
- assert( (pMem->flags&MEM_RowSet)==0 );
-
- if( n<32 ) n = 32;
- if( sqlite3DbMallocSize(pMem->db, pMem->zMalloc)<n ){
- if( preserve && pMem->z==pMem->zMalloc ){
- pMem->z = pMem->zMalloc = sqlite3DbReallocOrFree(pMem->db, pMem->z, n);
- preserve = 0;
- }else{
- sqlite3DbFree(pMem->db, pMem->zMalloc);
- pMem->zMalloc = sqlite3DbMallocRaw(pMem->db, n);
- }
- }
-
- if( pMem->z && preserve && pMem->zMalloc && pMem->z!=pMem->zMalloc ){
- memcpy(pMem->zMalloc, pMem->z, pMem->n);
- }
- if( pMem->flags&MEM_Dyn && pMem->xDel ){
- pMem->xDel((void *)(pMem->z));
- }
-
- pMem->z = pMem->zMalloc;
- if( pMem->z==0 ){
- pMem->flags = MEM_Null;
- }else{
- pMem->flags &= ~(MEM_Ephem|MEM_Static);
- }
- pMem->xDel = 0;
- return (pMem->z ? SQLITE_OK : SQLITE_NOMEM);
-}
-
-/*
-** Make the given Mem object MEM_Dyn. In other words, make it so
-** that any TEXT or BLOB content is stored in memory obtained from
-** malloc(). In this way, we know that the memory is safe to be
-** overwritten or altered.
-**
-** Return SQLITE_OK on success or SQLITE_NOMEM if malloc fails.
-*/
-SQLITE_PRIVATE int sqlite3VdbeMemMakeWriteable(Mem *pMem){
- int f;
- assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
- assert( (pMem->flags&MEM_RowSet)==0 );
- expandBlob(pMem);
- f = pMem->flags;
- if( (f&(MEM_Str|MEM_Blob)) && pMem->z!=pMem->zMalloc ){
- if( sqlite3VdbeMemGrow(pMem, pMem->n + 2, 1) ){
- return SQLITE_NOMEM;
- }
- pMem->z[pMem->n] = 0;
- pMem->z[pMem->n+1] = 0;
- pMem->flags |= MEM_Term;
- }
-
- return SQLITE_OK;
-}
-
-/*
-** If the given Mem* has a zero-filled tail, turn it into an ordinary
-** blob stored in dynamically allocated space.
-*/
-#ifndef SQLITE_OMIT_INCRBLOB
-SQLITE_PRIVATE int sqlite3VdbeMemExpandBlob(Mem *pMem){
- if( pMem->flags & MEM_Zero ){
- int nByte;
- assert( pMem->flags&MEM_Blob );
- assert( (pMem->flags&MEM_RowSet)==0 );
- assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
-
- /* Set nByte to the number of bytes required to store the expanded blob. */
- nByte = pMem->n + pMem->u.nZero;
- if( nByte<=0 ){
- nByte = 1;
- }
- if( sqlite3VdbeMemGrow(pMem, nByte, 1) ){
- return SQLITE_NOMEM;
- }
-
- memset(&pMem->z[pMem->n], 0, pMem->u.nZero);
- pMem->n += pMem->u.nZero;
- pMem->flags &= ~(MEM_Zero|MEM_Term);
- }
- return SQLITE_OK;
-}
-#endif
-
-
-/*
-** Make sure the given Mem is \u0000 terminated.
-*/
-SQLITE_PRIVATE int sqlite3VdbeMemNulTerminate(Mem *pMem){
- assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
- if( (pMem->flags & MEM_Term)!=0 || (pMem->flags & MEM_Str)==0 ){
- return SQLITE_OK; /* Nothing to do */
- }
- if( sqlite3VdbeMemGrow(pMem, pMem->n+2, 1) ){
- return SQLITE_NOMEM;
- }
- pMem->z[pMem->n] = 0;
- pMem->z[pMem->n+1] = 0;
- pMem->flags |= MEM_Term;
- return SQLITE_OK;
-}
-
-/*
-** Add MEM_Str to the set of representations for the given Mem. Numbers
-** are converted using sqlite3_snprintf(). Converting a BLOB to a string
-** is a no-op.
-**
-** Existing representations MEM_Int and MEM_Real are *not* invalidated.
-**
-** A MEM_Null value will never be passed to this function. This function is
-** used for converting values to text for returning to the user (i.e. via
-** sqlite3_value_text()), or for ensuring that values to be used as btree
-** keys are strings. In the former case a NULL pointer is returned the
-** user and the later is an internal programming error.
-*/
-SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem *pMem, int enc){
- int rc = SQLITE_OK;
- int fg = pMem->flags;
- const int nByte = 32;
-
- assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
- assert( !(fg&MEM_Zero) );
- assert( !(fg&(MEM_Str|MEM_Blob)) );
- assert( fg&(MEM_Int|MEM_Real) );
- assert( (pMem->flags&MEM_RowSet)==0 );
- assert( EIGHT_BYTE_ALIGNMENT(pMem) );
-
-
- if( sqlite3VdbeMemGrow(pMem, nByte, 0) ){
- return SQLITE_NOMEM;
- }
-
- /* For a Real or Integer, use sqlite3_mprintf() to produce the UTF-8
- ** string representation of the value. Then, if the required encoding
- ** is UTF-16le or UTF-16be do a translation.
- **
- ** FIX ME: It would be better if sqlite3_snprintf() could do UTF-16.
- */
- if( fg & MEM_Int ){
- sqlite3_snprintf(nByte, pMem->z, "%lld", pMem->u.i);
- }else{
- assert( fg & MEM_Real );
- sqlite3_snprintf(nByte, pMem->z, "%!.15g", pMem->r);
- }
- pMem->n = sqlite3Strlen30(pMem->z);
- pMem->enc = SQLITE_UTF8;
- pMem->flags |= MEM_Str|MEM_Term;
- sqlite3VdbeChangeEncoding(pMem, enc);
- return rc;
-}
-
-/*
-** Memory cell pMem contains the context of an aggregate function.
-** This routine calls the finalize method for that function. The
-** result of the aggregate is stored back into pMem.
-**
-** Return SQLITE_ERROR if the finalizer reports an error. SQLITE_OK
-** otherwise.
-*/
-SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem *pMem, FuncDef *pFunc){
- int rc = SQLITE_OK;
- if( ALWAYS(pFunc && pFunc->xFinalize) ){
- sqlite3_context ctx;
- assert( (pMem->flags & MEM_Null)!=0 || pFunc==pMem->u.pDef );
- assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
- memset(&ctx, 0, sizeof(ctx));
- ctx.s.flags = MEM_Null;
- ctx.s.db = pMem->db;
- ctx.pMem = pMem;
- ctx.pFunc = pFunc;
- pFunc->xFinalize(&ctx);
- assert( 0==(pMem->flags&MEM_Dyn) && !pMem->xDel );
- sqlite3DbFree(pMem->db, pMem->zMalloc);
- memcpy(pMem, &ctx.s, sizeof(ctx.s));
- rc = ctx.isError;
- }
- return rc;
-}
-
-/*
-** If the memory cell contains a string value that must be freed by
-** invoking an external callback, free it now. Calling this function
-** does not free any Mem.zMalloc buffer.
-*/
-SQLITE_PRIVATE void sqlite3VdbeMemReleaseExternal(Mem *p){
- assert( p->db==0 || sqlite3_mutex_held(p->db->mutex) );
- testcase( p->flags & MEM_Agg );
- testcase( p->flags & MEM_Dyn );
- testcase( p->flags & MEM_RowSet );
- testcase( p->flags & MEM_Frame );
- if( p->flags&(MEM_Agg|MEM_Dyn|MEM_RowSet|MEM_Frame) ){
- if( p->flags&MEM_Agg ){
- sqlite3VdbeMemFinalize(p, p->u.pDef);
- assert( (p->flags & MEM_Agg)==0 );
- sqlite3VdbeMemRelease(p);
- }else if( p->flags&MEM_Dyn && p->xDel ){
- assert( (p->flags&MEM_RowSet)==0 );
- p->xDel((void *)p->z);
- p->xDel = 0;
- }else if( p->flags&MEM_RowSet ){
- sqlite3RowSetClear(p->u.pRowSet);
- }else if( p->flags&MEM_Frame ){
- sqlite3VdbeMemSetNull(p);
- }
- }
-}
-
-/*
-** Release any memory held by the Mem. This may leave the Mem in an
-** inconsistent state, for example with (Mem.z==0) and
-** (Mem.type==SQLITE_TEXT).
-*/
-SQLITE_PRIVATE void sqlite3VdbeMemRelease(Mem *p){
- sqlite3VdbeMemReleaseExternal(p);
- sqlite3DbFree(p->db, p->zMalloc);
- p->z = 0;
- p->zMalloc = 0;
- p->xDel = 0;
-}
-
-/*
-** Convert a 64-bit IEEE double into a 64-bit signed integer.
-** If the double is too large, return 0x8000000000000000.
-**
-** Most systems appear to do this simply by assigning
-** variables and without the extra range tests. But
-** there are reports that windows throws an expection
-** if the floating point value is out of range. (See ticket #2880.)
-** Because we do not completely understand the problem, we will
-** take the conservative approach and always do range tests
-** before attempting the conversion.
-*/
-static i64 doubleToInt64(double r){
- /*
- ** Many compilers we encounter do not define constants for the
- ** minimum and maximum 64-bit integers, or they define them
- ** inconsistently. And many do not understand the "LL" notation.
- ** So we define our own static constants here using nothing
- ** larger than a 32-bit integer constant.
- */
- static const i64 maxInt = LARGEST_INT64;
- static const i64 minInt = SMALLEST_INT64;
-
- if( r<(double)minInt ){
- return minInt;
- }else if( r>(double)maxInt ){
- /* minInt is correct here - not maxInt. It turns out that assigning
- ** a very large positive number to an integer results in a very large
- ** negative integer. This makes no sense, but it is what x86 hardware
- ** does so for compatibility we will do the same in software. */
- return minInt;
- }else{
- return (i64)r;
- }
-}
-
-/*
-** Return some kind of integer value which is the best we can do
-** at representing the value that *pMem describes as an integer.
-** If pMem is an integer, then the value is exact. If pMem is
-** a floating-point then the value returned is the integer part.
-** If pMem is a string or blob, then we make an attempt to convert
-** it into a integer and return that. If pMem represents an
-** an SQL-NULL value, return 0.
-**
-** If pMem represents a string value, its encoding might be changed.
-*/
-SQLITE_PRIVATE i64 sqlite3VdbeIntValue(Mem *pMem){
- int flags;
- assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
- assert( EIGHT_BYTE_ALIGNMENT(pMem) );
- flags = pMem->flags;
- if( flags & MEM_Int ){
- return pMem->u.i;
- }else if( flags & MEM_Real ){
- return doubleToInt64(pMem->r);
- }else if( flags & (MEM_Str|MEM_Blob) ){
- i64 value;
- pMem->flags |= MEM_Str;
- if( sqlite3VdbeChangeEncoding(pMem, SQLITE_UTF8)
- || sqlite3VdbeMemNulTerminate(pMem) ){
- return 0;
- }
- assert( pMem->z );
- sqlite3Atoi64(pMem->z, &value);
- return value;
- }else{
- return 0;
- }
-}
-
-/*
-** Return the best representation of pMem that we can get into a
-** double. If pMem is already a double or an integer, return its
-** value. If it is a string or blob, try to convert it to a double.
-** If it is a NULL, return 0.0.
-*/
-SQLITE_PRIVATE double sqlite3VdbeRealValue(Mem *pMem){
- assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
- assert( EIGHT_BYTE_ALIGNMENT(pMem) );
- if( pMem->flags & MEM_Real ){
- return pMem->r;
- }else if( pMem->flags & MEM_Int ){
- return (double)pMem->u.i;
- }else if( pMem->flags & (MEM_Str|MEM_Blob) ){
- /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */
- double val = (double)0;
- pMem->flags |= MEM_Str;
- if( sqlite3VdbeChangeEncoding(pMem, SQLITE_UTF8)
- || sqlite3VdbeMemNulTerminate(pMem) ){
- /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */
- return (double)0;
- }
- assert( pMem->z );
- sqlite3AtoF(pMem->z, &val);
- return val;
- }else{
- /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */
- return (double)0;
- }
-}
-
-/*
-** The MEM structure is already a MEM_Real. Try to also make it a
-** MEM_Int if we can.
-*/
-SQLITE_PRIVATE void sqlite3VdbeIntegerAffinity(Mem *pMem){
- assert( pMem->flags & MEM_Real );
- assert( (pMem->flags & MEM_RowSet)==0 );
- assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
- assert( EIGHT_BYTE_ALIGNMENT(pMem) );
-
- pMem->u.i = doubleToInt64(pMem->r);
-
- /* Only mark the value as an integer if
- **
- ** (1) the round-trip conversion real->int->real is a no-op, and
- ** (2) The integer is neither the largest nor the smallest
- ** possible integer (ticket #3922)
- **
- ** The second and third terms in the following conditional enforces
- ** the second condition under the assumption that addition overflow causes
- ** values to wrap around. On x86 hardware, the third term is always
- ** true and could be omitted. But we leave it in because other
- ** architectures might behave differently.
- */
- if( pMem->r==(double)pMem->u.i && pMem->u.i>SMALLEST_INT64
- && ALWAYS(pMem->u.i<LARGEST_INT64) ){
- pMem->flags |= MEM_Int;
- }
-}
-
-/*
-** Convert pMem to type integer. Invalidate any prior representations.
-*/
-SQLITE_PRIVATE int sqlite3VdbeMemIntegerify(Mem *pMem){
- assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
- assert( (pMem->flags & MEM_RowSet)==0 );
- assert( EIGHT_BYTE_ALIGNMENT(pMem) );
-
- pMem->u.i = sqlite3VdbeIntValue(pMem);
- MemSetTypeFlag(pMem, MEM_Int);
- return SQLITE_OK;
-}
-
-/*
-** Convert pMem so that it is of type MEM_Real.
-** Invalidate any prior representations.
-*/
-SQLITE_PRIVATE int sqlite3VdbeMemRealify(Mem *pMem){
- assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
- assert( EIGHT_BYTE_ALIGNMENT(pMem) );
-
- pMem->r = sqlite3VdbeRealValue(pMem);
- MemSetTypeFlag(pMem, MEM_Real);
- return SQLITE_OK;
-}
-
-/*
-** Convert pMem so that it has types MEM_Real or MEM_Int or both.
-** Invalidate any prior representations.
-*/
-SQLITE_PRIVATE int sqlite3VdbeMemNumerify(Mem *pMem){
- double r1, r2;
- i64 i;
- assert( (pMem->flags & (MEM_Int|MEM_Real|MEM_Null))==0 );
- assert( (pMem->flags & (MEM_Blob|MEM_Str))!=0 );
- assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
- r1 = sqlite3VdbeRealValue(pMem);
- i = doubleToInt64(r1);
- r2 = (double)i;
- if( r1==r2 ){
- sqlite3VdbeMemIntegerify(pMem);
- }else{
- pMem->r = r1;
- MemSetTypeFlag(pMem, MEM_Real);
- }
- return SQLITE_OK;
-}
-
-/*
-** Delete any previous value and set the value stored in *pMem to NULL.
-*/
-SQLITE_PRIVATE void sqlite3VdbeMemSetNull(Mem *pMem){
- if( pMem->flags & MEM_Frame ){
- sqlite3VdbeFrameDelete(pMem->u.pFrame);
- }
- if( pMem->flags & MEM_RowSet ){
- sqlite3RowSetClear(pMem->u.pRowSet);
- }
- MemSetTypeFlag(pMem, MEM_Null);
- pMem->type = SQLITE_NULL;
-}
-
-/*
-** Delete any previous value and set the value to be a BLOB of length
-** n containing all zeros.
-*/
-SQLITE_PRIVATE void sqlite3VdbeMemSetZeroBlob(Mem *pMem, int n){
- sqlite3VdbeMemRelease(pMem);
- pMem->flags = MEM_Blob|MEM_Zero;
- pMem->type = SQLITE_BLOB;
- pMem->n = 0;
- if( n<0 ) n = 0;
- pMem->u.nZero = n;
- pMem->enc = SQLITE_UTF8;
-
-#ifdef SQLITE_OMIT_INCRBLOB
- sqlite3VdbeMemGrow(pMem, n, 0);
- if( pMem->z ){
- pMem->n = n;
- memset(pMem->z, 0, n);
- }
-#endif
-}
-
-/*
-** Delete any previous value and set the value stored in *pMem to val,
-** manifest type INTEGER.
-*/
-SQLITE_PRIVATE void sqlite3VdbeMemSetInt64(Mem *pMem, i64 val){
- sqlite3VdbeMemRelease(pMem);
- pMem->u.i = val;
- pMem->flags = MEM_Int;
- pMem->type = SQLITE_INTEGER;
-}
-
-/*
-** Delete any previous value and set the value stored in *pMem to val,
-** manifest type REAL.
-*/
-SQLITE_PRIVATE void sqlite3VdbeMemSetDouble(Mem *pMem, double val){
- if( sqlite3IsNaN(val) ){
- sqlite3VdbeMemSetNull(pMem);
- }else{
- sqlite3VdbeMemRelease(pMem);
- pMem->r = val;
- pMem->flags = MEM_Real;
- pMem->type = SQLITE_FLOAT;
- }
-}
-
-/*
-** Delete any previous value and set the value of pMem to be an
-** empty boolean index.
-*/
-SQLITE_PRIVATE void sqlite3VdbeMemSetRowSet(Mem *pMem){
- sqlite3 *db = pMem->db;
- assert( db!=0 );
- assert( (pMem->flags & MEM_RowSet)==0 );
- sqlite3VdbeMemRelease(pMem);
- pMem->zMalloc = sqlite3DbMallocRaw(db, 64);
- if( db->mallocFailed ){
- pMem->flags = MEM_Null;
- }else{
- assert( pMem->zMalloc );
- pMem->u.pRowSet = sqlite3RowSetInit(db, pMem->zMalloc,
- sqlite3DbMallocSize(db, pMem->zMalloc));
- assert( pMem->u.pRowSet!=0 );
- pMem->flags = MEM_RowSet;
- }
-}
-
-/*
-** Return true if the Mem object contains a TEXT or BLOB that is
-** too large - whose size exceeds SQLITE_MAX_LENGTH.
-*/
-SQLITE_PRIVATE int sqlite3VdbeMemTooBig(Mem *p){
- assert( p->db!=0 );
- if( p->flags & (MEM_Str|MEM_Blob) ){
- int n = p->n;
- if( p->flags & MEM_Zero ){
- n += p->u.nZero;
- }
- return n>p->db->aLimit[SQLITE_LIMIT_LENGTH];
- }
- return 0;
-}
-
-/*
-** Size of struct Mem not including the Mem.zMalloc member.
-*/
-#define MEMCELLSIZE (size_t)(&(((Mem *)0)->zMalloc))
-
-/*
-** Make an shallow copy of pFrom into pTo. Prior contents of
-** pTo are freed. The pFrom->z field is not duplicated. If
-** pFrom->z is used, then pTo->z points to the same thing as pFrom->z
-** and flags gets srcType (either MEM_Ephem or MEM_Static).
-*/
-SQLITE_PRIVATE void sqlite3VdbeMemShallowCopy(Mem *pTo, const Mem *pFrom, int srcType){
- assert( (pFrom->flags & MEM_RowSet)==0 );
- sqlite3VdbeMemReleaseExternal(pTo);
- memcpy(pTo, pFrom, MEMCELLSIZE);
- pTo->xDel = 0;
- if( (pFrom->flags&MEM_Dyn)!=0 || pFrom->z==pFrom->zMalloc ){
- pTo->flags &= ~(MEM_Dyn|MEM_Static|MEM_Ephem);
- assert( srcType==MEM_Ephem || srcType==MEM_Static );
- pTo->flags |= srcType;
- }
-}
-
-/*
-** Make a full copy of pFrom into pTo. Prior contents of pTo are
-** freed before the copy is made.
-*/
-SQLITE_PRIVATE int sqlite3VdbeMemCopy(Mem *pTo, const Mem *pFrom){
- int rc = SQLITE_OK;
-
- assert( (pFrom->flags & MEM_RowSet)==0 );
- sqlite3VdbeMemReleaseExternal(pTo);
- memcpy(pTo, pFrom, MEMCELLSIZE);
- pTo->flags &= ~MEM_Dyn;
-
- if( pTo->flags&(MEM_Str|MEM_Blob) ){
- if( 0==(pFrom->flags&MEM_Static) ){
- pTo->flags |= MEM_Ephem;
- rc = sqlite3VdbeMemMakeWriteable(pTo);
- }
- }
-
- return rc;
-}
-
-/*
-** Transfer the contents of pFrom to pTo. Any existing value in pTo is
-** freed. If pFrom contains ephemeral data, a copy is made.
-**
-** pFrom contains an SQL NULL when this routine returns.
-*/
-SQLITE_PRIVATE void sqlite3VdbeMemMove(Mem *pTo, Mem *pFrom){
- assert( pFrom->db==0 || sqlite3_mutex_held(pFrom->db->mutex) );
- assert( pTo->db==0 || sqlite3_mutex_held(pTo->db->mutex) );
- assert( pFrom->db==0 || pTo->db==0 || pFrom->db==pTo->db );
-
- sqlite3VdbeMemRelease(pTo);
- memcpy(pTo, pFrom, sizeof(Mem));
- pFrom->flags = MEM_Null;
- pFrom->xDel = 0;
- pFrom->zMalloc = 0;
-}
-
-/*
-** Change the value of a Mem to be a string or a BLOB.
-**
-** The memory management strategy depends on the value of the xDel
-** parameter. If the value passed is SQLITE_TRANSIENT, then the
-** string is copied into a (possibly existing) buffer managed by the
-** Mem structure. Otherwise, any existing buffer is freed and the
-** pointer copied.
-**
-** If the string is too large (if it exceeds the SQLITE_LIMIT_LENGTH
-** size limit) then no memory allocation occurs. If the string can be
-** stored without allocating memory, then it is. If a memory allocation
-** is required to store the string, then value of pMem is unchanged. In
-** either case, SQLITE_TOOBIG is returned.
-*/
-SQLITE_PRIVATE int sqlite3VdbeMemSetStr(
- Mem *pMem, /* Memory cell to set to string value */
- const char *z, /* String pointer */
- int n, /* Bytes in string, or negative */
- u8 enc, /* Encoding of z. 0 for BLOBs */
- void (*xDel)(void*) /* Destructor function */
-){
- int nByte = n; /* New value for pMem->n */
- int iLimit; /* Maximum allowed string or blob size */
- u16 flags = 0; /* New value for pMem->flags */
-
- assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
- assert( (pMem->flags & MEM_RowSet)==0 );
-
- /* If z is a NULL pointer, set pMem to contain an SQL NULL. */
- if( !z ){
- sqlite3VdbeMemSetNull(pMem);
- return SQLITE_OK;
- }
-
- if( pMem->db ){
- iLimit = pMem->db->aLimit[SQLITE_LIMIT_LENGTH];
- }else{
- iLimit = SQLITE_MAX_LENGTH;
- }
- flags = (enc==0?MEM_Blob:MEM_Str);
- if( nByte<0 ){
- assert( enc!=0 );
- if( enc==SQLITE_UTF8 ){
- for(nByte=0; nByte<=iLimit && z[nByte]; nByte++){}
- }else{
- for(nByte=0; nByte<=iLimit && (z[nByte] | z[nByte+1]); nByte+=2){}
- }
- flags |= MEM_Term;
- }
-
- /* The following block sets the new values of Mem.z and Mem.xDel. It
- ** also sets a flag in local variable "flags" to indicate the memory
- ** management (one of MEM_Dyn or MEM_Static).
- */
- if( xDel==SQLITE_TRANSIENT ){
- int nAlloc = nByte;
- if( flags&MEM_Term ){
- nAlloc += (enc==SQLITE_UTF8?1:2);
- }
- if( nByte>iLimit ){
- return SQLITE_TOOBIG;
- }
- if( sqlite3VdbeMemGrow(pMem, nAlloc, 0) ){
- return SQLITE_NOMEM;
- }
- memcpy(pMem->z, z, nAlloc);
- }else if( xDel==SQLITE_DYNAMIC ){
- sqlite3VdbeMemRelease(pMem);
- pMem->zMalloc = pMem->z = (char *)z;
- pMem->xDel = 0;
- }else{
- sqlite3VdbeMemRelease(pMem);
- pMem->z = (char *)z;
- pMem->xDel = xDel;
- flags |= ((xDel==SQLITE_STATIC)?MEM_Static:MEM_Dyn);
- }
-
- pMem->n = nByte;
- pMem->flags = flags;
- pMem->enc = (enc==0 ? SQLITE_UTF8 : enc);
- pMem->type = (enc==0 ? SQLITE_BLOB : SQLITE_TEXT);
-
-#ifndef SQLITE_OMIT_UTF16
- if( pMem->enc!=SQLITE_UTF8 && sqlite3VdbeMemHandleBom(pMem) ){
- return SQLITE_NOMEM;
- }
-#endif
-
- if( nByte>iLimit ){
- return SQLITE_TOOBIG;
- }
-
- return SQLITE_OK;
-}
-
-/*
-** Compare the values contained by the two memory cells, returning
-** negative, zero or positive if pMem1 is less than, equal to, or greater
-** than pMem2. Sorting order is NULL's first, followed by numbers (integers
-** and reals) sorted numerically, followed by text ordered by the collating
-** sequence pColl and finally blob's ordered by memcmp().
-**
-** Two NULL values are considered equal by this function.
-*/
-SQLITE_PRIVATE int sqlite3MemCompare(const Mem *pMem1, const Mem *pMem2, const CollSeq *pColl){
- int rc;
- int f1, f2;
- int combined_flags;
-
- /* Interchange pMem1 and pMem2 if the collating sequence specifies
- ** DESC order.
- */
- f1 = pMem1->flags;
- f2 = pMem2->flags;
- combined_flags = f1|f2;
- assert( (combined_flags & MEM_RowSet)==0 );
-
- /* If one value is NULL, it is less than the other. If both values
- ** are NULL, return 0.
- */
- if( combined_flags&MEM_Null ){
- return (f2&MEM_Null) - (f1&MEM_Null);
- }
-
- /* If one value is a number and the other is not, the number is less.
- ** If both are numbers, compare as reals if one is a real, or as integers
- ** if both values are integers.
- */
- if( combined_flags&(MEM_Int|MEM_Real) ){
- if( !(f1&(MEM_Int|MEM_Real)) ){
- return 1;
- }
- if( !(f2&(MEM_Int|MEM_Real)) ){
- return -1;
- }
- if( (f1 & f2 & MEM_Int)==0 ){
- double r1, r2;
- if( (f1&MEM_Real)==0 ){
- r1 = (double)pMem1->u.i;
- }else{
- r1 = pMem1->r;
- }
- if( (f2&MEM_Real)==0 ){
- r2 = (double)pMem2->u.i;
- }else{
- r2 = pMem2->r;
- }
- if( r1<r2 ) return -1;
- if( r1>r2 ) return 1;
- return 0;
- }else{
- assert( f1&MEM_Int );
- assert( f2&MEM_Int );
- if( pMem1->u.i < pMem2->u.i ) return -1;
- if( pMem1->u.i > pMem2->u.i ) return 1;
- return 0;
- }
- }
-
- /* If one value is a string and the other is a blob, the string is less.
- ** If both are strings, compare using the collating functions.
- */
- if( combined_flags&MEM_Str ){
- if( (f1 & MEM_Str)==0 ){
- return 1;
- }
- if( (f2 & MEM_Str)==0 ){
- return -1;
- }
-
- assert( pMem1->enc==pMem2->enc );
- assert( pMem1->enc==SQLITE_UTF8 ||
- pMem1->enc==SQLITE_UTF16LE || pMem1->enc==SQLITE_UTF16BE );
-
- /* The collation sequence must be defined at this point, even if
- ** the user deletes the collation sequence after the vdbe program is
- ** compiled (this was not always the case).
- */
- assert( !pColl || pColl->xCmp );
-
- if( pColl ){
- if( pMem1->enc==pColl->enc ){
- /* The strings are already in the correct encoding. Call the
- ** comparison function directly */
- return pColl->xCmp(pColl->pUser,pMem1->n,pMem1->z,pMem2->n,pMem2->z);
- }else{
- const void *v1, *v2;
- int n1, n2;
- Mem c1;
- Mem c2;
- memset(&c1, 0, sizeof(c1));
- memset(&c2, 0, sizeof(c2));
- sqlite3VdbeMemShallowCopy(&c1, pMem1, MEM_Ephem);
- sqlite3VdbeMemShallowCopy(&c2, pMem2, MEM_Ephem);
- v1 = sqlite3ValueText((sqlite3_value*)&c1, pColl->enc);
- n1 = v1==0 ? 0 : c1.n;
- v2 = sqlite3ValueText((sqlite3_value*)&c2, pColl->enc);
- n2 = v2==0 ? 0 : c2.n;
- rc = pColl->xCmp(pColl->pUser, n1, v1, n2, v2);
- sqlite3VdbeMemRelease(&c1);
- sqlite3VdbeMemRelease(&c2);
- return rc;
- }
- }
- /* If a NULL pointer was passed as the collate function, fall through
- ** to the blob case and use memcmp(). */
- }
-
- /* Both values must be blobs. Compare using memcmp(). */
- rc = memcmp(pMem1->z, pMem2->z, (pMem1->n>pMem2->n)?pMem2->n:pMem1->n);
- if( rc==0 ){
- rc = pMem1->n - pMem2->n;
- }
- return rc;
-}
-
-/*
-** Move data out of a btree key or data field and into a Mem structure.
-** The data or key is taken from the entry that pCur is currently pointing
-** to. offset and amt determine what portion of the data or key to retrieve.
-** key is true to get the key or false to get data. The result is written
-** into the pMem element.
-**
-** The pMem structure is assumed to be uninitialized. Any prior content
-** is overwritten without being freed.
-**
-** If this routine fails for any reason (malloc returns NULL or unable
-** to read from the disk) then the pMem is left in an inconsistent state.
-*/
-SQLITE_PRIVATE int sqlite3VdbeMemFromBtree(
- BtCursor *pCur, /* Cursor pointing at record to retrieve. */
- int offset, /* Offset from the start of data to return bytes from. */
- int amt, /* Number of bytes to return. */
- int key, /* If true, retrieve from the btree key, not data. */
- Mem *pMem /* OUT: Return data in this Mem structure. */
-){
- char *zData; /* Data from the btree layer */
- int available = 0; /* Number of bytes available on the local btree page */
- int rc = SQLITE_OK; /* Return code */
-
- assert( sqlite3BtreeCursorIsValid(pCur) );
-
- /* Note: the calls to BtreeKeyFetch() and DataFetch() below assert()
- ** that both the BtShared and database handle mutexes are held. */
- assert( (pMem->flags & MEM_RowSet)==0 );
- if( key ){
- zData = (char *)sqlite3BtreeKeyFetch(pCur, &available);
- }else{
- zData = (char *)sqlite3BtreeDataFetch(pCur, &available);
- }
- assert( zData!=0 );
-
- if( offset+amt<=available && (pMem->flags&MEM_Dyn)==0 ){
- sqlite3VdbeMemRelease(pMem);
- pMem->z = &zData[offset];
- pMem->flags = MEM_Blob|MEM_Ephem;
- }else if( SQLITE_OK==(rc = sqlite3VdbeMemGrow(pMem, amt+2, 0)) ){
- pMem->flags = MEM_Blob|MEM_Dyn|MEM_Term;
- pMem->enc = 0;
- pMem->type = SQLITE_BLOB;
- if( key ){
- rc = sqlite3BtreeKey(pCur, offset, amt, pMem->z);
- }else{
- rc = sqlite3BtreeData(pCur, offset, amt, pMem->z);
- }
- pMem->z[amt] = 0;
- pMem->z[amt+1] = 0;
- if( rc!=SQLITE_OK ){
- sqlite3VdbeMemRelease(pMem);
- }
- }
- pMem->n = amt;
-
- return rc;
-}
-
-/* This function is only available internally, it is not part of the
-** external API. It works in a similar way to sqlite3_value_text(),
-** except the data returned is in the encoding specified by the second
-** parameter, which must be one of SQLITE_UTF16BE, SQLITE_UTF16LE or
-** SQLITE_UTF8.
-**
-** (2006-02-16:) The enc value can be or-ed with SQLITE_UTF16_ALIGNED.
-** If that is the case, then the result must be aligned on an even byte
-** boundary.
-*/
-SQLITE_PRIVATE const void *sqlite3ValueText(sqlite3_value* pVal, u8 enc){
- if( !pVal ) return 0;
-
- assert( pVal->db==0 || sqlite3_mutex_held(pVal->db->mutex) );
- assert( (enc&3)==(enc&~SQLITE_UTF16_ALIGNED) );
- assert( (pVal->flags & MEM_RowSet)==0 );
-
- if( pVal->flags&MEM_Null ){
- return 0;
- }
- assert( (MEM_Blob>>3) == MEM_Str );
- pVal->flags |= (pVal->flags & MEM_Blob)>>3;
- 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)) ){
- assert( (pVal->flags & (MEM_Ephem|MEM_Static))!=0 );
- if( sqlite3VdbeMemMakeWriteable(pVal)!=SQLITE_OK ){
- return 0;
- }
- }
- sqlite3VdbeMemNulTerminate(pVal);
- }else{
- assert( (pVal->flags&MEM_Blob)==0 );
- sqlite3VdbeMemStringify(pVal, enc);
- assert( 0==(1&SQLITE_PTR_TO_INT(pVal->z)) );
- }
- assert(pVal->enc==(enc & ~SQLITE_UTF16_ALIGNED) || pVal->db==0
- || pVal->db->mallocFailed );
- if( pVal->enc==(enc & ~SQLITE_UTF16_ALIGNED) ){
- return pVal->z;
- }else{
- return 0;
- }
-}
-
-/*
-** Create a new sqlite3_value object.
-*/
-SQLITE_PRIVATE sqlite3_value *sqlite3ValueNew(sqlite3 *db){
- Mem *p = sqlite3DbMallocZero(db, sizeof(*p));
- if( p ){
- p->flags = MEM_Null;
- p->type = SQLITE_NULL;
- p->db = db;
- }
- return p;
-}
-
-/*
-** Create a new sqlite3_value object, containing the value of pExpr.
-**
-** This only works for very simple expressions that consist of one constant
-** token (i.e. "5", "5.1", "'a string'"). If the expression can
-** be converted directly into a value, then the value is allocated and
-** a pointer written to *ppVal. The caller is responsible for deallocating
-** the value by passing it to sqlite3ValueFree() later on. If the expression
-** cannot be converted to a value, then *ppVal is set to NULL.
-*/
-SQLITE_PRIVATE int sqlite3ValueFromExpr(
- sqlite3 *db, /* The database connection */
- Expr *pExpr, /* The expression to evaluate */
- u8 enc, /* Encoding to use */
- u8 affinity, /* Affinity to use */
- sqlite3_value **ppVal /* Write the new value here */
-){
- int op;
- char *zVal = 0;
- sqlite3_value *pVal = 0;
-
- if( !pExpr ){
- *ppVal = 0;
- return SQLITE_OK;
- }
- op = pExpr->op;
- if( op==TK_REGISTER ){
- op = pExpr->op2;
- }
-
- if( op==TK_STRING || op==TK_FLOAT || op==TK_INTEGER ){
- pVal = sqlite3ValueNew(db);
- if( pVal==0 ) goto no_mem;
- if( ExprHasProperty(pExpr, EP_IntValue) ){
- sqlite3VdbeMemSetInt64(pVal, (i64)pExpr->u.iValue);
- }else{
- zVal = sqlite3DbStrDup(db, pExpr->u.zToken);
- if( zVal==0 ) goto no_mem;
- sqlite3ValueSetStr(pVal, -1, zVal, SQLITE_UTF8, SQLITE_DYNAMIC);
- if( op==TK_FLOAT ) pVal->type = SQLITE_FLOAT;
- }
- if( (op==TK_INTEGER || op==TK_FLOAT ) && affinity==SQLITE_AFF_NONE ){
- sqlite3ValueApplyAffinity(pVal, SQLITE_AFF_NUMERIC, SQLITE_UTF8);
- }else{
- sqlite3ValueApplyAffinity(pVal, affinity, SQLITE_UTF8);
- }
- if( enc!=SQLITE_UTF8 ){
- sqlite3VdbeChangeEncoding(pVal, enc);
- }
- }else if( op==TK_UMINUS ) {
- if( SQLITE_OK==sqlite3ValueFromExpr(db,pExpr->pLeft,enc,affinity,&pVal) ){
- pVal->u.i = -1 * pVal->u.i;
- /* (double)-1 In case of SQLITE_OMIT_FLOATING_POINT... */
- pVal->r = (double)-1 * pVal->r;
- }
- }
-#ifndef SQLITE_OMIT_BLOB_LITERAL
- else if( op==TK_BLOB ){
- int nVal;
- assert( pExpr->u.zToken[0]=='x' || pExpr->u.zToken[0]=='X' );
- assert( pExpr->u.zToken[1]=='\'' );
- pVal = sqlite3ValueNew(db);
- if( !pVal ) goto no_mem;
- zVal = &pExpr->u.zToken[2];
- nVal = sqlite3Strlen30(zVal)-1;
- assert( zVal[nVal]=='\'' );
- sqlite3VdbeMemSetStr(pVal, sqlite3HexToBlob(db, zVal, nVal), nVal/2,
- 0, SQLITE_DYNAMIC);
- }
-#endif
-
- *ppVal = pVal;
- return SQLITE_OK;
-
-no_mem:
- db->mallocFailed = 1;
- sqlite3DbFree(db, zVal);
- sqlite3ValueFree(pVal);
- *ppVal = 0;
- return SQLITE_NOMEM;
-}
-
-/*
-** Change the string value of an sqlite3_value object
-*/
-SQLITE_PRIVATE void sqlite3ValueSetStr(
- sqlite3_value *v, /* Value to be set */
- int n, /* Length of string z */
- const void *z, /* Text of the new string */
- u8 enc, /* Encoding to use */
- void (*xDel)(void*) /* Destructor for the string */
-){
- if( v ) sqlite3VdbeMemSetStr((Mem *)v, z, n, enc, xDel);
-}
-
-/*
-** Free an sqlite3_value object
-*/
-SQLITE_PRIVATE void sqlite3ValueFree(sqlite3_value *v){
- if( !v ) return;
- sqlite3VdbeMemRelease((Mem *)v);
- sqlite3DbFree(((Mem*)v)->db, v);
-}
-
-/*
-** Return the number of bytes in the sqlite3_value object assuming
-** that it uses the encoding "enc"
-*/
-SQLITE_PRIVATE int sqlite3ValueBytes(sqlite3_value *pVal, u8 enc){
- Mem *p = (Mem*)pVal;
- if( (p->flags & MEM_Blob)!=0 || sqlite3ValueText(pVal, enc) ){
- if( p->flags & MEM_Zero ){
- return p->n + p->u.nZero;
- }else{
- return p->n;
- }
- }
- return 0;
-}
-
-/************** End of vdbemem.c *********************************************/
-/************** Begin file vdbeaux.c *****************************************/
-/*
-** 2003 September 6
-**
-** 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 code used for creating, destroying, and populating
-** a VDBE (or an "sqlite3_stmt" as it is known to the outside world.) Prior
-** to version 2.8.7, all this code was combined into the vdbe.c source file.
-** But that file was getting too big so this subroutines were split out.
-**
-** $Id: vdbeaux.c,v 1.480 2009/08/08 18:01:08 drh Exp $
-*/
-
-
-
-/*
-** When debugging the code generator in a symbolic debugger, one can
-** set the sqlite3VdbeAddopTrace to 1 and all opcodes will be printed
-** as they are added to the instruction stream.
-*/
-#ifdef SQLITE_DEBUG
-SQLITE_PRIVATE int sqlite3VdbeAddopTrace = 0;
-#endif
-
-
-/*
-** Create a new virtual database engine.
-*/
-SQLITE_PRIVATE Vdbe *sqlite3VdbeCreate(sqlite3 *db){
- Vdbe *p;
- p = sqlite3DbMallocZero(db, sizeof(Vdbe) );
- if( p==0 ) return 0;
- p->db = db;
- if( db->pVdbe ){
- db->pVdbe->pPrev = p;
- }
- p->pNext = db->pVdbe;
- p->pPrev = 0;
- db->pVdbe = p;
- p->magic = VDBE_MAGIC_INIT;
- return p;
-}
-
-/*
-** Remember the SQL string for a prepared statement.
-*/
-SQLITE_PRIVATE void sqlite3VdbeSetSql(Vdbe *p, const char *z, int n, int isPrepareV2){
- if( p==0 ) return;
-#ifdef SQLITE_OMIT_TRACE
- if( !isPrepareV2 ) return;
-#endif
- assert( p->zSql==0 );
- p->zSql = sqlite3DbStrNDup(p->db, z, n);
- p->isPrepareV2 = isPrepareV2 ? 1 : 0;
-}
-
-/*
-** Return the SQL associated with a prepared statement
-*/
-SQLITE_API const char *sqlite3_sql(sqlite3_stmt *pStmt){
- Vdbe *p = (Vdbe *)pStmt;
- return (p->isPrepareV2 ? p->zSql : 0);
-}
-
-/*
-** Swap all content between two VDBE structures.
-*/
-SQLITE_PRIVATE void sqlite3VdbeSwap(Vdbe *pA, Vdbe *pB){
- Vdbe tmp, *pTmp;
- char *zTmp;
- tmp = *pA;
- *pA = *pB;
- *pB = tmp;
- pTmp = pA->pNext;
- pA->pNext = pB->pNext;
- pB->pNext = pTmp;
- pTmp = pA->pPrev;
- pA->pPrev = pB->pPrev;
- pB->pPrev = pTmp;
- zTmp = pA->zSql;
- pA->zSql = pB->zSql;
- pB->zSql = zTmp;
- pB->isPrepareV2 = pA->isPrepareV2;
-}
-
-#ifdef SQLITE_DEBUG
-/*
-** Turn tracing on or off
-*/
-SQLITE_PRIVATE void sqlite3VdbeTrace(Vdbe *p, FILE *trace){
- p->trace = trace;
-}
-#endif
-
-/*
-** Resize the Vdbe.aOp array so that it is at least one op larger than
-** it was.
-**
-** If an out-of-memory error occurs while resizing the array, return
-** SQLITE_NOMEM. In this case Vdbe.aOp and Vdbe.nOpAlloc remain
-** unchanged (this is so that any opcodes already allocated can be
-** correctly deallocated along with the rest of the Vdbe).
-*/
-static int growOpArray(Vdbe *p){
- VdbeOp *pNew;
- int nNew = (p->nOpAlloc ? p->nOpAlloc*2 : (int)(1024/sizeof(Op)));
- pNew = sqlite3DbRealloc(p->db, p->aOp, nNew*sizeof(Op));
- if( pNew ){
- p->nOpAlloc = sqlite3DbMallocSize(p->db, pNew)/sizeof(Op);
- p->aOp = pNew;
- }
- return (pNew ? SQLITE_OK : SQLITE_NOMEM);
-}
-
-/*
-** Add a new instruction to the list of instructions current in the
-** VDBE. Return the address of the new instruction.
-**
-** Parameters:
-**
-** p Pointer to the VDBE
-**
-** op The opcode for this instruction
-**
-** p1, p2, p3 Operands
-**
-** Use the sqlite3VdbeResolveLabel() function to fix an address and
-** the sqlite3VdbeChangeP4() function to change the value of the P4
-** operand.
-*/
-SQLITE_PRIVATE int sqlite3VdbeAddOp3(Vdbe *p, int op, int p1, int p2, int p3){
- int i;
- VdbeOp *pOp;
-
- i = p->nOp;
- assert( p->magic==VDBE_MAGIC_INIT );
- assert( op>0 && op<0xff );
- if( p->nOpAlloc<=i ){
- if( growOpArray(p) ){
- return 1;
- }
- }
- p->nOp++;
- pOp = &p->aOp[i];
- pOp->opcode = (u8)op;
- pOp->p5 = 0;
- pOp->p1 = p1;
- pOp->p2 = p2;
- pOp->p3 = p3;
- pOp->p4.p = 0;
- pOp->p4type = P4_NOTUSED;
- p->expired = 0;
-#ifdef SQLITE_DEBUG
- pOp->zComment = 0;
- if( sqlite3VdbeAddopTrace ) sqlite3VdbePrintOp(0, i, &p->aOp[i]);
-#endif
-#ifdef VDBE_PROFILE
- pOp->cycles = 0;
- pOp->cnt = 0;
-#endif
- return i;
-}
-SQLITE_PRIVATE int sqlite3VdbeAddOp0(Vdbe *p, int op){
- return sqlite3VdbeAddOp3(p, op, 0, 0, 0);
-}
-SQLITE_PRIVATE int sqlite3VdbeAddOp1(Vdbe *p, int op, int p1){
- return sqlite3VdbeAddOp3(p, op, p1, 0, 0);
-}
-SQLITE_PRIVATE int sqlite3VdbeAddOp2(Vdbe *p, int op, int p1, int p2){
- return sqlite3VdbeAddOp3(p, op, p1, p2, 0);
-}
-
-
-/*
-** Add an opcode that includes the p4 value as a pointer.
-*/
-SQLITE_PRIVATE int sqlite3VdbeAddOp4(
- Vdbe *p, /* Add the opcode to this VM */
- int op, /* The new opcode */
- int p1, /* The P1 operand */
- int p2, /* The P2 operand */
- int p3, /* The P3 operand */
- const char *zP4, /* The P4 operand */
- int p4type /* P4 operand type */
-){
- int addr = sqlite3VdbeAddOp3(p, op, p1, p2, p3);
- sqlite3VdbeChangeP4(p, addr, zP4, p4type);
- return addr;
-}
-
-/*
-** Create a new symbolic label for an instruction that has yet to be
-** coded. The symbolic label is really just a negative number. The
-** label can be used as the P2 value of an operation. Later, when
-** the label is resolved to a specific address, the VDBE will scan
-** through its operation list and change all values of P2 which match
-** the label into the resolved address.
-**
-** The VDBE knows that a P2 value is a label because labels are
-** always negative and P2 values are suppose to be non-negative.
-** Hence, a negative P2 value is a label that has yet to be resolved.
-**
-** Zero is returned if a malloc() fails.
-*/
-SQLITE_PRIVATE int sqlite3VdbeMakeLabel(Vdbe *p){
- int i;
- i = p->nLabel++;
- assert( p->magic==VDBE_MAGIC_INIT );
- if( i>=p->nLabelAlloc ){
- int n = p->nLabelAlloc*2 + 5;
- p->aLabel = sqlite3DbReallocOrFree(p->db, p->aLabel,
- n*sizeof(p->aLabel[0]));
- p->nLabelAlloc = sqlite3DbMallocSize(p->db, p->aLabel)/sizeof(p->aLabel[0]);
- }
- if( p->aLabel ){
- p->aLabel[i] = -1;
- }
- return -1-i;
-}
-
-/*
-** Resolve label "x" to be the address of the next instruction to
-** be inserted. The parameter "x" must have been obtained from
-** a prior call to sqlite3VdbeMakeLabel().
-*/
-SQLITE_PRIVATE void sqlite3VdbeResolveLabel(Vdbe *p, int x){
- int j = -1-x;
- assert( p->magic==VDBE_MAGIC_INIT );
- assert( j>=0 && j<p->nLabel );
- if( p->aLabel ){
- p->aLabel[j] = p->nOp;
- }
-}
-
-#ifdef SQLITE_DEBUG
-
-/*
-** The following type and function are used to iterate through all opcodes
-** in a Vdbe main program and each of the sub-programs (triggers) it may
-** invoke directly or indirectly. It should be used as follows:
-**
-** Op *pOp;
-** VdbeOpIter sIter;
-**
-** memset(&sIter, 0, sizeof(sIter));
-** sIter.v = v; // v is of type Vdbe*
-** while( (pOp = opIterNext(&sIter)) ){
-** // Do something with pOp
-** }
-** sqlite3DbFree(v->db, sIter.apSub);
-**
-*/
-typedef struct VdbeOpIter VdbeOpIter;
-struct VdbeOpIter {
- Vdbe *v; /* Vdbe to iterate through the opcodes of */
- SubProgram **apSub; /* Array of subprograms */
- int nSub; /* Number of entries in apSub */
- int iAddr; /* Address of next instruction to return */
- int iSub; /* 0 = main program, 1 = first sub-program etc. */
-};
-static Op *opIterNext(VdbeOpIter *p){
- Vdbe *v = p->v;
- Op *pRet = 0;
- Op *aOp;
- int nOp;
-
- if( p->iSub<=p->nSub ){
-
- if( p->iSub==0 ){
- aOp = v->aOp;
- nOp = v->nOp;
- }else{
- aOp = p->apSub[p->iSub-1]->aOp;
- nOp = p->apSub[p->iSub-1]->nOp;
- }
- assert( p->iAddr<nOp );
-
- pRet = &aOp[p->iAddr];
- p->iAddr++;
- if( p->iAddr==nOp ){
- p->iSub++;
- p->iAddr = 0;
- }
-
- if( pRet->p4type==P4_SUBPROGRAM ){
- int nByte = (p->nSub+1)*sizeof(SubProgram*);
- int j;
- for(j=0; j<p->nSub; j++){
- if( p->apSub[j]==pRet->p4.pProgram ) break;
- }
- if( j==p->nSub ){
- p->apSub = sqlite3DbReallocOrFree(v->db, p->apSub, nByte);
- if( !p->apSub ){
- pRet = 0;
- }else{
- p->apSub[p->nSub++] = pRet->p4.pProgram;
- }
- }
- }
- }
-
- return pRet;
-}
-
-/*
-** Check if the program stored in the VM associated with pParse may
-** throw an ABORT exception (causing the statement, but not transaction
-** to be rolled back). This condition is true if the main program or any
-** sub-programs contains any of the following:
-**
-** * OP_Halt with P1=SQLITE_CONSTRAINT and P2=OE_Abort.
-** * OP_HaltIfNull with P1=SQLITE_CONSTRAINT and P2=OE_Abort.
-** * OP_Destroy
-** * OP_VUpdate
-** * OP_VRename
-**
-** Then check that the value of Parse.mayAbort is true if an
-** ABORT may be thrown, or false otherwise. Return true if it does
-** match, or false otherwise. This function is intended to be used as
-** part of an assert statement in the compiler. Similar to:
-**
-** assert( sqlite3VdbeAssertMayAbort(pParse->pVdbe, pParse->mayAbort) );
-*/
-SQLITE_PRIVATE int sqlite3VdbeAssertMayAbort(Vdbe *v, int mayAbort){
- int hasAbort = 0;
- Op *pOp;
- VdbeOpIter sIter;
- memset(&sIter, 0, sizeof(sIter));
- sIter.v = v;
-
- while( (pOp = opIterNext(&sIter))!=0 ){
- int opcode = pOp->opcode;
- if( opcode==OP_Destroy || opcode==OP_VUpdate || opcode==OP_VRename
- || ((opcode==OP_Halt || opcode==OP_HaltIfNull)
- && (pOp->p1==SQLITE_CONSTRAINT && pOp->p2==OE_Abort))
- ){
- hasAbort = 1;
- break;
- }
- }
- sqlite3DbFree(v->db, sIter.apSub);
-
- /* Return true if hasAbort==mayAbort. Or if a malloc failure occured.
- ** If malloc failed, then the while() loop above may not have iterated
- ** through all opcodes and hasAbort may be set incorrectly. Return
- ** true for this case to prevent the assert() in the callers frame
- ** from failing. */
- return ( v->db->mallocFailed || hasAbort==mayAbort );
-}
-#endif
-
-/*
-** Loop through the program looking for P2 values that are negative
-** on jump instructions. Each such value is a label. Resolve the
-** label by setting the P2 value to its correct non-zero value.
-**
-** This routine is called once after all opcodes have been inserted.
-**
-** Variable *pMaxFuncArgs is set to the maximum value of any P2 argument
-** to an OP_Function, OP_AggStep or OP_VFilter opcode. This is used by
-** sqlite3VdbeMakeReady() to size the Vdbe.apArg[] array.
-*/
-static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){
- int i;
- int nMaxArgs = *pMaxFuncArgs;
- Op *pOp;
- int *aLabel = p->aLabel;
- p->readOnly = 1;
- for(pOp=p->aOp, i=p->nOp-1; i>=0; i--, pOp++){
- u8 opcode = pOp->opcode;
-
- if( opcode==OP_Function || opcode==OP_AggStep ){
- if( pOp->p5>nMaxArgs ) nMaxArgs = pOp->p5;
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- }else if( opcode==OP_VUpdate ){
- if( pOp->p2>nMaxArgs ) nMaxArgs = pOp->p2;
-#endif
- }else if( opcode==OP_Transaction && pOp->p2!=0 ){
- p->readOnly = 0;
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- }else if( opcode==OP_VFilter ){
- int n;
- assert( p->nOp - i >= 3 );
- assert( pOp[-1].opcode==OP_Integer );
- n = pOp[-1].p1;
- if( n>nMaxArgs ) nMaxArgs = n;
-#endif
- }
-
- if( sqlite3VdbeOpcodeHasProperty(opcode, OPFLG_JUMP) && pOp->p2<0 ){
- assert( -1-pOp->p2<p->nLabel );
- pOp->p2 = aLabel[-1-pOp->p2];
- }
- }
- sqlite3DbFree(p->db, p->aLabel);
- p->aLabel = 0;
-
- *pMaxFuncArgs = nMaxArgs;
-}
-
-/*
-** Return the address of the next instruction to be inserted.
-*/
-SQLITE_PRIVATE int sqlite3VdbeCurrentAddr(Vdbe *p){
- assert( p->magic==VDBE_MAGIC_INIT );
- return p->nOp;
-}
-
-/*
-** This function returns a pointer to the array of opcodes associated with
-** the Vdbe passed as the first argument. It is the callers responsibility
-** to arrange for the returned array to be eventually freed using the
-** vdbeFreeOpArray() function.
-**
-** Before returning, *pnOp is set to the number of entries in the returned
-** array. Also, *pnMaxArg is set to the larger of its current value and
-** the number of entries in the Vdbe.apArg[] array required to execute the
-** returned program.
-*/
-SQLITE_PRIVATE VdbeOp *sqlite3VdbeTakeOpArray(Vdbe *p, int *pnOp, int *pnMaxArg){
- VdbeOp *aOp = p->aOp;
- assert( aOp && !p->db->mallocFailed );
-
- /* Check that sqlite3VdbeUsesBtree() was not called on this VM */
- assert( p->aMutex.nMutex==0 );
-
- resolveP2Values(p, pnMaxArg);
- *pnOp = p->nOp;
- p->aOp = 0;
- return aOp;
-}
-
-/*
-** Add a whole list of operations to the operation stack. Return the
-** address of the first operation added.
-*/
-SQLITE_PRIVATE int sqlite3VdbeAddOpList(Vdbe *p, int nOp, VdbeOpList const *aOp){
- int addr;
- assert( p->magic==VDBE_MAGIC_INIT );
- if( p->nOp + nOp > p->nOpAlloc && growOpArray(p) ){
- return 0;
- }
- addr = p->nOp;
- if( ALWAYS(nOp>0) ){
- int i;
- VdbeOpList const *pIn = aOp;
- for(i=0; i<nOp; i++, pIn++){
- int p2 = pIn->p2;
- VdbeOp *pOut = &p->aOp[i+addr];
- pOut->opcode = pIn->opcode;
- pOut->p1 = pIn->p1;
- if( p2<0 && sqlite3VdbeOpcodeHasProperty(pOut->opcode, OPFLG_JUMP) ){
- pOut->p2 = addr + ADDR(p2);
- }else{
- pOut->p2 = p2;
- }
- pOut->p3 = pIn->p3;
- pOut->p4type = P4_NOTUSED;
- pOut->p4.p = 0;
- pOut->p5 = 0;
-#ifdef SQLITE_DEBUG
- pOut->zComment = 0;
- if( sqlite3VdbeAddopTrace ){
- sqlite3VdbePrintOp(0, i+addr, &p->aOp[i+addr]);
- }
-#endif
- }
- p->nOp += nOp;
- }
- return addr;
-}
-
-/*
-** Change the value of the P1 operand for a specific instruction.
-** This routine is useful when a large program is loaded from a
-** static array using sqlite3VdbeAddOpList but we want to make a
-** few minor changes to the program.
-*/
-SQLITE_PRIVATE void sqlite3VdbeChangeP1(Vdbe *p, int addr, int val){
- assert( p!=0 );
- assert( addr>=0 );
- if( p->nOp>addr ){
- p->aOp[addr].p1 = val;
- }
-}
-
-/*
-** Change the value of the P2 operand for a specific instruction.
-** This routine is useful for setting a jump destination.
-*/
-SQLITE_PRIVATE void sqlite3VdbeChangeP2(Vdbe *p, int addr, int val){
- assert( p!=0 );
- assert( addr>=0 );
- if( p->nOp>addr ){
- p->aOp[addr].p2 = val;
- }
-}
-
-/*
-** Change the value of the P3 operand for a specific instruction.
-*/
-SQLITE_PRIVATE void sqlite3VdbeChangeP3(Vdbe *p, int addr, int val){
- assert( p!=0 );
- assert( addr>=0 );
- if( p->nOp>addr ){
- p->aOp[addr].p3 = val;
- }
-}
-
-/*
-** Change the value of the P5 operand for the most recently
-** added operation.
-*/
-SQLITE_PRIVATE void sqlite3VdbeChangeP5(Vdbe *p, u8 val){
- assert( p!=0 );
- if( p->aOp ){
- assert( p->nOp>0 );
- p->aOp[p->nOp-1].p5 = val;
- }
-}
-
-/*
-** Change the P2 operand of instruction addr so that it points to
-** the address of the next instruction to be coded.
-*/
-SQLITE_PRIVATE void sqlite3VdbeJumpHere(Vdbe *p, int addr){
- sqlite3VdbeChangeP2(p, addr, p->nOp);
-}
-
-
-/*
-** If the input FuncDef structure is ephemeral, then free it. If
-** the FuncDef is not ephermal, then do nothing.
-*/
-static void freeEphemeralFunction(sqlite3 *db, FuncDef *pDef){
- if( ALWAYS(pDef) && (pDef->flags & SQLITE_FUNC_EPHEM)!=0 ){
- sqlite3DbFree(db, pDef);
- }
-}
-
-/*
-** Delete a P4 value if necessary.
-*/
-static void freeP4(sqlite3 *db, int p4type, void *p4){
- if( p4 ){
- switch( p4type ){
- case P4_REAL:
- case P4_INT64:
- case P4_MPRINTF:
- case P4_DYNAMIC:
- case P4_KEYINFO:
- case P4_INTARRAY:
- case P4_KEYINFO_HANDOFF: {
- sqlite3DbFree(db, p4);
- break;
- }
- case P4_VDBEFUNC: {
- VdbeFunc *pVdbeFunc = (VdbeFunc *)p4;
- freeEphemeralFunction(db, pVdbeFunc->pFunc);
- sqlite3VdbeDeleteAuxData(pVdbeFunc, 0);
- sqlite3DbFree(db, pVdbeFunc);
- break;
- }
- case P4_FUNCDEF: {
- freeEphemeralFunction(db, (FuncDef*)p4);
- break;
- }
- case P4_MEM: {
- sqlite3ValueFree((sqlite3_value*)p4);
- break;
- }
- case P4_VTAB : {
- sqlite3VtabUnlock((VTable *)p4);
- break;
- }
- case P4_SUBPROGRAM : {
- sqlite3VdbeProgramDelete(db, (SubProgram *)p4, 1);
- break;
- }
- }
- }
-}
-
-/*
-** Free the space allocated for aOp and any p4 values allocated for the
-** opcodes contained within. If aOp is not NULL it is assumed to contain
-** nOp entries.
-*/
-static void vdbeFreeOpArray(sqlite3 *db, Op *aOp, int nOp){
- if( aOp ){
- Op *pOp;
- for(pOp=aOp; pOp<&aOp[nOp]; pOp++){
- freeP4(db, pOp->p4type, pOp->p4.p);
-#ifdef SQLITE_DEBUG
- sqlite3DbFree(db, pOp->zComment);
-#endif
- }
- }
- sqlite3DbFree(db, aOp);
-}
-
-/*
-** Decrement the ref-count on the SubProgram structure passed as the
-** second argument. If the ref-count reaches zero, free the structure.
-**
-** The array of VDBE opcodes stored as SubProgram.aOp is freed if
-** either the ref-count reaches zero or parameter freeop is non-zero.
-**
-** Since the array of opcodes pointed to by SubProgram.aOp may directly
-** or indirectly contain a reference to the SubProgram structure itself.
-** By passing a non-zero freeop parameter, the caller may ensure that all
-** SubProgram structures and their aOp arrays are freed, even when there
-** are such circular references.
-*/
-SQLITE_PRIVATE void sqlite3VdbeProgramDelete(sqlite3 *db, SubProgram *p, int freeop){
- if( p ){
- assert( p->nRef>0 );
- if( freeop || p->nRef==1 ){
- Op *aOp = p->aOp;
- p->aOp = 0;
- vdbeFreeOpArray(db, aOp, p->nOp);
- p->nOp = 0;
- }
- p->nRef--;
- if( p->nRef==0 ){
- sqlite3DbFree(db, p);
- }
- }
-}
-
-
-/*
-** Change N opcodes starting at addr to No-ops.
-*/
-SQLITE_PRIVATE void sqlite3VdbeChangeToNoop(Vdbe *p, int addr, int N){
- if( p->aOp ){
- VdbeOp *pOp = &p->aOp[addr];
- sqlite3 *db = p->db;
- while( N-- ){
- freeP4(db, pOp->p4type, pOp->p4.p);
- memset(pOp, 0, sizeof(pOp[0]));
- pOp->opcode = OP_Noop;
- pOp++;
- }
- }
-}
-
-/*
-** Change the value of the P4 operand for a specific instruction.
-** This routine is useful when a large program is loaded from a
-** static array using sqlite3VdbeAddOpList but we want to make a
-** few minor changes to the program.
-**
-** If n>=0 then the P4 operand is dynamic, meaning that a copy of
-** the string is made into memory obtained from sqlite3_malloc().
-** A value of n==0 means copy bytes of zP4 up to and including the
-** first null byte. If n>0 then copy n+1 bytes of zP4.
-**
-** If n==P4_KEYINFO it means that zP4 is a pointer to a KeyInfo structure.
-** A copy is made of the KeyInfo structure into memory obtained from
-** sqlite3_malloc, to be freed when the Vdbe is finalized.
-** n==P4_KEYINFO_HANDOFF indicates that zP4 points to a KeyInfo structure
-** stored in memory that the caller has obtained from sqlite3_malloc. The
-** caller should not free the allocation, it will be freed when the Vdbe is
-** finalized.
-**
-** Other values of n (P4_STATIC, P4_COLLSEQ etc.) indicate that zP4 points
-** to a string or structure that is guaranteed to exist for the lifetime of
-** the Vdbe. In these cases we can just copy the pointer.
-**
-** If addr<0 then change P4 on the most recently inserted instruction.
-*/
-SQLITE_PRIVATE void sqlite3VdbeChangeP4(Vdbe *p, int addr, const char *zP4, int n){
- Op *pOp;
- sqlite3 *db;
- assert( p!=0 );
- db = p->db;
- assert( p->magic==VDBE_MAGIC_INIT );
- if( p->aOp==0 || db->mallocFailed ){
- if ( n!=P4_KEYINFO && n!=P4_VTAB ) {
- freeP4(db, n, (void*)*(char**)&zP4);
- }
- return;
- }
- assert( p->nOp>0 );
- assert( addr<p->nOp );
- if( addr<0 ){
- addr = p->nOp - 1;
- }
- pOp = &p->aOp[addr];
- freeP4(db, pOp->p4type, pOp->p4.p);
- pOp->p4.p = 0;
- if( n==P4_INT32 ){
- /* Note: this cast is safe, because the origin data point was an int
- ** that was cast to a (const char *). */
- pOp->p4.i = SQLITE_PTR_TO_INT(zP4);
- pOp->p4type = P4_INT32;
- }else if( zP4==0 ){
- pOp->p4.p = 0;
- pOp->p4type = P4_NOTUSED;
- }else if( n==P4_KEYINFO ){
- KeyInfo *pKeyInfo;
- int nField, nByte;
-
- nField = ((KeyInfo*)zP4)->nField;
- nByte = sizeof(*pKeyInfo) + (nField-1)*sizeof(pKeyInfo->aColl[0]) + nField;
- pKeyInfo = sqlite3Malloc( nByte );
- pOp->p4.pKeyInfo = pKeyInfo;
- if( pKeyInfo ){
- u8 *aSortOrder;
- memcpy(pKeyInfo, zP4, nByte);
- aSortOrder = pKeyInfo->aSortOrder;
- if( aSortOrder ){
- pKeyInfo->aSortOrder = (unsigned char*)&pKeyInfo->aColl[nField];
- memcpy(pKeyInfo->aSortOrder, aSortOrder, nField);
- }
- pOp->p4type = P4_KEYINFO;
- }else{
- p->db->mallocFailed = 1;
- pOp->p4type = P4_NOTUSED;
- }
- }else if( n==P4_KEYINFO_HANDOFF ){
- pOp->p4.p = (void*)zP4;
- pOp->p4type = P4_KEYINFO;
- }else if( n==P4_VTAB ){
- pOp->p4.p = (void*)zP4;
- pOp->p4type = P4_VTAB;
- sqlite3VtabLock((VTable *)zP4);
- assert( ((VTable *)zP4)->db==p->db );
- }else if( n<0 ){
- pOp->p4.p = (void*)zP4;
- pOp->p4type = (signed char)n;
- }else{
- if( n==0 ) n = sqlite3Strlen30(zP4);
- pOp->p4.z = sqlite3DbStrNDup(p->db, zP4, n);
- pOp->p4type = P4_DYNAMIC;
- }
-}
-
-#ifndef NDEBUG
-/*
-** Change the comment on the the most recently coded instruction. Or
-** insert a No-op and add the comment to that new instruction. This
-** makes the code easier to read during debugging. None of this happens
-** in a production build.
-*/
-SQLITE_PRIVATE void sqlite3VdbeComment(Vdbe *p, const char *zFormat, ...){
- va_list ap;
- if( !p ) return;
- assert( p->nOp>0 || p->aOp==0 );
- assert( p->aOp==0 || p->aOp[p->nOp-1].zComment==0 || p->db->mallocFailed );
- if( p->nOp ){
- char **pz = &p->aOp[p->nOp-1].zComment;
- va_start(ap, zFormat);
- sqlite3DbFree(p->db, *pz);
- *pz = sqlite3VMPrintf(p->db, zFormat, ap);
- va_end(ap);
- }
-}
-SQLITE_PRIVATE void sqlite3VdbeNoopComment(Vdbe *p, const char *zFormat, ...){
- va_list ap;
- if( !p ) return;
- sqlite3VdbeAddOp0(p, OP_Noop);
- assert( p->nOp>0 || p->aOp==0 );
- assert( p->aOp==0 || p->aOp[p->nOp-1].zComment==0 || p->db->mallocFailed );
- if( p->nOp ){
- char **pz = &p->aOp[p->nOp-1].zComment;
- va_start(ap, zFormat);
- sqlite3DbFree(p->db, *pz);
- *pz = sqlite3VMPrintf(p->db, zFormat, ap);
- va_end(ap);
- }
-}
-#endif /* NDEBUG */
-
-/*
-** Return the opcode for a given address. If the address is -1, then
-** return the most recently inserted opcode.
-**
-** If a memory allocation error has occurred prior to the calling of this
-** routine, then a pointer to a dummy VdbeOp will be returned. That opcode
-** is readable and writable, but it has no effect. The return of a dummy
-** opcode allows the call to continue functioning after a OOM fault without
-** having to check to see if the return from this routine is a valid pointer.
-**
-** About the #ifdef SQLITE_OMIT_TRACE: Normally, this routine is never called
-** unless p->nOp>0. This is because in the absense of SQLITE_OMIT_TRACE,
-** an OP_Trace instruction is always inserted by sqlite3VdbeGet() as soon as
-** a new VDBE is created. So we are free to set addr to p->nOp-1 without
-** having to double-check to make sure that the result is non-negative. But
-** if SQLITE_OMIT_TRACE is defined, the OP_Trace is omitted and we do need to
-** check the value of p->nOp-1 before continuing.
-*/
-SQLITE_PRIVATE VdbeOp *sqlite3VdbeGetOp(Vdbe *p, int addr){
- static VdbeOp dummy;
- assert( p->magic==VDBE_MAGIC_INIT );
- if( addr<0 ){
-#ifdef SQLITE_OMIT_TRACE
- if( p->nOp==0 ) return &dummy;
-#endif
- addr = p->nOp - 1;
- }
- assert( (addr>=0 && addr<p->nOp) || p->db->mallocFailed );
- if( p->db->mallocFailed ){
- return &dummy;
- }else{
- return &p->aOp[addr];
- }
-}
-
-#if !defined(SQLITE_OMIT_EXPLAIN) || !defined(NDEBUG) \
- || defined(VDBE_PROFILE) || defined(SQLITE_DEBUG)
-/*
-** Compute a string that describes the P4 parameter for an opcode.
-** Use zTemp for any required temporary buffer space.
-*/
-static char *displayP4(Op *pOp, char *zTemp, int nTemp){
- char *zP4 = zTemp;
- assert( nTemp>=20 );
- switch( pOp->p4type ){
- case P4_KEYINFO_STATIC:
- case P4_KEYINFO: {
- int i, j;
- KeyInfo *pKeyInfo = pOp->p4.pKeyInfo;
- sqlite3_snprintf(nTemp, zTemp, "keyinfo(%d", pKeyInfo->nField);
- i = sqlite3Strlen30(zTemp);
- for(j=0; j<pKeyInfo->nField; j++){
- CollSeq *pColl = pKeyInfo->aColl[j];
- if( pColl ){
- int n = sqlite3Strlen30(pColl->zName);
- if( i+n>nTemp-6 ){
- memcpy(&zTemp[i],",...",4);
- break;
- }
- zTemp[i++] = ',';
- if( pKeyInfo->aSortOrder && pKeyInfo->aSortOrder[j] ){
- zTemp[i++] = '-';
- }
- memcpy(&zTemp[i], pColl->zName,n+1);
- i += n;
- }else if( i+4<nTemp-6 ){
- memcpy(&zTemp[i],",nil",4);
- i += 4;
- }
- }
- zTemp[i++] = ')';
- zTemp[i] = 0;
- assert( i<nTemp );
- break;
- }
- case P4_COLLSEQ: {
- CollSeq *pColl = pOp->p4.pColl;
- sqlite3_snprintf(nTemp, zTemp, "collseq(%.20s)", pColl->zName);
- break;
- }
- case P4_FUNCDEF: {
- FuncDef *pDef = pOp->p4.pFunc;
- sqlite3_snprintf(nTemp, zTemp, "%s(%d)", pDef->zName, pDef->nArg);
- break;
- }
- case P4_INT64: {
- sqlite3_snprintf(nTemp, zTemp, "%lld", *pOp->p4.pI64);
- break;
- }
- case P4_INT32: {
- sqlite3_snprintf(nTemp, zTemp, "%d", pOp->p4.i);
- break;
- }
- case P4_REAL: {
- sqlite3_snprintf(nTemp, zTemp, "%.16g", *pOp->p4.pReal);
- break;
- }
- 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{
- assert( pMem->flags & MEM_Blob );
- zP4 = "(blob)";
- }
- break;
- }
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- case P4_VTAB: {
- sqlite3_vtab *pVtab = pOp->p4.pVtab->pVtab;
- sqlite3_snprintf(nTemp, zTemp, "vtab:%p:%p", pVtab, pVtab->pModule);
- break;
- }
-#endif
- case P4_INTARRAY: {
- sqlite3_snprintf(nTemp, zTemp, "intarray");
- break;
- }
- case P4_SUBPROGRAM: {
- sqlite3_snprintf(nTemp, zTemp, "program");
- break;
- }
- default: {
- zP4 = pOp->p4.z;
- if( zP4==0 ){
- zP4 = zTemp;
- zTemp[0] = 0;
- }
- }
- }
- assert( zP4!=0 );
- return zP4;
-}
-#endif
-
-/*
-** Declare to the Vdbe that the BTree object at db->aDb[i] is used.
-*/
-SQLITE_PRIVATE void sqlite3VdbeUsesBtree(Vdbe *p, int i){
- int mask;
- assert( i>=0 && i<p->db->nDb && i<sizeof(u32)*8 );
- assert( i<(int)sizeof(p->btreeMask)*8 );
- mask = ((u32)1)<<i;
- if( (p->btreeMask & mask)==0 ){
- p->btreeMask |= mask;
- sqlite3BtreeMutexArrayInsert(&p->aMutex, p->db->aDb[i].pBt);
- }
-}
-
-
-#if defined(VDBE_PROFILE) || defined(SQLITE_DEBUG)
-/*
-** Print a single opcode. This routine is used for debugging only.
-*/
-SQLITE_PRIVATE void sqlite3VdbePrintOp(FILE *pOut, int pc, Op *pOp){
- char *zP4;
- char zPtr[50];
- static const char *zFormat1 = "%4d %-13s %4d %4d %4d %-4s %.2X %s\n";
- if( pOut==0 ) pOut = stdout;
- zP4 = displayP4(pOp, zPtr, sizeof(zPtr));
- fprintf(pOut, zFormat1, pc,
- sqlite3OpcodeName(pOp->opcode), pOp->p1, pOp->p2, pOp->p3, zP4, pOp->p5,
-#ifdef SQLITE_DEBUG
- pOp->zComment ? pOp->zComment : ""
-#else
- ""
-#endif
- );
- fflush(pOut);
-}
-#endif
-
-/*
-** Release an array of N Mem elements
-*/
-static void releaseMemArray(Mem *p, int N){
- if( p && N ){
- Mem *pEnd;
- sqlite3 *db = p->db;
- u8 malloc_failed = db->mallocFailed;
- for(pEnd=&p[N]; p<pEnd; p++){
- assert( (&p[1])==pEnd || p[0].db==p[1].db );
-
- /* This block is really an inlined version of sqlite3VdbeMemRelease()
- ** that takes advantage of the fact that the memory cell value is
- ** being set to NULL after releasing any dynamic resources.
- **
- ** The justification for duplicating code is that according to
- ** callgrind, this causes a certain test case to hit the CPU 4.7
- ** percent less (x86 linux, gcc version 4.1.2, -O6) than if
- ** sqlite3MemRelease() were called from here. With -O2, this jumps
- ** to 6.6 percent. The test case is inserting 1000 rows into a table
- ** with no indexes using a single prepared INSERT statement, bind()
- ** and reset(). Inserts are grouped into a transaction.
- */
- if( p->flags&(MEM_Agg|MEM_Dyn|MEM_Frame|MEM_RowSet) ){
- sqlite3VdbeMemRelease(p);
- }else if( p->zMalloc ){
- sqlite3DbFree(db, p->zMalloc);
- p->zMalloc = 0;
- }
-
- p->flags = MEM_Null;
- }
- db->mallocFailed = malloc_failed;
- }
-}
-
-/*
-** Delete a VdbeFrame object and its contents. VdbeFrame objects are
-** allocated by the OP_Program opcode in sqlite3VdbeExec().
-*/
-SQLITE_PRIVATE void sqlite3VdbeFrameDelete(VdbeFrame *p){
- int i;
- Mem *aMem = VdbeFrameMem(p);
- VdbeCursor **apCsr = (VdbeCursor **)&aMem[p->nChildMem];
- for(i=0; i<p->nChildCsr; i++){
- sqlite3VdbeFreeCursor(p->v, apCsr[i]);
- }
- releaseMemArray(aMem, p->nChildMem);
- sqlite3DbFree(p->v->db, p);
-}
-
-
-#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
-SQLITE_PRIVATE int sqlite3VdbeReleaseBuffers(Vdbe *p){
- int ii;
- int nFree = 0;
- assert( sqlite3_mutex_held(p->db->mutex) );
- for(ii=1; ii<=p->nMem; ii++){
- Mem *pMem = &p->aMem[ii];
- if( pMem->flags & MEM_RowSet ){
- sqlite3RowSetClear(pMem->u.pRowSet);
- }
- if( pMem->z && pMem->flags&MEM_Dyn ){
- assert( !pMem->xDel );
- nFree += sqlite3DbMallocSize(pMem->db, pMem->z);
- sqlite3VdbeMemRelease(pMem);
- }
- }
- return nFree;
-}
-#endif
-
-#ifndef SQLITE_OMIT_EXPLAIN
-/*
-** Give a listing of the program in the virtual machine.
-**
-** The interface is the same as sqlite3VdbeExec(). But instead of
-** running the code, it invokes the callback once for each instruction.
-** This feature is used to implement "EXPLAIN".
-**
-** When p->explain==1, each instruction is listed. When
-** p->explain==2, only OP_Explain instructions are listed and these
-** are shown in a different format. p->explain==2 is used to implement
-** EXPLAIN QUERY PLAN.
-*/
-SQLITE_PRIVATE int sqlite3VdbeList(
- Vdbe *p /* The VDBE */
-){
- int nRow; /* Total number of rows to return */
- int nSub = 0; /* Number of sub-vdbes seen so far */
- SubProgram **apSub = 0; /* Array of sub-vdbes */
- Mem *pSub = 0;
- sqlite3 *db = p->db;
- int i;
- int rc = SQLITE_OK;
- Mem *pMem = p->pResultSet = &p->aMem[1];
-
- assert( p->explain );
- assert( p->magic==VDBE_MAGIC_RUN );
- assert( db->magic==SQLITE_MAGIC_BUSY );
- assert( p->rc==SQLITE_OK || p->rc==SQLITE_BUSY || p->rc==SQLITE_NOMEM );
-
- /* Even though this opcode does not use dynamic strings for
- ** the result, result columns may become dynamic if the user calls
- ** sqlite3_column_text16(), causing a translation to UTF-16 encoding.
- */
- releaseMemArray(pMem, 8);
-
- if( p->rc==SQLITE_NOMEM ){
- /* This happens if a malloc() inside a call to sqlite3_column_text() or
- ** sqlite3_column_text16() failed. */
- db->mallocFailed = 1;
- return SQLITE_ERROR;
- }
-
- /* Figure out total number of rows that will be returned by this
- ** EXPLAIN program. */
- nRow = p->nOp;
- if( p->explain==1 ){
- pSub = &p->aMem[9];
- if( pSub->flags&MEM_Blob ){
- nSub = pSub->n/sizeof(Vdbe*);
- apSub = (SubProgram **)pSub->z;
- }
- for(i=0; i<nSub; i++){
- nRow += apSub[i]->nOp;
- }
- }
-
- do{
- i = p->pc++;
- }while( i<nRow && p->explain==2 && p->aOp[i].opcode!=OP_Explain );
- if( i>=nRow ){
- p->rc = SQLITE_OK;
- rc = SQLITE_DONE;
- }else if( db->u1.isInterrupted ){
- p->rc = SQLITE_INTERRUPT;
- rc = SQLITE_ERROR;
- sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3ErrStr(p->rc));
- }else{
- char *z;
- Op *pOp;
- if( i<p->nOp ){
- pOp = &p->aOp[i];
- }else{
- int j;
- i -= p->nOp;
- for(j=0; i>=apSub[j]->nOp; j++){
- i -= apSub[j]->nOp;
- }
- pOp = &apSub[j]->aOp[i];
- }
- if( p->explain==1 ){
- pMem->flags = MEM_Int;
- pMem->type = SQLITE_INTEGER;
- pMem->u.i = i; /* Program counter */
- pMem++;
-
- pMem->flags = MEM_Static|MEM_Str|MEM_Term;
- pMem->z = (char*)sqlite3OpcodeName(pOp->opcode); /* Opcode */
- assert( pMem->z!=0 );
- pMem->n = sqlite3Strlen30(pMem->z);
- pMem->type = SQLITE_TEXT;
- pMem->enc = SQLITE_UTF8;
- pMem++;
-
- if( pOp->p4type==P4_SUBPROGRAM ){
- int nByte = (nSub+1)*sizeof(SubProgram*);
- int j;
- for(j=0; j<nSub; j++){
- if( apSub[j]==pOp->p4.pProgram ) break;
- }
- if( j==nSub && SQLITE_OK==sqlite3VdbeMemGrow(pSub, nByte, 1) ){
- apSub = (SubProgram **)pSub->z;
- apSub[nSub++] = pOp->p4.pProgram;
- pSub->flags |= MEM_Blob;
- pSub->n = nSub*sizeof(SubProgram*);
- }
- }
- }
-
- pMem->flags = MEM_Int;
- pMem->u.i = pOp->p1; /* P1 */
- pMem->type = SQLITE_INTEGER;
- pMem++;
-
- pMem->flags = MEM_Int;
- pMem->u.i = pOp->p2; /* P2 */
- pMem->type = SQLITE_INTEGER;
- pMem++;
-
- if( p->explain==1 ){
- pMem->flags = MEM_Int;
- pMem->u.i = pOp->p3; /* P3 */
- pMem->type = SQLITE_INTEGER;
- pMem++;
- }
-
- if( sqlite3VdbeMemGrow(pMem, 32, 0) ){ /* P4 */
- assert( p->db->mallocFailed );
- return SQLITE_ERROR;
- }
- pMem->flags = MEM_Dyn|MEM_Str|MEM_Term;
- z = displayP4(pOp, pMem->z, 32);
- if( z!=pMem->z ){
- sqlite3VdbeMemSetStr(pMem, z, -1, SQLITE_UTF8, 0);
- }else{
- assert( pMem->z!=0 );
- pMem->n = sqlite3Strlen30(pMem->z);
- pMem->enc = SQLITE_UTF8;
- }
- pMem->type = SQLITE_TEXT;
- pMem++;
-
- if( p->explain==1 ){
- if( sqlite3VdbeMemGrow(pMem, 4, 0) ){
- assert( p->db->mallocFailed );
- return SQLITE_ERROR;
- }
- pMem->flags = MEM_Dyn|MEM_Str|MEM_Term;
- pMem->n = 2;
- sqlite3_snprintf(3, pMem->z, "%.2x", pOp->p5); /* P5 */
- pMem->type = SQLITE_TEXT;
- pMem->enc = SQLITE_UTF8;
- pMem++;
-
-#ifdef SQLITE_DEBUG
- if( pOp->zComment ){
- pMem->flags = MEM_Str|MEM_Term;
- pMem->z = pOp->zComment;
- pMem->n = sqlite3Strlen30(pMem->z);
- pMem->enc = SQLITE_UTF8;
- pMem->type = SQLITE_TEXT;
- }else
-#endif
- {
- pMem->flags = MEM_Null; /* Comment */
- pMem->type = SQLITE_NULL;
- }
- }
-
- p->nResColumn = 8 - 5*(p->explain-1);
- p->rc = SQLITE_OK;
- rc = SQLITE_ROW;
- }
- return rc;
-}
-#endif /* SQLITE_OMIT_EXPLAIN */
-
-#ifdef SQLITE_DEBUG
-/*
-** Print the SQL that was used to generate a VDBE program.
-*/
-SQLITE_PRIVATE void sqlite3VdbePrintSql(Vdbe *p){
- int nOp = p->nOp;
- VdbeOp *pOp;
- if( nOp<1 ) return;
- pOp = &p->aOp[0];
- if( pOp->opcode==OP_Trace && pOp->p4.z!=0 ){
- const char *z = pOp->p4.z;
- while( sqlite3Isspace(*z) ) z++;
- printf("SQL: [%s]\n", z);
- }
-}
-#endif
-
-#if !defined(SQLITE_OMIT_TRACE) && defined(SQLITE_ENABLE_IOTRACE)
-/*
-** Print an IOTRACE message showing SQL content.
-*/
-SQLITE_PRIVATE void sqlite3VdbeIOTraceSql(Vdbe *p){
- int nOp = p->nOp;
- VdbeOp *pOp;
- if( sqlite3IoTrace==0 ) return;
- if( nOp<1 ) return;
- pOp = &p->aOp[0];
- if( pOp->opcode==OP_Trace && pOp->p4.z!=0 ){
- int i, j;
- char z[1000];
- sqlite3_snprintf(sizeof(z), z, "%s", pOp->p4.z);
- for(i=0; sqlite3Isspace(z[i]); i++){}
- for(j=0; z[i]; i++){
- if( sqlite3Isspace(z[i]) ){
- if( z[i-1]!=' ' ){
- z[j++] = ' ';
- }
- }else{
- z[j++] = z[i];
- }
- }
- z[j] = 0;
- sqlite3IoTrace("SQL %s\n", z);
- }
-}
-#endif /* !SQLITE_OMIT_TRACE && SQLITE_ENABLE_IOTRACE */
-
-/*
-** Allocate space from a fixed size buffer. Make *pp point to the
-** allocated space. (Note: pp is a char* rather than a void** to
-** work around the pointer aliasing rules of C.) *pp should initially
-** be zero. If *pp is not zero, that means that the space has already
-** been allocated and this routine is a noop.
-**
-** nByte is the number of bytes of space needed.
-**
-** *ppFrom point to available space and pEnd points to the end of the
-** available space.
-**
-** *pnByte is a counter of the number of bytes of space that have failed
-** to allocate. If there is insufficient space in *ppFrom to satisfy the
-** request, then increment *pnByte by the amount of the request.
-*/
-static void allocSpace(
- char *pp, /* IN/OUT: Set *pp to point to allocated buffer */
- int nByte, /* Number of bytes to allocate */
- u8 **ppFrom, /* IN/OUT: Allocate from *ppFrom */
- u8 *pEnd, /* Pointer to 1 byte past the end of *ppFrom buffer */
- int *pnByte /* If allocation cannot be made, increment *pnByte */
-){
- assert( EIGHT_BYTE_ALIGNMENT(*ppFrom) );
- if( (*(void**)pp)==0 ){
- nByte = ROUND8(nByte);
- if( &(*ppFrom)[nByte] <= pEnd ){
- *(void**)pp = (void *)*ppFrom;
- *ppFrom += nByte;
- }else{
- *pnByte += nByte;
- }
- }
-}
-
-/*
-** Prepare a virtual machine for execution. This involves things such
-** as allocating stack space and initializing the program counter.
-** After the VDBE has be prepped, it can be executed by one or more
-** calls to sqlite3VdbeExec().
-**
-** This is the only way to move a VDBE from VDBE_MAGIC_INIT to
-** VDBE_MAGIC_RUN.
-**
-** This function may be called more than once on a single virtual machine.
-** The first call is made while compiling the SQL statement. Subsequent
-** calls are made as part of the process of resetting a statement to be
-** re-executed (from a call to sqlite3_reset()). The nVar, nMem, nCursor
-** and isExplain parameters are only passed correct values the first time
-** the function is called. On subsequent calls, from sqlite3_reset(), nVar
-** is passed -1 and nMem, nCursor and isExplain are all passed zero.
-*/
-SQLITE_PRIVATE void sqlite3VdbeMakeReady(
- Vdbe *p, /* The VDBE */
- int nVar, /* Number of '?' see in the SQL statement */
- int nMem, /* Number of memory cells to allocate */
- int nCursor, /* Number of cursors to allocate */
- int nArg, /* Maximum number of args in SubPrograms */
- int isExplain, /* True if the EXPLAIN keywords is present */
- int usesStmtJournal /* True to set Vdbe.usesStmtJournal */
-){
- int n;
- sqlite3 *db = p->db;
-
- assert( p!=0 );
- assert( p->magic==VDBE_MAGIC_INIT );
-
- /* There should be at least one opcode.
- */
- assert( p->nOp>0 );
-
- /* Set the magic to VDBE_MAGIC_RUN sooner rather than later. */
- p->magic = VDBE_MAGIC_RUN;
-
- /* For each cursor required, also allocate a memory cell. Memory
- ** cells (nMem+1-nCursor)..nMem, inclusive, will never be used by
- ** the vdbe program. Instead they are used to allocate space for
- ** VdbeCursor/BtCursor structures. The blob of memory associated with
- ** cursor 0 is stored in memory cell nMem. Memory cell (nMem-1)
- ** stores the blob of memory associated with cursor 1, etc.
- **
- ** See also: allocateCursor().
- */
- nMem += nCursor;
-
- /* Allocate space for memory registers, SQL variables, VDBE cursors and
- ** an array to marshal SQL function arguments in. This is only done the
- ** first time this function is called for a given VDBE, not when it is
- ** being called from sqlite3_reset() to reset the virtual machine.
- */
- if( nVar>=0 && ALWAYS(db->mallocFailed==0) ){
- u8 *zCsr = (u8 *)&p->aOp[p->nOp];
- u8 *zEnd = (u8 *)&p->aOp[p->nOpAlloc];
- int nByte;
- resolveP2Values(p, &nArg);
- p->usesStmtJournal = (u8)usesStmtJournal;
- if( isExplain && nMem<10 ){
- nMem = 10;
- }
- memset(zCsr, 0, zEnd-zCsr);
- zCsr += (zCsr - (u8*)0)&7;
- assert( EIGHT_BYTE_ALIGNMENT(zCsr) );
-
- do {
- nByte = 0;
- allocSpace((char*)&p->aMem, nMem*sizeof(Mem), &zCsr, zEnd, &nByte);
- allocSpace((char*)&p->aVar, nVar*sizeof(Mem), &zCsr, zEnd, &nByte);
- allocSpace((char*)&p->apArg, nArg*sizeof(Mem*), &zCsr, zEnd, &nByte);
- allocSpace((char*)&p->azVar, nVar*sizeof(char*), &zCsr, zEnd, &nByte);
- allocSpace((char*)&p->apCsr,
- nCursor*sizeof(VdbeCursor*), &zCsr, zEnd, &nByte
- );
- if( nByte ){
- p->pFree = sqlite3DbMallocZero(db, nByte);
- }
- zCsr = p->pFree;
- zEnd = &zCsr[nByte];
- }while( nByte && !db->mallocFailed );
-
- p->nCursor = (u16)nCursor;
- if( p->aVar ){
- p->nVar = (u16)nVar;
- for(n=0; n<nVar; n++){
- p->aVar[n].flags = MEM_Null;
- p->aVar[n].db = db;
- }
- }
- if( p->aMem ){
- p->aMem--; /* 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].db = db;
- }
- }
- }
-#ifdef SQLITE_DEBUG
- for(n=1; n<p->nMem; n++){
- assert( p->aMem[n].db==db );
- }
-#endif
-
- p->pc = -1;
- p->rc = SQLITE_OK;
- p->errorAction = OE_Abort;
- p->explain |= isExplain;
- p->magic = VDBE_MAGIC_RUN;
- p->nChange = 0;
- p->cacheCtr = 1;
- p->minWriteFileFormat = 255;
- p->iStatement = 0;
-#ifdef VDBE_PROFILE
- {
- int i;
- for(i=0; i<p->nOp; i++){
- p->aOp[i].cnt = 0;
- p->aOp[i].cycles = 0;
- }
- }
-#endif
-}
-
-/*
-** Close a VDBE cursor and release all the resources that cursor
-** happens to hold.
-*/
-SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *p, VdbeCursor *pCx){
- if( pCx==0 ){
- return;
- }
- if( pCx->pBt ){
- sqlite3BtreeClose(pCx->pBt);
- /* The pCx->pCursor will be close automatically, if it exists, by
- ** the call above. */
- }else if( pCx->pCursor ){
- sqlite3BtreeCloseCursor(pCx->pCursor);
- }
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- if( pCx->pVtabCursor ){
- sqlite3_vtab_cursor *pVtabCursor = pCx->pVtabCursor;
- const sqlite3_module *pModule = pCx->pModule;
- p->inVtabMethod = 1;
- (void)sqlite3SafetyOff(p->db);
- pModule->xClose(pVtabCursor);
- (void)sqlite3SafetyOn(p->db);
- p->inVtabMethod = 0;
- }
-#endif
-}
-
-/*
-** Copy the values stored in the VdbeFrame structure to its Vdbe. This
-** is used, for example, when a trigger sub-program is halted to restore
-** control to the main program.
-*/
-SQLITE_PRIVATE int sqlite3VdbeFrameRestore(VdbeFrame *pFrame){
- Vdbe *v = pFrame->v;
- v->aOp = pFrame->aOp;
- v->nOp = pFrame->nOp;
- v->aMem = pFrame->aMem;
- v->nMem = pFrame->nMem;
- v->apCsr = pFrame->apCsr;
- v->nCursor = pFrame->nCursor;
- v->db->lastRowid = pFrame->lastRowid;
- v->nChange = pFrame->nChange;
- return pFrame->pc;
-}
-
-/*
-** Close all cursors.
-**
-** Also release any dynamic memory held by the VM in the Vdbe.aMem memory
-** cell array. This is necessary as the memory cell array may contain
-** pointers to VdbeFrame objects, which may in turn contain pointers to
-** open cursors.
-*/
-static void closeAllCursors(Vdbe *p){
- if( p->pFrame ){
- VdbeFrame *pFrame = p->pFrame;
- for(pFrame=p->pFrame; pFrame->pParent; pFrame=pFrame->pParent);
- sqlite3VdbeFrameRestore(pFrame);
- }
- p->pFrame = 0;
- p->nFrame = 0;
-
- if( p->apCsr ){
- int i;
- for(i=0; i<p->nCursor; i++){
- VdbeCursor *pC = p->apCsr[i];
- if( pC ){
- sqlite3VdbeFreeCursor(p, pC);
- p->apCsr[i] = 0;
- }
- }
- }
- if( p->aMem ){
- releaseMemArray(&p->aMem[1], p->nMem);
- }
-}
-
-/*
-** Clean up the VM after execution.
-**
-** This routine will automatically close any cursors, lists, and/or
-** sorters that were left open. It also deletes the values of
-** variables in the aVar[] array.
-*/
-static void Cleanup(Vdbe *p){
- sqlite3 *db = p->db;
-
-#ifdef SQLITE_DEBUG
- /* Execute assert() statements to ensure that the Vdbe.apCsr[] and
- ** Vdbe.aMem[] arrays have already been cleaned up. */
- int i;
- for(i=0; i<p->nCursor; 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 );
-#endif
-
- sqlite3DbFree(db, p->zErrMsg);
- p->zErrMsg = 0;
- p->pResultSet = 0;
-}
-
-/*
-** Set the number of result columns that will be returned by this SQL
-** statement. This is now set at compile time, rather than during
-** execution of the vdbe program so that sqlite3_column_count() can
-** be called on an SQL statement before sqlite3_step().
-*/
-SQLITE_PRIVATE void sqlite3VdbeSetNumCols(Vdbe *p, int nResColumn){
- Mem *pColName;
- int n;
- sqlite3 *db = p->db;
-
- releaseMemArray(p->aColName, p->nResColumn*COLNAME_N);
- sqlite3DbFree(db, p->aColName);
- n = nResColumn*COLNAME_N;
- p->nResColumn = (u16)nResColumn;
- p->aColName = pColName = (Mem*)sqlite3DbMallocZero(db, sizeof(Mem)*n );
- if( p->aColName==0 ) return;
- while( n-- > 0 ){
- pColName->flags = MEM_Null;
- pColName->db = p->db;
- pColName++;
- }
-}
-
-/*
-** Set the name of the idx'th column to be returned by the SQL statement.
-** zName must be a pointer to a nul terminated string.
-**
-** This call must be made after a call to sqlite3VdbeSetNumCols().
-**
-** The final parameter, xDel, must be one of SQLITE_DYNAMIC, SQLITE_STATIC
-** or SQLITE_TRANSIENT. If it is SQLITE_DYNAMIC, then the buffer pointed
-** to by zName will be freed by sqlite3DbFree() when the vdbe is destroyed.
-*/
-SQLITE_PRIVATE int sqlite3VdbeSetColName(
- Vdbe *p, /* Vdbe being configured */
- int idx, /* Index of column zName applies to */
- int var, /* One of the COLNAME_* constants */
- const char *zName, /* Pointer to buffer containing name */
- void (*xDel)(void*) /* Memory management strategy for zName */
-){
- int rc;
- Mem *pColName;
- assert( idx<p->nResColumn );
- assert( var<COLNAME_N );
- if( p->db->mallocFailed ){
- assert( !zName || xDel!=SQLITE_DYNAMIC );
- return SQLITE_NOMEM;
- }
- assert( p->aColName!=0 );
- pColName = &(p->aColName[idx+var*p->nResColumn]);
- rc = sqlite3VdbeMemSetStr(pColName, zName, -1, SQLITE_UTF8, xDel);
- assert( rc!=0 || !zName || (pColName->flags&MEM_Term)!=0 );
- return rc;
-}
-
-/*
-** A read or write transaction may or may not be active on database handle
-** db. If a transaction is active, commit it. If there is a
-** write-transaction spanning more than one database file, this routine
-** takes care of the master journal trickery.
-*/
-static int vdbeCommit(sqlite3 *db, Vdbe *p){
- int i;
- int nTrans = 0; /* Number of databases with an active write-transaction */
- int rc = SQLITE_OK;
- int needXcommit = 0;
-
-#ifdef SQLITE_OMIT_VIRTUALTABLE
- /* With this option, sqlite3VtabSync() is defined to be simply
- ** SQLITE_OK so p is not used.
- */
- UNUSED_PARAMETER(p);
-#endif
-
- /* Before doing anything else, call the xSync() callback for any
- ** virtual module tables written in this transaction. This has to
- ** be done before determining whether a master journal file is
- ** required, as an xSync() callback may add an attached database
- ** to the transaction.
- */
- rc = sqlite3VtabSync(db, &p->zErrMsg);
- if( rc!=SQLITE_OK ){
- return rc;
- }
-
- /* This loop determines (a) if the commit hook should be invoked and
- ** (b) how many database files have open write transactions, not
- ** including the temp database. (b) is important because if more than
- ** one database file has an open write transaction, a master journal
- ** file is required for an atomic commit.
- */
- for(i=0; i<db->nDb; i++){
- Btree *pBt = db->aDb[i].pBt;
- if( sqlite3BtreeIsInTrans(pBt) ){
- needXcommit = 1;
- if( i!=1 ) nTrans++;
- }
- }
-
- /* If there are any write-transactions at all, invoke the commit hook */
- if( needXcommit && db->xCommitCallback ){
- (void)sqlite3SafetyOff(db);
- rc = db->xCommitCallback(db->pCommitArg);
- (void)sqlite3SafetyOn(db);
- if( rc ){
- return SQLITE_CONSTRAINT;
- }
- }
-
- /* The simple case - no more than one database file (not counting the
- ** TEMP database) has a transaction active. There is no need for the
- ** master-journal.
- **
- ** If the return value of sqlite3BtreeGetFilename() is a zero length
- ** string, it means the main database is :memory: or a temp file. In
- ** that case we do not support atomic multi-file commits, so use the
- ** simple case then too.
- */
- if( 0==sqlite3Strlen30(sqlite3BtreeGetFilename(db->aDb[0].pBt))
- || nTrans<=1
- ){
- for(i=0; rc==SQLITE_OK && i<db->nDb; i++){
- Btree *pBt = db->aDb[i].pBt;
- if( pBt ){
- rc = sqlite3BtreeCommitPhaseOne(pBt, 0);
- }
- }
-
- /* Do the commit only if all databases successfully complete phase 1.
- ** If one of the BtreeCommitPhaseOne() calls fails, this indicates an
- ** IO error while deleting or truncating a journal file. It is unlikely,
- ** but could happen. In this case abandon processing and return the error.
- */
- for(i=0; rc==SQLITE_OK && i<db->nDb; i++){
- Btree *pBt = db->aDb[i].pBt;
- if( pBt ){
- rc = sqlite3BtreeCommitPhaseTwo(pBt);
- }
- }
- if( rc==SQLITE_OK ){
- sqlite3VtabCommit(db);
- }
- }
-
- /* The complex case - There is a multi-file write-transaction active.
- ** This requires a master journal file to ensure the transaction is
- ** committed atomicly.
- */
-#ifndef SQLITE_OMIT_DISKIO
- else{
- sqlite3_vfs *pVfs = db->pVfs;
- int needSync = 0;
- char *zMaster = 0; /* File-name for the master journal */
- char const *zMainFile = sqlite3BtreeGetFilename(db->aDb[0].pBt);
- sqlite3_file *pMaster = 0;
- i64 offset = 0;
- int res;
-
- /* Select a master journal file name */
- 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;
- }
- rc = sqlite3OsAccess(pVfs, zMaster, SQLITE_ACCESS_EXISTS, &res);
- }while( rc==SQLITE_OK && res );
- if( rc==SQLITE_OK ){
- /* Open the master journal. */
- rc = sqlite3OsOpenMalloc(pVfs, zMaster, &pMaster,
- SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|
- SQLITE_OPEN_EXCLUSIVE|SQLITE_OPEN_MASTER_JOURNAL, 0
- );
- }
- if( rc!=SQLITE_OK ){
- sqlite3DbFree(db, zMaster);
- return rc;
- }
-
- /* Write the name of each database file in the transaction into the new
- ** master journal file. If an error occurs at this point close
- ** and delete the master journal file. All the individual journal files
- ** still have 'null' as the master journal pointer, so they will roll
- ** back independently if a failure occurs.
- */
- for(i=0; i<db->nDb; i++){
- Btree *pBt = db->aDb[i].pBt;
- if( i==1 ) continue; /* Ignore the TEMP database */
- if( sqlite3BtreeIsInTrans(pBt) ){
- char const *zFile = sqlite3BtreeGetJournalname(pBt);
- if( zFile[0]==0 ) continue; /* Ignore :memory: databases */
- if( !needSync && !sqlite3BtreeSyncDisabled(pBt) ){
- needSync = 1;
- }
- rc = sqlite3OsWrite(pMaster, zFile, sqlite3Strlen30(zFile)+1, offset);
- offset += sqlite3Strlen30(zFile)+1;
- if( rc!=SQLITE_OK ){
- sqlite3OsCloseFree(pMaster);
- sqlite3OsDelete(pVfs, zMaster, 0);
- sqlite3DbFree(db, zMaster);
- return rc;
- }
- }
- }
-
- /* Sync the master journal file. If the IOCAP_SEQUENTIAL device
- ** flag is set this is not required.
- */
- if( needSync
- && 0==(sqlite3OsDeviceCharacteristics(pMaster)&SQLITE_IOCAP_SEQUENTIAL)
- && SQLITE_OK!=(rc = sqlite3OsSync(pMaster, SQLITE_SYNC_NORMAL))
- ){
- sqlite3OsCloseFree(pMaster);
- sqlite3OsDelete(pVfs, zMaster, 0);
- sqlite3DbFree(db, zMaster);
- return rc;
- }
-
- /* Sync all the db files involved in the transaction. The same call
- ** sets the master journal pointer in each individual journal. If
- ** an error occurs here, do not delete the master journal file.
- **
- ** If the error occurs during the first call to
- ** sqlite3BtreeCommitPhaseOne(), then there is a chance that the
- ** master journal file will be orphaned. But we cannot delete it,
- ** in case the master journal file name was written into the journal
- ** file before the failure occurred.
- */
- for(i=0; rc==SQLITE_OK && i<db->nDb; i++){
- Btree *pBt = db->aDb[i].pBt;
- if( pBt ){
- rc = sqlite3BtreeCommitPhaseOne(pBt, zMaster);
- }
- }
- sqlite3OsCloseFree(pMaster);
- if( rc!=SQLITE_OK ){
- sqlite3DbFree(db, zMaster);
- return rc;
- }
-
- /* Delete the master journal file. This commits the transaction. After
- ** doing this the directory is synced again before any individual
- ** transaction files are deleted.
- */
- rc = sqlite3OsDelete(pVfs, zMaster, 1);
- sqlite3DbFree(db, zMaster);
- zMaster = 0;
- if( rc ){
- return rc;
- }
-
- /* All files and directories have already been synced, so the following
- ** calls to sqlite3BtreeCommitPhaseTwo() are only closing files and
- ** deleting or truncating journals. If something goes wrong while
- ** this is happening we don't really care. The integrity of the
- ** transaction is already guaranteed, but some stray 'cold' journals
- ** may be lying around. Returning an error code won't help matters.
- */
- disable_simulated_io_errors();
- sqlite3BeginBenignMalloc();
- for(i=0; i<db->nDb; i++){
- Btree *pBt = db->aDb[i].pBt;
- if( pBt ){
- sqlite3BtreeCommitPhaseTwo(pBt);
- }
- }
- sqlite3EndBenignMalloc();
- enable_simulated_io_errors();
-
- sqlite3VtabCommit(db);
- }
-#endif
-
- return rc;
-}
-
-/*
-** This routine checks that the sqlite3.activeVdbeCnt count variable
-** matches the number of vdbe's in the list sqlite3.pVdbe that are
-** currently active. An assertion fails if the two counts do not match.
-** This is an internal self-check only - it is not an essential processing
-** step.
-**
-** This is a no-op if NDEBUG is defined.
-*/
-#ifndef NDEBUG
-static void checkActiveVdbeCnt(sqlite3 *db){
- Vdbe *p;
- int cnt = 0;
- int nWrite = 0;
- p = db->pVdbe;
- while( p ){
- if( p->magic==VDBE_MAGIC_RUN && p->pc>=0 ){
- cnt++;
- if( p->readOnly==0 ) nWrite++;
- }
- p = p->pNext;
- }
- assert( cnt==db->activeVdbeCnt );
- assert( nWrite==db->writeVdbeCnt );
-}
-#else
-#define checkActiveVdbeCnt(x)
-#endif
-
-/*
-** For every Btree that in database connection db which
-** has been modified, "trip" or invalidate each cursor in
-** that Btree might have been modified so that the cursor
-** can never be used again. This happens when a rollback
-*** occurs. We have to trip all the other cursors, even
-** cursor from other VMs in different database connections,
-** so that none of them try to use the data at which they
-** were pointing and which now may have been changed due
-** to the rollback.
-**
-** Remember that a rollback can delete tables complete and
-** reorder rootpages. So it is not sufficient just to save
-** the state of the cursor. We have to invalidate the cursor
-** so that it is never used again.
-*/
-static void invalidateCursorsOnModifiedBtrees(sqlite3 *db){
- int i;
- for(i=0; i<db->nDb; i++){
- Btree *p = db->aDb[i].pBt;
- if( p && sqlite3BtreeIsInTrans(p) ){
- sqlite3BtreeTripAllCursors(p, SQLITE_ABORT);
- }
- }
-}
-
-/*
-** If the Vdbe passed as the first argument opened a statement-transaction,
-** close it now. Argument eOp must be either SAVEPOINT_ROLLBACK or
-** SAVEPOINT_RELEASE. If it is SAVEPOINT_ROLLBACK, then the statement
-** transaction is rolled back. If eOp is SAVEPOINT_RELEASE, then the
-** statement transaction is commtted.
-**
-** If an IO error occurs, an SQLITE_IOERR_XXX error code is returned.
-** Otherwise SQLITE_OK.
-*/
-SQLITE_PRIVATE int sqlite3VdbeCloseStatement(Vdbe *p, int eOp){
- sqlite3 *const db = p->db;
- int rc = SQLITE_OK;
-
- /* If p->iStatement is greater than zero, then this Vdbe opened a
- ** statement transaction that should be closed here. The only exception
- ** is that an IO error may have occured, causing an emergency rollback.
- ** In this case (db->nStatement==0), and there is nothing to do.
- */
- if( db->nStatement && p->iStatement ){
- int i;
- const int iSavepoint = p->iStatement-1;
-
- assert( eOp==SAVEPOINT_ROLLBACK || eOp==SAVEPOINT_RELEASE);
- assert( db->nStatement>0 );
- assert( p->iStatement==(db->nStatement+db->nSavepoint) );
-
- for(i=0; i<db->nDb; i++){
- int rc2 = SQLITE_OK;
- Btree *pBt = db->aDb[i].pBt;
- if( pBt ){
- if( eOp==SAVEPOINT_ROLLBACK ){
- rc2 = sqlite3BtreeSavepoint(pBt, SAVEPOINT_ROLLBACK, iSavepoint);
- }
- if( rc2==SQLITE_OK ){
- rc2 = sqlite3BtreeSavepoint(pBt, SAVEPOINT_RELEASE, iSavepoint);
- }
- if( rc==SQLITE_OK ){
- rc = rc2;
- }
- }
- }
- db->nStatement--;
- p->iStatement = 0;
- }
- return rc;
-}
-
-/*
-** If SQLite is compiled to support shared-cache mode and to be threadsafe,
-** this routine obtains the mutex associated with each BtShared structure
-** that may be accessed by the VM passed as an argument. In doing so it
-** sets the BtShared.db member of each of the BtShared structures, ensuring
-** that the correct busy-handler callback is invoked if required.
-**
-** If SQLite is not threadsafe but does support shared-cache mode, then
-** sqlite3BtreeEnterAll() is invoked to set the BtShared.db variables
-** of all of BtShared structures accessible via the database handle
-** associated with the VM. Of course only a subset of these structures
-** will be accessed by the VM, and we could use Vdbe.btreeMask to figure
-** that subset out, but there is no advantage to doing so.
-**
-** If SQLite is not threadsafe and does not support shared-cache mode, this
-** function is a no-op.
-*/
-#ifndef SQLITE_OMIT_SHARED_CACHE
-SQLITE_PRIVATE void sqlite3VdbeMutexArrayEnter(Vdbe *p){
-#if SQLITE_THREADSAFE
- sqlite3BtreeMutexArrayEnter(&p->aMutex);
-#else
- sqlite3BtreeEnterAll(p->db);
-#endif
-}
-#endif
-
-/*
-** This routine is called the when a VDBE tries to halt. If the VDBE
-** has made changes and is in autocommit mode, then commit those
-** changes. If a rollback is needed, then do the rollback.
-**
-** This routine is the only way to move the state of a VM from
-** SQLITE_MAGIC_RUN to SQLITE_MAGIC_HALT. It is harmless to
-** call this on a VM that is in the SQLITE_MAGIC_HALT state.
-**
-** Return an error code. If the commit could not complete because of
-** lock contention, return SQLITE_BUSY. If SQLITE_BUSY is returned, it
-** means the close did not happen and needs to be repeated.
-*/
-SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe *p){
- int rc; /* Used to store transient return codes */
- sqlite3 *db = p->db;
-
- /* This function contains the logic that determines if a statement or
- ** transaction will be committed or rolled back as a result of the
- ** execution of this virtual machine.
- **
- ** If any of the following errors occur:
- **
- ** SQLITE_NOMEM
- ** SQLITE_IOERR
- ** SQLITE_FULL
- ** SQLITE_INTERRUPT
- **
- ** Then the internal cache might have been left in an inconsistent
- ** state. We need to rollback the statement transaction, if there is
- ** one, or the complete transaction if there is no statement transaction.
- */
-
- if( p->db->mallocFailed ){
- p->rc = SQLITE_NOMEM;
- }
- closeAllCursors(p);
- if( p->magic!=VDBE_MAGIC_RUN ){
- return SQLITE_OK;
- }
- checkActiveVdbeCnt(db);
-
- /* No commit or rollback needed if the program never started */
- if( p->pc>=0 ){
- int mrc; /* Primary error code from p->rc */
- int eStatementOp = 0;
- int isSpecialError; /* Set to true if a 'special' error */
-
- /* Lock all btrees used by the statement */
- sqlite3VdbeMutexArrayEnter(p);
-
- /* Check for one of the special errors */
- mrc = p->rc & 0xff;
- assert( p->rc!=SQLITE_IOERR_BLOCKED ); /* This error no longer exists */
- isSpecialError = mrc==SQLITE_NOMEM || mrc==SQLITE_IOERR
- || mrc==SQLITE_INTERRUPT || mrc==SQLITE_FULL;
- if( isSpecialError ){
- /* If the query was read-only, we need do no rollback at all. Otherwise,
- ** proceed with the special handling.
- */
- if( !p->readOnly || mrc!=SQLITE_INTERRUPT ){
- if( (mrc==SQLITE_NOMEM || mrc==SQLITE_FULL) && p->usesStmtJournal ){
- eStatementOp = SAVEPOINT_ROLLBACK;
- }else{
- /* We are forced to roll back the active transaction. Before doing
- ** so, abort any other statements this handle currently has active.
- */
- invalidateCursorsOnModifiedBtrees(db);
- sqlite3RollbackAll(db);
- sqlite3CloseSavepoints(db);
- db->autoCommit = 1;
- }
- }
- }
-
- /* If the auto-commit flag is set and this is the only active writer
- ** VM, then we do either a commit or rollback of the current transaction.
- **
- ** Note: This block also runs if one of the special errors handled
- ** above has occurred.
- */
- if( !sqlite3VtabInSync(db)
- && db->autoCommit
- && db->writeVdbeCnt==(p->readOnly==0)
- ){
- if( p->rc==SQLITE_OK || (p->errorAction==OE_Fail && !isSpecialError) ){
- /* The auto-commit flag is true, and the vdbe program was
- ** successful or hit an 'OR FAIL' constraint. This means a commit
- ** is required.
- */
- rc = vdbeCommit(db, p);
- if( rc==SQLITE_BUSY ){
- sqlite3BtreeMutexArrayLeave(&p->aMutex);
- return SQLITE_BUSY;
- }else if( rc!=SQLITE_OK ){
- p->rc = rc;
- sqlite3RollbackAll(db);
- }else{
- sqlite3CommitInternalChanges(db);
- }
- }else{
- sqlite3RollbackAll(db);
- }
- db->nStatement = 0;
- }else if( eStatementOp==0 ){
- if( p->rc==SQLITE_OK || p->errorAction==OE_Fail ){
- eStatementOp = SAVEPOINT_RELEASE;
- }else if( p->errorAction==OE_Abort ){
- eStatementOp = SAVEPOINT_ROLLBACK;
- }else{
- invalidateCursorsOnModifiedBtrees(db);
- sqlite3RollbackAll(db);
- sqlite3CloseSavepoints(db);
- db->autoCommit = 1;
- }
- }
-
- /* If eStatementOp is non-zero, then a statement transaction needs to
- ** be committed or rolled back. Call sqlite3VdbeCloseStatement() to
- ** do so. If this operation returns an error, and the current statement
- ** error code is SQLITE_OK or SQLITE_CONSTRAINT, then set the error
- ** code to the new value.
- */
- if( eStatementOp ){
- rc = sqlite3VdbeCloseStatement(p, eStatementOp);
- if( rc && (p->rc==SQLITE_OK || p->rc==SQLITE_CONSTRAINT) ){
- p->rc = rc;
- sqlite3DbFree(db, p->zErrMsg);
- p->zErrMsg = 0;
- }
- }
-
- /* If this was an INSERT, UPDATE or DELETE and no statement transaction
- ** has been rolled back, update the database connection change-counter.
- */
- if( p->changeCntOn ){
- if( eStatementOp!=SAVEPOINT_ROLLBACK ){
- sqlite3VdbeSetChanges(db, p->nChange);
- }else{
- sqlite3VdbeSetChanges(db, 0);
- }
- p->nChange = 0;
- }
-
- /* Rollback or commit any schema changes that occurred. */
- if( p->rc!=SQLITE_OK && db->flags&SQLITE_InternChanges ){
- sqlite3ResetInternalSchema(db, 0);
- db->flags = (db->flags | SQLITE_InternChanges);
- }
-
- /* Release the locks */
- sqlite3BtreeMutexArrayLeave(&p->aMutex);
- }
-
- /* We have successfully halted and closed the VM. Record this fact. */
- if( p->pc>=0 ){
- db->activeVdbeCnt--;
- if( !p->readOnly ){
- db->writeVdbeCnt--;
- }
- assert( db->activeVdbeCnt>=db->writeVdbeCnt );
- }
- p->magic = VDBE_MAGIC_HALT;
- checkActiveVdbeCnt(db);
- if( p->db->mallocFailed ){
- p->rc = SQLITE_NOMEM;
- }
-
- /* If the auto-commit flag is set to true, then any locks that were held
- ** by connection db have now been released. Call sqlite3ConnectionUnlocked()
- ** to invoke any required unlock-notify callbacks.
- */
- if( db->autoCommit ){
- sqlite3ConnectionUnlocked(db);
- }
-
- assert( db->activeVdbeCnt>0 || db->autoCommit==0 || db->nStatement==0 );
- return SQLITE_OK;
-}
-
-
-/*
-** Each VDBE holds the result of the most recent sqlite3_step() call
-** in p->rc. This routine sets that result back to SQLITE_OK.
-*/
-SQLITE_PRIVATE void sqlite3VdbeResetStepResult(Vdbe *p){
- p->rc = SQLITE_OK;
-}
-
-/*
-** Clean up a VDBE after execution but do not delete the VDBE just yet.
-** Write any error messages into *pzErrMsg. Return the result code.
-**
-** After this routine is run, the VDBE should be ready to be executed
-** again.
-**
-** To look at it another way, this routine resets the state of the
-** virtual machine from VDBE_MAGIC_RUN or VDBE_MAGIC_HALT back to
-** VDBE_MAGIC_INIT.
-*/
-SQLITE_PRIVATE int sqlite3VdbeReset(Vdbe *p){
- sqlite3 *db;
- db = p->db;
-
- /* If the VM did not run to completion or if it encountered an
- ** error, then it might not have been halted properly. So halt
- ** it now.
- */
- (void)sqlite3SafetyOn(db);
- sqlite3VdbeHalt(p);
- (void)sqlite3SafetyOff(db);
-
- /* If the VDBE has be run even partially, then transfer the error code
- ** and error message from the VDBE into the main database structure. But
- ** if the VDBE has just been set to run but has not actually executed any
- ** instructions yet, leave the main database error information unchanged.
- */
- if( p->pc>=0 ){
- if( p->zErrMsg ){
- sqlite3BeginBenignMalloc();
- sqlite3ValueSetStr(db->pErr,-1,p->zErrMsg,SQLITE_UTF8,SQLITE_TRANSIENT);
- sqlite3EndBenignMalloc();
- db->errCode = p->rc;
- sqlite3DbFree(db, p->zErrMsg);
- p->zErrMsg = 0;
- }else if( p->rc ){
- sqlite3Error(db, p->rc, 0);
- }else{
- sqlite3Error(db, SQLITE_OK, 0);
- }
- }else if( p->rc && p->expired ){
- /* The expired flag was set on the VDBE before the first call
- ** to sqlite3_step(). For consistency (since sqlite3_step() was
- ** called), set the database error in this case as well.
- */
- sqlite3Error(db, p->rc, 0);
- sqlite3ValueSetStr(db->pErr, -1, p->zErrMsg, SQLITE_UTF8, SQLITE_TRANSIENT);
- sqlite3DbFree(db, p->zErrMsg);
- p->zErrMsg = 0;
- }
-
- /* Reclaim all memory used by the VDBE
- */
- Cleanup(p);
-
- /* Save profiling information from this VDBE run.
- */
-#ifdef VDBE_PROFILE
- {
- FILE *out = fopen("vdbe_profile.out", "a");
- if( out ){
- int i;
- fprintf(out, "---- ");
- for(i=0; i<p->nOp; i++){
- fprintf(out, "%02x", p->aOp[i].opcode);
- }
- fprintf(out, "\n");
- for(i=0; i<p->nOp; i++){
- fprintf(out, "%6d %10lld %8lld ",
- p->aOp[i].cnt,
- p->aOp[i].cycles,
- p->aOp[i].cnt>0 ? p->aOp[i].cycles/p->aOp[i].cnt : 0
- );
- sqlite3VdbePrintOp(out, i, &p->aOp[i]);
- }
- fclose(out);
- }
- }
-#endif
- p->magic = VDBE_MAGIC_INIT;
- return p->rc & db->errMask;
-}
-
-/*
-** Clean up and delete a VDBE after execution. Return an integer which is
-** the result code. Write any error message text into *pzErrMsg.
-*/
-SQLITE_PRIVATE int sqlite3VdbeFinalize(Vdbe *p){
- int rc = SQLITE_OK;
- if( p->magic==VDBE_MAGIC_RUN || p->magic==VDBE_MAGIC_HALT ){
- rc = sqlite3VdbeReset(p);
- assert( (rc & p->db->errMask)==rc );
- }
- sqlite3VdbeDelete(p);
- return rc;
-}
-
-/*
-** Call the destructor for each auxdata entry in pVdbeFunc for which
-** the corresponding bit in mask is clear. Auxdata entries beyond 31
-** are always destroyed. To destroy all auxdata entries, call this
-** routine with mask==0.
-*/
-SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(VdbeFunc *pVdbeFunc, int mask){
- int i;
- for(i=0; i<pVdbeFunc->nAux; i++){
- struct AuxData *pAux = &pVdbeFunc->apAux[i];
- if( (i>31 || !(mask&(((u32)1)<<i))) && pAux->pAux ){
- if( pAux->xDelete ){
- pAux->xDelete(pAux->pAux);
- }
- pAux->pAux = 0;
- }
- }
-}
-
-/*
-** Delete an entire VDBE.
-*/
-SQLITE_PRIVATE void sqlite3VdbeDelete(Vdbe *p){
- sqlite3 *db;
-
- if( NEVER(p==0) ) return;
- db = p->db;
- if( p->pPrev ){
- p->pPrev->pNext = p->pNext;
- }else{
- assert( db->pVdbe==p );
- db->pVdbe = p->pNext;
- }
- if( p->pNext ){
- p->pNext->pPrev = p->pPrev;
- }
- releaseMemArray(p->aVar, p->nVar);
- releaseMemArray(p->aColName, p->nResColumn*COLNAME_N);
- vdbeFreeOpArray(db, p->aOp, p->nOp);
- sqlite3DbFree(db, p->aLabel);
- sqlite3DbFree(db, p->aColName);
- sqlite3DbFree(db, p->zSql);
- p->magic = VDBE_MAGIC_DEAD;
- sqlite3DbFree(db, p->pFree);
- sqlite3DbFree(db, p);
-}
-
-/*
-** Make sure the cursor p is ready to read or write the row to which it
-** was last positioned. Return an error code if an OOM fault or I/O error
-** prevents us from positioning the cursor to its correct position.
-**
-** If a MoveTo operation is pending on the given cursor, then do that
-** MoveTo now. If no move is pending, check to see if the row has been
-** deleted out from under the cursor and if it has, mark the row as
-** a NULL row.
-**
-** If the cursor is already pointing to the correct row and that row has
-** not been deleted out from under the cursor, then this routine is a no-op.
-*/
-SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor *p){
- if( p->deferredMoveto ){
- int res, rc;
-#ifdef SQLITE_TEST
- extern int sqlite3_search_count;
-#endif
- assert( p->isTable );
- rc = sqlite3BtreeMovetoUnpacked(p->pCursor, 0, p->movetoTarget, 0, &res);
- if( rc ) return rc;
- p->lastRowid = p->movetoTarget;
- p->rowidIsValid = ALWAYS(res==0) ?1:0;
- if( NEVER(res<0) ){
- rc = sqlite3BtreeNext(p->pCursor, &res);
- if( rc ) return rc;
- }
-#ifdef SQLITE_TEST
- sqlite3_search_count++;
-#endif
- p->deferredMoveto = 0;
- p->cacheStatus = CACHE_STALE;
- }else if( ALWAYS(p->pCursor) ){
- int hasMoved;
- int rc = sqlite3BtreeCursorHasMoved(p->pCursor, &hasMoved);
- if( rc ) return rc;
- if( hasMoved ){
- p->cacheStatus = CACHE_STALE;
- p->nullRow = 1;
- }
- }
- return SQLITE_OK;
-}
-
-/*
-** The following functions:
-**
-** sqlite3VdbeSerialType()
-** sqlite3VdbeSerialTypeLen()
-** sqlite3VdbeSerialLen()
-** sqlite3VdbeSerialPut()
-** sqlite3VdbeSerialGet()
-**
-** encapsulate the code that serializes values for storage in SQLite
-** data and index records. Each serialized value consists of a
-** 'serial-type' and a blob of data. The serial type is an 8-byte unsigned
-** integer, stored as a varint.
-**
-** In an SQLite index record, the serial type is stored directly before
-** the blob of data that it corresponds to. In a table record, all serial
-** types are stored at the start of the record, and the blobs of data at
-** the end. Hence these functions allow the caller to handle the
-** serial-type and data blob seperately.
-**
-** The following table describes the various storage classes for data:
-**
-** serial type bytes of data type
-** -------------- --------------- ---------------
-** 0 0 NULL
-** 1 1 signed integer
-** 2 2 signed integer
-** 3 3 signed integer
-** 4 4 signed integer
-** 5 6 signed integer
-** 6 8 signed integer
-** 7 8 IEEE float
-** 8 0 Integer constant 0
-** 9 0 Integer constant 1
-** 10,11 reserved for expansion
-** N>=12 and even (N-12)/2 BLOB
-** N>=13 and odd (N-13)/2 text
-**
-** The 8 and 9 types were added in 3.3.0, file format 4. Prior versions
-** of SQLite will not understand those serial types.
-*/
-
-/*
-** Return the serial-type for the value stored in pMem.
-*/
-SQLITE_PRIVATE u32 sqlite3VdbeSerialType(Mem *pMem, int file_format){
- int flags = pMem->flags;
- int n;
-
- if( flags&MEM_Null ){
- return 0;
- }
- if( flags&MEM_Int ){
- /* Figure out whether to use 1, 2, 4, 6 or 8 bytes. */
-# define MAX_6BYTE ((((i64)0x00008000)<<32)-1)
- i64 i = pMem->u.i;
- u64 u;
- if( file_format>=4 && (i&1)==i ){
- return 8+(u32)i;
- }
- u = i<0 ? -i : i;
- if( u<=127 ) return 1;
- if( u<=32767 ) return 2;
- if( u<=8388607 ) return 3;
- if( u<=2147483647 ) return 4;
- if( u<=MAX_6BYTE ) return 5;
- return 6;
- }
- if( flags&MEM_Real ){
- return 7;
- }
- assert( pMem->db->mallocFailed || flags&(MEM_Str|MEM_Blob) );
- n = pMem->n;
- if( flags & MEM_Zero ){
- n += pMem->u.nZero;
- }
- assert( n>=0 );
- return ((n*2) + 12 + ((flags&MEM_Str)!=0));
-}
-
-/*
-** Return the length of the data corresponding to the supplied serial-type.
-*/
-SQLITE_PRIVATE u32 sqlite3VdbeSerialTypeLen(u32 serial_type){
- if( serial_type>=12 ){
- return (serial_type-12)/2;
- }else{
- static const u8 aSize[] = { 0, 1, 2, 3, 4, 6, 8, 8, 0, 0, 0, 0 };
- return aSize[serial_type];
- }
-}
-
-/*
-** If we are on an architecture with mixed-endian floating
-** points (ex: ARM7) then swap the lower 4 bytes with the
-** upper 4 bytes. Return the result.
-**
-** For most architectures, this is a no-op.
-**
-** (later): It is reported to me that the mixed-endian problem
-** on ARM7 is an issue with GCC, not with the ARM7 chip. It seems
-** that early versions of GCC stored the two words of a 64-bit
-** float in the wrong order. And that error has been propagated
-** ever since. The blame is not necessarily with GCC, though.
-** GCC might have just copying the problem from a prior compiler.
-** I am also told that newer versions of GCC that follow a different
-** ABI get the byte order right.
-**
-** Developers using SQLite on an ARM7 should compile and run their
-** application using -DSQLITE_DEBUG=1 at least once. With DEBUG
-** enabled, some asserts below will ensure that the byte order of
-** floating point values is correct.
-**
-** (2007-08-30) Frank van Vugt has studied this problem closely
-** and has send his findings to the SQLite developers. Frank
-** writes that some Linux kernels offer floating point hardware
-** emulation that uses only 32-bit mantissas instead of a full
-** 48-bits as required by the IEEE standard. (This is the
-** CONFIG_FPE_FASTFPE option.) On such systems, floating point
-** byte swapping becomes very complicated. To avoid problems,
-** the necessary byte swapping is carried out using a 64-bit integer
-** rather than a 64-bit float. Frank assures us that the code here
-** works for him. We, the developers, have no way to independently
-** verify this, but Frank seems to know what he is talking about
-** so we trust him.
-*/
-#ifdef SQLITE_MIXED_ENDIAN_64BIT_FLOAT
-static u64 floatSwap(u64 in){
- union {
- u64 r;
- u32 i[2];
- } u;
- u32 t;
-
- u.r = in;
- t = u.i[0];
- u.i[0] = u.i[1];
- u.i[1] = t;
- return u.r;
-}
-# define swapMixedEndianFloat(X) X = floatSwap(X)
-#else
-# define swapMixedEndianFloat(X)
-#endif
-
-/*
-** Write the serialized data blob for the value stored in pMem into
-** buf. It is assumed that the caller has allocated sufficient space.
-** Return the number of bytes written.
-**
-** nBuf is the amount of space left in buf[]. nBuf must always be
-** large enough to hold the entire field. Except, if the field is
-** a blob with a zero-filled tail, then buf[] might be just the right
-** size to hold everything except for the zero-filled tail. If buf[]
-** is only big enough to hold the non-zero prefix, then only write that
-** prefix into buf[]. But if buf[] is large enough to hold both the
-** prefix and the tail then write the prefix and set the tail to all
-** zeros.
-**
-** Return the number of bytes actually written into buf[]. The number
-** of bytes in the zero-filled tail is included in the return value only
-** if those bytes were zeroed in buf[].
-*/
-SQLITE_PRIVATE u32 sqlite3VdbeSerialPut(u8 *buf, int nBuf, Mem *pMem, int file_format){
- u32 serial_type = sqlite3VdbeSerialType(pMem, file_format);
- u32 len;
-
- /* Integer and Real */
- if( serial_type<=7 && serial_type>0 ){
- u64 v;
- u32 i;
- if( serial_type==7 ){
- assert( sizeof(v)==sizeof(pMem->r) );
- memcpy(&v, &pMem->r, sizeof(v));
- swapMixedEndianFloat(v);
- }else{
- v = pMem->u.i;
- }
- len = i = sqlite3VdbeSerialTypeLen(serial_type);
- assert( len<=(u32)nBuf );
- while( i-- ){
- buf[i] = (u8)(v&0xFF);
- v >>= 8;
- }
- return len;
- }
-
- /* String or blob */
- if( serial_type>=12 ){
- assert( pMem->n + ((pMem->flags & MEM_Zero)?pMem->u.nZero:0)
- == (int)sqlite3VdbeSerialTypeLen(serial_type) );
- assert( pMem->n<=nBuf );
- len = pMem->n;
- memcpy(buf, pMem->z, len);
- if( pMem->flags & MEM_Zero ){
- len += pMem->u.nZero;
- assert( nBuf>=0 );
- if( len > (u32)nBuf ){
- len = (u32)nBuf;
- }
- memset(&buf[pMem->n], 0, len-pMem->n);
- }
- return len;
- }
-
- /* NULL or constants 0 or 1 */
- return 0;
-}
-
-/*
-** Deserialize the data blob pointed to by buf as serial type serial_type
-** and store the result in pMem. Return the number of bytes read.
-*/
-SQLITE_PRIVATE u32 sqlite3VdbeSerialGet(
- const unsigned char *buf, /* Buffer to deserialize from */
- u32 serial_type, /* Serial type to deserialize */
- Mem *pMem /* Memory cell to write value into */
-){
- switch( serial_type ){
- case 10: /* Reserved for future use */
- case 11: /* Reserved for future use */
- case 0: { /* NULL */
- pMem->flags = MEM_Null;
- break;
- }
- case 1: { /* 1-byte signed integer */
- pMem->u.i = (signed char)buf[0];
- pMem->flags = MEM_Int;
- return 1;
- }
- case 2: { /* 2-byte signed integer */
- pMem->u.i = (((signed char)buf[0])<<8) | buf[1];
- pMem->flags = MEM_Int;
- return 2;
- }
- case 3: { /* 3-byte signed integer */
- pMem->u.i = (((signed char)buf[0])<<16) | (buf[1]<<8) | buf[2];
- pMem->flags = MEM_Int;
- return 3;
- }
- case 4: { /* 4-byte signed integer */
- pMem->u.i = (buf[0]<<24) | (buf[1]<<16) | (buf[2]<<8) | buf[3];
- pMem->flags = MEM_Int;
- return 4;
- }
- case 5: { /* 6-byte signed integer */
- u64 x = (((signed char)buf[0])<<8) | buf[1];
- u32 y = (buf[2]<<24) | (buf[3]<<16) | (buf[4]<<8) | buf[5];
- x = (x<<32) | y;
- pMem->u.i = *(i64*)&x;
- pMem->flags = MEM_Int;
- return 6;
- }
- case 6: /* 8-byte signed integer */
- case 7: { /* IEEE floating point */
- u64 x;
- u32 y;
-#if !defined(NDEBUG) && !defined(SQLITE_OMIT_FLOATING_POINT)
- /* Verify that integers and floating point values use the same
- ** byte order. Or, that if SQLITE_MIXED_ENDIAN_64BIT_FLOAT is
- ** defined that 64-bit floating point values really are mixed
- ** endian.
- */
- static const u64 t1 = ((u64)0x3ff00000)<<32;
- static const double r1 = 1.0;
- u64 t2 = t1;
- swapMixedEndianFloat(t2);
- assert( sizeof(r1)==sizeof(t2) && memcmp(&r1, &t2, sizeof(r1))==0 );
-#endif
-
- x = (buf[0]<<24) | (buf[1]<<16) | (buf[2]<<8) | buf[3];
- y = (buf[4]<<24) | (buf[5]<<16) | (buf[6]<<8) | buf[7];
- x = (x<<32) | y;
- if( serial_type==6 ){
- pMem->u.i = *(i64*)&x;
- pMem->flags = MEM_Int;
- }else{
- assert( sizeof(x)==8 && sizeof(pMem->r)==8 );
- swapMixedEndianFloat(x);
- memcpy(&pMem->r, &x, sizeof(x));
- pMem->flags = sqlite3IsNaN(pMem->r) ? MEM_Null : MEM_Real;
- }
- return 8;
- }
- case 8: /* Integer 0 */
- case 9: { /* Integer 1 */
- pMem->u.i = serial_type-8;
- pMem->flags = MEM_Int;
- return 0;
- }
- default: {
- u32 len = (serial_type-12)/2;
- pMem->z = (char *)buf;
- pMem->n = len;
- pMem->xDel = 0;
- if( serial_type&0x01 ){
- pMem->flags = MEM_Str | MEM_Ephem;
- }else{
- pMem->flags = MEM_Blob | MEM_Ephem;
- }
- return len;
- }
- }
- return 0;
-}
-
-
-/*
-** Given the nKey-byte encoding of a record in pKey[], parse the
-** record into a UnpackedRecord structure. Return a pointer to
-** that structure.
-**
-** The calling function might provide szSpace bytes of memory
-** space at pSpace. This space can be used to hold the returned
-** VDbeParsedRecord structure if it is large enough. If it is
-** not big enough, space is obtained from sqlite3_malloc().
-**
-** The returned structure should be closed by a call to
-** sqlite3VdbeDeleteUnpackedRecord().
-*/
-SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeRecordUnpack(
- KeyInfo *pKeyInfo, /* Information about the record format */
- int nKey, /* Size of the binary record */
- const void *pKey, /* The binary record */
- char *pSpace, /* Unaligned space available to hold the object */
- int szSpace /* Size of pSpace[] in bytes */
-){
- const unsigned char *aKey = (const unsigned char *)pKey;
- UnpackedRecord *p; /* The unpacked record that we will return */
- int nByte; /* Memory space needed to hold p, in bytes */
- int d;
- u32 idx;
- u16 u; /* Unsigned loop counter */
- u32 szHdr;
- Mem *pMem;
- int nOff; /* Increase pSpace by this much to 8-byte align it */
-
- /*
- ** We want to shift the pointer pSpace up such that it is 8-byte aligned.
- ** Thus, we need to calculate a value, nOff, between 0 and 7, to shift
- ** it by. If pSpace is already 8-byte aligned, nOff should be zero.
- */
- nOff = (8 - (SQLITE_PTR_TO_INT(pSpace) & 7)) & 7;
- pSpace += nOff;
- szSpace -= nOff;
- nByte = ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*(pKeyInfo->nField+1);
- if( nByte>szSpace ){
- p = sqlite3DbMallocRaw(pKeyInfo->db, nByte);
- if( p==0 ) return 0;
- p->flags = UNPACKED_NEED_FREE | UNPACKED_NEED_DESTROY;
- }else{
- p = (UnpackedRecord*)pSpace;
- p->flags = UNPACKED_NEED_DESTROY;
- }
- p->pKeyInfo = pKeyInfo;
- p->nField = pKeyInfo->nField + 1;
- p->aMem = pMem = (Mem*)&((char*)p)[ROUND8(sizeof(UnpackedRecord))];
- assert( EIGHT_BYTE_ALIGNMENT(pMem) );
- idx = getVarint32(aKey, szHdr);
- d = szHdr;
- u = 0;
- while( idx<szHdr && u<p->nField && d<=nKey ){
- u32 serial_type;
-
- idx += getVarint32(&aKey[idx], serial_type);
- pMem->enc = pKeyInfo->enc;
- pMem->db = pKeyInfo->db;
- pMem->flags = 0;
- pMem->zMalloc = 0;
- d += sqlite3VdbeSerialGet(&aKey[d], serial_type, pMem);
- pMem++;
- u++;
- }
- assert( u<=pKeyInfo->nField + 1 );
- p->nField = u;
- return (void*)p;
-}
-
-/*
-** This routine destroys a UnpackedRecord object.
-*/
-SQLITE_PRIVATE void sqlite3VdbeDeleteUnpackedRecord(UnpackedRecord *p){
- int i;
- Mem *pMem;
-
- assert( p!=0 );
- assert( p->flags & UNPACKED_NEED_DESTROY );
- for(i=0, pMem=p->aMem; i<p->nField; i++, pMem++){
- /* The unpacked record is always constructed by the
- ** sqlite3VdbeUnpackRecord() function above, which makes all
- ** strings and blobs static. And none of the elements are
- ** ever transformed, so there is never anything to delete.
- */
- if( NEVER(pMem->zMalloc) ) sqlite3VdbeMemRelease(pMem);
- }
- if( p->flags & UNPACKED_NEED_FREE ){
- sqlite3DbFree(p->pKeyInfo->db, p);
- }
-}
-
-/*
-** This function compares the two table rows or index records
-** specified by {nKey1, pKey1} and pPKey2. It returns a negative, zero
-** or positive integer if key1 is less than, equal to or
-** greater than key2. The {nKey1, pKey1} key must be a blob
-** created by th OP_MakeRecord opcode of the VDBE. The pPKey2
-** key must be a parsed key such as obtained from
-** sqlite3VdbeParseRecord.
-**
-** Key1 and Key2 do not have to contain the same number of fields.
-** The key with fewer fields is usually compares less than the
-** longer key. However if the UNPACKED_INCRKEY flags in pPKey2 is set
-** and the common prefixes are equal, then key1 is less than key2.
-** 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.
-*/
-SQLITE_PRIVATE int sqlite3VdbeRecordCompare(
- int nKey1, const void *pKey1, /* Left key */
- UnpackedRecord *pPKey2 /* Right key */
-){
- int d1; /* Offset into aKey[] of next data element */
- u32 idx1; /* Offset into aKey[] of next header element */
- u32 szHdr1; /* Number of bytes in header */
- int i = 0;
- int nField;
- int rc = 0;
- const unsigned char *aKey1 = (const unsigned char *)pKey1;
- KeyInfo *pKeyInfo;
- Mem mem1;
-
- pKeyInfo = pPKey2->pKeyInfo;
- mem1.enc = pKeyInfo->enc;
- mem1.db = pKeyInfo->db;
- mem1.flags = 0;
- mem1.u.i = 0; /* not needed, here to silence compiler warning */
- mem1.zMalloc = 0;
-
- idx1 = getVarint32(aKey1, szHdr1);
- d1 = szHdr1;
- if( pPKey2->flags & UNPACKED_IGNORE_ROWID ){
- szHdr1--;
- }
- nField = pKeyInfo->nField;
- while( idx1<szHdr1 && i<pPKey2->nField ){
- u32 serial_type1;
-
- /* Read the serial types for the next element in each key. */
- idx1 += getVarint32( aKey1+idx1, serial_type1 );
- if( d1>=nKey1 && sqlite3VdbeSerialTypeLen(serial_type1)>0 ) break;
-
- /* Extract the values to be compared.
- */
- d1 += sqlite3VdbeSerialGet(&aKey1[d1], serial_type1, &mem1);
-
- /* Do the comparison
- */
- rc = sqlite3MemCompare(&mem1, &pPKey2->aMem[i],
- i<nField ? pKeyInfo->aColl[i] : 0);
- if( rc!=0 ){
- break;
- }
- i++;
- }
-
- /* No memory allocation is ever used on mem1. */
- if( NEVER(mem1.zMalloc) ) sqlite3VdbeMemRelease(&mem1);
-
- /* If the PREFIX_SEARCH flag is set and all fields except the final
- ** rowid field were equal, then clear the PREFIX_SEARCH flag and set
- ** pPKey2->rowid to the value of the rowid field in (pKey1, nKey1).
- ** This is used by the OP_IsUnique opcode.
- */
- if( (pPKey2->flags & UNPACKED_PREFIX_SEARCH) && i==(pPKey2->nField-1) ){
- assert( idx1==szHdr1 && rc );
- assert( mem1.flags & MEM_Int );
- pPKey2->flags &= ~UNPACKED_PREFIX_SEARCH;
- pPKey2->rowid = mem1.u.i;
- }
-
- if( rc==0 ){
- /* rc==0 here means that one of the keys ran out of fields and
- ** all the fields up to that point were equal. If the UNPACKED_INCRKEY
- ** flag is set, then break the tie by treating key2 as larger.
- ** If the UPACKED_PREFIX_MATCH flag is set, then keys with common prefixes
- ** are considered to be equal. Otherwise, the longer key is the
- ** larger. As it happens, the pPKey2 will always be the longer
- ** if there is a difference.
- */
- if( pPKey2->flags & UNPACKED_INCRKEY ){
- rc = -1;
- }else if( pPKey2->flags & UNPACKED_PREFIX_MATCH ){
- /* Leave rc==0 */
- }else if( idx1<szHdr1 ){
- rc = 1;
- }
- }else if( pKeyInfo->aSortOrder && i<pKeyInfo->nField
- && pKeyInfo->aSortOrder[i] ){
- rc = -rc;
- }
-
- return rc;
-}
-
-
-/*
-** pCur points at an index entry created using the OP_MakeRecord opcode.
-** Read the rowid (the last field in the record) and store it in *rowid.
-** Return SQLITE_OK if everything works, or an error code otherwise.
-**
-** pCur might be pointing to text obtained from a corrupt database file.
-** So the content cannot be trusted. Do appropriate checks on the content.
-*/
-SQLITE_PRIVATE int sqlite3VdbeIdxRowid(sqlite3 *db, BtCursor *pCur, i64 *rowid){
- i64 nCellKey = 0;
- int rc;
- u32 szHdr; /* Size of the header */
- u32 typeRowid; /* Serial type of the rowid */
- u32 lenRowid; /* Size of the rowid */
- Mem m, v;
-
- UNUSED_PARAMETER(db);
-
- /* Get the size of the index entry. Only indices entries of less
- ** than 2GiB are support - anything large must be database corruption.
- ** Any corruption is detected in sqlite3BtreeParseCellPtr(), though, so
- ** this code can safely assume that nCellKey is 32-bits
- */
- assert( sqlite3BtreeCursorIsValid(pCur) );
- rc = sqlite3BtreeKeySize(pCur, &nCellKey);
- assert( rc==SQLITE_OK ); /* pCur is always valid so KeySize cannot fail */
- assert( (nCellKey & SQLITE_MAX_U32)==(u64)nCellKey );
-
- /* Read in the complete content of the index entry */
- memset(&m, 0, sizeof(m));
- rc = sqlite3VdbeMemFromBtree(pCur, 0, (int)nCellKey, 1, &m);
- if( rc ){
- return rc;
- }
-
- /* The index entry must begin with a header size */
- (void)getVarint32((u8*)m.z, szHdr);
- testcase( szHdr==3 );
- testcase( szHdr==m.n );
- if( unlikely(szHdr<3 || (int)szHdr>m.n) ){
- goto idx_rowid_corruption;
- }
-
- /* The last field of the index should be an integer - the ROWID.
- ** Verify that the last entry really is an integer. */
- (void)getVarint32((u8*)&m.z[szHdr-1], typeRowid);
- testcase( typeRowid==1 );
- testcase( typeRowid==2 );
- testcase( typeRowid==3 );
- testcase( typeRowid==4 );
- testcase( typeRowid==5 );
- testcase( typeRowid==6 );
- testcase( typeRowid==8 );
- testcase( typeRowid==9 );
- if( unlikely(typeRowid<1 || typeRowid>9 || typeRowid==7) ){
- goto idx_rowid_corruption;
- }
- lenRowid = sqlite3VdbeSerialTypeLen(typeRowid);
- testcase( (u32)m.n==szHdr+lenRowid );
- if( unlikely((u32)m.n<szHdr+lenRowid) ){
- goto idx_rowid_corruption;
- }
-
- /* Fetch the integer off the end of the index record */
- sqlite3VdbeSerialGet((u8*)&m.z[m.n-lenRowid], typeRowid, &v);
- *rowid = v.u.i;
- sqlite3VdbeMemRelease(&m);
- return SQLITE_OK;
-
- /* Jump here if database corruption is detected after m has been
- ** allocated. Free the m object and return SQLITE_CORRUPT. */
-idx_rowid_corruption:
- testcase( m.zMalloc!=0 );
- sqlite3VdbeMemRelease(&m);
- return SQLITE_CORRUPT_BKPT;
-}
-
-/*
-** Compare the key of the index entry that cursor pC is pointing to against
-** the key string in pUnpacked. Write into *pRes a number
-** that is negative, zero, or positive if pC is less than, equal to,
-** or greater than pUnpacked. Return SQLITE_OK on success.
-**
-** pUnpacked is either created without a rowid or is truncated so that it
-** omits the rowid at the end. The rowid at the end of the index entry
-** is ignored as well. Hence, this routine only compares the prefixes
-** of the keys prior to the final rowid, not the entire key.
-*/
-SQLITE_PRIVATE int sqlite3VdbeIdxKeyCompare(
- VdbeCursor *pC, /* The cursor to compare against */
- UnpackedRecord *pUnpacked, /* Unpacked version of key to compare against */
- int *res /* Write the comparison result here */
-){
- i64 nCellKey = 0;
- int rc;
- BtCursor *pCur = pC->pCursor;
- Mem m;
-
- assert( sqlite3BtreeCursorIsValid(pCur) );
- rc = sqlite3BtreeKeySize(pCur, &nCellKey);
- assert( rc==SQLITE_OK ); /* pCur is always valid so KeySize cannot fail */
- /* nCellKey will always be between 0 and 0xffffffff because of the say
- ** that btreeParseCellPtr() and sqlite3GetVarint32() are implemented */
- if( nCellKey<=0 || nCellKey>0x7fffffff ){
- *res = 0;
- return SQLITE_CORRUPT;
- }
- memset(&m, 0, sizeof(m));
- rc = sqlite3VdbeMemFromBtree(pC->pCursor, 0, (int)nCellKey, 1, &m);
- if( rc ){
- return rc;
- }
- assert( pUnpacked->flags & UNPACKED_IGNORE_ROWID );
- *res = sqlite3VdbeRecordCompare(m.n, m.z, pUnpacked);
- sqlite3VdbeMemRelease(&m);
- return SQLITE_OK;
-}
-
-/*
-** This routine sets the value to be returned by subsequent calls to
-** sqlite3_changes() on the database handle 'db'.
-*/
-SQLITE_PRIVATE void sqlite3VdbeSetChanges(sqlite3 *db, int nChange){
- assert( sqlite3_mutex_held(db->mutex) );
- db->nChange = nChange;
- db->nTotalChange += nChange;
-}
-
-/*
-** Set a flag in the vdbe to update the change counter when it is finalised
-** or reset.
-*/
-SQLITE_PRIVATE void sqlite3VdbeCountChanges(Vdbe *v){
- v->changeCntOn = 1;
-}
-
-/*
-** Mark every prepared statement associated with a database connection
-** as expired.
-**
-** An expired statement means that recompilation of the statement is
-** recommend. Statements expire when things happen that make their
-** programs obsolete. Removing user-defined functions or collating
-** sequences, or changing an authorization function are the types of
-** things that make prepared statements obsolete.
-*/
-SQLITE_PRIVATE void sqlite3ExpirePreparedStatements(sqlite3 *db){
- Vdbe *p;
- for(p = db->pVdbe; p; p=p->pNext){
- p->expired = 1;
- }
-}
-
-/*
-** Return the database associated with the Vdbe.
-*/
-SQLITE_PRIVATE sqlite3 *sqlite3VdbeDb(Vdbe *v){
- return v->db;
-}
-
-/************** End of vdbeaux.c *********************************************/
-/************** Begin file vdbeapi.c *****************************************/
-/*
-** 2004 May 26
-**
-** 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 code use to implement APIs that are part of the
-** VDBE.
-**
-** $Id: vdbeapi.c,v 1.167 2009/06/25 01:47:12 drh Exp $
-*/
-
-#ifndef SQLITE_OMIT_DEPRECATED
-/*
-** Return TRUE (non-zero) of the statement supplied as an argument needs
-** to be recompiled. A statement needs to be recompiled whenever the
-** execution environment changes in a way that would alter the program
-** that sqlite3_prepare() generates. For example, if new functions or
-** collating sequences are registered or if an authorizer function is
-** added or changed.
-*/
-SQLITE_API int sqlite3_expired(sqlite3_stmt *pStmt){
- Vdbe *p = (Vdbe*)pStmt;
- return p==0 || p->expired;
-}
-#endif
-
-/*
-** The following routine destroys a virtual machine that is created by
-** the sqlite3_compile() routine. The integer returned is an SQLITE_
-** success/failure code that describes the result of executing the virtual
-** machine.
-**
-** This routine sets the error code and string returned by
-** sqlite3_errcode(), sqlite3_errmsg() and sqlite3_errmsg16().
-*/
-SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt){
- int rc;
- if( pStmt==0 ){
- rc = SQLITE_OK;
- }else{
- Vdbe *v = (Vdbe*)pStmt;
- sqlite3 *db = v->db;
-#if SQLITE_THREADSAFE
- sqlite3_mutex *mutex = v->db->mutex;
-#endif
- sqlite3_mutex_enter(mutex);
- rc = sqlite3VdbeFinalize(v);
- rc = sqlite3ApiExit(db, rc);
- sqlite3_mutex_leave(mutex);
- }
- return rc;
-}
-
-/*
-** Terminate the current execution of an SQL statement and reset it
-** back to its starting state so that it can be reused. A success code from
-** the prior execution is returned.
-**
-** This routine sets the error code and string returned by
-** sqlite3_errcode(), sqlite3_errmsg() and sqlite3_errmsg16().
-*/
-SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt){
- int rc;
- if( pStmt==0 ){
- rc = SQLITE_OK;
- }else{
- Vdbe *v = (Vdbe*)pStmt;
- sqlite3_mutex_enter(v->db->mutex);
- rc = sqlite3VdbeReset(v);
- sqlite3VdbeMakeReady(v, -1, 0, 0, 0, 0, 0);
- assert( (rc & (v->db->errMask))==rc );
- rc = sqlite3ApiExit(v->db, rc);
- sqlite3_mutex_leave(v->db->mutex);
- }
- return rc;
-}
-
-/*
-** Set all the parameters in the compiled SQL statement to NULL.
-*/
-SQLITE_API int sqlite3_clear_bindings(sqlite3_stmt *pStmt){
- int i;
- int rc = SQLITE_OK;
- Vdbe *p = (Vdbe*)pStmt;
-#if SQLITE_THREADSAFE
- sqlite3_mutex *mutex = ((Vdbe*)pStmt)->db->mutex;
-#endif
- sqlite3_mutex_enter(mutex);
- for(i=0; i<p->nVar; i++){
- sqlite3VdbeMemRelease(&p->aVar[i]);
- p->aVar[i].flags = MEM_Null;
- }
- sqlite3_mutex_leave(mutex);
- return rc;
-}
-
-
-/**************************** sqlite3_value_ *******************************
-** The following routines extract information from a Mem or sqlite3_value
-** structure.
-*/
-SQLITE_API const void *sqlite3_value_blob(sqlite3_value *pVal){
- Mem *p = (Mem*)pVal;
- if( p->flags & (MEM_Blob|MEM_Str) ){
- sqlite3VdbeMemExpandBlob(p);
- p->flags &= ~MEM_Str;
- p->flags |= MEM_Blob;
- return p->z;
- }else{
- return sqlite3_value_text(pVal);
- }
-}
-SQLITE_API int sqlite3_value_bytes(sqlite3_value *pVal){
- return sqlite3ValueBytes(pVal, SQLITE_UTF8);
-}
-SQLITE_API int sqlite3_value_bytes16(sqlite3_value *pVal){
- return sqlite3ValueBytes(pVal, SQLITE_UTF16NATIVE);
-}
-SQLITE_API double sqlite3_value_double(sqlite3_value *pVal){
- return sqlite3VdbeRealValue((Mem*)pVal);
-}
-SQLITE_API int sqlite3_value_int(sqlite3_value *pVal){
- return (int)sqlite3VdbeIntValue((Mem*)pVal);
-}
-SQLITE_API sqlite_int64 sqlite3_value_int64(sqlite3_value *pVal){
- return sqlite3VdbeIntValue((Mem*)pVal);
-}
-SQLITE_API const unsigned char *sqlite3_value_text(sqlite3_value *pVal){
- return (const unsigned char *)sqlite3ValueText(pVal, SQLITE_UTF8);
-}
-#ifndef SQLITE_OMIT_UTF16
-SQLITE_API const void *sqlite3_value_text16(sqlite3_value* pVal){
- return sqlite3ValueText(pVal, SQLITE_UTF16NATIVE);
-}
-SQLITE_API const void *sqlite3_value_text16be(sqlite3_value *pVal){
- return sqlite3ValueText(pVal, SQLITE_UTF16BE);
-}
-SQLITE_API const void *sqlite3_value_text16le(sqlite3_value *pVal){
- return sqlite3ValueText(pVal, SQLITE_UTF16LE);
-}
-#endif /* SQLITE_OMIT_UTF16 */
-SQLITE_API int sqlite3_value_type(sqlite3_value* pVal){
- return pVal->type;
-}
-
-/**************************** sqlite3_result_ *******************************
-** The following routines are used by user-defined functions to specify
-** the function result.
-**
-** The setStrOrError() funtion calls sqlite3VdbeMemSetStr() to store the
-** result as a string or blob but if the string or blob is too large, it
-** then sets the error code to SQLITE_TOOBIG
-*/
-static void setResultStrOrError(
- sqlite3_context *pCtx, /* Function context */
- const char *z, /* String pointer */
- int n, /* Bytes in string, or negative */
- u8 enc, /* Encoding of z. 0 for BLOBs */
- void (*xDel)(void*) /* Destructor function */
-){
- if( sqlite3VdbeMemSetStr(&pCtx->s, z, n, enc, xDel)==SQLITE_TOOBIG ){
- sqlite3_result_error_toobig(pCtx);
- }
-}
-SQLITE_API void sqlite3_result_blob(
- sqlite3_context *pCtx,
- const void *z,
- int n,
- void (*xDel)(void *)
-){
- assert( n>=0 );
- assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
- setResultStrOrError(pCtx, z, n, 0, xDel);
-}
-SQLITE_API void sqlite3_result_double(sqlite3_context *pCtx, double rVal){
- assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
- sqlite3VdbeMemSetDouble(&pCtx->s, rVal);
-}
-SQLITE_API void sqlite3_result_error(sqlite3_context *pCtx, const char *z, int n){
- assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
- pCtx->isError = SQLITE_ERROR;
- sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF8, SQLITE_TRANSIENT);
-}
-#ifndef SQLITE_OMIT_UTF16
-SQLITE_API void sqlite3_result_error16(sqlite3_context *pCtx, const void *z, int n){
- assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
- pCtx->isError = SQLITE_ERROR;
- sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF16NATIVE, SQLITE_TRANSIENT);
-}
-#endif
-SQLITE_API void sqlite3_result_int(sqlite3_context *pCtx, int iVal){
- assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
- sqlite3VdbeMemSetInt64(&pCtx->s, (i64)iVal);
-}
-SQLITE_API void sqlite3_result_int64(sqlite3_context *pCtx, i64 iVal){
- assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
- sqlite3VdbeMemSetInt64(&pCtx->s, iVal);
-}
-SQLITE_API void sqlite3_result_null(sqlite3_context *pCtx){
- assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
- sqlite3VdbeMemSetNull(&pCtx->s);
-}
-SQLITE_API void sqlite3_result_text(
- sqlite3_context *pCtx,
- const char *z,
- int n,
- void (*xDel)(void *)
-){
- assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
- setResultStrOrError(pCtx, z, n, SQLITE_UTF8, xDel);
-}
-#ifndef SQLITE_OMIT_UTF16
-SQLITE_API void sqlite3_result_text16(
- sqlite3_context *pCtx,
- const void *z,
- int n,
- void (*xDel)(void *)
-){
- assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
- setResultStrOrError(pCtx, z, n, SQLITE_UTF16NATIVE, xDel);
-}
-SQLITE_API void sqlite3_result_text16be(
- sqlite3_context *pCtx,
- const void *z,
- int n,
- void (*xDel)(void *)
-){
- assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
- setResultStrOrError(pCtx, z, n, SQLITE_UTF16BE, xDel);
-}
-SQLITE_API void sqlite3_result_text16le(
- sqlite3_context *pCtx,
- const void *z,
- int n,
- void (*xDel)(void *)
-){
- assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
- setResultStrOrError(pCtx, z, n, SQLITE_UTF16LE, xDel);
-}
-#endif /* SQLITE_OMIT_UTF16 */
-SQLITE_API void sqlite3_result_value(sqlite3_context *pCtx, sqlite3_value *pValue){
- assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
- sqlite3VdbeMemCopy(&pCtx->s, pValue);
-}
-SQLITE_API void sqlite3_result_zeroblob(sqlite3_context *pCtx, int n){
- assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
- sqlite3VdbeMemSetZeroBlob(&pCtx->s, n);
-}
-SQLITE_API void sqlite3_result_error_code(sqlite3_context *pCtx, int errCode){
- pCtx->isError = errCode;
- if( pCtx->s.flags & MEM_Null ){
- sqlite3VdbeMemSetStr(&pCtx->s, sqlite3ErrStr(errCode), -1,
- SQLITE_UTF8, SQLITE_STATIC);
- }
-}
-
-/* Force an SQLITE_TOOBIG error. */
-SQLITE_API void sqlite3_result_error_toobig(sqlite3_context *pCtx){
- assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
- pCtx->isError = SQLITE_TOOBIG;
- sqlite3VdbeMemSetStr(&pCtx->s, "string or blob too big", -1,
- SQLITE_UTF8, SQLITE_STATIC);
-}
-
-/* An SQLITE_NOMEM error. */
-SQLITE_API void sqlite3_result_error_nomem(sqlite3_context *pCtx){
- assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
- sqlite3VdbeMemSetNull(&pCtx->s);
- pCtx->isError = SQLITE_NOMEM;
- pCtx->s.db->mallocFailed = 1;
-}
-
-/*
-** Execute the statement pStmt, either until a row of data is ready, the
-** statement is completely executed or an error occurs.
-**
-** This routine implements the bulk of the logic behind the sqlite_step()
-** API. The only thing omitted is the automatic recompile if a
-** schema change has occurred. That detail is handled by the
-** outer sqlite3_step() wrapper procedure.
-*/
-static int sqlite3Step(Vdbe *p){
- sqlite3 *db;
- int rc;
-
- assert(p);
- if( p->magic!=VDBE_MAGIC_RUN ){
- return SQLITE_MISUSE;
- }
-
- /* Assert that malloc() has not failed */
- db = p->db;
- if( db->mallocFailed ){
- return SQLITE_NOMEM;
- }
-
- if( p->pc<=0 && p->expired ){
- if( ALWAYS(p->rc==SQLITE_OK) ){
- p->rc = SQLITE_SCHEMA;
- }
- rc = SQLITE_ERROR;
- goto end_of_step;
- }
- if( sqlite3SafetyOn(db) ){
- p->rc = SQLITE_MISUSE;
- return SQLITE_MISUSE;
- }
- if( p->pc<0 ){
- /* If there are no other statements currently running, then
- ** reset the interrupt flag. This prevents a call to sqlite3_interrupt
- ** from interrupting a statement that has not yet started.
- */
- if( db->activeVdbeCnt==0 ){
- db->u1.isInterrupted = 0;
- }
-
-#ifndef SQLITE_OMIT_TRACE
- if( db->xProfile && !db->init.busy ){
- double rNow;
- sqlite3OsCurrentTime(db->pVfs, &rNow);
- p->startTime = (u64)((rNow - (int)rNow)*3600.0*24.0*1000000000.0);
- }
-#endif
-
- db->activeVdbeCnt++;
- if( p->readOnly==0 ) db->writeVdbeCnt++;
- p->pc = 0;
- }
-#ifndef SQLITE_OMIT_EXPLAIN
- if( p->explain ){
- rc = sqlite3VdbeList(p);
- }else
-#endif /* SQLITE_OMIT_EXPLAIN */
- {
- rc = sqlite3VdbeExec(p);
- }
-
- if( sqlite3SafetyOff(db) ){
- rc = SQLITE_MISUSE;
- }
-
-#ifndef SQLITE_OMIT_TRACE
- /* Invoke the profile callback if there is one
- */
- if( rc!=SQLITE_ROW && db->xProfile && !db->init.busy && p->zSql ){
- double rNow;
- u64 elapseTime;
-
- sqlite3OsCurrentTime(db->pVfs, &rNow);
- elapseTime = (u64)((rNow - (int)rNow)*3600.0*24.0*1000000000.0);
- elapseTime -= p->startTime;
- db->xProfile(db->pProfileArg, p->zSql, elapseTime);
- }
-#endif
-
- db->errCode = rc;
- if( SQLITE_NOMEM==sqlite3ApiExit(p->db, p->rc) ){
- p->rc = SQLITE_NOMEM;
- }
-end_of_step:
- /* At this point local variable rc holds the value that should be
- ** returned if this statement was compiled using the legacy
- ** sqlite3_prepare() interface. According to the docs, this can only
- ** be one of the values in the first assert() below. Variable p->rc
- ** contains the value that would be returned if sqlite3_finalize()
- ** were called on statement p.
- */
- assert( rc==SQLITE_ROW || rc==SQLITE_DONE || rc==SQLITE_ERROR
- || rc==SQLITE_BUSY || rc==SQLITE_MISUSE
- );
- assert( p->rc!=SQLITE_ROW && p->rc!=SQLITE_DONE );
- if( p->isPrepareV2 && rc!=SQLITE_ROW && rc!=SQLITE_DONE ){
- /* If this statement was prepared using sqlite3_prepare_v2(), and an
- ** error has occured, then return the error code in p->rc to the
- ** caller. Set the error code in the database handle to the same value.
- */
- rc = db->errCode = p->rc;
- }
- return (rc&db->errMask);
-}
-
-/*
-** This is the top-level implementation of sqlite3_step(). Call
-** sqlite3Step() to do most of the work. If a schema error occurs,
-** call sqlite3Reprepare() and try again.
-*/
-SQLITE_API int sqlite3_step(sqlite3_stmt *pStmt){
- int rc = SQLITE_MISUSE;
- if( pStmt ){
- int cnt = 0;
- Vdbe *v = (Vdbe*)pStmt;
- sqlite3 *db = v->db;
- sqlite3_mutex_enter(db->mutex);
- while( (rc = sqlite3Step(v))==SQLITE_SCHEMA
- && cnt++ < 5
- && (rc = sqlite3Reprepare(v))==SQLITE_OK ){
- sqlite3_reset(pStmt);
- v->expired = 0;
- }
- if( rc==SQLITE_SCHEMA && ALWAYS(v->isPrepareV2) && ALWAYS(db->pErr) ){
- /* This case occurs after failing to recompile an sql statement.
- ** The error message from the SQL compiler has already been loaded
- ** into the database handle. This block copies the error message
- ** from the database handle into the statement and sets the statement
- ** program counter to 0 to ensure that when the statement is
- ** finalized or reset the parser error message is available via
- ** sqlite3_errmsg() and sqlite3_errcode().
- */
- const char *zErr = (const char *)sqlite3_value_text(db->pErr);
- sqlite3DbFree(db, v->zErrMsg);
- if( !db->mallocFailed ){
- v->zErrMsg = sqlite3DbStrDup(db, zErr);
- } else {
- v->zErrMsg = 0;
- v->rc = SQLITE_NOMEM;
- }
- }
- rc = sqlite3ApiExit(db, rc);
- sqlite3_mutex_leave(db->mutex);
- }
- return rc;
-}
-
-/*
-** Extract the user data from a sqlite3_context structure and return a
-** pointer to it.
-*/
-SQLITE_API void *sqlite3_user_data(sqlite3_context *p){
- assert( p && p->pFunc );
- return p->pFunc->pUserData;
-}
-
-/*
-** Extract the user data from a sqlite3_context structure and return a
-** pointer to it.
-*/
-SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context *p){
- assert( p && p->pFunc );
- return p->s.db;
-}
-
-/*
-** The following is the implementation of an SQL function that always
-** fails with an error message stating that the function is used in the
-** wrong context. The sqlite3_overload_function() API might construct
-** SQL function that use this routine so that the functions will exist
-** for name resolution but are actually overloaded by the xFindFunction
-** method of virtual tables.
-*/
-SQLITE_PRIVATE void sqlite3InvalidFunction(
- sqlite3_context *context, /* The function calling context */
- int NotUsed, /* Number of arguments to the function */
- sqlite3_value **NotUsed2 /* Value of each argument */
-){
- const char *zName = context->pFunc->zName;
- char *zErr;
- UNUSED_PARAMETER2(NotUsed, NotUsed2);
- zErr = sqlite3_mprintf(
- "unable to use function %s in the requested context", zName);
- sqlite3_result_error(context, zErr, -1);
- sqlite3_free(zErr);
-}
-
-/*
-** Allocate or return the aggregate context for a user function. A new
-** context is allocated on the first call. Subsequent calls return the
-** same context that was returned on prior calls.
-*/
-SQLITE_API void *sqlite3_aggregate_context(sqlite3_context *p, int nByte){
- Mem *pMem;
- assert( p && p->pFunc && p->pFunc->xStep );
- assert( sqlite3_mutex_held(p->s.db->mutex) );
- pMem = p->pMem;
- if( (pMem->flags & MEM_Agg)==0 ){
- if( nByte==0 ){
- sqlite3VdbeMemReleaseExternal(pMem);
- pMem->flags = MEM_Null;
- pMem->z = 0;
- }else{
- sqlite3VdbeMemGrow(pMem, nByte, 0);
- pMem->flags = MEM_Agg;
- pMem->u.pDef = p->pFunc;
- if( pMem->z ){
- memset(pMem->z, 0, nByte);
- }
- }
- }
- return (void*)pMem->z;
-}
-
-/*
-** Return the auxilary data pointer, if any, for the iArg'th argument to
-** the user-function defined by pCtx.
-*/
-SQLITE_API void *sqlite3_get_auxdata(sqlite3_context *pCtx, int iArg){
- VdbeFunc *pVdbeFunc;
-
- assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
- pVdbeFunc = pCtx->pVdbeFunc;
- if( !pVdbeFunc || iArg>=pVdbeFunc->nAux || iArg<0 ){
- return 0;
- }
- return pVdbeFunc->apAux[iArg].pAux;
-}
-
-/*
-** Set the auxilary data pointer and delete function, for the iArg'th
-** argument to the user-function defined by pCtx. Any previous value is
-** deleted by calling the delete function specified when it was set.
-*/
-SQLITE_API void sqlite3_set_auxdata(
- sqlite3_context *pCtx,
- int iArg,
- void *pAux,
- void (*xDelete)(void*)
-){
- struct AuxData *pAuxData;
- VdbeFunc *pVdbeFunc;
- if( iArg<0 ) goto failed;
-
- assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
- pVdbeFunc = pCtx->pVdbeFunc;
- if( !pVdbeFunc || pVdbeFunc->nAux<=iArg ){
- int nAux = (pVdbeFunc ? pVdbeFunc->nAux : 0);
- int nMalloc = sizeof(VdbeFunc) + sizeof(struct AuxData)*iArg;
- pVdbeFunc = sqlite3DbRealloc(pCtx->s.db, pVdbeFunc, nMalloc);
- if( !pVdbeFunc ){
- goto failed;
- }
- pCtx->pVdbeFunc = pVdbeFunc;
- memset(&pVdbeFunc->apAux[nAux], 0, sizeof(struct AuxData)*(iArg+1-nAux));
- pVdbeFunc->nAux = iArg+1;
- pVdbeFunc->pFunc = pCtx->pFunc;
- }
-
- pAuxData = &pVdbeFunc->apAux[iArg];
- if( pAuxData->pAux && pAuxData->xDelete ){
- pAuxData->xDelete(pAuxData->pAux);
- }
- pAuxData->pAux = pAux;
- pAuxData->xDelete = xDelete;
- return;
-
-failed:
- if( xDelete ){
- xDelete(pAux);
- }
-}
-
-#ifndef SQLITE_OMIT_DEPRECATED
-/*
-** Return the number of times the Step function of a aggregate has been
-** called.
-**
-** This function is deprecated. Do not use it for new code. It is
-** provide only to avoid breaking legacy code. New aggregate function
-** implementations should keep their own counts within their aggregate
-** context.
-*/
-SQLITE_API int sqlite3_aggregate_count(sqlite3_context *p){
- assert( p && p->pMem && p->pFunc && p->pFunc->xStep );
- return p->pMem->n;
-}
-#endif
-
-/*
-** Return the number of columns in the result set for the statement pStmt.
-*/
-SQLITE_API int sqlite3_column_count(sqlite3_stmt *pStmt){
- Vdbe *pVm = (Vdbe *)pStmt;
- return pVm ? pVm->nResColumn : 0;
-}
-
-/*
-** Return the number of values available from the current row of the
-** currently executing statement pStmt.
-*/
-SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt){
- Vdbe *pVm = (Vdbe *)pStmt;
- if( pVm==0 || pVm->pResultSet==0 ) return 0;
- return pVm->nResColumn;
-}
-
-
-/*
-** Check to see if column iCol of the given statement is valid. If
-** it is, return a pointer to the Mem for the value of that column.
-** If iCol is not valid, return a pointer to a Mem which has a value
-** of NULL.
-*/
-static Mem *columnMem(sqlite3_stmt *pStmt, int i){
- Vdbe *pVm;
- int vals;
- Mem *pOut;
-
- pVm = (Vdbe *)pStmt;
- if( pVm && pVm->pResultSet!=0 && i<pVm->nResColumn && i>=0 ){
- sqlite3_mutex_enter(pVm->db->mutex);
- vals = sqlite3_data_count(pStmt);
- pOut = &pVm->pResultSet[i];
- }else{
- /* 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
- ** 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
- ** __attribute__((aligned(8))) macro. */
- static const Mem nullMem
-#if defined(SQLITE_DEBUG) && defined(__GNUC__)
- __attribute__((aligned(8)))
-#endif
- = {{0}, (double)0, 0, "", 0, MEM_Null, SQLITE_NULL, 0, 0, 0 };
-
- if( pVm && ALWAYS(pVm->db) ){
- sqlite3_mutex_enter(pVm->db->mutex);
- sqlite3Error(pVm->db, SQLITE_RANGE, 0);
- }
- pOut = (Mem*)&nullMem;
- }
- return pOut;
-}
-
-/*
-** This function is called after invoking an sqlite3_value_XXX function on a
-** column value (i.e. a value returned by evaluating an SQL expression in the
-** select list of a SELECT statement) that may cause a malloc() failure. If
-** malloc() has failed, the threads mallocFailed flag is cleared and the result
-** code of statement pStmt set to SQLITE_NOMEM.
-**
-** Specifically, this is called from within:
-**
-** sqlite3_column_int()
-** sqlite3_column_int64()
-** sqlite3_column_text()
-** sqlite3_column_text16()
-** sqlite3_column_real()
-** sqlite3_column_bytes()
-** sqlite3_column_bytes16()
-**
-** But not for sqlite3_column_blob(), which never calls malloc().
-*/
-static void columnMallocFailure(sqlite3_stmt *pStmt)
-{
- /* If malloc() failed during an encoding conversion within an
- ** sqlite3_column_XXX API, then set the return code of the statement to
- ** SQLITE_NOMEM. The next call to _step() (if any) will return SQLITE_ERROR
- ** and _finalize() will return NOMEM.
- */
- Vdbe *p = (Vdbe *)pStmt;
- if( p ){
- p->rc = sqlite3ApiExit(p->db, p->rc);
- sqlite3_mutex_leave(p->db->mutex);
- }
-}
-
-/**************************** sqlite3_column_ *******************************
-** The following routines are used to access elements of the current row
-** in the result set.
-*/
-SQLITE_API const void *sqlite3_column_blob(sqlite3_stmt *pStmt, int i){
- const void *val;
- val = sqlite3_value_blob( columnMem(pStmt,i) );
- /* Even though there is no encoding conversion, value_blob() might
- ** need to call malloc() to expand the result of a zeroblob()
- ** expression.
- */
- columnMallocFailure(pStmt);
- return val;
-}
-SQLITE_API int sqlite3_column_bytes(sqlite3_stmt *pStmt, int i){
- int val = sqlite3_value_bytes( columnMem(pStmt,i) );
- columnMallocFailure(pStmt);
- return val;
-}
-SQLITE_API int sqlite3_column_bytes16(sqlite3_stmt *pStmt, int i){
- int val = sqlite3_value_bytes16( columnMem(pStmt,i) );
- columnMallocFailure(pStmt);
- return val;
-}
-SQLITE_API double sqlite3_column_double(sqlite3_stmt *pStmt, int i){
- double val = sqlite3_value_double( columnMem(pStmt,i) );
- columnMallocFailure(pStmt);
- return val;
-}
-SQLITE_API int sqlite3_column_int(sqlite3_stmt *pStmt, int i){
- int val = sqlite3_value_int( columnMem(pStmt,i) );
- columnMallocFailure(pStmt);
- return val;
-}
-SQLITE_API sqlite_int64 sqlite3_column_int64(sqlite3_stmt *pStmt, int i){
- sqlite_int64 val = sqlite3_value_int64( columnMem(pStmt,i) );
- columnMallocFailure(pStmt);
- return val;
-}
-SQLITE_API const unsigned char *sqlite3_column_text(sqlite3_stmt *pStmt, int i){
- const unsigned char *val = sqlite3_value_text( columnMem(pStmt,i) );
- columnMallocFailure(pStmt);
- return val;
-}
-SQLITE_API sqlite3_value *sqlite3_column_value(sqlite3_stmt *pStmt, int i){
- Mem *pOut = columnMem(pStmt, i);
- if( pOut->flags&MEM_Static ){
- pOut->flags &= ~MEM_Static;
- pOut->flags |= MEM_Ephem;
- }
- columnMallocFailure(pStmt);
- return (sqlite3_value *)pOut;
-}
-#ifndef SQLITE_OMIT_UTF16
-SQLITE_API const void *sqlite3_column_text16(sqlite3_stmt *pStmt, int i){
- const void *val = sqlite3_value_text16( columnMem(pStmt,i) );
- columnMallocFailure(pStmt);
- return val;
-}
-#endif /* SQLITE_OMIT_UTF16 */
-SQLITE_API int sqlite3_column_type(sqlite3_stmt *pStmt, int i){
- int iType = sqlite3_value_type( columnMem(pStmt,i) );
- columnMallocFailure(pStmt);
- return iType;
-}
-
-/* The following function is experimental and subject to change or
-** removal */
-/*int sqlite3_column_numeric_type(sqlite3_stmt *pStmt, int i){
-** return sqlite3_value_numeric_type( columnMem(pStmt,i) );
-**}
-*/
-
-/*
-** Convert the N-th element of pStmt->pColName[] into a string using
-** xFunc() then return that string. If N is out of range, return 0.
-**
-** There are up to 5 names for each column. useType determines which
-** name is returned. Here are the names:
-**
-** 0 The column name as it should be displayed for output
-** 1 The datatype name for the column
-** 2 The name of the database that the column derives from
-** 3 The name of the table that the column derives from
-** 4 The name of the table column that the result column derives from
-**
-** If the result is not a simple column reference (if it is an expression
-** or a constant) then useTypes 2, 3, and 4 return NULL.
-*/
-static const void *columnName(
- sqlite3_stmt *pStmt,
- int N,
- const void *(*xFunc)(Mem*),
- int useType
-){
- const void *ret = 0;
- Vdbe *p = (Vdbe *)pStmt;
- int n;
- sqlite3 *db = p->db;
-
- assert( db!=0 );
- n = sqlite3_column_count(pStmt);
- if( N<n && N>=0 ){
- N += useType*n;
- sqlite3_mutex_enter(db->mutex);
- assert( db->mallocFailed==0 );
- ret = xFunc(&p->aColName[N]);
- /* A malloc may have failed inside of the xFunc() call. If this
- ** is the case, clear the mallocFailed flag and return NULL.
- */
- if( db->mallocFailed ){
- db->mallocFailed = 0;
- ret = 0;
- }
- sqlite3_mutex_leave(db->mutex);
- }
- return ret;
-}
-
-/*
-** Return the name of the Nth column of the result set returned by SQL
-** statement pStmt.
-*/
-SQLITE_API const char *sqlite3_column_name(sqlite3_stmt *pStmt, int N){
- return columnName(
- pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, COLNAME_NAME);
-}
-#ifndef SQLITE_OMIT_UTF16
-SQLITE_API const void *sqlite3_column_name16(sqlite3_stmt *pStmt, int N){
- return columnName(
- pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, COLNAME_NAME);
-}
-#endif
-
-/*
-** Constraint: If you have ENABLE_COLUMN_METADATA then you must
-** not define OMIT_DECLTYPE.
-*/
-#if defined(SQLITE_OMIT_DECLTYPE) && defined(SQLITE_ENABLE_COLUMN_METADATA)
-# error "Must not define both SQLITE_OMIT_DECLTYPE \
- and SQLITE_ENABLE_COLUMN_METADATA"
-#endif
-
-#ifndef SQLITE_OMIT_DECLTYPE
-/*
-** Return the column declaration type (if applicable) of the 'i'th column
-** of the result set of SQL statement pStmt.
-*/
-SQLITE_API const char *sqlite3_column_decltype(sqlite3_stmt *pStmt, int N){
- return columnName(
- pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, COLNAME_DECLTYPE);
-}
-#ifndef SQLITE_OMIT_UTF16
-SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt *pStmt, int N){
- return columnName(
- pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, COLNAME_DECLTYPE);
-}
-#endif /* SQLITE_OMIT_UTF16 */
-#endif /* SQLITE_OMIT_DECLTYPE */
-
-#ifdef SQLITE_ENABLE_COLUMN_METADATA
-/*
-** Return the name of the database from which a result column derives.
-** NULL is returned if the result column is an expression or constant or
-** anything else which is not an unabiguous reference to a database column.
-*/
-SQLITE_API const char *sqlite3_column_database_name(sqlite3_stmt *pStmt, int N){
- return columnName(
- pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, COLNAME_DATABASE);
-}
-#ifndef SQLITE_OMIT_UTF16
-SQLITE_API const void *sqlite3_column_database_name16(sqlite3_stmt *pStmt, int N){
- return columnName(
- pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, COLNAME_DATABASE);
-}
-#endif /* SQLITE_OMIT_UTF16 */
-
-/*
-** Return the name of the table from which a result column derives.
-** NULL is returned if the result column is an expression or constant or
-** anything else which is not an unabiguous reference to a database column.
-*/
-SQLITE_API const char *sqlite3_column_table_name(sqlite3_stmt *pStmt, int N){
- return columnName(
- pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, COLNAME_TABLE);
-}
-#ifndef SQLITE_OMIT_UTF16
-SQLITE_API const void *sqlite3_column_table_name16(sqlite3_stmt *pStmt, int N){
- return columnName(
- pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, COLNAME_TABLE);
-}
-#endif /* SQLITE_OMIT_UTF16 */
-
-/*
-** Return the name of the table column from which a result column derives.
-** NULL is returned if the result column is an expression or constant or
-** anything else which is not an unabiguous reference to a database column.
-*/
-SQLITE_API const char *sqlite3_column_origin_name(sqlite3_stmt *pStmt, int N){
- return columnName(
- pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, COLNAME_COLUMN);
-}
-#ifndef SQLITE_OMIT_UTF16
-SQLITE_API const void *sqlite3_column_origin_name16(sqlite3_stmt *pStmt, int N){
- return columnName(
- pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, COLNAME_COLUMN);
-}
-#endif /* SQLITE_OMIT_UTF16 */
-#endif /* SQLITE_ENABLE_COLUMN_METADATA */
-
-
-/******************************* sqlite3_bind_ ***************************
-**
-** Routines used to attach values to wildcards in a compiled SQL statement.
-*/
-/*
-** Unbind the value bound to variable i in virtual machine p. This is the
-** the same as binding a NULL value to the column. If the "i" parameter is
-** out of range, then SQLITE_RANGE is returned. Othewise SQLITE_OK.
-**
-** A successful evaluation of this routine acquires the mutex on p.
-** the mutex is released if any kind of error occurs.
-**
-** The error code stored in database p->db is overwritten with the return
-** value in any case.
-*/
-static int vdbeUnbind(Vdbe *p, int i){
- Mem *pVar;
- if( p==0 ) return SQLITE_MISUSE;
- sqlite3_mutex_enter(p->db->mutex);
- if( p->magic!=VDBE_MAGIC_RUN || p->pc>=0 ){
- sqlite3Error(p->db, SQLITE_MISUSE, 0);
- sqlite3_mutex_leave(p->db->mutex);
- return SQLITE_MISUSE;
- }
- if( i<1 || i>p->nVar ){
- sqlite3Error(p->db, SQLITE_RANGE, 0);
- sqlite3_mutex_leave(p->db->mutex);
- return SQLITE_RANGE;
- }
- i--;
- pVar = &p->aVar[i];
- sqlite3VdbeMemRelease(pVar);
- pVar->flags = MEM_Null;
- sqlite3Error(p->db, SQLITE_OK, 0);
- return SQLITE_OK;
-}
-
-/*
-** Bind a text or BLOB value.
-*/
-static int bindText(
- sqlite3_stmt *pStmt, /* The statement to bind against */
- int i, /* Index of the parameter to bind */
- const void *zData, /* Pointer to the data to be bound */
- int nData, /* Number of bytes of data to be bound */
- void (*xDel)(void*), /* Destructor for the data */
- u8 encoding /* Encoding for the data */
-){
- Vdbe *p = (Vdbe *)pStmt;
- Mem *pVar;
- int rc;
-
- rc = vdbeUnbind(p, i);
- if( rc==SQLITE_OK ){
- if( zData!=0 ){
- pVar = &p->aVar[i-1];
- rc = sqlite3VdbeMemSetStr(pVar, zData, nData, encoding, xDel);
- if( rc==SQLITE_OK && encoding!=0 ){
- rc = sqlite3VdbeChangeEncoding(pVar, ENC(p->db));
- }
- sqlite3Error(p->db, rc, 0);
- rc = sqlite3ApiExit(p->db, rc);
- }
- sqlite3_mutex_leave(p->db->mutex);
- }
- return rc;
-}
-
-
-/*
-** Bind a blob value to an SQL statement variable.
-*/
-SQLITE_API int sqlite3_bind_blob(
- sqlite3_stmt *pStmt,
- int i,
- const void *zData,
- int nData,
- void (*xDel)(void*)
-){
- return bindText(pStmt, i, zData, nData, xDel, 0);
-}
-SQLITE_API int sqlite3_bind_double(sqlite3_stmt *pStmt, int i, double rValue){
- int rc;
- Vdbe *p = (Vdbe *)pStmt;
- rc = vdbeUnbind(p, i);
- if( rc==SQLITE_OK ){
- sqlite3VdbeMemSetDouble(&p->aVar[i-1], rValue);
- sqlite3_mutex_leave(p->db->mutex);
- }
- return rc;
-}
-SQLITE_API int sqlite3_bind_int(sqlite3_stmt *p, int i, int iValue){
- return sqlite3_bind_int64(p, i, (i64)iValue);
-}
-SQLITE_API int sqlite3_bind_int64(sqlite3_stmt *pStmt, int i, sqlite_int64 iValue){
- int rc;
- Vdbe *p = (Vdbe *)pStmt;
- rc = vdbeUnbind(p, i);
- if( rc==SQLITE_OK ){
- sqlite3VdbeMemSetInt64(&p->aVar[i-1], iValue);
- sqlite3_mutex_leave(p->db->mutex);
- }
- return rc;
-}
-SQLITE_API int sqlite3_bind_null(sqlite3_stmt *pStmt, int i){
- int rc;
- Vdbe *p = (Vdbe*)pStmt;
- rc = vdbeUnbind(p, i);
- if( rc==SQLITE_OK ){
- sqlite3_mutex_leave(p->db->mutex);
- }
- return rc;
-}
-SQLITE_API int sqlite3_bind_text(
- sqlite3_stmt *pStmt,
- int i,
- const char *zData,
- int nData,
- void (*xDel)(void*)
-){
- return bindText(pStmt, i, zData, nData, xDel, SQLITE_UTF8);
-}
-#ifndef SQLITE_OMIT_UTF16
-SQLITE_API int sqlite3_bind_text16(
- sqlite3_stmt *pStmt,
- int i,
- const void *zData,
- int nData,
- void (*xDel)(void*)
-){
- return bindText(pStmt, i, zData, nData, xDel, SQLITE_UTF16NATIVE);
-}
-#endif /* SQLITE_OMIT_UTF16 */
-SQLITE_API int sqlite3_bind_value(sqlite3_stmt *pStmt, int i, const sqlite3_value *pValue){
- int rc;
- switch( pValue->type ){
- case SQLITE_INTEGER: {
- rc = sqlite3_bind_int64(pStmt, i, pValue->u.i);
- break;
- }
- case SQLITE_FLOAT: {
- rc = sqlite3_bind_double(pStmt, i, pValue->r);
- break;
- }
- case SQLITE_BLOB: {
- if( pValue->flags & MEM_Zero ){
- rc = sqlite3_bind_zeroblob(pStmt, i, pValue->u.nZero);
- }else{
- rc = sqlite3_bind_blob(pStmt, i, pValue->z, pValue->n,SQLITE_TRANSIENT);
- }
- break;
- }
- case SQLITE_TEXT: {
- rc = bindText(pStmt,i, pValue->z, pValue->n, SQLITE_TRANSIENT,
- pValue->enc);
- break;
- }
- default: {
- rc = sqlite3_bind_null(pStmt, i);
- break;
- }
- }
- return rc;
-}
-SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt *pStmt, int i, int n){
- int rc;
- Vdbe *p = (Vdbe *)pStmt;
- rc = vdbeUnbind(p, i);
- if( rc==SQLITE_OK ){
- sqlite3VdbeMemSetZeroBlob(&p->aVar[i-1], n);
- sqlite3_mutex_leave(p->db->mutex);
- }
- return rc;
-}
-
-/*
-** Return the number of wildcards that can be potentially bound to.
-** This routine is added to support DBD::SQLite.
-*/
-SQLITE_API int sqlite3_bind_parameter_count(sqlite3_stmt *pStmt){
- Vdbe *p = (Vdbe*)pStmt;
- return p ? p->nVar : 0;
-}
-
-/*
-** Create a mapping from variable numbers to variable names
-** in the Vdbe.azVar[] array, if such a mapping does not already
-** exist.
-*/
-static void createVarMap(Vdbe *p){
- if( !p->okVar ){
- int j;
- Op *pOp;
- sqlite3_mutex_enter(p->db->mutex);
- /* The race condition here is harmless. If two threads call this
- ** routine on the same Vdbe at the same time, they both might end
- ** up initializing the Vdbe.azVar[] array. That is a little extra
- ** work but it results in the same answer.
- */
- for(j=0, pOp=p->aOp; j<p->nOp; j++, pOp++){
- if( pOp->opcode==OP_Variable ){
- assert( pOp->p1>0 && pOp->p1<=p->nVar );
- p->azVar[pOp->p1-1] = pOp->p4.z;
- }
- }
- p->okVar = 1;
- sqlite3_mutex_leave(p->db->mutex);
- }
-}
-
-/*
-** Return the name of a wildcard parameter. Return NULL if the index
-** is out of range or if the wildcard is unnamed.
-**
-** The result is always UTF-8.
-*/
-SQLITE_API const char *sqlite3_bind_parameter_name(sqlite3_stmt *pStmt, int i){
- Vdbe *p = (Vdbe*)pStmt;
- if( p==0 || i<1 || i>p->nVar ){
- return 0;
- }
- createVarMap(p);
- return p->azVar[i-1];
-}
-
-/*
-** Given a wildcard parameter name, return the index of the variable
-** with that name. If there is no variable with the given name,
-** return 0.
-*/
-SQLITE_API int sqlite3_bind_parameter_index(sqlite3_stmt *pStmt, const char *zName){
- Vdbe *p = (Vdbe*)pStmt;
- int i;
- if( p==0 ){
- return 0;
- }
- createVarMap(p);
- if( zName ){
- for(i=0; i<p->nVar; i++){
- const char *z = p->azVar[i];
- if( z && strcmp(z,zName)==0 ){
- return i+1;
- }
- }
- }
- return 0;
-}
-
-/*
-** Transfer all bindings from the first statement over to the second.
-*/
-SQLITE_PRIVATE int sqlite3TransferBindings(sqlite3_stmt *pFromStmt, sqlite3_stmt *pToStmt){
- Vdbe *pFrom = (Vdbe*)pFromStmt;
- Vdbe *pTo = (Vdbe*)pToStmt;
- int i;
- assert( pTo->db==pFrom->db );
- assert( pTo->nVar==pFrom->nVar );
- sqlite3_mutex_enter(pTo->db->mutex);
- for(i=0; i<pFrom->nVar; i++){
- sqlite3VdbeMemMove(&pTo->aVar[i], &pFrom->aVar[i]);
- }
- sqlite3_mutex_leave(pTo->db->mutex);
- return SQLITE_OK;
-}
-
-#ifndef SQLITE_OMIT_DEPRECATED
-/*
-** Deprecated external interface. Internal/core SQLite code
-** should call sqlite3TransferBindings.
-**
-** Is is misuse to call this routine with statements from different
-** database connections. But as this is a deprecated interface, we
-** will not bother to check for that condition.
-**
-** If the two statements contain a different number of bindings, then
-** an SQLITE_ERROR is returned. Nothing else can go wrong, so otherwise
-** SQLITE_OK is returned.
-*/
-SQLITE_API int sqlite3_transfer_bindings(sqlite3_stmt *pFromStmt, sqlite3_stmt *pToStmt){
- Vdbe *pFrom = (Vdbe*)pFromStmt;
- Vdbe *pTo = (Vdbe*)pToStmt;
- if( pFrom->nVar!=pTo->nVar ){
- return SQLITE_ERROR;
- }
- return sqlite3TransferBindings(pFromStmt, pToStmt);
-}
-#endif
-
-/*
-** Return the sqlite3* database handle to which the prepared statement given
-** in the argument belongs. This is the same database handle that was
-** the first argument to the sqlite3_prepare() that was used to create
-** the statement in the first place.
-*/
-SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt *pStmt){
- return pStmt ? ((Vdbe*)pStmt)->db : 0;
-}
-
-/*
-** Return a pointer to the next prepared statement after pStmt associated
-** with database connection pDb. If pStmt is NULL, return the first
-** prepared statement for the database connection. Return NULL if there
-** are no more.
-*/
-SQLITE_API sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt){
- sqlite3_stmt *pNext;
- sqlite3_mutex_enter(pDb->mutex);
- if( pStmt==0 ){
- pNext = (sqlite3_stmt*)pDb->pVdbe;
- }else{
- pNext = (sqlite3_stmt*)((Vdbe*)pStmt)->pNext;
- }
- sqlite3_mutex_leave(pDb->mutex);
- return pNext;
-}
-
-/*
-** Return the value of a status counter for a prepared statement
-*/
-SQLITE_API int sqlite3_stmt_status(sqlite3_stmt *pStmt, int op, int resetFlag){
- Vdbe *pVdbe = (Vdbe*)pStmt;
- int v = pVdbe->aCounter[op-1];
- if( resetFlag ) pVdbe->aCounter[op-1] = 0;
- return v;
-}
-
-/************** End of vdbeapi.c *********************************************/
-/************** Begin file vdbe.c ********************************************/
-/*
-** 2001 September 15
-**
-** 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.
-**
-*************************************************************************
-** The code in this file implements execution method of the
-** Virtual Database Engine (VDBE). A separate file ("vdbeaux.c")
-** handles housekeeping details such as creating and deleting
-** VDBE instances. This file is solely interested in executing
-** the VDBE program.
-**
-** In the external interface, an "sqlite3_stmt*" is an opaque pointer
-** to a VDBE.
-**
-** The SQL parser generates a program which is then executed by
-** the VDBE to do the work of the SQL statement. VDBE programs are
-** similar in form to assembly language. The program consists of
-** a linear sequence of operations. Each operation has an opcode
-** and 5 operands. Operands P1, P2, and P3 are integers. Operand P4
-** is a null-terminated string. Operand P5 is an unsigned character.
-** Few opcodes use all 5 operands.
-**
-** Computation results are stored on a set of registers numbered beginning
-** with 1 and going up to Vdbe.nMem. Each register can store
-** either an integer, a null-terminated string, a floating point
-** number, or the SQL "NULL" value. An implicit conversion from one
-** type to the other occurs as necessary.
-**
-** Most of the code in this file is taken up by the sqlite3VdbeExec()
-** function which does the work of interpreting a VDBE program.
-** But other routines are also provided to help in building up
-** a program instruction by instruction.
-**
-** Various scripts scan this source file in order to generate HTML
-** documentation, headers files, or other derived files. The formatting
-** of the code in this file is, therefore, important. See other comments
-** in this file for details. If in doubt, do not deviate from existing
-** commenting and indentation practices when changing or adding code.
-**
-** $Id: vdbe.c,v 1.874 2009/07/24 17:58:53 danielk1977 Exp $
-*/
-
-/*
-** The following global variable is incremented every time a cursor
-** moves, either by the OP_SeekXX, OP_Next, or OP_Prev opcodes. The test
-** procedures use this information to make sure that indices are
-** working correctly. This variable has no function other than to
-** help verify the correct operation of the library.
-*/
-#ifdef SQLITE_TEST
-SQLITE_API int sqlite3_search_count = 0;
-#endif
-
-/*
-** 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.
-**
-** This facility is used for testing purposes only. It does not function
-** in an ordinary build.
-*/
-#ifdef SQLITE_TEST
-SQLITE_API int sqlite3_interrupt_count = 0;
-#endif
-
-/*
-** The next global variable is incremented each type the OP_Sort opcode
-** is executed. The test procedures use this information to make sure that
-** sorting is occurring or not occurring at appropriate times. This variable
-** has no function other than to help verify the correct operation of the
-** library.
-*/
-#ifdef SQLITE_TEST
-SQLITE_API int sqlite3_sort_count = 0;
-#endif
-
-/*
-** The next global variable records the size of the largest MEM_Blob
-** or MEM_Str that has been used by a VDBE opcode. The test procedures
-** use this information to make sure that the zero-blob functionality
-** is working correctly. This variable has no function other than to
-** help verify the correct operation of the library.
-*/
-#ifdef SQLITE_TEST
-SQLITE_API int sqlite3_max_blobsize = 0;
-static void updateMaxBlobsize(Mem *p){
- if( (p->flags & (MEM_Str|MEM_Blob))!=0 && p->n>sqlite3_max_blobsize ){
- sqlite3_max_blobsize = p->n;
- }
-}
-#endif
-
-/*
-** Test a register to see if it exceeds the current maximum blob size.
-** If it does, record the new maximum blob size.
-*/
-#if defined(SQLITE_TEST) && !defined(SQLITE_OMIT_BUILTIN_TEST)
-# define UPDATE_MAX_BLOBSIZE(P) updateMaxBlobsize(P)
-#else
-# define UPDATE_MAX_BLOBSIZE(P)
-#endif
-
-/*
-** Convert the given register into a string if it isn't one
-** already. Return non-zero if a malloc() fails.
-*/
-#define Stringify(P, enc) \
- if(((P)->flags&(MEM_Str|MEM_Blob))==0 && sqlite3VdbeMemStringify(P,enc)) \
- { goto no_mem; }
-
-/*
-** An ephemeral string value (signified by the MEM_Ephem flag) contains
-** a pointer to a dynamically allocated string where some other entity
-** is responsible for deallocating that string. Because the register
-** does not control the string, it might be deleted without the register
-** knowing it.
-**
-** This routine converts an ephemeral string into a dynamically allocated
-** string that the register itself controls. In other words, it
-** converts an MEM_Ephem string into an MEM_Dyn string.
-*/
-#define Deephemeralize(P) \
- 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)
-
-/*
-** Argument pMem points at a register that will be passed to a
-** user-defined function or returned to the user as the result of a query.
-** The second argument, 'db_enc' is the text encoding used by the vdbe for
-** register variables. This routine sets the pMem->enc and pMem->type
-** variables used by the sqlite3_value_*() routines.
-*/
-#define storeTypeInfo(A,B) _storeTypeInfo(A)
-static void _storeTypeInfo(Mem *pMem){
- int flags = pMem->flags;
- if( flags & MEM_Null ){
- pMem->type = SQLITE_NULL;
- }
- else if( flags & MEM_Int ){
- pMem->type = SQLITE_INTEGER;
- }
- else if( flags & MEM_Real ){
- pMem->type = SQLITE_FLOAT;
- }
- else if( flags & MEM_Str ){
- pMem->type = SQLITE_TEXT;
- }else{
- pMem->type = SQLITE_BLOB;
- }
-}
-
-/*
-** Properties of opcodes. The OPFLG_INITIALIZER macro is
-** created by mkopcodeh.awk during compilation. Data is obtained
-** from the comments following the "case OP_xxxx:" statements in
-** this file.
-*/
-static const unsigned char opcodeProperty[] = OPFLG_INITIALIZER;
-
-/*
-** Return true if an opcode has any of the OPFLG_xxx properties
-** specified by mask.
-*/
-SQLITE_PRIVATE int sqlite3VdbeOpcodeHasProperty(int opcode, int mask){
- assert( opcode>0 && opcode<(int)sizeof(opcodeProperty) );
- return (opcodeProperty[opcode]&mask)!=0;
-}
-
-/*
-** Allocate VdbeCursor number iCur. Return a pointer to it. Return NULL
-** if we run out of memory.
-*/
-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 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
- ** required for this VdbeCursor structure. It is convenient to use a
- ** vdbe memory cell to manage the memory allocation required for a
- ** VdbeCursor structure for the following reasons:
- **
- ** * Sometimes cursor numbers are used for a couple of different
- ** purposes in a vdbe program. The different uses might require
- ** different sized allocations. Memory cells provide growable
- ** allocations.
- **
- ** * When using ENABLE_MEMORY_MANAGEMENT, memory cell buffers can
- ** be freed lazily via the sqlite3_release_memory() API. This
- ** minimizes the number of malloc calls made by the system.
- **
- ** Memory cells for cursors are allocated at the top of the address
- ** space. Memory cell (p->nMem) corresponds to cursor 0. Space for
- ** cursor 1 is managed by memory cell (p->nMem-1), etc.
- */
- Mem *pMem = &p->aMem[p->nMem-iCur];
-
- int nByte;
- VdbeCursor *pCx = 0;
- nByte =
- sizeof(VdbeCursor) +
- (isBtreeCursor?sqlite3BtreeCursorSize():0) +
- 2*nField*sizeof(u32);
-
- assert( iCur<p->nCursor );
- if( p->apCsr[iCur] ){
- sqlite3VdbeFreeCursor(p, p->apCsr[iCur]);
- p->apCsr[iCur] = 0;
- }
- if( SQLITE_OK==sqlite3VdbeMemGrow(pMem, nByte, 0) ){
- p->apCsr[iCur] = pCx = (VdbeCursor*)pMem->z;
- memset(pMem->z, 0, nByte);
- pCx->iDb = iDb;
- pCx->nField = nField;
- if( nField ){
- pCx->aType = (u32 *)&pMem->z[sizeof(VdbeCursor)];
- }
- if( isBtreeCursor ){
- pCx->pCursor = (BtCursor*)
- &pMem->z[sizeof(VdbeCursor)+2*nField*sizeof(u32)];
- }
- }
- return pCx;
-}
-
-/*
-** Try to convert a value into a numeric representation if we can
-** do so without loss of information. In other words, if the string
-** looks like a number, convert it into a number. If it does not
-** look like a number, leave it alone.
-*/
-static void applyNumericAffinity(Mem *pRec){
- if( (pRec->flags & (MEM_Real|MEM_Int))==0 ){
- int realnum;
- sqlite3VdbeMemNulTerminate(pRec);
- if( (pRec->flags&MEM_Str)
- && sqlite3IsNumber(pRec->z, &realnum, pRec->enc) ){
- i64 value;
- sqlite3VdbeChangeEncoding(pRec, SQLITE_UTF8);
- if( !realnum && sqlite3Atoi64(pRec->z, &value) ){
- pRec->u.i = value;
- MemSetTypeFlag(pRec, MEM_Int);
- }else{
- sqlite3VdbeMemRealify(pRec);
- }
- }
- }
-}
-
-/*
-** Processing is determine by the affinity parameter:
-**
-** SQLITE_AFF_INTEGER:
-** SQLITE_AFF_REAL:
-** SQLITE_AFF_NUMERIC:
-** Try to convert pRec to an integer representation or a
-** floating-point representation if an integer representation
-** is not possible. Note that the integer representation is
-** always preferred, even if the affinity is REAL, because
-** an integer representation is more space efficient on disk.
-**
-** SQLITE_AFF_TEXT:
-** Convert pRec to a text representation.
-**
-** SQLITE_AFF_NONE:
-** No-op. pRec is unchanged.
-*/
-static void applyAffinity(
- Mem *pRec, /* The value to apply affinity to */
- char affinity, /* The affinity to be applied */
- u8 enc /* Use this text encoding */
-){
- if( affinity==SQLITE_AFF_TEXT ){
- /* Only attempt the conversion to TEXT if there is an integer or real
- ** representation (blob and NULL do not get converted) but no string
- ** representation.
- */
- if( 0==(pRec->flags&MEM_Str) && (pRec->flags&(MEM_Real|MEM_Int)) ){
- sqlite3VdbeMemStringify(pRec, enc);
- }
- pRec->flags &= ~(MEM_Real|MEM_Int);
- }else if( affinity!=SQLITE_AFF_NONE ){
- assert( affinity==SQLITE_AFF_INTEGER || affinity==SQLITE_AFF_REAL
- || affinity==SQLITE_AFF_NUMERIC );
- applyNumericAffinity(pRec);
- if( pRec->flags & MEM_Real ){
- sqlite3VdbeIntegerAffinity(pRec);
- }
- }
-}
-
-/*
-** Try to convert the type of a function argument or a result column
-** into a numeric representation. Use either INTEGER or REAL whichever
-** is appropriate. But only do the conversion if it is possible without
-** loss of information and return the revised type of the argument.
-**
-** This is an EXPERIMENTAL api and is subject to change or removal.
-*/
-SQLITE_API int sqlite3_value_numeric_type(sqlite3_value *pVal){
- Mem *pMem = (Mem*)pVal;
- applyNumericAffinity(pMem);
- storeTypeInfo(pMem, 0);
- return pMem->type;
-}
-
-/*
-** Exported version of applyAffinity(). This one works on sqlite3_value*,
-** not the internal Mem* type.
-*/
-SQLITE_PRIVATE void sqlite3ValueApplyAffinity(
- sqlite3_value *pVal,
- u8 affinity,
- u8 enc
-){
- applyAffinity((Mem *)pVal, affinity, enc);
-}
-
-#ifdef SQLITE_DEBUG
-/*
-** Write a nice string representation of the contents of cell pMem
-** into buffer zBuf, length nBuf.
-*/
-SQLITE_PRIVATE void sqlite3VdbeMemPrettyPrint(Mem *pMem, char *zBuf){
- char *zCsr = zBuf;
- int f = pMem->flags;
-
- static const char *const encnames[] = {"(X)", "(8)", "(16LE)", "(16BE)"};
-
- if( f&MEM_Blob ){
- int i;
- char c;
- if( f & MEM_Dyn ){
- c = 'z';
- assert( (f & (MEM_Static|MEM_Ephem))==0 );
- }else if( f & MEM_Static ){
- c = 't';
- assert( (f & (MEM_Dyn|MEM_Ephem))==0 );
- }else if( f & MEM_Ephem ){
- c = 'e';
- assert( (f & (MEM_Static|MEM_Dyn))==0 );
- }else{
- c = 's';
- }
-
- sqlite3_snprintf(100, zCsr, "%c", c);
- zCsr += sqlite3Strlen30(zCsr);
- sqlite3_snprintf(100, zCsr, "%d[", pMem->n);
- zCsr += sqlite3Strlen30(zCsr);
- for(i=0; i<16 && i<pMem->n; i++){
- sqlite3_snprintf(100, zCsr, "%02X", ((int)pMem->z[i] & 0xFF));
- zCsr += sqlite3Strlen30(zCsr);
- }
- for(i=0; i<16 && i<pMem->n; i++){
- char z = pMem->z[i];
- if( z<32 || z>126 ) *zCsr++ = '.';
- else *zCsr++ = z;
- }
-
- sqlite3_snprintf(100, zCsr, "]%s", encnames[pMem->enc]);
- zCsr += sqlite3Strlen30(zCsr);
- if( f & MEM_Zero ){
- sqlite3_snprintf(100, zCsr,"+%dz",pMem->u.nZero);
- zCsr += sqlite3Strlen30(zCsr);
- }
- *zCsr = '\0';
- }else if( f & MEM_Str ){
- int j, k;
- zBuf[0] = ' ';
- if( f & MEM_Dyn ){
- zBuf[1] = 'z';
- assert( (f & (MEM_Static|MEM_Ephem))==0 );
- }else if( f & MEM_Static ){
- zBuf[1] = 't';
- assert( (f & (MEM_Dyn|MEM_Ephem))==0 );
- }else if( f & MEM_Ephem ){
- zBuf[1] = 'e';
- assert( (f & (MEM_Static|MEM_Dyn))==0 );
- }else{
- zBuf[1] = 's';
- }
- k = 2;
- sqlite3_snprintf(100, &zBuf[k], "%d", pMem->n);
- k += sqlite3Strlen30(&zBuf[k]);
- zBuf[k++] = '[';
- for(j=0; j<15 && j<pMem->n; j++){
- u8 c = pMem->z[j];
- if( c>=0x20 && c<0x7f ){
- zBuf[k++] = c;
- }else{
- zBuf[k++] = '.';
- }
- }
- zBuf[k++] = ']';
- sqlite3_snprintf(100,&zBuf[k], encnames[pMem->enc]);
- k += sqlite3Strlen30(&zBuf[k]);
- zBuf[k++] = 0;
- }
-}
-#endif
-
-#ifdef SQLITE_DEBUG
-/*
-** Print the value of a register for tracing purposes:
-*/
-static void memTracePrint(FILE *out, Mem *p){
- if( p->flags & MEM_Null ){
- fprintf(out, " NULL");
- }else if( (p->flags & (MEM_Int|MEM_Str))==(MEM_Int|MEM_Str) ){
- fprintf(out, " si:%lld", p->u.i);
- }else if( p->flags & MEM_Int ){
- fprintf(out, " i:%lld", p->u.i);
-#ifndef SQLITE_OMIT_FLOATING_POINT
- }else if( p->flags & MEM_Real ){
- fprintf(out, " r:%g", p->r);
-#endif
- }else if( p->flags & MEM_RowSet ){
- fprintf(out, " (rowset)");
- }else{
- char zBuf[200];
- sqlite3VdbeMemPrettyPrint(p, zBuf);
- fprintf(out, " ");
- fprintf(out, "%s", zBuf);
- }
-}
-static void registerTrace(FILE *out, int iReg, Mem *p){
- fprintf(out, "REG[%d] = ", iReg);
- memTracePrint(out, p);
- fprintf(out, "\n");
-}
-#endif
-
-#ifdef SQLITE_DEBUG
-# define REGISTER_TRACE(R,M) if(p->trace)registerTrace(p->trace,R,M)
-#else
-# define REGISTER_TRACE(R,M)
-#endif
-
-
-#ifdef VDBE_PROFILE
-
-/*
-** hwtime.h contains inline assembler code for implementing
-** high-performance timing routines.
-*/
-/************** Include hwtime.h in the middle of vdbe.c *********************/
-/************** Begin file hwtime.h ******************************************/
-/*
-** 2008 May 27
-**
-** 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 inline asm code for retrieving "high-performance"
-** counters for x86 class CPUs.
-**
-** $Id: hwtime.h,v 1.3 2008/08/01 14:33:15 shane Exp $
-*/
-#ifndef _HWTIME_H_
-#define _HWTIME_H_
-
-/*
-** The following routine only works on pentium-class (or newer) processors.
-** It uses the RDTSC opcode to read the cycle count value out of the
-** processor and returns that value. This can be used for high-res
-** profiling.
-*/
-#if (defined(__GNUC__) || defined(_MSC_VER)) && \
- (defined(i386) || defined(__i386__) || defined(_M_IX86))
-
- #if defined(__GNUC__)
-
- __inline__ sqlite_uint64 sqlite3Hwtime(void){
- unsigned int lo, hi;
- __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
- return (sqlite_uint64)hi << 32 | lo;
- }
-
- #elif defined(_MSC_VER)
-
- __declspec(naked) __inline sqlite_uint64 __cdecl sqlite3Hwtime(void){
- __asm {
- rdtsc
- ret ; return value at EDX:EAX
- }
- }
-
- #endif
-
-#elif (defined(__GNUC__) && defined(__x86_64__))
-
- __inline__ sqlite_uint64 sqlite3Hwtime(void){
- unsigned long val;
- __asm__ __volatile__ ("rdtsc" : "=A" (val));
- return val;
- }
-
-#elif (defined(__GNUC__) && defined(__ppc__))
-
- __inline__ sqlite_uint64 sqlite3Hwtime(void){
- unsigned long long retval;
- unsigned long junk;
- __asm__ __volatile__ ("\n\
- 1: mftbu %1\n\
- mftb %L0\n\
- mftbu %0\n\
- cmpw %0,%1\n\
- bne 1b"
- : "=r" (retval), "=r" (junk));
- return retval;
- }
-
-#else
-
- #error Need implementation of sqlite3Hwtime() for your platform.
-
- /*
- ** To compile without implementing sqlite3Hwtime() for your platform,
- ** you can remove the above #error and use the following
- ** stub function. You will lose timing support for many
- ** of the debugging and testing utilities, but it should at
- ** least compile and run.
- */
-SQLITE_PRIVATE sqlite_uint64 sqlite3Hwtime(void){ return ((sqlite_uint64)0); }
-
-#endif
-
-#endif /* !defined(_HWTIME_H_) */
-
-/************** End of hwtime.h **********************************************/
-/************** Continuing where we left off in vdbe.c ***********************/
-
-#endif
-
-/*
-** The CHECK_FOR_INTERRUPT macro defined here looks to see if the
-** sqlite3_interrupt() routine has been called. If it has been, then
-** processing of the VDBE program is interrupted.
-**
-** 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
-** flag on jump instructions, we get a (small) speed improvement.
-*/
-#define CHECK_FOR_INTERRUPT \
- if( db->u1.isInterrupted ) goto abort_due_to_interrupt;
-
-#ifdef SQLITE_DEBUG
-static int fileExists(sqlite3 *db, const char *zFile){
- int res = 0;
- int rc = SQLITE_OK;
-#ifdef SQLITE_TEST
- /* If we are currently testing IO errors, then do not call OsAccess() to
- ** test for the presence of zFile. This is because any IO error that
- ** occurs here will not be reported, causing the test to fail.
- */
- extern int sqlite3_io_error_pending;
- if( sqlite3_io_error_pending<=0 )
-#endif
- rc = sqlite3OsAccess(db->pVfs, zFile, SQLITE_ACCESS_EXISTS, &res);
- return (res && rc==SQLITE_OK);
-}
-#endif
-
-#ifndef NDEBUG
-/*
-** This function is only called from within an assert() expression. It
-** checks that the sqlite3.nTransaction variable is correctly set to
-** the number of non-transaction savepoints currently in the
-** linked list starting at sqlite3.pSavepoint.
-**
-** Usage:
-**
-** assert( checkSavepointCount(db) );
-*/
-static int checkSavepointCount(sqlite3 *db){
- int n = 0;
- Savepoint *p;
- for(p=db->pSavepoint; p; p=p->pNext) n++;
- assert( n==(db->nSavepoint + db->isTransactionSavepoint) );
- return 1;
-}
-#endif
-
-/*
-** Execute as much of a VDBE program as we can then return.
-**
-** sqlite3VdbeMakeReady() must be called before this routine in order to
-** close the program with a final OP_Halt and to set up the callbacks
-** and the error message pointer.
-**
-** Whenever a row or result data is available, this routine will either
-** invoke the result callback (if there is one) or return with
-** SQLITE_ROW.
-**
-** If an attempt is made to open a locked database, then this routine
-** will either invoke the busy callback (if there is one) or it will
-** return SQLITE_BUSY.
-**
-** If an error occurs, an error message is written to memory obtained
-** from sqlite3_malloc() and p->zErrMsg is made to point to that memory.
-** The error code is stored in p->rc and this routine returns SQLITE_ERROR.
-**
-** If the callback ever returns non-zero, then the program exits
-** immediately. There will be no error message but the p->rc field is
-** set to SQLITE_ABORT and this routine will return SQLITE_ERROR.
-**
-** A memory allocation error causes p->rc to be set to SQLITE_NOMEM and this
-** routine to return SQLITE_ERROR.
-**
-** Other fatal errors return SQLITE_ERROR.
-**
-** After this routine has finished, sqlite3VdbeFinalize() should be
-** used to clean up the mess that was left behind.
-*/
-SQLITE_PRIVATE int sqlite3VdbeExec(
- Vdbe *p /* The VDBE */
-){
- int pc; /* The program counter */
- Op *pOp; /* Current operation */
- int rc = SQLITE_OK; /* Value to return */
- sqlite3 *db = p->db; /* The database */
- u8 encoding = ENC(db); /* The database encoding */
- Mem *pIn1 = 0; /* 1st input operand */
- Mem *pIn2 = 0; /* 2nd input operand */
- Mem *pIn3 = 0; /* 3rd input operand */
- Mem *pOut = 0; /* Output operand */
- u8 opProperty;
- int iCompare = 0; /* Result of last OP_Compare operation */
- int *aPermute = 0; /* Permutation of columns for OP_Compare */
-#ifdef VDBE_PROFILE
- u64 start; /* CPU clock count at start of opcode */
- int origPc; /* Program counter at start of opcode */
-#endif
-#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
- int nProgressOps = 0; /* Opcodes executed since progress callback. */
-#endif
- /********************************************************************
- ** Automatically generated code
- **
- ** The following union is automatically generated by the
- ** vdbe-compress.tcl script. The purpose of this union is to
- ** reduce the amount of stack space required by this function.
- ** See comments in the vdbe-compress.tcl script for details.
- */
- union vdbeExecUnion {
- struct OP_Yield_stack_vars {
- int pcDest;
- } aa;
- struct OP_Variable_stack_vars {
- int p1; /* Variable to copy from */
- int p2; /* Register to copy to */
- int n; /* Number of values left to copy */
- Mem *pVar; /* Value being transferred */
- } ab;
- struct OP_Move_stack_vars {
- char *zMalloc; /* Holding variable for allocated memory */
- int n; /* Number of registers left to copy */
- int p1; /* Register to copy from */
- int p2; /* Register to copy to */
- } ac;
- struct OP_ResultRow_stack_vars {
- Mem *pMem;
- int i;
- } ad;
- struct OP_Concat_stack_vars {
- i64 nByte;
- } ae;
- struct OP_Remainder_stack_vars {
- int flags; /* Combined MEM_* flags from both inputs */
- i64 iA; /* Integer value of left operand */
- i64 iB; /* Integer value of right operand */
- double rA; /* Real value of left operand */
- double rB; /* Real value of right operand */
- } af;
- struct OP_Function_stack_vars {
- int i;
- Mem *pArg;
- sqlite3_context ctx;
- sqlite3_value **apVal;
- int n;
- } ag;
- struct OP_ShiftRight_stack_vars {
- i64 a;
- i64 b;
- } ah;
- struct OP_Ge_stack_vars {
- int flags;
- int res;
- char affinity;
- } ai;
- struct OP_Compare_stack_vars {
- int n;
- int i;
- int p1;
- int p2;
- const KeyInfo *pKeyInfo;
- int idx;
- CollSeq *pColl; /* Collating sequence to use on this term */
- int bRev; /* True for DESCENDING sort order */
- } aj;
- struct OP_Or_stack_vars {
- int v1; /* Left operand: 0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */
- int v2; /* Right operand: 0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */
- } ak;
- struct OP_IfNot_stack_vars {
- int c;
- } al;
- struct OP_Column_stack_vars {
- u32 payloadSize; /* Number of bytes in the record */
- i64 payloadSize64; /* Number of bytes in the record */
- int p1; /* P1 value of the opcode */
- int p2; /* column number to retrieve */
- VdbeCursor *pC; /* The VDBE cursor */
- char *zRec; /* Pointer to complete record-data */
- BtCursor *pCrsr; /* The BTree cursor */
- u32 *aType; /* aType[i] holds the numeric type of the i-th column */
- u32 *aOffset; /* aOffset[i] is offset to start of data for i-th column */
- int nField; /* number of fields in the record */
- int len; /* The length of the serialized data for the column */
- int i; /* Loop counter */
- char *zData; /* Part of the record being decoded */
- Mem *pDest; /* Where to write the extracted value */
- Mem sMem; /* For storing the record being decoded */
- u8 *zIdx; /* Index into header */
- u8 *zEndHdr; /* Pointer to first byte after the header */
- u32 offset; /* Offset into the data */
- u64 offset64; /* 64-bit offset. 64 bits needed to catch overflow */
- int szHdr; /* Size of the header size field at start of record */
- int avail; /* Number of bytes of available data */
- Mem *pReg; /* PseudoTable input register */
- } am;
- struct OP_Affinity_stack_vars {
- char *zAffinity; /* The affinity to be applied */
- Mem *pData0; /* First register to which to apply affinity */
- Mem *pLast; /* Last register to which to apply affinity */
- Mem *pRec; /* Current register */
- } an;
- struct OP_MakeRecord_stack_vars {
- u8 *zNewRecord; /* A buffer to hold the data for the new record */
- Mem *pRec; /* The new record */
- u64 nData; /* Number of bytes of data space */
- int nHdr; /* Number of bytes of header space */
- i64 nByte; /* Data space required for this record */
- int nZero; /* Number of zero bytes at the end of the record */
- int nVarint; /* Number of bytes in a varint */
- u32 serial_type; /* Type field */
- Mem *pData0; /* First field to be combined into the record */
- Mem *pLast; /* Last field of the record */
- int nField; /* Number of fields in the record */
- char *zAffinity; /* The affinity string for the record */
- int file_format; /* File format to use for encoding */
- int i; /* Space used in zNewRecord[] */
- int len; /* Length of a field */
- } ao;
- struct OP_Count_stack_vars {
- i64 nEntry;
- BtCursor *pCrsr;
- } ap;
- struct OP_Savepoint_stack_vars {
- int p1; /* Value of P1 operand */
- char *zName; /* Name of savepoint */
- int nName;
- Savepoint *pNew;
- Savepoint *pSavepoint;
- Savepoint *pTmp;
- int iSavepoint;
- int ii;
- } aq;
- struct OP_AutoCommit_stack_vars {
- int desiredAutoCommit;
- int iRollback;
- int turnOnAC;
- } ar;
- struct OP_Transaction_stack_vars {
- Btree *pBt;
- } as;
- struct OP_ReadCookie_stack_vars {
- int iMeta;
- int iDb;
- int iCookie;
- } at;
- struct OP_SetCookie_stack_vars {
- Db *pDb;
- } au;
- struct OP_VerifyCookie_stack_vars {
- int iMeta;
- Btree *pBt;
- } av;
- struct OP_OpenWrite_stack_vars {
- int nField;
- KeyInfo *pKeyInfo;
- int p2;
- int iDb;
- int wrFlag;
- Btree *pX;
- VdbeCursor *pCur;
- Db *pDb;
- } aw;
- struct OP_OpenEphemeral_stack_vars {
- VdbeCursor *pCx;
- } ax;
- struct OP_OpenPseudo_stack_vars {
- VdbeCursor *pCx;
- } ay;
- struct OP_SeekGt_stack_vars {
- int res;
- int oc;
- VdbeCursor *pC;
- UnpackedRecord r;
- int nField;
- i64 iKey; /* The rowid we are to seek to */
- } az;
- struct OP_Seek_stack_vars {
- VdbeCursor *pC;
- } ba;
- struct OP_Found_stack_vars {
- int alreadyExists;
- VdbeCursor *pC;
- int res;
- UnpackedRecord *pIdxKey;
- char aTempRec[ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*3 + 7];
- } bb;
- struct OP_IsUnique_stack_vars {
- u16 ii;
- VdbeCursor *pCx;
- BtCursor *pCrsr;
- u16 nField;
- Mem *aMem;
- UnpackedRecord r; /* B-Tree index search key */
- i64 R; /* Rowid stored in register P3 */
- } bc;
- struct OP_NotExists_stack_vars {
- VdbeCursor *pC;
- BtCursor *pCrsr;
- int res;
- u64 iKey;
- } bd;
- struct OP_NewRowid_stack_vars {
- i64 v; /* The new rowid */
- VdbeCursor *pC; /* Cursor of table to get the new rowid */
- int res; /* Result of an sqlite3BtreeLast() */
- int cnt; /* Counter to limit the number of searches */
- Mem *pMem; /* Register holding largest rowid for AUTOINCREMENT */
- VdbeFrame *pFrame; /* Root frame of VDBE */
- } be;
- struct OP_Insert_stack_vars {
- Mem *pData; /* MEM cell holding data for the record to be inserted */
- Mem *pKey; /* MEM cell holding key for the record */
- i64 iKey; /* The integer ROWID or key for the record to be inserted */
- VdbeCursor *pC; /* Cursor to table into which insert is written */
- int nZero; /* Number of zero-bytes to append */
- int seekResult; /* Result of prior seek or 0 if no USESEEKRESULT flag */
- const char *zDb; /* database name - used by the update hook */
- const char *zTbl; /* Table name - used by the opdate hook */
- int op; /* Opcode for update hook: SQLITE_UPDATE or SQLITE_INSERT */
- } bf;
- struct OP_Delete_stack_vars {
- i64 iKey;
- VdbeCursor *pC;
- } bg;
- struct OP_RowData_stack_vars {
- VdbeCursor *pC;
- BtCursor *pCrsr;
- u32 n;
- i64 n64;
- } bh;
- struct OP_Rowid_stack_vars {
- VdbeCursor *pC;
- i64 v;
- sqlite3_vtab *pVtab;
- const sqlite3_module *pModule;
- } bi;
- struct OP_NullRow_stack_vars {
- VdbeCursor *pC;
- } bj;
- struct OP_Last_stack_vars {
- VdbeCursor *pC;
- BtCursor *pCrsr;
- int res;
- } bk;
- struct OP_Rewind_stack_vars {
- VdbeCursor *pC;
- BtCursor *pCrsr;
- int res;
- } bl;
- struct OP_Next_stack_vars {
- VdbeCursor *pC;
- BtCursor *pCrsr;
- int res;
- } bm;
- struct OP_IdxInsert_stack_vars {
- VdbeCursor *pC;
- BtCursor *pCrsr;
- int nKey;
- const char *zKey;
- } bn;
- struct OP_IdxDelete_stack_vars {
- VdbeCursor *pC;
- BtCursor *pCrsr;
- int res;
- UnpackedRecord r;
- } bo;
- struct OP_IdxRowid_stack_vars {
- BtCursor *pCrsr;
- VdbeCursor *pC;
- i64 rowid;
- } bp;
- struct OP_IdxGE_stack_vars {
- VdbeCursor *pC;
- int res;
- UnpackedRecord r;
- } bq;
- struct OP_Destroy_stack_vars {
- int iMoved;
- int iCnt;
- Vdbe *pVdbe;
- int iDb;
- } br;
- struct OP_Clear_stack_vars {
- int nChange;
- } bs;
- struct OP_CreateTable_stack_vars {
- int pgno;
- int flags;
- Db *pDb;
- } bt;
- struct OP_ParseSchema_stack_vars {
- int iDb;
- const char *zMaster;
- char *zSql;
- InitData initData;
- } bu;
- struct OP_IntegrityCk_stack_vars {
- int nRoot; /* Number of tables to check. (Number of root pages.) */
- int *aRoot; /* Array of rootpage numbers for tables to be checked */
- int j; /* Loop counter */
- int nErr; /* Number of errors reported */
- char *z; /* Text of the error report */
- Mem *pnErr; /* Register keeping track of errors remaining */
- } bv;
- struct OP_RowSetAdd_stack_vars {
- Mem *pIdx;
- Mem *pVal;
- } bw;
- struct OP_RowSetRead_stack_vars {
- Mem *pIdx;
- i64 val;
- } bx;
- struct OP_RowSetTest_stack_vars {
- int iSet;
- int exists;
- } by;
- struct OP_Program_stack_vars {
- int nMem; /* Number of memory registers for sub-program */
- int nByte; /* Bytes of runtime space required for sub-program */
- Mem *pRt; /* Register to allocate runtime space */
- Mem *pMem; /* Used to iterate through memory cells */
- Mem *pEnd; /* Last memory cell in new array */
- VdbeFrame *pFrame; /* New vdbe frame to execute in */
- SubProgram *pProgram; /* Sub-program to execute */
- void *t; /* Token identifying trigger */
- } bz;
- struct OP_Param_stack_vars {
- VdbeFrame *pFrame;
- Mem *pIn;
- } ca;
- struct OP_MemMax_stack_vars {
- Mem *pIn1;
- VdbeFrame *pFrame;
- } cb;
- struct OP_AggStep_stack_vars {
- int n;
- int i;
- Mem *pMem;
- Mem *pRec;
- sqlite3_context ctx;
- sqlite3_value **apVal;
- } cc;
- struct OP_AggFinal_stack_vars {
- Mem *pMem;
- } cd;
- struct OP_IncrVacuum_stack_vars {
- Btree *pBt;
- } ce;
- struct OP_VBegin_stack_vars {
- VTable *pVTab;
- } cf;
- struct OP_VOpen_stack_vars {
- VdbeCursor *pCur;
- sqlite3_vtab_cursor *pVtabCursor;
- sqlite3_vtab *pVtab;
- sqlite3_module *pModule;
- } cg;
- struct OP_VFilter_stack_vars {
- int nArg;
- int iQuery;
- const sqlite3_module *pModule;
- Mem *pQuery;
- Mem *pArgc;
- sqlite3_vtab_cursor *pVtabCursor;
- sqlite3_vtab *pVtab;
- VdbeCursor *pCur;
- int res;
- int i;
- Mem **apArg;
- } ch;
- struct OP_VColumn_stack_vars {
- sqlite3_vtab *pVtab;
- const sqlite3_module *pModule;
- Mem *pDest;
- sqlite3_context sContext;
- } ci;
- struct OP_VNext_stack_vars {
- sqlite3_vtab *pVtab;
- const sqlite3_module *pModule;
- int res;
- VdbeCursor *pCur;
- } cj;
- struct OP_VRename_stack_vars {
- sqlite3_vtab *pVtab;
- Mem *pName;
- } ck;
- struct OP_VUpdate_stack_vars {
- sqlite3_vtab *pVtab;
- sqlite3_module *pModule;
- int nArg;
- int i;
- sqlite_int64 rowid;
- Mem **apArg;
- Mem *pX;
- } cl;
- struct OP_Pagecount_stack_vars {
- int p1;
- int nPage;
- Pager *pPager;
- } cm;
- struct OP_Trace_stack_vars {
- char *zTrace;
- } cn;
- } u;
- /* End automatically generated code
- ********************************************************************/
-
- assert( p->magic==VDBE_MAGIC_RUN ); /* sqlite3_step() verifies this */
- assert( db->magic==SQLITE_MAGIC_BUSY );
- sqlite3VdbeMutexArrayEnter(p);
- if( p->rc==SQLITE_NOMEM ){
- /* This happens if a malloc() inside a call to sqlite3_column_text() or
- ** sqlite3_column_text16() failed. */
- goto no_mem;
- }
- assert( p->rc==SQLITE_OK || p->rc==SQLITE_BUSY );
- p->rc = SQLITE_OK;
- assert( p->explain==0 );
- p->pResultSet = 0;
- db->busyHandler.nBusy = 0;
- CHECK_FOR_INTERRUPT;
- sqlite3VdbeIOTraceSql(p);
-#ifdef SQLITE_DEBUG
- sqlite3BeginBenignMalloc();
- if( p->pc==0
- && ((p->db->flags & SQLITE_VdbeListing) || fileExists(db, "vdbe_explain"))
- ){
- int i;
- printf("VDBE Program Listing:\n");
- sqlite3VdbePrintSql(p);
- for(i=0; i<p->nOp; i++){
- sqlite3VdbePrintOp(stdout, i, &p->aOp[i]);
- }
- }
- if( fileExists(db, "vdbe_trace") ){
- p->trace = stdout;
- }
- sqlite3EndBenignMalloc();
-#endif
- for(pc=p->pc; rc==SQLITE_OK; pc++){
- assert( pc>=0 && pc<p->nOp );
- if( db->mallocFailed ) goto no_mem;
-#ifdef VDBE_PROFILE
- origPc = pc;
- start = sqlite3Hwtime();
-#endif
- pOp = &p->aOp[pc];
-
- /* Only allow tracing if SQLITE_DEBUG is defined.
- */
-#ifdef SQLITE_DEBUG
- if( p->trace ){
- if( pc==0 ){
- printf("VDBE Execution Trace:\n");
- sqlite3VdbePrintSql(p);
- }
- sqlite3VdbePrintOp(p->trace, pc, pOp);
- }
- if( p->trace==0 && pc==0 ){
- sqlite3BeginBenignMalloc();
- if( fileExists(db, "vdbe_sqltrace") ){
- sqlite3VdbePrintSql(p);
- }
- sqlite3EndBenignMalloc();
- }
-#endif
-
-
- /* Check to see if we need to simulate an interrupt. This only happens
- ** if we have a special test build.
- */
-#ifdef SQLITE_TEST
- if( sqlite3_interrupt_count>0 ){
- sqlite3_interrupt_count--;
- if( sqlite3_interrupt_count==0 ){
- sqlite3_interrupt(db);
- }
- }
-#endif
-
-#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
- /* Call the progress callback if it is configured and the required number
- ** of VDBE ops have been executed (either since this invocation of
- ** sqlite3VdbeExec() or since last time the progress callback was called).
- ** If the progress callback returns non-zero, exit the virtual machine with
- ** a return code SQLITE_ABORT.
- */
- if( db->xProgress ){
- if( db->nProgressOps==nProgressOps ){
- int prc;
- if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
- prc =db->xProgress(db->pProgressArg);
- if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
- if( prc!=0 ){
- rc = SQLITE_INTERRUPT;
- goto vdbe_error_halt;
- }
- nProgressOps = 0;
- }
- nProgressOps++;
- }
-#endif
-
- /* Do common setup processing for any opcode that is marked
- ** with the "out2-prerelease" tag. Such opcodes have a single
- ** output which is specified by the P2 parameter. The P2 register
- ** is initialized to a NULL.
- */
- opProperty = opcodeProperty[pOp->opcode];
- if( (opProperty & OPFLG_OUT2_PRERELEASE)!=0 ){
- assert( pOp->p2>0 );
- assert( pOp->p2<=p->nMem );
- pOut = &p->aMem[pOp->p2];
- sqlite3VdbeMemReleaseExternal(pOut);
- pOut->flags = MEM_Null;
- pOut->n = 0;
- }else
-
- /* Do common setup for opcodes marked with one of the following
- ** combinations of properties.
- **
- ** in1
- ** in1 in2
- ** in1 in2 out3
- ** in1 in3
- **
- ** Variables pIn1, pIn2, and pIn3 are made to point to appropriate
- ** registers for inputs. Variable pOut points to the output register.
- */
- if( (opProperty & OPFLG_IN1)!=0 ){
- assert( pOp->p1>0 );
- assert( pOp->p1<=p->nMem );
- pIn1 = &p->aMem[pOp->p1];
- REGISTER_TRACE(pOp->p1, pIn1);
- if( (opProperty & OPFLG_IN2)!=0 ){
- assert( pOp->p2>0 );
- assert( pOp->p2<=p->nMem );
- pIn2 = &p->aMem[pOp->p2];
- REGISTER_TRACE(pOp->p2, pIn2);
- /* As currently implemented, in2 implies out3. There is no reason
- ** why this has to be, it just worked out that way. */
- assert( (opProperty & OPFLG_OUT3)!=0 );
- assert( pOp->p3>0 );
- assert( pOp->p3<=p->nMem );
- pOut = &p->aMem[pOp->p3];
- }else if( (opProperty & OPFLG_IN3)!=0 ){
- assert( pOp->p3>0 );
- assert( pOp->p3<=p->nMem );
- pIn3 = &p->aMem[pOp->p3];
- REGISTER_TRACE(pOp->p3, pIn3);
- }
- }else if( (opProperty & OPFLG_IN2)!=0 ){
- assert( pOp->p2>0 );
- assert( pOp->p2<=p->nMem );
- pIn2 = &p->aMem[pOp->p2];
- REGISTER_TRACE(pOp->p2, pIn2);
- }else if( (opProperty & OPFLG_IN3)!=0 ){
- assert( pOp->p3>0 );
- assert( pOp->p3<=p->nMem );
- pIn3 = &p->aMem[pOp->p3];
- REGISTER_TRACE(pOp->p3, pIn3);
- }
-
- switch( pOp->opcode ){
-
-/*****************************************************************************
-** What follows is a massive switch statement where each case implements a
-** separate instruction in the virtual machine. If we follow the usual
-** indentation conventions, each case should be indented by 6 spaces. But
-** that is a lot of wasted space on the left margin. So the code within
-** the switch statement will break with convention and be flush-left. Another
-** big comment (similar to this one) will mark the point in the code where
-** we transition back to normal indentation.
-**
-** The formatting of each case is important. The makefile for SQLite
-** generates two C files "opcodes.h" and "opcodes.c" by scanning this
-** file looking for lines that begin with "case OP_". The opcodes.h files
-** will be filled with #defines that give unique integer values to each
-** opcode and the opcodes.c file is filled with an array of strings where
-** each string is the symbolic name for the corresponding opcode. If the
-** case statement is followed by a comment of the form "/# same as ... #/"
-** that comment is used to determine the particular value of the opcode.
-**
-** Other keywords in the comment that follows each case are used to
-** construct the OPFLG_INITIALIZER value that initializes opcodeProperty[].
-** Keywords include: in1, in2, in3, out2_prerelease, out2, out3. See
-** the mkopcodeh.awk script for additional information.
-**
-** Documentation about VDBE opcodes is generated by scanning this file
-** for lines of that contain "Opcode:". That line and all subsequent
-** comment lines are used in the generation of the opcode.html documentation
-** file.
-**
-** SUMMARY:
-**
-** Formatting is important to scripts that scan this file.
-** Do not deviate from the formatting style currently in use.
-**
-*****************************************************************************/
-
-/* Opcode: Goto * P2 * * *
-**
-** An unconditional jump to address P2.
-** The next instruction executed will be
-** the one at index P2 from the beginning of
-** the program.
-*/
-case OP_Goto: { /* jump */
- CHECK_FOR_INTERRUPT;
- pc = pOp->p2 - 1;
- break;
-}
-
-/* Opcode: Gosub P1 P2 * * *
-**
-** Write the current address onto register P1
-** and then jump to address P2.
-*/
-case OP_Gosub: { /* jump */
- assert( pOp->p1>0 );
- assert( pOp->p1<=p->nMem );
- pIn1 = &p->aMem[pOp->p1];
- assert( (pIn1->flags & MEM_Dyn)==0 );
- pIn1->flags = MEM_Int;
- pIn1->u.i = pc;
- REGISTER_TRACE(pOp->p1, pIn1);
- pc = pOp->p2 - 1;
- break;
-}
-
-/* Opcode: Return P1 * * * *
-**
-** Jump to the next instruction after the address in register P1.
-*/
-case OP_Return: { /* in1 */
- assert( pIn1->flags & MEM_Int );
- pc = (int)pIn1->u.i;
- break;
-}
-
-/* Opcode: Yield P1 * * * *
-**
-** Swap the program counter with the value in register P1.
-*/
-case OP_Yield: { /* in1 */
-#if 0 /* local variables moved into u.aa */
- int pcDest;
-#endif /* local variables moved into u.aa */
- assert( (pIn1->flags & MEM_Dyn)==0 );
- pIn1->flags = MEM_Int;
- u.aa.pcDest = (int)pIn1->u.i;
- pIn1->u.i = pc;
- REGISTER_TRACE(pOp->p1, pIn1);
- pc = u.aa.pcDest;
- break;
-}
-
-/* Opcode: HaltIfNull P1 P2 P3 P4 *
-**
-** Check the value in register P3. If is is NULL then Halt using
-** parameter P1, P2, and P4 as if this were a Halt instruction. If the
-** value in register P3 is not NULL, then this routine is a no-op.
-*/
-case OP_HaltIfNull: { /* in3 */
- if( (pIn3->flags & MEM_Null)==0 ) break;
- /* Fall through into OP_Halt */
-}
-
-/* Opcode: Halt P1 P2 * P4 *
-**
-** Exit immediately. All open cursors, etc are closed
-** automatically.
-**
-** P1 is the result code returned by sqlite3_exec(), sqlite3_reset(),
-** or sqlite3_finalize(). For a normal halt, this should be SQLITE_OK (0).
-** For errors, it can be some other value. If P1!=0 then P2 will determine
-** whether or not to rollback the current transaction. Do not rollback
-** if P2==OE_Fail. Do the rollback if P2==OE_Rollback. If P2==OE_Abort,
-** then back out all changes that have occurred during this execution of the
-** VDBE, but do not rollback the transaction.
-**
-** If P4 is not null then it is an error message string.
-**
-** There is an implied "Halt 0 0 0" instruction inserted at the very end of
-** every program. So a jump past the last instruction of the program
-** is the same as executing Halt.
-*/
-case OP_Halt: {
- if( pOp->p1==SQLITE_OK && p->pFrame ){
- /* Halt the sub-program. Return control to the parent frame. */
- VdbeFrame *pFrame = p->pFrame;
- p->pFrame = pFrame->pParent;
- p->nFrame--;
- sqlite3VdbeSetChanges(db, p->nChange);
- pc = sqlite3VdbeFrameRestore(pFrame);
- if( pOp->p2==OE_Ignore ){
- /* Instruction pc is the OP_Program that invoked the sub-program
- ** currently being halted. If the p2 instruction of this OP_Halt
- ** instruction is set to OE_Ignore, then the sub-program is throwing
- ** an IGNORE exception. In this case jump to the address specified
- ** as the p2 of the calling OP_Program. */
- pc = p->aOp[pc].p2-1;
- }
- break;
- }
-
- p->rc = pOp->p1;
- p->errorAction = (u8)pOp->p2;
- p->pc = pc;
- if( pOp->p4.z ){
- sqlite3SetString(&p->zErrMsg, db, "%s", pOp->p4.z);
- }
- rc = sqlite3VdbeHalt(p);
- assert( rc==SQLITE_BUSY || rc==SQLITE_OK );
- if( rc==SQLITE_BUSY ){
- p->rc = rc = SQLITE_BUSY;
- }else{
- rc = p->rc ? SQLITE_ERROR : SQLITE_DONE;
- }
- goto vdbe_return;
-}
-
-/* Opcode: Integer P1 P2 * * *
-**
-** The 32-bit integer value P1 is written into register P2.
-*/
-case OP_Integer: { /* out2-prerelease */
- pOut->flags = MEM_Int;
- pOut->u.i = pOp->p1;
- break;
-}
-
-/* Opcode: Int64 * P2 * P4 *
-**
-** P4 is a pointer to a 64-bit integer value.
-** Write that value into register P2.
-*/
-case OP_Int64: { /* out2-prerelease */
- assert( pOp->p4.pI64!=0 );
- pOut->flags = MEM_Int;
- pOut->u.i = *pOp->p4.pI64;
- break;
-}
-
-/* Opcode: Real * P2 * P4 *
-**
-** P4 is a pointer to a 64-bit floating point value.
-** Write that value into register P2.
-*/
-case OP_Real: { /* same as TK_FLOAT, out2-prerelease */
- pOut->flags = MEM_Real;
- assert( !sqlite3IsNaN(*pOp->p4.pReal) );
- pOut->r = *pOp->p4.pReal;
- break;
-}
-
-/* Opcode: String8 * P2 * P4 *
-**
-** P4 points to a nul terminated UTF-8 string. This opcode is transformed
-** into an OP_String before it is executed for the first time.
-*/
-case OP_String8: { /* same as TK_STRING, out2-prerelease */
- assert( pOp->p4.z!=0 );
- pOp->opcode = OP_String;
- pOp->p1 = sqlite3Strlen30(pOp->p4.z);
-
-#ifndef SQLITE_OMIT_UTF16
- if( encoding!=SQLITE_UTF8 ){
- rc = sqlite3VdbeMemSetStr(pOut, pOp->p4.z, -1, SQLITE_UTF8, SQLITE_STATIC);
- if( rc==SQLITE_TOOBIG ) goto too_big;
- if( SQLITE_OK!=sqlite3VdbeChangeEncoding(pOut, encoding) ) goto no_mem;
- assert( pOut->zMalloc==pOut->z );
- assert( pOut->flags & MEM_Dyn );
- pOut->zMalloc = 0;
- pOut->flags |= MEM_Static;
- pOut->flags &= ~MEM_Dyn;
- if( pOp->p4type==P4_DYNAMIC ){
- sqlite3DbFree(db, pOp->p4.z);
- }
- pOp->p4type = P4_DYNAMIC;
- pOp->p4.z = pOut->z;
- pOp->p1 = pOut->n;
- }
-#endif
- if( pOp->p1>db->aLimit[SQLITE_LIMIT_LENGTH] ){
- goto too_big;
- }
- /* Fall through to the next case, OP_String */
-}
-
-/* Opcode: String P1 P2 * P4 *
-**
-** The string value P4 of length P1 (bytes) is stored in register P2.
-*/
-case OP_String: { /* out2-prerelease */
- assert( pOp->p4.z!=0 );
- pOut->flags = MEM_Str|MEM_Static|MEM_Term;
- pOut->z = pOp->p4.z;
- pOut->n = pOp->p1;
- pOut->enc = encoding;
- UPDATE_MAX_BLOBSIZE(pOut);
- break;
-}
-
-/* Opcode: Null * P2 * * *
-**
-** Write a NULL into register P2.
-*/
-case OP_Null: { /* out2-prerelease */
- break;
-}
-
-
-/* Opcode: Blob P1 P2 * P4
-**
-** P4 points to a blob of data P1 bytes long. Store this
-** blob in register P2. This instruction is not coded directly
-** by the compiler. Instead, the compiler layer specifies
-** an OP_HexBlob opcode, with the hex string representation of
-** the blob as P4. This opcode is transformed to an OP_Blob
-** the first time it is executed.
-*/
-case OP_Blob: { /* out2-prerelease */
- assert( pOp->p1 <= SQLITE_MAX_LENGTH );
- sqlite3VdbeMemSetStr(pOut, pOp->p4.z, pOp->p1, 0, 0);
- pOut->enc = encoding;
- UPDATE_MAX_BLOBSIZE(pOut);
- break;
-}
-
-/* Opcode: Variable P1 P2 P3 P4 *
-**
-** Transfer the values of bound parameters P1..P1+P3-1 into registers
-** P2..P2+P3-1.
-**
-** If the parameter is named, then its name appears in P4 and P3==1.
-** The P4 value is used by sqlite3_bind_parameter_name().
-*/
-case OP_Variable: {
-#if 0 /* local variables moved into u.ab */
- int p1; /* Variable to copy from */
- int p2; /* Register to copy to */
- int n; /* Number of values left to copy */
- Mem *pVar; /* Value being transferred */
-#endif /* local variables moved into u.ab */
-
- u.ab.p1 = pOp->p1 - 1;
- u.ab.p2 = pOp->p2;
- u.ab.n = pOp->p3;
- assert( u.ab.p1>=0 && u.ab.p1+u.ab.n<=p->nVar );
- assert( u.ab.p2>=1 && u.ab.p2+u.ab.n-1<=p->nMem );
- assert( pOp->p4.z==0 || pOp->p3==1 );
-
- while( u.ab.n-- > 0 ){
- u.ab.pVar = &p->aVar[u.ab.p1++];
- if( sqlite3VdbeMemTooBig(u.ab.pVar) ){
- goto too_big;
- }
- pOut = &p->aMem[u.ab.p2++];
- sqlite3VdbeMemReleaseExternal(pOut);
- pOut->flags = MEM_Null;
- sqlite3VdbeMemShallowCopy(pOut, u.ab.pVar, MEM_Static);
- UPDATE_MAX_BLOBSIZE(pOut);
- }
- break;
-}
-
-/* Opcode: Move P1 P2 P3 * *
-**
-** Move the values in register P1..P1+P3-1 over into
-** registers P2..P2+P3-1. Registers P1..P1+P1-1 are
-** left holding a NULL. It is an error for register ranges
-** P1..P1+P3-1 and P2..P2+P3-1 to overlap.
-*/
-case OP_Move: {
-#if 0 /* local variables moved into u.ac */
- char *zMalloc; /* Holding variable for allocated memory */
- int n; /* Number of registers left to copy */
- int p1; /* Register to copy from */
- int p2; /* Register to copy to */
-#endif /* local variables moved into u.ac */
-
- u.ac.n = pOp->p3;
- u.ac.p1 = pOp->p1;
- u.ac.p2 = pOp->p2;
- assert( u.ac.n>0 && u.ac.p1>0 && u.ac.p2>0 );
- assert( u.ac.p1+u.ac.n<=u.ac.p2 || u.ac.p2+u.ac.n<=u.ac.p1 );
-
- pIn1 = &p->aMem[u.ac.p1];
- pOut = &p->aMem[u.ac.p2];
- while( u.ac.n-- ){
- assert( pOut<=&p->aMem[p->nMem] );
- assert( pIn1<=&p->aMem[p->nMem] );
- u.ac.zMalloc = pOut->zMalloc;
- pOut->zMalloc = 0;
- sqlite3VdbeMemMove(pOut, pIn1);
- pIn1->zMalloc = u.ac.zMalloc;
- REGISTER_TRACE(u.ac.p2++, pOut);
- pIn1++;
- pOut++;
- }
- break;
-}
-
-/* Opcode: Copy P1 P2 * * *
-**
-** Make a copy of register P1 into register P2.
-**
-** This instruction makes a deep copy of the value. A duplicate
-** is made of any string or blob constant. See also OP_SCopy.
-*/
-case OP_Copy: { /* in1 */
- assert( pOp->p2>0 );
- assert( pOp->p2<=p->nMem );
- pOut = &p->aMem[pOp->p2];
- assert( pOut!=pIn1 );
- sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem);
- Deephemeralize(pOut);
- REGISTER_TRACE(pOp->p2, pOut);
- break;
-}
-
-/* Opcode: SCopy P1 P2 * * *
-**
-** Make a shallow copy of register P1 into register P2.
-**
-** This instruction makes a shallow copy of the value. If the value
-** is a string or blob, then the copy is only a pointer to the
-** original and hence if the original changes so will the copy.
-** Worse, if the original is deallocated, the copy becomes invalid.
-** Thus the program must guarantee that the original will not change
-** during the lifetime of the copy. Use OP_Copy to make a complete
-** copy.
-*/
-case OP_SCopy: { /* in1 */
- REGISTER_TRACE(pOp->p1, pIn1);
- assert( pOp->p2>0 );
- assert( pOp->p2<=p->nMem );
- pOut = &p->aMem[pOp->p2];
- assert( pOut!=pIn1 );
- sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem);
- REGISTER_TRACE(pOp->p2, pOut);
- break;
-}
-
-/* Opcode: ResultRow P1 P2 * * *
-**
-** The registers P1 through P1+P2-1 contain a single row of
-** results. This opcode causes the sqlite3_step() call to terminate
-** with an SQLITE_ROW return code and it sets up the sqlite3_stmt
-** structure to provide access to the top P1 values as the result
-** row.
-*/
-case OP_ResultRow: {
-#if 0 /* local variables moved into u.ad */
- Mem *pMem;
- int i;
-#endif /* local variables moved into u.ad */
- assert( p->nResColumn==pOp->p2 );
- assert( pOp->p1>0 );
- assert( pOp->p1+pOp->p2<=p->nMem+1 );
-
- /* If the SQLITE_CountRows flag is set in sqlite3.flags mask, then
- ** DML statements invoke this opcode to return the number of rows
- ** modified to the user. This is the only way that a VM that
- ** opens a statement transaction may invoke this opcode.
- **
- ** In case this is such a statement, close any statement transaction
- ** opened by this VM before returning control to the user. This is to
- ** ensure that statement-transactions are always nested, not overlapping.
- ** If the open statement-transaction is not closed here, then the user
- ** may step another VM that opens its own statement transaction. This
- ** may lead to overlapping statement transactions.
- **
- ** The statement transaction is never a top-level transaction. Hence
- ** the RELEASE call below can never fail.
- */
- assert( p->iStatement==0 || db->flags&SQLITE_CountRows );
- rc = sqlite3VdbeCloseStatement(p, SAVEPOINT_RELEASE);
- if( NEVER(rc!=SQLITE_OK) ){
- break;
- }
-
- /* Invalidate all ephemeral cursor row caches */
- p->cacheCtr = (p->cacheCtr + 2)|1;
-
- /* 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.
- */
- u.ad.pMem = p->pResultSet = &p->aMem[pOp->p1];
- for(u.ad.i=0; u.ad.i<pOp->p2; u.ad.i++){
- sqlite3VdbeMemNulTerminate(&u.ad.pMem[u.ad.i]);
- storeTypeInfo(&u.ad.pMem[u.ad.i], encoding);
- REGISTER_TRACE(pOp->p1+u.ad.i, &u.ad.pMem[u.ad.i]);
- }
- if( db->mallocFailed ) goto no_mem;
-
- /* Return SQLITE_ROW
- */
- p->pc = pc + 1;
- rc = SQLITE_ROW;
- goto vdbe_return;
-}
-
-/* Opcode: Concat P1 P2 P3 * *
-**
-** Add the text in register P1 onto the end of the text in
-** register P2 and store the result in register P3.
-** If either the P1 or P2 text are NULL then store NULL in P3.
-**
-** P3 = P2 || P1
-**
-** It is illegal for P1 and P3 to be the same register. Sometimes,
-** if P3 is the same register as P2, the implementation is able
-** to avoid a memcpy().
-*/
-case OP_Concat: { /* same as TK_CONCAT, in1, in2, out3 */
-#if 0 /* local variables moved into u.ae */
- i64 nByte;
-#endif /* local variables moved into u.ae */
-
- assert( pIn1!=pOut );
- if( (pIn1->flags | pIn2->flags) & MEM_Null ){
- sqlite3VdbeMemSetNull(pOut);
- break;
- }
- if( ExpandBlob(pIn1) || ExpandBlob(pIn2) ) goto no_mem;
- Stringify(pIn1, encoding);
- Stringify(pIn2, encoding);
- u.ae.nByte = pIn1->n + pIn2->n;
- if( u.ae.nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){
- goto too_big;
- }
- MemSetTypeFlag(pOut, MEM_Str);
- if( sqlite3VdbeMemGrow(pOut, (int)u.ae.nByte+2, pOut==pIn2) ){
- goto no_mem;
- }
- if( pOut!=pIn2 ){
- memcpy(pOut->z, pIn2->z, pIn2->n);
- }
- memcpy(&pOut->z[pIn2->n], pIn1->z, pIn1->n);
- pOut->z[u.ae.nByte] = 0;
- pOut->z[u.ae.nByte+1] = 0;
- pOut->flags |= MEM_Term;
- pOut->n = (int)u.ae.nByte;
- pOut->enc = encoding;
- UPDATE_MAX_BLOBSIZE(pOut);
- break;
-}
-
-/* Opcode: Add P1 P2 P3 * *
-**
-** Add the value in register P1 to the value in register P2
-** and store the result in register P3.
-** If either input is NULL, the result is NULL.
-*/
-/* Opcode: Multiply P1 P2 P3 * *
-**
-**
-** Multiply the value in register P1 by the value in register P2
-** and store the result in register P3.
-** If either input is NULL, the result is NULL.
-*/
-/* Opcode: Subtract P1 P2 P3 * *
-**
-** Subtract the value in register P1 from the value in register P2
-** and store the result in register P3.
-** If either input is NULL, the result is NULL.
-*/
-/* Opcode: Divide P1 P2 P3 * *
-**
-** Divide the value in register P1 by the value in register P2
-** and store the result in register P3 (P3=P2/P1). If the value in
-** register P1 is zero, then the result is NULL. If either input is
-** NULL, the result is NULL.
-*/
-/* Opcode: Remainder P1 P2 P3 * *
-**
-** Compute the remainder after integer division of the value in
-** register P1 by the value in register P2 and store the result in P3.
-** If the value in register P2 is zero the result is NULL.
-** If either operand is NULL, the result is NULL.
-*/
-case OP_Add: /* same as TK_PLUS, in1, in2, out3 */
-case OP_Subtract: /* same as TK_MINUS, in1, in2, out3 */
-case OP_Multiply: /* same as TK_STAR, in1, in2, out3 */
-case OP_Divide: /* same as TK_SLASH, in1, in2, out3 */
-case OP_Remainder: { /* same as TK_REM, in1, in2, out3 */
-#if 0 /* local variables moved into u.af */
- int flags; /* Combined MEM_* flags from both inputs */
- i64 iA; /* Integer value of left operand */
- i64 iB; /* Integer value of right operand */
- double rA; /* Real value of left operand */
- double rB; /* Real value of right operand */
-#endif /* local variables moved into u.af */
-
- applyNumericAffinity(pIn1);
- applyNumericAffinity(pIn2);
- u.af.flags = pIn1->flags | pIn2->flags;
- if( (u.af.flags & MEM_Null)!=0 ) goto arithmetic_result_is_null;
- if( (pIn1->flags & pIn2->flags & MEM_Int)==MEM_Int ){
- u.af.iA = pIn1->u.i;
- u.af.iB = pIn2->u.i;
- switch( pOp->opcode ){
- case OP_Add: u.af.iB += u.af.iA; break;
- case OP_Subtract: u.af.iB -= u.af.iA; break;
- case OP_Multiply: u.af.iB *= u.af.iA; break;
- case OP_Divide: {
- if( u.af.iA==0 ) goto arithmetic_result_is_null;
- /* Dividing the largest possible negative 64-bit integer (1<<63) by
- ** -1 returns an integer too large to store in a 64-bit data-type. On
- ** some architectures, the value overflows to (1<<63). On others,
- ** a SIGFPE is issued. The following statement normalizes this
- ** behavior so that all architectures behave as if integer
- ** overflow occurred.
- */
- if( u.af.iA==-1 && u.af.iB==SMALLEST_INT64 ) u.af.iA = 1;
- u.af.iB /= u.af.iA;
- break;
- }
- default: {
- if( u.af.iA==0 ) goto arithmetic_result_is_null;
- if( u.af.iA==-1 ) u.af.iA = 1;
- u.af.iB %= u.af.iA;
- break;
- }
- }
- pOut->u.i = u.af.iB;
- MemSetTypeFlag(pOut, MEM_Int);
- }else{
- u.af.rA = sqlite3VdbeRealValue(pIn1);
- u.af.rB = sqlite3VdbeRealValue(pIn2);
- switch( pOp->opcode ){
- case OP_Add: u.af.rB += u.af.rA; break;
- case OP_Subtract: u.af.rB -= u.af.rA; break;
- case OP_Multiply: u.af.rB *= u.af.rA; break;
- case OP_Divide: {
- /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */
- if( u.af.rA==(double)0 ) goto arithmetic_result_is_null;
- u.af.rB /= u.af.rA;
- break;
- }
- default: {
- u.af.iA = (i64)u.af.rA;
- u.af.iB = (i64)u.af.rB;
- if( u.af.iA==0 ) goto arithmetic_result_is_null;
- if( u.af.iA==-1 ) u.af.iA = 1;
- u.af.rB = (double)(u.af.iB % u.af.iA);
- break;
- }
- }
- if( sqlite3IsNaN(u.af.rB) ){
- goto arithmetic_result_is_null;
- }
- pOut->r = u.af.rB;
- MemSetTypeFlag(pOut, MEM_Real);
- if( (u.af.flags & MEM_Real)==0 ){
- sqlite3VdbeIntegerAffinity(pOut);
- }
- }
- break;
-
-arithmetic_result_is_null:
- sqlite3VdbeMemSetNull(pOut);
- break;
-}
-
-/* Opcode: CollSeq * * P4
-**
-** P4 is a pointer to a CollSeq struct. If the next call to a user function
-** or aggregate calls sqlite3GetFuncCollSeq(), this collation sequence will
-** be returned. This is used by the built-in min(), max() and nullif()
-** functions.
-**
-** The interface used by the implementation of the aforementioned functions
-** to retrieve the collation sequence set by this opcode is not available
-** publicly, only to user functions defined in func.c.
-*/
-case OP_CollSeq: {
- assert( pOp->p4type==P4_COLLSEQ );
- break;
-}
-
-/* Opcode: Function P1 P2 P3 P4 P5
-**
-** Invoke a user function (P4 is a pointer to a Function structure that
-** defines the function) with P5 arguments taken from register P2 and
-** successors. The result of the function is stored in register P3.
-** Register P3 must not be one of the function inputs.
-**
-** P1 is a 32-bit bitmask indicating whether or not each argument to the
-** function was determined to be constant at compile time. If the first
-** argument was constant then bit 0 of P1 is set. This is used to determine
-** whether meta data associated with a user function argument using the
-** sqlite3_set_auxdata() API may be safely retained until the next
-** invocation of this opcode.
-**
-** See also: AggStep and AggFinal
-*/
-case OP_Function: {
-#if 0 /* local variables moved into u.ag */
- int i;
- Mem *pArg;
- sqlite3_context ctx;
- sqlite3_value **apVal;
- int n;
-#endif /* local variables moved into u.ag */
-
- u.ag.n = pOp->p5;
- u.ag.apVal = p->apArg;
- assert( u.ag.apVal || u.ag.n==0 );
-
- assert( u.ag.n==0 || (pOp->p2>0 && pOp->p2+u.ag.n<=p->nMem+1) );
- assert( pOp->p3<pOp->p2 || pOp->p3>=pOp->p2+u.ag.n );
- u.ag.pArg = &p->aMem[pOp->p2];
- for(u.ag.i=0; u.ag.i<u.ag.n; u.ag.i++, u.ag.pArg++){
- u.ag.apVal[u.ag.i] = u.ag.pArg;
- storeTypeInfo(u.ag.pArg, encoding);
- REGISTER_TRACE(pOp->p2, u.ag.pArg);
- }
-
- assert( pOp->p4type==P4_FUNCDEF || pOp->p4type==P4_VDBEFUNC );
- if( pOp->p4type==P4_FUNCDEF ){
- u.ag.ctx.pFunc = pOp->p4.pFunc;
- u.ag.ctx.pVdbeFunc = 0;
- }else{
- u.ag.ctx.pVdbeFunc = (VdbeFunc*)pOp->p4.pVdbeFunc;
- u.ag.ctx.pFunc = u.ag.ctx.pVdbeFunc->pFunc;
- }
-
- assert( pOp->p3>0 && pOp->p3<=p->nMem );
- pOut = &p->aMem[pOp->p3];
- u.ag.ctx.s.flags = MEM_Null;
- u.ag.ctx.s.db = db;
- u.ag.ctx.s.xDel = 0;
- u.ag.ctx.s.zMalloc = 0;
-
- /* The output cell may already have a buffer allocated. Move
- ** the pointer to u.ag.ctx.s so in case the user-function can use
- ** the already allocated buffer instead of allocating a new one.
- */
- sqlite3VdbeMemMove(&u.ag.ctx.s, pOut);
- MemSetTypeFlag(&u.ag.ctx.s, MEM_Null);
-
- u.ag.ctx.isError = 0;
- if( u.ag.ctx.pFunc->flags & SQLITE_FUNC_NEEDCOLL ){
- assert( pOp>p->aOp );
- assert( pOp[-1].p4type==P4_COLLSEQ );
- assert( pOp[-1].opcode==OP_CollSeq );
- u.ag.ctx.pColl = pOp[-1].p4.pColl;
- }
- if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
- (*u.ag.ctx.pFunc->xFunc)(&u.ag.ctx, u.ag.n, u.ag.apVal);
- if( sqlite3SafetyOn(db) ){
- sqlite3VdbeMemRelease(&u.ag.ctx.s);
- goto abort_due_to_misuse;
- }
- if( db->mallocFailed ){
- /* Even though a malloc() has failed, the implementation of the
- ** user function may have called an sqlite3_result_XXX() function
- ** to return a value. The following call releases any resources
- ** associated with such a value.
- **
- ** Note: Maybe MemRelease() should be called if sqlite3SafetyOn()
- ** fails also (the if(...) statement above). But if people are
- ** misusing sqlite, they have bigger problems than a leaked value.
- */
- sqlite3VdbeMemRelease(&u.ag.ctx.s);
- goto no_mem;
- }
-
- /* If any auxiliary data functions have been called by this user function,
- ** immediately call the destructor for any non-static values.
- */
- if( u.ag.ctx.pVdbeFunc ){
- sqlite3VdbeDeleteAuxData(u.ag.ctx.pVdbeFunc, pOp->p1);
- pOp->p4.pVdbeFunc = u.ag.ctx.pVdbeFunc;
- pOp->p4type = P4_VDBEFUNC;
- }
-
- /* If the function returned an error, throw an exception */
- if( u.ag.ctx.isError ){
- sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&u.ag.ctx.s));
- rc = u.ag.ctx.isError;
- }
-
- /* Copy the result of the function into register P3 */
- sqlite3VdbeChangeEncoding(&u.ag.ctx.s, encoding);
- sqlite3VdbeMemMove(pOut, &u.ag.ctx.s);
- if( sqlite3VdbeMemTooBig(pOut) ){
- goto too_big;
- }
- REGISTER_TRACE(pOp->p3, pOut);
- UPDATE_MAX_BLOBSIZE(pOut);
- break;
-}
-
-/* Opcode: BitAnd P1 P2 P3 * *
-**
-** Take the bit-wise AND of the values in register P1 and P2 and
-** store the result in register P3.
-** If either input is NULL, the result is NULL.
-*/
-/* Opcode: BitOr P1 P2 P3 * *
-**
-** Take the bit-wise OR of the values in register P1 and P2 and
-** store the result in register P3.
-** If either input is NULL, the result is NULL.
-*/
-/* Opcode: ShiftLeft P1 P2 P3 * *
-**
-** Shift the integer value in register P2 to the left by the
-** number of bits specified by the integer in regiser P1.
-** Store the result in register P3.
-** If either input is NULL, the result is NULL.
-*/
-/* Opcode: ShiftRight P1 P2 P3 * *
-**
-** Shift the integer value in register P2 to the right by the
-** number of bits specified by the integer in register P1.
-** Store the result in register P3.
-** If either input is NULL, the result is NULL.
-*/
-case OP_BitAnd: /* same as TK_BITAND, in1, in2, out3 */
-case OP_BitOr: /* same as TK_BITOR, in1, in2, out3 */
-case OP_ShiftLeft: /* same as TK_LSHIFT, in1, in2, out3 */
-case OP_ShiftRight: { /* same as TK_RSHIFT, in1, in2, out3 */
-#if 0 /* local variables moved into u.ah */
- i64 a;
- i64 b;
-#endif /* local variables moved into u.ah */
-
- if( (pIn1->flags | pIn2->flags) & MEM_Null ){
- sqlite3VdbeMemSetNull(pOut);
- break;
- }
- u.ah.a = sqlite3VdbeIntValue(pIn2);
- u.ah.b = sqlite3VdbeIntValue(pIn1);
- switch( pOp->opcode ){
- case OP_BitAnd: u.ah.a &= u.ah.b; break;
- case OP_BitOr: u.ah.a |= u.ah.b; break;
- case OP_ShiftLeft: u.ah.a <<= u.ah.b; break;
- default: assert( pOp->opcode==OP_ShiftRight );
- u.ah.a >>= u.ah.b; break;
- }
- pOut->u.i = u.ah.a;
- MemSetTypeFlag(pOut, MEM_Int);
- break;
-}
-
-/* Opcode: AddImm P1 P2 * * *
-**
-** Add the constant P2 to the value in register P1.
-** The result is always an integer.
-**
-** To force any register to be an integer, just add 0.
-*/
-case OP_AddImm: { /* in1 */
- sqlite3VdbeMemIntegerify(pIn1);
- pIn1->u.i += pOp->p2;
- break;
-}
-
-/* Opcode: MustBeInt P1 P2 * * *
-**
-** Force the value in register P1 to be an integer. If the value
-** in P1 is not an integer and cannot be converted into an integer
-** without data loss, then jump immediately to P2, or if P2==0
-** raise an SQLITE_MISMATCH exception.
-*/
-case OP_MustBeInt: { /* jump, in1 */
- applyAffinity(pIn1, SQLITE_AFF_NUMERIC, encoding);
- if( (pIn1->flags & MEM_Int)==0 ){
- if( pOp->p2==0 ){
- rc = SQLITE_MISMATCH;
- goto abort_due_to_error;
- }else{
- pc = pOp->p2 - 1;
- }
- }else{
- MemSetTypeFlag(pIn1, MEM_Int);
- }
- break;
-}
-
-/* Opcode: RealAffinity P1 * * * *
-**
-** If register P1 holds an integer convert it to a real value.
-**
-** This opcode is used when extracting information from a column that
-** has REAL affinity. Such column values may still be stored as
-** integers, for space efficiency, but after extraction we want them
-** to have only a real value.
-*/
-case OP_RealAffinity: { /* in1 */
- if( pIn1->flags & MEM_Int ){
- sqlite3VdbeMemRealify(pIn1);
- }
- break;
-}
-
-#ifndef SQLITE_OMIT_CAST
-/* Opcode: ToText P1 * * * *
-**
-** Force the value in register P1 to be text.
-** If the value is numeric, convert it to a string using the
-** equivalent of printf(). Blob values are unchanged and
-** are afterwards simply interpreted as text.
-**
-** A NULL value is not changed by this routine. It remains NULL.
-*/
-case OP_ToText: { /* same as TK_TO_TEXT, in1 */
- if( pIn1->flags & MEM_Null ) break;
- assert( MEM_Str==(MEM_Blob>>3) );
- pIn1->flags |= (pIn1->flags&MEM_Blob)>>3;
- applyAffinity(pIn1, SQLITE_AFF_TEXT, encoding);
- rc = ExpandBlob(pIn1);
- assert( pIn1->flags & MEM_Str || db->mallocFailed );
- pIn1->flags &= ~(MEM_Int|MEM_Real|MEM_Blob|MEM_Zero);
- UPDATE_MAX_BLOBSIZE(pIn1);
- break;
-}
-
-/* Opcode: ToBlob P1 * * * *
-**
-** Force the value in register P1 to be a BLOB.
-** If the value is numeric, convert it to a string first.
-** Strings are simply reinterpreted as blobs with no change
-** to the underlying data.
-**
-** A NULL value is not changed by this routine. It remains NULL.
-*/
-case OP_ToBlob: { /* same as TK_TO_BLOB, in1 */
- if( pIn1->flags & MEM_Null ) break;
- if( (pIn1->flags & MEM_Blob)==0 ){
- applyAffinity(pIn1, SQLITE_AFF_TEXT, encoding);
- assert( pIn1->flags & MEM_Str || db->mallocFailed );
- MemSetTypeFlag(pIn1, MEM_Blob);
- }else{
- pIn1->flags &= ~(MEM_TypeMask&~MEM_Blob);
- }
- UPDATE_MAX_BLOBSIZE(pIn1);
- break;
-}
-
-/* Opcode: ToNumeric P1 * * * *
-**
-** Force the value in register P1 to be numeric (either an
-** integer or a floating-point number.)
-** If the value is text or blob, try to convert it to an using the
-** equivalent of atoi() or atof() and store 0 if no such conversion
-** is possible.
-**
-** A NULL value is not changed by this routine. It remains NULL.
-*/
-case OP_ToNumeric: { /* same as TK_TO_NUMERIC, in1 */
- if( (pIn1->flags & (MEM_Null|MEM_Int|MEM_Real))==0 ){
- sqlite3VdbeMemNumerify(pIn1);
- }
- break;
-}
-#endif /* SQLITE_OMIT_CAST */
-
-/* Opcode: ToInt P1 * * * *
-**
-** Force the value in register P1 be an integer. If
-** The value is currently a real number, drop its fractional part.
-** If the value is text or blob, try to convert it to an integer using the
-** equivalent of atoi() and store 0 if no such conversion is possible.
-**
-** A NULL value is not changed by this routine. It remains NULL.
-*/
-case OP_ToInt: { /* same as TK_TO_INT, in1 */
- if( (pIn1->flags & MEM_Null)==0 ){
- sqlite3VdbeMemIntegerify(pIn1);
- }
- break;
-}
-
-#ifndef SQLITE_OMIT_CAST
-/* Opcode: ToReal P1 * * * *
-**
-** Force the value in register P1 to be a floating point number.
-** If The value is currently an integer, convert it.
-** If the value is text or blob, try to convert it to an integer using the
-** equivalent of atoi() and store 0.0 if no such conversion is possible.
-**
-** A NULL value is not changed by this routine. It remains NULL.
-*/
-case OP_ToReal: { /* same as TK_TO_REAL, in1 */
- if( (pIn1->flags & MEM_Null)==0 ){
- sqlite3VdbeMemRealify(pIn1);
- }
- break;
-}
-#endif /* SQLITE_OMIT_CAST */
-
-/* Opcode: Lt P1 P2 P3 P4 P5
-**
-** Compare the values in register P1 and P3. If reg(P3)<reg(P1) then
-** jump to address P2.
-**
-** If the SQLITE_JUMPIFNULL bit of P5 is set and either reg(P1) or
-** reg(P3) is NULL then take the jump. If the SQLITE_JUMPIFNULL
-** bit is clear then fall thru if either operand is NULL.
-**
-** The SQLITE_AFF_MASK portion of P5 must be an affinity character -
-** SQLITE_AFF_TEXT, SQLITE_AFF_INTEGER, and so forth. An attempt is made
-** to coerce both inputs according to this affinity before the
-** comparison is made. If the SQLITE_AFF_MASK is 0x00, then numeric
-** affinity is used. Note that the affinity conversions are stored
-** back into the input registers P1 and P3. So this opcode can cause
-** persistent changes to registers P1 and P3.
-**
-** Once any conversions have taken place, and neither value is NULL,
-** the values are compared. If both values are blobs then memcmp() is
-** used to determine the results of the comparison. If both values
-** are text, then the appropriate collating function specified in
-** P4 is used to do the comparison. If P4 is not specified then
-** memcmp() is used to compare text string. If both values are
-** numeric, then a numeric comparison is used. If the two values
-** are of different types, then numbers are considered less than
-** strings and strings are considered less than blobs.
-**
-** If the SQLITE_STOREP2 bit of P5 is set, then do not jump. Instead,
-** store a boolean result (either 0, or 1, or NULL) in register P2.
-*/
-/* Opcode: Ne P1 P2 P3 P4 P5
-**
-** This works just like the Lt opcode except that the jump is taken if
-** the operands in registers P1 and P3 are not equal. See the Lt opcode for
-** additional information.
-*/
-/* Opcode: Eq P1 P2 P3 P4 P5
-**
-** This works just like the Lt opcode except that the jump is taken if
-** the operands in registers P1 and P3 are equal.
-** See the Lt opcode for additional information.
-*/
-/* Opcode: Le P1 P2 P3 P4 P5
-**
-** This works just like the Lt opcode except that the jump is taken if
-** the content of register P3 is less than or equal to the content of
-** register P1. See the Lt opcode for additional information.
-*/
-/* Opcode: Gt P1 P2 P3 P4 P5
-**
-** This works just like the Lt opcode except that the jump is taken if
-** the content of register P3 is greater than the content of
-** register P1. See the Lt opcode for additional information.
-*/
-/* Opcode: Ge P1 P2 P3 P4 P5
-**
-** This works just like the Lt opcode except that the jump is taken if
-** the content of register P3 is greater than or equal to the content of
-** register P1. See the Lt opcode for additional information.
-*/
-case OP_Eq: /* same as TK_EQ, jump, in1, in3 */
-case OP_Ne: /* same as TK_NE, jump, in1, in3 */
-case OP_Lt: /* same as TK_LT, jump, in1, in3 */
-case OP_Le: /* same as TK_LE, jump, in1, in3 */
-case OP_Gt: /* same as TK_GT, jump, in1, in3 */
-case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
-#if 0 /* local variables moved into u.ai */
- int flags;
- int res;
- char affinity;
-#endif /* local variables moved into u.ai */
-
- u.ai.flags = pIn1->flags|pIn3->flags;
-
- if( u.ai.flags&MEM_Null ){
- /* If either operand is NULL then the result is always NULL.
- ** The jump is taken if the SQLITE_JUMPIFNULL bit is set.
- */
- if( pOp->p5 & SQLITE_STOREP2 ){
- pOut = &p->aMem[pOp->p2];
- MemSetTypeFlag(pOut, MEM_Null);
- REGISTER_TRACE(pOp->p2, pOut);
- }else if( pOp->p5 & SQLITE_JUMPIFNULL ){
- pc = pOp->p2-1;
- }
- break;
- }
-
- u.ai.affinity = pOp->p5 & SQLITE_AFF_MASK;
- if( u.ai.affinity ){
- applyAffinity(pIn1, u.ai.affinity, encoding);
- applyAffinity(pIn3, u.ai.affinity, encoding);
- if( db->mallocFailed ) goto no_mem;
- }
-
- assert( pOp->p4type==P4_COLLSEQ || pOp->p4.pColl==0 );
- ExpandBlob(pIn1);
- ExpandBlob(pIn3);
- u.ai.res = sqlite3MemCompare(pIn3, pIn1, pOp->p4.pColl);
- switch( pOp->opcode ){
- case OP_Eq: u.ai.res = u.ai.res==0; break;
- case OP_Ne: u.ai.res = u.ai.res!=0; break;
- case OP_Lt: u.ai.res = u.ai.res<0; break;
- case OP_Le: u.ai.res = u.ai.res<=0; break;
- case OP_Gt: u.ai.res = u.ai.res>0; break;
- default: u.ai.res = u.ai.res>=0; break;
- }
-
- if( pOp->p5 & SQLITE_STOREP2 ){
- pOut = &p->aMem[pOp->p2];
- MemSetTypeFlag(pOut, MEM_Int);
- pOut->u.i = u.ai.res;
- REGISTER_TRACE(pOp->p2, pOut);
- }else if( u.ai.res ){
- pc = pOp->p2-1;
- }
- break;
-}
-
-/* Opcode: Permutation * * * P4 *
-**
-** Set the permutation used by the OP_Compare operator to be the array
-** of integers in P4.
-**
-** The permutation is only valid until the next OP_Permutation, OP_Compare,
-** OP_Halt, or OP_ResultRow. Typically the OP_Permutation should occur
-** immediately prior to the OP_Compare.
-*/
-case OP_Permutation: {
- assert( pOp->p4type==P4_INTARRAY );
- assert( pOp->p4.ai );
- aPermute = pOp->p4.ai;
- break;
-}
-
-/* Opcode: Compare P1 P2 P3 P4 *
-**
-** Compare to vectors of registers in reg(P1)..reg(P1+P3-1) (all this
-** one "A") and in reg(P2)..reg(P2+P3-1) ("B"). Save the result of
-** the comparison for use by the next OP_Jump instruct.
-**
-** P4 is a KeyInfo structure that defines collating sequences and sort
-** orders for the comparison. The permutation applies to registers
-** only. The KeyInfo elements are used sequentially.
-**
-** The comparison is a sort comparison, so NULLs compare equal,
-** NULLs are less than numbers, numbers are less than strings,
-** and strings are less than blobs.
-*/
-case OP_Compare: {
-#if 0 /* local variables moved into u.aj */
- int n;
- int i;
- int p1;
- int p2;
- const KeyInfo *pKeyInfo;
- int idx;
- CollSeq *pColl; /* Collating sequence to use on this term */
- int bRev; /* True for DESCENDING sort order */
-#endif /* local variables moved into u.aj */
-
- u.aj.n = pOp->p3;
- u.aj.pKeyInfo = pOp->p4.pKeyInfo;
- assert( u.aj.n>0 );
- assert( u.aj.pKeyInfo!=0 );
- u.aj.p1 = pOp->p1;
- assert( u.aj.p1>0 && u.aj.p1+u.aj.n<=p->nMem+1 );
- u.aj.p2 = pOp->p2;
- assert( u.aj.p2>0 && u.aj.p2+u.aj.n<=p->nMem+1 );
- for(u.aj.i=0; u.aj.i<u.aj.n; u.aj.i++){
- u.aj.idx = aPermute ? aPermute[u.aj.i] : u.aj.i;
- REGISTER_TRACE(u.aj.p1+u.aj.idx, &p->aMem[u.aj.p1+u.aj.idx]);
- REGISTER_TRACE(u.aj.p2+u.aj.idx, &p->aMem[u.aj.p2+u.aj.idx]);
- assert( u.aj.i<u.aj.pKeyInfo->nField );
- u.aj.pColl = u.aj.pKeyInfo->aColl[u.aj.i];
- u.aj.bRev = u.aj.pKeyInfo->aSortOrder[u.aj.i];
- iCompare = sqlite3MemCompare(&p->aMem[u.aj.p1+u.aj.idx], &p->aMem[u.aj.p2+u.aj.idx], u.aj.pColl);
- if( iCompare ){
- if( u.aj.bRev ) iCompare = -iCompare;
- break;
- }
- }
- aPermute = 0;
- break;
-}
-
-/* Opcode: Jump P1 P2 P3 * *
-**
-** Jump to the instruction at address P1, P2, or P3 depending on whether
-** in the most recent OP_Compare instruction the P1 vector was less than
-** equal to, or greater than the P2 vector, respectively.
-*/
-case OP_Jump: { /* jump */
- if( iCompare<0 ){
- pc = pOp->p1 - 1;
- }else if( iCompare==0 ){
- pc = pOp->p2 - 1;
- }else{
- pc = pOp->p3 - 1;
- }
- break;
-}
-
-/* Opcode: And P1 P2 P3 * *
-**
-** Take the logical AND of the values in registers P1 and P2 and
-** write the result into register P3.
-**
-** If either P1 or P2 is 0 (false) then the result is 0 even if
-** the other input is NULL. A NULL and true or two NULLs give
-** a NULL output.
-*/
-/* Opcode: Or P1 P2 P3 * *
-**
-** Take the logical OR of the values in register P1 and P2 and
-** store the answer in register P3.
-**
-** If either P1 or P2 is nonzero (true) then the result is 1 (true)
-** even if the other input is NULL. A NULL and false or two NULLs
-** give a NULL output.
-*/
-case OP_And: /* same as TK_AND, in1, in2, out3 */
-case OP_Or: { /* same as TK_OR, in1, in2, out3 */
-#if 0 /* local variables moved into u.ak */
- int v1; /* Left operand: 0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */
- int v2; /* Right operand: 0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */
-#endif /* local variables moved into u.ak */
-
- if( pIn1->flags & MEM_Null ){
- u.ak.v1 = 2;
- }else{
- u.ak.v1 = sqlite3VdbeIntValue(pIn1)!=0;
- }
- if( pIn2->flags & MEM_Null ){
- u.ak.v2 = 2;
- }else{
- u.ak.v2 = sqlite3VdbeIntValue(pIn2)!=0;
- }
- if( pOp->opcode==OP_And ){
- static const unsigned char and_logic[] = { 0, 0, 0, 0, 1, 2, 0, 2, 2 };
- u.ak.v1 = and_logic[u.ak.v1*3+u.ak.v2];
- }else{
- static const unsigned char or_logic[] = { 0, 1, 2, 1, 1, 1, 2, 1, 2 };
- u.ak.v1 = or_logic[u.ak.v1*3+u.ak.v2];
- }
- if( u.ak.v1==2 ){
- MemSetTypeFlag(pOut, MEM_Null);
- }else{
- pOut->u.i = u.ak.v1;
- MemSetTypeFlag(pOut, MEM_Int);
- }
- break;
-}
-
-/* Opcode: Not P1 P2 * * *
-**
-** Interpret the value in register P1 as a boolean value. Store the
-** boolean complement in register P2. If the value in register P1 is
-** NULL, then a NULL is stored in P2.
-*/
-case OP_Not: { /* same as TK_NOT, in1 */
- pOut = &p->aMem[pOp->p2];
- if( pIn1->flags & MEM_Null ){
- sqlite3VdbeMemSetNull(pOut);
- }else{
- sqlite3VdbeMemSetInt64(pOut, !sqlite3VdbeIntValue(pIn1));
- }
- break;
-}
-
-/* Opcode: BitNot P1 P2 * * *
-**
-** Interpret the content of register P1 as an integer. Store the
-** ones-complement of the P1 value into register P2. If P1 holds
-** a NULL then store a NULL in P2.
-*/
-case OP_BitNot: { /* same as TK_BITNOT, in1 */
- pOut = &p->aMem[pOp->p2];
- if( pIn1->flags & MEM_Null ){
- sqlite3VdbeMemSetNull(pOut);
- }else{
- sqlite3VdbeMemSetInt64(pOut, ~sqlite3VdbeIntValue(pIn1));
- }
- break;
-}
-
-/* Opcode: If P1 P2 P3 * *
-**
-** Jump to P2 if the value in register P1 is true. The value is
-** 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.
-*/
-/* Opcode: IfNot P1 P2 P3 * *
-**
-** Jump to P2 if the value in register P1 is False. The value is
-** 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.
-*/
-case OP_If: /* jump, in1 */
-case OP_IfNot: { /* jump, in1 */
-#if 0 /* local variables moved into u.al */
- int c;
-#endif /* local variables moved into u.al */
- if( pIn1->flags & MEM_Null ){
- u.al.c = pOp->p3;
- }else{
-#ifdef SQLITE_OMIT_FLOATING_POINT
- u.al.c = sqlite3VdbeIntValue(pIn1)!=0;
-#else
- u.al.c = sqlite3VdbeRealValue(pIn1)!=0.0;
-#endif
- if( pOp->opcode==OP_IfNot ) u.al.c = !u.al.c;
- }
- if( u.al.c ){
- pc = pOp->p2-1;
- }
- break;
-}
-
-/* Opcode: IsNull P1 P2 * * *
-**
-** Jump to P2 if the value in register P1 is NULL.
-*/
-case OP_IsNull: { /* same as TK_ISNULL, jump, in1 */
- if( (pIn1->flags & MEM_Null)!=0 ){
- pc = pOp->p2 - 1;
- }
- break;
-}
-
-/* Opcode: NotNull P1 P2 * * *
-**
-** Jump to P2 if the value in register P1 is not NULL.
-*/
-case OP_NotNull: { /* same as TK_NOTNULL, jump, in1 */
- if( (pIn1->flags & MEM_Null)==0 ){
- pc = pOp->p2 - 1;
- }
- break;
-}
-
-/* Opcode: Column P1 P2 P3 P4 P5
-**
-** Interpret the data that cursor P1 points to as a structure built using
-** the MakeRecord instruction. (See the MakeRecord opcode for additional
-** information about the format of the data.) Extract the P2-th column
-** from this record. If there are less that (P2+1)
-** values in the record, extract a NULL.
-**
-** The value extracted is stored in register P3.
-**
-** If the column contains fewer than P2 fields, then extract a NULL. Or,
-** if the P4 argument is a P4_MEM use the value of the P4 argument as
-** the result.
-**
-** If the OPFLAG_CLEARCACHE bit is set on P5 and P1 is a pseudo-table cursor,
-** then the cache of the cursor is reset prior to extracting the column.
-** The first OP_Column against a pseudo-table after the value of the content
-** register has changed should have this bit set.
-*/
-case OP_Column: {
-#if 0 /* local variables moved into u.am */
- u32 payloadSize; /* Number of bytes in the record */
- i64 payloadSize64; /* Number of bytes in the record */
- int p1; /* P1 value of the opcode */
- int p2; /* column number to retrieve */
- VdbeCursor *pC; /* The VDBE cursor */
- char *zRec; /* Pointer to complete record-data */
- BtCursor *pCrsr; /* The BTree cursor */
- u32 *aType; /* aType[i] holds the numeric type of the i-th column */
- u32 *aOffset; /* aOffset[i] is offset to start of data for i-th column */
- int nField; /* number of fields in the record */
- int len; /* The length of the serialized data for the column */
- int i; /* Loop counter */
- char *zData; /* Part of the record being decoded */
- Mem *pDest; /* Where to write the extracted value */
- Mem sMem; /* For storing the record being decoded */
- u8 *zIdx; /* Index into header */
- u8 *zEndHdr; /* Pointer to first byte after the header */
- u32 offset; /* Offset into the data */
- u64 offset64; /* 64-bit offset. 64 bits needed to catch overflow */
- int szHdr; /* Size of the header size field at start of record */
- int avail; /* Number of bytes of available data */
- Mem *pReg; /* PseudoTable input register */
-#endif /* local variables moved into u.am */
-
-
- u.am.p1 = pOp->p1;
- u.am.p2 = pOp->p2;
- u.am.pC = 0;
- memset(&u.am.sMem, 0, sizeof(u.am.sMem));
- assert( u.am.p1<p->nCursor );
- assert( pOp->p3>0 && pOp->p3<=p->nMem );
- u.am.pDest = &p->aMem[pOp->p3];
- MemSetTypeFlag(u.am.pDest, MEM_Null);
- u.am.zRec = 0;
-
- /* This block sets the variable u.am.payloadSize to be the total number of
- ** bytes in the record.
- **
- ** u.am.zRec is set to be the complete text of the record if it is available.
- ** The complete record text is always available for pseudo-tables
- ** If the record is stored in a cursor, the complete record text
- ** might be available in the u.am.pC->aRow cache. Or it might not be.
- ** If the data is unavailable, u.am.zRec is set to NULL.
- **
- ** We also compute the number of columns in the record. For cursors,
- ** the number of columns is stored in the VdbeCursor.nField element.
- */
- u.am.pC = p->apCsr[u.am.p1];
- assert( u.am.pC!=0 );
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- assert( u.am.pC->pVtabCursor==0 );
-#endif
- u.am.pCrsr = u.am.pC->pCursor;
- if( u.am.pCrsr!=0 ){
- /* The record is stored in a B-Tree */
- rc = sqlite3VdbeCursorMoveto(u.am.pC);
- if( rc ) goto abort_due_to_error;
- if( u.am.pC->nullRow ){
- u.am.payloadSize = 0;
- }else if( u.am.pC->cacheStatus==p->cacheCtr ){
- u.am.payloadSize = u.am.pC->payloadSize;
- u.am.zRec = (char*)u.am.pC->aRow;
- }else if( u.am.pC->isIndex ){
- assert( sqlite3BtreeCursorIsValid(u.am.pCrsr) );
- rc = sqlite3BtreeKeySize(u.am.pCrsr, &u.am.payloadSize64);
- assert( rc==SQLITE_OK ); /* True because of CursorMoveto() call above */
- /* sqlite3BtreeParseCellPtr() uses getVarint32() to extract the
- ** payload size, so it is impossible for u.am.payloadSize64 to be
- ** larger than 32 bits. */
- assert( (u.am.payloadSize64 & SQLITE_MAX_U32)==(u64)u.am.payloadSize64 );
- u.am.payloadSize = (u32)u.am.payloadSize64;
- }else{
- assert( sqlite3BtreeCursorIsValid(u.am.pCrsr) );
- rc = sqlite3BtreeDataSize(u.am.pCrsr, &u.am.payloadSize);
- assert( rc==SQLITE_OK ); /* DataSize() cannot fail */
- }
- }else if( u.am.pC->pseudoTableReg>0 ){
- u.am.pReg = &p->aMem[u.am.pC->pseudoTableReg];
- assert( u.am.pReg->flags & MEM_Blob );
- u.am.payloadSize = u.am.pReg->n;
- u.am.zRec = u.am.pReg->z;
- u.am.pC->cacheStatus = (pOp->p5&OPFLAG_CLEARCACHE) ? CACHE_STALE : p->cacheCtr;
- assert( u.am.payloadSize==0 || u.am.zRec!=0 );
- }else{
- /* Consider the row to be NULL */
- u.am.payloadSize = 0;
- }
-
- /* If u.am.payloadSize is 0, then just store a NULL */
- if( u.am.payloadSize==0 ){
- assert( u.am.pDest->flags&MEM_Null );
- goto op_column_out;
- }
- assert( db->aLimit[SQLITE_LIMIT_LENGTH]>=0 );
- if( u.am.payloadSize > (u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){
- goto too_big;
- }
-
- u.am.nField = u.am.pC->nField;
- assert( u.am.p2<u.am.nField );
-
- /* Read and parse the table header. Store the results of the parse
- ** into the record header cache fields of the cursor.
- */
- u.am.aType = u.am.pC->aType;
- if( u.am.pC->cacheStatus==p->cacheCtr ){
- u.am.aOffset = u.am.pC->aOffset;
- }else{
- assert(u.am.aType);
- u.am.avail = 0;
- u.am.pC->aOffset = u.am.aOffset = &u.am.aType[u.am.nField];
- u.am.pC->payloadSize = u.am.payloadSize;
- u.am.pC->cacheStatus = p->cacheCtr;
-
- /* Figure out how many bytes are in the header */
- if( u.am.zRec ){
- u.am.zData = u.am.zRec;
- }else{
- if( u.am.pC->isIndex ){
- u.am.zData = (char*)sqlite3BtreeKeyFetch(u.am.pCrsr, &u.am.avail);
- }else{
- u.am.zData = (char*)sqlite3BtreeDataFetch(u.am.pCrsr, &u.am.avail);
- }
- /* If KeyFetch()/DataFetch() managed to get the entire payload,
- ** save the payload in the u.am.pC->aRow cache. That will save us from
- ** having to make additional calls to fetch the content portion of
- ** the record.
- */
- assert( u.am.avail>=0 );
- if( u.am.payloadSize <= (u32)u.am.avail ){
- u.am.zRec = u.am.zData;
- u.am.pC->aRow = (u8*)u.am.zData;
- }else{
- u.am.pC->aRow = 0;
- }
- }
- /* The following assert is true in all cases accept when
- ** the database file has been corrupted externally.
- ** assert( u.am.zRec!=0 || u.am.avail>=u.am.payloadSize || u.am.avail>=9 ); */
- u.am.szHdr = getVarint32((u8*)u.am.zData, u.am.offset);
-
- /* Make sure a corrupt database has not given us an oversize header.
- ** Do this now to avoid an oversize memory allocation.
- **
- ** Type entries can be between 1 and 5 bytes each. But 4 and 5 byte
- ** types use so much data space that there can only be 4096 and 32 of
- ** them, respectively. So the maximum header length results from a
- ** 3-byte type for each of the maximum of 32768 columns plus three
- ** extra bytes for the header length itself. 32768*3 + 3 = 98307.
- */
- if( u.am.offset > 98307 ){
- rc = SQLITE_CORRUPT_BKPT;
- goto op_column_out;
- }
-
- /* Compute in u.am.len the number of bytes of data we need to read in order
- ** to get u.am.nField type values. u.am.offset is an upper bound on this. But
- ** u.am.nField might be significantly less than the true number of columns
- ** in the table, and in that case, 5*u.am.nField+3 might be smaller than u.am.offset.
- ** We want to minimize u.am.len in order to limit the size of the memory
- ** allocation, especially if a corrupt database file has caused u.am.offset
- ** to be oversized. Offset is limited to 98307 above. But 98307 might
- ** still exceed Robson memory allocation limits on some configurations.
- ** On systems that cannot tolerate large memory allocations, u.am.nField*5+3
- ** will likely be much smaller since u.am.nField will likely be less than
- ** 20 or so. This insures that Robson memory allocation limits are
- ** not exceeded even for corrupt database files.
- */
- u.am.len = u.am.nField*5 + 3;
- if( u.am.len > (int)u.am.offset ) u.am.len = (int)u.am.offset;
-
- /* The KeyFetch() or DataFetch() above are fast and will get the entire
- ** record header in most cases. But they will fail to get the complete
- ** record header if the record header does not fit on a single page
- ** in the B-Tree. When that happens, use sqlite3VdbeMemFromBtree() to
- ** acquire the complete header text.
- */
- if( !u.am.zRec && u.am.avail<u.am.len ){
- u.am.sMem.flags = 0;
- u.am.sMem.db = 0;
- rc = sqlite3VdbeMemFromBtree(u.am.pCrsr, 0, u.am.len, u.am.pC->isIndex, &u.am.sMem);
- if( rc!=SQLITE_OK ){
- goto op_column_out;
- }
- u.am.zData = u.am.sMem.z;
- }
- u.am.zEndHdr = (u8 *)&u.am.zData[u.am.len];
- u.am.zIdx = (u8 *)&u.am.zData[u.am.szHdr];
-
- /* Scan the header and use it to fill in the u.am.aType[] and u.am.aOffset[]
- ** arrays. u.am.aType[u.am.i] will contain the type integer for the u.am.i-th
- ** column and u.am.aOffset[u.am.i] will contain the u.am.offset from the beginning
- ** of the record to the start of the data for the u.am.i-th column
- */
- u.am.offset64 = u.am.offset;
- for(u.am.i=0; u.am.i<u.am.nField; u.am.i++){
- if( u.am.zIdx<u.am.zEndHdr ){
- u.am.aOffset[u.am.i] = (u32)u.am.offset64;
- u.am.zIdx += getVarint32(u.am.zIdx, u.am.aType[u.am.i]);
- u.am.offset64 += sqlite3VdbeSerialTypeLen(u.am.aType[u.am.i]);
- }else{
- /* If u.am.i is less that u.am.nField, then there are less fields in this
- ** record than SetNumColumns indicated there are columns in the
- ** table. Set the u.am.offset for any extra columns not present in
- ** the record to 0. This tells code below to store a NULL
- ** instead of deserializing a value from the record.
- */
- u.am.aOffset[u.am.i] = 0;
- }
- }
- sqlite3VdbeMemRelease(&u.am.sMem);
- u.am.sMem.flags = MEM_Null;
-
- /* If we have read more header data than was contained in the header,
- ** or if the end of the last field appears to be past the end of the
- ** record, or if the end of the last field appears to be before the end
- ** of the record (when all fields present), then we must be dealing
- ** with a corrupt database.
- */
- if( (u.am.zIdx > u.am.zEndHdr)|| (u.am.offset64 > u.am.payloadSize)
- || (u.am.zIdx==u.am.zEndHdr && u.am.offset64!=(u64)u.am.payloadSize) ){
- rc = SQLITE_CORRUPT_BKPT;
- goto op_column_out;
- }
- }
-
- /* Get the column information. If u.am.aOffset[u.am.p2] is non-zero, then
- ** deserialize the value from the record. If u.am.aOffset[u.am.p2] is zero,
- ** then there are not enough fields in the record to satisfy the
- ** request. In this case, set the value NULL or to P4 if P4 is
- ** a pointer to a Mem object.
- */
- if( u.am.aOffset[u.am.p2] ){
- assert( rc==SQLITE_OK );
- if( u.am.zRec ){
- sqlite3VdbeMemReleaseExternal(u.am.pDest);
- sqlite3VdbeSerialGet((u8 *)&u.am.zRec[u.am.aOffset[u.am.p2]], u.am.aType[u.am.p2], u.am.pDest);
- }else{
- u.am.len = sqlite3VdbeSerialTypeLen(u.am.aType[u.am.p2]);
- sqlite3VdbeMemMove(&u.am.sMem, u.am.pDest);
- rc = sqlite3VdbeMemFromBtree(u.am.pCrsr, u.am.aOffset[u.am.p2], u.am.len, u.am.pC->isIndex, &u.am.sMem);
- if( rc!=SQLITE_OK ){
- goto op_column_out;
- }
- u.am.zData = u.am.sMem.z;
- sqlite3VdbeSerialGet((u8*)u.am.zData, u.am.aType[u.am.p2], u.am.pDest);
- }
- u.am.pDest->enc = encoding;
- }else{
- if( pOp->p4type==P4_MEM ){
- sqlite3VdbeMemShallowCopy(u.am.pDest, pOp->p4.pMem, MEM_Static);
- }else{
- assert( u.am.pDest->flags&MEM_Null );
- }
- }
-
- /* If we dynamically allocated space to hold the data (in the
- ** sqlite3VdbeMemFromBtree() call above) then transfer control of that
- ** dynamically allocated space over to the u.am.pDest structure.
- ** This prevents a memory copy.
- */
- if( u.am.sMem.zMalloc ){
- assert( u.am.sMem.z==u.am.sMem.zMalloc );
- assert( !(u.am.pDest->flags & MEM_Dyn) );
- assert( !(u.am.pDest->flags & (MEM_Blob|MEM_Str)) || u.am.pDest->z==u.am.sMem.z );
- u.am.pDest->flags &= ~(MEM_Ephem|MEM_Static);
- u.am.pDest->flags |= MEM_Term;
- u.am.pDest->z = u.am.sMem.z;
- u.am.pDest->zMalloc = u.am.sMem.zMalloc;
- }
-
- rc = sqlite3VdbeMemMakeWriteable(u.am.pDest);
-
-op_column_out:
- UPDATE_MAX_BLOBSIZE(u.am.pDest);
- REGISTER_TRACE(pOp->p3, u.am.pDest);
- break;
-}
-
-/* Opcode: Affinity P1 P2 * P4 *
-**
-** Apply affinities to a range of P2 registers starting with P1.
-**
-** P4 is a string that is P2 characters long. The nth character of the
-** string indicates the column affinity that should be used for the nth
-** memory cell in the range.
-*/
-case OP_Affinity: {
-#if 0 /* local variables moved into u.an */
- char *zAffinity; /* The affinity to be applied */
- Mem *pData0; /* First register to which to apply affinity */
- Mem *pLast; /* Last register to which to apply affinity */
- Mem *pRec; /* Current register */
-#endif /* local variables moved into u.an */
-
- u.an.zAffinity = pOp->p4.z;
- u.an.pData0 = &p->aMem[pOp->p1];
- u.an.pLast = &u.an.pData0[pOp->p2-1];
- for(u.an.pRec=u.an.pData0; u.an.pRec<=u.an.pLast; u.an.pRec++){
- ExpandBlob(u.an.pRec);
- applyAffinity(u.an.pRec, u.an.zAffinity[u.an.pRec-u.an.pData0], encoding);
- }
- break;
-}
-
-/* Opcode: MakeRecord P1 P2 P3 P4 *
-**
-** Convert P2 registers beginning with P1 into a single entry
-** suitable for use as a data record in a database table or as a key
-** in an index. The details of the format are irrelevant as long as
-** the OP_Column opcode can decode the record later.
-** Refer to source code comments for the details of the record
-** format.
-**
-** P4 may be a string that is P2 characters long. The nth character of the
-** string indicates the column affinity that should be used for the nth
-** field of the index key.
-**
-** The mapping from character to affinity is given by the SQLITE_AFF_
-** macros defined in sqliteInt.h.
-**
-** If P4 is NULL then all index fields have the affinity NONE.
-*/
-case OP_MakeRecord: {
-#if 0 /* local variables moved into u.ao */
- u8 *zNewRecord; /* A buffer to hold the data for the new record */
- Mem *pRec; /* The new record */
- u64 nData; /* Number of bytes of data space */
- int nHdr; /* Number of bytes of header space */
- i64 nByte; /* Data space required for this record */
- int nZero; /* Number of zero bytes at the end of the record */
- int nVarint; /* Number of bytes in a varint */
- u32 serial_type; /* Type field */
- Mem *pData0; /* First field to be combined into the record */
- Mem *pLast; /* Last field of the record */
- int nField; /* Number of fields in the record */
- char *zAffinity; /* The affinity string for the record */
- int file_format; /* File format to use for encoding */
- int i; /* Space used in zNewRecord[] */
- int len; /* Length of a field */
-#endif /* local variables moved into u.ao */
-
- /* Assuming the record contains N fields, the record format looks
- ** like this:
- **
- ** ------------------------------------------------------------------------
- ** | hdr-size | type 0 | type 1 | ... | type N-1 | data0 | ... | data N-1 |
- ** ------------------------------------------------------------------------
- **
- ** Data(0) is taken from register P1. Data(1) comes from register P1+1
- ** and so froth.
- **
- ** Each type field is a varint representing the serial type of the
- ** corresponding data element (see sqlite3VdbeSerialType()). The
- ** hdr-size field is also a varint which is the offset from the beginning
- ** of the record to data0.
- */
- u.ao.nData = 0; /* Number of bytes of data space */
- u.ao.nHdr = 0; /* Number of bytes of header space */
- u.ao.nByte = 0; /* Data space required for this record */
- u.ao.nZero = 0; /* Number of zero bytes at the end of the record */
- u.ao.nField = pOp->p1;
- u.ao.zAffinity = pOp->p4.z;
- assert( u.ao.nField>0 && pOp->p2>0 && pOp->p2+u.ao.nField<=p->nMem+1 );
- u.ao.pData0 = &p->aMem[u.ao.nField];
- u.ao.nField = pOp->p2;
- u.ao.pLast = &u.ao.pData0[u.ao.nField-1];
- u.ao.file_format = p->minWriteFileFormat;
-
- /* Loop through the elements that will make up the record to figure
- ** out how much space is required for the new record.
- */
- for(u.ao.pRec=u.ao.pData0; u.ao.pRec<=u.ao.pLast; u.ao.pRec++){
- if( u.ao.zAffinity ){
- applyAffinity(u.ao.pRec, u.ao.zAffinity[u.ao.pRec-u.ao.pData0], encoding);
- }
- if( u.ao.pRec->flags&MEM_Zero && u.ao.pRec->n>0 ){
- sqlite3VdbeMemExpandBlob(u.ao.pRec);
- }
- u.ao.serial_type = sqlite3VdbeSerialType(u.ao.pRec, u.ao.file_format);
- u.ao.len = sqlite3VdbeSerialTypeLen(u.ao.serial_type);
- u.ao.nData += u.ao.len;
- u.ao.nHdr += sqlite3VarintLen(u.ao.serial_type);
- if( u.ao.pRec->flags & MEM_Zero ){
- /* Only pure zero-filled BLOBs can be input to this Opcode.
- ** We do not allow blobs with a prefix and a zero-filled tail. */
- u.ao.nZero += u.ao.pRec->u.nZero;
- }else if( u.ao.len ){
- u.ao.nZero = 0;
- }
- }
-
- /* Add the initial header varint and total the size */
- u.ao.nHdr += u.ao.nVarint = sqlite3VarintLen(u.ao.nHdr);
- if( u.ao.nVarint<sqlite3VarintLen(u.ao.nHdr) ){
- u.ao.nHdr++;
- }
- u.ao.nByte = u.ao.nHdr+u.ao.nData-u.ao.nZero;
- if( u.ao.nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){
- goto too_big;
- }
-
- /* Make sure the output register has a buffer large enough to store
- ** the new record. The output register (pOp->p3) is not allowed to
- ** be one of the input registers (because the following call to
- ** sqlite3VdbeMemGrow() could clobber the value before it is used).
- */
- assert( pOp->p3<pOp->p1 || pOp->p3>=pOp->p1+pOp->p2 );
- pOut = &p->aMem[pOp->p3];
- if( sqlite3VdbeMemGrow(pOut, (int)u.ao.nByte, 0) ){
- goto no_mem;
- }
- u.ao.zNewRecord = (u8 *)pOut->z;
-
- /* Write the record */
- u.ao.i = putVarint32(u.ao.zNewRecord, u.ao.nHdr);
- for(u.ao.pRec=u.ao.pData0; u.ao.pRec<=u.ao.pLast; u.ao.pRec++){
- u.ao.serial_type = sqlite3VdbeSerialType(u.ao.pRec, u.ao.file_format);
- u.ao.i += putVarint32(&u.ao.zNewRecord[u.ao.i], u.ao.serial_type); /* serial type */
- }
- for(u.ao.pRec=u.ao.pData0; u.ao.pRec<=u.ao.pLast; u.ao.pRec++){ /* serial data */
- u.ao.i += sqlite3VdbeSerialPut(&u.ao.zNewRecord[u.ao.i], (int)(u.ao.nByte-u.ao.i), u.ao.pRec,u.ao.file_format);
- }
- assert( u.ao.i==u.ao.nByte );
-
- assert( pOp->p3>0 && pOp->p3<=p->nMem );
- pOut->n = (int)u.ao.nByte;
- pOut->flags = MEM_Blob | MEM_Dyn;
- pOut->xDel = 0;
- if( u.ao.nZero ){
- pOut->u.nZero = u.ao.nZero;
- pOut->flags |= MEM_Zero;
- }
- pOut->enc = SQLITE_UTF8; /* In case the blob is ever converted to text */
- REGISTER_TRACE(pOp->p3, pOut);
- UPDATE_MAX_BLOBSIZE(pOut);
- break;
-}
-
-/* Opcode: Count P1 P2 * * *
-**
-** Store the number of entries (an integer value) in the table or index
-** opened by cursor P1 in register P2
-*/
-#ifndef SQLITE_OMIT_BTREECOUNT
-case OP_Count: { /* out2-prerelease */
-#if 0 /* local variables moved into u.ap */
- i64 nEntry;
- BtCursor *pCrsr;
-#endif /* local variables moved into u.ap */
-
- u.ap.pCrsr = p->apCsr[pOp->p1]->pCursor;
- if( u.ap.pCrsr ){
- rc = sqlite3BtreeCount(u.ap.pCrsr, &u.ap.nEntry);
- }else{
- u.ap.nEntry = 0;
- }
- pOut->flags = MEM_Int;
- pOut->u.i = u.ap.nEntry;
- break;
-}
-#endif
-
-/* Opcode: Savepoint P1 * * P4 *
-**
-** Open, release or rollback the savepoint named by parameter P4, depending
-** on the value of P1. To open a new savepoint, P1==0. To release (commit) an
-** existing savepoint, P1==1, or to rollback an existing savepoint P1==2.
-*/
-case OP_Savepoint: {
-#if 0 /* local variables moved into u.aq */
- int p1; /* Value of P1 operand */
- char *zName; /* Name of savepoint */
- int nName;
- Savepoint *pNew;
- Savepoint *pSavepoint;
- Savepoint *pTmp;
- int iSavepoint;
- int ii;
-#endif /* local variables moved into u.aq */
-
- u.aq.p1 = pOp->p1;
- u.aq.zName = pOp->p4.z;
-
- /* Assert that the u.aq.p1 parameter is valid. Also that if there is no open
- ** transaction, then there cannot be any savepoints.
- */
- assert( db->pSavepoint==0 || db->autoCommit==0 );
- assert( u.aq.p1==SAVEPOINT_BEGIN||u.aq.p1==SAVEPOINT_RELEASE||u.aq.p1==SAVEPOINT_ROLLBACK );
- assert( db->pSavepoint || db->isTransactionSavepoint==0 );
- assert( checkSavepointCount(db) );
-
- if( u.aq.p1==SAVEPOINT_BEGIN ){
- if( db->writeVdbeCnt>0 ){
- /* A new savepoint cannot be created if there are active write
- ** statements (i.e. open read/write incremental blob handles).
- */
- sqlite3SetString(&p->zErrMsg, db, "cannot open savepoint - "
- "SQL statements in progress");
- rc = SQLITE_BUSY;
- }else{
- u.aq.nName = sqlite3Strlen30(u.aq.zName);
-
- /* Create a new savepoint structure. */
- u.aq.pNew = sqlite3DbMallocRaw(db, sizeof(Savepoint)+u.aq.nName+1);
- if( u.aq.pNew ){
- u.aq.pNew->zName = (char *)&u.aq.pNew[1];
- memcpy(u.aq.pNew->zName, u.aq.zName, u.aq.nName+1);
-
- /* If there is no open transaction, then mark this as a special
- ** "transaction savepoint". */
- if( db->autoCommit ){
- db->autoCommit = 0;
- db->isTransactionSavepoint = 1;
- }else{
- db->nSavepoint++;
- }
-
- /* Link the new savepoint into the database handle's list. */
- u.aq.pNew->pNext = db->pSavepoint;
- db->pSavepoint = u.aq.pNew;
- }
- }
- }else{
- u.aq.iSavepoint = 0;
-
- /* Find the named savepoint. If there is no such savepoint, then an
- ** an error is returned to the user. */
- for(
- u.aq.pSavepoint = db->pSavepoint;
- u.aq.pSavepoint && sqlite3StrICmp(u.aq.pSavepoint->zName, u.aq.zName);
- u.aq.pSavepoint = u.aq.pSavepoint->pNext
- ){
- u.aq.iSavepoint++;
- }
- if( !u.aq.pSavepoint ){
- sqlite3SetString(&p->zErrMsg, db, "no such savepoint: %s", u.aq.zName);
- rc = SQLITE_ERROR;
- }else if(
- db->writeVdbeCnt>0 || (u.aq.p1==SAVEPOINT_ROLLBACK && db->activeVdbeCnt>1)
- ){
- /* It is not possible to release (commit) a savepoint if there are
- ** active write statements. It is not possible to rollback a savepoint
- ** if there are any active statements at all.
- */
- sqlite3SetString(&p->zErrMsg, db,
- "cannot %s savepoint - SQL statements in progress",
- (u.aq.p1==SAVEPOINT_ROLLBACK ? "rollback": "release")
- );
- rc = SQLITE_BUSY;
- }else{
-
- /* Determine whether or not this is a transaction savepoint. If so,
- ** and this is a RELEASE command, then the current transaction
- ** is committed.
- */
- int isTransaction = u.aq.pSavepoint->pNext==0 && db->isTransactionSavepoint;
- if( isTransaction && u.aq.p1==SAVEPOINT_RELEASE ){
- db->autoCommit = 1;
- if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){
- p->pc = pc;
- db->autoCommit = 0;
- p->rc = rc = SQLITE_BUSY;
- goto vdbe_return;
- }
- db->isTransactionSavepoint = 0;
- rc = p->rc;
- }else{
- u.aq.iSavepoint = db->nSavepoint - u.aq.iSavepoint - 1;
- for(u.aq.ii=0; u.aq.ii<db->nDb; u.aq.ii++){
- rc = sqlite3BtreeSavepoint(db->aDb[u.aq.ii].pBt, u.aq.p1, u.aq.iSavepoint);
- if( rc!=SQLITE_OK ){
- goto abort_due_to_error;
- }
- }
- if( u.aq.p1==SAVEPOINT_ROLLBACK && (db->flags&SQLITE_InternChanges)!=0 ){
- sqlite3ExpirePreparedStatements(db);
- sqlite3ResetInternalSchema(db, 0);
- }
- }
-
- /* Regardless of whether this is a RELEASE or ROLLBACK, destroy all
- ** savepoints nested inside of the savepoint being operated on. */
- while( db->pSavepoint!=u.aq.pSavepoint ){
- u.aq.pTmp = db->pSavepoint;
- db->pSavepoint = u.aq.pTmp->pNext;
- sqlite3DbFree(db, u.aq.pTmp);
- db->nSavepoint--;
- }
-
- /* If it is a RELEASE, then destroy the savepoint being operated on too */
- if( u.aq.p1==SAVEPOINT_RELEASE ){
- assert( u.aq.pSavepoint==db->pSavepoint );
- db->pSavepoint = u.aq.pSavepoint->pNext;
- sqlite3DbFree(db, u.aq.pSavepoint);
- if( !isTransaction ){
- db->nSavepoint--;
- }
- }
- }
- }
-
- break;
-}
-
-/* Opcode: AutoCommit P1 P2 * * *
-**
-** Set the database auto-commit flag to P1 (1 or 0). If P2 is true, roll
-** back any currently active btree transactions. If there are any active
-** VMs (apart from this one), then a ROLLBACK fails. A COMMIT fails if
-** there are active writing VMs or active VMs that use shared cache.
-**
-** This instruction causes the VM to halt.
-*/
-case OP_AutoCommit: {
-#if 0 /* local variables moved into u.ar */
- int desiredAutoCommit;
- int iRollback;
- int turnOnAC;
-#endif /* local variables moved into u.ar */
-
- u.ar.desiredAutoCommit = pOp->p1;
- u.ar.iRollback = pOp->p2;
- u.ar.turnOnAC = u.ar.desiredAutoCommit && !db->autoCommit;
- assert( u.ar.desiredAutoCommit==1 || u.ar.desiredAutoCommit==0 );
- assert( u.ar.desiredAutoCommit==1 || u.ar.iRollback==0 );
- assert( db->activeVdbeCnt>0 ); /* At least this one VM is active */
-
- if( u.ar.turnOnAC && u.ar.iRollback && db->activeVdbeCnt>1 ){
- /* If this instruction implements a ROLLBACK and other VMs are
- ** still running, and a transaction is active, return an error indicating
- ** that the other VMs must complete first.
- */
- sqlite3SetString(&p->zErrMsg, db, "cannot rollback transaction - "
- "SQL statements in progress");
- rc = SQLITE_BUSY;
- }else if( u.ar.turnOnAC && !u.ar.iRollback && db->writeVdbeCnt>0 ){
- /* If this instruction implements a COMMIT and other VMs are writing
- ** return an error indicating that the other VMs must complete first.
- */
- sqlite3SetString(&p->zErrMsg, db, "cannot commit transaction - "
- "SQL statements in progress");
- rc = SQLITE_BUSY;
- }else if( u.ar.desiredAutoCommit!=db->autoCommit ){
- if( u.ar.iRollback ){
- assert( u.ar.desiredAutoCommit==1 );
- sqlite3RollbackAll(db);
- db->autoCommit = 1;
- }else{
- db->autoCommit = (u8)u.ar.desiredAutoCommit;
- if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){
- p->pc = pc;
- db->autoCommit = (u8)(1-u.ar.desiredAutoCommit);
- p->rc = rc = SQLITE_BUSY;
- goto vdbe_return;
- }
- }
- assert( db->nStatement==0 );
- sqlite3CloseSavepoints(db);
- if( p->rc==SQLITE_OK ){
- rc = SQLITE_DONE;
- }else{
- rc = SQLITE_ERROR;
- }
- goto vdbe_return;
- }else{
- sqlite3SetString(&p->zErrMsg, db,
- (!u.ar.desiredAutoCommit)?"cannot start a transaction within a transaction":(
- (u.ar.iRollback)?"cannot rollback - no transaction is active":
- "cannot commit - no transaction is active"));
-
- rc = SQLITE_ERROR;
- }
- break;
-}
-
-/* Opcode: Transaction P1 P2 * * *
-**
-** Begin a transaction. The transaction ends when a Commit or Rollback
-** opcode is encountered. Depending on the ON CONFLICT setting, the
-** transaction might also be rolled back if an error is encountered.
-**
-** P1 is the index of the database file on which the transaction is
-** started. Index 0 is the main database file and index 1 is the
-** file used for temporary tables. Indices of 2 or more are used for
-** attached databases.
-**
-** If P2 is non-zero, then a write-transaction is started. A RESERVED lock is
-** obtained on the database file when a write-transaction is started. No
-** other process can start another write transaction while this transaction is
-** underway. Starting a write transaction also creates a rollback journal. A
-** write transaction must be started before any changes can be made to the
-** database. If P2 is 2 or greater then an EXCLUSIVE lock is also obtained
-** on the file.
-**
-** If a write-transaction is started and the Vdbe.usesStmtJournal flag is
-** true (this flag is set if the Vdbe may modify more than one row and may
-** throw an ABORT exception), a statement transaction may also be opened.
-** More specifically, a statement transaction is opened iff the database
-** connection is currently not in autocommit mode, or if there are other
-** active statements. A statement transaction allows the affects of this
-** VDBE to be rolled back after an error without having to roll back the
-** entire transaction. If no error is encountered, the statement transaction
-** will automatically commit when the VDBE halts.
-**
-** If P2 is zero, then a read-lock is obtained on the database file.
-*/
-case OP_Transaction: {
-#if 0 /* local variables moved into u.as */
- Btree *pBt;
-#endif /* local variables moved into u.as */
-
- assert( pOp->p1>=0 && pOp->p1<db->nDb );
- assert( (p->btreeMask & (1<<pOp->p1))!=0 );
- u.as.pBt = db->aDb[pOp->p1].pBt;
-
- if( u.as.pBt ){
- rc = sqlite3BtreeBeginTrans(u.as.pBt, pOp->p2);
- if( rc==SQLITE_BUSY ){
- p->pc = pc;
- p->rc = rc = SQLITE_BUSY;
- goto vdbe_return;
- }
- if( rc!=SQLITE_OK && rc!=SQLITE_READONLY /* && rc!=SQLITE_BUSY */ ){
- goto abort_due_to_error;
- }
-
- if( pOp->p2 && p->usesStmtJournal
- && (db->autoCommit==0 || db->activeVdbeCnt>1)
- ){
- assert( sqlite3BtreeIsInTrans(u.as.pBt) );
- if( p->iStatement==0 ){
- assert( db->nStatement>=0 && db->nSavepoint>=0 );
- db->nStatement++;
- p->iStatement = db->nSavepoint + db->nStatement;
- }
- rc = sqlite3BtreeBeginStmt(u.as.pBt, p->iStatement);
- }
- }
- break;
-}
-
-/* Opcode: ReadCookie P1 P2 P3 * *
-**
-** Read cookie number P3 from database P1 and write it into register P2.
-** P3==1 is the schema version. P3==2 is the database format.
-** P3==3 is the recommended pager cache size, and so forth. P1==0 is
-** the main database file and P1==1 is the database file used to store
-** temporary tables.
-**
-** There must be a read-lock on the database (either a transaction
-** must be started or there must be an open cursor) before
-** executing this instruction.
-*/
-case OP_ReadCookie: { /* out2-prerelease */
-#if 0 /* local variables moved into u.at */
- int iMeta;
- int iDb;
- int iCookie;
-#endif /* local variables moved into u.at */
-
- u.at.iDb = pOp->p1;
- u.at.iCookie = pOp->p3;
- assert( pOp->p3<SQLITE_N_BTREE_META );
- assert( u.at.iDb>=0 && u.at.iDb<db->nDb );
- assert( db->aDb[u.at.iDb].pBt!=0 );
- assert( (p->btreeMask & (1<<u.at.iDb))!=0 );
-
- sqlite3BtreeGetMeta(db->aDb[u.at.iDb].pBt, u.at.iCookie, (u32 *)&u.at.iMeta);
- pOut->u.i = u.at.iMeta;
- MemSetTypeFlag(pOut, MEM_Int);
- break;
-}
-
-/* Opcode: SetCookie P1 P2 P3 * *
-**
-** Write the content of register P3 (interpreted as an integer)
-** into cookie number P2 of database P1. P2==1 is the schema version.
-** P2==2 is the database format. P2==3 is the recommended pager cache
-** size, and so forth. P1==0 is the main database file and P1==1 is the
-** database file used to store temporary tables.
-**
-** A transaction must be started before executing this opcode.
-*/
-case OP_SetCookie: { /* in3 */
-#if 0 /* local variables moved into u.au */
- Db *pDb;
-#endif /* local variables moved into u.au */
- assert( pOp->p2<SQLITE_N_BTREE_META );
- assert( pOp->p1>=0 && pOp->p1<db->nDb );
- assert( (p->btreeMask & (1<<pOp->p1))!=0 );
- u.au.pDb = &db->aDb[pOp->p1];
- assert( u.au.pDb->pBt!=0 );
- sqlite3VdbeMemIntegerify(pIn3);
- /* See note about index shifting on OP_ReadCookie */
- rc = sqlite3BtreeUpdateMeta(u.au.pDb->pBt, pOp->p2, (int)pIn3->u.i);
- if( pOp->p2==BTREE_SCHEMA_VERSION ){
- /* When the schema cookie changes, record the new cookie internally */
- u.au.pDb->pSchema->schema_cookie = (int)pIn3->u.i;
- db->flags |= SQLITE_InternChanges;
- }else if( pOp->p2==BTREE_FILE_FORMAT ){
- /* Record changes in the file format */
- u.au.pDb->pSchema->file_format = (u8)pIn3->u.i;
- }
- if( pOp->p1==1 ){
- /* Invalidate all prepared statements whenever the TEMP database
- ** schema is changed. Ticket #1644 */
- sqlite3ExpirePreparedStatements(db);
- }
- break;
-}
-
-/* Opcode: VerifyCookie P1 P2 *
-**
-** Check the value of global database parameter number 0 (the
-** schema version) and make sure it is equal to P2.
-** P1 is the database number which is 0 for the main database file
-** and 1 for the file holding temporary tables and some higher number
-** for auxiliary databases.
-**
-** The cookie changes its value whenever the database schema changes.
-** This operation is used to detect when that the cookie has changed
-** and that the current process needs to reread the schema.
-**
-** Either a transaction needs to have been started or an OP_Open needs
-** to be executed (to establish a read lock) before this opcode is
-** invoked.
-*/
-case OP_VerifyCookie: {
-#if 0 /* local variables moved into u.av */
- int iMeta;
- Btree *pBt;
-#endif /* local variables moved into u.av */
- assert( pOp->p1>=0 && pOp->p1<db->nDb );
- assert( (p->btreeMask & (1<<pOp->p1))!=0 );
- u.av.pBt = db->aDb[pOp->p1].pBt;
- if( u.av.pBt ){
- sqlite3BtreeGetMeta(u.av.pBt, BTREE_SCHEMA_VERSION, (u32 *)&u.av.iMeta);
- }else{
- u.av.iMeta = 0;
- }
- if( u.av.iMeta!=pOp->p2 ){
- sqlite3DbFree(db, p->zErrMsg);
- p->zErrMsg = sqlite3DbStrDup(db, "database schema has changed");
- /* If the schema-cookie from the database file matches the cookie
- ** stored with the in-memory representation of the schema, do
- ** not reload the schema from the database file.
- **
- ** If virtual-tables are in use, this is not just an optimization.
- ** Often, v-tables store their data in other SQLite tables, which
- ** are queried from within xNext() and other v-table methods using
- ** prepared queries. If such a query is out-of-date, we do not want to
- ** discard the database schema, as the user code implementing the
- ** v-table would have to be ready for the sqlite3_vtab structure itself
- ** to be invalidated whenever sqlite3_step() is called from within
- ** a v-table method.
- */
- if( db->aDb[pOp->p1].pSchema->schema_cookie!=u.av.iMeta ){
- sqlite3ResetInternalSchema(db, pOp->p1);
- }
-
- sqlite3ExpirePreparedStatements(db);
- rc = SQLITE_SCHEMA;
- }
- break;
-}
-
-/* Opcode: OpenRead P1 P2 P3 P4 P5
-**
-** Open a read-only cursor for the database table whose root page is
-** P2 in a database file. The database file is determined by P3.
-** P3==0 means the main database, P3==1 means the database used for
-** temporary tables, and P3>1 means used the corresponding attached
-** database. Give the new cursor an identifier of P1. The P1
-** values need not be contiguous but all P1 values should be small integers.
-** It is an error for P1 to be negative.
-**
-** If P5!=0 then use the content of register P2 as the root page, not
-** the value of P2 itself.
-**
-** There will be a read lock on the database whenever there is an
-** open cursor. If the database was unlocked prior to this instruction
-** then a read lock is acquired as part of this instruction. A read
-** lock allows other processes to read the database but prohibits
-** any other process from modifying the database. The read lock is
-** released when all cursors are closed. If this instruction attempts
-** to get a read lock but fails, the script terminates with an
-** SQLITE_BUSY error code.
-**
-** The P4 value may be either an integer (P4_INT32) or a pointer to
-** a KeyInfo structure (P4_KEYINFO). If it is a pointer to a KeyInfo
-** structure, then said structure defines the content and collating
-** sequence of the index being opened. Otherwise, if P4 is an integer
-** value, it is set to the number of columns in the table.
-**
-** See also OpenWrite.
-*/
-/* Opcode: OpenWrite P1 P2 P3 P4 P5
-**
-** Open a read/write cursor named P1 on the table or index whose root
-** page is P2. Or if P5!=0 use the content of register P2 to find the
-** root page.
-**
-** The P4 value may be either an integer (P4_INT32) or a pointer to
-** a KeyInfo structure (P4_KEYINFO). If it is a pointer to a KeyInfo
-** structure, then said structure defines the content and collating
-** sequence of the index being opened. Otherwise, if P4 is an integer
-** value, it is set to the number of columns in the table, or to the
-** largest index of any column of the table that is actually used.
-**
-** This instruction works just like OpenRead except that it opens the cursor
-** in read/write mode. For a given table, there can be one or more read-only
-** cursors or a single read/write cursor but not both.
-**
-** See also OpenRead.
-*/
-case OP_OpenRead:
-case OP_OpenWrite: {
-#if 0 /* local variables moved into u.aw */
- int nField;
- KeyInfo *pKeyInfo;
- int p2;
- int iDb;
- int wrFlag;
- Btree *pX;
- VdbeCursor *pCur;
- Db *pDb;
-#endif /* local variables moved into u.aw */
-
- u.aw.nField = 0;
- u.aw.pKeyInfo = 0;
- u.aw.p2 = pOp->p2;
- u.aw.iDb = pOp->p3;
- assert( u.aw.iDb>=0 && u.aw.iDb<db->nDb );
- assert( (p->btreeMask & (1<<u.aw.iDb))!=0 );
- u.aw.pDb = &db->aDb[u.aw.iDb];
- u.aw.pX = u.aw.pDb->pBt;
- assert( u.aw.pX!=0 );
- if( pOp->opcode==OP_OpenWrite ){
- u.aw.wrFlag = 1;
- if( u.aw.pDb->pSchema->file_format < p->minWriteFileFormat ){
- p->minWriteFileFormat = u.aw.pDb->pSchema->file_format;
- }
- }else{
- u.aw.wrFlag = 0;
- }
- if( pOp->p5 ){
- assert( u.aw.p2>0 );
- assert( u.aw.p2<=p->nMem );
- pIn2 = &p->aMem[u.aw.p2];
- sqlite3VdbeMemIntegerify(pIn2);
- u.aw.p2 = (int)pIn2->u.i;
- /* The u.aw.p2 value always comes from a prior OP_CreateTable opcode and
- ** that opcode will always set the u.aw.p2 value to 2 or more or else fail.
- ** If there were a failure, the prepared statement would have halted
- ** before reaching this instruction. */
- if( NEVER(u.aw.p2<2) ) {
- rc = SQLITE_CORRUPT_BKPT;
- goto abort_due_to_error;
- }
- }
- if( pOp->p4type==P4_KEYINFO ){
- u.aw.pKeyInfo = pOp->p4.pKeyInfo;
- u.aw.pKeyInfo->enc = ENC(p->db);
- u.aw.nField = u.aw.pKeyInfo->nField+1;
- }else if( pOp->p4type==P4_INT32 ){
- u.aw.nField = pOp->p4.i;
- }
- assert( pOp->p1>=0 );
- u.aw.pCur = allocateCursor(p, pOp->p1, u.aw.nField, u.aw.iDb, 1);
- if( u.aw.pCur==0 ) goto no_mem;
- u.aw.pCur->nullRow = 1;
- rc = sqlite3BtreeCursor(u.aw.pX, u.aw.p2, u.aw.wrFlag, u.aw.pKeyInfo, u.aw.pCur->pCursor);
- u.aw.pCur->pKeyInfo = u.aw.pKeyInfo;
-
- /* Since it performs no memory allocation or IO, the only values that
- ** sqlite3BtreeCursor() may return are SQLITE_EMPTY and SQLITE_OK.
- ** SQLITE_EMPTY is only returned when attempting to open the table
- ** rooted at page 1 of a zero-byte database. */
- assert( rc==SQLITE_EMPTY || rc==SQLITE_OK );
- if( rc==SQLITE_EMPTY ){
- u.aw.pCur->pCursor = 0;
- rc = SQLITE_OK;
- }
-
- /* Set the VdbeCursor.isTable and isIndex variables. Previous versions of
- ** SQLite used to check if the root-page flags were sane at this point
- ** and report database corruption if they were not, but this check has
- ** since moved into the btree layer. */
- u.aw.pCur->isTable = pOp->p4type!=P4_KEYINFO;
- u.aw.pCur->isIndex = !u.aw.pCur->isTable;
- break;
-}
-
-/* Opcode: OpenEphemeral P1 P2 * P4 *
-**
-** Open a new cursor P1 to a transient table.
-** The cursor is always opened read/write even if
-** the main database is read-only. The transient or virtual
-** table is deleted automatically when the cursor is closed.
-**
-** P2 is the number of columns in the virtual table.
-** The cursor points to a BTree table if P4==0 and to a BTree index
-** if P4 is not 0. If P4 is not NULL, it points to a KeyInfo structure
-** that defines the format of keys in the index.
-**
-** This opcode was once called OpenTemp. But that created
-** confusion because the term "temp table", might refer either
-** to a TEMP table at the SQL level, or to a table opened by
-** this opcode. Then this opcode was call OpenVirtual. But
-** that created confusion with the whole virtual-table idea.
-*/
-case OP_OpenEphemeral: {
-#if 0 /* local variables moved into u.ax */
- VdbeCursor *pCx;
-#endif /* local variables moved into u.ax */
- static const int openFlags =
- SQLITE_OPEN_READWRITE |
- SQLITE_OPEN_CREATE |
- SQLITE_OPEN_EXCLUSIVE |
- SQLITE_OPEN_DELETEONCLOSE |
- SQLITE_OPEN_TRANSIENT_DB;
-
- assert( pOp->p1>=0 );
- u.ax.pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, 1);
- if( u.ax.pCx==0 ) goto no_mem;
- u.ax.pCx->nullRow = 1;
- rc = sqlite3BtreeFactory(db, 0, 1, SQLITE_DEFAULT_TEMP_CACHE_SIZE, openFlags,
- &u.ax.pCx->pBt);
- if( rc==SQLITE_OK ){
- rc = sqlite3BtreeBeginTrans(u.ax.pCx->pBt, 1);
- }
- if( rc==SQLITE_OK ){
- /* If a transient index is required, create it by calling
- ** sqlite3BtreeCreateTable() with the BTREE_ZERODATA flag before
- ** opening it. If a transient table is required, just use the
- ** automatically created table with root-page 1 (an INTKEY table).
- */
- if( pOp->p4.pKeyInfo ){
- int pgno;
- assert( pOp->p4type==P4_KEYINFO );
- rc = sqlite3BtreeCreateTable(u.ax.pCx->pBt, &pgno, BTREE_ZERODATA);
- if( rc==SQLITE_OK ){
- assert( pgno==MASTER_ROOT+1 );
- rc = sqlite3BtreeCursor(u.ax.pCx->pBt, pgno, 1,
- (KeyInfo*)pOp->p4.z, u.ax.pCx->pCursor);
- u.ax.pCx->pKeyInfo = pOp->p4.pKeyInfo;
- u.ax.pCx->pKeyInfo->enc = ENC(p->db);
- }
- u.ax.pCx->isTable = 0;
- }else{
- rc = sqlite3BtreeCursor(u.ax.pCx->pBt, MASTER_ROOT, 1, 0, u.ax.pCx->pCursor);
- u.ax.pCx->isTable = 1;
- }
- }
- u.ax.pCx->isIndex = !u.ax.pCx->isTable;
- break;
-}
-
-/* Opcode: OpenPseudo P1 P2 P3 * *
-**
-** Open a new cursor that points to a fake table that contains a single
-** row of data. The content of that one row in the content of memory
-** register P2. In other words, cursor P1 becomes an alias for the
-** MEM_Blob content contained in register P2.
-**
-** A pseudo-table created by this opcode is used to hold the a single
-** row output from the sorter so that the row can be decomposed into
-** individual columns using the OP_Column opcode. The OP_Column opcode
-** is the only cursor opcode that works with a pseudo-table.
-**
-** P3 is the number of fields in the records that will be stored by
-** the pseudo-table.
-*/
-case OP_OpenPseudo: {
-#if 0 /* local variables moved into u.ay */
- VdbeCursor *pCx;
-#endif /* local variables moved into u.ay */
-
- assert( pOp->p1>=0 );
- u.ay.pCx = allocateCursor(p, pOp->p1, pOp->p3, -1, 0);
- if( u.ay.pCx==0 ) goto no_mem;
- u.ay.pCx->nullRow = 1;
- u.ay.pCx->pseudoTableReg = pOp->p2;
- u.ay.pCx->isTable = 1;
- u.ay.pCx->isIndex = 0;
- break;
-}
-
-/* Opcode: Close P1 * * * *
-**
-** Close a cursor previously opened as P1. If P1 is not
-** currently open, this instruction is a no-op.
-*/
-case OP_Close: {
- assert( pOp->p1>=0 && pOp->p1<p->nCursor );
- sqlite3VdbeFreeCursor(p, p->apCsr[pOp->p1]);
- p->apCsr[pOp->p1] = 0;
- break;
-}
-
-/* Opcode: SeekGe P1 P2 P3 P4 *
-**
-** If cursor P1 refers to an SQL table (B-Tree that uses integer keys),
-** use the value in register P3 as the key. If cursor P1 refers
-** to an SQL index, then P3 is the first in an array of P4 registers
-** that are used as an unpacked index key.
-**
-** Reposition cursor P1 so that it points to the smallest entry that
-** is greater than or equal to the key value. If there are no records
-** greater than or equal to the key and P2 is not zero, then jump to P2.
-**
-** See also: Found, NotFound, Distinct, SeekLt, SeekGt, SeekLe
-*/
-/* Opcode: SeekGt P1 P2 P3 P4 *
-**
-** If cursor P1 refers to an SQL table (B-Tree that uses integer keys),
-** use the value in register P3 as a key. If cursor P1 refers
-** to an SQL index, then P3 is the first in an array of P4 registers
-** that are used as an unpacked index key.
-**
-** Reposition cursor P1 so that it points to the smallest entry that
-** is greater than the key value. If there are no records greater than
-** the key and P2 is not zero, then jump to P2.
-**
-** See also: Found, NotFound, Distinct, SeekLt, SeekGe, SeekLe
-*/
-/* Opcode: SeekLt P1 P2 P3 P4 *
-**
-** If cursor P1 refers to an SQL table (B-Tree that uses integer keys),
-** use the value in register P3 as a key. If cursor P1 refers
-** to an SQL index, then P3 is the first in an array of P4 registers
-** that are used as an unpacked index key.
-**
-** Reposition cursor P1 so that it points to the largest entry that
-** is less than the key value. If there are no records less than
-** the key and P2 is not zero, then jump to P2.
-**
-** See also: Found, NotFound, Distinct, SeekGt, SeekGe, SeekLe
-*/
-/* Opcode: SeekLe P1 P2 P3 P4 *
-**
-** If cursor P1 refers to an SQL table (B-Tree that uses integer keys),
-** use the value in register P3 as a key. If cursor P1 refers
-** to an SQL index, then P3 is the first in an array of P4 registers
-** that are used as an unpacked index key.
-**
-** Reposition cursor P1 so that it points to the largest entry that
-** is less than or equal to the key value. If there are no records
-** less than or equal to the key and P2 is not zero, then jump to P2.
-**
-** See also: Found, NotFound, Distinct, SeekGt, SeekGe, SeekLt
-*/
-case OP_SeekLt: /* jump, in3 */
-case OP_SeekLe: /* jump, in3 */
-case OP_SeekGe: /* jump, in3 */
-case OP_SeekGt: { /* jump, in3 */
-#if 0 /* local variables moved into u.az */
- int res;
- int oc;
- VdbeCursor *pC;
- UnpackedRecord r;
- int nField;
- i64 iKey; /* The rowid we are to seek to */
-#endif /* local variables moved into u.az */
-
- assert( pOp->p1>=0 && pOp->p1<p->nCursor );
- assert( pOp->p2!=0 );
- u.az.pC = p->apCsr[pOp->p1];
- assert( u.az.pC!=0 );
- assert( u.az.pC->pseudoTableReg==0 );
- if( u.az.pC->pCursor!=0 ){
- u.az.oc = pOp->opcode;
- u.az.pC->nullRow = 0;
- if( u.az.pC->isTable ){
- /* The input value in P3 might be of any type: integer, real, string,
- ** blob, or NULL. But it needs to be an integer before we can do
- ** the seek, so covert it. */
- applyNumericAffinity(pIn3);
- u.az.iKey = sqlite3VdbeIntValue(pIn3);
- u.az.pC->rowidIsValid = 0;
-
- /* If the P3 value could not be converted into an integer without
- ** loss of information, then special processing is required... */
- if( (pIn3->flags & MEM_Int)==0 ){
- if( (pIn3->flags & MEM_Real)==0 ){
- /* If the P3 value cannot be converted into any kind of a number,
- ** then the seek is not possible, so jump to P2 */
- pc = pOp->p2 - 1;
- break;
- }
- /* If we reach this point, then the P3 value must be a floating
- ** point number. */
- assert( (pIn3->flags & MEM_Real)!=0 );
-
- if( u.az.iKey==SMALLEST_INT64 && (pIn3->r<(double)u.az.iKey || pIn3->r>0) ){
- /* The P3 value is too large in magnitude to be expressed as an
- ** integer. */
- u.az.res = 1;
- if( pIn3->r<0 ){
- if( u.az.oc==OP_SeekGt || u.az.oc==OP_SeekGe ){
- rc = sqlite3BtreeFirst(u.az.pC->pCursor, &u.az.res);
- if( rc!=SQLITE_OK ) goto abort_due_to_error;
- }
- }else{
- if( u.az.oc==OP_SeekLt || u.az.oc==OP_SeekLe ){
- rc = sqlite3BtreeLast(u.az.pC->pCursor, &u.az.res);
- if( rc!=SQLITE_OK ) goto abort_due_to_error;
- }
- }
- if( u.az.res ){
- pc = pOp->p2 - 1;
- }
- break;
- }else if( u.az.oc==OP_SeekLt || u.az.oc==OP_SeekGe ){
- /* Use the ceiling() function to convert real->int */
- if( pIn3->r > (double)u.az.iKey ) u.az.iKey++;
- }else{
- /* Use the floor() function to convert real->int */
- assert( u.az.oc==OP_SeekLe || u.az.oc==OP_SeekGt );
- if( pIn3->r < (double)u.az.iKey ) u.az.iKey--;
- }
- }
- rc = sqlite3BtreeMovetoUnpacked(u.az.pC->pCursor, 0, (u64)u.az.iKey, 0, &u.az.res);
- if( rc!=SQLITE_OK ){
- goto abort_due_to_error;
- }
- if( u.az.res==0 ){
- u.az.pC->rowidIsValid = 1;
- u.az.pC->lastRowid = u.az.iKey;
- }
- }else{
- u.az.nField = pOp->p4.i;
- assert( pOp->p4type==P4_INT32 );
- assert( u.az.nField>0 );
- u.az.r.pKeyInfo = u.az.pC->pKeyInfo;
- u.az.r.nField = (u16)u.az.nField;
- if( u.az.oc==OP_SeekGt || u.az.oc==OP_SeekLe ){
- u.az.r.flags = UNPACKED_INCRKEY;
- }else{
- u.az.r.flags = 0;
- }
- u.az.r.aMem = &p->aMem[pOp->p3];
- rc = sqlite3BtreeMovetoUnpacked(u.az.pC->pCursor, &u.az.r, 0, 0, &u.az.res);
- if( rc!=SQLITE_OK ){
- goto abort_due_to_error;
- }
- u.az.pC->rowidIsValid = 0;
- }
- u.az.pC->deferredMoveto = 0;
- u.az.pC->cacheStatus = CACHE_STALE;
-#ifdef SQLITE_TEST
- sqlite3_search_count++;
-#endif
- if( u.az.oc==OP_SeekGe || u.az.oc==OP_SeekGt ){
- if( u.az.res<0 || (u.az.res==0 && u.az.oc==OP_SeekGt) ){
- rc = sqlite3BtreeNext(u.az.pC->pCursor, &u.az.res);
- if( rc!=SQLITE_OK ) goto abort_due_to_error;
- u.az.pC->rowidIsValid = 0;
- }else{
- u.az.res = 0;
- }
- }else{
- assert( u.az.oc==OP_SeekLt || u.az.oc==OP_SeekLe );
- if( u.az.res>0 || (u.az.res==0 && u.az.oc==OP_SeekLt) ){
- rc = sqlite3BtreePrevious(u.az.pC->pCursor, &u.az.res);
- if( rc!=SQLITE_OK ) goto abort_due_to_error;
- u.az.pC->rowidIsValid = 0;
- }else{
- /* u.az.res might be negative because the table is empty. Check to
- ** see if this is the case.
- */
- u.az.res = sqlite3BtreeEof(u.az.pC->pCursor);
- }
- }
- assert( pOp->p2>0 );
- if( u.az.res ){
- pc = pOp->p2 - 1;
- }
- }else{
- /* This happens when attempting to open the sqlite3_master table
- ** for read access returns SQLITE_EMPTY. In this case always
- ** take the jump (since there are no records in the table).
- */
- pc = pOp->p2 - 1;
- }
- break;
-}
-
-/* Opcode: Seek P1 P2 * * *
-**
-** P1 is an open table cursor and P2 is a rowid integer. Arrange
-** for P1 to move so that it points to the rowid given by P2.
-**
-** This is actually a deferred seek. Nothing actually happens until
-** the cursor is used to read a record. That way, if no reads
-** occur, no unnecessary I/O happens.
-*/
-case OP_Seek: { /* in2 */
-#if 0 /* local variables moved into u.ba */
- VdbeCursor *pC;
-#endif /* local variables moved into u.ba */
-
- assert( pOp->p1>=0 && pOp->p1<p->nCursor );
- u.ba.pC = p->apCsr[pOp->p1];
- assert( u.ba.pC!=0 );
- if( ALWAYS(u.ba.pC->pCursor!=0) ){
- assert( u.ba.pC->isTable );
- u.ba.pC->nullRow = 0;
- u.ba.pC->movetoTarget = sqlite3VdbeIntValue(pIn2);
- u.ba.pC->rowidIsValid = 0;
- u.ba.pC->deferredMoveto = 1;
- }
- break;
-}
-
-
-/* Opcode: Found P1 P2 P3 * *
-**
-** Register P3 holds a blob constructed by MakeRecord. P1 is an index.
-** If an entry that matches the value in register p3 exists in P1 then
-** jump to P2. If the P3 value does not match any entry in P1
-** then fall thru. The P1 cursor is left pointing at the matching entry
-** if it exists.
-**
-** This instruction is used to implement the IN operator where the
-** left-hand side is a SELECT statement. P1 may be a true index, or it
-** may be a temporary index that holds the results of the SELECT
-** statement. This instruction is also used to implement the
-** DISTINCT keyword in SELECT statements.
-**
-** This instruction checks if index P1 contains a record for which
-** the first N serialized values exactly match the N serialized values
-** in the record in register P3, where N is the total number of values in
-** the P3 record (the P3 record is a prefix of the P1 record).
-**
-** See also: NotFound, IsUnique, NotExists
-*/
-/* Opcode: NotFound P1 P2 P3 * *
-**
-** Register P3 holds a blob constructed by MakeRecord. P1 is
-** an index. If no entry exists in P1 that matches the blob then jump
-** to P2. If an entry does existing, fall through. The cursor is left
-** pointing to the entry that matches.
-**
-** See also: Found, NotExists, IsUnique
-*/
-case OP_NotFound: /* jump, in3 */
-case OP_Found: { /* jump, in3 */
-#if 0 /* local variables moved into u.bb */
- int alreadyExists;
- VdbeCursor *pC;
- int res;
- UnpackedRecord *pIdxKey;
- char aTempRec[ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*3 + 7];
-#endif /* local variables moved into u.bb */
-
- u.bb.alreadyExists = 0;
- assert( pOp->p1>=0 && pOp->p1<p->nCursor );
- u.bb.pC = p->apCsr[pOp->p1];
- assert( u.bb.pC!=0 );
- if( ALWAYS(u.bb.pC->pCursor!=0) ){
-
- assert( u.bb.pC->isTable==0 );
- assert( pIn3->flags & MEM_Blob );
- ExpandBlob(pIn3);
- u.bb.pIdxKey = sqlite3VdbeRecordUnpack(u.bb.pC->pKeyInfo, pIn3->n, pIn3->z,
- u.bb.aTempRec, sizeof(u.bb.aTempRec));
- if( u.bb.pIdxKey==0 ){
- goto no_mem;
- }
- if( pOp->opcode==OP_Found ){
- u.bb.pIdxKey->flags |= UNPACKED_PREFIX_MATCH;
- }
- rc = sqlite3BtreeMovetoUnpacked(u.bb.pC->pCursor, u.bb.pIdxKey, 0, 0, &u.bb.res);
- sqlite3VdbeDeleteUnpackedRecord(u.bb.pIdxKey);
- if( rc!=SQLITE_OK ){
- break;
- }
- u.bb.alreadyExists = (u.bb.res==0);
- u.bb.pC->deferredMoveto = 0;
- u.bb.pC->cacheStatus = CACHE_STALE;
- }
- if( pOp->opcode==OP_Found ){
- if( u.bb.alreadyExists ) pc = pOp->p2 - 1;
- }else{
- if( !u.bb.alreadyExists ) pc = pOp->p2 - 1;
- }
- break;
-}
-
-/* Opcode: IsUnique P1 P2 P3 P4 *
-**
-** Cursor P1 is open on an index. So it has no data and its key consists
-** of a record generated by OP_MakeRecord where the last field is the
-** rowid of the entry that the index refers to.
-**
-** The P3 register contains an integer record number. Call this record
-** number R. Register P4 is the first in a set of N contiguous registers
-** that make up an unpacked index key that can be used with cursor P1.
-** The value of N can be inferred from the cursor. N includes the rowid
-** value appended to the end of the index record. This rowid value may
-** or may not be the same as R.
-**
-** If any of the N registers beginning with register P4 contains a NULL
-** value, jump immediately to P2.
-**
-** Otherwise, this instruction checks if cursor P1 contains an entry
-** where the first (N-1) fields match but the rowid value at the end
-** of the index entry is not R. If there is no such entry, control jumps
-** to instruction P2. Otherwise, the rowid of the conflicting index
-** entry is copied to register P3 and control falls through to the next
-** instruction.
-**
-** See also: NotFound, NotExists, Found
-*/
-case OP_IsUnique: { /* jump, in3 */
-#if 0 /* local variables moved into u.bc */
- u16 ii;
- VdbeCursor *pCx;
- BtCursor *pCrsr;
- u16 nField;
- Mem *aMem;
- UnpackedRecord r; /* B-Tree index search key */
- i64 R; /* Rowid stored in register P3 */
-#endif /* local variables moved into u.bc */
-
- u.bc.aMem = &p->aMem[pOp->p4.i];
- /* Assert that the values of parameters P1 and P4 are in range. */
- assert( pOp->p4type==P4_INT32 );
- assert( pOp->p4.i>0 && pOp->p4.i<=p->nMem );
- assert( pOp->p1>=0 && pOp->p1<p->nCursor );
-
- /* Find the index cursor. */
- u.bc.pCx = p->apCsr[pOp->p1];
- assert( u.bc.pCx->deferredMoveto==0 );
- u.bc.pCx->seekResult = 0;
- u.bc.pCx->cacheStatus = CACHE_STALE;
- u.bc.pCrsr = u.bc.pCx->pCursor;
-
- /* If any of the values are NULL, take the jump. */
- u.bc.nField = u.bc.pCx->pKeyInfo->nField;
- for(u.bc.ii=0; u.bc.ii<u.bc.nField; u.bc.ii++){
- if( u.bc.aMem[u.bc.ii].flags & MEM_Null ){
- pc = pOp->p2 - 1;
- u.bc.pCrsr = 0;
- break;
- }
- }
- assert( (u.bc.aMem[u.bc.nField].flags & MEM_Null)==0 );
-
- if( u.bc.pCrsr!=0 ){
- /* Populate the index search key. */
- u.bc.r.pKeyInfo = u.bc.pCx->pKeyInfo;
- u.bc.r.nField = u.bc.nField + 1;
- u.bc.r.flags = UNPACKED_PREFIX_SEARCH;
- u.bc.r.aMem = u.bc.aMem;
-
- /* Extract the value of u.bc.R from register P3. */
- sqlite3VdbeMemIntegerify(pIn3);
- u.bc.R = pIn3->u.i;
-
- /* Search the B-Tree index. If no conflicting record is found, jump
- ** to P2. Otherwise, copy the rowid of the conflicting record to
- ** register P3 and fall through to the next instruction. */
- rc = sqlite3BtreeMovetoUnpacked(u.bc.pCrsr, &u.bc.r, 0, 0, &u.bc.pCx->seekResult);
- if( (u.bc.r.flags & UNPACKED_PREFIX_SEARCH) || u.bc.r.rowid==u.bc.R ){
- pc = pOp->p2 - 1;
- }else{
- pIn3->u.i = u.bc.r.rowid;
- }
- }
- break;
-}
-
-/* Opcode: NotExists P1 P2 P3 * *
-**
-** Use the content of register P3 as a integer key. If a record
-** with that key does not exist in table of P1, then jump to P2.
-** If the record does exist, then fall thru. The cursor is left
-** pointing to the record if it exists.
-**
-** The difference between this operation and NotFound is that this
-** operation assumes the key is an integer and that P1 is a table whereas
-** NotFound assumes key is a blob constructed from MakeRecord and
-** P1 is an index.
-**
-** See also: Found, NotFound, IsUnique
-*/
-case OP_NotExists: { /* jump, in3 */
-#if 0 /* local variables moved into u.bd */
- VdbeCursor *pC;
- BtCursor *pCrsr;
- int res;
- u64 iKey;
-#endif /* local variables moved into u.bd */
-
- assert( pIn3->flags & MEM_Int );
- assert( pOp->p1>=0 && pOp->p1<p->nCursor );
- u.bd.pC = p->apCsr[pOp->p1];
- assert( u.bd.pC!=0 );
- assert( u.bd.pC->isTable );
- assert( u.bd.pC->pseudoTableReg==0 );
- u.bd.pCrsr = u.bd.pC->pCursor;
- if( u.bd.pCrsr!=0 ){
- u.bd.res = 0;
- u.bd.iKey = pIn3->u.i;
- rc = sqlite3BtreeMovetoUnpacked(u.bd.pCrsr, 0, u.bd.iKey, 0, &u.bd.res);
- u.bd.pC->lastRowid = pIn3->u.i;
- u.bd.pC->rowidIsValid = u.bd.res==0 ?1:0;
- u.bd.pC->nullRow = 0;
- u.bd.pC->cacheStatus = CACHE_STALE;
- u.bd.pC->deferredMoveto = 0;
- if( u.bd.res!=0 ){
- pc = pOp->p2 - 1;
- assert( u.bd.pC->rowidIsValid==0 );
- }
- u.bd.pC->seekResult = u.bd.res;
- }else{
- /* This happens when an attempt to open a read cursor on the
- ** sqlite_master table returns SQLITE_EMPTY.
- */
- pc = pOp->p2 - 1;
- assert( u.bd.pC->rowidIsValid==0 );
- u.bd.pC->seekResult = 0;
- }
- break;
-}
-
-/* Opcode: Sequence P1 P2 * * *
-**
-** Find the next available sequence number for cursor P1.
-** Write the sequence number into register P2.
-** The sequence number on the cursor is incremented after this
-** instruction.
-*/
-case OP_Sequence: { /* out2-prerelease */
- assert( pOp->p1>=0 && pOp->p1<p->nCursor );
- assert( p->apCsr[pOp->p1]!=0 );
- pOut->u.i = p->apCsr[pOp->p1]->seqCount++;
- MemSetTypeFlag(pOut, MEM_Int);
- break;
-}
-
-
-/* Opcode: NewRowid P1 P2 P3 * *
-**
-** Get a new integer record number (a.k.a "rowid") used as the key to a table.
-** The record number is not previously used as a key in the database
-** table that cursor P1 points to. The new record number is written
-** written to register P2.
-**
-** If P3>0 then P3 is a register in the root frame of this VDBE that holds
-** the largest previously generated record number. No new record numbers are
-** allowed to be less than this value. When this value reaches its maximum,
-** a SQLITE_FULL error is generated. The P3 register is updated with the '
-** generated record number. This P3 mechanism is used to help implement the
-** AUTOINCREMENT feature.
-*/
-case OP_NewRowid: { /* out2-prerelease */
-#if 0 /* local variables moved into u.be */
- i64 v; /* The new rowid */
- VdbeCursor *pC; /* Cursor of table to get the new rowid */
- int res; /* Result of an sqlite3BtreeLast() */
- int cnt; /* Counter to limit the number of searches */
- Mem *pMem; /* Register holding largest rowid for AUTOINCREMENT */
- VdbeFrame *pFrame; /* Root frame of VDBE */
-#endif /* local variables moved into u.be */
-
- u.be.v = 0;
- u.be.res = 0;
- assert( pOp->p1>=0 && pOp->p1<p->nCursor );
- u.be.pC = p->apCsr[pOp->p1];
- assert( u.be.pC!=0 );
- if( NEVER(u.be.pC->pCursor==0) ){
- /* The zero initialization above is all that is needed */
- }else{
- /* The next rowid or record number (different terms for the same
- ** thing) is obtained in a two-step algorithm.
- **
- ** First we attempt to find the largest existing rowid and add one
- ** to that. But if the largest existing rowid is already the maximum
- ** positive integer, we have to fall through to the second
- ** probabilistic algorithm
- **
- ** The second algorithm is to select a rowid at random and see if
- ** it already exists in the table. If it does not exist, we have
- ** succeeded. If the random rowid does exist, we select a new one
- ** and try again, up to 100 times.
- */
- assert( u.be.pC->isTable );
- u.be.cnt = 0;
-
-#ifdef SQLITE_32BIT_ROWID
-# define MAX_ROWID 0x7fffffff
-#else
- /* Some compilers complain about constants of the form 0x7fffffffffffffff.
- ** Others complain about 0x7ffffffffffffffffLL. The following macro seems
- ** to provide the constant while making all compilers happy.
- */
-# define MAX_ROWID (i64)( (((u64)0x7fffffff)<<32) | (u64)0xffffffff )
-#endif
-
- if( !u.be.pC->useRandomRowid ){
- u.be.v = sqlite3BtreeGetCachedRowid(u.be.pC->pCursor);
- if( u.be.v==0 ){
- rc = sqlite3BtreeLast(u.be.pC->pCursor, &u.be.res);
- if( rc!=SQLITE_OK ){
- goto abort_due_to_error;
- }
- if( u.be.res ){
- u.be.v = 1;
- }else{
- assert( sqlite3BtreeCursorIsValid(u.be.pC->pCursor) );
- rc = sqlite3BtreeKeySize(u.be.pC->pCursor, &u.be.v);
- assert( rc==SQLITE_OK ); /* Cannot fail following BtreeLast() */
- if( u.be.v==MAX_ROWID ){
- u.be.pC->useRandomRowid = 1;
- }else{
- u.be.v++;
- }
- }
- }
-
-#ifndef SQLITE_OMIT_AUTOINCREMENT
- if( pOp->p3 ){
- /* Assert that P3 is a valid memory cell. */
- assert( pOp->p3>0 );
- if( p->pFrame ){
- for(u.be.pFrame=p->pFrame; u.be.pFrame->pParent; u.be.pFrame=u.be.pFrame->pParent);
- /* Assert that P3 is a valid memory cell. */
- assert( pOp->p3<=u.be.pFrame->nMem );
- u.be.pMem = &u.be.pFrame->aMem[pOp->p3];
- }else{
- /* Assert that P3 is a valid memory cell. */
- assert( pOp->p3<=p->nMem );
- u.be.pMem = &p->aMem[pOp->p3];
- }
-
- REGISTER_TRACE(pOp->p3, u.be.pMem);
- sqlite3VdbeMemIntegerify(u.be.pMem);
- assert( (u.be.pMem->flags & MEM_Int)!=0 ); /* mem(P3) holds an integer */
- if( u.be.pMem->u.i==MAX_ROWID || u.be.pC->useRandomRowid ){
- rc = SQLITE_FULL;
- goto abort_due_to_error;
- }
- if( u.be.v<u.be.pMem->u.i+1 ){
- u.be.v = u.be.pMem->u.i + 1;
- }
- u.be.pMem->u.i = u.be.v;
- }
-#endif
-
- sqlite3BtreeSetCachedRowid(u.be.pC->pCursor, u.be.v<MAX_ROWID ? u.be.v+1 : 0);
- }
- if( u.be.pC->useRandomRowid ){
- assert( pOp->p3==0 ); /* We cannot be in random rowid mode if this is
- ** an AUTOINCREMENT table. */
- u.be.v = db->lastRowid;
- u.be.cnt = 0;
- do{
- if( u.be.cnt==0 && (u.be.v&0xffffff)==u.be.v ){
- u.be.v++;
- }else{
- sqlite3_randomness(sizeof(u.be.v), &u.be.v);
- if( u.be.cnt<5 ) u.be.v &= 0xffffff;
- }
- rc = sqlite3BtreeMovetoUnpacked(u.be.pC->pCursor, 0, (u64)u.be.v, 0, &u.be.res);
- u.be.cnt++;
- }while( u.be.cnt<100 && rc==SQLITE_OK && u.be.res==0 );
- if( rc==SQLITE_OK && u.be.res==0 ){
- rc = SQLITE_FULL;
- goto abort_due_to_error;
- }
- }
- u.be.pC->rowidIsValid = 0;
- u.be.pC->deferredMoveto = 0;
- u.be.pC->cacheStatus = CACHE_STALE;
- }
- MemSetTypeFlag(pOut, MEM_Int);
- pOut->u.i = u.be.v;
- break;
-}
-
-/* Opcode: Insert P1 P2 P3 P4 P5
-**
-** Write an entry into the table of cursor P1. A new entry is
-** created if it doesn't already exist or the data for an existing
-** entry is overwritten. The data is the value MEM_Blob stored in register
-** number P2. The key is stored in register P3. The key must
-** be a MEM_Int.
-**
-** If the OPFLAG_NCHANGE flag of P5 is set, then the row change count is
-** incremented (otherwise not). If the OPFLAG_LASTROWID flag of P5 is set,
-** then rowid is stored for subsequent return by the
-** sqlite3_last_insert_rowid() function (otherwise it is unmodified).
-**
-** If the OPFLAG_USESEEKRESULT flag of P5 is set and if the result of
-** the last seek operation (OP_NotExists) was a success, then this
-** operation will not attempt to find the appropriate row before doing
-** the insert but will instead overwrite the row that the cursor is
-** currently pointing to. Presumably, the prior OP_NotExists opcode
-** has already positioned the cursor correctly. This is an optimization
-** that boosts performance by avoiding redundant seeks.
-**
-** If the OPFLAG_ISUPDATE flag is set, then this opcode is part of an
-** UPDATE operation. Otherwise (if the flag is clear) then this opcode
-** is part of an INSERT operation. The difference is only important to
-** the update hook.
-**
-** Parameter P4 may point to a string containing the table-name, or
-** may be NULL. If it is not NULL, then the update-hook
-** (sqlite3.xUpdateCallback) is invoked following a successful insert.
-**
-** (WARNING/TODO: If P1 is a pseudo-cursor and P2 is dynamically
-** allocated, then ownership of P2 is transferred to the pseudo-cursor
-** and register P2 becomes ephemeral. If the cursor is changed, the
-** value of register P2 will then change. Make sure this does not
-** cause any problems.)
-**
-** This instruction only works on tables. The equivalent instruction
-** for indices is OP_IdxInsert.
-*/
-case OP_Insert: {
-#if 0 /* local variables moved into u.bf */
- Mem *pData; /* MEM cell holding data for the record to be inserted */
- Mem *pKey; /* MEM cell holding key for the record */
- i64 iKey; /* The integer ROWID or key for the record to be inserted */
- VdbeCursor *pC; /* Cursor to table into which insert is written */
- int nZero; /* Number of zero-bytes to append */
- int seekResult; /* Result of prior seek or 0 if no USESEEKRESULT flag */
- const char *zDb; /* database name - used by the update hook */
- const char *zTbl; /* Table name - used by the opdate hook */
- int op; /* Opcode for update hook: SQLITE_UPDATE or SQLITE_INSERT */
-#endif /* local variables moved into u.bf */
-
- u.bf.pData = &p->aMem[pOp->p2];
- u.bf.pKey = &p->aMem[pOp->p3];
- assert( pOp->p1>=0 && pOp->p1<p->nCursor );
- u.bf.pC = p->apCsr[pOp->p1];
- assert( u.bf.pC!=0 );
- assert( u.bf.pC->pCursor!=0 );
- assert( u.bf.pC->pseudoTableReg==0 );
- assert( u.bf.pKey->flags & MEM_Int );
- assert( u.bf.pC->isTable );
- REGISTER_TRACE(pOp->p2, u.bf.pData);
- REGISTER_TRACE(pOp->p3, u.bf.pKey);
-
- u.bf.iKey = u.bf.pKey->u.i;
- if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++;
- if( pOp->p5 & OPFLAG_LASTROWID ) db->lastRowid = u.bf.pKey->u.i;
- if( u.bf.pData->flags & MEM_Null ){
- u.bf.pData->z = 0;
- u.bf.pData->n = 0;
- }else{
- assert( u.bf.pData->flags & (MEM_Blob|MEM_Str) );
- }
- u.bf.seekResult = ((pOp->p5 & OPFLAG_USESEEKRESULT) ? u.bf.pC->seekResult : 0);
- if( u.bf.pData->flags & MEM_Zero ){
- u.bf.nZero = u.bf.pData->u.nZero;
- }else{
- u.bf.nZero = 0;
- }
- sqlite3BtreeSetCachedRowid(u.bf.pC->pCursor, 0);
- rc = sqlite3BtreeInsert(u.bf.pC->pCursor, 0, u.bf.iKey,
- u.bf.pData->z, u.bf.pData->n, u.bf.nZero,
- pOp->p5 & OPFLAG_APPEND, u.bf.seekResult
- );
- u.bf.pC->rowidIsValid = 0;
- u.bf.pC->deferredMoveto = 0;
- u.bf.pC->cacheStatus = CACHE_STALE;
-
- /* Invoke the update-hook if required. */
- if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z ){
- u.bf.zDb = db->aDb[u.bf.pC->iDb].zName;
- u.bf.zTbl = pOp->p4.z;
- u.bf.op = ((pOp->p5 & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_INSERT);
- assert( u.bf.pC->isTable );
- db->xUpdateCallback(db->pUpdateArg, u.bf.op, u.bf.zDb, u.bf.zTbl, u.bf.iKey);
- assert( u.bf.pC->iDb>=0 );
- }
- break;
-}
-
-/* Opcode: Delete P1 P2 * P4 *
-**
-** Delete the record at which the P1 cursor is currently pointing.
-**
-** The cursor will be left pointing at either the next or the previous
-** record in the table. If it is left pointing at the next record, then
-** the next Next instruction will be a no-op. Hence it is OK to delete
-** a record from within an Next loop.
-**
-** If the OPFLAG_NCHANGE flag of P2 is set, then the row change count is
-** incremented (otherwise not).
-**
-** P1 must not be pseudo-table. It has to be a real table with
-** multiple rows.
-**
-** If P4 is not NULL, then it is the name of the table that P1 is
-** pointing to. The update hook will be invoked, if it exists.
-** If P4 is not NULL then the P1 cursor must have been positioned
-** using OP_NotFound prior to invoking this opcode.
-*/
-case OP_Delete: {
-#if 0 /* local variables moved into u.bg */
- i64 iKey;
- VdbeCursor *pC;
-#endif /* local variables moved into u.bg */
-
- u.bg.iKey = 0;
- assert( pOp->p1>=0 && pOp->p1<p->nCursor );
- u.bg.pC = p->apCsr[pOp->p1];
- assert( u.bg.pC!=0 );
- assert( u.bg.pC->pCursor!=0 ); /* Only valid for real tables, no pseudotables */
-
- /* If the update-hook will be invoked, set u.bg.iKey to the rowid of the
- ** row being deleted.
- */
- if( db->xUpdateCallback && pOp->p4.z ){
- assert( u.bg.pC->isTable );
- assert( u.bg.pC->rowidIsValid ); /* lastRowid set by previous OP_NotFound */
- u.bg.iKey = u.bg.pC->lastRowid;
- }
-
- /* The OP_Delete opcode always follows an OP_NotExists or OP_Last or
- ** OP_Column on the same table without any intervening operations that
- ** might move or invalidate the cursor. Hence cursor u.bg.pC is always pointing
- ** to the row to be deleted and the sqlite3VdbeCursorMoveto() operation
- ** below is always a no-op and cannot fail. We will run it anyhow, though,
- ** to guard against future changes to the code generator.
- **/
- assert( u.bg.pC->deferredMoveto==0 );
- rc = sqlite3VdbeCursorMoveto(u.bg.pC);
- if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error;
-
- sqlite3BtreeSetCachedRowid(u.bg.pC->pCursor, 0);
- rc = sqlite3BtreeDelete(u.bg.pC->pCursor);
- u.bg.pC->cacheStatus = CACHE_STALE;
-
- /* Invoke the update-hook if required. */
- if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z ){
- const char *zDb = db->aDb[u.bg.pC->iDb].zName;
- const char *zTbl = pOp->p4.z;
- db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE, zDb, zTbl, u.bg.iKey);
- assert( u.bg.pC->iDb>=0 );
- }
- if( pOp->p2 & OPFLAG_NCHANGE ) p->nChange++;
- break;
-}
-/* Opcode: ResetCount * * * * *
-**
-** The value of the change counter is copied to the database handle
-** change counter (returned by subsequent calls to sqlite3_changes()).
-** Then the VMs internal change counter resets to 0.
-** This is used by trigger programs.
-*/
-case OP_ResetCount: {
- sqlite3VdbeSetChanges(db, p->nChange);
- p->nChange = 0;
- break;
-}
-
-/* Opcode: RowData P1 P2 * * *
-**
-** Write into register P2 the complete row data for cursor P1.
-** There is no interpretation of the data.
-** It is just copied onto the P2 register exactly as
-** it is found in the database file.
-**
-** If the P1 cursor must be pointing to a valid row (not a NULL row)
-** of a real table, not a pseudo-table.
-*/
-/* Opcode: RowKey P1 P2 * * *
-**
-** Write into register P2 the complete row key for cursor P1.
-** There is no interpretation of the data.
-** The key is copied onto the P3 register exactly as
-** it is found in the database file.
-**
-** If the P1 cursor must be pointing to a valid row (not a NULL row)
-** of a real table, not a pseudo-table.
-*/
-case OP_RowKey:
-case OP_RowData: {
-#if 0 /* local variables moved into u.bh */
- VdbeCursor *pC;
- BtCursor *pCrsr;
- u32 n;
- i64 n64;
-#endif /* local variables moved into u.bh */
-
- pOut = &p->aMem[pOp->p2];
-
- /* Note that RowKey and RowData are really exactly the same instruction */
- assert( pOp->p1>=0 && pOp->p1<p->nCursor );
- u.bh.pC = p->apCsr[pOp->p1];
- assert( u.bh.pC->isTable || pOp->opcode==OP_RowKey );
- assert( u.bh.pC->isIndex || pOp->opcode==OP_RowData );
- assert( u.bh.pC!=0 );
- assert( u.bh.pC->nullRow==0 );
- assert( u.bh.pC->pseudoTableReg==0 );
- assert( u.bh.pC->pCursor!=0 );
- u.bh.pCrsr = u.bh.pC->pCursor;
- assert( sqlite3BtreeCursorIsValid(u.bh.pCrsr) );
-
- /* The OP_RowKey and OP_RowData opcodes always follow OP_NotExists or
- ** OP_Rewind/Op_Next with no intervening instructions that might invalidate
- ** the cursor. Hence the following sqlite3VdbeCursorMoveto() call is always
- ** a no-op and can never fail. But we leave it in place as a safety.
- */
- assert( u.bh.pC->deferredMoveto==0 );
- rc = sqlite3VdbeCursorMoveto(u.bh.pC);
- if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error;
-
- if( u.bh.pC->isIndex ){
- assert( !u.bh.pC->isTable );
- rc = sqlite3BtreeKeySize(u.bh.pCrsr, &u.bh.n64);
- assert( rc==SQLITE_OK ); /* True because of CursorMoveto() call above */
- if( u.bh.n64>db->aLimit[SQLITE_LIMIT_LENGTH] ){
- goto too_big;
- }
- u.bh.n = (u32)u.bh.n64;
- }else{
- rc = sqlite3BtreeDataSize(u.bh.pCrsr, &u.bh.n);
- assert( rc==SQLITE_OK ); /* DataSize() cannot fail */
- if( u.bh.n>(u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){
- goto too_big;
- }
- }
- if( sqlite3VdbeMemGrow(pOut, u.bh.n, 0) ){
- goto no_mem;
- }
- pOut->n = u.bh.n;
- MemSetTypeFlag(pOut, MEM_Blob);
- if( u.bh.pC->isIndex ){
- rc = sqlite3BtreeKey(u.bh.pCrsr, 0, u.bh.n, pOut->z);
- }else{
- rc = sqlite3BtreeData(u.bh.pCrsr, 0, u.bh.n, pOut->z);
- }
- pOut->enc = SQLITE_UTF8; /* In case the blob is ever cast to text */
- UPDATE_MAX_BLOBSIZE(pOut);
- break;
-}
-
-/* Opcode: Rowid P1 P2 * * *
-**
-** Store in register P2 an integer which is the key of the table entry that
-** P1 is currently point to.
-**
-** P1 can be either an ordinary table or a virtual table. There used to
-** be a separate OP_VRowid opcode for use with virtual tables, but this
-** one opcode now works for both table types.
-*/
-case OP_Rowid: { /* out2-prerelease */
-#if 0 /* local variables moved into u.bi */
- VdbeCursor *pC;
- i64 v;
- sqlite3_vtab *pVtab;
- const sqlite3_module *pModule;
-#endif /* local variables moved into u.bi */
-
- assert( pOp->p1>=0 && pOp->p1<p->nCursor );
- u.bi.pC = p->apCsr[pOp->p1];
- assert( u.bi.pC!=0 );
- assert( u.bi.pC->pseudoTableReg==0 );
- if( u.bi.pC->nullRow ){
- /* Do nothing so that reg[P2] remains NULL */
- break;
- }else if( u.bi.pC->deferredMoveto ){
- u.bi.v = u.bi.pC->movetoTarget;
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- }else if( u.bi.pC->pVtabCursor ){
- u.bi.pVtab = u.bi.pC->pVtabCursor->pVtab;
- u.bi.pModule = u.bi.pVtab->pModule;
- assert( u.bi.pModule->xRowid );
- if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
- rc = u.bi.pModule->xRowid(u.bi.pC->pVtabCursor, &u.bi.v);
- sqlite3DbFree(db, p->zErrMsg);
- p->zErrMsg = u.bi.pVtab->zErrMsg;
- u.bi.pVtab->zErrMsg = 0;
- if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
-#endif /* SQLITE_OMIT_VIRTUALTABLE */
- }else{
- assert( u.bi.pC->pCursor!=0 );
- rc = sqlite3VdbeCursorMoveto(u.bi.pC);
- if( rc ) goto abort_due_to_error;
- if( u.bi.pC->rowidIsValid ){
- u.bi.v = u.bi.pC->lastRowid;
- }else{
- rc = sqlite3BtreeKeySize(u.bi.pC->pCursor, &u.bi.v);
- assert( rc==SQLITE_OK ); /* Always so because of CursorMoveto() above */
- }
- }
- pOut->u.i = u.bi.v;
- MemSetTypeFlag(pOut, MEM_Int);
- break;
-}
-
-/* Opcode: NullRow P1 * * * *
-**
-** Move the cursor P1 to a null row. Any OP_Column operations
-** that occur while the cursor is on the null row will always
-** write a NULL.
-*/
-case OP_NullRow: {
-#if 0 /* local variables moved into u.bj */
- VdbeCursor *pC;
-#endif /* local variables moved into u.bj */
-
- assert( pOp->p1>=0 && pOp->p1<p->nCursor );
- u.bj.pC = p->apCsr[pOp->p1];
- assert( u.bj.pC!=0 );
- u.bj.pC->nullRow = 1;
- u.bj.pC->rowidIsValid = 0;
- if( u.bj.pC->pCursor ){
- sqlite3BtreeClearCursor(u.bj.pC->pCursor);
- }
- break;
-}
-
-/* Opcode: Last P1 P2 * * *
-**
-** The next use of the Rowid or Column or Next instruction for P1
-** will refer to the last entry in the database table or index.
-** If the table or index is empty and P2>0, then jump immediately to P2.
-** If P2 is 0 or if the table or index is not empty, fall through
-** to the following instruction.
-*/
-case OP_Last: { /* jump */
-#if 0 /* local variables moved into u.bk */
- VdbeCursor *pC;
- BtCursor *pCrsr;
- int res;
-#endif /* local variables moved into u.bk */
-
- assert( pOp->p1>=0 && pOp->p1<p->nCursor );
- u.bk.pC = p->apCsr[pOp->p1];
- assert( u.bk.pC!=0 );
- u.bk.pCrsr = u.bk.pC->pCursor;
- if( u.bk.pCrsr==0 ){
- u.bk.res = 1;
- }else{
- rc = sqlite3BtreeLast(u.bk.pCrsr, &u.bk.res);
- }
- u.bk.pC->nullRow = (u8)u.bk.res;
- u.bk.pC->deferredMoveto = 0;
- u.bk.pC->rowidIsValid = 0;
- u.bk.pC->cacheStatus = CACHE_STALE;
- if( pOp->p2>0 && u.bk.res ){
- pc = pOp->p2 - 1;
- }
- break;
-}
-
-
-/* Opcode: Sort P1 P2 * * *
-**
-** This opcode does exactly the same thing as OP_Rewind except that
-** it increments an undocumented global variable used for testing.
-**
-** Sorting is accomplished by writing records into a sorting index,
-** then rewinding that index and playing it back from beginning to
-** end. We use the OP_Sort opcode instead of OP_Rewind to do the
-** rewinding so that the global variable will be incremented and
-** regression tests can determine whether or not the optimizer is
-** correctly optimizing out sorts.
-*/
-case OP_Sort: { /* jump */
-#ifdef SQLITE_TEST
- sqlite3_sort_count++;
- sqlite3_search_count--;
-#endif
- p->aCounter[SQLITE_STMTSTATUS_SORT-1]++;
- /* Fall through into OP_Rewind */
-}
-/* Opcode: Rewind P1 P2 * * *
-**
-** The next use of the Rowid or Column or Next instruction for P1
-** will refer to the first entry in the database table or index.
-** If the table or index is empty and P2>0, then jump immediately to P2.
-** If P2 is 0 or if the table or index is not empty, fall through
-** to the following instruction.
-*/
-case OP_Rewind: { /* jump */
-#if 0 /* local variables moved into u.bl */
- VdbeCursor *pC;
- BtCursor *pCrsr;
- int res;
-#endif /* local variables moved into u.bl */
-
- assert( pOp->p1>=0 && pOp->p1<p->nCursor );
- u.bl.pC = p->apCsr[pOp->p1];
- assert( u.bl.pC!=0 );
- if( (u.bl.pCrsr = u.bl.pC->pCursor)!=0 ){
- rc = sqlite3BtreeFirst(u.bl.pCrsr, &u.bl.res);
- u.bl.pC->atFirst = u.bl.res==0 ?1:0;
- u.bl.pC->deferredMoveto = 0;
- u.bl.pC->cacheStatus = CACHE_STALE;
- u.bl.pC->rowidIsValid = 0;
- }else{
- u.bl.res = 1;
- }
- u.bl.pC->nullRow = (u8)u.bl.res;
- assert( pOp->p2>0 && pOp->p2<p->nOp );
- if( u.bl.res ){
- pc = pOp->p2 - 1;
- }
- break;
-}
-
-/* Opcode: Next P1 P2 * * *
-**
-** Advance cursor P1 so that it points to the next key/data pair in its
-** table or index. If there are no more key/value pairs then fall through
-** to the following instruction. But if the cursor advance was successful,
-** jump immediately to P2.
-**
-** The P1 cursor must be for a real table, not a pseudo-table.
-**
-** See also: Prev
-*/
-/* Opcode: Prev P1 P2 * * *
-**
-** Back up cursor P1 so that it points to the previous key/data pair in its
-** table or index. If there is no previous key/value pairs then fall through
-** to the following instruction. But if the cursor backup was successful,
-** jump immediately to P2.
-**
-** The P1 cursor must be for a real table, not a pseudo-table.
-*/
-case OP_Prev: /* jump */
-case OP_Next: { /* jump */
-#if 0 /* local variables moved into u.bm */
- VdbeCursor *pC;
- BtCursor *pCrsr;
- int res;
-#endif /* local variables moved into u.bm */
-
- CHECK_FOR_INTERRUPT;
- assert( pOp->p1>=0 && pOp->p1<p->nCursor );
- u.bm.pC = p->apCsr[pOp->p1];
- if( u.bm.pC==0 ){
- break; /* See ticket #2273 */
- }
- u.bm.pCrsr = u.bm.pC->pCursor;
- if( u.bm.pCrsr==0 ){
- u.bm.pC->nullRow = 1;
- break;
- }
- u.bm.res = 1;
- assert( u.bm.pC->deferredMoveto==0 );
- rc = pOp->opcode==OP_Next ? sqlite3BtreeNext(u.bm.pCrsr, &u.bm.res) :
- sqlite3BtreePrevious(u.bm.pCrsr, &u.bm.res);
- u.bm.pC->nullRow = (u8)u.bm.res;
- u.bm.pC->cacheStatus = CACHE_STALE;
- if( u.bm.res==0 ){
- pc = pOp->p2 - 1;
- if( pOp->p5 ) p->aCounter[pOp->p5-1]++;
-#ifdef SQLITE_TEST
- sqlite3_search_count++;
-#endif
- }
- u.bm.pC->rowidIsValid = 0;
- break;
-}
-
-/* Opcode: IdxInsert P1 P2 P3 * P5
-**
-** Register P2 holds a SQL index key made using the
-** MakeRecord instructions. This opcode writes that key
-** into the index P1. Data for the entry is nil.
-**
-** P3 is a flag that provides a hint to the b-tree layer that this
-** insert is likely to be an append.
-**
-** This instruction only works for indices. The equivalent instruction
-** for tables is OP_Insert.
-*/
-case OP_IdxInsert: { /* in2 */
-#if 0 /* local variables moved into u.bn */
- VdbeCursor *pC;
- BtCursor *pCrsr;
- int nKey;
- const char *zKey;
-#endif /* local variables moved into u.bn */
-
- assert( pOp->p1>=0 && pOp->p1<p->nCursor );
- u.bn.pC = p->apCsr[pOp->p1];
- assert( u.bn.pC!=0 );
- assert( pIn2->flags & MEM_Blob );
- u.bn.pCrsr = u.bn.pC->pCursor;
- if( ALWAYS(u.bn.pCrsr!=0) ){
- assert( u.bn.pC->isTable==0 );
- rc = ExpandBlob(pIn2);
- if( rc==SQLITE_OK ){
- u.bn.nKey = pIn2->n;
- u.bn.zKey = pIn2->z;
- rc = sqlite3BtreeInsert(u.bn.pCrsr, u.bn.zKey, u.bn.nKey, "", 0, 0, pOp->p3,
- ((pOp->p5 & OPFLAG_USESEEKRESULT) ? u.bn.pC->seekResult : 0)
- );
- assert( u.bn.pC->deferredMoveto==0 );
- u.bn.pC->cacheStatus = CACHE_STALE;
- }
- }
- break;
-}
-
-/* Opcode: IdxDelete P1 P2 P3 * *
-**
-** The content of P3 registers starting at register P2 form
-** an unpacked index key. This opcode removes that entry from the
-** index opened by cursor P1.
-*/
-case OP_IdxDelete: {
-#if 0 /* local variables moved into u.bo */
- VdbeCursor *pC;
- BtCursor *pCrsr;
- int res;
- UnpackedRecord r;
-#endif /* local variables moved into u.bo */
-
- assert( pOp->p3>0 );
- assert( pOp->p2>0 && pOp->p2+pOp->p3<=p->nMem+1 );
- assert( pOp->p1>=0 && pOp->p1<p->nCursor );
- u.bo.pC = p->apCsr[pOp->p1];
- assert( u.bo.pC!=0 );
- u.bo.pCrsr = u.bo.pC->pCursor;
- if( ALWAYS(u.bo.pCrsr!=0) ){
- u.bo.r.pKeyInfo = u.bo.pC->pKeyInfo;
- u.bo.r.nField = (u16)pOp->p3;
- u.bo.r.flags = 0;
- u.bo.r.aMem = &p->aMem[pOp->p2];
- rc = sqlite3BtreeMovetoUnpacked(u.bo.pCrsr, &u.bo.r, 0, 0, &u.bo.res);
- if( rc==SQLITE_OK && u.bo.res==0 ){
- rc = sqlite3BtreeDelete(u.bo.pCrsr);
- }
- assert( u.bo.pC->deferredMoveto==0 );
- u.bo.pC->cacheStatus = CACHE_STALE;
- }
- break;
-}
-
-/* Opcode: IdxRowid P1 P2 * * *
-**
-** Write into register P2 an integer which is the last entry in the record at
-** the end of the index key pointed to by cursor P1. This integer should be
-** the rowid of the table entry to which this index entry points.
-**
-** See also: Rowid, MakeRecord.
-*/
-case OP_IdxRowid: { /* out2-prerelease */
-#if 0 /* local variables moved into u.bp */
- BtCursor *pCrsr;
- VdbeCursor *pC;
- i64 rowid;
-#endif /* local variables moved into u.bp */
-
- assert( pOp->p1>=0 && pOp->p1<p->nCursor );
- u.bp.pC = p->apCsr[pOp->p1];
- assert( u.bp.pC!=0 );
- u.bp.pCrsr = u.bp.pC->pCursor;
- if( ALWAYS(u.bp.pCrsr!=0) ){
- rc = sqlite3VdbeCursorMoveto(u.bp.pC);
- if( NEVER(rc) ) goto abort_due_to_error;
- assert( u.bp.pC->deferredMoveto==0 );
- assert( u.bp.pC->isTable==0 );
- if( !u.bp.pC->nullRow ){
- rc = sqlite3VdbeIdxRowid(db, u.bp.pCrsr, &u.bp.rowid);
- if( rc!=SQLITE_OK ){
- goto abort_due_to_error;
- }
- MemSetTypeFlag(pOut, MEM_Int);
- pOut->u.i = u.bp.rowid;
- }
- }
- break;
-}
-
-/* Opcode: IdxGE P1 P2 P3 P4 P5
-**
-** The P4 register values beginning with P3 form an unpacked index
-** key that omits the ROWID. Compare this key value against the index
-** that P1 is currently pointing to, ignoring the ROWID on the P1 index.
-**
-** If the P1 index entry is greater than or equal to the key value
-** then jump to P2. Otherwise fall through to the next instruction.
-**
-** If P5 is non-zero then the key value is increased by an epsilon
-** prior to the comparison. This make the opcode work like IdxGT except
-** that if the key from register P3 is a prefix of the key in the cursor,
-** the result is false whereas it would be true with IdxGT.
-*/
-/* Opcode: IdxLT P1 P2 P3 * P5
-**
-** The P4 register values beginning with P3 form an unpacked index
-** key that omits the ROWID. Compare this key value against the index
-** that P1 is currently pointing to, ignoring the ROWID on the P1 index.
-**
-** If the P1 index entry is less than the key value then jump to P2.
-** Otherwise fall through to the next instruction.
-**
-** If P5 is non-zero then the key value is increased by an epsilon prior
-** to the comparison. This makes the opcode work like IdxLE.
-*/
-case OP_IdxLT: /* jump, in3 */
-case OP_IdxGE: { /* jump, in3 */
-#if 0 /* local variables moved into u.bq */
- VdbeCursor *pC;
- int res;
- UnpackedRecord r;
-#endif /* local variables moved into u.bq */
-
- assert( pOp->p1>=0 && pOp->p1<p->nCursor );
- u.bq.pC = p->apCsr[pOp->p1];
- assert( u.bq.pC!=0 );
- if( ALWAYS(u.bq.pC->pCursor!=0) ){
- assert( u.bq.pC->deferredMoveto==0 );
- assert( pOp->p5==0 || pOp->p5==1 );
- assert( pOp->p4type==P4_INT32 );
- u.bq.r.pKeyInfo = u.bq.pC->pKeyInfo;
- u.bq.r.nField = (u16)pOp->p4.i;
- if( pOp->p5 ){
- u.bq.r.flags = UNPACKED_INCRKEY | UNPACKED_IGNORE_ROWID;
- }else{
- u.bq.r.flags = UNPACKED_IGNORE_ROWID;
- }
- u.bq.r.aMem = &p->aMem[pOp->p3];
- rc = sqlite3VdbeIdxKeyCompare(u.bq.pC, &u.bq.r, &u.bq.res);
- if( pOp->opcode==OP_IdxLT ){
- u.bq.res = -u.bq.res;
- }else{
- assert( pOp->opcode==OP_IdxGE );
- u.bq.res++;
- }
- if( u.bq.res>0 ){
- pc = pOp->p2 - 1 ;
- }
- }
- break;
-}
-
-/* Opcode: Destroy P1 P2 P3 * *
-**
-** Delete an entire database table or index whose root page in the database
-** file is given by P1.
-**
-** The table being destroyed is in the main database file if P3==0. If
-** P3==1 then the table to be clear is in the auxiliary database file
-** that is used to store tables create using CREATE TEMPORARY TABLE.
-**
-** If AUTOVACUUM is enabled then it is possible that another root page
-** might be moved into the newly deleted root page in order to keep all
-** root pages contiguous at the beginning of the database. The former
-** value of the root page that moved - its value before the move occurred -
-** is stored in register P2. If no page
-** movement was required (because the table being dropped was already
-** the last one in the database) then a zero is stored in register P2.
-** If AUTOVACUUM is disabled then a zero is stored in register P2.
-**
-** See also: Clear
-*/
-case OP_Destroy: { /* out2-prerelease */
-#if 0 /* local variables moved into u.br */
- int iMoved;
- int iCnt;
- Vdbe *pVdbe;
- int iDb;
-#endif /* local variables moved into u.br */
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- u.br.iCnt = 0;
- for(u.br.pVdbe=db->pVdbe; u.br.pVdbe; u.br.pVdbe = u.br.pVdbe->pNext){
- if( u.br.pVdbe->magic==VDBE_MAGIC_RUN && u.br.pVdbe->inVtabMethod<2 && u.br.pVdbe->pc>=0 ){
- u.br.iCnt++;
- }
- }
-#else
- u.br.iCnt = db->activeVdbeCnt;
-#endif
- if( u.br.iCnt>1 ){
- rc = SQLITE_LOCKED;
- p->errorAction = OE_Abort;
- }else{
- u.br.iDb = pOp->p3;
- assert( u.br.iCnt==1 );
- assert( (p->btreeMask & (1<<u.br.iDb))!=0 );
- rc = sqlite3BtreeDropTable(db->aDb[u.br.iDb].pBt, pOp->p1, &u.br.iMoved);
- MemSetTypeFlag(pOut, MEM_Int);
- pOut->u.i = u.br.iMoved;
-#ifndef SQLITE_OMIT_AUTOVACUUM
- if( rc==SQLITE_OK && u.br.iMoved!=0 ){
- sqlite3RootPageMoved(&db->aDb[u.br.iDb], u.br.iMoved, pOp->p1);
- }
-#endif
- }
- break;
-}
-
-/* Opcode: Clear P1 P2 P3
-**
-** Delete all contents of the database table or index whose root page
-** in the database file is given by P1. But, unlike Destroy, do not
-** remove the table or index from the database file.
-**
-** The table being clear is in the main database file if P2==0. If
-** P2==1 then the table to be clear is in the auxiliary database file
-** that is used to store tables create using CREATE TEMPORARY TABLE.
-**
-** If the P3 value is non-zero, then the table referred to must be an
-** intkey table (an SQL table, not an index). In this case the row change
-** count is incremented by the number of rows in the table being cleared.
-** If P3 is greater than zero, then the value stored in register P3 is
-** also incremented by the number of rows in the table being cleared.
-**
-** See also: Destroy
-*/
-case OP_Clear: {
-#if 0 /* local variables moved into u.bs */
- int nChange;
-#endif /* local variables moved into u.bs */
-
- u.bs.nChange = 0;
- assert( (p->btreeMask & (1<<pOp->p2))!=0 );
- rc = sqlite3BtreeClearTable(
- db->aDb[pOp->p2].pBt, pOp->p1, (pOp->p3 ? &u.bs.nChange : 0)
- );
- if( pOp->p3 ){
- p->nChange += u.bs.nChange;
- if( pOp->p3>0 ){
- p->aMem[pOp->p3].u.i += u.bs.nChange;
- }
- }
- break;
-}
-
-/* Opcode: CreateTable P1 P2 * * *
-**
-** Allocate a new table in the main database file if P1==0 or in the
-** auxiliary database file if P1==1 or in an attached database if
-** P1>1. Write the root page number of the new table into
-** register P2
-**
-** The difference between a table and an index is this: A table must
-** have a 4-byte integer key and can have arbitrary data. An index
-** has an arbitrary key but no data.
-**
-** See also: CreateIndex
-*/
-/* Opcode: CreateIndex P1 P2 * * *
-**
-** Allocate a new index in the main database file if P1==0 or in the
-** auxiliary database file if P1==1 or in an attached database if
-** P1>1. Write the root page number of the new table into
-** register P2.
-**
-** See documentation on OP_CreateTable for additional information.
-*/
-case OP_CreateIndex: /* out2-prerelease */
-case OP_CreateTable: { /* out2-prerelease */
-#if 0 /* local variables moved into u.bt */
- int pgno;
- int flags;
- Db *pDb;
-#endif /* local variables moved into u.bt */
-
- u.bt.pgno = 0;
- assert( pOp->p1>=0 && pOp->p1<db->nDb );
- assert( (p->btreeMask & (1<<pOp->p1))!=0 );
- u.bt.pDb = &db->aDb[pOp->p1];
- assert( u.bt.pDb->pBt!=0 );
- if( pOp->opcode==OP_CreateTable ){
- /* u.bt.flags = BTREE_INTKEY; */
- u.bt.flags = BTREE_LEAFDATA|BTREE_INTKEY;
- }else{
- u.bt.flags = BTREE_ZERODATA;
- }
- rc = sqlite3BtreeCreateTable(u.bt.pDb->pBt, &u.bt.pgno, u.bt.flags);
- pOut->u.i = u.bt.pgno;
- MemSetTypeFlag(pOut, MEM_Int);
- break;
-}
-
-/* Opcode: ParseSchema P1 P2 * P4 *
-**
-** Read and parse all entries from the SQLITE_MASTER table of database P1
-** that match the WHERE clause P4. P2 is the "force" flag. Always do
-** the parsing if P2 is true. If P2 is false, then this routine is a
-** no-op if the schema is not currently loaded. In other words, if P2
-** is false, the SQLITE_MASTER table is only parsed if the rest of the
-** schema is already loaded into the symbol table.
-**
-** This opcode invokes the parser to create a new virtual machine,
-** then runs the new virtual machine. It is thus a re-entrant opcode.
-*/
-case OP_ParseSchema: {
-#if 0 /* local variables moved into u.bu */
- int iDb;
- const char *zMaster;
- char *zSql;
- InitData initData;
-#endif /* local variables moved into u.bu */
-
- u.bu.iDb = pOp->p1;
- assert( u.bu.iDb>=0 && u.bu.iDb<db->nDb );
-
- /* If pOp->p2 is 0, then this opcode is being executed to read a
- ** single row, for example the row corresponding to a new index
- ** created by this VDBE, from the sqlite_master table. It only
- ** does this if the corresponding in-memory schema is currently
- ** loaded. Otherwise, the new index definition can be loaded along
- ** with the rest of the schema when it is required.
- **
- ** Although the mutex on the BtShared object that corresponds to
- ** database u.bu.iDb (the database containing the sqlite_master table
- ** read by this instruction) is currently held, it is necessary to
- ** obtain the mutexes on all attached databases before checking if
- ** the schema of u.bu.iDb is loaded. This is because, at the start of
- ** the sqlite3_exec() call below, SQLite will invoke
- ** sqlite3BtreeEnterAll(). If all mutexes are not already held, the
- ** u.bu.iDb mutex may be temporarily released to avoid deadlock. If
- ** this happens, then some other thread may delete the in-memory
- ** schema of database u.bu.iDb before the SQL statement runs. The schema
- ** will not be reloaded becuase the db->init.busy flag is set. This
- ** can result in a "no such table: sqlite_master" or "malformed
- ** database schema" error being returned to the user.
- */
- assert( sqlite3BtreeHoldsMutex(db->aDb[u.bu.iDb].pBt) );
- sqlite3BtreeEnterAll(db);
- if( pOp->p2 || DbHasProperty(db, u.bu.iDb, DB_SchemaLoaded) ){
- u.bu.zMaster = SCHEMA_TABLE(u.bu.iDb);
- u.bu.initData.db = db;
- u.bu.initData.iDb = pOp->p1;
- u.bu.initData.pzErrMsg = &p->zErrMsg;
- u.bu.zSql = sqlite3MPrintf(db,
- "SELECT name, rootpage, sql FROM '%q'.%s WHERE %s",
- db->aDb[u.bu.iDb].zName, u.bu.zMaster, pOp->p4.z);
- if( u.bu.zSql==0 ){
- rc = SQLITE_NOMEM;
- }else{
- (void)sqlite3SafetyOff(db);
- assert( db->init.busy==0 );
- db->init.busy = 1;
- u.bu.initData.rc = SQLITE_OK;
- assert( !db->mallocFailed );
- rc = sqlite3_exec(db, u.bu.zSql, sqlite3InitCallback, &u.bu.initData, 0);
- if( rc==SQLITE_OK ) rc = u.bu.initData.rc;
- sqlite3DbFree(db, u.bu.zSql);
- db->init.busy = 0;
- (void)sqlite3SafetyOn(db);
- }
- }
- sqlite3BtreeLeaveAll(db);
- if( rc==SQLITE_NOMEM ){
- goto no_mem;
- }
- break;
-}
-
-#if !defined(SQLITE_OMIT_ANALYZE)
-/* Opcode: LoadAnalysis P1 * * * *
-**
-** Read the sqlite_stat1 table for database P1 and load the content
-** of that table into the internal index hash table. This will cause
-** the analysis to be used when preparing all subsequent queries.
-*/
-case OP_LoadAnalysis: {
- assert( pOp->p1>=0 && pOp->p1<db->nDb );
- rc = sqlite3AnalysisLoad(db, pOp->p1);
- break;
-}
-#endif /* !defined(SQLITE_OMIT_ANALYZE) */
-
-/* Opcode: DropTable P1 * * P4 *
-**
-** Remove the internal (in-memory) data structures that describe
-** the table named P4 in database P1. This is called after a table
-** is dropped in order to keep the internal representation of the
-** schema consistent with what is on disk.
-*/
-case OP_DropTable: {
- sqlite3UnlinkAndDeleteTable(db, pOp->p1, pOp->p4.z);
- break;
-}
-
-/* Opcode: DropIndex P1 * * P4 *
-**
-** Remove the internal (in-memory) data structures that describe
-** the index named P4 in database P1. This is called after an index
-** is dropped in order to keep the internal representation of the
-** schema consistent with what is on disk.
-*/
-case OP_DropIndex: {
- sqlite3UnlinkAndDeleteIndex(db, pOp->p1, pOp->p4.z);
- break;
-}
-
-/* Opcode: DropTrigger P1 * * P4 *
-**
-** Remove the internal (in-memory) data structures that describe
-** the trigger named P4 in database P1. This is called after a trigger
-** is dropped in order to keep the internal representation of the
-** schema consistent with what is on disk.
-*/
-case OP_DropTrigger: {
- sqlite3UnlinkAndDeleteTrigger(db, pOp->p1, pOp->p4.z);
- break;
-}
-
-
-#ifndef SQLITE_OMIT_INTEGRITY_CHECK
-/* Opcode: IntegrityCk P1 P2 P3 * P5
-**
-** Do an analysis of the currently open database. Store in
-** register P1 the text of an error message describing any problems.
-** If no problems are found, store a NULL in register P1.
-**
-** The register P3 contains the maximum number of allowed errors.
-** At most reg(P3) errors will be reported.
-** In other words, the analysis stops as soon as reg(P1) errors are
-** seen. Reg(P1) is updated with the number of errors remaining.
-**
-** The root page numbers of all tables in the database are integer
-** stored in reg(P1), reg(P1+1), reg(P1+2), .... There are P2 tables
-** total.
-**
-** If P5 is not zero, the check is done on the auxiliary database
-** file, not the main database file.
-**
-** This opcode is used to implement the integrity_check pragma.
-*/
-case OP_IntegrityCk: {
-#if 0 /* local variables moved into u.bv */
- int nRoot; /* Number of tables to check. (Number of root pages.) */
- int *aRoot; /* Array of rootpage numbers for tables to be checked */
- int j; /* Loop counter */
- int nErr; /* Number of errors reported */
- char *z; /* Text of the error report */
- Mem *pnErr; /* Register keeping track of errors remaining */
-#endif /* local variables moved into u.bv */
-
- u.bv.nRoot = pOp->p2;
- assert( u.bv.nRoot>0 );
- u.bv.aRoot = sqlite3DbMallocRaw(db, sizeof(int)*(u.bv.nRoot+1) );
- if( u.bv.aRoot==0 ) goto no_mem;
- assert( pOp->p3>0 && pOp->p3<=p->nMem );
- u.bv.pnErr = &p->aMem[pOp->p3];
- assert( (u.bv.pnErr->flags & MEM_Int)!=0 );
- assert( (u.bv.pnErr->flags & (MEM_Str|MEM_Blob))==0 );
- pIn1 = &p->aMem[pOp->p1];
- for(u.bv.j=0; u.bv.j<u.bv.nRoot; u.bv.j++){
- u.bv.aRoot[u.bv.j] = (int)sqlite3VdbeIntValue(&pIn1[u.bv.j]);
- }
- u.bv.aRoot[u.bv.j] = 0;
- assert( pOp->p5<db->nDb );
- assert( (p->btreeMask & (1<<pOp->p5))!=0 );
- u.bv.z = sqlite3BtreeIntegrityCheck(db->aDb[pOp->p5].pBt, u.bv.aRoot, u.bv.nRoot,
- (int)u.bv.pnErr->u.i, &u.bv.nErr);
- sqlite3DbFree(db, u.bv.aRoot);
- u.bv.pnErr->u.i -= u.bv.nErr;
- sqlite3VdbeMemSetNull(pIn1);
- if( u.bv.nErr==0 ){
- assert( u.bv.z==0 );
- }else if( u.bv.z==0 ){
- goto no_mem;
- }else{
- sqlite3VdbeMemSetStr(pIn1, u.bv.z, -1, SQLITE_UTF8, sqlite3_free);
- }
- UPDATE_MAX_BLOBSIZE(pIn1);
- sqlite3VdbeChangeEncoding(pIn1, encoding);
- break;
-}
-#endif /* SQLITE_OMIT_INTEGRITY_CHECK */
-
-/* Opcode: RowSetAdd P1 P2 * * *
-**
-** Insert the integer value held by register P2 into a boolean index
-** held in register P1.
-**
-** An assertion fails if P2 is not an integer.
-*/
-case OP_RowSetAdd: { /* in2 */
-#if 0 /* local variables moved into u.bw */
- Mem *pIdx;
- Mem *pVal;
-#endif /* local variables moved into u.bw */
- assert( pOp->p1>0 && pOp->p1<=p->nMem );
- u.bw.pIdx = &p->aMem[pOp->p1];
- assert( pOp->p2>0 && pOp->p2<=p->nMem );
- u.bw.pVal = &p->aMem[pOp->p2];
- assert( (u.bw.pVal->flags & MEM_Int)!=0 );
- if( (u.bw.pIdx->flags & MEM_RowSet)==0 ){
- sqlite3VdbeMemSetRowSet(u.bw.pIdx);
- if( (u.bw.pIdx->flags & MEM_RowSet)==0 ) goto no_mem;
- }
- sqlite3RowSetInsert(u.bw.pIdx->u.pRowSet, u.bw.pVal->u.i);
- break;
-}
-
-/* Opcode: RowSetRead P1 P2 P3 * *
-**
-** Extract the smallest value from boolean index P1 and put that value into
-** register P3. Or, if boolean index P1 is initially empty, leave P3
-** unchanged and jump to instruction P2.
-*/
-case OP_RowSetRead: { /* jump, out3 */
-#if 0 /* local variables moved into u.bx */
- Mem *pIdx;
- i64 val;
-#endif /* local variables moved into u.bx */
- assert( pOp->p1>0 && pOp->p1<=p->nMem );
- CHECK_FOR_INTERRUPT;
- u.bx.pIdx = &p->aMem[pOp->p1];
- pOut = &p->aMem[pOp->p3];
- if( (u.bx.pIdx->flags & MEM_RowSet)==0
- || sqlite3RowSetNext(u.bx.pIdx->u.pRowSet, &u.bx.val)==0
- ){
- /* The boolean index is empty */
- sqlite3VdbeMemSetNull(u.bx.pIdx);
- pc = pOp->p2 - 1;
- }else{
- /* A value was pulled from the index */
- assert( pOp->p3>0 && pOp->p3<=p->nMem );
- sqlite3VdbeMemSetInt64(pOut, u.bx.val);
- }
- break;
-}
-
-/* Opcode: RowSetTest P1 P2 P3 P4
-**
-** Register P3 is assumed to hold a 64-bit integer value. If register P1
-** contains a RowSet object and that RowSet object contains
-** the value held in P3, jump to register P2. Otherwise, insert the
-** integer in P3 into the RowSet and continue on to the
-** next opcode.
-**
-** The RowSet object is optimized for the case where successive sets
-** of integers, where each set contains no duplicates. Each set
-** of values is identified by a unique P4 value. The first set
-** must have P4==0, the final set P4=-1. P4 must be either -1 or
-** non-negative. For non-negative values of P4 only the lower 4
-** bits are significant.
-**
-** This allows optimizations: (a) when P4==0 there is no need to test
-** the rowset object for P3, as it is guaranteed not to contain it,
-** (b) when P4==-1 there is no need to insert the value, as it will
-** never be tested for, and (c) when a value that is part of set X is
-** inserted, there is no need to search to see if the same value was
-** previously inserted as part of set X (only if it was previously
-** inserted as part of some other set).
-*/
-case OP_RowSetTest: { /* jump, in1, in3 */
-#if 0 /* local variables moved into u.by */
- int iSet;
- int exists;
-#endif /* local variables moved into u.by */
-
- u.by.iSet = pOp->p4.i;
- assert( pIn3->flags&MEM_Int );
-
- /* If there is anything other than a rowset object in memory cell P1,
- ** delete it now and initialize P1 with an empty rowset
- */
- if( (pIn1->flags & MEM_RowSet)==0 ){
- sqlite3VdbeMemSetRowSet(pIn1);
- if( (pIn1->flags & MEM_RowSet)==0 ) goto no_mem;
- }
-
- assert( pOp->p4type==P4_INT32 );
- assert( u.by.iSet==-1 || u.by.iSet>=0 );
- if( u.by.iSet ){
- u.by.exists = sqlite3RowSetTest(pIn1->u.pRowSet,
- (u8)(u.by.iSet>=0 ? u.by.iSet & 0xf : 0xff),
- pIn3->u.i);
- if( u.by.exists ){
- pc = pOp->p2 - 1;
- break;
- }
- }
- if( u.by.iSet>=0 ){
- sqlite3RowSetInsert(pIn1->u.pRowSet, pIn3->u.i);
- }
- break;
-}
-
-
-#ifndef SQLITE_OMIT_TRIGGER
-
-/* Opcode: Program P1 P2 P3 P4 *
-**
-** Execute the trigger program passed as P4 (type P4_SUBPROGRAM).
-**
-** P1 contains the address of the memory cell that contains the first memory
-** cell in an array of values used as arguments to the sub-program. P2
-** contains the address to jump to if the sub-program throws an IGNORE
-** exception using the RAISE() function. Register P3 contains the address
-** of a memory cell in this (the parent) VM that is used to allocate the
-** memory required by the sub-vdbe at runtime.
-**
-** P4 is a pointer to the VM containing the trigger program.
-*/
-case OP_Program: { /* jump */
-#if 0 /* local variables moved into u.bz */
- int nMem; /* Number of memory registers for sub-program */
- int nByte; /* Bytes of runtime space required for sub-program */
- Mem *pRt; /* Register to allocate runtime space */
- Mem *pMem; /* Used to iterate through memory cells */
- Mem *pEnd; /* Last memory cell in new array */
- VdbeFrame *pFrame; /* New vdbe frame to execute in */
- SubProgram *pProgram; /* Sub-program to execute */
- void *t; /* Token identifying trigger */
-#endif /* local variables moved into u.bz */
-
- u.bz.pProgram = pOp->p4.pProgram;
- u.bz.pRt = &p->aMem[pOp->p3];
- assert( u.bz.pProgram->nOp>0 );
-
- /* If the SQLITE_RecTriggers flag is clear, then recursive invocation of
- ** triggers is disabled for backwards compatibility (flag set/cleared by
- ** the "PRAGMA recursive_triggers" command).
- **
- ** It is recursive invocation of triggers, at the SQL level, that is
- ** disabled. In some cases a single trigger may generate more than one
- ** SubProgram (if the trigger may be executed with more than one different
- ** ON CONFLICT algorithm). SubProgram structures associated with a
- ** single trigger all have the same value for the SubProgram.token
- ** variable.
- */
- if( 0==(db->flags&SQLITE_RecTriggers) ){
- u.bz.t = u.bz.pProgram->token;
- for(u.bz.pFrame=p->pFrame; u.bz.pFrame && u.bz.pFrame->token!=u.bz.t; u.bz.pFrame=u.bz.pFrame->pParent);
- if( u.bz.pFrame ) break;
- }
-
- if( p->nFrame>db->aLimit[SQLITE_LIMIT_TRIGGER_DEPTH] ){
- rc = SQLITE_ERROR;
- sqlite3SetString(&p->zErrMsg, db, "too many levels of trigger recursion");
- break;
- }
-
- /* Register u.bz.pRt is used to store the memory required to save the state
- ** of the current program, and the memory required at runtime to execute
- ** the trigger program. If this trigger has been fired before, then u.bz.pRt
- ** is already allocated. Otherwise, it must be initialized. */
- if( (u.bz.pRt->flags&MEM_Frame)==0 ){
- /* SubProgram.nMem is set to the number of memory cells used by the
- ** program stored in SubProgram.aOp. As well as these, one memory
- ** cell is required for each cursor used by the program. Set local
- ** variable u.bz.nMem (and later, VdbeFrame.nChildMem) to this value.
- */
- u.bz.nMem = u.bz.pProgram->nMem + u.bz.pProgram->nCsr;
- u.bz.nByte = ROUND8(sizeof(VdbeFrame))
- + u.bz.nMem * sizeof(Mem)
- + u.bz.pProgram->nCsr * sizeof(VdbeCursor *);
- u.bz.pFrame = sqlite3DbMallocZero(db, u.bz.nByte);
- if( !u.bz.pFrame ){
- goto no_mem;
- }
- sqlite3VdbeMemRelease(u.bz.pRt);
- u.bz.pRt->flags = MEM_Frame;
- u.bz.pRt->u.pFrame = u.bz.pFrame;
-
- u.bz.pFrame->v = p;
- u.bz.pFrame->nChildMem = u.bz.nMem;
- u.bz.pFrame->nChildCsr = u.bz.pProgram->nCsr;
- u.bz.pFrame->pc = pc;
- u.bz.pFrame->aMem = p->aMem;
- u.bz.pFrame->nMem = p->nMem;
- u.bz.pFrame->apCsr = p->apCsr;
- u.bz.pFrame->nCursor = p->nCursor;
- u.bz.pFrame->aOp = p->aOp;
- u.bz.pFrame->nOp = p->nOp;
- u.bz.pFrame->token = u.bz.pProgram->token;
-
- u.bz.pEnd = &VdbeFrameMem(u.bz.pFrame)[u.bz.pFrame->nChildMem];
- for(u.bz.pMem=VdbeFrameMem(u.bz.pFrame); u.bz.pMem!=u.bz.pEnd; u.bz.pMem++){
- u.bz.pMem->flags = MEM_Null;
- u.bz.pMem->db = db;
- }
- }else{
- u.bz.pFrame = u.bz.pRt->u.pFrame;
- assert( u.bz.pProgram->nMem+u.bz.pProgram->nCsr==u.bz.pFrame->nChildMem );
- assert( u.bz.pProgram->nCsr==u.bz.pFrame->nChildCsr );
- assert( pc==u.bz.pFrame->pc );
- }
-
- p->nFrame++;
- u.bz.pFrame->pParent = p->pFrame;
- u.bz.pFrame->lastRowid = db->lastRowid;
- u.bz.pFrame->nChange = p->nChange;
- p->nChange = 0;
- p->pFrame = u.bz.pFrame;
- p->aMem = &VdbeFrameMem(u.bz.pFrame)[-1];
- p->nMem = u.bz.pFrame->nChildMem;
- p->nCursor = (u16)u.bz.pFrame->nChildCsr;
- p->apCsr = (VdbeCursor **)&p->aMem[p->nMem+1];
- p->aOp = u.bz.pProgram->aOp;
- p->nOp = u.bz.pProgram->nOp;
- pc = -1;
-
- break;
-}
-
-/* Opcode: Param P1 P2 * * *
-**
-** This opcode is only ever present in sub-programs called via the
-** OP_Program instruction. Copy a value currently stored in a memory
-** cell of the calling (parent) frame to cell P2 in the current frames
-** address space. This is used by trigger programs to access the new.*
-** and old.* values.
-**
-** The address of the cell in the parent frame is determined by adding
-** the value of the P1 argument to the value of the P1 argument to the
-** calling OP_Program instruction.
-*/
-case OP_Param: { /* out2-prerelease */
-#if 0 /* local variables moved into u.ca */
- VdbeFrame *pFrame;
- Mem *pIn;
-#endif /* local variables moved into u.ca */
- u.ca.pFrame = p->pFrame;
- u.ca.pIn = &u.ca.pFrame->aMem[pOp->p1 + u.ca.pFrame->aOp[u.ca.pFrame->pc].p1];
- sqlite3VdbeMemShallowCopy(pOut, u.ca.pIn, MEM_Ephem);
- break;
-}
-
-#endif /* #ifndef SQLITE_OMIT_TRIGGER */
-
-#ifndef SQLITE_OMIT_AUTOINCREMENT
-/* Opcode: MemMax P1 P2 * * *
-**
-** P1 is a register in the root frame of this VM (the root frame is
-** different from the current frame if this instruction is being executed
-** within a sub-program). Set the value of register P1 to the maximum of
-** its current value and the value in register P2.
-**
-** This instruction throws an error if the memory cell is not initially
-** an integer.
-*/
-case OP_MemMax: { /* in2 */
-#if 0 /* local variables moved into u.cb */
- Mem *pIn1;
- VdbeFrame *pFrame;
-#endif /* local variables moved into u.cb */
- if( p->pFrame ){
- for(u.cb.pFrame=p->pFrame; u.cb.pFrame->pParent; u.cb.pFrame=u.cb.pFrame->pParent);
- u.cb.pIn1 = &u.cb.pFrame->aMem[pOp->p1];
- }else{
- u.cb.pIn1 = &p->aMem[pOp->p1];
- }
- sqlite3VdbeMemIntegerify(u.cb.pIn1);
- sqlite3VdbeMemIntegerify(pIn2);
- if( u.cb.pIn1->u.i<pIn2->u.i){
- u.cb.pIn1->u.i = pIn2->u.i;
- }
- break;
-}
-#endif /* SQLITE_OMIT_AUTOINCREMENT */
-
-/* Opcode: IfPos P1 P2 * * *
-**
-** If the value of register P1 is 1 or greater, jump to P2.
-**
-** It is illegal to use this instruction on a register that does
-** not contain an integer. An assertion fault will result if you try.
-*/
-case OP_IfPos: { /* jump, in1 */
- assert( pIn1->flags&MEM_Int );
- if( pIn1->u.i>0 ){
- pc = pOp->p2 - 1;
- }
- break;
-}
-
-/* Opcode: IfNeg P1 P2 * * *
-**
-** If the value of register P1 is less than zero, jump to P2.
-**
-** It is illegal to use this instruction on a register that does
-** not contain an integer. An assertion fault will result if you try.
-*/
-case OP_IfNeg: { /* jump, in1 */
- assert( pIn1->flags&MEM_Int );
- if( pIn1->u.i<0 ){
- pc = pOp->p2 - 1;
- }
- break;
-}
-
-/* Opcode: IfZero P1 P2 * * *
-**
-** If the value of register P1 is exactly 0, jump to P2.
-**
-** It is illegal to use this instruction on a register that does
-** not contain an integer. An assertion fault will result if you try.
-*/
-case OP_IfZero: { /* jump, in1 */
- assert( pIn1->flags&MEM_Int );
- if( pIn1->u.i==0 ){
- pc = pOp->p2 - 1;
- }
- break;
-}
-
-/* Opcode: AggStep * P2 P3 P4 P5
-**
-** Execute the step function for an aggregate. The
-** function has P5 arguments. P4 is a pointer to the FuncDef
-** structure that specifies the function. Use register
-** P3 as the accumulator.
-**
-** The P5 arguments are taken from register P2 and its
-** successors.
-*/
-case OP_AggStep: {
-#if 0 /* local variables moved into u.cc */
- int n;
- int i;
- Mem *pMem;
- Mem *pRec;
- sqlite3_context ctx;
- sqlite3_value **apVal;
-#endif /* local variables moved into u.cc */
-
- u.cc.n = pOp->p5;
- assert( u.cc.n>=0 );
- u.cc.pRec = &p->aMem[pOp->p2];
- u.cc.apVal = p->apArg;
- assert( u.cc.apVal || u.cc.n==0 );
- for(u.cc.i=0; u.cc.i<u.cc.n; u.cc.i++, u.cc.pRec++){
- u.cc.apVal[u.cc.i] = u.cc.pRec;
- storeTypeInfo(u.cc.pRec, encoding);
- }
- u.cc.ctx.pFunc = pOp->p4.pFunc;
- assert( pOp->p3>0 && pOp->p3<=p->nMem );
- u.cc.ctx.pMem = u.cc.pMem = &p->aMem[pOp->p3];
- u.cc.pMem->n++;
- u.cc.ctx.s.flags = MEM_Null;
- u.cc.ctx.s.z = 0;
- u.cc.ctx.s.zMalloc = 0;
- u.cc.ctx.s.xDel = 0;
- u.cc.ctx.s.db = db;
- u.cc.ctx.isError = 0;
- u.cc.ctx.pColl = 0;
- if( u.cc.ctx.pFunc->flags & SQLITE_FUNC_NEEDCOLL ){
- assert( pOp>p->aOp );
- assert( pOp[-1].p4type==P4_COLLSEQ );
- assert( pOp[-1].opcode==OP_CollSeq );
- u.cc.ctx.pColl = pOp[-1].p4.pColl;
- }
- (u.cc.ctx.pFunc->xStep)(&u.cc.ctx, u.cc.n, u.cc.apVal);
- if( u.cc.ctx.isError ){
- sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&u.cc.ctx.s));
- rc = u.cc.ctx.isError;
- }
- sqlite3VdbeMemRelease(&u.cc.ctx.s);
- break;
-}
-
-/* Opcode: AggFinal P1 P2 * P4 *
-**
-** Execute the finalizer function for an aggregate. P1 is
-** the memory location that is the accumulator for the aggregate.
-**
-** P2 is the number of arguments that the step function takes and
-** P4 is a pointer to the FuncDef for this function. The P2
-** argument is not used by this opcode. It is only there to disambiguate
-** functions that can take varying numbers of arguments. The
-** P4 argument is only needed for the degenerate case where
-** the step function was not previously called.
-*/
-case OP_AggFinal: {
-#if 0 /* local variables moved into u.cd */
- Mem *pMem;
-#endif /* local variables moved into u.cd */
- assert( pOp->p1>0 && pOp->p1<=p->nMem );
- u.cd.pMem = &p->aMem[pOp->p1];
- assert( (u.cd.pMem->flags & ~(MEM_Null|MEM_Agg))==0 );
- rc = sqlite3VdbeMemFinalize(u.cd.pMem, pOp->p4.pFunc);
- if( rc ){
- sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(u.cd.pMem));
- }
- sqlite3VdbeChangeEncoding(u.cd.pMem, encoding);
- UPDATE_MAX_BLOBSIZE(u.cd.pMem);
- if( sqlite3VdbeMemTooBig(u.cd.pMem) ){
- goto too_big;
- }
- break;
-}
-
-
-#if !defined(SQLITE_OMIT_VACUUM) && !defined(SQLITE_OMIT_ATTACH)
-/* Opcode: Vacuum * * * * *
-**
-** Vacuum the entire database. This opcode will cause other virtual
-** machines to be created and run. It may not be called from within
-** a transaction.
-*/
-case OP_Vacuum: {
- if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
- rc = sqlite3RunVacuum(&p->zErrMsg, db);
- if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
- break;
-}
-#endif
-
-#if !defined(SQLITE_OMIT_AUTOVACUUM)
-/* Opcode: IncrVacuum P1 P2 * * *
-**
-** Perform a single step of the incremental vacuum procedure on
-** the P1 database. If the vacuum has finished, jump to instruction
-** P2. Otherwise, fall through to the next instruction.
-*/
-case OP_IncrVacuum: { /* jump */
-#if 0 /* local variables moved into u.ce */
- Btree *pBt;
-#endif /* local variables moved into u.ce */
-
- assert( pOp->p1>=0 && pOp->p1<db->nDb );
- assert( (p->btreeMask & (1<<pOp->p1))!=0 );
- u.ce.pBt = db->aDb[pOp->p1].pBt;
- rc = sqlite3BtreeIncrVacuum(u.ce.pBt);
- if( rc==SQLITE_DONE ){
- pc = pOp->p2 - 1;
- rc = SQLITE_OK;
- }
- break;
-}
-#endif
-
-/* Opcode: Expire P1 * * * *
-**
-** Cause precompiled statements to become expired. An expired statement
-** fails with an error code of SQLITE_SCHEMA if it is ever executed
-** (via sqlite3_step()).
-**
-** If P1 is 0, then all SQL statements become expired. If P1 is non-zero,
-** then only the currently executing statement is affected.
-*/
-case OP_Expire: {
- if( !pOp->p1 ){
- sqlite3ExpirePreparedStatements(db);
- }else{
- p->expired = 1;
- }
- break;
-}
-
-#ifndef SQLITE_OMIT_SHARED_CACHE
-/* Opcode: TableLock P1 P2 P3 P4 *
-**
-** Obtain a lock on a particular table. This instruction is only used when
-** the shared-cache feature is enabled.
-**
-** P1 is the index of the database in sqlite3.aDb[] of the database
-** on which the lock is acquired. A readlock is obtained if P3==0 or
-** a write lock if P3==1.
-**
-** P2 contains the root-page of the table to lock.
-**
-** P4 contains a pointer to the name of the table being locked. This is only
-** used to generate an error message if the lock cannot be obtained.
-*/
-case OP_TableLock: {
- u8 isWriteLock = (u8)pOp->p3;
- if( isWriteLock || 0==(db->flags&SQLITE_ReadUncommitted) ){
- int p1 = pOp->p1;
- assert( p1>=0 && p1<db->nDb );
- assert( (p->btreeMask & (1<<p1))!=0 );
- assert( isWriteLock==0 || isWriteLock==1 );
- rc = sqlite3BtreeLockTable(db->aDb[p1].pBt, pOp->p2, isWriteLock);
- if( (rc&0xFF)==SQLITE_LOCKED ){
- const char *z = pOp->p4.z;
- sqlite3SetString(&p->zErrMsg, db, "database table is locked: %s", z);
- }
- }
- break;
-}
-#endif /* SQLITE_OMIT_SHARED_CACHE */
-
-#ifndef SQLITE_OMIT_VIRTUALTABLE
-/* Opcode: VBegin * * * P4 *
-**
-** P4 may be a pointer to an sqlite3_vtab structure. If so, call the
-** xBegin method for that table.
-**
-** Also, whether or not P4 is set, check that this is not being called from
-** within a callback to a virtual table xSync() method. If it is, the error
-** code will be set to SQLITE_LOCKED.
-*/
-case OP_VBegin: {
-#if 0 /* local variables moved into u.cf */
- VTable *pVTab;
-#endif /* local variables moved into u.cf */
- u.cf.pVTab = pOp->p4.pVtab;
- rc = sqlite3VtabBegin(db, u.cf.pVTab);
- if( u.cf.pVTab ){
- sqlite3DbFree(db, p->zErrMsg);
- p->zErrMsg = u.cf.pVTab->pVtab->zErrMsg;
- u.cf.pVTab->pVtab->zErrMsg = 0;
- }
- break;
-}
-#endif /* SQLITE_OMIT_VIRTUALTABLE */
-
-#ifndef SQLITE_OMIT_VIRTUALTABLE
-/* Opcode: VCreate P1 * * P4 *
-**
-** P4 is the name of a virtual table in database P1. Call the xCreate method
-** for that table.
-*/
-case OP_VCreate: {
- rc = sqlite3VtabCallCreate(db, pOp->p1, pOp->p4.z, &p->zErrMsg);
- break;
-}
-#endif /* SQLITE_OMIT_VIRTUALTABLE */
-
-#ifndef SQLITE_OMIT_VIRTUALTABLE
-/* Opcode: VDestroy P1 * * P4 *
-**
-** P4 is the name of a virtual table in database P1. Call the xDestroy method
-** of that table.
-*/
-case OP_VDestroy: {
- p->inVtabMethod = 2;
- rc = sqlite3VtabCallDestroy(db, pOp->p1, pOp->p4.z);
- p->inVtabMethod = 0;
- break;
-}
-#endif /* SQLITE_OMIT_VIRTUALTABLE */
-
-#ifndef SQLITE_OMIT_VIRTUALTABLE
-/* Opcode: VOpen P1 * * P4 *
-**
-** P4 is a pointer to a virtual table object, an sqlite3_vtab structure.
-** P1 is a cursor number. This opcode opens a cursor to the virtual
-** table and stores that cursor in P1.
-*/
-case OP_VOpen: {
-#if 0 /* local variables moved into u.cg */
- VdbeCursor *pCur;
- sqlite3_vtab_cursor *pVtabCursor;
- sqlite3_vtab *pVtab;
- sqlite3_module *pModule;
-#endif /* local variables moved into u.cg */
-
- u.cg.pCur = 0;
- u.cg.pVtabCursor = 0;
- u.cg.pVtab = pOp->p4.pVtab->pVtab;
- u.cg.pModule = (sqlite3_module *)u.cg.pVtab->pModule;
- assert(u.cg.pVtab && u.cg.pModule);
- if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
- rc = u.cg.pModule->xOpen(u.cg.pVtab, &u.cg.pVtabCursor);
- sqlite3DbFree(db, p->zErrMsg);
- p->zErrMsg = u.cg.pVtab->zErrMsg;
- u.cg.pVtab->zErrMsg = 0;
- if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
- if( SQLITE_OK==rc ){
- /* Initialize sqlite3_vtab_cursor base class */
- u.cg.pVtabCursor->pVtab = u.cg.pVtab;
-
- /* Initialise vdbe cursor object */
- u.cg.pCur = allocateCursor(p, pOp->p1, 0, -1, 0);
- if( u.cg.pCur ){
- u.cg.pCur->pVtabCursor = u.cg.pVtabCursor;
- u.cg.pCur->pModule = u.cg.pVtabCursor->pVtab->pModule;
- }else{
- db->mallocFailed = 1;
- u.cg.pModule->xClose(u.cg.pVtabCursor);
- }
- }
- break;
-}
-#endif /* SQLITE_OMIT_VIRTUALTABLE */
-
-#ifndef SQLITE_OMIT_VIRTUALTABLE
-/* Opcode: VFilter P1 P2 P3 P4 *
-**
-** P1 is a cursor opened using VOpen. P2 is an address to jump to if
-** the filtered result set is empty.
-**
-** P4 is either NULL or a string that was generated by the xBestIndex
-** method of the module. The interpretation of the P4 string is left
-** to the module implementation.
-**
-** This opcode invokes the xFilter method on the virtual table specified
-** by P1. The integer query plan parameter to xFilter is stored in register
-** P3. Register P3+1 stores the argc parameter to be passed to the
-** xFilter method. Registers P3+2..P3+1+argc are the argc
-** additional parameters which are passed to
-** xFilter as argv. Register P3+2 becomes argv[0] when passed to xFilter.
-**
-** A jump is made to P2 if the result set after filtering would be empty.
-*/
-case OP_VFilter: { /* jump */
-#if 0 /* local variables moved into u.ch */
- int nArg;
- int iQuery;
- const sqlite3_module *pModule;
- Mem *pQuery;
- Mem *pArgc;
- sqlite3_vtab_cursor *pVtabCursor;
- sqlite3_vtab *pVtab;
- VdbeCursor *pCur;
- int res;
- int i;
- Mem **apArg;
-#endif /* local variables moved into u.ch */
-
- u.ch.pQuery = &p->aMem[pOp->p3];
- u.ch.pArgc = &u.ch.pQuery[1];
- u.ch.pCur = p->apCsr[pOp->p1];
- REGISTER_TRACE(pOp->p3, u.ch.pQuery);
- assert( u.ch.pCur->pVtabCursor );
- u.ch.pVtabCursor = u.ch.pCur->pVtabCursor;
- u.ch.pVtab = u.ch.pVtabCursor->pVtab;
- u.ch.pModule = u.ch.pVtab->pModule;
-
- /* Grab the index number and argc parameters */
- assert( (u.ch.pQuery->flags&MEM_Int)!=0 && u.ch.pArgc->flags==MEM_Int );
- u.ch.nArg = (int)u.ch.pArgc->u.i;
- u.ch.iQuery = (int)u.ch.pQuery->u.i;
-
- /* Invoke the xFilter method */
- {
- u.ch.res = 0;
- u.ch.apArg = p->apArg;
- for(u.ch.i = 0; u.ch.i<u.ch.nArg; u.ch.i++){
- u.ch.apArg[u.ch.i] = &u.ch.pArgc[u.ch.i+1];
- storeTypeInfo(u.ch.apArg[u.ch.i], 0);
- }
-
- if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
- p->inVtabMethod = 1;
- rc = u.ch.pModule->xFilter(u.ch.pVtabCursor, u.ch.iQuery, pOp->p4.z, u.ch.nArg, u.ch.apArg);
- p->inVtabMethod = 0;
- sqlite3DbFree(db, p->zErrMsg);
- p->zErrMsg = u.ch.pVtab->zErrMsg;
- u.ch.pVtab->zErrMsg = 0;
- if( rc==SQLITE_OK ){
- u.ch.res = u.ch.pModule->xEof(u.ch.pVtabCursor);
- }
- if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
-
- if( u.ch.res ){
- pc = pOp->p2 - 1;
- }
- }
- u.ch.pCur->nullRow = 0;
-
- break;
-}
-#endif /* SQLITE_OMIT_VIRTUALTABLE */
-
-#ifndef SQLITE_OMIT_VIRTUALTABLE
-/* Opcode: VColumn P1 P2 P3 * *
-**
-** Store the value of the P2-th column of
-** the row of the virtual-table that the
-** P1 cursor is pointing to into register P3.
-*/
-case OP_VColumn: {
-#if 0 /* local variables moved into u.ci */
- sqlite3_vtab *pVtab;
- const sqlite3_module *pModule;
- Mem *pDest;
- sqlite3_context sContext;
-#endif /* local variables moved into u.ci */
-
- VdbeCursor *pCur = p->apCsr[pOp->p1];
- assert( pCur->pVtabCursor );
- assert( pOp->p3>0 && pOp->p3<=p->nMem );
- u.ci.pDest = &p->aMem[pOp->p3];
- if( pCur->nullRow ){
- sqlite3VdbeMemSetNull(u.ci.pDest);
- break;
- }
- u.ci.pVtab = pCur->pVtabCursor->pVtab;
- u.ci.pModule = u.ci.pVtab->pModule;
- assert( u.ci.pModule->xColumn );
- memset(&u.ci.sContext, 0, sizeof(u.ci.sContext));
-
- /* The output cell may already have a buffer allocated. Move
- ** the current contents to u.ci.sContext.s so in case the user-function
- ** can use the already allocated buffer instead of allocating a
- ** new one.
- */
- sqlite3VdbeMemMove(&u.ci.sContext.s, u.ci.pDest);
- MemSetTypeFlag(&u.ci.sContext.s, MEM_Null);
-
- if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
- rc = u.ci.pModule->xColumn(pCur->pVtabCursor, &u.ci.sContext, pOp->p2);
- sqlite3DbFree(db, p->zErrMsg);
- p->zErrMsg = u.ci.pVtab->zErrMsg;
- u.ci.pVtab->zErrMsg = 0;
- if( u.ci.sContext.isError ){
- rc = u.ci.sContext.isError;
- }
-
- /* Copy the result of the function to the P3 register. We
- ** do this regardless of whether or not an error occurred to ensure any
- ** dynamic allocation in u.ci.sContext.s (a Mem struct) is released.
- */
- sqlite3VdbeChangeEncoding(&u.ci.sContext.s, encoding);
- REGISTER_TRACE(pOp->p3, u.ci.pDest);
- sqlite3VdbeMemMove(u.ci.pDest, &u.ci.sContext.s);
- UPDATE_MAX_BLOBSIZE(u.ci.pDest);
-
- if( sqlite3SafetyOn(db) ){
- goto abort_due_to_misuse;
- }
- if( sqlite3VdbeMemTooBig(u.ci.pDest) ){
- goto too_big;
- }
- break;
-}
-#endif /* SQLITE_OMIT_VIRTUALTABLE */
-
-#ifndef SQLITE_OMIT_VIRTUALTABLE
-/* Opcode: VNext P1 P2 * * *
-**
-** Advance virtual table P1 to the next row in its result set and
-** jump to instruction P2. Or, if the virtual table has reached
-** the end of its result set, then fall through to the next instruction.
-*/
-case OP_VNext: { /* jump */
-#if 0 /* local variables moved into u.cj */
- sqlite3_vtab *pVtab;
- const sqlite3_module *pModule;
- int res;
- VdbeCursor *pCur;
-#endif /* local variables moved into u.cj */
-
- u.cj.res = 0;
- u.cj.pCur = p->apCsr[pOp->p1];
- assert( u.cj.pCur->pVtabCursor );
- if( u.cj.pCur->nullRow ){
- break;
- }
- u.cj.pVtab = u.cj.pCur->pVtabCursor->pVtab;
- u.cj.pModule = u.cj.pVtab->pModule;
- assert( u.cj.pModule->xNext );
-
- /* Invoke the xNext() method of the module. There is no way for the
- ** underlying implementation to return an error if one occurs during
- ** xNext(). Instead, if an error occurs, true is returned (indicating that
- ** data is available) and the error code returned when xColumn or
- ** some other method is next invoked on the save virtual table cursor.
- */
- if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
- p->inVtabMethod = 1;
- rc = u.cj.pModule->xNext(u.cj.pCur->pVtabCursor);
- p->inVtabMethod = 0;
- sqlite3DbFree(db, p->zErrMsg);
- p->zErrMsg = u.cj.pVtab->zErrMsg;
- u.cj.pVtab->zErrMsg = 0;
- if( rc==SQLITE_OK ){
- u.cj.res = u.cj.pModule->xEof(u.cj.pCur->pVtabCursor);
- }
- if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
-
- if( !u.cj.res ){
- /* If there is data, jump to P2 */
- pc = pOp->p2 - 1;
- }
- break;
-}
-#endif /* SQLITE_OMIT_VIRTUALTABLE */
-
-#ifndef SQLITE_OMIT_VIRTUALTABLE
-/* Opcode: VRename P1 * * P4 *
-**
-** P4 is a pointer to a virtual table object, an sqlite3_vtab structure.
-** This opcode invokes the corresponding xRename method. The value
-** in register P1 is passed as the zName argument to the xRename method.
-*/
-case OP_VRename: {
-#if 0 /* local variables moved into u.ck */
- sqlite3_vtab *pVtab;
- Mem *pName;
-#endif /* local variables moved into u.ck */
-
- u.ck.pVtab = pOp->p4.pVtab->pVtab;
- u.ck.pName = &p->aMem[pOp->p1];
- assert( u.ck.pVtab->pModule->xRename );
- REGISTER_TRACE(pOp->p1, u.ck.pName);
- assert( u.ck.pName->flags & MEM_Str );
- if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
- rc = u.ck.pVtab->pModule->xRename(u.ck.pVtab, u.ck.pName->z);
- sqlite3DbFree(db, p->zErrMsg);
- p->zErrMsg = u.ck.pVtab->zErrMsg;
- u.ck.pVtab->zErrMsg = 0;
- if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
-
- break;
-}
-#endif
-
-#ifndef SQLITE_OMIT_VIRTUALTABLE
-/* Opcode: VUpdate P1 P2 P3 P4 *
-**
-** P4 is a pointer to a virtual table object, an sqlite3_vtab structure.
-** This opcode invokes the corresponding xUpdate method. P2 values
-** are contiguous memory cells starting at P3 to pass to the xUpdate
-** invocation. The value in register (P3+P2-1) corresponds to the
-** p2th element of the argv array passed to xUpdate.
-**
-** The xUpdate method will do a DELETE or an INSERT or both.
-** The argv[0] element (which corresponds to memory cell P3)
-** is the rowid of a row to delete. If argv[0] is NULL then no
-** deletion occurs. The argv[1] element is the rowid of the new
-** row. This can be NULL to have the virtual table select the new
-** rowid for itself. The subsequent elements in the array are
-** the values of columns in the new row.
-**
-** If P2==1 then no insert is performed. argv[0] is the rowid of
-** a row to delete.
-**
-** P1 is a boolean flag. If it is set to true and the xUpdate call
-** is successful, then the value returned by sqlite3_last_insert_rowid()
-** is set to the value of the rowid for the row just inserted.
-*/
-case OP_VUpdate: {
-#if 0 /* local variables moved into u.cl */
- sqlite3_vtab *pVtab;
- sqlite3_module *pModule;
- int nArg;
- int i;
- sqlite_int64 rowid;
- Mem **apArg;
- Mem *pX;
-#endif /* local variables moved into u.cl */
-
- u.cl.pVtab = pOp->p4.pVtab->pVtab;
- u.cl.pModule = (sqlite3_module *)u.cl.pVtab->pModule;
- u.cl.nArg = pOp->p2;
- assert( pOp->p4type==P4_VTAB );
- if( ALWAYS(u.cl.pModule->xUpdate) ){
- u.cl.apArg = p->apArg;
- u.cl.pX = &p->aMem[pOp->p3];
- for(u.cl.i=0; u.cl.i<u.cl.nArg; u.cl.i++){
- storeTypeInfo(u.cl.pX, 0);
- u.cl.apArg[u.cl.i] = u.cl.pX;
- u.cl.pX++;
- }
- if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
- rc = u.cl.pModule->xUpdate(u.cl.pVtab, u.cl.nArg, u.cl.apArg, &u.cl.rowid);
- sqlite3DbFree(db, p->zErrMsg);
- p->zErrMsg = u.cl.pVtab->zErrMsg;
- u.cl.pVtab->zErrMsg = 0;
- if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
- if( rc==SQLITE_OK && pOp->p1 ){
- assert( u.cl.nArg>1 && u.cl.apArg[0] && (u.cl.apArg[0]->flags&MEM_Null) );
- db->lastRowid = u.cl.rowid;
- }
- p->nChange++;
- }
- break;
-}
-#endif /* SQLITE_OMIT_VIRTUALTABLE */
-
-#ifndef SQLITE_OMIT_PAGER_PRAGMAS
-/* Opcode: Pagecount P1 P2 * * *
-**
-** Write the current number of pages in database P1 to memory cell P2.
-*/
-case OP_Pagecount: { /* out2-prerelease */
-#if 0 /* local variables moved into u.cm */
- int p1;
- int nPage;
- Pager *pPager;
-#endif /* local variables moved into u.cm */
-
- u.cm.p1 = pOp->p1;
- u.cm.pPager = sqlite3BtreePager(db->aDb[u.cm.p1].pBt);
- rc = sqlite3PagerPagecount(u.cm.pPager, &u.cm.nPage);
- /* OP_Pagecount is always called from within a read transaction. The
- ** page count has already been successfully read and cached. So the
- ** sqlite3PagerPagecount() call above cannot fail. */
- if( ALWAYS(rc==SQLITE_OK) ){
- pOut->flags = MEM_Int;
- pOut->u.i = u.cm.nPage;
- }
- break;
-}
-#endif
-
-#ifndef SQLITE_OMIT_TRACE
-/* Opcode: Trace * * * P4 *
-**
-** If tracing is enabled (by the sqlite3_trace()) interface, then
-** the UTF-8 string contained in P4 is emitted on the trace callback.
-*/
-case OP_Trace: {
-#if 0 /* local variables moved into u.cn */
- char *zTrace;
-#endif /* local variables moved into u.cn */
-
- u.cn.zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql);
- if( u.cn.zTrace ){
- if( db->xTrace ){
- db->xTrace(db->pTraceArg, u.cn.zTrace);
- }
-#ifdef SQLITE_DEBUG
- if( (db->flags & SQLITE_SqlTrace)!=0 ){
- sqlite3DebugPrintf("SQL-trace: %s\n", u.cn.zTrace);
- }
-#endif /* SQLITE_DEBUG */
- }
- break;
-}
-#endif
-
-
-/* Opcode: Noop * * * * *
-**
-** Do nothing. This instruction is often useful as a jump
-** destination.
-*/
-/*
-** The magic Explain opcode are only inserted when explain==2 (which
-** is to say when the EXPLAIN QUERY PLAN syntax is used.)
-** This opcode records information from the optimizer. It is the
-** the same as a no-op. This opcodesnever appears in a real VM program.
-*/
-default: { /* This is really OP_Noop and OP_Explain */
- break;
-}
-
-/*****************************************************************************
-** The cases of the switch statement above this line should all be indented
-** by 6 spaces. But the left-most 6 spaces have been removed to improve the
-** readability. From this point on down, the normal indentation rules are
-** restored.
-*****************************************************************************/
- }
-
-#ifdef VDBE_PROFILE
- {
- u64 elapsed = sqlite3Hwtime() - start;
- pOp->cycles += elapsed;
- pOp->cnt++;
-#if 0
- fprintf(stdout, "%10llu ", elapsed);
- sqlite3VdbePrintOp(stdout, origPc, &p->aOp[origPc]);
-#endif
- }
-#endif
-
- /* The following code adds nothing to the actual functionality
- ** of the program. It is only here for testing and debugging.
- ** On the other hand, it does burn CPU cycles every time through
- ** the evaluator loop. So we can leave it out when NDEBUG is defined.
- */
-#ifndef NDEBUG
- assert( pc>=-1 && pc<p->nOp );
-
-#ifdef SQLITE_DEBUG
- if( p->trace ){
- if( rc!=0 ) fprintf(p->trace,"rc=%d\n",rc);
- if( opProperty & OPFLG_OUT2_PRERELEASE ){
- registerTrace(p->trace, pOp->p2, pOut);
- }
- if( opProperty & OPFLG_OUT3 ){
- registerTrace(p->trace, pOp->p3, pOut);
- }
- }
-#endif /* SQLITE_DEBUG */
-#endif /* NDEBUG */
- } /* The end of the for(;;) loop the loops through opcodes */
-
- /* If we reach this point, it means that execution is finished with
- ** an error of some kind.
- */
-vdbe_error_halt:
- assert( rc );
- p->rc = rc;
- sqlite3VdbeHalt(p);
- if( rc==SQLITE_IOERR_NOMEM ) db->mallocFailed = 1;
- rc = SQLITE_ERROR;
-
- /* This is the only way out of this procedure. We have to
- ** release the mutexes on btrees that were acquired at the
- ** top. */
-vdbe_return:
- sqlite3BtreeMutexArrayLeave(&p->aMutex);
- return rc;
-
- /* Jump to here if a string or blob larger than SQLITE_MAX_LENGTH
- ** is encountered.
- */
-too_big:
- sqlite3SetString(&p->zErrMsg, db, "string or blob too big");
- rc = SQLITE_TOOBIG;
- goto vdbe_error_halt;
-
- /* Jump to here if a malloc() fails.
- */
-no_mem:
- db->mallocFailed = 1;
- sqlite3SetString(&p->zErrMsg, db, "out of memory");
- rc = SQLITE_NOMEM;
- goto vdbe_error_halt;
-
- /* Jump to here for an SQLITE_MISUSE error.
- */
-abort_due_to_misuse:
- rc = SQLITE_MISUSE;
- /* Fall thru into abort_due_to_error */
-
- /* Jump to here for any other kind of fatal error. The "rc" variable
- ** should hold the error number.
- */
-abort_due_to_error:
- assert( p->zErrMsg==0 );
- if( db->mallocFailed ) rc = SQLITE_NOMEM;
- if( rc!=SQLITE_IOERR_NOMEM ){
- sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3ErrStr(rc));
- }
- goto vdbe_error_halt;
-
- /* Jump to here if the sqlite3_interrupt() API sets the interrupt
- ** flag.
- */
-abort_due_to_interrupt:
- assert( db->u1.isInterrupted );
- rc = SQLITE_INTERRUPT;
- p->rc = rc;
- sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3ErrStr(rc));
- goto vdbe_error_halt;
-}
-
-/************** End of vdbe.c ************************************************/
-/************** Begin file vdbeblob.c ****************************************/
-/*
-** 2007 May 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 code used to implement incremental BLOB I/O.
-**
-** $Id: vdbeblob.c,v 1.35 2009/07/02 07:47:33 danielk1977 Exp $
-*/
-
-
-#ifndef SQLITE_OMIT_INCRBLOB
-
-/*
-** Valid sqlite3_blob* handles point to Incrblob structures.
-*/
-typedef struct Incrblob Incrblob;
-struct Incrblob {
- int flags; /* Copy of "flags" passed to sqlite3_blob_open() */
- int nByte; /* Size of open blob, in bytes */
- int iOffset; /* Byte offset of blob in cursor data */
- BtCursor *pCsr; /* Cursor pointing at blob row */
- sqlite3_stmt *pStmt; /* Statement holding cursor open */
- sqlite3 *db; /* The associated database */
-};
-
-/*
-** Open a blob handle.
-*/
-SQLITE_API int sqlite3_blob_open(
- sqlite3* db, /* The database connection */
- const char *zDb, /* The attached database containing the blob */
- const char *zTable, /* The table containing the blob */
- const char *zColumn, /* The column containing the blob */
- sqlite_int64 iRow, /* The row containing the glob */
- int flags, /* True -> read/write access, false -> read-only */
- sqlite3_blob **ppBlob /* Handle for accessing the blob returned here */
-){
- int nAttempt = 0;
- int iCol; /* Index of zColumn in row-record */
-
- /* This VDBE program seeks a btree cursor to the identified
- ** db/table/row entry. The reason for using a vdbe program instead
- ** of writing code to use the b-tree layer directly is that the
- ** vdbe program will take advantage of the various transaction,
- ** locking and error handling infrastructure built into the vdbe.
- **
- ** After seeking the cursor, the vdbe executes an OP_ResultRow.
- ** Code external to the Vdbe then "borrows" the b-tree cursor and
- ** uses it to implement the blob_read(), blob_write() and
- ** blob_bytes() functions.
- **
- ** The sqlite3_blob_close() function finalizes the vdbe program,
- ** which closes the b-tree cursor and (possibly) commits the
- ** transaction.
- */
- static const VdbeOpList openBlob[] = {
- {OP_Transaction, 0, 0, 0}, /* 0: Start a transaction */
- {OP_VerifyCookie, 0, 0, 0}, /* 1: Check the schema cookie */
- {OP_TableLock, 0, 0, 0}, /* 2: Acquire a read or write lock */
-
- /* One of the following two instructions is replaced by an OP_Noop. */
- {OP_OpenRead, 0, 0, 0}, /* 3: Open cursor 0 for reading */
- {OP_OpenWrite, 0, 0, 0}, /* 4: Open cursor 0 for read/write */
-
- {OP_Variable, 1, 1, 1}, /* 5: Push the rowid to the stack */
- {OP_NotExists, 0, 9, 1}, /* 6: Seek the cursor */
- {OP_Column, 0, 0, 1}, /* 7 */
- {OP_ResultRow, 1, 0, 0}, /* 8 */
- {OP_Close, 0, 0, 0}, /* 9 */
- {OP_Halt, 0, 0, 0}, /* 10 */
- };
-
- Vdbe *v = 0;
- int rc = SQLITE_OK;
- char *zErr = 0;
- Table *pTab;
- Parse *pParse;
-
- *ppBlob = 0;
- sqlite3_mutex_enter(db->mutex);
- pParse = sqlite3StackAllocRaw(db, sizeof(*pParse));
- if( pParse==0 ){
- rc = SQLITE_NOMEM;
- goto blob_open_out;
- }
- do {
- memset(pParse, 0, sizeof(Parse));
- pParse->db = db;
-
- if( sqlite3SafetyOn(db) ){
- sqlite3DbFree(db, zErr);
- sqlite3StackFree(db, pParse);
- sqlite3_mutex_leave(db->mutex);
- return SQLITE_MISUSE;
- }
-
- sqlite3BtreeEnterAll(db);
- pTab = sqlite3LocateTable(pParse, 0, zTable, zDb);
- if( pTab && IsVirtual(pTab) ){
- pTab = 0;
- sqlite3ErrorMsg(pParse, "cannot open virtual table: %s", zTable);
- }
-#ifndef SQLITE_OMIT_VIEW
- if( pTab && pTab->pSelect ){
- pTab = 0;
- sqlite3ErrorMsg(pParse, "cannot open view: %s", zTable);
- }
-#endif
- if( !pTab ){
- if( pParse->zErrMsg ){
- sqlite3DbFree(db, zErr);
- zErr = pParse->zErrMsg;
- pParse->zErrMsg = 0;
- }
- rc = SQLITE_ERROR;
- (void)sqlite3SafetyOff(db);
- sqlite3BtreeLeaveAll(db);
- goto blob_open_out;
- }
-
- /* Now search pTab for the exact column. */
- for(iCol=0; iCol < pTab->nCol; iCol++) {
- if( sqlite3StrICmp(pTab->aCol[iCol].zName, zColumn)==0 ){
- break;
- }
- }
- if( iCol==pTab->nCol ){
- sqlite3DbFree(db, zErr);
- zErr = sqlite3MPrintf(db, "no such column: \"%s\"", zColumn);
- rc = SQLITE_ERROR;
- (void)sqlite3SafetyOff(db);
- sqlite3BtreeLeaveAll(db);
- goto blob_open_out;
- }
-
- /* If the value is being opened for writing, check that the
- ** column is not indexed. It is against the rules to open an
- ** indexed column for writing.
- */
- if( flags ){
- Index *pIdx;
- for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
- int j;
- for(j=0; j<pIdx->nColumn; j++){
- if( pIdx->aiColumn[j]==iCol ){
- sqlite3DbFree(db, zErr);
- zErr = sqlite3MPrintf(db,
- "cannot open indexed column for writing");
- rc = SQLITE_ERROR;
- (void)sqlite3SafetyOff(db);
- sqlite3BtreeLeaveAll(db);
- goto blob_open_out;
- }
- }
- }
- }
-
- v = sqlite3VdbeCreate(db);
- if( v ){
- int iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
- sqlite3VdbeAddOpList(v, sizeof(openBlob)/sizeof(VdbeOpList), openBlob);
- flags = !!flags; /* flags = (flags ? 1 : 0); */
-
- /* Configure the OP_Transaction */
- sqlite3VdbeChangeP1(v, 0, iDb);
- sqlite3VdbeChangeP2(v, 0, flags);
-
- /* Configure the OP_VerifyCookie */
- sqlite3VdbeChangeP1(v, 1, iDb);
- sqlite3VdbeChangeP2(v, 1, pTab->pSchema->schema_cookie);
-
- /* Make sure a mutex is held on the table to be accessed */
- sqlite3VdbeUsesBtree(v, iDb);
-
- /* Configure the OP_TableLock instruction */
- sqlite3VdbeChangeP1(v, 2, iDb);
- sqlite3VdbeChangeP2(v, 2, pTab->tnum);
- sqlite3VdbeChangeP3(v, 2, flags);
- sqlite3VdbeChangeP4(v, 2, pTab->zName, P4_TRANSIENT);
-
- /* Remove either the OP_OpenWrite or OpenRead. Set the P2
- ** parameter of the other to pTab->tnum. */
- sqlite3VdbeChangeToNoop(v, 4 - flags, 1);
- sqlite3VdbeChangeP2(v, 3 + flags, pTab->tnum);
- sqlite3VdbeChangeP3(v, 3 + flags, iDb);
-
- /* Configure the number of columns. Configure the cursor to
- ** think that the table has one more column than it really
- ** does. An OP_Column to retrieve this imaginary column will
- ** always return an SQL NULL. This is useful because it means
- ** we can invoke OP_Column to fill in the vdbe cursors type
- ** and offset cache without causing any IO.
- */
- sqlite3VdbeChangeP4(v, 3+flags, SQLITE_INT_TO_PTR(pTab->nCol+1),P4_INT32);
- sqlite3VdbeChangeP2(v, 7, pTab->nCol);
- if( !db->mallocFailed ){
- sqlite3VdbeMakeReady(v, 1, 1, 1, 0, 0, 0);
- }
- }
-
- sqlite3BtreeLeaveAll(db);
- rc = sqlite3SafetyOff(db);
- if( NEVER(rc!=SQLITE_OK) || db->mallocFailed ){
- goto blob_open_out;
- }
-
- sqlite3_bind_int64((sqlite3_stmt *)v, 1, iRow);
- rc = sqlite3_step((sqlite3_stmt *)v);
- if( rc!=SQLITE_ROW ){
- nAttempt++;
- rc = sqlite3_finalize((sqlite3_stmt *)v);
- sqlite3DbFree(db, zErr);
- zErr = sqlite3MPrintf(db, sqlite3_errmsg(db));
- v = 0;
- }
- } while( nAttempt<5 && rc==SQLITE_SCHEMA );
-
- if( rc==SQLITE_ROW ){
- /* The row-record has been opened successfully. Check that the
- ** column in question contains text or a blob. If it contains
- ** text, it is up to the caller to get the encoding right.
- */
- Incrblob *pBlob;
- u32 type = v->apCsr[0]->aType[iCol];
-
- if( type<12 ){
- sqlite3DbFree(db, zErr);
- zErr = sqlite3MPrintf(db, "cannot open value of type %s",
- type==0?"null": type==7?"real": "integer"
- );
- rc = SQLITE_ERROR;
- goto blob_open_out;
- }
- pBlob = (Incrblob *)sqlite3DbMallocZero(db, sizeof(Incrblob));
- if( db->mallocFailed ){
- sqlite3DbFree(db, pBlob);
- goto blob_open_out;
- }
- pBlob->flags = flags;
- pBlob->pCsr = v->apCsr[0]->pCursor;
- sqlite3BtreeEnterCursor(pBlob->pCsr);
- sqlite3BtreeCacheOverflow(pBlob->pCsr);
- sqlite3BtreeLeaveCursor(pBlob->pCsr);
- pBlob->pStmt = (sqlite3_stmt *)v;
- pBlob->iOffset = v->apCsr[0]->aOffset[iCol];
- pBlob->nByte = sqlite3VdbeSerialTypeLen(type);
- pBlob->db = db;
- *ppBlob = (sqlite3_blob *)pBlob;
- rc = SQLITE_OK;
- }else if( rc==SQLITE_OK ){
- sqlite3DbFree(db, zErr);
- zErr = sqlite3MPrintf(db, "no such rowid: %lld", iRow);
- rc = SQLITE_ERROR;
- }
-
-blob_open_out:
- if( v && (rc!=SQLITE_OK || db->mallocFailed) ){
- sqlite3VdbeFinalize(v);
- }
- sqlite3Error(db, rc, zErr);
- sqlite3DbFree(db, zErr);
- sqlite3StackFree(db, pParse);
- rc = sqlite3ApiExit(db, rc);
- sqlite3_mutex_leave(db->mutex);
- return rc;
-}
-
-/*
-** Close a blob handle that was previously created using
-** sqlite3_blob_open().
-*/
-SQLITE_API int sqlite3_blob_close(sqlite3_blob *pBlob){
- Incrblob *p = (Incrblob *)pBlob;
- int rc;
- sqlite3 *db;
-
- if( p ){
- db = p->db;
- sqlite3_mutex_enter(db->mutex);
- rc = sqlite3_finalize(p->pStmt);
- sqlite3DbFree(db, p);
- sqlite3_mutex_leave(db->mutex);
- }else{
- rc = SQLITE_OK;
- }
- return rc;
-}
-
-/*
-** Perform a read or write operation on a blob
-*/
-static int blobReadWrite(
- sqlite3_blob *pBlob,
- void *z,
- int n,
- int iOffset,
- int (*xCall)(BtCursor*, u32, u32, void*)
-){
- int rc;
- Incrblob *p = (Incrblob *)pBlob;
- Vdbe *v;
- sqlite3 *db;
-
- if( p==0 ) return SQLITE_MISUSE;
- db = p->db;
- sqlite3_mutex_enter(db->mutex);
- v = (Vdbe*)p->pStmt;
-
- if( n<0 || iOffset<0 || (iOffset+n)>p->nByte ){
- /* Request is out of range. Return a transient error. */
- rc = SQLITE_ERROR;
- sqlite3Error(db, SQLITE_ERROR, 0);
- } else if( v==0 ){
- /* If there is no statement handle, then the blob-handle has
- ** already been invalidated. Return SQLITE_ABORT in this case.
- */
- rc = SQLITE_ABORT;
- }else{
- /* Call either BtreeData() or BtreePutData(). If SQLITE_ABORT is
- ** returned, clean-up the statement handle.
- */
- assert( db == v->db );
- sqlite3BtreeEnterCursor(p->pCsr);
- rc = xCall(p->pCsr, iOffset+p->iOffset, n, z);
- sqlite3BtreeLeaveCursor(p->pCsr);
- if( rc==SQLITE_ABORT ){
- sqlite3VdbeFinalize(v);
- p->pStmt = 0;
- }else{
- db->errCode = rc;
- v->rc = rc;
- }
- }
- rc = sqlite3ApiExit(db, rc);
- sqlite3_mutex_leave(db->mutex);
- return rc;
-}
-
-/*
-** Read data from a blob handle.
-*/
-SQLITE_API int sqlite3_blob_read(sqlite3_blob *pBlob, void *z, int n, int iOffset){
- return blobReadWrite(pBlob, z, n, iOffset, sqlite3BtreeData);
-}
-
-/*
-** Write data to a blob handle.
-*/
-SQLITE_API int sqlite3_blob_write(sqlite3_blob *pBlob, const void *z, int n, int iOffset){
- return blobReadWrite(pBlob, (void *)z, n, iOffset, sqlite3BtreePutData);
-}
-
-/*
-** Query a blob handle for the size of the data.
-**
-** The Incrblob.nByte field is fixed for the lifetime of the Incrblob
-** so no mutex is required for access.
-*/
-SQLITE_API int sqlite3_blob_bytes(sqlite3_blob *pBlob){
- Incrblob *p = (Incrblob *)pBlob;
- return p ? p->nByte : 0;
-}
-
-#endif /* #ifndef SQLITE_OMIT_INCRBLOB */
-
-/************** End of vdbeblob.c ********************************************/
-/************** Begin file journal.c *****************************************/
-/*
-** 2007 August 22
-**
-** 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.
-**
-*************************************************************************
-**
-** @(#) $Id: journal.c,v 1.9 2009/01/20 17:06:27 danielk1977 Exp $
-*/
-
-#ifdef SQLITE_ENABLE_ATOMIC_WRITE
-
-/*
-** This file implements a special kind of sqlite3_file object used
-** by SQLite to create journal files if the atomic-write optimization
-** is enabled.
-**
-** The distinctive characteristic of this sqlite3_file is that the
-** actual on disk file is created lazily. When the file is created,
-** the caller specifies a buffer size for an in-memory buffer to
-** be used to service read() and write() requests. The actual file
-** on disk is not created or populated until either:
-**
-** 1) The in-memory representation grows too large for the allocated
-** buffer, or
-** 2) The sqlite3JournalCreate() function is called.
-*/
-
-
-
-/*
-** A JournalFile object is a subclass of sqlite3_file used by
-** as an open file handle for journal files.
-*/
-struct JournalFile {
- sqlite3_io_methods *pMethod; /* I/O methods on journal files */
- int nBuf; /* Size of zBuf[] in bytes */
- char *zBuf; /* Space to buffer journal writes */
- int iSize; /* Amount of zBuf[] currently used */
- int flags; /* xOpen flags */
- sqlite3_vfs *pVfs; /* The "real" underlying VFS */
- sqlite3_file *pReal; /* The "real" underlying file descriptor */
- const char *zJournal; /* Name of the journal file */
-};
-typedef struct JournalFile JournalFile;
-
-/*
-** If it does not already exists, create and populate the on-disk file
-** for JournalFile p.
-*/
-static int createFile(JournalFile *p){
- int rc = SQLITE_OK;
- if( !p->pReal ){
- sqlite3_file *pReal = (sqlite3_file *)&p[1];
- rc = sqlite3OsOpen(p->pVfs, p->zJournal, pReal, p->flags, 0);
- if( rc==SQLITE_OK ){
- p->pReal = pReal;
- if( p->iSize>0 ){
- assert(p->iSize<=p->nBuf);
- rc = sqlite3OsWrite(p->pReal, p->zBuf, p->iSize, 0);
- }
- }
- }
- return rc;
-}
-
-/*
-** Close the file.
-*/
-static int jrnlClose(sqlite3_file *pJfd){
- JournalFile *p = (JournalFile *)pJfd;
- if( p->pReal ){
- sqlite3OsClose(p->pReal);
- }
- sqlite3_free(p->zBuf);
- return SQLITE_OK;
-}
-
-/*
-** Read data from the file.
-*/
-static int jrnlRead(
- sqlite3_file *pJfd, /* The journal file from which to read */
- void *zBuf, /* Put the results here */
- int iAmt, /* Number of bytes to read */
- sqlite_int64 iOfst /* Begin reading at this offset */
-){
- int rc = SQLITE_OK;
- JournalFile *p = (JournalFile *)pJfd;
- if( p->pReal ){
- rc = sqlite3OsRead(p->pReal, zBuf, iAmt, iOfst);
- }else if( (iAmt+iOfst)>p->iSize ){
- rc = SQLITE_IOERR_SHORT_READ;
- }else{
- memcpy(zBuf, &p->zBuf[iOfst], iAmt);
- }
- return rc;
-}
-
-/*
-** Write data to the file.
-*/
-static int jrnlWrite(
- sqlite3_file *pJfd, /* The journal file into which to write */
- const void *zBuf, /* Take data to be written from here */
- int iAmt, /* Number of bytes to write */
- sqlite_int64 iOfst /* Begin writing at this offset into the file */
-){
- int rc = SQLITE_OK;
- JournalFile *p = (JournalFile *)pJfd;
- if( !p->pReal && (iOfst+iAmt)>p->nBuf ){
- rc = createFile(p);
- }
- if( rc==SQLITE_OK ){
- if( p->pReal ){
- rc = sqlite3OsWrite(p->pReal, zBuf, iAmt, iOfst);
- }else{
- memcpy(&p->zBuf[iOfst], zBuf, iAmt);
- if( p->iSize<(iOfst+iAmt) ){
- p->iSize = (iOfst+iAmt);
- }
- }
- }
- return rc;
-}
-
-/*
-** Truncate the file.
-*/
-static int jrnlTruncate(sqlite3_file *pJfd, sqlite_int64 size){
- int rc = SQLITE_OK;
- JournalFile *p = (JournalFile *)pJfd;
- if( p->pReal ){
- rc = sqlite3OsTruncate(p->pReal, size);
- }else if( size<p->iSize ){
- p->iSize = size;
- }
- return rc;
-}
-
-/*
-** Sync the file.
-*/
-static int jrnlSync(sqlite3_file *pJfd, int flags){
- int rc;
- JournalFile *p = (JournalFile *)pJfd;
- if( p->pReal ){
- rc = sqlite3OsSync(p->pReal, flags);
- }else{
- rc = SQLITE_OK;
- }
- return rc;
-}
-
-/*
-** Query the size of the file in bytes.
-*/
-static int jrnlFileSize(sqlite3_file *pJfd, sqlite_int64 *pSize){
- int rc = SQLITE_OK;
- JournalFile *p = (JournalFile *)pJfd;
- if( p->pReal ){
- rc = sqlite3OsFileSize(p->pReal, pSize);
- }else{
- *pSize = (sqlite_int64) p->iSize;
- }
- return rc;
-}
-
-/*
-** Table of methods for JournalFile sqlite3_file object.
-*/
-static struct sqlite3_io_methods JournalFileMethods = {
- 1, /* iVersion */
- jrnlClose, /* xClose */
- jrnlRead, /* xRead */
- jrnlWrite, /* xWrite */
- jrnlTruncate, /* xTruncate */
- jrnlSync, /* xSync */
- jrnlFileSize, /* xFileSize */
- 0, /* xLock */
- 0, /* xUnlock */
- 0, /* xCheckReservedLock */
- 0, /* xFileControl */
- 0, /* xSectorSize */
- 0 /* xDeviceCharacteristics */
-};
-
-/*
-** Open a journal file.
-*/
-SQLITE_PRIVATE int sqlite3JournalOpen(
- sqlite3_vfs *pVfs, /* The VFS to use for actual file I/O */
- const char *zName, /* Name of the journal file */
- sqlite3_file *pJfd, /* Preallocated, blank file handle */
- int flags, /* Opening flags */
- int nBuf /* Bytes buffered before opening the file */
-){
- JournalFile *p = (JournalFile *)pJfd;
- memset(p, 0, sqlite3JournalSize(pVfs));
- if( nBuf>0 ){
- p->zBuf = sqlite3MallocZero(nBuf);
- if( !p->zBuf ){
- return SQLITE_NOMEM;
- }
- }else{
- return sqlite3OsOpen(pVfs, zName, pJfd, flags, 0);
- }
- p->pMethod = &JournalFileMethods;
- p->nBuf = nBuf;
- p->flags = flags;
- p->zJournal = zName;
- p->pVfs = pVfs;
- return SQLITE_OK;
-}
-
-/*
-** If the argument p points to a JournalFile structure, and the underlying
-** file has not yet been created, create it now.
-*/
-SQLITE_PRIVATE int sqlite3JournalCreate(sqlite3_file *p){
- if( p->pMethods!=&JournalFileMethods ){
- return SQLITE_OK;
- }
- return createFile((JournalFile *)p);
-}
-
-/*
-** Return the number of bytes required to store a JournalFile that uses vfs
-** pVfs to create the underlying on-disk files.
-*/
-SQLITE_PRIVATE int sqlite3JournalSize(sqlite3_vfs *pVfs){
- return (pVfs->szOsFile+sizeof(JournalFile));
-}
-#endif
-
-/************** End of journal.c *********************************************/
-/************** Begin file memjournal.c **************************************/
-/*
-** 2008 October 7
-**
-** 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 code use to implement an in-memory rollback journal.
-** The in-memory rollback journal is used to journal transactions for
-** ":memory:" databases and when the journal_mode=MEMORY pragma is used.
-**
-** @(#) $Id: memjournal.c,v 1.12 2009/05/04 11:42:30 danielk1977 Exp $
-*/
-
-/* Forward references to internal structures */
-typedef struct MemJournal MemJournal;
-typedef struct FilePoint FilePoint;
-typedef struct FileChunk FileChunk;
-
-/* Space to hold the rollback journal is allocated in increments of
-** this many bytes.
-**
-** The size chosen is a little less than a power of two. That way,
-** the FileChunk object will have a size that almost exactly fills
-** a power-of-two allocation. This mimimizes wasted space in power-of-two
-** memory allocators.
-*/
-#define JOURNAL_CHUNKSIZE ((int)(1024-sizeof(FileChunk*)))
-
-/* Macro to find the minimum of two numeric values.
-*/
-#ifndef MIN
-# define MIN(x,y) ((x)<(y)?(x):(y))
-#endif
-
-/*
-** The rollback journal is composed of a linked list of these structures.
-*/
-struct FileChunk {
- FileChunk *pNext; /* Next chunk in the journal */
- u8 zChunk[JOURNAL_CHUNKSIZE]; /* Content of this chunk */
-};
-
-/*
-** An instance of this object serves as a cursor into the rollback journal.
-** The cursor can be either for reading or writing.
-*/
-struct FilePoint {
- sqlite3_int64 iOffset; /* Offset from the beginning of the file */
- FileChunk *pChunk; /* Specific chunk into which cursor points */
-};
-
-/*
-** This subclass is a subclass of sqlite3_file. Each open memory-journal
-** is an instance of this class.
-*/
-struct MemJournal {
- sqlite3_io_methods *pMethod; /* Parent class. MUST BE FIRST */
- FileChunk *pFirst; /* Head of in-memory chunk-list */
- FilePoint endpoint; /* Pointer to the end of the file */
- FilePoint readpoint; /* Pointer to the end of the last xRead() */
-};
-
-/*
-** Read data from the in-memory journal file. This is the implementation
-** of the sqlite3_vfs.xRead method.
-*/
-static int memjrnlRead(
- sqlite3_file *pJfd, /* The journal file from which to read */
- void *zBuf, /* Put the results here */
- int iAmt, /* Number of bytes to read */
- sqlite_int64 iOfst /* Begin reading at this offset */
-){
- MemJournal *p = (MemJournal *)pJfd;
- u8 *zOut = zBuf;
- int nRead = iAmt;
- int iChunkOffset;
- FileChunk *pChunk;
-
- /* SQLite never tries to read past the end of a rollback journal file */
- assert( iOfst+iAmt<=p->endpoint.iOffset );
-
- if( p->readpoint.iOffset!=iOfst || iOfst==0 ){
- sqlite3_int64 iOff = 0;
- for(pChunk=p->pFirst;
- ALWAYS(pChunk) && (iOff+JOURNAL_CHUNKSIZE)<=iOfst;
- pChunk=pChunk->pNext
- ){
- iOff += JOURNAL_CHUNKSIZE;
- }
- }else{
- pChunk = p->readpoint.pChunk;
- }
-
- iChunkOffset = (int)(iOfst%JOURNAL_CHUNKSIZE);
- do {
- int iSpace = JOURNAL_CHUNKSIZE - iChunkOffset;
- int nCopy = MIN(nRead, (JOURNAL_CHUNKSIZE - iChunkOffset));
- memcpy(zOut, &pChunk->zChunk[iChunkOffset], nCopy);
- zOut += nCopy;
- nRead -= iSpace;
- iChunkOffset = 0;
- } while( nRead>=0 && (pChunk=pChunk->pNext)!=0 && nRead>0 );
- p->readpoint.iOffset = iOfst+iAmt;
- p->readpoint.pChunk = pChunk;
-
- return SQLITE_OK;
-}
-
-/*
-** Write data to the file.
-*/
-static int memjrnlWrite(
- sqlite3_file *pJfd, /* The journal file into which to write */
- const void *zBuf, /* Take data to be written from here */
- int iAmt, /* Number of bytes to write */
- sqlite_int64 iOfst /* Begin writing at this offset into the file */
-){
- MemJournal *p = (MemJournal *)pJfd;
- int nWrite = iAmt;
- u8 *zWrite = (u8 *)zBuf;
-
- /* An in-memory journal file should only ever be appended to. Random
- ** access writes are not required by sqlite.
- */
- assert( iOfst==p->endpoint.iOffset );
- UNUSED_PARAMETER(iOfst);
-
- while( nWrite>0 ){
- FileChunk *pChunk = p->endpoint.pChunk;
- int iChunkOffset = (int)(p->endpoint.iOffset%JOURNAL_CHUNKSIZE);
- int iSpace = MIN(nWrite, JOURNAL_CHUNKSIZE - iChunkOffset);
-
- if( iChunkOffset==0 ){
- /* New chunk is required to extend the file. */
- FileChunk *pNew = sqlite3_malloc(sizeof(FileChunk));
- if( !pNew ){
- return SQLITE_IOERR_NOMEM;
- }
- pNew->pNext = 0;
- if( pChunk ){
- assert( p->pFirst );
- pChunk->pNext = pNew;
- }else{
- assert( !p->pFirst );
- p->pFirst = pNew;
- }
- p->endpoint.pChunk = pNew;
- }
-
- memcpy(&p->endpoint.pChunk->zChunk[iChunkOffset], zWrite, iSpace);
- zWrite += iSpace;
- nWrite -= iSpace;
- p->endpoint.iOffset += iSpace;
- }
-
- return SQLITE_OK;
-}
-
-/*
-** Truncate the file.
-*/
-static int memjrnlTruncate(sqlite3_file *pJfd, sqlite_int64 size){
- MemJournal *p = (MemJournal *)pJfd;
- FileChunk *pChunk;
- assert(size==0);
- UNUSED_PARAMETER(size);
- pChunk = p->pFirst;
- while( pChunk ){
- FileChunk *pTmp = pChunk;
- pChunk = pChunk->pNext;
- sqlite3_free(pTmp);
- }
- sqlite3MemJournalOpen(pJfd);
- return SQLITE_OK;
-}
-
-/*
-** Close the file.
-*/
-static int memjrnlClose(sqlite3_file *pJfd){
- memjrnlTruncate(pJfd, 0);
- return SQLITE_OK;
-}
-
-
-/*
-** Sync the file.
-**
-** Syncing an in-memory journal is a no-op. And, in fact, this routine
-** is never called in a working implementation. This implementation
-** exists purely as a contingency, in case some malfunction in some other
-** part of SQLite causes Sync to be called by mistake.
-*/
-static int memjrnlSync(sqlite3_file *NotUsed, int NotUsed2){ /*NO_TEST*/
- UNUSED_PARAMETER2(NotUsed, NotUsed2); /*NO_TEST*/
- assert( 0 ); /*NO_TEST*/
- return SQLITE_OK; /*NO_TEST*/
-} /*NO_TEST*/
-
-/*
-** Query the size of the file in bytes.
-*/
-static int memjrnlFileSize(sqlite3_file *pJfd, sqlite_int64 *pSize){
- MemJournal *p = (MemJournal *)pJfd;
- *pSize = (sqlite_int64) p->endpoint.iOffset;
- return SQLITE_OK;
-}
-
-/*
-** Table of methods for MemJournal sqlite3_file object.
-*/
-static struct sqlite3_io_methods MemJournalMethods = {
- 1, /* iVersion */
- memjrnlClose, /* xClose */
- memjrnlRead, /* xRead */
- memjrnlWrite, /* xWrite */
- memjrnlTruncate, /* xTruncate */
- memjrnlSync, /* xSync */
- memjrnlFileSize, /* xFileSize */
- 0, /* xLock */
- 0, /* xUnlock */
- 0, /* xCheckReservedLock */
- 0, /* xFileControl */
- 0, /* xSectorSize */
- 0 /* xDeviceCharacteristics */
-};
-
-/*
-** Open a journal file.
-*/
-SQLITE_PRIVATE void sqlite3MemJournalOpen(sqlite3_file *pJfd){
- MemJournal *p = (MemJournal *)pJfd;
- assert( EIGHT_BYTE_ALIGNMENT(p) );
- memset(p, 0, sqlite3MemJournalSize());
- p->pMethod = &MemJournalMethods;
-}
-
-/*
-** Return true if the file-handle passed as an argument is
-** an in-memory journal
-*/
-SQLITE_PRIVATE int sqlite3IsMemJournal(sqlite3_file *pJfd){
- return pJfd->pMethods==&MemJournalMethods;
-}
-
-/*
-** Return the number of bytes required to store a MemJournal that uses vfs
-** pVfs to create the underlying on-disk files.
-*/
-SQLITE_PRIVATE int sqlite3MemJournalSize(void){
- return sizeof(MemJournal);
-}
-
-/************** End of memjournal.c ******************************************/
-/************** Begin file walker.c ******************************************/
-/*
-** 2008 August 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 routines used for walking the parser tree for
-** an SQL statement.
-**
-** $Id: walker.c,v 1.7 2009/06/15 23:15:59 drh Exp $
-*/
-
-
-/*
-** Walk an expression tree. Invoke the callback once for each node
-** of the expression, while decending. (In other words, the callback
-** is invoked before visiting children.)
-**
-** The return value from the callback should be one of the WRC_*
-** constants to specify how to proceed with the walk.
-**
-** WRC_Continue Continue descending down the tree.
-**
-** WRC_Prune Do not descend into child nodes. But allow
-** the walk to continue with sibling nodes.
-**
-** WRC_Abort Do no more callbacks. Unwind the stack and
-** return the top-level walk call.
-**
-** The return value from this routine is WRC_Abort to abandon the tree walk
-** and WRC_Continue to continue.
-*/
-SQLITE_PRIVATE int sqlite3WalkExpr(Walker *pWalker, Expr *pExpr){
- int rc;
- if( pExpr==0 ) return WRC_Continue;
- testcase( ExprHasProperty(pExpr, EP_TokenOnly) );
- testcase( ExprHasProperty(pExpr, EP_Reduced) );
- rc = pWalker->xExprCallback(pWalker, pExpr);
- if( rc==WRC_Continue
- && !ExprHasAnyProperty(pExpr,EP_TokenOnly) ){
- if( sqlite3WalkExpr(pWalker, pExpr->pLeft) ) return WRC_Abort;
- if( sqlite3WalkExpr(pWalker, pExpr->pRight) ) return WRC_Abort;
- if( ExprHasProperty(pExpr, EP_xIsSelect) ){
- if( sqlite3WalkSelect(pWalker, pExpr->x.pSelect) ) return WRC_Abort;
- }else{
- if( sqlite3WalkExprList(pWalker, pExpr->x.pList) ) return WRC_Abort;
- }
- }
- return rc & WRC_Abort;
-}
-
-/*
-** Call sqlite3WalkExpr() for every expression in list p or until
-** an abort request is seen.
-*/
-SQLITE_PRIVATE int sqlite3WalkExprList(Walker *pWalker, ExprList *p){
- int i;
- struct ExprList_item *pItem;
- if( p ){
- for(i=p->nExpr, pItem=p->a; i>0; i--, pItem++){
- if( sqlite3WalkExpr(pWalker, pItem->pExpr) ) return WRC_Abort;
- }
- }
- return WRC_Continue;
-}
-
-/*
-** Walk all expressions associated with SELECT statement p. Do
-** not invoke the SELECT callback on p, but do (of course) invoke
-** any expr callbacks and SELECT callbacks that come from subqueries.
-** Return WRC_Abort or WRC_Continue.
-*/
-SQLITE_PRIVATE int sqlite3WalkSelectExpr(Walker *pWalker, Select *p){
- if( sqlite3WalkExprList(pWalker, p->pEList) ) return WRC_Abort;
- if( sqlite3WalkExpr(pWalker, p->pWhere) ) return WRC_Abort;
- if( sqlite3WalkExprList(pWalker, p->pGroupBy) ) return WRC_Abort;
- if( sqlite3WalkExpr(pWalker, p->pHaving) ) return WRC_Abort;
- if( sqlite3WalkExprList(pWalker, p->pOrderBy) ) return WRC_Abort;
- if( sqlite3WalkExpr(pWalker, p->pLimit) ) return WRC_Abort;
- if( sqlite3WalkExpr(pWalker, p->pOffset) ) return WRC_Abort;
- return WRC_Continue;
-}
-
-/*
-** Walk the parse trees associated with all subqueries in the
-** FROM clause of SELECT statement p. Do not invoke the select
-** callback on p, but do invoke it on each FROM clause subquery
-** and on any subqueries further down in the tree. Return
-** WRC_Abort or WRC_Continue;
-*/
-SQLITE_PRIVATE int sqlite3WalkSelectFrom(Walker *pWalker, Select *p){
- SrcList *pSrc;
- int i;
- struct SrcList_item *pItem;
-
- pSrc = p->pSrc;
- if( ALWAYS(pSrc) ){
- for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){
- if( sqlite3WalkSelect(pWalker, pItem->pSelect) ){
- return WRC_Abort;
- }
- }
- }
- return WRC_Continue;
-}
-
-/*
-** Call sqlite3WalkExpr() for every expression in Select statement p.
-** Invoke sqlite3WalkSelect() for subqueries in the FROM clause and
-** on the compound select chain, p->pPrior.
-**
-** Return WRC_Continue under normal conditions. Return WRC_Abort if
-** there is an abort request.
-**
-** If the Walker does not have an xSelectCallback() then this routine
-** is a no-op returning WRC_Continue.
-*/
-SQLITE_PRIVATE int sqlite3WalkSelect(Walker *pWalker, Select *p){
- int rc;
- if( p==0 || pWalker->xSelectCallback==0 ) return WRC_Continue;
- rc = WRC_Continue;
- while( p ){
- rc = pWalker->xSelectCallback(pWalker, p);
- if( rc ) break;
- if( sqlite3WalkSelectExpr(pWalker, p) ) return WRC_Abort;
- if( sqlite3WalkSelectFrom(pWalker, p) ) return WRC_Abort;
- p = p->pPrior;
- }
- return rc & WRC_Abort;
-}
-
-/************** End of walker.c **********************************************/
-/************** Begin file resolve.c *****************************************/
-/*
-** 2008 August 18
-**
-** 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 routines used for walking the parser tree and
-** resolve all identifiers by associating them with a particular
-** table and column.
-**
-** $Id: resolve.c,v 1.30 2009/06/15 23:15:59 drh Exp $
-*/
-
-/*
-** Turn the pExpr expression into an alias for the iCol-th column of the
-** result set in pEList.
-**
-** If the result set column is a simple column reference, then this routine
-** makes an exact copy. But for any other kind of expression, this
-** routine make a copy of the result set column as the argument to the
-** TK_AS operator. The TK_AS operator causes the expression to be
-** evaluated just once and then reused for each alias.
-**
-** The reason for suppressing the TK_AS term when the expression is a simple
-** column reference is so that the column reference will be recognized as
-** usable by indices within the WHERE clause processing logic.
-**
-** Hack: The TK_AS operator is inhibited if zType[0]=='G'. This means
-** that in a GROUP BY clause, the expression is evaluated twice. Hence:
-**
-** SELECT random()%5 AS x, count(*) FROM tab GROUP BY x
-**
-** Is equivalent to:
-**
-** SELECT random()%5 AS x, count(*) FROM tab GROUP BY random()%5
-**
-** The result of random()%5 in the GROUP BY clause is probably different
-** from the result in the result-set. We might fix this someday. Or
-** then again, we might not...
-*/
-static void resolveAlias(
- Parse *pParse, /* Parsing context */
- ExprList *pEList, /* A result set */
- int iCol, /* A column in the result set. 0..pEList->nExpr-1 */
- Expr *pExpr, /* Transform this into an alias to the result set */
- const char *zType /* "GROUP" or "ORDER" or "" */
-){
- Expr *pOrig; /* The iCol-th column of the result set */
- Expr *pDup; /* Copy of pOrig */
- sqlite3 *db; /* The database connection */
-
- assert( iCol>=0 && iCol<pEList->nExpr );
- pOrig = pEList->a[iCol].pExpr;
- assert( pOrig!=0 );
- assert( pOrig->flags & EP_Resolved );
- db = pParse->db;
- if( pOrig->op!=TK_COLUMN && zType[0]!='G' ){
- pDup = sqlite3ExprDup(db, pOrig, 0);
- pDup = sqlite3PExpr(pParse, TK_AS, pDup, 0, 0);
- if( pDup==0 ) return;
- if( pEList->a[iCol].iAlias==0 ){
- pEList->a[iCol].iAlias = (u16)(++pParse->nAlias);
- }
- pDup->iTable = pEList->a[iCol].iAlias;
- }else if( ExprHasProperty(pOrig, EP_IntValue) || pOrig->u.zToken==0 ){
- pDup = sqlite3ExprDup(db, pOrig, 0);
- if( pDup==0 ) return;
- }else{
- char *zToken = pOrig->u.zToken;
- assert( zToken!=0 );
- pOrig->u.zToken = 0;
- pDup = sqlite3ExprDup(db, pOrig, 0);
- pOrig->u.zToken = zToken;
- if( pDup==0 ) return;
- assert( (pDup->flags & (EP_Reduced|EP_TokenOnly))==0 );
- pDup->flags2 |= EP2_MallocedToken;
- pDup->u.zToken = sqlite3DbStrDup(db, zToken);
- }
- if( pExpr->flags & EP_ExpCollate ){
- pDup->pColl = pExpr->pColl;
- pDup->flags |= EP_ExpCollate;
- }
- sqlite3ExprClear(db, pExpr);
- memcpy(pExpr, pDup, sizeof(*pExpr));
- sqlite3DbFree(db, pDup);
-}
-
-/*
-** Given the name of a column of the form X.Y.Z or Y.Z or just Z, look up
-** that name in the set of source tables in pSrcList and make the pExpr
-** expression node refer back to that source column. The following changes
-** are made to pExpr:
-**
-** pExpr->iDb Set the index in db->aDb[] of the database X
-** (even if X is implied).
-** pExpr->iTable Set to the cursor number for the table obtained
-** from pSrcList.
-** pExpr->pTab Points to the Table structure of X.Y (even if
-** X and/or Y are implied.)
-** pExpr->iColumn Set to the column number within the table.
-** pExpr->op Set to TK_COLUMN.
-** pExpr->pLeft Any expression this points to is deleted
-** pExpr->pRight Any expression this points to is deleted.
-**
-** The zDb variable is the name of the database (the "X"). This value may be
-** NULL meaning that name is of the form Y.Z or Z. Any available database
-** can be used. The zTable variable is the name of the table (the "Y"). This
-** value can be NULL if zDb is also NULL. If zTable is NULL it
-** means that the form of the name is Z and that columns from any table
-** can be used.
-**
-** If the name cannot be resolved unambiguously, leave an error message
-** in pParse and return WRC_Abort. Return WRC_Prune on success.
-*/
-static int lookupName(
- Parse *pParse, /* The parsing context */
- const char *zDb, /* Name of the database containing table, or NULL */
- const char *zTab, /* Name of table containing column, or NULL */
- const char *zCol, /* Name of the column. */
- NameContext *pNC, /* The name context used to resolve the name */
- Expr *pExpr /* Make this EXPR node point to the selected column */
-){
- int i, j; /* Loop counters */
- int cnt = 0; /* Number of matching column names */
- int cntTab = 0; /* Number of matching table names */
- sqlite3 *db = pParse->db; /* The database connection */
- struct SrcList_item *pItem; /* Use for looping over pSrcList items */
- struct SrcList_item *pMatch = 0; /* The matching pSrcList item */
- NameContext *pTopNC = pNC; /* First namecontext in the list */
- Schema *pSchema = 0; /* Schema of the expression */
- int isTrigger = 0;
-
- assert( pNC ); /* the name context cannot be NULL. */
- assert( zCol ); /* The Z in X.Y.Z cannot be NULL */
- assert( ~ExprHasAnyProperty(pExpr, EP_TokenOnly|EP_Reduced) );
-
- /* Initialize the node to no-match */
- pExpr->iTable = -1;
- pExpr->pTab = 0;
- ExprSetIrreducible(pExpr);
-
- /* Start at the inner-most context and move outward until a match is found */
- while( pNC && cnt==0 ){
- ExprList *pEList;
- SrcList *pSrcList = pNC->pSrcList;
-
- if( pSrcList ){
- for(i=0, pItem=pSrcList->a; i<pSrcList->nSrc; i++, pItem++){
- Table *pTab;
- int iDb;
- Column *pCol;
-
- pTab = pItem->pTab;
- assert( pTab!=0 && pTab->zName!=0 );
- iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
- assert( pTab->nCol>0 );
- if( zTab ){
- if( pItem->zAlias ){
- char *zTabName = pItem->zAlias;
- if( sqlite3StrICmp(zTabName, zTab)!=0 ) continue;
- }else{
- char *zTabName = pTab->zName;
- if( NEVER(zTabName==0) || sqlite3StrICmp(zTabName, zTab)!=0 ){
- continue;
- }
- if( zDb!=0 && sqlite3StrICmp(db->aDb[iDb].zName, zDb)!=0 ){
- continue;
- }
- }
- }
- if( 0==(cntTab++) ){
- pExpr->iTable = pItem->iCursor;
- pExpr->pTab = pTab;
- pSchema = pTab->pSchema;
- pMatch = pItem;
- }
- for(j=0, pCol=pTab->aCol; j<pTab->nCol; j++, pCol++){
- if( sqlite3StrICmp(pCol->zName, zCol)==0 ){
- IdList *pUsing;
- cnt++;
- pExpr->iTable = pItem->iCursor;
- pExpr->pTab = pTab;
- pMatch = pItem;
- pSchema = pTab->pSchema;
- /* Substitute the rowid (column -1) for the INTEGER PRIMARY KEY */
- pExpr->iColumn = j==pTab->iPKey ? -1 : (i16)j;
- if( i<pSrcList->nSrc-1 ){
- if( pItem[1].jointype & JT_NATURAL ){
- /* If this match occurred in the left table of a natural join,
- ** then skip the right table to avoid a duplicate match */
- pItem++;
- i++;
- }else if( (pUsing = pItem[1].pUsing)!=0 ){
- /* If this match occurs on a column that is in the USING clause
- ** of a join, skip the search of the right table of the join
- ** to avoid a duplicate match there. */
- int k;
- for(k=0; k<pUsing->nId; k++){
- if( sqlite3StrICmp(pUsing->a[k].zName, zCol)==0 ){
- pItem++;
- i++;
- break;
- }
- }
- }
- }
- break;
- }
- }
- }
- }
-
-#ifndef SQLITE_OMIT_TRIGGER
- /* If we have not already resolved the name, then maybe
- ** it is a new.* or old.* trigger argument reference
- */
- if( zDb==0 && zTab!=0 && cnt==0 && pParse->pTriggerTab!=0 ){
- int op = pParse->eTriggerOp;
- Table *pTab = 0;
- assert( op==TK_DELETE || op==TK_UPDATE || op==TK_INSERT );
- if( op!=TK_DELETE && sqlite3StrICmp("new",zTab) == 0 ){
- pExpr->iTable = 1;
- pTab = pParse->pTriggerTab;
- }else if( op!=TK_INSERT && sqlite3StrICmp("old",zTab)==0 ){
- pExpr->iTable = 0;
- pTab = pParse->pTriggerTab;
- }
-
- if( pTab ){
- int iCol;
- pSchema = pTab->pSchema;
- cntTab++;
- if( sqlite3IsRowid(zCol) ){
- iCol = -1;
- }else{
- for(iCol=0; iCol<pTab->nCol; iCol++){
- Column *pCol = &pTab->aCol[iCol];
- if( sqlite3StrICmp(pCol->zName, zCol)==0 ){
- if( iCol==pTab->iPKey ){
- iCol = -1;
- }
- break;
- }
- }
- }
- if( iCol<pTab->nCol ){
- cnt++;
- if( iCol<0 ){
- pExpr->affinity = SQLITE_AFF_INTEGER;
- }else if( pExpr->iTable==0 ){
- testcase( iCol==31 );
- testcase( iCol==32 );
- pParse->oldmask |= (iCol>=32 ? 0xffffffff : (((u32)1)<<iCol));
- }
- pExpr->iColumn = (i16)iCol;
- pExpr->pTab = pTab;
- isTrigger = 1;
- }
- }
- }
-#endif /* !defined(SQLITE_OMIT_TRIGGER) */
-
- /*
- ** Perhaps the name is a reference to the ROWID
- */
- if( cnt==0 && cntTab==1 && sqlite3IsRowid(zCol) ){
- cnt = 1;
- pExpr->iColumn = -1;
- pExpr->affinity = SQLITE_AFF_INTEGER;
- }
-
- /*
- ** If the input is of the form Z (not Y.Z or X.Y.Z) then the name Z
- ** might refer to an result-set alias. This happens, for example, when
- ** we are resolving names in the WHERE clause of the following command:
- **
- ** SELECT a+b AS x FROM table WHERE x<10;
- **
- ** In cases like this, replace pExpr with a copy of the expression that
- ** forms the result set entry ("a+b" in the example) and return immediately.
- ** Note that the expression in the result set should have already been
- ** resolved by the time the WHERE clause is resolved.
- */
- if( cnt==0 && (pEList = pNC->pEList)!=0 && zTab==0 ){
- for(j=0; j<pEList->nExpr; j++){
- char *zAs = pEList->a[j].zName;
- if( zAs!=0 && sqlite3StrICmp(zAs, zCol)==0 ){
- Expr *pOrig;
- assert( pExpr->pLeft==0 && pExpr->pRight==0 );
- assert( pExpr->x.pList==0 );
- assert( pExpr->x.pSelect==0 );
- pOrig = pEList->a[j].pExpr;
- if( !pNC->allowAgg && ExprHasProperty(pOrig, EP_Agg) ){
- sqlite3ErrorMsg(pParse, "misuse of aliased aggregate %s", zAs);
- return WRC_Abort;
- }
- resolveAlias(pParse, pEList, j, pExpr, "");
- cnt = 1;
- pMatch = 0;
- assert( zTab==0 && zDb==0 );
- goto lookupname_end;
- }
- }
- }
-
- /* Advance to the next name context. The loop will exit when either
- ** we have a match (cnt>0) or when we run out of name contexts.
- */
- if( cnt==0 ){
- pNC = pNC->pNext;
- }
- }
-
- /*
- ** If X and Y are NULL (in other words if only the column name Z is
- ** supplied) and the value of Z is enclosed in double-quotes, then
- ** Z is a string literal if it doesn't match any column names. In that
- ** case, we need to return right away and not make any changes to
- ** pExpr.
- **
- ** Because no reference was made to outer contexts, the pNC->nRef
- ** fields are not changed in any context.
- */
- if( cnt==0 && zTab==0 && ExprHasProperty(pExpr,EP_DblQuoted) ){
- pExpr->op = TK_STRING;
- pExpr->pTab = 0;
- return WRC_Prune;
- }
-
- /*
- ** cnt==0 means there was not match. cnt>1 means there were two or
- ** more matches. Either way, we have an error.
- */
- if( cnt!=1 ){
- const char *zErr;
- zErr = cnt==0 ? "no such column" : "ambiguous column name";
- if( zDb ){
- sqlite3ErrorMsg(pParse, "%s: %s.%s.%s", zErr, zDb, zTab, zCol);
- }else if( zTab ){
- sqlite3ErrorMsg(pParse, "%s: %s.%s", zErr, zTab, zCol);
- }else{
- sqlite3ErrorMsg(pParse, "%s: %s", zErr, zCol);
- }
- pTopNC->nErr++;
- }
-
- /* If a column from a table in pSrcList is referenced, then record
- ** this fact in the pSrcList.a[].colUsed bitmask. Column 0 causes
- ** bit 0 to be set. Column 1 sets bit 1. And so forth. If the
- ** column number is greater than the number of bits in the bitmask
- ** then set the high-order bit of the bitmask.
- */
- if( pExpr->iColumn>=0 && pMatch!=0 ){
- int n = pExpr->iColumn;
- testcase( n==BMS-1 );
- if( n>=BMS ){
- n = BMS-1;
- }
- assert( pMatch->iCursor==pExpr->iTable );
- pMatch->colUsed |= ((Bitmask)1)<<n;
- }
-
- /* Clean up and return
- */
- sqlite3ExprDelete(db, pExpr->pLeft);
- pExpr->pLeft = 0;
- sqlite3ExprDelete(db, pExpr->pRight);
- pExpr->pRight = 0;
- pExpr->op = (isTrigger ? TK_TRIGGER : TK_COLUMN);
-lookupname_end:
- if( cnt==1 ){
- assert( pNC!=0 );
- sqlite3AuthRead(pParse, pExpr, pSchema, pNC->pSrcList);
- /* Increment the nRef value on all name contexts from TopNC up to
- ** the point where the name matched. */
- for(;;){
- assert( pTopNC!=0 );
- pTopNC->nRef++;
- if( pTopNC==pNC ) break;
- pTopNC = pTopNC->pNext;
- }
- return WRC_Prune;
- } else {
- return WRC_Abort;
- }
-}
-
-/*
-** This routine is callback for sqlite3WalkExpr().
-**
-** Resolve symbolic names into TK_COLUMN operators for the current
-** node in the expression tree. Return 0 to continue the search down
-** the tree or 2 to abort the tree walk.
-**
-** This routine also does error checking and name resolution for
-** function names. The operator for aggregate functions is changed
-** to TK_AGG_FUNCTION.
-*/
-static int resolveExprStep(Walker *pWalker, Expr *pExpr){
- NameContext *pNC;
- Parse *pParse;
-
- pNC = pWalker->u.pNC;
- assert( pNC!=0 );
- pParse = pNC->pParse;
- assert( pParse==pWalker->pParse );
-
- if( ExprHasAnyProperty(pExpr, EP_Resolved) ) return WRC_Prune;
- ExprSetProperty(pExpr, EP_Resolved);
-#ifndef NDEBUG
- if( pNC->pSrcList && pNC->pSrcList->nAlloc>0 ){
- SrcList *pSrcList = pNC->pSrcList;
- int i;
- for(i=0; i<pNC->pSrcList->nSrc; i++){
- assert( pSrcList->a[i].iCursor>=0 && pSrcList->a[i].iCursor<pParse->nTab);
- }
- }
-#endif
- switch( pExpr->op ){
-
-#if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY)
- /* The special operator TK_ROW means use the rowid for the first
- ** column in the FROM clause. This is used by the LIMIT and ORDER BY
- ** clause processing on UPDATE and DELETE statements.
- */
- case TK_ROW: {
- SrcList *pSrcList = pNC->pSrcList;
- struct SrcList_item *pItem;
- assert( pSrcList && pSrcList->nSrc==1 );
- pItem = pSrcList->a;
- pExpr->op = TK_COLUMN;
- pExpr->pTab = pItem->pTab;
- pExpr->iTable = pItem->iCursor;
- pExpr->iColumn = -1;
- pExpr->affinity = SQLITE_AFF_INTEGER;
- break;
- }
-#endif /* defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY) */
-
- /* A lone identifier is the name of a column.
- */
- case TK_ID: {
- return lookupName(pParse, 0, 0, pExpr->u.zToken, pNC, pExpr);
- }
-
- /* A table name and column name: ID.ID
- ** Or a database, table and column: ID.ID.ID
- */
- case TK_DOT: {
- const char *zColumn;
- const char *zTable;
- const char *zDb;
- Expr *pRight;
-
- /* if( pSrcList==0 ) break; */
- pRight = pExpr->pRight;
- if( pRight->op==TK_ID ){
- zDb = 0;
- zTable = pExpr->pLeft->u.zToken;
- zColumn = pRight->u.zToken;
- }else{
- assert( pRight->op==TK_DOT );
- zDb = pExpr->pLeft->u.zToken;
- zTable = pRight->pLeft->u.zToken;
- zColumn = pRight->pRight->u.zToken;
- }
- return lookupName(pParse, zDb, zTable, zColumn, pNC, pExpr);
- }
-
- /* Resolve function names
- */
- case TK_CONST_FUNC:
- case TK_FUNCTION: {
- ExprList *pList = pExpr->x.pList; /* The argument list */
- int n = pList ? pList->nExpr : 0; /* Number of arguments */
- int no_such_func = 0; /* True if no such function exists */
- int wrong_num_args = 0; /* True if wrong number of arguments */
- int is_agg = 0; /* True if is an aggregate function */
- int auth; /* Authorization to use the function */
- int nId; /* Number of characters in function name */
- const char *zId; /* The function name. */
- FuncDef *pDef; /* Information about the function */
- u8 enc = ENC(pParse->db); /* The database encoding */
-
- testcase( pExpr->op==TK_CONST_FUNC );
- assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
- zId = pExpr->u.zToken;
- nId = sqlite3Strlen30(zId);
- pDef = sqlite3FindFunction(pParse->db, zId, nId, n, enc, 0);
- if( pDef==0 ){
- pDef = sqlite3FindFunction(pParse->db, zId, nId, -1, enc, 0);
- if( pDef==0 ){
- no_such_func = 1;
- }else{
- wrong_num_args = 1;
- }
- }else{
- is_agg = pDef->xFunc==0;
- }
-#ifndef SQLITE_OMIT_AUTHORIZATION
- if( pDef ){
- auth = sqlite3AuthCheck(pParse, SQLITE_FUNCTION, 0, pDef->zName, 0);
- if( auth!=SQLITE_OK ){
- if( auth==SQLITE_DENY ){
- sqlite3ErrorMsg(pParse, "not authorized to use function: %s",
- pDef->zName);
- pNC->nErr++;
- }
- pExpr->op = TK_NULL;
- return WRC_Prune;
- }
- }
-#endif
- if( is_agg && !pNC->allowAgg ){
- sqlite3ErrorMsg(pParse, "misuse of aggregate function %.*s()", nId,zId);
- pNC->nErr++;
- is_agg = 0;
- }else if( no_such_func ){
- sqlite3ErrorMsg(pParse, "no such function: %.*s", nId, zId);
- pNC->nErr++;
- }else if( wrong_num_args ){
- sqlite3ErrorMsg(pParse,"wrong number of arguments to function %.*s()",
- nId, zId);
- pNC->nErr++;
- }
- if( is_agg ){
- pExpr->op = TK_AGG_FUNCTION;
- pNC->hasAgg = 1;
- }
- if( is_agg ) pNC->allowAgg = 0;
- sqlite3WalkExprList(pWalker, pList);
- if( is_agg ) pNC->allowAgg = 1;
- /* FIX ME: Compute pExpr->affinity based on the expected return
- ** type of the function
- */
- return WRC_Prune;
- }
-#ifndef SQLITE_OMIT_SUBQUERY
- case TK_SELECT:
- case TK_EXISTS: testcase( pExpr->op==TK_EXISTS );
-#endif
- case TK_IN: {
- testcase( pExpr->op==TK_IN );
- if( ExprHasProperty(pExpr, EP_xIsSelect) ){
- int nRef = pNC->nRef;
-#ifndef SQLITE_OMIT_CHECK
- if( pNC->isCheck ){
- sqlite3ErrorMsg(pParse,"subqueries prohibited in CHECK constraints");
- }
-#endif
- sqlite3WalkSelect(pWalker, pExpr->x.pSelect);
- assert( pNC->nRef>=nRef );
- if( nRef!=pNC->nRef ){
- ExprSetProperty(pExpr, EP_VarSelect);
- }
- }
- break;
- }
-#ifndef SQLITE_OMIT_CHECK
- case TK_VARIABLE: {
- if( pNC->isCheck ){
- sqlite3ErrorMsg(pParse,"parameters prohibited in CHECK constraints");
- }
- break;
- }
-#endif
- }
- return (pParse->nErr || pParse->db->mallocFailed) ? WRC_Abort : WRC_Continue;
-}
-
-/*
-** pEList is a list of expressions which are really the result set of the
-** a SELECT statement. pE is a term in an ORDER BY or GROUP BY clause.
-** This routine checks to see if pE is a simple identifier which corresponds
-** to the AS-name of one of the terms of the expression list. If it is,
-** this routine return an integer between 1 and N where N is the number of
-** elements in pEList, corresponding to the matching entry. If there is
-** no match, or if pE is not a simple identifier, then this routine
-** return 0.
-**
-** pEList has been resolved. pE has not.
-*/
-static int resolveAsName(
- Parse *pParse, /* Parsing context for error messages */
- ExprList *pEList, /* List of expressions to scan */
- Expr *pE /* Expression we are trying to match */
-){
- int i; /* Loop counter */
-
- UNUSED_PARAMETER(pParse);
-
- if( pE->op==TK_ID ){
- char *zCol = pE->u.zToken;
- for(i=0; i<pEList->nExpr; i++){
- char *zAs = pEList->a[i].zName;
- if( zAs!=0 && sqlite3StrICmp(zAs, zCol)==0 ){
- return i+1;
- }
- }
- }
- return 0;
-}
-
-/*
-** pE is a pointer to an expression which is a single term in the
-** ORDER BY of a compound SELECT. The expression has not been
-** name resolved.
-**
-** At the point this routine is called, we already know that the
-** ORDER BY term is not an integer index into the result set. That
-** case is handled by the calling routine.
-**
-** Attempt to match pE against result set columns in the left-most
-** SELECT statement. Return the index i of the matching column,
-** as an indication to the caller that it should sort by the i-th column.
-** The left-most column is 1. In other words, the value returned is the
-** same integer value that would be used in the SQL statement to indicate
-** the column.
-**
-** If there is no match, return 0. Return -1 if an error occurs.
-*/
-static int resolveOrderByTermToExprList(
- Parse *pParse, /* Parsing context for error messages */
- Select *pSelect, /* The SELECT statement with the ORDER BY clause */
- Expr *pE /* The specific ORDER BY term */
-){
- int i; /* Loop counter */
- ExprList *pEList; /* The columns of the result set */
- NameContext nc; /* Name context for resolving pE */
-
- assert( sqlite3ExprIsInteger(pE, &i)==0 );
- pEList = pSelect->pEList;
-
- /* Resolve all names in the ORDER BY term expression
- */
- memset(&nc, 0, sizeof(nc));
- nc.pParse = pParse;
- nc.pSrcList = pSelect->pSrc;
- nc.pEList = pEList;
- nc.allowAgg = 1;
- nc.nErr = 0;
- if( sqlite3ResolveExprNames(&nc, pE) ){
- sqlite3ErrorClear(pParse);
- return 0;
- }
-
- /* Try to match the ORDER BY expression against an expression
- ** in the result set. Return an 1-based index of the matching
- ** result-set entry.
- */
- for(i=0; i<pEList->nExpr; i++){
- if( sqlite3ExprCompare(pEList->a[i].pExpr, pE) ){
- return i+1;
- }
- }
-
- /* If no match, return 0. */
- return 0;
-}
-
-/*
-** Generate an ORDER BY or GROUP BY term out-of-range error.
-*/
-static void resolveOutOfRangeError(
- Parse *pParse, /* The error context into which to write the error */
- const char *zType, /* "ORDER" or "GROUP" */
- int i, /* The index (1-based) of the term out of range */
- int mx /* Largest permissible value of i */
-){
- sqlite3ErrorMsg(pParse,
- "%r %s BY term out of range - should be "
- "between 1 and %d", i, zType, mx);
-}
-
-/*
-** Analyze the ORDER BY clause in a compound SELECT statement. Modify
-** each term of the ORDER BY clause is a constant integer between 1
-** and N where N is the number of columns in the compound SELECT.
-**
-** ORDER BY terms that are already an integer between 1 and N are
-** unmodified. ORDER BY terms that are integers outside the range of
-** 1 through N generate an error. ORDER BY terms that are expressions
-** are matched against result set expressions of compound SELECT
-** beginning with the left-most SELECT and working toward the right.
-** At the first match, the ORDER BY expression is transformed into
-** the integer column number.
-**
-** Return the number of errors seen.
-*/
-static int resolveCompoundOrderBy(
- Parse *pParse, /* Parsing context. Leave error messages here */
- Select *pSelect /* The SELECT statement containing the ORDER BY */
-){
- int i;
- ExprList *pOrderBy;
- ExprList *pEList;
- sqlite3 *db;
- int moreToDo = 1;
-
- pOrderBy = pSelect->pOrderBy;
- if( pOrderBy==0 ) return 0;
- db = pParse->db;
-#if SQLITE_MAX_COLUMN
- if( pOrderBy->nExpr>db->aLimit[SQLITE_LIMIT_COLUMN] ){
- sqlite3ErrorMsg(pParse, "too many terms in ORDER BY clause");
- return 1;
- }
-#endif
- for(i=0; i<pOrderBy->nExpr; i++){
- pOrderBy->a[i].done = 0;
- }
- pSelect->pNext = 0;
- while( pSelect->pPrior ){
- pSelect->pPrior->pNext = pSelect;
- pSelect = pSelect->pPrior;
- }
- while( pSelect && moreToDo ){
- struct ExprList_item *pItem;
- moreToDo = 0;
- pEList = pSelect->pEList;
- assert( pEList!=0 );
- for(i=0, pItem=pOrderBy->a; i<pOrderBy->nExpr; i++, pItem++){
- int iCol = -1;
- Expr *pE, *pDup;
- if( pItem->done ) continue;
- pE = pItem->pExpr;
- if( sqlite3ExprIsInteger(pE, &iCol) ){
- if( iCol<=0 || iCol>pEList->nExpr ){
- resolveOutOfRangeError(pParse, "ORDER", i+1, pEList->nExpr);
- return 1;
- }
- }else{
- iCol = resolveAsName(pParse, pEList, pE);
- if( iCol==0 ){
- pDup = sqlite3ExprDup(db, pE, 0);
- if( !db->mallocFailed ){
- assert(pDup);
- iCol = resolveOrderByTermToExprList(pParse, pSelect, pDup);
- }
- sqlite3ExprDelete(db, pDup);
- }
- }
- if( iCol>0 ){
- CollSeq *pColl = pE->pColl;
- int flags = pE->flags & EP_ExpCollate;
- sqlite3ExprDelete(db, pE);
- pItem->pExpr = pE = sqlite3Expr(db, TK_INTEGER, 0);
- if( pE==0 ) return 1;
- pE->pColl = pColl;
- pE->flags |= EP_IntValue | flags;
- pE->u.iValue = iCol;
- pItem->iCol = (u16)iCol;
- pItem->done = 1;
- }else{
- moreToDo = 1;
- }
- }
- pSelect = pSelect->pNext;
- }
- for(i=0; i<pOrderBy->nExpr; i++){
- if( pOrderBy->a[i].done==0 ){
- sqlite3ErrorMsg(pParse, "%r ORDER BY term does not match any "
- "column in the result set", i+1);
- return 1;
- }
- }
- return 0;
-}
-
-/*
-** Check every term in the ORDER BY or GROUP BY clause pOrderBy of
-** the SELECT statement pSelect. If any term is reference to a
-** result set expression (as determined by the ExprList.a.iCol field)
-** then convert that term into a copy of the corresponding result set
-** column.
-**
-** If any errors are detected, add an error message to pParse and
-** return non-zero. Return zero if no errors are seen.
-*/
-SQLITE_PRIVATE int sqlite3ResolveOrderGroupBy(
- Parse *pParse, /* Parsing context. Leave error messages here */
- Select *pSelect, /* The SELECT statement containing the clause */
- ExprList *pOrderBy, /* The ORDER BY or GROUP BY clause to be processed */
- const char *zType /* "ORDER" or "GROUP" */
-){
- int i;
- sqlite3 *db = pParse->db;
- ExprList *pEList;
- struct ExprList_item *pItem;
-
- if( pOrderBy==0 || pParse->db->mallocFailed ) return 0;
-#if SQLITE_MAX_COLUMN
- if( pOrderBy->nExpr>db->aLimit[SQLITE_LIMIT_COLUMN] ){
- sqlite3ErrorMsg(pParse, "too many terms in %s BY clause", zType);
- return 1;
- }
-#endif
- pEList = pSelect->pEList;
- assert( pEList!=0 ); /* sqlite3SelectNew() guarantees this */
- for(i=0, pItem=pOrderBy->a; i<pOrderBy->nExpr; i++, pItem++){
- if( pItem->iCol ){
- if( pItem->iCol>pEList->nExpr ){
- resolveOutOfRangeError(pParse, zType, i+1, pEList->nExpr);
- return 1;
- }
- resolveAlias(pParse, pEList, pItem->iCol-1, pItem->pExpr, zType);
- }
- }
- return 0;
-}
-
-/*
-** pOrderBy is an ORDER BY or GROUP BY clause in SELECT statement pSelect.
-** The Name context of the SELECT statement is pNC. zType is either
-** "ORDER" or "GROUP" depending on which type of clause pOrderBy is.
-**
-** This routine resolves each term of the clause into an expression.
-** If the order-by term is an integer I between 1 and N (where N is the
-** number of columns in the result set of the SELECT) then the expression
-** in the resolution is a copy of the I-th result-set expression. If
-** the order-by term is an identify that corresponds to the AS-name of
-** a result-set expression, then the term resolves to a copy of the
-** result-set expression. Otherwise, the expression is resolved in
-** the usual way - using sqlite3ResolveExprNames().
-**
-** This routine returns the number of errors. If errors occur, then
-** an appropriate error message might be left in pParse. (OOM errors
-** excepted.)
-*/
-static int resolveOrderGroupBy(
- NameContext *pNC, /* The name context of the SELECT statement */
- Select *pSelect, /* The SELECT statement holding pOrderBy */
- ExprList *pOrderBy, /* An ORDER BY or GROUP BY clause to resolve */
- const char *zType /* Either "ORDER" or "GROUP", as appropriate */
-){
- int i; /* Loop counter */
- int iCol; /* Column number */
- struct ExprList_item *pItem; /* A term of the ORDER BY clause */
- Parse *pParse; /* Parsing context */
- int nResult; /* Number of terms in the result set */
-
- if( pOrderBy==0 ) return 0;
- nResult = pSelect->pEList->nExpr;
- pParse = pNC->pParse;
- for(i=0, pItem=pOrderBy->a; i<pOrderBy->nExpr; i++, pItem++){
- Expr *pE = pItem->pExpr;
- iCol = resolveAsName(pParse, pSelect->pEList, pE);
- if( iCol>0 ){
- /* If an AS-name match is found, mark this ORDER BY column as being
- ** 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;
- continue;
- }
- if( sqlite3ExprIsInteger(pE, &iCol) ){
- /* The ORDER BY term is an integer constant. Again, set the column
- ** number so that sqlite3ResolveOrderGroupBy() will convert the
- ** order-by term to a copy of the result-set expression */
- if( iCol<1 ){
- resolveOutOfRangeError(pParse, zType, i+1, nResult);
- return 1;
- }
- pItem->iCol = (u16)iCol;
- continue;
- }
-
- /* Otherwise, treat the ORDER BY term as an ordinary expression */
- pItem->iCol = 0;
- if( sqlite3ResolveExprNames(pNC, pE) ){
- return 1;
- }
- }
- return sqlite3ResolveOrderGroupBy(pParse, pSelect, pOrderBy, zType);
-}
-
-/*
-** Resolve names in the SELECT statement p and all of its descendents.
-*/
-static int resolveSelectStep(Walker *pWalker, Select *p){
- NameContext *pOuterNC; /* Context that contains this SELECT */
- NameContext sNC; /* Name context of this SELECT */
- int isCompound; /* True if p is a compound select */
- int nCompound; /* Number of compound terms processed so far */
- Parse *pParse; /* Parsing context */
- ExprList *pEList; /* Result set expression list */
- int i; /* Loop counter */
- ExprList *pGroupBy; /* The GROUP BY clause */
- Select *pLeftmost; /* Left-most of SELECT of a compound */
- sqlite3 *db; /* Database connection */
-
-
- assert( p!=0 );
- if( p->selFlags & SF_Resolved ){
- return WRC_Prune;
- }
- pOuterNC = pWalker->u.pNC;
- pParse = pWalker->pParse;
- db = pParse->db;
-
- /* Normally sqlite3SelectExpand() will be called first and will have
- ** already expanded this SELECT. However, if this is a subquery within
- ** an expression, sqlite3ResolveExprNames() will be called without a
- ** prior call to sqlite3SelectExpand(). When that happens, let
- ** sqlite3SelectPrep() do all of the processing for this SELECT.
- ** sqlite3SelectPrep() will invoke both sqlite3SelectExpand() and
- ** this routine in the correct order.
- */
- if( (p->selFlags & SF_Expanded)==0 ){
- sqlite3SelectPrep(pParse, p, pOuterNC);
- return (pParse->nErr || db->mallocFailed) ? WRC_Abort : WRC_Prune;
- }
-
- isCompound = p->pPrior!=0;
- nCompound = 0;
- pLeftmost = p;
- while( p ){
- assert( (p->selFlags & SF_Expanded)!=0 );
- assert( (p->selFlags & SF_Resolved)==0 );
- p->selFlags |= SF_Resolved;
-
- /* Resolve the expressions in the LIMIT and OFFSET clauses. These
- ** are not allowed to refer to any names, so pass an empty NameContext.
- */
- memset(&sNC, 0, sizeof(sNC));
- sNC.pParse = pParse;
- if( sqlite3ResolveExprNames(&sNC, p->pLimit) ||
- sqlite3ResolveExprNames(&sNC, p->pOffset) ){
- return WRC_Abort;
- }
-
- /* Set up the local name-context to pass to sqlite3ResolveExprNames() to
- ** resolve the result-set expression list.
- */
- sNC.allowAgg = 1;
- sNC.pSrcList = p->pSrc;
- sNC.pNext = pOuterNC;
-
- /* Resolve names in the result set. */
- pEList = p->pEList;
- assert( pEList!=0 );
- for(i=0; i<pEList->nExpr; i++){
- Expr *pX = pEList->a[i].pExpr;
- if( sqlite3ResolveExprNames(&sNC, pX) ){
- return WRC_Abort;
- }
- }
-
- /* Recursively resolve names in all subqueries
- */
- for(i=0; i<p->pSrc->nSrc; i++){
- struct SrcList_item *pItem = &p->pSrc->a[i];
- if( pItem->pSelect ){
- const char *zSavedContext = pParse->zAuthContext;
- if( pItem->zName ) pParse->zAuthContext = pItem->zName;
- sqlite3ResolveSelectNames(pParse, pItem->pSelect, pOuterNC);
- pParse->zAuthContext = zSavedContext;
- if( pParse->nErr || db->mallocFailed ) return WRC_Abort;
- }
- }
-
- /* If there are no aggregate functions in the result-set, and no GROUP BY
- ** expression, do not allow aggregates in any of the other expressions.
- */
- assert( (p->selFlags & SF_Aggregate)==0 );
- pGroupBy = p->pGroupBy;
- if( pGroupBy || sNC.hasAgg ){
- p->selFlags |= SF_Aggregate;
- }else{
- sNC.allowAgg = 0;
- }
-
- /* If a HAVING clause is present, then there must be a GROUP BY clause.
- */
- if( p->pHaving && !pGroupBy ){
- sqlite3ErrorMsg(pParse, "a GROUP BY clause is required before HAVING");
- return WRC_Abort;
- }
-
- /* Add the expression list to the name-context before parsing the
- ** other expressions in the SELECT statement. This is so that
- ** expressions in the WHERE clause (etc.) can refer to expressions by
- ** aliases in the result set.
- **
- ** Minor point: If this is the case, then the expression will be
- ** re-evaluated for each reference to it.
- */
- sNC.pEList = p->pEList;
- if( sqlite3ResolveExprNames(&sNC, p->pWhere) ||
- sqlite3ResolveExprNames(&sNC, p->pHaving)
- ){
- return WRC_Abort;
- }
-
- /* The ORDER BY and GROUP BY clauses may not refer to terms in
- ** outer queries
- */
- sNC.pNext = 0;
- sNC.allowAgg = 1;
-
- /* Process the ORDER BY clause for singleton SELECT statements.
- ** The ORDER BY clause for compounds SELECT statements is handled
- ** below, after all of the result-sets for all of the elements of
- ** the compound have been resolved.
- */
- if( !isCompound && resolveOrderGroupBy(&sNC, p, p->pOrderBy, "ORDER") ){
- return WRC_Abort;
- }
- if( db->mallocFailed ){
- return WRC_Abort;
- }
-
- /* Resolve the GROUP BY clause. At the same time, make sure
- ** the GROUP BY clause does not contain aggregate functions.
- */
- if( pGroupBy ){
- struct ExprList_item *pItem;
-
- if( resolveOrderGroupBy(&sNC, p, pGroupBy, "GROUP") || db->mallocFailed ){
- return WRC_Abort;
- }
- for(i=0, pItem=pGroupBy->a; i<pGroupBy->nExpr; i++, pItem++){
- if( ExprHasProperty(pItem->pExpr, EP_Agg) ){
- sqlite3ErrorMsg(pParse, "aggregate functions are not allowed in "
- "the GROUP BY clause");
- return WRC_Abort;
- }
- }
- }
-
- /* Advance to the next term of the compound
- */
- p = p->pPrior;
- nCompound++;
- }
-
- /* Resolve the ORDER BY on a compound SELECT after all terms of
- ** the compound have been resolved.
- */
- if( isCompound && resolveCompoundOrderBy(pParse, pLeftmost) ){
- return WRC_Abort;
- }
-
- return WRC_Prune;
-}
-
-/*
-** This routine walks an expression tree and resolves references to
-** table columns and result-set columns. At the same time, do error
-** checking on function usage and set a flag if any aggregate functions
-** are seen.
-**
-** To resolve table columns references we look for nodes (or subtrees) of the
-** form X.Y.Z or Y.Z or just Z where
-**
-** X: The name of a database. Ex: "main" or "temp" or
-** the symbolic name assigned to an ATTACH-ed database.
-**
-** Y: The name of a table in a FROM clause. Or in a trigger
-** one of the special names "old" or "new".
-**
-** Z: The name of a column in table Y.
-**
-** The node at the root of the subtree is modified as follows:
-**
-** Expr.op Changed to TK_COLUMN
-** Expr.pTab Points to the Table object for X.Y
-** Expr.iColumn The column index in X.Y. -1 for the rowid.
-** Expr.iTable The VDBE cursor number for X.Y
-**
-**
-** To resolve result-set references, look for expression nodes of the
-** form Z (with no X and Y prefix) where the Z matches the right-hand
-** size of an AS clause in the result-set of a SELECT. The Z expression
-** is replaced by a copy of the left-hand side of the result-set expression.
-** Table-name and function resolution occurs on the substituted expression
-** tree. For example, in:
-**
-** SELECT a+b AS x, c+d AS y FROM t1 ORDER BY x;
-**
-** The "x" term of the order by is replaced by "a+b" to render:
-**
-** SELECT a+b AS x, c+d AS y FROM t1 ORDER BY a+b;
-**
-** Function calls are checked to make sure that the function is
-** defined and that the correct number of arguments are specified.
-** If the function is an aggregate function, then the pNC->hasAgg is
-** set and the opcode is changed from TK_FUNCTION to TK_AGG_FUNCTION.
-** If an expression contains aggregate functions then the EP_Agg
-** property on the expression is set.
-**
-** An error message is left in pParse if anything is amiss. The number
-** if errors is returned.
-*/
-SQLITE_PRIVATE int sqlite3ResolveExprNames(
- NameContext *pNC, /* Namespace to resolve expressions in. */
- Expr *pExpr /* The expression to be analyzed. */
-){
- int savedHasAgg;
- Walker w;
-
- if( pExpr==0 ) return 0;
-#if SQLITE_MAX_EXPR_DEPTH>0
- {
- Parse *pParse = pNC->pParse;
- if( sqlite3ExprCheckHeight(pParse, pExpr->nHeight+pNC->pParse->nHeight) ){
- return 1;
- }
- pParse->nHeight += pExpr->nHeight;
- }
-#endif
- savedHasAgg = pNC->hasAgg;
- pNC->hasAgg = 0;
- w.xExprCallback = resolveExprStep;
- w.xSelectCallback = resolveSelectStep;
- w.pParse = pNC->pParse;
- w.u.pNC = pNC;
- sqlite3WalkExpr(&w, pExpr);
-#if SQLITE_MAX_EXPR_DEPTH>0
- pNC->pParse->nHeight -= pExpr->nHeight;
-#endif
- if( pNC->nErr>0 || w.pParse->nErr>0 ){
- ExprSetProperty(pExpr, EP_Error);
- }
- if( pNC->hasAgg ){
- ExprSetProperty(pExpr, EP_Agg);
- }else if( savedHasAgg ){
- pNC->hasAgg = 1;
- }
- return ExprHasProperty(pExpr, EP_Error);
-}
-
-
-/*
-** Resolve all names in all expressions of a SELECT and in all
-** decendents of the SELECT, including compounds off of p->pPrior,
-** subqueries in expressions, and subqueries used as FROM clause
-** terms.
-**
-** See sqlite3ResolveExprNames() for a description of the kinds of
-** transformations that occur.
-**
-** All SELECT statements should have been expanded using
-** sqlite3SelectExpand() prior to invoking this routine.
-*/
-SQLITE_PRIVATE void sqlite3ResolveSelectNames(
- Parse *pParse, /* The parser context */
- Select *p, /* The SELECT statement being coded. */
- NameContext *pOuterNC /* Name context for parent SELECT statement */
-){
- Walker w;
-
- assert( p!=0 );
- w.xExprCallback = resolveExprStep;
- w.xSelectCallback = resolveSelectStep;
- w.pParse = pParse;
- w.u.pNC = pOuterNC;
- sqlite3WalkSelect(&w, p);
-}
-
-/************** End of resolve.c *********************************************/
-/************** Begin file expr.c ********************************************/
-/*
-** 2001 September 15
-**
-** 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 routines used for analyzing expressions and
-** for generating VDBE code that evaluates expressions in SQLite.
-*/
-
-/*
-** Return the 'affinity' of the expression pExpr if any.
-**
-** If pExpr is a column, a reference to a column via an 'AS' alias,
-** or a sub-select with a column as the return value, then the
-** affinity of that column is returned. Otherwise, 0x00 is returned,
-** indicating no affinity for the expression.
-**
-** i.e. the WHERE clause expresssions in the following statements all
-** have an affinity:
-**
-** CREATE TABLE t1(a);
-** SELECT * FROM t1 WHERE a;
-** SELECT a AS b FROM t1 WHERE b;
-** SELECT * FROM t1 WHERE (select a from t1);
-*/
-SQLITE_PRIVATE char sqlite3ExprAffinity(Expr *pExpr){
- int op = pExpr->op;
- if( op==TK_SELECT ){
- assert( pExpr->flags&EP_xIsSelect );
- return sqlite3ExprAffinity(pExpr->x.pSelect->pEList->a[0].pExpr);
- }
-#ifndef SQLITE_OMIT_CAST
- if( op==TK_CAST ){
- assert( !ExprHasProperty(pExpr, EP_IntValue) );
- return sqlite3AffinityType(pExpr->u.zToken);
- }
-#endif
- if( (op==TK_AGG_COLUMN || op==TK_COLUMN || op==TK_REGISTER)
- && pExpr->pTab!=0
- ){
- /* op==TK_REGISTER && pExpr->pTab!=0 happens when pExpr was originally
- ** a TK_COLUMN but was previously evaluated and cached in a register */
- int j = pExpr->iColumn;
- if( j<0 ) return SQLITE_AFF_INTEGER;
- assert( pExpr->pTab && j<pExpr->pTab->nCol );
- return pExpr->pTab->aCol[j].affinity;
- }
- return pExpr->affinity;
-}
-
-/*
-** Set the collating sequence for expression pExpr to be the collating
-** sequence named by pToken. Return a pointer to the revised expression.
-** The collating sequence is marked as "explicit" using the EP_ExpCollate
-** flag. An explicit collating sequence will override implicit
-** collating sequences.
-*/
-SQLITE_PRIVATE Expr *sqlite3ExprSetColl(Parse *pParse, Expr *pExpr, Token *pCollName){
- char *zColl = 0; /* Dequoted name of collation sequence */
- CollSeq *pColl;
- sqlite3 *db = pParse->db;
- zColl = sqlite3NameFromToken(db, pCollName);
- if( pExpr && zColl ){
- pColl = sqlite3LocateCollSeq(pParse, zColl);
- if( pColl ){
- pExpr->pColl = pColl;
- pExpr->flags |= EP_ExpCollate;
- }
- }
- sqlite3DbFree(db, zColl);
- return pExpr;
-}
-
-/*
-** Return the default collation sequence for the expression pExpr. If
-** there is no default collation type, return 0.
-*/
-SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){
- CollSeq *pColl = 0;
- Expr *p = pExpr;
- while( ALWAYS(p) ){
- int op;
- pColl = p->pColl;
- if( pColl ) break;
- op = p->op;
- if( p->pTab!=0 && (
- op==TK_AGG_COLUMN || op==TK_COLUMN || op==TK_REGISTER || op==TK_TRIGGER
- )){
- /* op==TK_REGISTER && p->pTab!=0 happens when pExpr was originally
- ** a TK_COLUMN but was previously evaluated and cached in a register */
- const char *zColl;
- int j = p->iColumn;
- if( j>=0 ){
- sqlite3 *db = pParse->db;
- zColl = p->pTab->aCol[j].zColl;
- pColl = sqlite3FindCollSeq(db, ENC(db), zColl, 0);
- pExpr->pColl = pColl;
- }
- break;
- }
- if( op!=TK_CAST && op!=TK_UPLUS ){
- break;
- }
- p = p->pLeft;
- }
- if( sqlite3CheckCollSeq(pParse, pColl) ){
- pColl = 0;
- }
- return pColl;
-}
-
-/*
-** pExpr is an operand of a comparison operator. aff2 is the
-** type affinity of the other operand. This routine returns the
-** type affinity that should be used for the comparison operator.
-*/
-SQLITE_PRIVATE char sqlite3CompareAffinity(Expr *pExpr, char aff2){
- char aff1 = sqlite3ExprAffinity(pExpr);
- if( aff1 && aff2 ){
- /* Both sides of the comparison are columns. If one has numeric
- ** affinity, use that. Otherwise use no affinity.
- */
- if( sqlite3IsNumericAffinity(aff1) || sqlite3IsNumericAffinity(aff2) ){
- return SQLITE_AFF_NUMERIC;
- }else{
- return SQLITE_AFF_NONE;
- }
- }else if( !aff1 && !aff2 ){
- /* Neither side of the comparison is a column. Compare the
- ** results directly.
- */
- return SQLITE_AFF_NONE;
- }else{
- /* One side is a column, the other is not. Use the columns affinity. */
- assert( aff1==0 || aff2==0 );
- return (aff1 + aff2);
- }
-}
-
-/*
-** pExpr is a comparison operator. Return the type affinity that should
-** be applied to both operands prior to doing the comparison.
-*/
-static char comparisonAffinity(Expr *pExpr){
- char aff;
- assert( pExpr->op==TK_EQ || pExpr->op==TK_IN || pExpr->op==TK_LT ||
- pExpr->op==TK_GT || pExpr->op==TK_GE || pExpr->op==TK_LE ||
- pExpr->op==TK_NE );
- assert( pExpr->pLeft );
- aff = sqlite3ExprAffinity(pExpr->pLeft);
- if( pExpr->pRight ){
- aff = sqlite3CompareAffinity(pExpr->pRight, aff);
- }else if( ExprHasProperty(pExpr, EP_xIsSelect) ){
- aff = sqlite3CompareAffinity(pExpr->x.pSelect->pEList->a[0].pExpr, aff);
- }else if( !aff ){
- aff = SQLITE_AFF_NONE;
- }
- return aff;
-}
-
-/*
-** pExpr is a comparison expression, eg. '=', '<', IN(...) etc.
-** idx_affinity is the affinity of an indexed column. Return true
-** if the index with affinity idx_affinity may be used to implement
-** the comparison in pExpr.
-*/
-SQLITE_PRIVATE int sqlite3IndexAffinityOk(Expr *pExpr, char idx_affinity){
- char aff = comparisonAffinity(pExpr);
- switch( aff ){
- case SQLITE_AFF_NONE:
- return 1;
- case SQLITE_AFF_TEXT:
- return idx_affinity==SQLITE_AFF_TEXT;
- default:
- return sqlite3IsNumericAffinity(idx_affinity);
- }
-}
-
-/*
-** Return the P5 value that should be used for a binary comparison
-** opcode (OP_Eq, OP_Ge etc.) used to compare pExpr1 and pExpr2.
-*/
-static u8 binaryCompareP5(Expr *pExpr1, Expr *pExpr2, int jumpIfNull){
- u8 aff = (char)sqlite3ExprAffinity(pExpr2);
- aff = (u8)sqlite3CompareAffinity(pExpr1, aff) | (u8)jumpIfNull;
- return aff;
-}
-
-/*
-** Return a pointer to the collation sequence that should be used by
-** a binary comparison operator comparing pLeft and pRight.
-**
-** If the left hand expression has a collating sequence type, then it is
-** used. Otherwise the collation sequence for the right hand expression
-** is used, or the default (BINARY) if neither expression has a collating
-** type.
-**
-** Argument pRight (but not pLeft) may be a null pointer. In this case,
-** it is not considered.
-*/
-SQLITE_PRIVATE CollSeq *sqlite3BinaryCompareCollSeq(
- Parse *pParse,
- Expr *pLeft,
- Expr *pRight
-){
- CollSeq *pColl;
- assert( pLeft );
- if( pLeft->flags & EP_ExpCollate ){
- assert( pLeft->pColl );
- pColl = pLeft->pColl;
- }else if( pRight && pRight->flags & EP_ExpCollate ){
- assert( pRight->pColl );
- pColl = pRight->pColl;
- }else{
- pColl = sqlite3ExprCollSeq(pParse, pLeft);
- if( !pColl ){
- pColl = sqlite3ExprCollSeq(pParse, pRight);
- }
- }
- return pColl;
-}
-
-/*
-** Generate the operands for a comparison operation. Before
-** generating the code for each operand, set the EP_AnyAff
-** flag on the expression so that it will be able to used a
-** cached column value that has previously undergone an
-** affinity change.
-*/
-static void codeCompareOperands(
- Parse *pParse, /* Parsing and code generating context */
- Expr *pLeft, /* The left operand */
- int *pRegLeft, /* Register where left operand is stored */
- int *pFreeLeft, /* Free this register when done */
- Expr *pRight, /* The right operand */
- int *pRegRight, /* Register where right operand is stored */
- int *pFreeRight /* Write temp register for right operand there */
-){
- while( pLeft->op==TK_UPLUS ) pLeft = pLeft->pLeft;
- pLeft->flags |= EP_AnyAff;
- *pRegLeft = sqlite3ExprCodeTemp(pParse, pLeft, pFreeLeft);
- while( pRight->op==TK_UPLUS ) pRight = pRight->pLeft;
- pRight->flags |= EP_AnyAff;
- *pRegRight = sqlite3ExprCodeTemp(pParse, pRight, pFreeRight);
-}
-
-/*
-** Generate code for a comparison operator.
-*/
-static int codeCompare(
- Parse *pParse, /* The parsing (and code generating) context */
- Expr *pLeft, /* The left operand */
- Expr *pRight, /* The right operand */
- int opcode, /* The comparison opcode */
- int in1, int in2, /* Register holding operands */
- int dest, /* Jump here if true. */
- int jumpIfNull /* If true, jump if either operand is NULL */
-){
- int p5;
- int addr;
- CollSeq *p4;
-
- p4 = sqlite3BinaryCompareCollSeq(pParse, pLeft, pRight);
- p5 = binaryCompareP5(pLeft, pRight, jumpIfNull);
- addr = sqlite3VdbeAddOp4(pParse->pVdbe, opcode, in2, dest, in1,
- (void*)p4, P4_COLLSEQ);
- sqlite3VdbeChangeP5(pParse->pVdbe, (u8)p5);
- if( (p5 & SQLITE_AFF_MASK)!=SQLITE_AFF_NONE ){
- sqlite3ExprCacheAffinityChange(pParse, in1, 1);
- sqlite3ExprCacheAffinityChange(pParse, in2, 1);
- }
- return addr;
-}
-
-#if SQLITE_MAX_EXPR_DEPTH>0
-/*
-** Check that argument nHeight is less than or equal to the maximum
-** expression depth allowed. If it is not, leave an error message in
-** pParse.
-*/
-SQLITE_PRIVATE int sqlite3ExprCheckHeight(Parse *pParse, int nHeight){
- int rc = SQLITE_OK;
- int mxHeight = pParse->db->aLimit[SQLITE_LIMIT_EXPR_DEPTH];
- if( nHeight>mxHeight ){
- sqlite3ErrorMsg(pParse,
- "Expression tree is too large (maximum depth %d)", mxHeight
- );
- rc = SQLITE_ERROR;
- }
- return rc;
-}
-
-/* The following three functions, heightOfExpr(), heightOfExprList()
-** and heightOfSelect(), are used to determine the maximum height
-** of any expression tree referenced by the structure passed as the
-** first argument.
-**
-** If this maximum height is greater than the current value pointed
-** to by pnHeight, the second parameter, then set *pnHeight to that
-** value.
-*/
-static void heightOfExpr(Expr *p, int *pnHeight){
- if( p ){
- if( p->nHeight>*pnHeight ){
- *pnHeight = p->nHeight;
- }
- }
-}
-static void heightOfExprList(ExprList *p, int *pnHeight){
- if( p ){
- int i;
- for(i=0; i<p->nExpr; i++){
- heightOfExpr(p->a[i].pExpr, pnHeight);
- }
- }
-}
-static void heightOfSelect(Select *p, int *pnHeight){
- if( p ){
- heightOfExpr(p->pWhere, pnHeight);
- heightOfExpr(p->pHaving, pnHeight);
- heightOfExpr(p->pLimit, pnHeight);
- heightOfExpr(p->pOffset, pnHeight);
- heightOfExprList(p->pEList, pnHeight);
- heightOfExprList(p->pGroupBy, pnHeight);
- heightOfExprList(p->pOrderBy, pnHeight);
- heightOfSelect(p->pPrior, pnHeight);
- }
-}
-
-/*
-** Set the Expr.nHeight variable in the structure passed as an
-** argument. An expression with no children, Expr.pList or
-** Expr.pSelect member has a height of 1. Any other expression
-** has a height equal to the maximum height of any other
-** referenced Expr plus one.
-*/
-static void exprSetHeight(Expr *p){
- int nHeight = 0;
- heightOfExpr(p->pLeft, &nHeight);
- heightOfExpr(p->pRight, &nHeight);
- if( ExprHasProperty(p, EP_xIsSelect) ){
- heightOfSelect(p->x.pSelect, &nHeight);
- }else{
- heightOfExprList(p->x.pList, &nHeight);
- }
- p->nHeight = nHeight + 1;
-}
-
-/*
-** Set the Expr.nHeight variable using the exprSetHeight() function. If
-** the height is greater than the maximum allowed expression depth,
-** leave an error in pParse.
-*/
-SQLITE_PRIVATE void sqlite3ExprSetHeight(Parse *pParse, Expr *p){
- exprSetHeight(p);
- sqlite3ExprCheckHeight(pParse, p->nHeight);
-}
-
-/*
-** Return the maximum height of any expression tree referenced
-** by the select statement passed as an argument.
-*/
-SQLITE_PRIVATE int sqlite3SelectExprHeight(Select *p){
- int nHeight = 0;
- heightOfSelect(p, &nHeight);
- return nHeight;
-}
-#else
- #define exprSetHeight(y)
-#endif /* SQLITE_MAX_EXPR_DEPTH>0 */
-
-/*
-** This routine is the core allocator for Expr nodes.
-**
-** Construct a new expression node and return a pointer to it. Memory
-** for this node and for the pToken argument is a single allocation
-** obtained from sqlite3DbMalloc(). The calling function
-** is responsible for making sure the node eventually gets freed.
-**
-** If dequote is true, then the token (if it exists) is dequoted.
-** If dequote is false, no dequoting is performance. The deQuote
-** parameter is ignored if pToken is NULL or if the token does not
-** appear to be quoted. If the quotes were of the form "..." (double-quotes)
-** then the EP_DblQuoted flag is set on the expression node.
-**
-** Special case: If op==TK_INTEGER and pToken points to a string that
-** can be translated into a 32-bit integer, then the token is not
-** stored in u.zToken. Instead, the integer values is written
-** into u.iValue and the EP_IntValue flag is set. No extra storage
-** is allocated to hold the integer text and the dequote flag is ignored.
-*/
-SQLITE_PRIVATE Expr *sqlite3ExprAlloc(
- sqlite3 *db, /* Handle for sqlite3DbMallocZero() (may be null) */
- int op, /* Expression opcode */
- const Token *pToken, /* Token argument. Might be NULL */
- int dequote /* True to dequote */
-){
- Expr *pNew;
- int nExtra = 0;
- int iValue = 0;
-
- if( pToken ){
- if( op!=TK_INTEGER || pToken->z==0
- || sqlite3GetInt32(pToken->z, &iValue)==0 ){
- nExtra = pToken->n+1;
- }
- }
- pNew = sqlite3DbMallocZero(db, sizeof(Expr)+nExtra);
- if( pNew ){
- pNew->op = (u8)op;
- pNew->iAgg = -1;
- if( pToken ){
- if( nExtra==0 ){
- pNew->flags |= EP_IntValue;
- pNew->u.iValue = iValue;
- }else{
- int c;
- pNew->u.zToken = (char*)&pNew[1];
- memcpy(pNew->u.zToken, pToken->z, pToken->n);
- pNew->u.zToken[pToken->n] = 0;
- if( dequote && nExtra>=3
- && ((c = pToken->z[0])=='\'' || c=='"' || c=='[' || c=='`') ){
- sqlite3Dequote(pNew->u.zToken);
- if( c=='"' ) pNew->flags |= EP_DblQuoted;
- }
- }
- }
-#if SQLITE_MAX_EXPR_DEPTH>0
- pNew->nHeight = 1;
-#endif
- }
- return pNew;
-}
-
-/*
-** Allocate a new expression node from a zero-terminated token that has
-** already been dequoted.
-*/
-SQLITE_PRIVATE Expr *sqlite3Expr(
- sqlite3 *db, /* Handle for sqlite3DbMallocZero() (may be null) */
- int op, /* Expression opcode */
- const char *zToken /* Token argument. Might be NULL */
-){
- Token x;
- x.z = zToken;
- x.n = zToken ? sqlite3Strlen30(zToken) : 0;
- return sqlite3ExprAlloc(db, op, &x, 0);
-}
-
-/*
-** Attach subtrees pLeft and pRight to the Expr node pRoot.
-**
-** If pRoot==NULL that means that a memory allocation error has occurred.
-** In that case, delete the subtrees pLeft and pRight.
-*/
-SQLITE_PRIVATE void sqlite3ExprAttachSubtrees(
- sqlite3 *db,
- Expr *pRoot,
- Expr *pLeft,
- Expr *pRight
-){
- if( pRoot==0 ){
- assert( db->mallocFailed );
- sqlite3ExprDelete(db, pLeft);
- sqlite3ExprDelete(db, pRight);
- }else{
- if( pRight ){
- pRoot->pRight = pRight;
- if( pRight->flags & EP_ExpCollate ){
- pRoot->flags |= EP_ExpCollate;
- pRoot->pColl = pRight->pColl;
- }
- }
- if( pLeft ){
- pRoot->pLeft = pLeft;
- if( pLeft->flags & EP_ExpCollate ){
- pRoot->flags |= EP_ExpCollate;
- pRoot->pColl = pLeft->pColl;
- }
- }
- exprSetHeight(pRoot);
- }
-}
-
-/*
-** Allocate a Expr node which joins as many as two subtrees.
-**
-** One or both of the subtrees can be NULL. Return a pointer to the new
-** Expr node. Or, if an OOM error occurs, set pParse->db->mallocFailed,
-** free the subtrees and return NULL.
-*/
-SQLITE_PRIVATE Expr *sqlite3PExpr(
- Parse *pParse, /* Parsing context */
- int op, /* Expression opcode */
- Expr *pLeft, /* Left operand */
- Expr *pRight, /* Right operand */
- const Token *pToken /* Argument token */
-){
- Expr *p = sqlite3ExprAlloc(pParse->db, op, pToken, 1);
- sqlite3ExprAttachSubtrees(pParse->db, p, pLeft, pRight);
- return p;
-}
-
-/*
-** Join two expressions using an AND operator. If either expression is
-** NULL, then just return the other expression.
-*/
-SQLITE_PRIVATE Expr *sqlite3ExprAnd(sqlite3 *db, Expr *pLeft, Expr *pRight){
- if( pLeft==0 ){
- return pRight;
- }else if( pRight==0 ){
- return pLeft;
- }else{
- Expr *pNew = sqlite3ExprAlloc(db, TK_AND, 0, 0);
- sqlite3ExprAttachSubtrees(db, pNew, pLeft, pRight);
- return pNew;
- }
-}
-
-/*
-** Construct a new expression node for a function with multiple
-** arguments.
-*/
-SQLITE_PRIVATE Expr *sqlite3ExprFunction(Parse *pParse, ExprList *pList, Token *pToken){
- Expr *pNew;
- sqlite3 *db = pParse->db;
- assert( pToken );
- pNew = sqlite3ExprAlloc(db, TK_FUNCTION, pToken, 1);
- if( pNew==0 ){
- sqlite3ExprListDelete(db, pList); /* Avoid memory leak when malloc fails */
- return 0;
- }
- pNew->x.pList = pList;
- assert( !ExprHasProperty(pNew, EP_xIsSelect) );
- sqlite3ExprSetHeight(pParse, pNew);
- return pNew;
-}
-
-/*
-** Assign a variable number to an expression that encodes a wildcard
-** in the original SQL statement.
-**
-** Wildcards consisting of a single "?" are assigned the next sequential
-** variable number.
-**
-** Wildcards of the form "?nnn" are assigned the number "nnn". We make
-** sure "nnn" is not too be to avoid a denial of service attack when
-** the SQL statement comes from an external source.
-**
-** Wildcards of the form ":aaa", "@aaa", or "$aaa" are assigned the same number
-** as the previous instance of the same wildcard. Or if this is the first
-** instance of the wildcard, the next sequenial variable number is
-** assigned.
-*/
-SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr){
- sqlite3 *db = pParse->db;
- const char *z;
-
- if( pExpr==0 ) return;
- assert( !ExprHasAnyProperty(pExpr, EP_IntValue|EP_Reduced|EP_TokenOnly) );
- z = pExpr->u.zToken;
- assert( z!=0 );
- assert( z[0]!=0 );
- if( z[1]==0 ){
- /* Wildcard of the form "?". Assign the next variable number */
- assert( z[0]=='?' );
- pExpr->iTable = ++pParse->nVar;
- }else if( z[0]=='?' ){
- /* Wildcard of the form "?nnn". Convert "nnn" to an integer and
- ** use it as the variable number */
- int i;
- pExpr->iTable = i = atoi((char*)&z[1]);
- testcase( i==0 );
- testcase( i==1 );
- testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]-1 );
- testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] );
- if( i<1 || i>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){
- sqlite3ErrorMsg(pParse, "variable number must be between ?1 and ?%d",
- db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]);
- }
- if( i>pParse->nVar ){
- pParse->nVar = i;
- }
- }else{
- /* Wildcards like ":aaa", "$aaa" or "@aaa". Reuse the same variable
- ** number as the prior appearance of the same name, or if the name
- ** has never appeared before, reuse the same variable number
- */
- int i;
- u32 n;
- n = sqlite3Strlen30(z);
- for(i=0; i<pParse->nVarExpr; i++){
- Expr *pE = pParse->apVarExpr[i];
- assert( pE!=0 );
- if( memcmp(pE->u.zToken, z, n)==0 && pE->u.zToken[n]==0 ){
- pExpr->iTable = pE->iTable;
- break;
- }
- }
- if( i>=pParse->nVarExpr ){
- pExpr->iTable = ++pParse->nVar;
- if( pParse->nVarExpr>=pParse->nVarExprAlloc-1 ){
- pParse->nVarExprAlloc += pParse->nVarExprAlloc + 10;
- pParse->apVarExpr =
- sqlite3DbReallocOrFree(
- db,
- pParse->apVarExpr,
- pParse->nVarExprAlloc*sizeof(pParse->apVarExpr[0])
- );
- }
- if( !db->mallocFailed ){
- assert( pParse->apVarExpr!=0 );
- pParse->apVarExpr[pParse->nVarExpr++] = pExpr;
- }
- }
- }
- if( !pParse->nErr && pParse->nVar>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){
- sqlite3ErrorMsg(pParse, "too many SQL variables");
- }
-}
-
-/*
-** Clear an expression structure without deleting the structure itself.
-** Substructure is deleted.
-*/
-SQLITE_PRIVATE void sqlite3ExprClear(sqlite3 *db, Expr *p){
- assert( p!=0 );
- if( !ExprHasAnyProperty(p, EP_TokenOnly) ){
- sqlite3ExprDelete(db, p->pLeft);
- sqlite3ExprDelete(db, p->pRight);
- if( !ExprHasProperty(p, EP_Reduced) && (p->flags2 & EP2_MallocedToken)!=0 ){
- sqlite3DbFree(db, p->u.zToken);
- }
- if( ExprHasProperty(p, EP_xIsSelect) ){
- sqlite3SelectDelete(db, p->x.pSelect);
- }else{
- sqlite3ExprListDelete(db, p->x.pList);
- }
- }
-}
-
-/*
-** Recursively delete an expression tree.
-*/
-SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3 *db, Expr *p){
- if( p==0 ) return;
- sqlite3ExprClear(db, p);
- if( !ExprHasProperty(p, EP_Static) ){
- sqlite3DbFree(db, p);
- }
-}
-
-/*
-** Return the number of bytes allocated for the expression structure
-** passed as the first argument. This is always one of EXPR_FULLSIZE,
-** EXPR_REDUCEDSIZE or EXPR_TOKENONLYSIZE.
-*/
-static int exprStructSize(Expr *p){
- if( ExprHasProperty(p, EP_TokenOnly) ) return EXPR_TOKENONLYSIZE;
- if( ExprHasProperty(p, EP_Reduced) ) return EXPR_REDUCEDSIZE;
- return EXPR_FULLSIZE;
-}
-
-/*
-** The dupedExpr*Size() routines each return the number of bytes required
-** to store a copy of an expression or expression tree. They differ in
-** how much of the tree is measured.
-**
-** dupedExprStructSize() Size of only the Expr structure
-** dupedExprNodeSize() Size of Expr + space for token
-** dupedExprSize() Expr + token + subtree components
-**
-***************************************************************************
-**
-** The dupedExprStructSize() function returns two values OR-ed together:
-** (1) the space required for a copy of the Expr structure only and
-** (2) the EP_xxx flags that indicate what the structure size should be.
-** The return values is always one of:
-**
-** EXPR_FULLSIZE
-** EXPR_REDUCEDSIZE | EP_Reduced
-** EXPR_TOKENONLYSIZE | EP_TokenOnly
-**
-** The size of the structure can be found by masking the return value
-** of this routine with 0xfff. The flags can be found by masking the
-** return value with EP_Reduced|EP_TokenOnly.
-**
-** Note that with flags==EXPRDUP_REDUCE, this routines works on full-size
-** (unreduced) Expr objects as they or originally constructed by the parser.
-** During expression analysis, extra information is computed and moved into
-** later parts of teh Expr object and that extra information might get chopped
-** off if the expression is reduced. Note also that it does not work to
-** make a EXPRDUP_REDUCE copy of a reduced expression. It is only legal
-** to reduce a pristine expression tree from the parser. The implementation
-** of dupedExprStructSize() contain multiple assert() statements that attempt
-** to enforce this constraint.
-*/
-static int dupedExprStructSize(Expr *p, int flags){
- int nSize;
- assert( flags==EXPRDUP_REDUCE || flags==0 ); /* Only one flag value allowed */
- if( 0==(flags&EXPRDUP_REDUCE) ){
- nSize = EXPR_FULLSIZE;
- }else{
- assert( !ExprHasAnyProperty(p, EP_TokenOnly|EP_Reduced) );
- assert( !ExprHasProperty(p, EP_FromJoin) );
- assert( (p->flags2 & EP2_MallocedToken)==0 );
- assert( (p->flags2 & EP2_Irreducible)==0 );
- if( p->pLeft || p->pRight || p->pColl || p->x.pList ){
- nSize = EXPR_REDUCEDSIZE | EP_Reduced;
- }else{
- nSize = EXPR_TOKENONLYSIZE | EP_TokenOnly;
- }
- }
- return nSize;
-}
-
-/*
-** This function returns the space in bytes required to store the copy
-** of the Expr structure and a copy of the Expr.u.zToken string (if that
-** string is defined.)
-*/
-static int dupedExprNodeSize(Expr *p, int flags){
- int nByte = dupedExprStructSize(p, flags) & 0xfff;
- if( !ExprHasProperty(p, EP_IntValue) && p->u.zToken ){
- nByte += sqlite3Strlen30(p->u.zToken)+1;
- }
- return ROUND8(nByte);
-}
-
-/*
-** Return the number of bytes required to create a duplicate of the
-** expression passed as the first argument. The second argument is a
-** mask containing EXPRDUP_XXX flags.
-**
-** The value returned includes space to create a copy of the Expr struct
-** itself and the buffer referred to by Expr.u.zToken, if any.
-**
-** If the EXPRDUP_REDUCE flag is set, then the return value includes
-** space to duplicate all Expr nodes in the tree formed by Expr.pLeft
-** and Expr.pRight variables (but not for any structures pointed to or
-** descended from the Expr.x.pList or Expr.x.pSelect variables).
-*/
-static int dupedExprSize(Expr *p, int flags){
- int nByte = 0;
- if( p ){
- nByte = dupedExprNodeSize(p, flags);
- if( flags&EXPRDUP_REDUCE ){
- nByte += dupedExprSize(p->pLeft, flags) + dupedExprSize(p->pRight, flags);
- }
- }
- return nByte;
-}
-
-/*
-** This function is similar to sqlite3ExprDup(), except that if pzBuffer
-** is not NULL then *pzBuffer is assumed to point to a buffer large enough
-** to store the copy of expression p, the copies of p->u.zToken
-** (if applicable), and the copies of the p->pLeft and p->pRight expressions,
-** if any. Before returning, *pzBuffer is set to the first byte passed the
-** portion of the buffer copied into by this function.
-*/
-static Expr *exprDup(sqlite3 *db, Expr *p, int flags, u8 **pzBuffer){
- Expr *pNew = 0; /* Value to return */
- if( p ){
- const int isReduced = (flags&EXPRDUP_REDUCE);
- u8 *zAlloc;
- u32 staticFlag = 0;
-
- assert( pzBuffer==0 || isReduced );
-
- /* Figure out where to write the new Expr structure. */
- if( pzBuffer ){
- zAlloc = *pzBuffer;
- staticFlag = EP_Static;
- }else{
- zAlloc = sqlite3DbMallocRaw(db, dupedExprSize(p, flags));
- }
- pNew = (Expr *)zAlloc;
-
- if( pNew ){
- /* Set nNewSize to the size allocated for the structure pointed to
- ** by pNew. This is either EXPR_FULLSIZE, EXPR_REDUCEDSIZE or
- ** EXPR_TOKENONLYSIZE. nToken is set to the number of bytes consumed
- ** by the copy of the p->u.zToken string (if any).
- */
- const unsigned nStructSize = dupedExprStructSize(p, flags);
- const int nNewSize = nStructSize & 0xfff;
- int nToken;
- if( !ExprHasProperty(p, EP_IntValue) && p->u.zToken ){
- nToken = sqlite3Strlen30(p->u.zToken) + 1;
- }else{
- nToken = 0;
- }
- if( isReduced ){
- assert( ExprHasProperty(p, EP_Reduced)==0 );
- memcpy(zAlloc, p, nNewSize);
- }else{
- int nSize = exprStructSize(p);
- memcpy(zAlloc, p, nSize);
- memset(&zAlloc[nSize], 0, EXPR_FULLSIZE-nSize);
- }
-
- /* Set the EP_Reduced, EP_TokenOnly, and EP_Static flags appropriately. */
- pNew->flags &= ~(EP_Reduced|EP_TokenOnly|EP_Static);
- pNew->flags |= nStructSize & (EP_Reduced|EP_TokenOnly);
- pNew->flags |= staticFlag;
-
- /* Copy the p->u.zToken string, if any. */
- if( nToken ){
- char *zToken = pNew->u.zToken = (char*)&zAlloc[nNewSize];
- memcpy(zToken, p->u.zToken, nToken);
- }
-
- if( 0==((p->flags|pNew->flags) & EP_TokenOnly) ){
- /* Fill in the pNew->x.pSelect or pNew->x.pList member. */
- if( ExprHasProperty(p, EP_xIsSelect) ){
- pNew->x.pSelect = sqlite3SelectDup(db, p->x.pSelect, isReduced);
- }else{
- pNew->x.pList = sqlite3ExprListDup(db, p->x.pList, isReduced);
- }
- }
-
- /* Fill in pNew->pLeft and pNew->pRight. */
- if( ExprHasAnyProperty(pNew, EP_Reduced|EP_TokenOnly) ){
- zAlloc += dupedExprNodeSize(p, flags);
- if( ExprHasProperty(pNew, EP_Reduced) ){
- pNew->pLeft = exprDup(db, p->pLeft, EXPRDUP_REDUCE, &zAlloc);
- pNew->pRight = exprDup(db, p->pRight, EXPRDUP_REDUCE, &zAlloc);
- }
- if( pzBuffer ){
- *pzBuffer = zAlloc;
- }
- }else{
- pNew->flags2 = 0;
- if( !ExprHasAnyProperty(p, EP_TokenOnly) ){
- pNew->pLeft = sqlite3ExprDup(db, p->pLeft, 0);
- pNew->pRight = sqlite3ExprDup(db, p->pRight, 0);
- }
- }
-
- }
- }
- return pNew;
-}
-
-/*
-** The following group of routines make deep copies of expressions,
-** expression lists, ID lists, and select statements. The copies can
-** be deleted (by being passed to their respective ...Delete() routines)
-** without effecting the originals.
-**
-** The expression list, ID, and source lists return by sqlite3ExprListDup(),
-** sqlite3IdListDup(), and sqlite3SrcListDup() can not be further expanded
-** by subsequent calls to sqlite*ListAppend() routines.
-**
-** Any tables that the SrcList might point to are not duplicated.
-**
-** The flags parameter contains a combination of the EXPRDUP_XXX flags.
-** If the EXPRDUP_REDUCE flag is set, then the structure returned is a
-** truncated version of the usual Expr structure that will be stored as
-** part of the in-memory representation of the database schema.
-*/
-SQLITE_PRIVATE Expr *sqlite3ExprDup(sqlite3 *db, Expr *p, int flags){
- return exprDup(db, p, flags, 0);
-}
-SQLITE_PRIVATE ExprList *sqlite3ExprListDup(sqlite3 *db, ExprList *p, int flags){
- ExprList *pNew;
- struct ExprList_item *pItem, *pOldItem;
- int i;
- if( p==0 ) return 0;
- pNew = sqlite3DbMallocRaw(db, sizeof(*pNew) );
- if( pNew==0 ) return 0;
- pNew->iECursor = 0;
- pNew->nExpr = pNew->nAlloc = p->nExpr;
- pNew->a = pItem = sqlite3DbMallocRaw(db, p->nExpr*sizeof(p->a[0]) );
- if( pItem==0 ){
- sqlite3DbFree(db, pNew);
- return 0;
- }
- pOldItem = p->a;
- for(i=0; i<p->nExpr; i++, pItem++, pOldItem++){
- Expr *pOldExpr = pOldItem->pExpr;
- pItem->pExpr = sqlite3ExprDup(db, pOldExpr, flags);
- pItem->zName = sqlite3DbStrDup(db, pOldItem->zName);
- pItem->zSpan = sqlite3DbStrDup(db, pOldItem->zSpan);
- pItem->sortOrder = pOldItem->sortOrder;
- pItem->done = 0;
- pItem->iCol = pOldItem->iCol;
- pItem->iAlias = pOldItem->iAlias;
- }
- return pNew;
-}
-
-/*
-** If cursors, triggers, views and subqueries are all omitted from
-** the build, then none of the following routines, except for
-** sqlite3SelectDup(), can be called. sqlite3SelectDup() is sometimes
-** called with a NULL argument.
-*/
-#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER) \
- || !defined(SQLITE_OMIT_SUBQUERY)
-SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3 *db, SrcList *p, int flags){
- SrcList *pNew;
- int i;
- int nByte;
- if( p==0 ) return 0;
- nByte = sizeof(*p) + (p->nSrc>0 ? sizeof(p->a[0]) * (p->nSrc-1) : 0);
- pNew = sqlite3DbMallocRaw(db, nByte );
- if( pNew==0 ) return 0;
- pNew->nSrc = pNew->nAlloc = p->nSrc;
- for(i=0; i<p->nSrc; i++){
- struct SrcList_item *pNewItem = &pNew->a[i];
- struct SrcList_item *pOldItem = &p->a[i];
- Table *pTab;
- pNewItem->zDatabase = sqlite3DbStrDup(db, pOldItem->zDatabase);
- pNewItem->zName = sqlite3DbStrDup(db, pOldItem->zName);
- pNewItem->zAlias = sqlite3DbStrDup(db, pOldItem->zAlias);
- pNewItem->jointype = pOldItem->jointype;
- pNewItem->iCursor = pOldItem->iCursor;
- pNewItem->isPopulated = pOldItem->isPopulated;
- pNewItem->zIndex = sqlite3DbStrDup(db, pOldItem->zIndex);
- pNewItem->notIndexed = pOldItem->notIndexed;
- pNewItem->pIndex = pOldItem->pIndex;
- pTab = pNewItem->pTab = pOldItem->pTab;
- if( pTab ){
- pTab->nRef++;
- }
- pNewItem->pSelect = sqlite3SelectDup(db, pOldItem->pSelect, flags);
- pNewItem->pOn = sqlite3ExprDup(db, pOldItem->pOn, flags);
- pNewItem->pUsing = sqlite3IdListDup(db, pOldItem->pUsing);
- pNewItem->colUsed = pOldItem->colUsed;
- }
- return pNew;
-}
-SQLITE_PRIVATE IdList *sqlite3IdListDup(sqlite3 *db, IdList *p){
- IdList *pNew;
- int i;
- if( p==0 ) return 0;
- pNew = sqlite3DbMallocRaw(db, sizeof(*pNew) );
- if( pNew==0 ) return 0;
- pNew->nId = pNew->nAlloc = p->nId;
- pNew->a = sqlite3DbMallocRaw(db, p->nId*sizeof(p->a[0]) );
- if( pNew->a==0 ){
- sqlite3DbFree(db, pNew);
- return 0;
- }
- for(i=0; i<p->nId; i++){
- struct IdList_item *pNewItem = &pNew->a[i];
- struct IdList_item *pOldItem = &p->a[i];
- pNewItem->zName = sqlite3DbStrDup(db, pOldItem->zName);
- pNewItem->idx = pOldItem->idx;
- }
- return pNew;
-}
-SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3 *db, Select *p, int flags){
- Select *pNew;
- if( p==0 ) return 0;
- pNew = sqlite3DbMallocRaw(db, sizeof(*p) );
- if( pNew==0 ) return 0;
- pNew->pEList = sqlite3ExprListDup(db, p->pEList, flags);
- pNew->pSrc = sqlite3SrcListDup(db, p->pSrc, flags);
- pNew->pWhere = sqlite3ExprDup(db, p->pWhere, flags);
- pNew->pGroupBy = sqlite3ExprListDup(db, p->pGroupBy, 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->pLimit = sqlite3ExprDup(db, p->pLimit, flags);
- pNew->pOffset = sqlite3ExprDup(db, p->pOffset, flags);
- pNew->iLimit = 0;
- pNew->iOffset = 0;
- pNew->selFlags = p->selFlags & ~SF_UsesEphemeral;
- pNew->pRightmost = 0;
- pNew->addrOpenEphm[0] = -1;
- pNew->addrOpenEphm[1] = -1;
- pNew->addrOpenEphm[2] = -1;
- return pNew;
-}
-#else
-SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3 *db, Select *p, int flags){
- assert( p==0 );
- return 0;
-}
-#endif
-
-
-/*
-** Add a new element to the end of an expression list. If pList is
-** initially NULL, then create a new expression list.
-**
-** If a memory allocation error occurs, the entire list is freed and
-** NULL is returned. If non-NULL is returned, then it is guaranteed
-** that the new entry was successfully appended.
-*/
-SQLITE_PRIVATE ExprList *sqlite3ExprListAppend(
- Parse *pParse, /* Parsing context */
- ExprList *pList, /* List to which to append. Might be NULL */
- Expr *pExpr /* Expression to be appended. Might be NULL */
-){
- sqlite3 *db = pParse->db;
- if( pList==0 ){
- pList = sqlite3DbMallocZero(db, sizeof(ExprList) );
- if( pList==0 ){
- goto no_mem;
- }
- assert( pList->nAlloc==0 );
- }
- if( pList->nAlloc<=pList->nExpr ){
- struct ExprList_item *a;
- int n = pList->nAlloc*2 + 4;
- a = sqlite3DbRealloc(db, pList->a, n*sizeof(pList->a[0]));
- if( a==0 ){
- goto no_mem;
- }
- pList->a = a;
- pList->nAlloc = sqlite3DbMallocSize(db, a)/sizeof(a[0]);
- }
- assert( pList->a!=0 );
- if( 1 ){
- struct ExprList_item *pItem = &pList->a[pList->nExpr++];
- memset(pItem, 0, sizeof(*pItem));
- pItem->pExpr = pExpr;
- }
- return pList;
-
-no_mem:
- /* Avoid leaking memory if malloc has failed. */
- sqlite3ExprDelete(db, pExpr);
- sqlite3ExprListDelete(db, pList);
- return 0;
-}
-
-/*
-** Set the ExprList.a[].zName element of the most recently added item
-** on the expression list.
-**
-** pList might be NULL following an OOM error. But pName should never be
-** NULL. If a memory allocation fails, the pParse->db->mallocFailed flag
-** is set.
-*/
-SQLITE_PRIVATE void sqlite3ExprListSetName(
- Parse *pParse, /* Parsing context */
- ExprList *pList, /* List to which to add the span. */
- Token *pName, /* Name to be added */
- int dequote /* True to cause the name to be dequoted */
-){
- assert( pList!=0 || pParse->db->mallocFailed!=0 );
- if( pList ){
- struct ExprList_item *pItem;
- assert( pList->nExpr>0 );
- pItem = &pList->a[pList->nExpr-1];
- assert( pItem->zName==0 );
- pItem->zName = sqlite3DbStrNDup(pParse->db, pName->z, pName->n);
- if( dequote && pItem->zName ) sqlite3Dequote(pItem->zName);
- }
-}
-
-/*
-** Set the ExprList.a[].zSpan element of the most recently added item
-** on the expression list.
-**
-** pList might be NULL following an OOM error. But pSpan should never be
-** NULL. If a memory allocation fails, the pParse->db->mallocFailed flag
-** is set.
-*/
-SQLITE_PRIVATE void sqlite3ExprListSetSpan(
- Parse *pParse, /* Parsing context */
- ExprList *pList, /* List to which to add the span. */
- ExprSpan *pSpan /* The span to be added */
-){
- sqlite3 *db = pParse->db;
- assert( pList!=0 || db->mallocFailed!=0 );
- if( pList ){
- struct ExprList_item *pItem = &pList->a[pList->nExpr-1];
- assert( pList->nExpr>0 );
- assert( db->mallocFailed || pItem->pExpr==pSpan->pExpr );
- sqlite3DbFree(db, pItem->zSpan);
- pItem->zSpan = sqlite3DbStrNDup(db, (char*)pSpan->zStart,
- (int)(pSpan->zEnd - pSpan->zStart));
- }
-}
-
-/*
-** If the expression list pEList contains more than iLimit elements,
-** leave an error message in pParse.
-*/
-SQLITE_PRIVATE void sqlite3ExprListCheckLength(
- Parse *pParse,
- ExprList *pEList,
- const char *zObject
-){
- int mx = pParse->db->aLimit[SQLITE_LIMIT_COLUMN];
- testcase( pEList && pEList->nExpr==mx );
- testcase( pEList && pEList->nExpr==mx+1 );
- if( pEList && pEList->nExpr>mx ){
- sqlite3ErrorMsg(pParse, "too many columns in %s", zObject);
- }
-}
-
-/*
-** Delete an entire expression list.
-*/
-SQLITE_PRIVATE void sqlite3ExprListDelete(sqlite3 *db, ExprList *pList){
- int i;
- struct ExprList_item *pItem;
- if( pList==0 ) return;
- assert( pList->a!=0 || (pList->nExpr==0 && pList->nAlloc==0) );
- assert( pList->nExpr<=pList->nAlloc );
- for(pItem=pList->a, i=0; i<pList->nExpr; i++, pItem++){
- sqlite3ExprDelete(db, pItem->pExpr);
- sqlite3DbFree(db, pItem->zName);
- sqlite3DbFree(db, pItem->zSpan);
- }
- sqlite3DbFree(db, pList->a);
- sqlite3DbFree(db, pList);
-}
-
-/*
-** These routines are Walker callbacks. Walker.u.pi is a pointer
-** to an integer. These routines are checking an expression to see
-** if it is a constant. Set *Walker.u.pi to 0 if the expression is
-** not constant.
-**
-** These callback routines are used to implement the following:
-**
-** sqlite3ExprIsConstant()
-** sqlite3ExprIsConstantNotJoin()
-** sqlite3ExprIsConstantOrFunction()
-**
-*/
-static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){
-
- /* If pWalker->u.i is 3 then any term of the expression that comes from
- ** the ON or USING clauses of a join disqualifies the expression
- ** from being considered constant. */
- if( pWalker->u.i==3 && ExprHasAnyProperty(pExpr, EP_FromJoin) ){
- pWalker->u.i = 0;
- return WRC_Abort;
- }
-
- switch( pExpr->op ){
- /* Consider functions to be constant if all their arguments are constant
- ** and pWalker->u.i==2 */
- case TK_FUNCTION:
- if( pWalker->u.i==2 ) return 0;
- /* Fall through */
- case TK_ID:
- case TK_COLUMN:
- case TK_AGG_FUNCTION:
- case TK_AGG_COLUMN:
- testcase( pExpr->op==TK_ID );
- testcase( pExpr->op==TK_COLUMN );
- testcase( pExpr->op==TK_AGG_FUNCTION );
- testcase( pExpr->op==TK_AGG_COLUMN );
- pWalker->u.i = 0;
- return WRC_Abort;
- default:
- testcase( pExpr->op==TK_SELECT ); /* selectNodeIsConstant will disallow */
- testcase( pExpr->op==TK_EXISTS ); /* selectNodeIsConstant will disallow */
- return WRC_Continue;
- }
-}
-static int selectNodeIsConstant(Walker *pWalker, Select *NotUsed){
- UNUSED_PARAMETER(NotUsed);
- pWalker->u.i = 0;
- return WRC_Abort;
-}
-static int exprIsConst(Expr *p, int initFlag){
- Walker w;
- w.u.i = initFlag;
- w.xExprCallback = exprNodeIsConstant;
- w.xSelectCallback = selectNodeIsConstant;
- sqlite3WalkExpr(&w, p);
- return w.u.i;
-}
-
-/*
-** Walk an expression tree. Return 1 if the expression is constant
-** and 0 if it involves variables or function calls.
-**
-** For the purposes of this function, a double-quoted string (ex: "abc")
-** is considered a variable but a single-quoted string (ex: 'abc') is
-** a constant.
-*/
-SQLITE_PRIVATE int sqlite3ExprIsConstant(Expr *p){
- return exprIsConst(p, 1);
-}
-
-/*
-** Walk an expression tree. Return 1 if the expression is constant
-** that does no originate from the ON or USING clauses of a join.
-** Return 0 if it involves variables or function calls or terms from
-** an ON or USING clause.
-*/
-SQLITE_PRIVATE int sqlite3ExprIsConstantNotJoin(Expr *p){
- return exprIsConst(p, 3);
-}
-
-/*
-** Walk an expression tree. Return 1 if the expression is constant
-** or a function call with constant arguments. Return and 0 if there
-** are any variables.
-**
-** For the purposes of this function, a double-quoted string (ex: "abc")
-** is considered a variable but a single-quoted string (ex: 'abc') is
-** a constant.
-*/
-SQLITE_PRIVATE int sqlite3ExprIsConstantOrFunction(Expr *p){
- return exprIsConst(p, 2);
-}
-
-/*
-** If the expression p codes a constant integer that is small enough
-** to fit in a 32-bit integer, return 1 and put the value of the integer
-** in *pValue. If the expression is not an integer or if it is too big
-** to fit in a signed 32-bit integer, return 0 and leave *pValue unchanged.
-*/
-SQLITE_PRIVATE int sqlite3ExprIsInteger(Expr *p, int *pValue){
- int rc = 0;
- if( p->flags & EP_IntValue ){
- *pValue = p->u.iValue;
- return 1;
- }
- switch( p->op ){
- case TK_INTEGER: {
- rc = sqlite3GetInt32(p->u.zToken, pValue);
- assert( rc==0 );
- break;
- }
- case TK_UPLUS: {
- rc = sqlite3ExprIsInteger(p->pLeft, pValue);
- break;
- }
- case TK_UMINUS: {
- int v;
- if( sqlite3ExprIsInteger(p->pLeft, &v) ){
- *pValue = -v;
- rc = 1;
- }
- break;
- }
- default: break;
- }
- if( rc ){
- assert( ExprHasAnyProperty(p, EP_Reduced|EP_TokenOnly)
- || (p->flags2 & EP2_MallocedToken)==0 );
- p->op = TK_INTEGER;
- p->flags |= EP_IntValue;
- p->u.iValue = *pValue;
- }
- return rc;
-}
-
-/*
-** Return TRUE if the given string is a row-id column name.
-*/
-SQLITE_PRIVATE int sqlite3IsRowid(const char *z){
- if( sqlite3StrICmp(z, "_ROWID_")==0 ) return 1;
- if( sqlite3StrICmp(z, "ROWID")==0 ) return 1;
- if( sqlite3StrICmp(z, "OID")==0 ) return 1;
- return 0;
-}
-
-/*
-** Return true if we are able to the IN operator optimization on a
-** query of the form
-**
-** x IN (SELECT ...)
-**
-** Where the SELECT... clause is as specified by the parameter to this
-** routine.
-**
-** The Select object passed in has already been preprocessed and no
-** errors have been found.
-*/
-#ifndef SQLITE_OMIT_SUBQUERY
-static int isCandidateForInOpt(Select *p){
- SrcList *pSrc;
- ExprList *pEList;
- Table *pTab;
- if( p==0 ) return 0; /* right-hand side of IN is SELECT */
- if( p->pPrior ) return 0; /* Not a compound SELECT */
- if( p->selFlags & (SF_Distinct|SF_Aggregate) ){
- testcase( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct );
- testcase( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Aggregate );
- return 0; /* No DISTINCT keyword and no aggregate functions */
- }
- assert( p->pGroupBy==0 ); /* Has no GROUP BY clause */
- if( p->pLimit ) return 0; /* Has no LIMIT clause */
- assert( p->pOffset==0 ); /* No LIMIT means no OFFSET */
- if( p->pWhere ) return 0; /* Has no WHERE clause */
- pSrc = p->pSrc;
- assert( pSrc!=0 );
- if( pSrc->nSrc!=1 ) return 0; /* Single term in FROM clause */
- if( pSrc->a[0].pSelect ) return 0; /* FROM is not a subquery or view */
- pTab = pSrc->a[0].pTab;
- if( NEVER(pTab==0) ) return 0;
- assert( pTab->pSelect==0 ); /* FROM clause is not a view */
- if( IsVirtual(pTab) ) return 0; /* FROM clause not a virtual table */
- pEList = p->pEList;
- if( pEList->nExpr!=1 ) return 0; /* One column in the result set */
- if( pEList->a[0].pExpr->op!=TK_COLUMN ) return 0; /* Result is a column */
- return 1;
-}
-#endif /* SQLITE_OMIT_SUBQUERY */
-
-/*
-** 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
-** either to test for membership of the (...) set or to iterate through
-** its members, skipping duplicates.
-**
-** The index of the cursor opened on the b-tree (database table, database index
-** or ephermal table) is stored in pX->iTable before this function returns.
-** The returned value of this function indicates the b-tree type, as follows:
-**
-** IN_INDEX_ROWID - The cursor was opened on a database table.
-** IN_INDEX_INDEX - The cursor was opened on a database index.
-** IN_INDEX_EPH - The cursor was opened on a specially created and
-** populated epheremal table.
-**
-** An existing b-tree may only be used if the SELECT is of the simple
-** form:
-**
-** SELECT <column> FROM <table>
-**
-** If the prNotFound parameter is 0, then the b-tree will be used to iterate
-** through the set members, skipping any duplicates. In this case an
-** epheremal table must be used unless the selected <column> is guaranteed
-** to be unique - either because it is an INTEGER PRIMARY KEY or it
-** has a UNIQUE constraint or UNIQUE index.
-**
-** If the prNotFound parameter is not 0, then the b-tree will be used
-** for fast set membership tests. In this case an epheremal table must
-** be used unless <column> is an INTEGER PRIMARY KEY or an index can
-** be found with <column> as its left-most column.
-**
-** When the b-tree is being used for membership tests, the calling function
-** needs to know whether or not the structure contains an SQL NULL
-** value in order to correctly evaluate expressions like "X IN (Y, Z)".
-** If there is a chance that the b-tree might contain a NULL value at
-** runtime, then a register is allocated and the register number written
-** to *prNotFound. If there is no chance that the b-tree contains a
-** NULL value, then *prNotFound is left unchanged.
-**
-** If a register is allocated and its location stored in *prNotFound, then
-** its initial value is NULL. If the b-tree does not remain constant
-** for the duration of the query (i.e. the SELECT that generates the b-tree
-** is a correlated subquery) then the value of the allocated register is
-** reset to NULL each time the b-tree is repopulated. This allows the
-** caller to use vdbe code equivalent to the following:
-**
-** if( register==NULL ){
-** has_null = <test if data structure contains null>
-** register = 1
-** }
-**
-** in order to avoid running the <test if data structure contains null>
-** test more often than is necessary.
-*/
-#ifndef SQLITE_OMIT_SUBQUERY
-SQLITE_PRIVATE int sqlite3FindInIndex(Parse *pParse, Expr *pX, int *prNotFound){
- Select *p; /* SELECT to the right of IN operator */
- 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 */
-
- /* Check to see if an existing table or index can be used to
- ** satisfy the query. This is preferable to generating a new
- ** ephemeral table.
- */
- p = (ExprHasProperty(pX, EP_xIsSelect) ? pX->x.pSelect : 0);
- if( ALWAYS(pParse->nErr==0) && isCandidateForInOpt(p) ){
- sqlite3 *db = pParse->db; /* Database connection */
- Expr *pExpr = p->pEList->a[0].pExpr; /* Expression <column> */
- int iCol = pExpr->iColumn; /* Index of column <column> */
- Vdbe *v = sqlite3GetVdbe(pParse); /* Virtual machine being coded */
- Table *pTab = p->pSrc->a[0].pTab; /* Table <table>. */
- int iDb; /* Database idx for pTab */
-
- /* Code an OP_VerifyCookie and OP_TableLock for <table>. */
- iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
- sqlite3CodeVerifySchema(pParse, iDb);
- sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
-
- /* This function is only called from two places. In both cases the vdbe
- ** has already been allocated. So assume sqlite3GetVdbe() is always
- ** successful here.
- */
- assert(v);
- if( iCol<0 ){
- int iMem = ++pParse->nMem;
- int iAddr;
-
- iAddr = sqlite3VdbeAddOp1(v, OP_If, iMem);
- sqlite3VdbeAddOp2(v, OP_Integer, 1, iMem);
-
- sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead);
- eType = IN_INDEX_ROWID;
-
- sqlite3VdbeJumpHere(v, iAddr);
- }else{
- Index *pIdx; /* Iterator variable */
-
- /* The collation sequence used by the comparison. If an index is to
- ** be used in place of a temp-table, it must be ordered according
- ** to this collation sequence. */
- CollSeq *pReq = sqlite3BinaryCompareCollSeq(pParse, pX->pLeft, pExpr);
-
- /* Check that the affinity that will be used to perform the
- ** comparison is the same as the affinity of the column. If
- ** it is not, it is not possible to use any index.
- */
- char aff = comparisonAffinity(pX);
- int affinity_ok = (pTab->aCol[iCol].affinity==aff||aff==SQLITE_AFF_NONE);
-
- for(pIdx=pTab->pIndex; pIdx && eType==0 && affinity_ok; pIdx=pIdx->pNext){
- if( (pIdx->aiColumn[0]==iCol)
- && 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_If, iMem);
- sqlite3VdbeAddOp2(v, OP_Integer, 1, iMem);
-
- sqlite3VdbeAddOp4(v, OP_OpenRead, iTab, pIdx->tnum, iDb,
- pKey,P4_KEYINFO_HANDOFF);
- VdbeComment((v, "%s", pIdx->zName));
- eType = IN_INDEX_INDEX;
-
- sqlite3VdbeJumpHere(v, iAddr);
- if( prNotFound && !pTab->aCol[iCol].notNull ){
- *prNotFound = ++pParse->nMem;
- }
- }
- }
- }
- }
-
- if( eType==0 ){
- /* Could not found an existing able or index to use as the RHS b-tree.
- ** We will have to generate an ephemeral table to do the job.
- */
- int rMayHaveNull = 0;
- eType = IN_INDEX_EPH;
- if( prNotFound ){
- *prNotFound = rMayHaveNull = ++pParse->nMem;
- }else if( pX->pLeft->iColumn<0 && !ExprHasAnyProperty(pX, EP_xIsSelect) ){
- eType = IN_INDEX_ROWID;
- }
- sqlite3CodeSubselect(pParse, pX, rMayHaveNull, eType==IN_INDEX_ROWID);
- }else{
- pX->iTable = iTab;
- }
- return eType;
-}
-#endif
-
-/*
-** Generate code for scalar subqueries used as an expression
-** and IN operators. Examples:
-**
-** (SELECT a FROM b) -- subquery
-** EXISTS (SELECT a FROM b) -- EXISTS subquery
-** x IN (4,5,11) -- IN operator with list on right-hand side
-** x IN (SELECT a FROM b) -- IN operator with subquery on the right
-**
-** The pExpr parameter describes the expression that contains the IN
-** operator or subquery.
-**
-** If parameter isRowid is non-zero, then expression pExpr is guaranteed
-** to be of the form "<rowid> IN (?, ?, ?)", where <rowid> is a reference
-** to some integer key column of a table B-Tree. In this case, use an
-** intkey B-Tree to store the set of IN(...) values instead of the usual
-** (slower) variable length keys B-Tree.
-**
-** If rMayHaveNull is non-zero, that means that the operation is an IN
-** (not a SELECT or EXISTS) and that the RHS might contains NULLs.
-** Furthermore, the IN is in a WHERE clause and that we really want
-** to iterate over the RHS of the IN operator in order to quickly locate
-** all corresponding LHS elements. All this routine does is initialize
-** the register given by rMayHaveNull to NULL. Calling routines will take
-** care of changing this register value to non-NULL if the RHS is NULL-free.
-**
-** If rMayHaveNull is zero, that means that the subquery is being used
-** for membership testing only. There is no need to initialize any
-** registers to indicate the presense or absence of NULLs on the RHS.
-*/
-#ifndef SQLITE_OMIT_SUBQUERY
-SQLITE_PRIVATE void sqlite3CodeSubselect(
- Parse *pParse, /* Parsing context */
- Expr *pExpr, /* The IN, SELECT, or EXISTS operator */
- int rMayHaveNull, /* Register that records whether NULLs exist in RHS */
- int isRowid /* If true, LHS of IN operator is a rowid */
-){
- int testAddr = 0; /* One-time test address */
- Vdbe *v = sqlite3GetVdbe(pParse);
- if( NEVER(v==0) ) return;
- sqlite3ExprCachePush(pParse);
-
- /* This code must be run in its entirety every time it is encountered
- ** if any of the following is true:
- **
- ** * The right-hand side is a correlated subquery
- ** * The right-hand side is an expression list containing variables
- ** * We are inside a trigger
- **
- ** 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;
- sqlite3VdbeAddOp1(v, OP_If, mem);
- testAddr = sqlite3VdbeAddOp2(v, OP_Integer, 1, mem);
- assert( testAddr>0 || pParse->db->mallocFailed );
- }
-
- switch( pExpr->op ){
- case TK_IN: {
- char affinity;
- KeyInfo keyInfo;
- int addr; /* Address of OP_OpenEphemeral instruction */
- Expr *pLeft = pExpr->pLeft;
-
- if( rMayHaveNull ){
- sqlite3VdbeAddOp2(v, OP_Null, 0, rMayHaveNull);
- }
-
- affinity = sqlite3ExprAffinity(pLeft);
-
- /* Whether this is an 'x IN(SELECT...)' or an 'x IN(<exprlist>)'
- ** expression it is handled the same way. A virtual table is
- ** filled with single-field index keys representing the results
- ** from the SELECT or the <exprlist>.
- **
- ** If the 'x' expression is a column value, or the SELECT...
- ** statement returns a column value, then the affinity of that
- ** column is used to build the index keys. If both 'x' and the
- ** SELECT... statement are columns, then numeric affinity is used
- ** if either column has NUMERIC or INTEGER affinity. If neither
- ** 'x' nor the SELECT... statement are columns, then numeric affinity
- ** is used.
- */
- pExpr->iTable = pParse->nTab++;
- addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pExpr->iTable, !isRowid);
- memset(&keyInfo, 0, sizeof(keyInfo));
- keyInfo.nField = 1;
-
- if( ExprHasProperty(pExpr, EP_xIsSelect) ){
- /* Case 1: expr IN (SELECT ...)
- **
- ** Generate code to write the results of the select into the temporary
- ** table allocated and opened above.
- */
- SelectDest dest;
- ExprList *pEList;
-
- assert( !isRowid );
- sqlite3SelectDestInit(&dest, SRT_Set, pExpr->iTable);
- dest.affinity = (u8)affinity;
- assert( (pExpr->iTable&0x0000FFFF)==pExpr->iTable );
- if( sqlite3Select(pParse, pExpr->x.pSelect, &dest) ){
- return;
- }
- pEList = pExpr->x.pSelect->pEList;
- if( ALWAYS(pEList!=0 && pEList->nExpr>0) ){
- keyInfo.aColl[0] = sqlite3BinaryCompareCollSeq(pParse, pExpr->pLeft,
- pEList->a[0].pExpr);
- }
- }else if( pExpr->x.pList!=0 ){
- /* Case 2: expr IN (exprlist)
- **
- ** For each expression, build an index key from the evaluation and
- ** store it in the temporary table. If <expr> is a column, then use
- ** that columns affinity when building index keys. If <expr> is not
- ** a column, use numeric affinity.
- */
- int i;
- ExprList *pList = pExpr->x.pList;
- struct ExprList_item *pItem;
- int r1, r2, r3;
-
- if( !affinity ){
- affinity = SQLITE_AFF_NONE;
- }
- keyInfo.aColl[0] = sqlite3ExprCollSeq(pParse, pExpr->pLeft);
-
- /* Loop through each expression in <exprlist>. */
- r1 = sqlite3GetTempReg(pParse);
- r2 = sqlite3GetTempReg(pParse);
- sqlite3VdbeAddOp2(v, OP_Null, 0, r2);
- for(i=pList->nExpr, pItem=pList->a; i>0; i--, pItem++){
- Expr *pE2 = pItem->pExpr;
-
- /* If the expression is not constant then we will need to
- ** disable the test that was generated above that makes sure
- ** this code only executes once. Because for a non-constant
- ** expression we need to rerun this code each time.
- */
- if( testAddr && !sqlite3ExprIsConstant(pE2) ){
- sqlite3VdbeChangeToNoop(v, testAddr-1, 2);
- testAddr = 0;
- }
-
- /* Evaluate the expression and insert it into the temp table */
- r3 = sqlite3ExprCodeTarget(pParse, pE2, r1);
- if( isRowid ){
- sqlite3VdbeAddOp2(v, OP_MustBeInt, r3, sqlite3VdbeCurrentAddr(v)+2);
- sqlite3VdbeAddOp3(v, OP_Insert, pExpr->iTable, r2, r3);
- }else{
- sqlite3VdbeAddOp4(v, OP_MakeRecord, r3, 1, r2, &affinity, 1);
- sqlite3ExprCacheAffinityChange(pParse, r3, 1);
- sqlite3VdbeAddOp2(v, OP_IdxInsert, pExpr->iTable, r2);
- }
- }
- sqlite3ReleaseTempReg(pParse, r1);
- sqlite3ReleaseTempReg(pParse, r2);
- }
- if( !isRowid ){
- sqlite3VdbeChangeP4(v, addr, (void *)&keyInfo, P4_KEYINFO);
- }
- break;
- }
-
- case TK_EXISTS:
- case TK_SELECT:
- default: {
- /* If this has to be a scalar SELECT. Generate code to put the
- ** value of this select in a memory cell and record the number
- ** of the memory cell in iColumn. If this is an EXISTS, write
- ** an integer 0 (not exists) or 1 (exists) into a memory cell
- ** and record that memory cell in iColumn.
- */
- static const Token one = { "1", 1 }; /* Token for literal value 1 */
- Select *pSel; /* SELECT statement to encode */
- SelectDest dest; /* How to deal with SELECt result */
-
- testcase( pExpr->op==TK_EXISTS );
- testcase( pExpr->op==TK_SELECT );
- assert( pExpr->op==TK_EXISTS || pExpr->op==TK_SELECT );
-
- assert( ExprHasProperty(pExpr, EP_xIsSelect) );
- pSel = pExpr->x.pSelect;
- sqlite3SelectDestInit(&dest, 0, ++pParse->nMem);
- if( pExpr->op==TK_SELECT ){
- dest.eDest = SRT_Mem;
- sqlite3VdbeAddOp2(v, OP_Null, 0, dest.iParm);
- VdbeComment((v, "Init subquery result"));
- }else{
- dest.eDest = SRT_Exists;
- sqlite3VdbeAddOp2(v, OP_Integer, 0, dest.iParm);
- VdbeComment((v, "Init EXISTS result"));
- }
- sqlite3ExprDelete(pParse->db, pSel->pLimit);
- pSel->pLimit = sqlite3PExpr(pParse, TK_INTEGER, 0, 0, &one);
- if( sqlite3Select(pParse, pSel, &dest) ){
- return;
- }
- pExpr->iColumn = (i16)dest.iParm;
- ExprSetIrreducible(pExpr);
- break;
- }
- }
-
- if( testAddr ){
- sqlite3VdbeJumpHere(v, testAddr-1);
- }
- sqlite3ExprCachePop(pParse, 1);
-
- return;
-}
-#endif /* SQLITE_OMIT_SUBQUERY */
-
-/*
-** Duplicate an 8-byte value
-*/
-static char *dup8bytes(Vdbe *v, const char *in){
- char *out = sqlite3DbMallocRaw(sqlite3VdbeDb(v), 8);
- if( out ){
- memcpy(out, in, 8);
- }
- return out;
-}
-
-/*
-** Generate an instruction that will put the floating point
-** value described by z[0..n-1] into register iMem.
-**
-** The z[] string will probably not be zero-terminated. But the
-** z[n] character is guaranteed to be something that does not look
-** like the continuation of the number.
-*/
-static void codeReal(Vdbe *v, const char *z, int negateFlag, int iMem){
- if( ALWAYS(z!=0) ){
- double value;
- char *zV;
- sqlite3AtoF(z, &value);
- assert( !sqlite3IsNaN(value) ); /* The new AtoF never returns NaN */
- if( negateFlag ) value = -value;
- zV = dup8bytes(v, (char*)&value);
- sqlite3VdbeAddOp4(v, OP_Real, 0, iMem, 0, zV, P4_REAL);
- }
-}
-
-
-/*
-** Generate an instruction that will put the integer describe by
-** text z[0..n-1] into register iMem.
-**
-** The z[] string will probably not be zero-terminated. But the
-** z[n] character is guaranteed to be something that does not look
-** like the continuation of the number.
-*/
-static void codeInteger(Vdbe *v, Expr *pExpr, int negFlag, int iMem){
- if( pExpr->flags & EP_IntValue ){
- int i = pExpr->u.iValue;
- if( negFlag ) i = -i;
- sqlite3VdbeAddOp2(v, OP_Integer, i, iMem);
- }else{
- const char *z = pExpr->u.zToken;
- assert( z!=0 );
- if( sqlite3FitsIn64Bits(z, negFlag) ){
- i64 value;
- char *zV;
- sqlite3Atoi64(z, &value);
- if( negFlag ) value = -value;
- zV = dup8bytes(v, (char*)&value);
- sqlite3VdbeAddOp4(v, OP_Int64, 0, iMem, 0, zV, P4_INT64);
- }else{
- codeReal(v, z, negFlag, iMem);
- }
- }
-}
-
-/*
-** Clear a cache entry.
-*/
-static void cacheEntryClear(Parse *pParse, struct yColCache *p){
- if( p->tempReg ){
- if( pParse->nTempReg<ArraySize(pParse->aTempReg) ){
- pParse->aTempReg[pParse->nTempReg++] = p->iReg;
- }
- p->tempReg = 0;
- }
-}
-
-
-/*
-** Record in the column cache that a particular column from a
-** particular table is stored in a particular register.
-*/
-SQLITE_PRIVATE void sqlite3ExprCacheStore(Parse *pParse, int iTab, int iCol, int iReg){
- int i;
- int minLru;
- int idxLru;
- struct yColCache *p;
-
- assert( iReg>0 ); /* Register numbers are always positive */
- assert( iCol>=-1 && iCol<32768 ); /* Finite column numbers */
-
- /* First replace any existing entry */
- for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
- if( p->iReg && p->iTable==iTab && p->iColumn==iCol ){
- cacheEntryClear(pParse, p);
- p->iLevel = pParse->iCacheLevel;
- p->iReg = iReg;
- p->affChange = 0;
- p->lru = pParse->iCacheCnt++;
- return;
- }
- }
-
- /* Find an empty slot and replace it */
- for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
- if( p->iReg==0 ){
- p->iLevel = pParse->iCacheLevel;
- p->iTable = iTab;
- p->iColumn = iCol;
- p->iReg = iReg;
- p->affChange = 0;
- p->tempReg = 0;
- p->lru = pParse->iCacheCnt++;
- return;
- }
- }
-
- /* Replace the last recently used */
- minLru = 0x7fffffff;
- idxLru = -1;
- for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
- if( p->lru<minLru ){
- idxLru = i;
- minLru = p->lru;
- }
- }
- if( ALWAYS(idxLru>=0) ){
- p = &pParse->aColCache[idxLru];
- p->iLevel = pParse->iCacheLevel;
- p->iTable = iTab;
- p->iColumn = iCol;
- p->iReg = iReg;
- p->affChange = 0;
- p->tempReg = 0;
- p->lru = pParse->iCacheCnt++;
- return;
- }
-}
-
-/*
-** Indicate that a register is being overwritten. Purge the register
-** from the column cache.
-*/
-SQLITE_PRIVATE void sqlite3ExprCacheRemove(Parse *pParse, int iReg){
- int i;
- struct yColCache *p;
- for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
- if( p->iReg==iReg ){
- cacheEntryClear(pParse, p);
- p->iReg = 0;
- }
- }
-}
-
-/*
-** Remember the current column cache context. Any new entries added
-** added to the column cache after this call are removed when the
-** corresponding pop occurs.
-*/
-SQLITE_PRIVATE void sqlite3ExprCachePush(Parse *pParse){
- pParse->iCacheLevel++;
-}
-
-/*
-** Remove from the column cache any entries that were added since the
-** the previous N Push operations. In other words, restore the cache
-** to the state it was in N Pushes ago.
-*/
-SQLITE_PRIVATE void sqlite3ExprCachePop(Parse *pParse, int N){
- int i;
- struct yColCache *p;
- assert( N>0 );
- assert( pParse->iCacheLevel>=N );
- pParse->iCacheLevel -= N;
- for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
- if( p->iReg && p->iLevel>pParse->iCacheLevel ){
- cacheEntryClear(pParse, p);
- p->iReg = 0;
- }
- }
-}
-
-/*
-** When a cached column is reused, make sure that its register is
-** no longer available as a temp register. ticket #3879: that same
-** register might be in the cache in multiple places, so be sure to
-** get them all.
-*/
-static void sqlite3ExprCachePinRegister(Parse *pParse, int iReg){
- int i;
- struct yColCache *p;
- for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
- if( p->iReg==iReg ){
- p->tempReg = 0;
- }
- }
-}
-
-/*
-** Generate code that will extract the iColumn-th column from
-** table pTab and store the column value in a register. An effort
-** is made to store the column value in register iReg, but this is
-** not guaranteed. The location of the column value is returned.
-**
-** There must be an open cursor to pTab in iTable when this routine
-** is called. If iColumn<0 then code is generated that extracts the rowid.
-**
-** This routine might attempt to reuse the value of the column that
-** has already been loaded into a register. The value will always
-** be used if it has not undergone any affinity changes. But if
-** an affinity change has occurred, then the cached value will only be
-** used if allowAffChng is true.
-*/
-SQLITE_PRIVATE int sqlite3ExprCodeGetColumn(
- Parse *pParse, /* Parsing and code generating context */
- Table *pTab, /* Description of the table we are reading from */
- int iColumn, /* Index of the table column */
- int iTable, /* The cursor pointing to the table */
- int iReg, /* Store results here */
- int allowAffChng /* True if prior affinity changes are OK */
-){
- Vdbe *v = pParse->pVdbe;
- int i;
- struct yColCache *p;
-
- for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
- if( p->iReg>0 && p->iTable==iTable && p->iColumn==iColumn
- && (!p->affChange || allowAffChng) ){
- p->lru = pParse->iCacheCnt++;
- sqlite3ExprCachePinRegister(pParse, p->iReg);
- return p->iReg;
- }
- }
- assert( v!=0 );
- if( iColumn<0 ){
- sqlite3VdbeAddOp2(v, OP_Rowid, iTable, iReg);
- }else if( ALWAYS(pTab!=0) ){
- int op = IsVirtual(pTab) ? OP_VColumn : OP_Column;
- sqlite3VdbeAddOp3(v, op, iTable, iColumn, iReg);
- sqlite3ColumnDefault(v, pTab, iColumn, iReg);
- }
- sqlite3ExprCacheStore(pParse, iTable, iColumn, iReg);
- return iReg;
-}
-
-/*
-** Clear all column cache entries.
-*/
-SQLITE_PRIVATE void sqlite3ExprCacheClear(Parse *pParse){
- int i;
- struct yColCache *p;
-
- for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
- if( p->iReg ){
- cacheEntryClear(pParse, p);
- p->iReg = 0;
- }
- }
-}
-
-/*
-** Record the fact that an affinity change has occurred on iCount
-** registers starting with iStart.
-*/
-SQLITE_PRIVATE void sqlite3ExprCacheAffinityChange(Parse *pParse, int iStart, int iCount){
- int iEnd = iStart + iCount - 1;
- int i;
- struct yColCache *p;
- for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
- int r = p->iReg;
- if( r>=iStart && r<=iEnd ){
- p->affChange = 1;
- }
- }
-}
-
-/*
-** Generate code to move content from registers iFrom...iFrom+nReg-1
-** over to iTo..iTo+nReg-1. Keep the column cache up-to-date.
-*/
-SQLITE_PRIVATE void sqlite3ExprCodeMove(Parse *pParse, int iFrom, int iTo, int nReg){
- int i;
- struct yColCache *p;
- if( NEVER(iFrom==iTo) ) return;
- sqlite3VdbeAddOp3(pParse->pVdbe, OP_Move, iFrom, iTo, nReg);
- for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
- int x = p->iReg;
- if( x>=iFrom && x<iFrom+nReg ){
- p->iReg += iTo-iFrom;
- }
- }
-}
-
-/*
-** Generate code to copy content from registers iFrom...iFrom+nReg-1
-** over to iTo..iTo+nReg-1.
-*/
-SQLITE_PRIVATE void sqlite3ExprCodeCopy(Parse *pParse, int iFrom, int iTo, int nReg){
- int i;
- if( NEVER(iFrom==iTo) ) return;
- for(i=0; i<nReg; i++){
- sqlite3VdbeAddOp2(pParse->pVdbe, OP_Copy, iFrom+i, iTo+i);
- }
-}
-
-/*
-** Return true if any register in the range iFrom..iTo (inclusive)
-** is used as part of the column cache.
-*/
-static int usedAsColumnCache(Parse *pParse, int iFrom, int iTo){
- int i;
- struct yColCache *p;
- for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
- int r = p->iReg;
- if( r>=iFrom && r<=iTo ) return 1;
- }
- return 0;
-}
-
-/*
-** If the last instruction coded is an ephemeral copy of any of
-** the registers in the nReg registers beginning with iReg, then
-** convert the last instruction from OP_SCopy to OP_Copy.
-*/
-SQLITE_PRIVATE void sqlite3ExprHardCopy(Parse *pParse, int iReg, int nReg){
- VdbeOp *pOp;
- Vdbe *v;
-
- assert( pParse->db->mallocFailed==0 );
- v = pParse->pVdbe;
- assert( v!=0 );
- pOp = sqlite3VdbeGetOp(v, -1);
- assert( pOp!=0 );
- if( pOp->opcode==OP_SCopy && pOp->p1>=iReg && pOp->p1<iReg+nReg ){
- pOp->opcode = OP_Copy;
- }
-}
-
-/*
-** Generate code to store the value of the iAlias-th alias in register
-** target. The first time this is called, pExpr is evaluated to compute
-** the value of the alias. The value is stored in an auxiliary register
-** and the number of that register is returned. On subsequent calls,
-** the register number is returned without generating any code.
-**
-** Note that in order for this to work, code must be generated in the
-** same order that it is executed.
-**
-** Aliases are numbered starting with 1. So iAlias is in the range
-** of 1 to pParse->nAlias inclusive.
-**
-** pParse->aAlias[iAlias-1] records the register number where the value
-** of the iAlias-th alias is stored. If zero, that means that the
-** alias has not yet been computed.
-*/
-static int codeAlias(Parse *pParse, int iAlias, Expr *pExpr, int target){
-#if 0
- sqlite3 *db = pParse->db;
- int iReg;
- if( pParse->nAliasAlloc<pParse->nAlias ){
- pParse->aAlias = sqlite3DbReallocOrFree(db, pParse->aAlias,
- sizeof(pParse->aAlias[0])*pParse->nAlias );
- testcase( db->mallocFailed && pParse->nAliasAlloc>0 );
- if( db->mallocFailed ) return 0;
- memset(&pParse->aAlias[pParse->nAliasAlloc], 0,
- (pParse->nAlias-pParse->nAliasAlloc)*sizeof(pParse->aAlias[0]));
- pParse->nAliasAlloc = pParse->nAlias;
- }
- assert( iAlias>0 && iAlias<=pParse->nAlias );
- iReg = pParse->aAlias[iAlias-1];
- if( iReg==0 ){
- if( pParse->iCacheLevel>0 ){
- iReg = sqlite3ExprCodeTarget(pParse, pExpr, target);
- }else{
- iReg = ++pParse->nMem;
- sqlite3ExprCode(pParse, pExpr, iReg);
- pParse->aAlias[iAlias-1] = iReg;
- }
- }
- return iReg;
-#else
- UNUSED_PARAMETER(iAlias);
- return sqlite3ExprCodeTarget(pParse, pExpr, target);
-#endif
-}
-
-/*
-** Generate code into the current Vdbe to evaluate the given
-** expression. Attempt to store the results in register "target".
-** Return the register where results are stored.
-**
-** With this routine, there is no guarantee that results will
-** be stored in target. The result might be stored in some other
-** register if it is convenient to do so. The calling function
-** must check the return code and move the results to the desired
-** register.
-*/
-SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
- Vdbe *v = pParse->pVdbe; /* The VM under construction */
- int op; /* The opcode being coded */
- int inReg = target; /* Results stored in register inReg */
- int regFree1 = 0; /* If non-zero free this temporary register */
- int regFree2 = 0; /* If non-zero free this temporary register */
- int r1, r2, r3, r4; /* Various register numbers */
- sqlite3 *db = pParse->db; /* The database connection */
-
- assert( target>0 && target<=pParse->nMem );
- if( v==0 ){
- assert( pParse->db->mallocFailed );
- return 0;
- }
-
- if( pExpr==0 ){
- op = TK_NULL;
- }else{
- op = pExpr->op;
- }
- switch( op ){
- case TK_AGG_COLUMN: {
- AggInfo *pAggInfo = pExpr->pAggInfo;
- struct AggInfo_col *pCol = &pAggInfo->aCol[pExpr->iAgg];
- if( !pAggInfo->directMode ){
- assert( pCol->iMem>0 );
- inReg = pCol->iMem;
- break;
- }else if( pAggInfo->useSortingIdx ){
- sqlite3VdbeAddOp3(v, OP_Column, pAggInfo->sortingIdx,
- pCol->iSorterColumn, target);
- break;
- }
- /* Otherwise, fall thru into the TK_COLUMN case */
- }
- case TK_COLUMN: {
- if( pExpr->iTable<0 ){
- /* This only happens when coding check constraints */
- assert( pParse->ckBase>0 );
- inReg = pExpr->iColumn + pParse->ckBase;
- }else{
- testcase( (pExpr->flags & EP_AnyAff)!=0 );
- inReg = sqlite3ExprCodeGetColumn(pParse, pExpr->pTab,
- pExpr->iColumn, pExpr->iTable, target,
- pExpr->flags & EP_AnyAff);
- }
- break;
- }
- case TK_INTEGER: {
- codeInteger(v, pExpr, 0, target);
- break;
- }
- case TK_FLOAT: {
- assert( !ExprHasProperty(pExpr, EP_IntValue) );
- codeReal(v, pExpr->u.zToken, 0, target);
- break;
- }
- case TK_STRING: {
- assert( !ExprHasProperty(pExpr, EP_IntValue) );
- sqlite3VdbeAddOp4(v, OP_String8, 0, target, 0, pExpr->u.zToken, 0);
- break;
- }
- case TK_NULL: {
- sqlite3VdbeAddOp2(v, OP_Null, 0, target);
- break;
- }
-#ifndef SQLITE_OMIT_BLOB_LITERAL
- case TK_BLOB: {
- int n;
- const char *z;
- char *zBlob;
- assert( !ExprHasProperty(pExpr, EP_IntValue) );
- assert( pExpr->u.zToken[0]=='x' || pExpr->u.zToken[0]=='X' );
- assert( pExpr->u.zToken[1]=='\'' );
- z = &pExpr->u.zToken[2];
- n = sqlite3Strlen30(z) - 1;
- assert( z[n]=='\'' );
- zBlob = sqlite3HexToBlob(sqlite3VdbeDb(v), z, n);
- sqlite3VdbeAddOp4(v, OP_Blob, n/2, target, 0, zBlob, P4_DYNAMIC);
- break;
- }
-#endif
- case TK_VARIABLE: {
- VdbeOp *pOp;
- assert( !ExprHasProperty(pExpr, EP_IntValue) );
- assert( pExpr->u.zToken!=0 );
- assert( pExpr->u.zToken[0]!=0 );
- if( pExpr->u.zToken[1]==0
- && (pOp = sqlite3VdbeGetOp(v, -1))->opcode==OP_Variable
- && pOp->p1+pOp->p3==pExpr->iTable
- && pOp->p2+pOp->p3==target
- && pOp->p4.z==0
- ){
- /* If the previous instruction was a copy of the previous unnamed
- ** parameter into the previous register, then simply increment the
- ** repeat count on the prior instruction rather than making a new
- ** instruction.
- */
- pOp->p3++;
- }else{
- sqlite3VdbeAddOp3(v, OP_Variable, pExpr->iTable, target, 1);
- if( pExpr->u.zToken[1]!=0 ){
- sqlite3VdbeChangeP4(v, -1, pExpr->u.zToken, 0);
- }
- }
- break;
- }
- case TK_REGISTER: {
- inReg = pExpr->iTable;
- break;
- }
- case TK_AS: {
- inReg = codeAlias(pParse, pExpr->iTable, pExpr->pLeft, target);
- break;
- }
-#ifndef SQLITE_OMIT_CAST
- case TK_CAST: {
- /* Expressions of the form: CAST(pLeft AS token) */
- int aff, to_op;
- inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target);
- assert( !ExprHasProperty(pExpr, EP_IntValue) );
- aff = sqlite3AffinityType(pExpr->u.zToken);
- to_op = aff - SQLITE_AFF_TEXT + OP_ToText;
- assert( to_op==OP_ToText || aff!=SQLITE_AFF_TEXT );
- assert( to_op==OP_ToBlob || aff!=SQLITE_AFF_NONE );
- assert( to_op==OP_ToNumeric || aff!=SQLITE_AFF_NUMERIC );
- assert( to_op==OP_ToInt || aff!=SQLITE_AFF_INTEGER );
- assert( to_op==OP_ToReal || aff!=SQLITE_AFF_REAL );
- testcase( to_op==OP_ToText );
- testcase( to_op==OP_ToBlob );
- testcase( to_op==OP_ToNumeric );
- testcase( to_op==OP_ToInt );
- testcase( to_op==OP_ToReal );
- if( inReg!=target ){
- sqlite3VdbeAddOp2(v, OP_SCopy, inReg, target);
- inReg = target;
- }
- sqlite3VdbeAddOp1(v, to_op, inReg);
- testcase( usedAsColumnCache(pParse, inReg, inReg) );
- sqlite3ExprCacheAffinityChange(pParse, inReg, 1);
- break;
- }
-#endif /* SQLITE_OMIT_CAST */
- case TK_LT:
- case TK_LE:
- case TK_GT:
- case TK_GE:
- case TK_NE:
- case TK_EQ: {
- assert( TK_LT==OP_Lt );
- assert( TK_LE==OP_Le );
- assert( TK_GT==OP_Gt );
- assert( TK_GE==OP_Ge );
- assert( TK_EQ==OP_Eq );
- assert( TK_NE==OP_Ne );
- testcase( op==TK_LT );
- testcase( op==TK_LE );
- testcase( op==TK_GT );
- testcase( op==TK_GE );
- testcase( op==TK_EQ );
- testcase( op==TK_NE );
- codeCompareOperands(pParse, pExpr->pLeft, &r1, &regFree1,
- pExpr->pRight, &r2, &regFree2);
- codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op,
- r1, r2, inReg, SQLITE_STOREP2);
- testcase( regFree1==0 );
- testcase( regFree2==0 );
- break;
- }
- case TK_AND:
- case TK_OR:
- case TK_PLUS:
- case TK_STAR:
- case TK_MINUS:
- case TK_REM:
- case TK_BITAND:
- case TK_BITOR:
- case TK_SLASH:
- case TK_LSHIFT:
- case TK_RSHIFT:
- case TK_CONCAT: {
- assert( TK_AND==OP_And );
- assert( TK_OR==OP_Or );
- assert( TK_PLUS==OP_Add );
- assert( TK_MINUS==OP_Subtract );
- assert( TK_REM==OP_Remainder );
- assert( TK_BITAND==OP_BitAnd );
- assert( TK_BITOR==OP_BitOr );
- assert( TK_SLASH==OP_Divide );
- assert( TK_LSHIFT==OP_ShiftLeft );
- assert( TK_RSHIFT==OP_ShiftRight );
- assert( TK_CONCAT==OP_Concat );
- testcase( op==TK_AND );
- testcase( op==TK_OR );
- testcase( op==TK_PLUS );
- testcase( op==TK_MINUS );
- testcase( op==TK_REM );
- testcase( op==TK_BITAND );
- testcase( op==TK_BITOR );
- testcase( op==TK_SLASH );
- testcase( op==TK_LSHIFT );
- testcase( op==TK_RSHIFT );
- testcase( op==TK_CONCAT );
- r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, &regFree1);
- r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, &regFree2);
- sqlite3VdbeAddOp3(v, op, r2, r1, target);
- testcase( regFree1==0 );
- testcase( regFree2==0 );
- break;
- }
- case TK_UMINUS: {
- Expr *pLeft = pExpr->pLeft;
- assert( pLeft );
- if( pLeft->op==TK_FLOAT ){
- assert( !ExprHasProperty(pExpr, EP_IntValue) );
- codeReal(v, pLeft->u.zToken, 1, target);
- }else if( pLeft->op==TK_INTEGER ){
- codeInteger(v, pLeft, 1, target);
- }else{
- regFree1 = r1 = sqlite3GetTempReg(pParse);
- sqlite3VdbeAddOp2(v, OP_Integer, 0, r1);
- r2 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, &regFree2);
- sqlite3VdbeAddOp3(v, OP_Subtract, r2, r1, target);
- testcase( regFree2==0 );
- }
- inReg = target;
- break;
- }
- case TK_BITNOT:
- case TK_NOT: {
- assert( TK_BITNOT==OP_BitNot );
- assert( TK_NOT==OP_Not );
- testcase( op==TK_BITNOT );
- testcase( op==TK_NOT );
- r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, &regFree1);
- testcase( regFree1==0 );
- inReg = target;
- sqlite3VdbeAddOp2(v, op, r1, inReg);
- break;
- }
- case TK_ISNULL:
- case TK_NOTNULL: {
- int addr;
- assert( TK_ISNULL==OP_IsNull );
- assert( TK_NOTNULL==OP_NotNull );
- testcase( op==TK_ISNULL );
- testcase( op==TK_NOTNULL );
- sqlite3VdbeAddOp2(v, OP_Integer, 1, target);
- r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, &regFree1);
- testcase( regFree1==0 );
- addr = sqlite3VdbeAddOp1(v, op, r1);
- sqlite3VdbeAddOp2(v, OP_AddImm, target, -1);
- sqlite3VdbeJumpHere(v, addr);
- break;
- }
- case TK_AGG_FUNCTION: {
- AggInfo *pInfo = pExpr->pAggInfo;
- if( pInfo==0 ){
- assert( !ExprHasProperty(pExpr, EP_IntValue) );
- sqlite3ErrorMsg(pParse, "misuse of aggregate: %s()", pExpr->u.zToken);
- }else{
- inReg = pInfo->aFunc[pExpr->iAgg].iMem;
- }
- break;
- }
- case TK_CONST_FUNC:
- case TK_FUNCTION: {
- ExprList *pFarg; /* List of function arguments */
- int nFarg; /* Number of function arguments */
- FuncDef *pDef; /* The function definition object */
- int nId; /* Length of the function name in bytes */
- const char *zId; /* The function name */
- int constMask = 0; /* Mask of function arguments that are constant */
- int i; /* Loop counter */
- u8 enc = ENC(db); /* The text encoding used by this database */
- CollSeq *pColl = 0; /* A collating sequence */
-
- assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
- testcase( op==TK_CONST_FUNC );
- testcase( op==TK_FUNCTION );
- if( ExprHasAnyProperty(pExpr, EP_TokenOnly) ){
- pFarg = 0;
- }else{
- pFarg = pExpr->x.pList;
- }
- nFarg = pFarg ? pFarg->nExpr : 0;
- assert( !ExprHasProperty(pExpr, EP_IntValue) );
- zId = pExpr->u.zToken;
- nId = sqlite3Strlen30(zId);
- pDef = sqlite3FindFunction(db, zId, nId, nFarg, enc, 0);
- if( pDef==0 ){
- sqlite3ErrorMsg(pParse, "unknown function: %.*s()", nId, zId);
- break;
- }
- if( pFarg ){
- r1 = sqlite3GetTempRange(pParse, nFarg);
- sqlite3ExprCachePush(pParse); /* Ticket 2ea2425d34be */
- sqlite3ExprCodeExprList(pParse, pFarg, r1, 1);
- sqlite3ExprCachePop(pParse, 1); /* Ticket 2ea2425d34be */
- }else{
- r1 = 0;
- }
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- /* Possibly overload the function if the first argument is
- ** a virtual table column.
- **
- ** For infix functions (LIKE, GLOB, REGEXP, and MATCH) use the
- ** second argument, not the first, as the argument to test to
- ** see if it is a column in a virtual table. This is done because
- ** the left operand of infix functions (the operand we want to
- ** control overloading) ends up as the second argument to the
- ** function. The expression "A glob B" is equivalent to
- ** "glob(B,A). We want to use the A in "A glob B" to test
- ** for function overloading. But we use the B term in "glob(B,A)".
- */
- if( nFarg>=2 && (pExpr->flags & EP_InfixFunc) ){
- pDef = sqlite3VtabOverloadFunction(db, pDef, nFarg, pFarg->a[1].pExpr);
- }else if( nFarg>0 ){
- pDef = sqlite3VtabOverloadFunction(db, pDef, nFarg, pFarg->a[0].pExpr);
- }
-#endif
- for(i=0; i<nFarg; i++){
- if( i<32 && sqlite3ExprIsConstant(pFarg->a[i].pExpr) ){
- constMask |= (1<<i);
- }
- if( (pDef->flags & SQLITE_FUNC_NEEDCOLL)!=0 && !pColl ){
- pColl = sqlite3ExprCollSeq(pParse, pFarg->a[i].pExpr);
- }
- }
- if( pDef->flags & SQLITE_FUNC_NEEDCOLL ){
- if( !pColl ) pColl = db->pDfltColl;
- sqlite3VdbeAddOp4(v, OP_CollSeq, 0, 0, 0, (char *)pColl, P4_COLLSEQ);
- }
- sqlite3VdbeAddOp4(v, OP_Function, constMask, r1, target,
- (char*)pDef, P4_FUNCDEF);
- sqlite3VdbeChangeP5(v, (u8)nFarg);
- if( nFarg ){
- sqlite3ReleaseTempRange(pParse, r1, nFarg);
- }
- sqlite3ExprCacheAffinityChange(pParse, r1, nFarg);
- break;
- }
-#ifndef SQLITE_OMIT_SUBQUERY
- case TK_EXISTS:
- case TK_SELECT: {
- testcase( op==TK_EXISTS );
- testcase( op==TK_SELECT );
- sqlite3CodeSubselect(pParse, pExpr, 0, 0);
- inReg = pExpr->iColumn;
- break;
- }
- case TK_IN: {
- int rNotFound = 0;
- int rMayHaveNull = 0;
- int j2, j3, j4, j5;
- char affinity;
- int eType;
-
- VdbeNoopComment((v, "begin IN expr r%d", target));
- eType = sqlite3FindInIndex(pParse, pExpr, &rMayHaveNull);
- if( rMayHaveNull ){
- rNotFound = ++pParse->nMem;
- }
-
- /* Figure out the affinity to use to create a key from the results
- ** of the expression. affinityStr stores a static string suitable for
- ** P4 of OP_MakeRecord.
- */
- affinity = comparisonAffinity(pExpr);
-
-
- /* Code the <expr> from "<expr> IN (...)". The temporary table
- ** pExpr->iTable contains the values that make up the (...) set.
- */
- sqlite3ExprCachePush(pParse);
- sqlite3ExprCode(pParse, pExpr->pLeft, target);
- j2 = sqlite3VdbeAddOp1(v, OP_IsNull, target);
- if( eType==IN_INDEX_ROWID ){
- j3 = sqlite3VdbeAddOp1(v, OP_MustBeInt, target);
- j4 = sqlite3VdbeAddOp3(v, OP_NotExists, pExpr->iTable, 0, target);
- sqlite3VdbeAddOp2(v, OP_Integer, 1, target);
- j5 = sqlite3VdbeAddOp0(v, OP_Goto);
- sqlite3VdbeJumpHere(v, j3);
- sqlite3VdbeJumpHere(v, j4);
- sqlite3VdbeAddOp2(v, OP_Integer, 0, target);
- }else{
- r2 = regFree2 = sqlite3GetTempReg(pParse);
-
- /* Create a record and test for set membership. If the set contains
- ** the value, then jump to the end of the test code. The target
- ** register still contains the true (1) value written to it earlier.
- */
- sqlite3VdbeAddOp4(v, OP_MakeRecord, target, 1, r2, &affinity, 1);
- sqlite3VdbeAddOp2(v, OP_Integer, 1, target);
- j5 = sqlite3VdbeAddOp3(v, OP_Found, pExpr->iTable, 0, r2);
-
- /* If the set membership test fails, then the result of the
- ** "x IN (...)" expression must be either 0 or NULL. If the set
- ** contains no NULL values, then the result is 0. If the set
- ** contains one or more NULL values, then the result of the
- ** expression is also NULL.
- */
- if( rNotFound==0 ){
- /* This branch runs if it is known at compile time (now) that
- ** the set contains no NULL values. This happens as the result
- ** of a "NOT NULL" constraint in the database schema. No need
- ** to test the data structure at runtime in this case.
- */
- sqlite3VdbeAddOp2(v, OP_Integer, 0, target);
- }else{
- /* This block populates the rNotFound register with either NULL
- ** or 0 (an integer value). If the data structure contains one
- ** or more NULLs, then set rNotFound to NULL. Otherwise, set it
- ** to 0. If register rMayHaveNull is already set to some value
- ** other than NULL, then the test has already been run and
- ** rNotFound is already populated.
- */
- static const char nullRecord[] = { 0x02, 0x00 };
- j3 = sqlite3VdbeAddOp1(v, OP_NotNull, rMayHaveNull);
- sqlite3VdbeAddOp2(v, OP_Null, 0, rNotFound);
- sqlite3VdbeAddOp4(v, OP_Blob, 2, rMayHaveNull, 0,
- nullRecord, P4_STATIC);
- j4 = sqlite3VdbeAddOp3(v, OP_Found, pExpr->iTable, 0, rMayHaveNull);
- sqlite3VdbeAddOp2(v, OP_Integer, 0, rNotFound);
- sqlite3VdbeJumpHere(v, j4);
- sqlite3VdbeJumpHere(v, j3);
-
- /* Copy the value of register rNotFound (which is either NULL or 0)
- ** into the target register. This will be the result of the
- ** expression.
- */
- sqlite3VdbeAddOp2(v, OP_Copy, rNotFound, target);
- }
- }
- sqlite3VdbeJumpHere(v, j2);
- sqlite3VdbeJumpHere(v, j5);
- sqlite3ExprCachePop(pParse, 1);
- VdbeComment((v, "end IN expr r%d", target));
- break;
- }
-#endif
- /*
- ** 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 *pLeft = pExpr->pLeft;
- struct ExprList_item *pLItem = pExpr->x.pList->a;
- Expr *pRight = pLItem->pExpr;
-
- codeCompareOperands(pParse, pLeft, &r1, &regFree1,
- pRight, &r2, &regFree2);
- testcase( regFree1==0 );
- testcase( regFree2==0 );
- r3 = sqlite3GetTempReg(pParse);
- r4 = sqlite3GetTempReg(pParse);
- codeCompare(pParse, pLeft, pRight, OP_Ge,
- r1, r2, r3, SQLITE_STOREP2);
- pLItem++;
- pRight = pLItem->pExpr;
- sqlite3ReleaseTempReg(pParse, regFree2);
- r2 = sqlite3ExprCodeTemp(pParse, pRight, &regFree2);
- testcase( regFree2==0 );
- codeCompare(pParse, pLeft, pRight, OP_Le, r1, r2, r4, SQLITE_STOREP2);
- sqlite3VdbeAddOp3(v, OP_And, r3, r4, target);
- sqlite3ReleaseTempReg(pParse, r3);
- sqlite3ReleaseTempReg(pParse, r4);
- break;
- }
- case TK_UPLUS: {
- inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target);
- 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.
- **
- ** The expression is implemented using an OP_Param opcode. The p1
- ** parameter is set to 0 for an old.rowid reference, or to (i+1)
- ** to reference another column of the old.* pseudo-table, where
- ** i is the index of the column. For a new.rowid reference, p1 is
- ** set to (n+1), where n is the number of columns in each pseudo-table.
- ** For a reference to any other column in the new.* pseudo-table, p1
- ** is set to (n+2+i), where n and i are as defined previously. For
- ** example, if the table on which triggers are being fired is
- ** declared as:
- **
- ** CREATE TABLE t1(a, b);
- **
- ** Then p1 is interpreted as follows:
- **
- ** p1==0 -> old.rowid p1==3 -> new.rowid
- ** p1==1 -> old.a p1==4 -> new.a
- ** p1==2 -> old.b p1==5 -> new.b
- */
- Table *pTab = pExpr->pTab;
- int p1 = pExpr->iTable * (pTab->nCol+1) + 1 + pExpr->iColumn;
-
- assert( pExpr->iTable==0 || pExpr->iTable==1 );
- assert( pExpr->iColumn>=-1 && pExpr->iColumn<pTab->nCol );
- assert( pTab->iPKey<0 || pExpr->iColumn!=pTab->iPKey );
- assert( p1>=0 && p1<(pTab->nCol*2+2) );
-
- sqlite3VdbeAddOp2(v, OP_Param, p1, target);
- VdbeComment((v, "%s.%s -> $%d",
- (pExpr->iTable ? "new" : "old"),
- (pExpr->iColumn<0 ? "rowid" : pExpr->pTab->aCol[pExpr->iColumn].zName),
- target
- ));
-
- /* If the column has REAL affinity, it may currently be stored as an
- ** integer. Use OP_RealAffinity to make sure it is really real. */
- if( pExpr->iColumn>=0
- && pTab->aCol[pExpr->iColumn].affinity==SQLITE_AFF_REAL
- ){
- sqlite3VdbeAddOp1(v, OP_RealAffinity, target);
- }
- break;
- }
-
-
- /*
- ** Form A:
- ** CASE x WHEN e1 THEN r1 WHEN e2 THEN r2 ... WHEN eN THEN rN ELSE y END
- **
- ** Form B:
- ** CASE WHEN e1 THEN r1 WHEN e2 THEN r2 ... WHEN eN THEN rN ELSE y END
- **
- ** Form A is can be transformed into the equivalent form B as follows:
- ** CASE WHEN x=e1 THEN r1 WHEN x=e2 THEN r2 ...
- ** WHEN x=eN THEN rN ELSE y END
- **
- ** X (if it exists) is in pExpr->pLeft.
- ** Y is in pExpr->pRight. The Y is also optional. If there is no
- ** ELSE clause and no other term matches, then the result of the
- ** exprssion is NULL.
- ** Ei is in pExpr->pList->a[i*2] and Ri is pExpr->pList->a[i*2+1].
- **
- ** The result of the expression is the Ri for the first matching Ei,
- ** or if there is no matching Ei, the ELSE term Y, or if there is
- ** no ELSE term, NULL.
- */
- default: assert( op==TK_CASE ); {
- int endLabel; /* GOTO label for end of CASE stmt */
- int nextCase; /* GOTO label for next WHEN clause */
- int nExpr; /* 2x number of WHEN terms */
- int i; /* Loop counter */
- ExprList *pEList; /* List of WHEN terms */
- struct ExprList_item *aListelem; /* Array of WHEN terms */
- Expr opCompare; /* The X==Ei expression */
- Expr cacheX; /* Cached expression X */
- Expr *pX; /* The X expression */
- Expr *pTest = 0; /* X==Ei (form A) or just Ei (form B) */
- VVA_ONLY( int iCacheLevel = pParse->iCacheLevel; )
-
- assert( !ExprHasProperty(pExpr, EP_xIsSelect) && pExpr->x.pList );
- assert((pExpr->x.pList->nExpr % 2) == 0);
- assert(pExpr->x.pList->nExpr > 0);
- pEList = pExpr->x.pList;
- aListelem = pEList->a;
- nExpr = pEList->nExpr;
- endLabel = sqlite3VdbeMakeLabel(v);
- if( (pX = pExpr->pLeft)!=0 ){
- cacheX = *pX;
- testcase( pX->op==TK_COLUMN );
- testcase( pX->op==TK_REGISTER );
- cacheX.iTable = sqlite3ExprCodeTemp(pParse, pX, &regFree1);
- testcase( regFree1==0 );
- cacheX.op = TK_REGISTER;
- opCompare.op = TK_EQ;
- opCompare.pLeft = &cacheX;
- pTest = &opCompare;
- }
- for(i=0; i<nExpr; i=i+2){
- sqlite3ExprCachePush(pParse);
- if( pX ){
- assert( pTest!=0 );
- opCompare.pRight = aListelem[i].pExpr;
- }else{
- pTest = aListelem[i].pExpr;
- }
- nextCase = sqlite3VdbeMakeLabel(v);
- testcase( pTest->op==TK_COLUMN );
- sqlite3ExprIfFalse(pParse, pTest, nextCase, SQLITE_JUMPIFNULL);
- testcase( aListelem[i+1].pExpr->op==TK_COLUMN );
- testcase( aListelem[i+1].pExpr->op==TK_REGISTER );
- sqlite3ExprCode(pParse, aListelem[i+1].pExpr, target);
- sqlite3VdbeAddOp2(v, OP_Goto, 0, endLabel);
- sqlite3ExprCachePop(pParse, 1);
- sqlite3VdbeResolveLabel(v, nextCase);
- }
- if( pExpr->pRight ){
- sqlite3ExprCachePush(pParse);
- sqlite3ExprCode(pParse, pExpr->pRight, target);
- sqlite3ExprCachePop(pParse, 1);
- }else{
- sqlite3VdbeAddOp2(v, OP_Null, 0, target);
- }
- assert( db->mallocFailed || pParse->nErr>0
- || pParse->iCacheLevel==iCacheLevel );
- sqlite3VdbeResolveLabel(v, endLabel);
- break;
- }
-#ifndef SQLITE_OMIT_TRIGGER
- case TK_RAISE: {
- assert( pExpr->affinity==OE_Rollback
- || pExpr->affinity==OE_Abort
- || pExpr->affinity==OE_Fail
- || pExpr->affinity==OE_Ignore
- );
- if( !pParse->pTriggerTab ){
- sqlite3ErrorMsg(pParse,
- "RAISE() may only be used within a trigger-program");
- return 0;
- }
- if( pExpr->affinity==OE_Abort ){
- sqlite3MayAbort(pParse);
- }
- assert( !ExprHasProperty(pExpr, EP_IntValue) );
- if( pExpr->affinity==OE_Ignore ){
- sqlite3VdbeAddOp4(
- v, OP_Halt, SQLITE_OK, OE_Ignore, 0, pExpr->u.zToken,0);
- }else{
- sqlite3HaltConstraint(pParse, pExpr->affinity, pExpr->u.zToken, 0);
- }
-
- break;
- }
-#endif
- }
- sqlite3ReleaseTempReg(pParse, regFree1);
- sqlite3ReleaseTempReg(pParse, regFree2);
- return inReg;
-}
-
-/*
-** Generate code to evaluate an expression and store the results
-** into a register. Return the register number where the results
-** are stored.
-**
-** If the register is a temporary register that can be deallocated,
-** then write its number into *pReg. If the result register is not
-** a temporary, then set *pReg to zero.
-*/
-SQLITE_PRIVATE int sqlite3ExprCodeTemp(Parse *pParse, Expr *pExpr, int *pReg){
- int r1 = sqlite3GetTempReg(pParse);
- int r2 = sqlite3ExprCodeTarget(pParse, pExpr, r1);
- if( r2==r1 ){
- *pReg = r1;
- }else{
- sqlite3ReleaseTempReg(pParse, r1);
- *pReg = 0;
- }
- return r2;
-}
-
-/*
-** Generate code that will evaluate expression pExpr and store the
-** results in register target. The results are guaranteed to appear
-** in register target.
-*/
-SQLITE_PRIVATE int sqlite3ExprCode(Parse *pParse, Expr *pExpr, int target){
- int inReg;
-
- assert( target>0 && target<=pParse->nMem );
- inReg = sqlite3ExprCodeTarget(pParse, pExpr, target);
- assert( pParse->pVdbe || pParse->db->mallocFailed );
- if( inReg!=target && pParse->pVdbe ){
- sqlite3VdbeAddOp2(pParse->pVdbe, OP_SCopy, inReg, target);
- }
- return target;
-}
-
-/*
-** Generate code that evalutes the given expression and puts the result
-** in register target.
-**
-** Also make a copy of the expression results into another "cache" register
-** and modify the expression so that the next time it is evaluated,
-** the result is a copy of the cache register.
-**
-** This routine is used for expressions that are used multiple
-** times. They are evaluated once and the results of the expression
-** are reused.
-*/
-SQLITE_PRIVATE int sqlite3ExprCodeAndCache(Parse *pParse, Expr *pExpr, int target){
- Vdbe *v = pParse->pVdbe;
- int inReg;
- inReg = sqlite3ExprCode(pParse, pExpr, target);
- assert( target>0 );
- /* This routine is called for terms to INSERT or UPDATE. And the only
- ** other place where expressions can be converted into TK_REGISTER is
- ** in WHERE clause processing. So as currently implemented, there is
- ** no way for a TK_REGISTER to exist here. But it seems prudent to
- ** keep the ALWAYS() in case the conditions above change with future
- ** modifications or enhancements. */
- if( ALWAYS(pExpr->op!=TK_REGISTER) ){
- int iMem;
- iMem = ++pParse->nMem;
- sqlite3VdbeAddOp2(v, OP_Copy, inReg, iMem);
- pExpr->iTable = iMem;
- pExpr->op = TK_REGISTER;
- }
- return inReg;
-}
-
-/*
-** Return TRUE if pExpr is an constant expression that is appropriate
-** for factoring out of a loop. Appropriate expressions are:
-**
-** * Any expression that evaluates to two or more opcodes.
-**
-** * Any OP_Integer, OP_Real, OP_String, OP_Blob, OP_Null,
-** or OP_Variable that does not need to be placed in a
-** specific register.
-**
-** There is no point in factoring out single-instruction constant
-** expressions that need to be placed in a particular register.
-** We could factor them out, but then we would end up adding an
-** OP_SCopy instruction to move the value into the correct register
-** later. We might as well just use the original instruction and
-** avoid the OP_SCopy.
-*/
-static int isAppropriateForFactoring(Expr *p){
- if( !sqlite3ExprIsConstantNotJoin(p) ){
- return 0; /* Only constant expressions are appropriate for factoring */
- }
- if( (p->flags & EP_FixedDest)==0 ){
- return 1; /* Any constant without a fixed destination is appropriate */
- }
- while( p->op==TK_UPLUS ) p = p->pLeft;
- switch( p->op ){
-#ifndef SQLITE_OMIT_BLOB_LITERAL
- case TK_BLOB:
-#endif
- case TK_VARIABLE:
- case TK_INTEGER:
- case TK_FLOAT:
- case TK_NULL:
- case TK_STRING: {
- testcase( p->op==TK_BLOB );
- testcase( p->op==TK_VARIABLE );
- testcase( p->op==TK_INTEGER );
- testcase( p->op==TK_FLOAT );
- testcase( p->op==TK_NULL );
- testcase( p->op==TK_STRING );
- /* Single-instruction constants with a fixed destination are
- ** better done in-line. If we factor them, they will just end
- ** up generating an OP_SCopy to move the value to the destination
- ** register. */
- return 0;
- }
- case TK_UMINUS: {
- if( p->pLeft->op==TK_FLOAT || p->pLeft->op==TK_INTEGER ){
- return 0;
- }
- break;
- }
- default: {
- break;
- }
- }
- return 1;
-}
-
-/*
-** If pExpr is a constant expression that is appropriate for
-** factoring out of a loop, then evaluate the expression
-** into a register and convert the expression into a TK_REGISTER
-** expression.
-*/
-static int evalConstExpr(Walker *pWalker, Expr *pExpr){
- Parse *pParse = pWalker->pParse;
- switch( pExpr->op ){
- case TK_REGISTER: {
- return WRC_Prune;
- }
- case TK_FUNCTION:
- case TK_AGG_FUNCTION:
- case TK_CONST_FUNC: {
- /* The arguments to a function have a fixed destination.
- ** Mark them this way to avoid generated unneeded OP_SCopy
- ** instructions.
- */
- ExprList *pList = pExpr->x.pList;
- assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
- if( pList ){
- int i = pList->nExpr;
- struct ExprList_item *pItem = pList->a;
- for(; i>0; i--, pItem++){
- if( ALWAYS(pItem->pExpr) ) pItem->pExpr->flags |= EP_FixedDest;
- }
- }
- break;
- }
- }
- if( isAppropriateForFactoring(pExpr) ){
- int r1 = ++pParse->nMem;
- int r2;
- r2 = sqlite3ExprCodeTarget(pParse, pExpr, r1);
- if( NEVER(r1!=r2) ) sqlite3ReleaseTempReg(pParse, r1);
- pExpr->op2 = pExpr->op;
- pExpr->op = TK_REGISTER;
- pExpr->iTable = r2;
- return WRC_Prune;
- }
- return WRC_Continue;
-}
-
-/*
-** Preevaluate constant subexpressions within pExpr and store the
-** results in registers. Modify pExpr so that the constant subexpresions
-** are TK_REGISTER opcodes that refer to the precomputed values.
-*/
-SQLITE_PRIVATE void sqlite3ExprCodeConstants(Parse *pParse, Expr *pExpr){
- Walker w;
- w.xExprCallback = evalConstExpr;
- w.xSelectCallback = 0;
- w.pParse = pParse;
- sqlite3WalkExpr(&w, pExpr);
-}
-
-
-/*
-** Generate code that pushes the value of every element of the given
-** expression list into a sequence of registers beginning at target.
-**
-** Return the number of elements evaluated.
-*/
-SQLITE_PRIVATE int sqlite3ExprCodeExprList(
- Parse *pParse, /* Parsing context */
- ExprList *pList, /* The expression list to be coded */
- int target, /* Where to write results */
- int doHardCopy /* Make a hard copy of every element */
-){
- struct ExprList_item *pItem;
- int i, n;
- assert( pList!=0 );
- assert( target>0 );
- n = pList->nExpr;
- for(pItem=pList->a, i=0; i<n; i++, pItem++){
- if( pItem->iAlias ){
- int iReg = codeAlias(pParse, pItem->iAlias, pItem->pExpr, target+i);
- Vdbe *v = sqlite3GetVdbe(pParse);
- if( iReg!=target+i ){
- sqlite3VdbeAddOp2(v, OP_SCopy, iReg, target+i);
- }
- }else{
- sqlite3ExprCode(pParse, pItem->pExpr, target+i);
- }
- if( doHardCopy && !pParse->db->mallocFailed ){
- sqlite3ExprHardCopy(pParse, target, n);
- }
- }
- return n;
-}
-
-/*
-** Generate code for a boolean expression such that a jump is made
-** to the label "dest" if the expression is true but execution
-** continues straight thru if the expression is false.
-**
-** If the expression evaluates to NULL (neither true nor false), then
-** take the jump if the jumpIfNull flag is SQLITE_JUMPIFNULL.
-**
-** This code depends on the fact that certain token values (ex: TK_EQ)
-** are the same as opcode values (ex: OP_Eq) that implement the corresponding
-** operation. Special comments in vdbe.c and the mkopcodeh.awk script in
-** the make process cause these values to align. Assert()s in the code
-** below verify that the numbers are aligned correctly.
-*/
-SQLITE_PRIVATE void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
- Vdbe *v = pParse->pVdbe;
- int op = 0;
- int regFree1 = 0;
- int regFree2 = 0;
- int r1, r2;
-
- assert( jumpIfNull==SQLITE_JUMPIFNULL || jumpIfNull==0 );
- if( NEVER(v==0) ) return; /* Existance of VDBE checked by caller */
- if( NEVER(pExpr==0) ) return; /* No way this can happen */
- op = pExpr->op;
- switch( op ){
- case TK_AND: {
- int d2 = sqlite3VdbeMakeLabel(v);
- testcase( jumpIfNull==0 );
- sqlite3ExprCachePush(pParse);
- sqlite3ExprIfFalse(pParse, pExpr->pLeft, d2,jumpIfNull^SQLITE_JUMPIFNULL);
- sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull);
- sqlite3VdbeResolveLabel(v, d2);
- sqlite3ExprCachePop(pParse, 1);
- break;
- }
- case TK_OR: {
- testcase( jumpIfNull==0 );
- sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull);
- sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull);
- break;
- }
- case TK_NOT: {
- testcase( jumpIfNull==0 );
- sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull);
- break;
- }
- case TK_LT:
- case TK_LE:
- case TK_GT:
- case TK_GE:
- case TK_NE:
- case TK_EQ: {
- assert( TK_LT==OP_Lt );
- assert( TK_LE==OP_Le );
- assert( TK_GT==OP_Gt );
- assert( TK_GE==OP_Ge );
- assert( TK_EQ==OP_Eq );
- assert( TK_NE==OP_Ne );
- testcase( op==TK_LT );
- testcase( op==TK_LE );
- testcase( op==TK_GT );
- testcase( op==TK_GE );
- testcase( op==TK_EQ );
- testcase( op==TK_NE );
- testcase( jumpIfNull==0 );
- codeCompareOperands(pParse, pExpr->pLeft, &r1, &regFree1,
- pExpr->pRight, &r2, &regFree2);
- codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op,
- r1, r2, dest, jumpIfNull);
- testcase( regFree1==0 );
- testcase( regFree2==0 );
- break;
- }
- case TK_ISNULL:
- case TK_NOTNULL: {
- assert( TK_ISNULL==OP_IsNull );
- assert( TK_NOTNULL==OP_NotNull );
- testcase( op==TK_ISNULL );
- testcase( op==TK_NOTNULL );
- r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, &regFree1);
- sqlite3VdbeAddOp2(v, op, r1, dest);
- testcase( regFree1==0 );
- break;
- }
- case TK_BETWEEN: {
- /* x BETWEEN y AND z
- **
- ** Is equivalent to
- **
- ** x>=y AND x<=z
- **
- ** Code it as such, taking care to do the common subexpression
- ** elementation of x.
- */
- Expr exprAnd;
- Expr compLeft;
- Expr compRight;
- Expr exprX;
-
- assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
- exprX = *pExpr->pLeft;
- exprAnd.op = TK_AND;
- exprAnd.pLeft = &compLeft;
- exprAnd.pRight = &compRight;
- compLeft.op = TK_GE;
- compLeft.pLeft = &exprX;
- compLeft.pRight = pExpr->x.pList->a[0].pExpr;
- compRight.op = TK_LE;
- compRight.pLeft = &exprX;
- compRight.pRight = pExpr->x.pList->a[1].pExpr;
- exprX.iTable = sqlite3ExprCodeTemp(pParse, &exprX, &regFree1);
- testcase( regFree1==0 );
- exprX.op = TK_REGISTER;
- testcase( jumpIfNull==0 );
- sqlite3ExprIfTrue(pParse, &exprAnd, dest, jumpIfNull);
- break;
- }
- default: {
- r1 = sqlite3ExprCodeTemp(pParse, pExpr, &regFree1);
- sqlite3VdbeAddOp3(v, OP_If, r1, dest, jumpIfNull!=0);
- testcase( regFree1==0 );
- testcase( jumpIfNull==0 );
- break;
- }
- }
- sqlite3ReleaseTempReg(pParse, regFree1);
- sqlite3ReleaseTempReg(pParse, regFree2);
-}
-
-/*
-** Generate code for a boolean expression such that a jump is made
-** to the label "dest" if the expression is false but execution
-** continues straight thru if the expression is true.
-**
-** If the expression evaluates to NULL (neither true nor false) then
-** jump if jumpIfNull is SQLITE_JUMPIFNULL or fall through if jumpIfNull
-** is 0.
-*/
-SQLITE_PRIVATE void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
- Vdbe *v = pParse->pVdbe;
- int op = 0;
- int regFree1 = 0;
- int regFree2 = 0;
- int r1, r2;
-
- assert( jumpIfNull==SQLITE_JUMPIFNULL || jumpIfNull==0 );
- if( NEVER(v==0) ) return; /* Existance of VDBE checked by caller */
- if( pExpr==0 ) return;
-
- /* The value of pExpr->op and op are related as follows:
- **
- ** pExpr->op op
- ** --------- ----------
- ** TK_ISNULL OP_NotNull
- ** TK_NOTNULL OP_IsNull
- ** TK_NE OP_Eq
- ** TK_EQ OP_Ne
- ** TK_GT OP_Le
- ** TK_LE OP_Gt
- ** TK_GE OP_Lt
- ** TK_LT OP_Ge
- **
- ** For other values of pExpr->op, op is undefined and unused.
- ** The value of TK_ and OP_ constants are arranged such that we
- ** can compute the mapping above using the following expression.
- ** Assert()s verify that the computation is correct.
- */
- op = ((pExpr->op+(TK_ISNULL&1))^1)-(TK_ISNULL&1);
-
- /* Verify correct alignment of TK_ and OP_ constants
- */
- assert( pExpr->op!=TK_ISNULL || op==OP_NotNull );
- assert( pExpr->op!=TK_NOTNULL || op==OP_IsNull );
- assert( pExpr->op!=TK_NE || op==OP_Eq );
- assert( pExpr->op!=TK_EQ || op==OP_Ne );
- assert( pExpr->op!=TK_LT || op==OP_Ge );
- assert( pExpr->op!=TK_LE || op==OP_Gt );
- assert( pExpr->op!=TK_GT || op==OP_Le );
- assert( pExpr->op!=TK_GE || op==OP_Lt );
-
- switch( pExpr->op ){
- case TK_AND: {
- testcase( jumpIfNull==0 );
- sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull);
- sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull);
- break;
- }
- case TK_OR: {
- int d2 = sqlite3VdbeMakeLabel(v);
- testcase( jumpIfNull==0 );
- sqlite3ExprCachePush(pParse);
- sqlite3ExprIfTrue(pParse, pExpr->pLeft, d2, jumpIfNull^SQLITE_JUMPIFNULL);
- sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull);
- sqlite3VdbeResolveLabel(v, d2);
- sqlite3ExprCachePop(pParse, 1);
- break;
- }
- case TK_NOT: {
- sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull);
- break;
- }
- case TK_LT:
- case TK_LE:
- case TK_GT:
- case TK_GE:
- case TK_NE:
- case TK_EQ: {
- testcase( op==TK_LT );
- testcase( op==TK_LE );
- testcase( op==TK_GT );
- testcase( op==TK_GE );
- testcase( op==TK_EQ );
- testcase( op==TK_NE );
- testcase( jumpIfNull==0 );
- codeCompareOperands(pParse, pExpr->pLeft, &r1, &regFree1,
- pExpr->pRight, &r2, &regFree2);
- codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op,
- r1, r2, dest, jumpIfNull);
- testcase( regFree1==0 );
- testcase( regFree2==0 );
- break;
- }
- case TK_ISNULL:
- case TK_NOTNULL: {
- testcase( op==TK_ISNULL );
- testcase( op==TK_NOTNULL );
- r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, &regFree1);
- sqlite3VdbeAddOp2(v, op, r1, dest);
- testcase( regFree1==0 );
- break;
- }
- case TK_BETWEEN: {
- /* x BETWEEN y AND z
- **
- ** Is equivalent to
- **
- ** x>=y AND x<=z
- **
- ** Code it as such, taking care to do the common subexpression
- ** elementation of x.
- */
- Expr exprAnd;
- Expr compLeft;
- Expr compRight;
- Expr exprX;
-
- assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
- exprX = *pExpr->pLeft;
- exprAnd.op = TK_AND;
- exprAnd.pLeft = &compLeft;
- exprAnd.pRight = &compRight;
- compLeft.op = TK_GE;
- compLeft.pLeft = &exprX;
- compLeft.pRight = pExpr->x.pList->a[0].pExpr;
- compRight.op = TK_LE;
- compRight.pLeft = &exprX;
- compRight.pRight = pExpr->x.pList->a[1].pExpr;
- exprX.iTable = sqlite3ExprCodeTemp(pParse, &exprX, &regFree1);
- testcase( regFree1==0 );
- exprX.op = TK_REGISTER;
- testcase( jumpIfNull==0 );
- sqlite3ExprIfFalse(pParse, &exprAnd, dest, jumpIfNull);
- break;
- }
- default: {
- r1 = sqlite3ExprCodeTemp(pParse, pExpr, &regFree1);
- sqlite3VdbeAddOp3(v, OP_IfNot, r1, dest, jumpIfNull!=0);
- testcase( regFree1==0 );
- testcase( jumpIfNull==0 );
- break;
- }
- }
- sqlite3ReleaseTempReg(pParse, regFree1);
- sqlite3ReleaseTempReg(pParse, regFree2);
-}
-
-/*
-** Do a deep comparison of two expression trees. Return TRUE (non-zero)
-** if they are identical and return FALSE if they differ in any way.
-**
-** Sometimes this routine will return FALSE even if the two expressions
-** really are equivalent. If we cannot prove that the expressions are
-** identical, we return FALSE just to be safe. So if this routine
-** returns false, then you do not really know for certain if the two
-** expressions are the same. But if you get a TRUE return, then you
-** can be sure the expressions are the same. In the places where
-** this routine is used, it does not hurt to get an extra FALSE - that
-** just might result in some slightly slower code. But returning
-** an incorrect TRUE could lead to a malfunction.
-*/
-SQLITE_PRIVATE int sqlite3ExprCompare(Expr *pA, Expr *pB){
- int i;
- if( pA==0||pB==0 ){
- return pB==pA;
- }
- assert( !ExprHasAnyProperty(pA, EP_TokenOnly|EP_Reduced) );
- assert( !ExprHasAnyProperty(pB, EP_TokenOnly|EP_Reduced) );
- if( ExprHasProperty(pA, EP_xIsSelect) || ExprHasProperty(pB, EP_xIsSelect) ){
- return 0;
- }
- if( (pA->flags & EP_Distinct)!=(pB->flags & EP_Distinct) ) return 0;
- if( pA->op!=pB->op ) return 0;
- if( !sqlite3ExprCompare(pA->pLeft, pB->pLeft) ) return 0;
- if( !sqlite3ExprCompare(pA->pRight, pB->pRight) ) return 0;
-
- if( pA->x.pList && pB->x.pList ){
- if( pA->x.pList->nExpr!=pB->x.pList->nExpr ) return 0;
- for(i=0; i<pA->x.pList->nExpr; i++){
- Expr *pExprA = pA->x.pList->a[i].pExpr;
- Expr *pExprB = pB->x.pList->a[i].pExpr;
- if( !sqlite3ExprCompare(pExprA, pExprB) ) return 0;
- }
- }else if( pA->x.pList || pB->x.pList ){
- return 0;
- }
-
- if( pA->iTable!=pB->iTable || pA->iColumn!=pB->iColumn ) return 0;
- if( ExprHasProperty(pA, EP_IntValue) ){
- if( !ExprHasProperty(pB, EP_IntValue) || pA->u.iValue!=pB->u.iValue ){
- return 0;
- }
- }else if( pA->op!=TK_COLUMN && pA->u.zToken ){
- if( ExprHasProperty(pB, EP_IntValue) || NEVER(pB->u.zToken==0) ) return 0;
- if( sqlite3StrICmp(pA->u.zToken,pB->u.zToken)!=0 ){
- return 0;
- }
- }
- return 1;
-}
-
-
-/*
-** Add a new element to the pAggInfo->aCol[] array. Return the index of
-** the new element. Return a negative number if malloc fails.
-*/
-static int addAggInfoColumn(sqlite3 *db, AggInfo *pInfo){
- int i;
- pInfo->aCol = sqlite3ArrayAllocate(
- db,
- pInfo->aCol,
- sizeof(pInfo->aCol[0]),
- 3,
- &pInfo->nColumn,
- &pInfo->nColumnAlloc,
- &i
- );
- return i;
-}
-
-/*
-** Add a new element to the pAggInfo->aFunc[] array. Return the index of
-** the new element. Return a negative number if malloc fails.
-*/
-static int addAggInfoFunc(sqlite3 *db, AggInfo *pInfo){
- int i;
- pInfo->aFunc = sqlite3ArrayAllocate(
- db,
- pInfo->aFunc,
- sizeof(pInfo->aFunc[0]),
- 3,
- &pInfo->nFunc,
- &pInfo->nFuncAlloc,
- &i
- );
- return i;
-}
-
-/*
-** This is the xExprCallback for a tree walker. It is used to
-** implement sqlite3ExprAnalyzeAggregates(). See sqlite3ExprAnalyzeAggregates
-** for additional information.
-*/
-static int analyzeAggregate(Walker *pWalker, Expr *pExpr){
- int i;
- NameContext *pNC = pWalker->u.pNC;
- Parse *pParse = pNC->pParse;
- SrcList *pSrcList = pNC->pSrcList;
- AggInfo *pAggInfo = pNC->pAggInfo;
-
- switch( pExpr->op ){
- case TK_AGG_COLUMN:
- case TK_COLUMN: {
- testcase( pExpr->op==TK_AGG_COLUMN );
- testcase( pExpr->op==TK_COLUMN );
- /* Check to see if the column is in one of the tables in the FROM
- ** clause of the aggregate query */
- if( ALWAYS(pSrcList!=0) ){
- struct SrcList_item *pItem = pSrcList->a;
- for(i=0; i<pSrcList->nSrc; i++, pItem++){
- struct AggInfo_col *pCol;
- assert( !ExprHasAnyProperty(pExpr, EP_TokenOnly|EP_Reduced) );
- if( pExpr->iTable==pItem->iCursor ){
- /* If we reach this point, it means that pExpr refers to a table
- ** that is in the FROM clause of the aggregate query.
- **
- ** Make an entry for the column in pAggInfo->aCol[] if there
- ** is not an entry there already.
- */
- int k;
- pCol = pAggInfo->aCol;
- for(k=0; k<pAggInfo->nColumn; k++, pCol++){
- if( pCol->iTable==pExpr->iTable &&
- pCol->iColumn==pExpr->iColumn ){
- break;
- }
- }
- if( (k>=pAggInfo->nColumn)
- && (k = addAggInfoColumn(pParse->db, pAggInfo))>=0
- ){
- pCol = &pAggInfo->aCol[k];
- pCol->pTab = pExpr->pTab;
- pCol->iTable = pExpr->iTable;
- pCol->iColumn = pExpr->iColumn;
- pCol->iMem = ++pParse->nMem;
- pCol->iSorterColumn = -1;
- pCol->pExpr = pExpr;
- if( pAggInfo->pGroupBy ){
- int j, n;
- ExprList *pGB = pAggInfo->pGroupBy;
- struct ExprList_item *pTerm = pGB->a;
- n = pGB->nExpr;
- for(j=0; j<n; j++, pTerm++){
- Expr *pE = pTerm->pExpr;
- if( pE->op==TK_COLUMN && pE->iTable==pExpr->iTable &&
- pE->iColumn==pExpr->iColumn ){
- pCol->iSorterColumn = j;
- break;
- }
- }
- }
- if( pCol->iSorterColumn<0 ){
- pCol->iSorterColumn = pAggInfo->nSortingColumn++;
- }
- }
- /* There is now an entry for pExpr in pAggInfo->aCol[] (either
- ** because it was there before or because we just created it).
- ** Convert the pExpr to be a TK_AGG_COLUMN referring to that
- ** pAggInfo->aCol[] entry.
- */
- ExprSetIrreducible(pExpr);
- pExpr->pAggInfo = pAggInfo;
- pExpr->op = TK_AGG_COLUMN;
- pExpr->iAgg = (i16)k;
- break;
- } /* endif pExpr->iTable==pItem->iCursor */
- } /* end loop over pSrcList */
- }
- return WRC_Prune;
- }
- case TK_AGG_FUNCTION: {
- /* The pNC->nDepth==0 test causes aggregate functions in subqueries
- ** to be ignored */
- if( pNC->nDepth==0 ){
- /* Check to see if pExpr is a duplicate of another aggregate
- ** function that is already in the pAggInfo structure
- */
- struct AggInfo_func *pItem = pAggInfo->aFunc;
- for(i=0; i<pAggInfo->nFunc; i++, pItem++){
- if( sqlite3ExprCompare(pItem->pExpr, pExpr) ){
- break;
- }
- }
- if( i>=pAggInfo->nFunc ){
- /* pExpr is original. Make a new entry in pAggInfo->aFunc[]
- */
- u8 enc = ENC(pParse->db);
- i = addAggInfoFunc(pParse->db, pAggInfo);
- if( i>=0 ){
- assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
- pItem = &pAggInfo->aFunc[i];
- pItem->pExpr = pExpr;
- pItem->iMem = ++pParse->nMem;
- assert( !ExprHasProperty(pExpr, EP_IntValue) );
- pItem->pFunc = sqlite3FindFunction(pParse->db,
- pExpr->u.zToken, sqlite3Strlen30(pExpr->u.zToken),
- pExpr->x.pList ? pExpr->x.pList->nExpr : 0, enc, 0);
- if( pExpr->flags & EP_Distinct ){
- pItem->iDistinct = pParse->nTab++;
- }else{
- pItem->iDistinct = -1;
- }
- }
- }
- /* Make pExpr point to the appropriate pAggInfo->aFunc[] entry
- */
- assert( !ExprHasAnyProperty(pExpr, EP_TokenOnly|EP_Reduced) );
- ExprSetIrreducible(pExpr);
- pExpr->iAgg = (i16)i;
- pExpr->pAggInfo = pAggInfo;
- return WRC_Prune;
- }
- }
- }
- return WRC_Continue;
-}
-static int analyzeAggregatesInSelect(Walker *pWalker, Select *pSelect){
- NameContext *pNC = pWalker->u.pNC;
- if( pNC->nDepth==0 ){
- pNC->nDepth++;
- sqlite3WalkSelect(pWalker, pSelect);
- pNC->nDepth--;
- return WRC_Prune;
- }else{
- return WRC_Continue;
- }
-}
-
-/*
-** Analyze the given expression looking for aggregate functions and
-** for variables that need to be added to the pParse->aAgg[] array.
-** Make additional entries to the pParse->aAgg[] array as necessary.
-**
-** This routine should only be called after the expression has been
-** analyzed by sqlite3ResolveExprNames().
-*/
-SQLITE_PRIVATE void sqlite3ExprAnalyzeAggregates(NameContext *pNC, Expr *pExpr){
- Walker w;
- w.xExprCallback = analyzeAggregate;
- w.xSelectCallback = analyzeAggregatesInSelect;
- w.u.pNC = pNC;
- assert( pNC->pSrcList!=0 );
- sqlite3WalkExpr(&w, pExpr);
-}
-
-/*
-** Call sqlite3ExprAnalyzeAggregates() for every expression in an
-** expression list. Return the number of errors.
-**
-** If an error is found, the analysis is cut short.
-*/
-SQLITE_PRIVATE void sqlite3ExprAnalyzeAggList(NameContext *pNC, ExprList *pList){
- struct ExprList_item *pItem;
- int i;
- if( pList ){
- for(pItem=pList->a, i=0; i<pList->nExpr; i++, pItem++){
- sqlite3ExprAnalyzeAggregates(pNC, pItem->pExpr);
- }
- }
-}
-
-/*
-** Allocate a single new register for use to hold some intermediate result.
-*/
-SQLITE_PRIVATE int sqlite3GetTempReg(Parse *pParse){
- if( pParse->nTempReg==0 ){
- return ++pParse->nMem;
- }
- return pParse->aTempReg[--pParse->nTempReg];
-}
-
-/*
-** Deallocate a register, making available for reuse for some other
-** purpose.
-**
-** If a register is currently being used by the column cache, then
-** the dallocation is deferred until the column cache line that uses
-** the register becomes stale.
-*/
-SQLITE_PRIVATE void sqlite3ReleaseTempReg(Parse *pParse, int iReg){
- if( iReg && pParse->nTempReg<ArraySize(pParse->aTempReg) ){
- int i;
- struct yColCache *p;
- for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
- if( p->iReg==iReg ){
- p->tempReg = 1;
- return;
- }
- }
- pParse->aTempReg[pParse->nTempReg++] = iReg;
- }
-}
-
-/*
-** Allocate or deallocate a block of nReg consecutive registers
-*/
-SQLITE_PRIVATE int sqlite3GetTempRange(Parse *pParse, int nReg){
- int i, n;
- i = pParse->iRangeReg;
- n = pParse->nRangeReg;
- if( nReg<=n && !usedAsColumnCache(pParse, i, i+n-1) ){
- pParse->iRangeReg += nReg;
- pParse->nRangeReg -= nReg;
- }else{
- i = pParse->nMem+1;
- pParse->nMem += nReg;
- }
- return i;
-}
-SQLITE_PRIVATE void sqlite3ReleaseTempRange(Parse *pParse, int iReg, int nReg){
- if( nReg>pParse->nRangeReg ){
- pParse->nRangeReg = nReg;
- pParse->iRangeReg = iReg;
- }
-}
-
-/************** End of expr.c ************************************************/
-/************** Begin file alter.c *******************************************/
-/*
-** 2005 February 15
-**
-** 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 C code routines that used to generate VDBE code
-** that implements the ALTER TABLE command.
-**
-** $Id: alter.c,v 1.62 2009/07/24 17:58:53 danielk1977 Exp $
-*/
-
-/*
-** The code in this file only exists if we are not omitting the
-** ALTER TABLE logic from the build.
-*/
-#ifndef SQLITE_OMIT_ALTERTABLE
-
-
-/*
-** This function is used by SQL generated to implement the
-** ALTER TABLE command. The first argument is the text of a CREATE TABLE or
-** CREATE INDEX command. The second is a table name. The table name in
-** the CREATE TABLE or CREATE INDEX statement is replaced with the third
-** argument and the result returned. Examples:
-**
-** sqlite_rename_table('CREATE TABLE abc(a, b, c)', 'def')
-** -> 'CREATE TABLE def(a, b, c)'
-**
-** sqlite_rename_table('CREATE INDEX i ON abc(a)', 'def')
-** -> 'CREATE INDEX i ON def(a, b, c)'
-*/
-static void renameTableFunc(
- sqlite3_context *context,
- int NotUsed,
- sqlite3_value **argv
-){
- unsigned char const *zSql = sqlite3_value_text(argv[0]);
- unsigned char const *zTableName = sqlite3_value_text(argv[1]);
-
- int token;
- Token tname;
- unsigned char const *zCsr = zSql;
- int len = 0;
- char *zRet;
-
- sqlite3 *db = sqlite3_context_db_handle(context);
-
- UNUSED_PARAMETER(NotUsed);
-
- /* The principle used to locate the table name in the CREATE TABLE
- ** statement is that the table name is the first non-space token that
- ** is immediately followed by a TK_LP or TK_USING token.
- */
- if( zSql ){
- do {
- if( !*zCsr ){
- /* Ran out of input before finding an opening bracket. Return NULL. */
- return;
- }
-
- /* Store the token that zCsr points to in tname. */
- tname.z = (char*)zCsr;
- tname.n = len;
-
- /* Advance zCsr to the next token. Store that token type in 'token',
- ** and its length in 'len' (to be used next iteration of this loop).
- */
- do {
- zCsr += len;
- len = sqlite3GetToken(zCsr, &token);
- } while( token==TK_SPACE );
- assert( len>0 );
- } while( token!=TK_LP && token!=TK_USING );
-
- zRet = sqlite3MPrintf(db, "%.*s\"%w\"%s", ((u8*)tname.z) - zSql, zSql,
- zTableName, tname.z+tname.n);
- sqlite3_result_text(context, zRet, -1, SQLITE_DYNAMIC);
- }
-}
-
-#ifndef SQLITE_OMIT_TRIGGER
-/* This function is used by SQL generated to implement the
-** ALTER TABLE command. The first argument is the text of a CREATE TRIGGER
-** statement. The second is a table name. The table name in the CREATE
-** TRIGGER statement is replaced with the third argument and the result
-** returned. This is analagous to renameTableFunc() above, except for CREATE
-** TRIGGER, not CREATE INDEX and CREATE TABLE.
-*/
-static void renameTriggerFunc(
- sqlite3_context *context,
- int NotUsed,
- sqlite3_value **argv
-){
- unsigned char const *zSql = sqlite3_value_text(argv[0]);
- unsigned char const *zTableName = sqlite3_value_text(argv[1]);
-
- int token;
- Token tname;
- int dist = 3;
- unsigned char const *zCsr = zSql;
- int len = 0;
- char *zRet;
- sqlite3 *db = sqlite3_context_db_handle(context);
-
- UNUSED_PARAMETER(NotUsed);
-
- /* The principle used to locate the table name in the CREATE TRIGGER
- ** statement is that the table name is the first token that is immediatedly
- ** preceded by either TK_ON or TK_DOT and immediatedly followed by one
- ** of TK_WHEN, TK_BEGIN or TK_FOR.
- */
- if( zSql ){
- do {
-
- if( !*zCsr ){
- /* Ran out of input before finding the table name. Return NULL. */
- return;
- }
-
- /* Store the token that zCsr points to in tname. */
- tname.z = (char*)zCsr;
- tname.n = len;
-
- /* Advance zCsr to the next token. Store that token type in 'token',
- ** and its length in 'len' (to be used next iteration of this loop).
- */
- do {
- zCsr += len;
- len = sqlite3GetToken(zCsr, &token);
- }while( token==TK_SPACE );
- assert( len>0 );
-
- /* Variable 'dist' stores the number of tokens read since the most
- ** recent TK_DOT or TK_ON. This means that when a WHEN, FOR or BEGIN
- ** token is read and 'dist' equals 2, the condition stated above
- ** to be met.
- **
- ** Note that ON cannot be a database, table or column name, so
- ** there is no need to worry about syntax like
- ** "CREATE TRIGGER ... ON ON.ON BEGIN ..." etc.
- */
- dist++;
- if( token==TK_DOT || token==TK_ON ){
- dist = 0;
- }
- } while( dist!=2 || (token!=TK_WHEN && token!=TK_FOR && token!=TK_BEGIN) );
-
- /* Variable tname now contains the token that is the old table-name
- ** in the CREATE TRIGGER statement.
- */
- zRet = sqlite3MPrintf(db, "%.*s\"%w\"%s", ((u8*)tname.z) - zSql, zSql,
- zTableName, tname.z+tname.n);
- sqlite3_result_text(context, zRet, -1, SQLITE_DYNAMIC);
- }
-}
-#endif /* !SQLITE_OMIT_TRIGGER */
-
-/*
-** Register built-in functions used to help implement ALTER TABLE
-*/
-SQLITE_PRIVATE void sqlite3AlterFunctions(sqlite3 *db){
- sqlite3CreateFunc(db, "sqlite_rename_table", 2, SQLITE_UTF8, 0,
- renameTableFunc, 0, 0);
-#ifndef SQLITE_OMIT_TRIGGER
- sqlite3CreateFunc(db, "sqlite_rename_trigger", 2, SQLITE_UTF8, 0,
- renameTriggerFunc, 0, 0);
-#endif
-}
-
-/*
-** Generate the text of a WHERE expression which can be used to select all
-** temporary triggers on table pTab from the sqlite_temp_master table. If
-** table pTab has no temporary triggers, or is itself stored in the
-** temporary database, NULL is returned.
-*/
-static char *whereTempTriggers(Parse *pParse, Table *pTab){
- Trigger *pTrig;
- char *zWhere = 0;
- char *tmp = 0;
- const Schema *pTempSchema = pParse->db->aDb[1].pSchema; /* Temp db schema */
-
- /* If the table is not located in the temp-db (in which case NULL is
- ** returned, loop through the tables list of triggers. For each trigger
- ** that is not part of the temp-db schema, add a clause to the WHERE
- ** expression being built up in zWhere.
- */
- if( pTab->pSchema!=pTempSchema ){
- sqlite3 *db = pParse->db;
- for(pTrig=sqlite3TriggerList(pParse, pTab); pTrig; pTrig=pTrig->pNext){
- if( pTrig->pSchema==pTempSchema ){
- if( !zWhere ){
- zWhere = sqlite3MPrintf(db, "name=%Q", pTrig->zName);
- }else{
- tmp = zWhere;
- zWhere = sqlite3MPrintf(db, "%s OR name=%Q", zWhere, pTrig->zName);
- sqlite3DbFree(db, tmp);
- }
- }
- }
- }
- return zWhere;
-}
-
-/*
-** Generate code to drop and reload the internal representation of table
-** pTab from the database, including triggers and temporary triggers.
-** Argument zName is the name of the table in the database schema at
-** the time the generated code is executed. This can be different from
-** pTab->zName if this function is being called to code part of an
-** "ALTER TABLE RENAME TO" statement.
-*/
-static void reloadTableSchema(Parse *pParse, Table *pTab, const char *zName){
- Vdbe *v;
- char *zWhere;
- int iDb; /* Index of database containing pTab */
-#ifndef SQLITE_OMIT_TRIGGER
- Trigger *pTrig;
-#endif
-
- v = sqlite3GetVdbe(pParse);
- if( NEVER(v==0) ) return;
- assert( sqlite3BtreeHoldsAllMutexes(pParse->db) );
- iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
- assert( iDb>=0 );
-
-#ifndef SQLITE_OMIT_TRIGGER
- /* Drop any table triggers from the internal schema. */
- for(pTrig=sqlite3TriggerList(pParse, pTab); pTrig; pTrig=pTrig->pNext){
- int iTrigDb = sqlite3SchemaToIndex(pParse->db, pTrig->pSchema);
- assert( iTrigDb==iDb || iTrigDb==1 );
- sqlite3VdbeAddOp4(v, OP_DropTrigger, iTrigDb, 0, 0, pTrig->zName, 0);
- }
-#endif
-
- /* Drop the table and index from the internal schema */
- sqlite3VdbeAddOp4(v, OP_DropTable, iDb, 0, 0, pTab->zName, 0);
-
- /* Reload the table, index and permanent trigger schemas. */
- zWhere = sqlite3MPrintf(pParse->db, "tbl_name=%Q", zName);
- if( !zWhere ) return;
- sqlite3VdbeAddOp4(v, OP_ParseSchema, iDb, 0, 0, zWhere, P4_DYNAMIC);
-
-#ifndef SQLITE_OMIT_TRIGGER
- /* Now, if the table is not stored in the temp database, reload any temp
- ** triggers. Don't use IN(...) in case SQLITE_OMIT_SUBQUERY is defined.
- */
- if( (zWhere=whereTempTriggers(pParse, pTab))!=0 ){
- sqlite3VdbeAddOp4(v, OP_ParseSchema, 1, 0, 0, zWhere, P4_DYNAMIC);
- }
-#endif
-}
-
-/*
-** Generate code to implement the "ALTER TABLE xxx RENAME TO yyy"
-** command.
-*/
-SQLITE_PRIVATE void sqlite3AlterRenameTable(
- Parse *pParse, /* Parser context. */
- SrcList *pSrc, /* The table to rename. */
- Token *pName /* The new table name. */
-){
- int iDb; /* Database that contains the table */
- char *zDb; /* Name of database iDb */
- Table *pTab; /* Table being renamed */
- char *zName = 0; /* NULL-terminated version of pName */
- sqlite3 *db = pParse->db; /* Database connection */
- int nTabName; /* Number of UTF-8 characters in zTabName */
- const char *zTabName; /* Original name of the table */
- Vdbe *v;
-#ifndef SQLITE_OMIT_TRIGGER
- char *zWhere = 0; /* Where clause to locate temp triggers */
-#endif
- VTable *pVTab = 0; /* Non-zero if this is a v-tab with an xRename() */
-
- if( NEVER(db->mallocFailed) ) goto exit_rename_table;
- assert( pSrc->nSrc==1 );
- assert( sqlite3BtreeHoldsAllMutexes(pParse->db) );
-
- pTab = sqlite3LocateTable(pParse, 0, pSrc->a[0].zName, pSrc->a[0].zDatabase);
- if( !pTab ) goto exit_rename_table;
- iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
- zDb = db->aDb[iDb].zName;
-
- /* Get a NULL terminated version of the new table name. */
- zName = sqlite3NameFromToken(db, pName);
- if( !zName ) goto exit_rename_table;
-
- /* Check that a table or index named 'zName' does not already exist
- ** in database iDb. If so, this is an error.
- */
- if( sqlite3FindTable(db, zName, zDb) || sqlite3FindIndex(db, zName, zDb) ){
- sqlite3ErrorMsg(pParse,
- "there is already another table or index with this name: %s", zName);
- goto exit_rename_table;
- }
-
- /* Make sure it is not a system table being altered, or a reserved name
- ** that the table is being renamed to.
- */
- if( sqlite3Strlen30(pTab->zName)>6
- && 0==sqlite3StrNICmp(pTab->zName, "sqlite_", 7)
- ){
- sqlite3ErrorMsg(pParse, "table %s may not be altered", pTab->zName);
- goto exit_rename_table;
- }
- if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){
- goto exit_rename_table;
- }
-
-#ifndef SQLITE_OMIT_VIEW
- if( pTab->pSelect ){
- sqlite3ErrorMsg(pParse, "view %s may not be altered", pTab->zName);
- goto exit_rename_table;
- }
-#endif
-
-#ifndef SQLITE_OMIT_AUTHORIZATION
- /* Invoke the authorization callback. */
- if( sqlite3AuthCheck(pParse, SQLITE_ALTER_TABLE, zDb, pTab->zName, 0) ){
- goto exit_rename_table;
- }
-#endif
-
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- if( sqlite3ViewGetColumnNames(pParse, pTab) ){
- goto exit_rename_table;
- }
- if( IsVirtual(pTab) ){
- pVTab = sqlite3GetVTable(db, pTab);
- if( pVTab->pVtab->pModule->xRename==0 ){
- pVTab = 0;
- }
- }
-#endif
-
- /* Begin a transaction and code the VerifyCookie for database iDb.
- ** Then modify the schema cookie (since the ALTER TABLE modifies the
- ** schema). Open a statement transaction if the table is a virtual
- ** table.
- */
- v = sqlite3GetVdbe(pParse);
- if( v==0 ){
- goto exit_rename_table;
- }
- sqlite3BeginWriteOperation(pParse, pVTab!=0, iDb);
- sqlite3ChangeCookie(pParse, iDb);
-
- /* If this is a virtual table, invoke the xRename() function if
- ** one is defined. The xRename() callback will modify the names
- ** of any resources used by the v-table implementation (including other
- ** SQLite tables) that are identified by the name of the virtual table.
- */
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- if( pVTab ){
- int i = ++pParse->nMem;
- sqlite3VdbeAddOp4(v, OP_String8, 0, i, 0, zName, 0);
- sqlite3VdbeAddOp4(v, OP_VRename, i, 0, 0,(const char*)pVTab, P4_VTAB);
- sqlite3MayAbort(pParse);
- }
-#endif
-
- /* figure out how many UTF-8 characters are in zName */
- zTabName = pTab->zName;
- nTabName = sqlite3Utf8CharLen(zTabName, -1);
-
- /* Modify the sqlite_master table to use the new table name. */
- sqlite3NestedParse(pParse,
- "UPDATE %Q.%s SET "
-#ifdef SQLITE_OMIT_TRIGGER
- "sql = sqlite_rename_table(sql, %Q), "
-#else
- "sql = CASE "
- "WHEN type = 'trigger' THEN sqlite_rename_trigger(sql, %Q)"
- "ELSE sqlite_rename_table(sql, %Q) END, "
-#endif
- "tbl_name = %Q, "
- "name = CASE "
- "WHEN type='table' THEN %Q "
- "WHEN name LIKE 'sqlite_autoindex%%' AND type='index' THEN "
- "'sqlite_autoindex_' || %Q || substr(name,%d+18) "
- "ELSE name END "
- "WHERE tbl_name=%Q AND "
- "(type='table' OR type='index' OR type='trigger');",
- zDb, SCHEMA_TABLE(iDb), zName, zName, zName,
-#ifndef SQLITE_OMIT_TRIGGER
- zName,
-#endif
- zName, nTabName, zTabName
- );
-
-#ifndef SQLITE_OMIT_AUTOINCREMENT
- /* If the sqlite_sequence table exists in this database, then update
- ** it with the new table name.
- */
- if( sqlite3FindTable(db, "sqlite_sequence", zDb) ){
- sqlite3NestedParse(pParse,
- "UPDATE \"%w\".sqlite_sequence set name = %Q WHERE name = %Q",
- zDb, zName, pTab->zName);
- }
-#endif
-
-#ifndef SQLITE_OMIT_TRIGGER
- /* If there are TEMP triggers on this table, modify the sqlite_temp_master
- ** table. Don't do this if the table being ALTERed is itself located in
- ** the temp database.
- */
- if( (zWhere=whereTempTriggers(pParse, pTab))!=0 ){
- sqlite3NestedParse(pParse,
- "UPDATE sqlite_temp_master SET "
- "sql = sqlite_rename_trigger(sql, %Q), "
- "tbl_name = %Q "
- "WHERE %s;", zName, zName, zWhere);
- sqlite3DbFree(db, zWhere);
- }
-#endif
-
- /* Drop and reload the internal table schema. */
- reloadTableSchema(pParse, pTab, zName);
-
-exit_rename_table:
- sqlite3SrcListDelete(db, pSrc);
- sqlite3DbFree(db, zName);
-}
-
-
-/*
-** Generate code to make sure the file format number is at least minFormat.
-** The generated code will increase the file format number if necessary.
-*/
-SQLITE_PRIVATE void sqlite3MinimumFileFormat(Parse *pParse, int iDb, int minFormat){
- Vdbe *v;
- v = sqlite3GetVdbe(pParse);
- /* The VDBE should have been allocated before this routine is called.
- ** If that allocation failed, we would have quit before reaching this
- ** point */
- if( ALWAYS(v) ){
- int r1 = sqlite3GetTempReg(pParse);
- int r2 = sqlite3GetTempReg(pParse);
- int j1;
- sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, r1, BTREE_FILE_FORMAT);
- sqlite3VdbeUsesBtree(v, iDb);
- sqlite3VdbeAddOp2(v, OP_Integer, minFormat, r2);
- j1 = sqlite3VdbeAddOp3(v, OP_Ge, r2, 0, r1);
- sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, r2);
- sqlite3VdbeJumpHere(v, j1);
- sqlite3ReleaseTempReg(pParse, r1);
- sqlite3ReleaseTempReg(pParse, r2);
- }
-}
-
-/*
-** This function is called after an "ALTER TABLE ... ADD" statement
-** has been parsed. Argument pColDef contains the text of the new
-** column definition.
-**
-** The Table structure pParse->pNewTable was extended to include
-** the new column during parsing.
-*/
-SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){
- Table *pNew; /* Copy of pParse->pNewTable */
- Table *pTab; /* Table being altered */
- int iDb; /* Database number */
- const char *zDb; /* Database name */
- const char *zTab; /* Table name */
- char *zCol; /* Null-terminated column definition */
- Column *pCol; /* The new column */
- Expr *pDflt; /* Default value for the new column */
- sqlite3 *db; /* The database connection; */
-
- db = pParse->db;
- if( pParse->nErr || db->mallocFailed ) return;
- pNew = pParse->pNewTable;
- assert( pNew );
-
- assert( sqlite3BtreeHoldsAllMutexes(db) );
- iDb = sqlite3SchemaToIndex(db, pNew->pSchema);
- zDb = db->aDb[iDb].zName;
- zTab = &pNew->zName[16]; /* Skip the "sqlite_altertab_" prefix on the name */
- pCol = &pNew->aCol[pNew->nCol-1];
- pDflt = pCol->pDflt;
- pTab = sqlite3FindTable(db, zTab, zDb);
- assert( pTab );
-
-#ifndef SQLITE_OMIT_AUTHORIZATION
- /* Invoke the authorization callback. */
- if( sqlite3AuthCheck(pParse, SQLITE_ALTER_TABLE, zDb, pTab->zName, 0) ){
- return;
- }
-#endif
-
- /* If the default value for the new column was specified with a
- ** literal NULL, then set pDflt to 0. This simplifies checking
- ** for an SQL NULL default below.
- */
- if( pDflt && pDflt->op==TK_NULL ){
- pDflt = 0;
- }
-
- /* Check that the new column is not specified as PRIMARY KEY or UNIQUE.
- ** If there is a NOT NULL constraint, then the default value for the
- ** column must not be NULL.
- */
- if( pCol->isPrimKey ){
- sqlite3ErrorMsg(pParse, "Cannot add a PRIMARY KEY column");
- return;
- }
- if( pNew->pIndex ){
- sqlite3ErrorMsg(pParse, "Cannot add a UNIQUE column");
- return;
- }
- if( pCol->notNull && !pDflt ){
- sqlite3ErrorMsg(pParse,
- "Cannot add a NOT NULL column with default value NULL");
- return;
- }
-
- /* Ensure the default expression is something that sqlite3ValueFromExpr()
- ** can handle (i.e. not CURRENT_TIME etc.)
- */
- if( pDflt ){
- sqlite3_value *pVal;
- if( sqlite3ValueFromExpr(db, pDflt, SQLITE_UTF8, SQLITE_AFF_NONE, &pVal) ){
- db->mallocFailed = 1;
- return;
- }
- if( !pVal ){
- sqlite3ErrorMsg(pParse, "Cannot add a column with non-constant default");
- return;
- }
- sqlite3ValueFree(pVal);
- }
-
- /* Modify the CREATE TABLE statement. */
- zCol = sqlite3DbStrNDup(db, (char*)pColDef->z, pColDef->n);
- if( zCol ){
- char *zEnd = &zCol[pColDef->n-1];
- while( zEnd>zCol && (*zEnd==';' || sqlite3Isspace(*zEnd)) ){
- *zEnd-- = '\0';
- }
- sqlite3NestedParse(pParse,
- "UPDATE \"%w\".%s SET "
- "sql = substr(sql,1,%d) || ', ' || %Q || substr(sql,%d) "
- "WHERE type = 'table' AND name = %Q",
- zDb, SCHEMA_TABLE(iDb), pNew->addColOffset, zCol, pNew->addColOffset+1,
- zTab
- );
- sqlite3DbFree(db, zCol);
- }
-
- /* If the default value of the new column is NULL, then set the file
- ** format to 2. If the default value of the new column is not NULL,
- ** the file format becomes 3.
- */
- sqlite3MinimumFileFormat(pParse, iDb, pDflt ? 3 : 2);
-
- /* Reload the schema of the modified table. */
- reloadTableSchema(pParse, pTab, pTab->zName);
-}
-
-/*
-** This function is called by the parser after the table-name in
-** an "ALTER TABLE <table-name> ADD" statement is parsed. Argument
-** pSrc is the full-name of the table being altered.
-**
-** This routine makes a (partial) copy of the Table structure
-** for the table being altered and sets Parse.pNewTable to point
-** to it. Routines called by the parser as the column definition
-** is parsed (i.e. sqlite3AddColumn()) add the new Column data to
-** the copy. The copy of the Table structure is deleted by tokenize.c
-** after parsing is finished.
-**
-** Routine sqlite3AlterFinishAddColumn() will be called to complete
-** coding the "ALTER TABLE ... ADD" statement.
-*/
-SQLITE_PRIVATE void sqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){
- Table *pNew;
- Table *pTab;
- Vdbe *v;
- int iDb;
- int i;
- int nAlloc;
- sqlite3 *db = pParse->db;
-
- /* Look up the table being altered. */
- assert( pParse->pNewTable==0 );
- assert( sqlite3BtreeHoldsAllMutexes(db) );
- if( db->mallocFailed ) goto exit_begin_add_column;
- pTab = sqlite3LocateTable(pParse, 0, pSrc->a[0].zName, pSrc->a[0].zDatabase);
- if( !pTab ) goto exit_begin_add_column;
-
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- if( IsVirtual(pTab) ){
- sqlite3ErrorMsg(pParse, "virtual tables may not be altered");
- goto exit_begin_add_column;
- }
-#endif
-
- /* Make sure this is not an attempt to ALTER a view. */
- if( pTab->pSelect ){
- sqlite3ErrorMsg(pParse, "Cannot add a column to a view");
- goto exit_begin_add_column;
- }
-
- assert( pTab->addColOffset>0 );
- iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
-
- /* Put a copy of the Table struct in Parse.pNewTable for the
- ** sqlite3AddColumn() function and friends to modify. But modify
- ** the name by adding an "sqlite_altertab_" prefix. By adding this
- ** prefix, we insure that the name will not collide with an existing
- ** table because user table are not allowed to have the "sqlite_"
- ** prefix on their name.
- */
- pNew = (Table*)sqlite3DbMallocZero(db, sizeof(Table));
- if( !pNew ) goto exit_begin_add_column;
- pParse->pNewTable = pNew;
- pNew->nRef = 1;
- pNew->dbMem = pTab->dbMem;
- pNew->nCol = pTab->nCol;
- assert( pNew->nCol>0 );
- nAlloc = (((pNew->nCol-1)/8)*8)+8;
- assert( nAlloc>=pNew->nCol && nAlloc%8==0 && nAlloc-pNew->nCol<8 );
- pNew->aCol = (Column*)sqlite3DbMallocZero(db, sizeof(Column)*nAlloc);
- pNew->zName = sqlite3MPrintf(db, "sqlite_altertab_%s", pTab->zName);
- if( !pNew->aCol || !pNew->zName ){
- db->mallocFailed = 1;
- goto exit_begin_add_column;
- }
- memcpy(pNew->aCol, pTab->aCol, sizeof(Column)*pNew->nCol);
- for(i=0; i<pNew->nCol; i++){
- Column *pCol = &pNew->aCol[i];
- pCol->zName = sqlite3DbStrDup(db, pCol->zName);
- pCol->zColl = 0;
- pCol->zType = 0;
- pCol->pDflt = 0;
- pCol->zDflt = 0;
- }
- pNew->pSchema = db->aDb[iDb].pSchema;
- pNew->addColOffset = pTab->addColOffset;
- pNew->nRef = 1;
-
- /* Begin a transaction and increment the schema cookie. */
- sqlite3BeginWriteOperation(pParse, 0, iDb);
- v = sqlite3GetVdbe(pParse);
- if( !v ) goto exit_begin_add_column;
- sqlite3ChangeCookie(pParse, iDb);
-
-exit_begin_add_column:
- sqlite3SrcListDelete(db, pSrc);
- return;
-}
-#endif /* SQLITE_ALTER_TABLE */
-
-/************** End of alter.c ***********************************************/
-/************** Begin file analyze.c *****************************************/
-/*
-** 2005 July 8
-**
-** 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 code associated with the ANALYZE command.
-**
-** @(#) $Id: analyze.c,v 1.52 2009/04/16 17:45:48 drh Exp $
-*/
-#ifndef SQLITE_OMIT_ANALYZE
-
-/*
-** This routine generates code that opens the sqlite_stat1 table for
-** writing with cursor iStatCur. If the library was built with the
-** SQLITE_ENABLE_STAT2 macro defined, then the sqlite_stat2 table is
-** opened for writing using cursor (iStatCur+1)
-**
-** If the sqlite_stat1 tables does not previously exist, it is created.
-** Similarly, if the sqlite_stat2 table does not exist and the library
-** is compiled with SQLITE_ENABLE_STAT2 defined, it is created.
-**
-** Argument zWhere may be a pointer to a buffer containing a table name,
-** or it may be a NULL pointer. If it is not NULL, then all entries in
-** the sqlite_stat1 and (if applicable) sqlite_stat2 tables associated
-** with the named table are deleted. If zWhere==0, then code is generated
-** to delete all stat table entries.
-*/
-static void openStatTable(
- Parse *pParse, /* Parsing context */
- int iDb, /* The database we are looking in */
- int iStatCur, /* Open the sqlite_stat1 table on this cursor */
- const char *zWhere /* Delete entries associated with this table */
-){
- static struct {
- const char *zName;
- const char *zCols;
- } aTable[] = {
- { "sqlite_stat1", "tbl,idx,stat" },
-#ifdef SQLITE_ENABLE_STAT2
- { "sqlite_stat2", "tbl,idx,sampleno,sample" },
-#endif
- };
-
- int aRoot[] = {0, 0};
- u8 aCreateTbl[] = {0, 0};
-
- int i;
- sqlite3 *db = pParse->db;
- Db *pDb;
- Vdbe *v = sqlite3GetVdbe(pParse);
- if( v==0 ) return;
- assert( sqlite3BtreeHoldsAllMutexes(db) );
- assert( sqlite3VdbeDb(v)==db );
- pDb = &db->aDb[iDb];
-
- for(i=0; i<ArraySize(aTable); i++){
- const char *zTab = aTable[i].zName;
- Table *pStat;
- if( (pStat = sqlite3FindTable(db, zTab, pDb->zName))==0 ){
- /* The sqlite_stat[12] table does not exist. Create it. Note that a
- ** side-effect of the CREATE TABLE statement is to leave the rootpage
- ** of the new table in register pParse->regRoot. This is important
- ** because the OpenWrite opcode below will be needing it. */
- sqlite3NestedParse(pParse,
- "CREATE TABLE %Q.%s(%s)", pDb->zName, zTab, aTable[i].zCols
- );
- aRoot[i] = pParse->regRoot;
- aCreateTbl[i] = 1;
- }else{
- /* The table already exists. If zWhere is not NULL, delete all entries
- ** associated with the table zWhere. If zWhere is NULL, delete the
- ** entire contents of the table. */
- aRoot[i] = pStat->tnum;
- sqlite3TableLock(pParse, iDb, aRoot[i], 1, zTab);
- if( zWhere ){
- sqlite3NestedParse(pParse,
- "DELETE FROM %Q.%s WHERE tbl=%Q", pDb->zName, zTab, zWhere
- );
- }else{
- /* The sqlite_stat[12] table already exists. Delete all rows. */
- sqlite3VdbeAddOp2(v, OP_Clear, aRoot[i], iDb);
- }
- }
- }
-
- /* Open the sqlite_stat[12] tables for writing. */
- for(i=0; i<ArraySize(aTable); i++){
- sqlite3VdbeAddOp3(v, OP_OpenWrite, iStatCur+i, aRoot[i], iDb);
- sqlite3VdbeChangeP4(v, -1, (char *)3, P4_INT32);
- sqlite3VdbeChangeP5(v, aCreateTbl[i]);
- }
-}
-
-/*
-** Generate code to do an analysis of all indices associated with
-** a single table.
-*/
-static void analyzeOneTable(
- Parse *pParse, /* Parser context */
- Table *pTab, /* Table whose indices are to be analyzed */
- int iStatCur, /* Index of VdbeCursor that writes the sqlite_stat1 table */
- int iMem /* Available memory locations begin here */
-){
- sqlite3 *db = pParse->db; /* Database handle */
- Index *pIdx; /* An index to being analyzed */
- int iIdxCur; /* Cursor open on index being analyzed */
- Vdbe *v; /* The virtual machine being built up */
- int i; /* Loop counter */
- int topOfLoop; /* The top of the loop */
- int endOfLoop; /* The end of the loop */
- int addr; /* The address of an instruction */
- int iDb; /* Index of database containing pTab */
- int regTabname = iMem++; /* Register containing table name */
- int regIdxname = iMem++; /* Register containing index name */
- int regSampleno = iMem++; /* Register containing next sample number */
- int regCol = iMem++; /* Content of a column analyzed table */
- int regRec = iMem++; /* Register holding completed record */
- int regTemp = iMem++; /* Temporary use register */
- int regRowid = iMem++; /* Rowid for the inserted record */
-
-#ifdef SQLITE_ENABLE_STAT2
- int regTemp2 = iMem++; /* Temporary use register */
- int regSamplerecno = iMem++; /* Index of next sample to record */
- int regRecno = iMem++; /* Current sample index */
- int regLast = iMem++; /* Index of last sample to record */
- int regFirst = iMem++; /* Index of first sample to record */
-#endif
-
- v = sqlite3GetVdbe(pParse);
- if( v==0 || NEVER(pTab==0) || pTab->pIndex==0 ){
- /* Do no analysis for tables that have no indices */
- return;
- }
- assert( sqlite3BtreeHoldsAllMutexes(db) );
- iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
- assert( iDb>=0 );
-#ifndef SQLITE_OMIT_AUTHORIZATION
- if( sqlite3AuthCheck(pParse, SQLITE_ANALYZE, pTab->zName, 0,
- db->aDb[iDb].zName ) ){
- return;
- }
-#endif
-
- /* Establish a read-lock on the table at the shared-cache level. */
- sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
-
- iIdxCur = pParse->nTab++;
- for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
- int nCol = pIdx->nColumn;
- KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx);
-
- if( iMem+1+(nCol*2)>pParse->nMem ){
- pParse->nMem = iMem+1+(nCol*2);
- }
-
- /* Open a cursor to the index to be analyzed. */
- assert( iDb==sqlite3SchemaToIndex(db, pIdx->pSchema) );
- sqlite3VdbeAddOp4(v, OP_OpenRead, iIdxCur, pIdx->tnum, iDb,
- (char *)pKey, P4_KEYINFO_HANDOFF);
- VdbeComment((v, "%s", pIdx->zName));
-
- /* Populate the registers containing the table and index names. */
- if( pTab->pIndex==pIdx ){
- sqlite3VdbeAddOp4(v, OP_String8, 0, regTabname, 0, pTab->zName, 0);
- }
- sqlite3VdbeAddOp4(v, OP_String8, 0, regIdxname, 0, pIdx->zName, 0);
-
-#ifdef SQLITE_ENABLE_STAT2
-
- /* If this iteration of the loop is generating code to analyze the
- ** first index in the pTab->pIndex list, then register regLast has
- ** not been populated. In this case populate it now. */
- if( pTab->pIndex==pIdx ){
- sqlite3VdbeAddOp2(v, OP_Integer, SQLITE_INDEX_SAMPLES, regSamplerecno);
- sqlite3VdbeAddOp2(v, OP_Integer, SQLITE_INDEX_SAMPLES*2-1, regTemp);
- sqlite3VdbeAddOp2(v, OP_Integer, SQLITE_INDEX_SAMPLES*2, regTemp2);
-
- sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regLast);
- sqlite3VdbeAddOp2(v, OP_Null, 0, regFirst);
- addr = sqlite3VdbeAddOp3(v, OP_Lt, regSamplerecno, 0, regLast);
- sqlite3VdbeAddOp3(v, OP_Divide, regTemp2, regLast, regFirst);
- sqlite3VdbeAddOp3(v, OP_Multiply, regLast, regTemp, regLast);
- sqlite3VdbeAddOp2(v, OP_AddImm, regLast, SQLITE_INDEX_SAMPLES*2-2);
- sqlite3VdbeAddOp3(v, OP_Divide, regTemp2, regLast, regLast);
- sqlite3VdbeJumpHere(v, addr);
- }
-
- /* Zero the regSampleno and regRecno registers. */
- sqlite3VdbeAddOp2(v, OP_Integer, 0, regSampleno);
- sqlite3VdbeAddOp2(v, OP_Integer, 0, regRecno);
- sqlite3VdbeAddOp2(v, OP_Copy, regFirst, regSamplerecno);
-#endif
-
- /* The block of memory cells initialized here is used as follows.
- **
- ** iMem:
- ** The total number of rows in the table.
- **
- ** iMem+1 .. iMem+nCol:
- ** Number of distinct entries in index considering the
- ** left-most N columns only, where N is between 1 and nCol,
- ** inclusive.
- **
- ** iMem+nCol+1 .. Mem+2*nCol:
- ** Previous value of indexed columns, from left to right.
- **
- ** Cells iMem through iMem+nCol are initialized to 0. The others are
- ** initialized to contain an SQL NULL.
- */
- for(i=0; i<=nCol; i++){
- sqlite3VdbeAddOp2(v, OP_Integer, 0, iMem+i);
- }
- for(i=0; i<nCol; i++){
- sqlite3VdbeAddOp2(v, OP_Null, 0, iMem+nCol+i+1);
- }
-
- /* Start the analysis loop. This loop runs through all the entries in
- ** the index b-tree. */
- endOfLoop = sqlite3VdbeMakeLabel(v);
- sqlite3VdbeAddOp2(v, OP_Rewind, iIdxCur, endOfLoop);
- topOfLoop = sqlite3VdbeCurrentAddr(v);
- sqlite3VdbeAddOp2(v, OP_AddImm, iMem, 1);
-
- for(i=0; i<nCol; i++){
- sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, regCol);
-#ifdef SQLITE_ENABLE_STAT2
- if( i==0 ){
- /* Check if the record that cursor iIdxCur points to contains a
- ** value that should be stored in the sqlite_stat2 table. If so,
- ** store it. */
- int ne = sqlite3VdbeAddOp3(v, OP_Ne, regRecno, 0, regSamplerecno);
- assert( regTabname+1==regIdxname
- && regTabname+2==regSampleno
- && regTabname+3==regCol
- );
- sqlite3VdbeChangeP5(v, SQLITE_JUMPIFNULL);
- sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 4, regRec, "aaab", 0);
- sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur+1, regRowid);
- sqlite3VdbeAddOp3(v, OP_Insert, iStatCur+1, regRec, regRowid);
-
- /* Calculate new values for regSamplerecno and regSampleno.
- **
- ** sampleno = sampleno + 1
- ** samplerecno = samplerecno+(remaining records)/(remaining samples)
- */
- sqlite3VdbeAddOp2(v, OP_AddImm, regSampleno, 1);
- sqlite3VdbeAddOp3(v, OP_Subtract, regRecno, regLast, regTemp);
- sqlite3VdbeAddOp2(v, OP_AddImm, regTemp, -1);
- sqlite3VdbeAddOp2(v, OP_Integer, SQLITE_INDEX_SAMPLES, regTemp2);
- sqlite3VdbeAddOp3(v, OP_Subtract, regSampleno, regTemp2, regTemp2);
- sqlite3VdbeAddOp3(v, OP_Divide, regTemp2, regTemp, regTemp);
- sqlite3VdbeAddOp3(v, OP_Add, regSamplerecno, regTemp, regSamplerecno);
-
- sqlite3VdbeJumpHere(v, ne);
- sqlite3VdbeAddOp2(v, OP_AddImm, regRecno, 1);
- }
-#endif
-
- sqlite3VdbeAddOp3(v, OP_Ne, regCol, 0, iMem+nCol+i+1);
- /**** TODO: add collating sequence *****/
- sqlite3VdbeChangeP5(v, SQLITE_JUMPIFNULL);
- }
- if( db->mallocFailed ){
- /* If a malloc failure has occurred, then the result of the expression
- ** passed as the second argument to the call to sqlite3VdbeJumpHere()
- ** below may be negative. Which causes an assert() to fail (or an
- ** out-of-bounds write if SQLITE_DEBUG is not defined). */
- return;
- }
- sqlite3VdbeAddOp2(v, OP_Goto, 0, endOfLoop);
- for(i=0; i<nCol; i++){
- sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-(nCol*2));
- sqlite3VdbeAddOp2(v, OP_AddImm, iMem+i+1, 1);
- sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, iMem+nCol+i+1);
- }
-
- /* End of the analysis loop. */
- sqlite3VdbeResolveLabel(v, endOfLoop);
- sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, topOfLoop);
- sqlite3VdbeAddOp1(v, OP_Close, iIdxCur);
-
- /* Store the results in sqlite_stat1.
- **
- ** The result is a single row of the sqlite_stat1 table. The first
- ** two columns are the names of the table and index. The third column
- ** is a string composed of a list of integer statistics about the
- ** index. The first integer in the list is the total number of entries
- ** in the index. There is one additional integer in the list for each
- ** column of the table. This additional integer is a guess of how many
- ** rows of the table the index will select. If D is the count of distinct
- ** values and K is the total number of rows, then the integer is computed
- ** as:
- **
- ** I = (K+D-1)/D
- **
- ** If K==0 then no entry is made into the sqlite_stat1 table.
- ** If K>0 then it is always the case the D>0 so division by zero
- ** is never possible.
- */
- addr = sqlite3VdbeAddOp1(v, OP_IfNot, iMem);
- sqlite3VdbeAddOp2(v, OP_SCopy, iMem, regSampleno);
- for(i=0; i<nCol; i++){
- sqlite3VdbeAddOp4(v, OP_String8, 0, regTemp, 0, " ", 0);
- sqlite3VdbeAddOp3(v, OP_Concat, regTemp, regSampleno, regSampleno);
- sqlite3VdbeAddOp3(v, OP_Add, iMem, iMem+i+1, regTemp);
- sqlite3VdbeAddOp2(v, OP_AddImm, regTemp, -1);
- sqlite3VdbeAddOp3(v, OP_Divide, iMem+i+1, regTemp, regTemp);
- sqlite3VdbeAddOp1(v, OP_ToInt, regTemp);
- sqlite3VdbeAddOp3(v, OP_Concat, regTemp, regSampleno, regSampleno);
- }
- sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regRec, "aaa", 0);
- sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regRowid);
- sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regRec, regRowid);
- sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
- sqlite3VdbeJumpHere(v, addr);
- }
-}
-
-/*
-** Generate code that will cause the most recent index analysis to
-** be laoded into internal hash tables where is can be used.
-*/
-static void loadAnalysis(Parse *pParse, int iDb){
- Vdbe *v = sqlite3GetVdbe(pParse);
- if( v ){
- sqlite3VdbeAddOp1(v, OP_LoadAnalysis, iDb);
- }
-}
-
-/*
-** Generate code that will do an analysis of an entire database
-*/
-static void analyzeDatabase(Parse *pParse, int iDb){
- sqlite3 *db = pParse->db;
- Schema *pSchema = db->aDb[iDb].pSchema; /* Schema of database iDb */
- HashElem *k;
- int iStatCur;
- int iMem;
-
- sqlite3BeginWriteOperation(pParse, 0, iDb);
- iStatCur = pParse->nTab;
- pParse->nTab += 2;
- openStatTable(pParse, iDb, iStatCur, 0);
- iMem = pParse->nMem+1;
- for(k=sqliteHashFirst(&pSchema->tblHash); k; k=sqliteHashNext(k)){
- Table *pTab = (Table*)sqliteHashData(k);
- analyzeOneTable(pParse, pTab, iStatCur, iMem);
- }
- loadAnalysis(pParse, iDb);
-}
-
-/*
-** Generate code that will do an analysis of a single table in
-** a database.
-*/
-static void analyzeTable(Parse *pParse, Table *pTab){
- int iDb;
- int iStatCur;
-
- assert( pTab!=0 );
- assert( sqlite3BtreeHoldsAllMutexes(pParse->db) );
- iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
- sqlite3BeginWriteOperation(pParse, 0, iDb);
- iStatCur = pParse->nTab;
- pParse->nTab += 2;
- openStatTable(pParse, iDb, iStatCur, pTab->zName);
- analyzeOneTable(pParse, pTab, iStatCur, pParse->nMem+1);
- loadAnalysis(pParse, iDb);
-}
-
-/*
-** Generate code for the ANALYZE command. The parser calls this routine
-** when it recognizes an ANALYZE command.
-**
-** ANALYZE -- 1
-** ANALYZE <database> -- 2
-** ANALYZE ?<database>.?<tablename> -- 3
-**
-** Form 1 causes all indices in all attached databases to be analyzed.
-** Form 2 analyzes all indices the single database named.
-** Form 3 analyzes all indices associated with the named table.
-*/
-SQLITE_PRIVATE void sqlite3Analyze(Parse *pParse, Token *pName1, Token *pName2){
- sqlite3 *db = pParse->db;
- int iDb;
- int i;
- char *z, *zDb;
- Table *pTab;
- Token *pTableName;
-
- /* Read the database schema. If an error occurs, leave an error message
- ** and code in pParse and return NULL. */
- assert( sqlite3BtreeHoldsAllMutexes(pParse->db) );
- if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
- return;
- }
-
- assert( pName2!=0 || pName1==0 );
- if( pName1==0 ){
- /* Form 1: Analyze everything */
- for(i=0; i<db->nDb; i++){
- if( i==1 ) continue; /* Do not analyze the TEMP database */
- analyzeDatabase(pParse, i);
- }
- }else if( pName2->n==0 ){
- /* Form 2: Analyze the database or table named */
- iDb = sqlite3FindDb(db, pName1);
- if( iDb>=0 ){
- analyzeDatabase(pParse, iDb);
- }else{
- z = sqlite3NameFromToken(db, pName1);
- if( z ){
- pTab = sqlite3LocateTable(pParse, 0, z, 0);
- sqlite3DbFree(db, z);
- if( pTab ){
- analyzeTable(pParse, pTab);
- }
- }
- }
- }else{
- /* Form 3: Analyze the fully qualified table name */
- iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pTableName);
- if( iDb>=0 ){
- zDb = db->aDb[iDb].zName;
- z = sqlite3NameFromToken(db, pTableName);
- if( z ){
- pTab = sqlite3LocateTable(pParse, 0, z, zDb);
- sqlite3DbFree(db, z);
- if( pTab ){
- analyzeTable(pParse, pTab);
- }
- }
- }
- }
-}
-
-/*
-** Used to pass information from the analyzer reader through to the
-** callback routine.
-*/
-typedef struct analysisInfo analysisInfo;
-struct analysisInfo {
- sqlite3 *db;
- const char *zDatabase;
-};
-
-/*
-** This callback is invoked once for each index when reading the
-** sqlite_stat1 table.
-**
-** argv[0] = name of the index
-** argv[1] = results of analysis - on integer for each column
-*/
-static int analysisLoader(void *pData, int argc, char **argv, char **NotUsed){
- analysisInfo *pInfo = (analysisInfo*)pData;
- Index *pIndex;
- int i, c;
- unsigned int v;
- const char *z;
-
- assert( argc==2 );
- UNUSED_PARAMETER2(NotUsed, argc);
-
- if( argv==0 || argv[0]==0 || argv[1]==0 ){
- return 0;
- }
- pIndex = sqlite3FindIndex(pInfo->db, argv[0], pInfo->zDatabase);
- if( pIndex==0 ){
- return 0;
- }
- z = argv[1];
- for(i=0; *z && i<=pIndex->nColumn; i++){
- v = 0;
- while( (c=z[0])>='0' && c<='9' ){
- v = v*10 + c - '0';
- z++;
- }
- pIndex->aiRowEst[i] = v;
- if( *z==' ' ) z++;
- }
- return 0;
-}
-
-/*
-** If the Index.aSample variable is not NULL, delete the aSample[] array
-** and its contents.
-*/
-SQLITE_PRIVATE void sqlite3DeleteIndexSamples(Index *pIdx){
-#ifdef SQLITE_ENABLE_STAT2
- if( pIdx->aSample ){
- int j;
- sqlite3 *dbMem = pIdx->pTable->dbMem;
- for(j=0; j<SQLITE_INDEX_SAMPLES; j++){
- IndexSample *p = &pIdx->aSample[j];
- if( p->eType==SQLITE_TEXT || p->eType==SQLITE_BLOB ){
- sqlite3DbFree(pIdx->pTable->dbMem, p->u.z);
- }
- }
- sqlite3DbFree(dbMem, pIdx->aSample);
- pIdx->aSample = 0;
- }
-#else
- UNUSED_PARAMETER(pIdx);
-#endif
-}
-
-/*
-** Load the content of the sqlite_stat1 and sqlite_stat2 tables. The
-** contents of sqlite_stat1 are used to populate the Index.aiRowEst[]
-** arrays. The contents of sqlite_stat2 are used to populate the
-** Index.aSample[] arrays.
-**
-** If the sqlite_stat1 table is not present in the database, SQLITE_ERROR
-** is returned. In this case, even if SQLITE_ENABLE_STAT2 was defined
-** during compilation and the sqlite_stat2 table is present, no data is
-** read from it.
-**
-** If SQLITE_ENABLE_STAT2 was defined during compilation and the
-** sqlite_stat2 table is not present in the database, SQLITE_ERROR is
-** returned. However, in this case, data is read from the sqlite_stat1
-** table (if it is present) before returning.
-**
-** If an OOM error occurs, this function always sets db->mallocFailed.
-** This means if the caller does not care about other errors, the return
-** code may be ignored.
-*/
-SQLITE_PRIVATE int sqlite3AnalysisLoad(sqlite3 *db, int iDb){
- analysisInfo sInfo;
- HashElem *i;
- char *zSql;
- int rc;
-
- assert( iDb>=0 && iDb<db->nDb );
- assert( db->aDb[iDb].pBt!=0 );
- assert( sqlite3BtreeHoldsMutex(db->aDb[iDb].pBt) );
-
- /* Clear any prior statistics */
- for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash);i;i=sqliteHashNext(i)){
- Index *pIdx = sqliteHashData(i);
- sqlite3DefaultRowEst(pIdx);
- sqlite3DeleteIndexSamples(pIdx);
- }
-
- /* Check to make sure the sqlite_stat1 table exists */
- sInfo.db = db;
- sInfo.zDatabase = db->aDb[iDb].zName;
- if( sqlite3FindTable(db, "sqlite_stat1", sInfo.zDatabase)==0 ){
- return SQLITE_ERROR;
- }
-
- /* Load new statistics out of the sqlite_stat1 table */
- zSql = sqlite3MPrintf(db,
- "SELECT idx, stat FROM %Q.sqlite_stat1", sInfo.zDatabase);
- if( zSql==0 ){
- rc = SQLITE_NOMEM;
- }else{
- (void)sqlite3SafetyOff(db);
- rc = sqlite3_exec(db, zSql, analysisLoader, &sInfo, 0);
- (void)sqlite3SafetyOn(db);
- sqlite3DbFree(db, zSql);
- }
-
-
- /* Load the statistics from the sqlite_stat2 table. */
-#ifdef SQLITE_ENABLE_STAT2
- if( rc==SQLITE_OK && !sqlite3FindTable(db, "sqlite_stat2", sInfo.zDatabase) ){
- rc = SQLITE_ERROR;
- }
- if( rc==SQLITE_OK ){
- sqlite3_stmt *pStmt = 0;
-
- zSql = sqlite3MPrintf(db,
- "SELECT idx,sampleno,sample FROM %Q.sqlite_stat2", sInfo.zDatabase);
- if( !zSql ){
- rc = SQLITE_NOMEM;
- }else{
- (void)sqlite3SafetyOff(db);
- rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0);
- (void)sqlite3SafetyOn(db);
- sqlite3DbFree(db, zSql);
- }
-
- if( rc==SQLITE_OK ){
- (void)sqlite3SafetyOff(db);
- while( sqlite3_step(pStmt)==SQLITE_ROW ){
- char *zIndex = (char *)sqlite3_column_text(pStmt, 0);
- Index *pIdx = sqlite3FindIndex(db, zIndex, sInfo.zDatabase);
- if( pIdx ){
- int iSample = sqlite3_column_int(pStmt, 1);
- sqlite3 *dbMem = pIdx->pTable->dbMem;
- assert( dbMem==db || dbMem==0 );
- if( iSample<SQLITE_INDEX_SAMPLES && iSample>=0 ){
- int eType = sqlite3_column_type(pStmt, 2);
-
- if( pIdx->aSample==0 ){
- static const int sz = sizeof(IndexSample)*SQLITE_INDEX_SAMPLES;
- pIdx->aSample = (IndexSample *)sqlite3DbMallocZero(dbMem, sz);
- if( pIdx->aSample==0 ){
- db->mallocFailed = 1;
- break;
- }
- }
-
- assert( pIdx->aSample );
- {
- IndexSample *pSample = &pIdx->aSample[iSample];
- pSample->eType = (u8)eType;
- if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){
- pSample->u.r = sqlite3_column_double(pStmt, 2);
- }else if( eType==SQLITE_TEXT || eType==SQLITE_BLOB ){
- const char *z = (const char *)(
- (eType==SQLITE_BLOB) ?
- sqlite3_column_blob(pStmt, 2):
- sqlite3_column_text(pStmt, 2)
- );
- int n = sqlite3_column_bytes(pStmt, 2);
- if( n>24 ){
- n = 24;
- }
- pSample->nByte = (u8)n;
- pSample->u.z = sqlite3DbMallocRaw(dbMem, n);
- if( pSample->u.z ){
- memcpy(pSample->u.z, z, n);
- }else{
- db->mallocFailed = 1;
- break;
- }
- }
- }
- }
- }
- }
- rc = sqlite3_finalize(pStmt);
- (void)sqlite3SafetyOn(db);
- }
- }
-#endif
-
- if( rc==SQLITE_NOMEM ){
- db->mallocFailed = 1;
- }
- return rc;
-}
-
-
-#endif /* SQLITE_OMIT_ANALYZE */
-
-/************** End of analyze.c *********************************************/
-/************** Begin file attach.c ******************************************/
-/*
-** 2003 April 6
-**
-** 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 code used to implement the ATTACH and DETACH commands.
-**
-** $Id: attach.c,v 1.93 2009/05/31 21:21:41 drh Exp $
-*/
-
-#ifndef SQLITE_OMIT_ATTACH
-/*
-** Resolve an expression that was part of an ATTACH or DETACH statement. This
-** is slightly different from resolving a normal SQL expression, because simple
-** identifiers are treated as strings, not possible column names or aliases.
-**
-** i.e. if the parser sees:
-**
-** ATTACH DATABASE abc AS def
-**
-** it treats the two expressions as literal strings 'abc' and 'def' instead of
-** looking for columns of the same name.
-**
-** This only applies to the root node of pExpr, so the statement:
-**
-** ATTACH DATABASE abc||def AS 'db2'
-**
-** will fail because neither abc or def can be resolved.
-*/
-static int resolveAttachExpr(NameContext *pName, Expr *pExpr)
-{
- int rc = SQLITE_OK;
- if( pExpr ){
- if( pExpr->op!=TK_ID ){
- rc = sqlite3ResolveExprNames(pName, pExpr);
- if( rc==SQLITE_OK && !sqlite3ExprIsConstant(pExpr) ){
- sqlite3ErrorMsg(pName->pParse, "invalid name: \"%s\"", pExpr->u.zToken);
- return SQLITE_ERROR;
- }
- }else{
- pExpr->op = TK_STRING;
- }
- }
- return rc;
-}
-
-/*
-** An SQL user-function registered to do the work of an ATTACH statement. The
-** three arguments to the function come directly from an attach statement:
-**
-** ATTACH DATABASE x AS y KEY z
-**
-** SELECT sqlite_attach(x, y, z)
-**
-** If the optional "KEY z" syntax is omitted, an SQL NULL is passed as the
-** third argument.
-*/
-static void attachFunc(
- sqlite3_context *context,
- int NotUsed,
- sqlite3_value **argv
-){
- int i;
- int rc = 0;
- sqlite3 *db = sqlite3_context_db_handle(context);
- const char *zName;
- const char *zFile;
- Db *aNew;
- char *zErrDyn = 0;
-
- UNUSED_PARAMETER(NotUsed);
-
- zFile = (const char *)sqlite3_value_text(argv[0]);
- zName = (const char *)sqlite3_value_text(argv[1]);
- if( zFile==0 ) zFile = "";
- if( zName==0 ) zName = "";
-
- /* Check for the following errors:
- **
- ** * Too many attached databases,
- ** * Transaction currently open
- ** * Specified database name already being used.
- */
- if( db->nDb>=db->aLimit[SQLITE_LIMIT_ATTACHED]+2 ){
- zErrDyn = sqlite3MPrintf(db, "too many attached databases - max %d",
- db->aLimit[SQLITE_LIMIT_ATTACHED]
- );
- goto attach_error;
- }
- if( !db->autoCommit ){
- zErrDyn = sqlite3MPrintf(db, "cannot ATTACH database within transaction");
- goto attach_error;
- }
- for(i=0; i<db->nDb; i++){
- char *z = db->aDb[i].zName;
- assert( z && zName );
- if( sqlite3StrICmp(z, zName)==0 ){
- zErrDyn = sqlite3MPrintf(db, "database %s is already in use", zName);
- goto attach_error;
- }
- }
-
- /* Allocate the new entry in the db->aDb[] array and initialise the schema
- ** hash tables.
- */
- if( db->aDb==db->aDbStatic ){
- aNew = sqlite3DbMallocRaw(db, sizeof(db->aDb[0])*3 );
- if( aNew==0 ) return;
- memcpy(aNew, db->aDb, sizeof(db->aDb[0])*2);
- }else{
- aNew = sqlite3DbRealloc(db, db->aDb, sizeof(db->aDb[0])*(db->nDb+1) );
- if( aNew==0 ) return;
- }
- db->aDb = aNew;
- aNew = &db->aDb[db->nDb];
- memset(aNew, 0, sizeof(*aNew));
-
- /* Open the database file. If the btree is successfully opened, use
- ** it to obtain the database schema. At this point the schema may
- ** or may not be initialised.
- */
- rc = sqlite3BtreeFactory(db, zFile, 0, SQLITE_DEFAULT_CACHE_SIZE,
- db->openFlags | SQLITE_OPEN_MAIN_DB,
- &aNew->pBt);
- db->nDb++;
- if( rc==SQLITE_CONSTRAINT ){
- rc = SQLITE_ERROR;
- zErrDyn = sqlite3MPrintf(db, "database is already attached");
- }else if( rc==SQLITE_OK ){
- Pager *pPager;
- aNew->pSchema = sqlite3SchemaGet(db, aNew->pBt);
- if( !aNew->pSchema ){
- rc = SQLITE_NOMEM;
- }else if( aNew->pSchema->file_format && aNew->pSchema->enc!=ENC(db) ){
- zErrDyn = sqlite3MPrintf(db,
- "attached databases must use the same text encoding as main database");
- rc = SQLITE_ERROR;
- }
- pPager = sqlite3BtreePager(aNew->pBt);
- sqlite3PagerLockingMode(pPager, db->dfltLockMode);
- sqlite3PagerJournalMode(pPager, db->dfltJournalMode);
- }
- aNew->zName = sqlite3DbStrDup(db, zName);
- aNew->safety_level = 3;
-
-#ifdef SQLITE_HAS_CODEC
- {
- extern int sqlite3CodecAttach(sqlite3*, int, const void*, int);
- extern void sqlite3CodecGetKey(sqlite3*, int, void**, int*);
- int nKey;
- char *zKey;
- int t = sqlite3_value_type(argv[2]);
- switch( t ){
- case SQLITE_INTEGER:
- case SQLITE_FLOAT:
- zErrDyn = sqlite3DbStrDup(db, "Invalid key value");
- rc = SQLITE_ERROR;
- break;
-
- case SQLITE_TEXT:
- case SQLITE_BLOB:
- nKey = sqlite3_value_bytes(argv[2]);
- zKey = (char *)sqlite3_value_blob(argv[2]);
- sqlite3CodecAttach(db, db->nDb-1, zKey, nKey);
- break;
-
- case SQLITE_NULL:
- /* No key specified. Use the key from the main database */
- sqlite3CodecGetKey(db, 0, (void**)&zKey, &nKey);
- sqlite3CodecAttach(db, db->nDb-1, zKey, nKey);
- break;
- }
- }
-#endif
-
- /* If the file was opened successfully, read the schema for the new database.
- ** If this fails, or if opening the file failed, then close the file and
- ** remove the entry from the db->aDb[] array. i.e. put everything back the way
- ** we found it.
- */
- if( rc==SQLITE_OK ){
- (void)sqlite3SafetyOn(db);
- sqlite3BtreeEnterAll(db);
- rc = sqlite3Init(db, &zErrDyn);
- sqlite3BtreeLeaveAll(db);
- (void)sqlite3SafetyOff(db);
- }
- if( rc ){
- int iDb = db->nDb - 1;
- assert( iDb>=2 );
- if( db->aDb[iDb].pBt ){
- sqlite3BtreeClose(db->aDb[iDb].pBt);
- db->aDb[iDb].pBt = 0;
- db->aDb[iDb].pSchema = 0;
- }
- sqlite3ResetInternalSchema(db, 0);
- db->nDb = iDb;
- if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){
- db->mallocFailed = 1;
- sqlite3DbFree(db, zErrDyn);
- zErrDyn = sqlite3MPrintf(db, "out of memory");
- }else if( zErrDyn==0 ){
- zErrDyn = sqlite3MPrintf(db, "unable to open database: %s", zFile);
- }
- goto attach_error;
- }
-
- return;
-
-attach_error:
- /* Return an error if we get here */
- if( zErrDyn ){
- sqlite3_result_error(context, zErrDyn, -1);
- sqlite3DbFree(db, zErrDyn);
- }
- if( rc ) sqlite3_result_error_code(context, rc);
-}
-
-/*
-** An SQL user-function registered to do the work of an DETACH statement. The
-** three arguments to the function come directly from a detach statement:
-**
-** DETACH DATABASE x
-**
-** SELECT sqlite_detach(x)
-*/
-static void detachFunc(
- sqlite3_context *context,
- int NotUsed,
- sqlite3_value **argv
-){
- const char *zName = (const char *)sqlite3_value_text(argv[0]);
- sqlite3 *db = sqlite3_context_db_handle(context);
- int i;
- Db *pDb = 0;
- char zErr[128];
-
- UNUSED_PARAMETER(NotUsed);
-
- if( zName==0 ) zName = "";
- for(i=0; i<db->nDb; i++){
- pDb = &db->aDb[i];
- if( pDb->pBt==0 ) continue;
- if( sqlite3StrICmp(pDb->zName, zName)==0 ) break;
- }
-
- if( i>=db->nDb ){
- sqlite3_snprintf(sizeof(zErr),zErr, "no such database: %s", zName);
- goto detach_error;
- }
- if( i<2 ){
- sqlite3_snprintf(sizeof(zErr),zErr, "cannot detach database %s", zName);
- goto detach_error;
- }
- if( !db->autoCommit ){
- sqlite3_snprintf(sizeof(zErr), zErr,
- "cannot DETACH database within transaction");
- goto detach_error;
- }
- if( sqlite3BtreeIsInReadTrans(pDb->pBt) || sqlite3BtreeIsInBackup(pDb->pBt) ){
- sqlite3_snprintf(sizeof(zErr),zErr, "database %s is locked", zName);
- goto detach_error;
- }
-
- sqlite3BtreeClose(pDb->pBt);
- pDb->pBt = 0;
- pDb->pSchema = 0;
- sqlite3ResetInternalSchema(db, 0);
- return;
-
-detach_error:
- sqlite3_result_error(context, zErr, -1);
-}
-
-/*
-** This procedure generates VDBE code for a single invocation of either the
-** sqlite_detach() or sqlite_attach() SQL user functions.
-*/
-static void codeAttach(
- Parse *pParse, /* The parser context */
- int type, /* Either SQLITE_ATTACH or SQLITE_DETACH */
- FuncDef *pFunc, /* FuncDef wrapper for detachFunc() or attachFunc() */
- Expr *pAuthArg, /* Expression to pass to authorization callback */
- Expr *pFilename, /* Name of database file */
- Expr *pDbname, /* Name of the database to use internally */
- Expr *pKey /* Database key for encryption extension */
-){
- int rc;
- NameContext sName;
- Vdbe *v;
- sqlite3* db = pParse->db;
- int regArgs;
-
- memset(&sName, 0, sizeof(NameContext));
- sName.pParse = pParse;
-
- if(
- SQLITE_OK!=(rc = resolveAttachExpr(&sName, pFilename)) ||
- SQLITE_OK!=(rc = resolveAttachExpr(&sName, pDbname)) ||
- SQLITE_OK!=(rc = resolveAttachExpr(&sName, pKey))
- ){
- pParse->nErr++;
- goto attach_end;
- }
-
-#ifndef SQLITE_OMIT_AUTHORIZATION
- if( pAuthArg ){
- char *zAuthArg = pAuthArg->u.zToken;
- if( NEVER(zAuthArg==0) ){
- goto attach_end;
- }
- rc = sqlite3AuthCheck(pParse, type, zAuthArg, 0, 0);
- if(rc!=SQLITE_OK ){
- goto attach_end;
- }
- }
-#endif /* SQLITE_OMIT_AUTHORIZATION */
-
-
- v = sqlite3GetVdbe(pParse);
- regArgs = sqlite3GetTempRange(pParse, 4);
- sqlite3ExprCode(pParse, pFilename, regArgs);
- sqlite3ExprCode(pParse, pDbname, regArgs+1);
- sqlite3ExprCode(pParse, pKey, regArgs+2);
-
- assert( v || db->mallocFailed );
- if( v ){
- sqlite3VdbeAddOp3(v, OP_Function, 0, regArgs+3-pFunc->nArg, regArgs+3);
- assert( pFunc->nArg==-1 || (pFunc->nArg&0xff)==pFunc->nArg );
- sqlite3VdbeChangeP5(v, (u8)(pFunc->nArg));
- sqlite3VdbeChangeP4(v, -1, (char *)pFunc, P4_FUNCDEF);
-
- /* Code an OP_Expire. For an ATTACH statement, set P1 to true (expire this
- ** statement only). For DETACH, set it to false (expire all existing
- ** statements).
- */
- sqlite3VdbeAddOp1(v, OP_Expire, (type==SQLITE_ATTACH));
- }
-
-attach_end:
- sqlite3ExprDelete(db, pFilename);
- sqlite3ExprDelete(db, pDbname);
- sqlite3ExprDelete(db, pKey);
-}
-
-/*
-** Called by the parser to compile a DETACH statement.
-**
-** DETACH pDbname
-*/
-SQLITE_PRIVATE void sqlite3Detach(Parse *pParse, Expr *pDbname){
- static FuncDef detach_func = {
- 1, /* nArg */
- SQLITE_UTF8, /* iPrefEnc */
- 0, /* flags */
- 0, /* pUserData */
- 0, /* pNext */
- detachFunc, /* xFunc */
- 0, /* xStep */
- 0, /* xFinalize */
- "sqlite_detach", /* zName */
- 0 /* pHash */
- };
- codeAttach(pParse, SQLITE_DETACH, &detach_func, pDbname, 0, 0, pDbname);
-}
-
-/*
-** Called by the parser to compile an ATTACH statement.
-**
-** ATTACH p AS pDbname KEY pKey
-*/
-SQLITE_PRIVATE void sqlite3Attach(Parse *pParse, Expr *p, Expr *pDbname, Expr *pKey){
- static FuncDef attach_func = {
- 3, /* nArg */
- SQLITE_UTF8, /* iPrefEnc */
- 0, /* flags */
- 0, /* pUserData */
- 0, /* pNext */
- attachFunc, /* xFunc */
- 0, /* xStep */
- 0, /* xFinalize */
- "sqlite_attach", /* zName */
- 0 /* pHash */
- };
- codeAttach(pParse, SQLITE_ATTACH, &attach_func, p, p, pDbname, pKey);
-}
-#endif /* SQLITE_OMIT_ATTACH */
-
-/*
-** Initialize a DbFixer structure. This routine must be called prior
-** to passing the structure to one of the sqliteFixAAAA() routines below.
-**
-** The return value indicates whether or not fixation is required. TRUE
-** means we do need to fix the database references, FALSE means we do not.
-*/
-SQLITE_PRIVATE int sqlite3FixInit(
- DbFixer *pFix, /* The fixer to be initialized */
- Parse *pParse, /* Error messages will be written here */
- int iDb, /* This is the database that must be used */
- const char *zType, /* "view", "trigger", or "index" */
- const Token *pName /* Name of the view, trigger, or index */
-){
- sqlite3 *db;
-
- if( NEVER(iDb<0) || iDb==1 ) return 0;
- db = pParse->db;
- assert( db->nDb>iDb );
- pFix->pParse = pParse;
- pFix->zDb = db->aDb[iDb].zName;
- pFix->zType = zType;
- pFix->pName = pName;
- return 1;
-}
-
-/*
-** The following set of routines walk through the parse tree and assign
-** a specific database to all table references where the database name
-** was left unspecified in the original SQL statement. The pFix structure
-** must have been initialized by a prior call to sqlite3FixInit().
-**
-** These routines are used to make sure that an index, trigger, or
-** view in one database does not refer to objects in a different database.
-** (Exception: indices, triggers, and views in the TEMP database are
-** allowed to refer to anything.) If a reference is explicitly made
-** to an object in a different database, an error message is added to
-** pParse->zErrMsg and these routines return non-zero. If everything
-** checks out, these routines return 0.
-*/
-SQLITE_PRIVATE int sqlite3FixSrcList(
- DbFixer *pFix, /* Context of the fixation */
- SrcList *pList /* The Source list to check and modify */
-){
- int i;
- const char *zDb;
- struct SrcList_item *pItem;
-
- if( NEVER(pList==0) ) return 0;
- zDb = pFix->zDb;
- for(i=0, pItem=pList->a; i<pList->nSrc; i++, pItem++){
- if( pItem->zDatabase==0 ){
- pItem->zDatabase = sqlite3DbStrDup(pFix->pParse->db, zDb);
- }else if( sqlite3StrICmp(pItem->zDatabase,zDb)!=0 ){
- sqlite3ErrorMsg(pFix->pParse,
- "%s %T cannot reference objects in database %s",
- pFix->zType, pFix->pName, pItem->zDatabase);
- return 1;
- }
-#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER)
- if( sqlite3FixSelect(pFix, pItem->pSelect) ) return 1;
- if( sqlite3FixExpr(pFix, pItem->pOn) ) return 1;
-#endif
- }
- return 0;
-}
-#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER)
-SQLITE_PRIVATE int sqlite3FixSelect(
- DbFixer *pFix, /* Context of the fixation */
- Select *pSelect /* The SELECT statement to be fixed to one database */
-){
- while( pSelect ){
- if( sqlite3FixExprList(pFix, pSelect->pEList) ){
- return 1;
- }
- if( sqlite3FixSrcList(pFix, pSelect->pSrc) ){
- return 1;
- }
- if( sqlite3FixExpr(pFix, pSelect->pWhere) ){
- return 1;
- }
- if( sqlite3FixExpr(pFix, pSelect->pHaving) ){
- return 1;
- }
- pSelect = pSelect->pPrior;
- }
- return 0;
-}
-SQLITE_PRIVATE int sqlite3FixExpr(
- DbFixer *pFix, /* Context of the fixation */
- Expr *pExpr /* The expression to be fixed to one database */
-){
- while( pExpr ){
- if( ExprHasAnyProperty(pExpr, EP_TokenOnly) ) break;
- if( ExprHasProperty(pExpr, EP_xIsSelect) ){
- if( sqlite3FixSelect(pFix, pExpr->x.pSelect) ) return 1;
- }else{
- if( sqlite3FixExprList(pFix, pExpr->x.pList) ) return 1;
- }
- if( sqlite3FixExpr(pFix, pExpr->pRight) ){
- return 1;
- }
- pExpr = pExpr->pLeft;
- }
- return 0;
-}
-SQLITE_PRIVATE int sqlite3FixExprList(
- DbFixer *pFix, /* Context of the fixation */
- ExprList *pList /* The expression to be fixed to one database */
-){
- int i;
- struct ExprList_item *pItem;
- if( pList==0 ) return 0;
- for(i=0, pItem=pList->a; i<pList->nExpr; i++, pItem++){
- if( sqlite3FixExpr(pFix, pItem->pExpr) ){
- return 1;
- }
- }
- return 0;
-}
-#endif
-
-#ifndef SQLITE_OMIT_TRIGGER
-SQLITE_PRIVATE int sqlite3FixTriggerStep(
- DbFixer *pFix, /* Context of the fixation */
- TriggerStep *pStep /* The trigger step be fixed to one database */
-){
- while( pStep ){
- if( sqlite3FixSelect(pFix, pStep->pSelect) ){
- return 1;
- }
- if( sqlite3FixExpr(pFix, pStep->pWhere) ){
- return 1;
- }
- if( sqlite3FixExprList(pFix, pStep->pExprList) ){
- return 1;
- }
- pStep = pStep->pNext;
- }
- return 0;
-}
-#endif
-
-/************** End of attach.c **********************************************/
-/************** Begin file auth.c ********************************************/
-/*
-** 2003 January 11
-**
-** 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 code used to implement the sqlite3_set_authorizer()
-** API. This facility is an optional feature of the library. Embedded
-** systems that do not need this facility may omit it by recompiling
-** the library with -DSQLITE_OMIT_AUTHORIZATION=1
-**
-** $Id: auth.c,v 1.32 2009/07/02 18:40:35 danielk1977 Exp $
-*/
-
-/*
-** All of the code in this file may be omitted by defining a single
-** macro.
-*/
-#ifndef SQLITE_OMIT_AUTHORIZATION
-
-/*
-** Set or clear the access authorization function.
-**
-** The access authorization function is be called during the compilation
-** phase to verify that the user has read and/or write access permission on
-** various fields of the database. The first argument to the auth function
-** is a copy of the 3rd argument to this routine. The second argument
-** to the auth function is one of these constants:
-**
-** SQLITE_CREATE_INDEX
-** SQLITE_CREATE_TABLE
-** SQLITE_CREATE_TEMP_INDEX
-** SQLITE_CREATE_TEMP_TABLE
-** SQLITE_CREATE_TEMP_TRIGGER
-** SQLITE_CREATE_TEMP_VIEW
-** SQLITE_CREATE_TRIGGER
-** SQLITE_CREATE_VIEW
-** SQLITE_DELETE
-** SQLITE_DROP_INDEX
-** SQLITE_DROP_TABLE
-** SQLITE_DROP_TEMP_INDEX
-** SQLITE_DROP_TEMP_TABLE
-** SQLITE_DROP_TEMP_TRIGGER
-** SQLITE_DROP_TEMP_VIEW
-** SQLITE_DROP_TRIGGER
-** SQLITE_DROP_VIEW
-** SQLITE_INSERT
-** SQLITE_PRAGMA
-** SQLITE_READ
-** SQLITE_SELECT
-** SQLITE_TRANSACTION
-** SQLITE_UPDATE
-**
-** The third and fourth arguments to the auth function are the name of
-** the table and the column that are being accessed. The auth function
-** should return either SQLITE_OK, SQLITE_DENY, or SQLITE_IGNORE. If
-** SQLITE_OK is returned, it means that access is allowed. SQLITE_DENY
-** means that the SQL statement will never-run - the sqlite3_exec() call
-** will return with an error. SQLITE_IGNORE means that the SQL statement
-** should run but attempts to read the specified column will return NULL
-** and attempts to write the column will be ignored.
-**
-** Setting the auth function to NULL disables this hook. The default
-** setting of the auth function is NULL.
-*/
-SQLITE_API int sqlite3_set_authorizer(
- sqlite3 *db,
- int (*xAuth)(void*,int,const char*,const char*,const char*,const char*),
- void *pArg
-){
- sqlite3_mutex_enter(db->mutex);
- db->xAuth = xAuth;
- db->pAuthArg = pArg;
- sqlite3ExpirePreparedStatements(db);
- sqlite3_mutex_leave(db->mutex);
- return SQLITE_OK;
-}
-
-/*
-** Write an error message into pParse->zErrMsg that explains that the
-** user-supplied authorization function returned an illegal value.
-*/
-static void sqliteAuthBadReturnCode(Parse *pParse){
- sqlite3ErrorMsg(pParse, "authorizer malfunction");
- pParse->rc = SQLITE_ERROR;
-}
-
-/*
-** The pExpr should be a TK_COLUMN expression. The table referred to
-** is in pTabList or else it is the NEW or OLD table of a trigger.
-** Check to see if it is OK to read this particular column.
-**
-** If the auth function returns SQLITE_IGNORE, change the TK_COLUMN
-** instruction into a TK_NULL. If the auth function returns SQLITE_DENY,
-** then generate an error.
-*/
-SQLITE_PRIVATE void sqlite3AuthRead(
- Parse *pParse, /* The parser context */
- Expr *pExpr, /* The expression to check authorization on */
- Schema *pSchema, /* The schema of the expression */
- SrcList *pTabList /* All table that pExpr might refer to */
-){
- sqlite3 *db = pParse->db;
- int rc;
- Table *pTab = 0; /* The table being read */
- const char *zCol; /* Name of the column of the table */
- int iSrc; /* Index in pTabList->a[] of table being read */
- const char *zDBase; /* Name of database being accessed */
- int iDb; /* The index of the database the expression refers to */
- int iCol; /* Index of column in table */
-
- if( db->xAuth==0 ) return;
- iDb = sqlite3SchemaToIndex(pParse->db, pSchema);
- if( iDb<0 ){
- /* An attempt to read a column out of a subquery or other
- ** temporary table. */
- return;
- }
-
- assert( pExpr->op==TK_COLUMN || pExpr->op==TK_TRIGGER );
- if( pExpr->op==TK_TRIGGER ){
- pTab = pParse->pTriggerTab;
- }else{
- assert( pTabList );
- for(iSrc=0; ALWAYS(iSrc<pTabList->nSrc); iSrc++){
- if( pExpr->iTable==pTabList->a[iSrc].iCursor ){
- pTab = pTabList->a[iSrc].pTab;
- break;
- }
- }
- }
- iCol = pExpr->iColumn;
- if( NEVER(pTab==0) ) return;
-
- if( iCol>=0 ){
- assert( iCol<pTab->nCol );
- zCol = pTab->aCol[iCol].zName;
- }else if( pTab->iPKey>=0 ){
- assert( pTab->iPKey<pTab->nCol );
- zCol = pTab->aCol[pTab->iPKey].zName;
- }else{
- zCol = "ROWID";
- }
- assert( iDb>=0 && iDb<db->nDb );
- zDBase = db->aDb[iDb].zName;
- rc = db->xAuth(db->pAuthArg, SQLITE_READ, pTab->zName, zCol, zDBase,
- pParse->zAuthContext);
- if( rc==SQLITE_IGNORE ){
- pExpr->op = TK_NULL;
- }else if( rc==SQLITE_DENY ){
- if( db->nDb>2 || iDb!=0 ){
- sqlite3ErrorMsg(pParse, "access to %s.%s.%s is prohibited",
- zDBase, pTab->zName, zCol);
- }else{
- sqlite3ErrorMsg(pParse, "access to %s.%s is prohibited",pTab->zName,zCol);
- }
- pParse->rc = SQLITE_AUTH;
- }else if( rc!=SQLITE_OK ){
- sqliteAuthBadReturnCode(pParse);
- }
-}
-
-/*
-** Do an authorization check using the code and arguments given. Return
-** either SQLITE_OK (zero) or SQLITE_IGNORE or SQLITE_DENY. If SQLITE_DENY
-** is returned, then the error count and error message in pParse are
-** modified appropriately.
-*/
-SQLITE_PRIVATE int sqlite3AuthCheck(
- Parse *pParse,
- int code,
- const char *zArg1,
- const char *zArg2,
- const char *zArg3
-){
- sqlite3 *db = pParse->db;
- int rc;
-
- /* Don't do any authorization checks if the database is initialising
- ** or if the parser is being invoked from within sqlite3_declare_vtab.
- */
- if( db->init.busy || IN_DECLARE_VTAB ){
- return SQLITE_OK;
- }
-
- if( db->xAuth==0 ){
- return SQLITE_OK;
- }
- rc = db->xAuth(db->pAuthArg, code, zArg1, zArg2, zArg3, pParse->zAuthContext);
- if( rc==SQLITE_DENY ){
- sqlite3ErrorMsg(pParse, "not authorized");
- pParse->rc = SQLITE_AUTH;
- }else if( rc!=SQLITE_OK && rc!=SQLITE_IGNORE ){
- rc = SQLITE_DENY;
- sqliteAuthBadReturnCode(pParse);
- }
- return rc;
-}
-
-/*
-** Push an authorization context. After this routine is called, the
-** zArg3 argument to authorization callbacks will be zContext until
-** popped. Or if pParse==0, this routine is a no-op.
-*/
-SQLITE_PRIVATE void sqlite3AuthContextPush(
- Parse *pParse,
- AuthContext *pContext,
- const char *zContext
-){
- assert( pParse );
- pContext->pParse = pParse;
- pContext->zAuthContext = pParse->zAuthContext;
- pParse->zAuthContext = zContext;
-}
-
-/*
-** Pop an authorization context that was previously pushed
-** by sqlite3AuthContextPush
-*/
-SQLITE_PRIVATE void sqlite3AuthContextPop(AuthContext *pContext){
- if( pContext->pParse ){
- pContext->pParse->zAuthContext = pContext->zAuthContext;
- pContext->pParse = 0;
- }
-}
-
-#endif /* SQLITE_OMIT_AUTHORIZATION */
-
-/************** End of auth.c ************************************************/
-/************** Begin file build.c *******************************************/
-/*
-** 2001 September 15
-**
-** 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 C code routines that are called by the SQLite parser
-** when syntax rules are reduced. The routines in this file handle the
-** following kinds of SQL syntax:
-**
-** CREATE TABLE
-** DROP TABLE
-** CREATE INDEX
-** DROP INDEX
-** creating ID lists
-** BEGIN TRANSACTION
-** COMMIT
-** ROLLBACK
-**
-** $Id: build.c,v 1.557 2009/07/24 17:58:53 danielk1977 Exp $
-*/
-
-/*
-** This routine is called when a new SQL statement is beginning to
-** be parsed. Initialize the pParse structure as needed.
-*/
-SQLITE_PRIVATE void sqlite3BeginParse(Parse *pParse, int explainFlag){
- pParse->explain = (u8)explainFlag;
- pParse->nVar = 0;
-}
-
-#ifndef SQLITE_OMIT_SHARED_CACHE
-/*
-** The TableLock structure is only used by the sqlite3TableLock() and
-** codeTableLocks() functions.
-*/
-struct TableLock {
- int iDb; /* The database containing the table to be locked */
- int iTab; /* The root page of the table to be locked */
- u8 isWriteLock; /* True for write lock. False for a read lock */
- const char *zName; /* Name of the table */
-};
-
-/*
-** Record the fact that we want to lock a table at run-time.
-**
-** The table to be locked has root page iTab and is found in database iDb.
-** A read or a write lock can be taken depending on isWritelock.
-**
-** This routine just records the fact that the lock is desired. The
-** code to make the lock occur is generated by a later call to
-** codeTableLocks() which occurs during sqlite3FinishCoding().
-*/
-SQLITE_PRIVATE void sqlite3TableLock(
- Parse *pParse, /* Parsing context */
- int iDb, /* Index of the database containing the table to lock */
- int iTab, /* Root page number of the table to be locked */
- u8 isWriteLock, /* True for a write lock */
- const char *zName /* Name of the table to be locked */
-){
- Parse *pToplevel = sqlite3ParseToplevel(pParse);
- int i;
- int nBytes;
- TableLock *p;
- assert( iDb>=0 );
-
- for(i=0; i<pToplevel->nTableLock; i++){
- p = &pToplevel->aTableLock[i];
- if( p->iDb==iDb && p->iTab==iTab ){
- p->isWriteLock = (p->isWriteLock || isWriteLock);
- return;
- }
- }
-
- nBytes = sizeof(TableLock) * (pToplevel->nTableLock+1);
- pToplevel->aTableLock =
- sqlite3DbReallocOrFree(pToplevel->db, pToplevel->aTableLock, nBytes);
- if( pToplevel->aTableLock ){
- p = &pToplevel->aTableLock[pToplevel->nTableLock++];
- p->iDb = iDb;
- p->iTab = iTab;
- p->isWriteLock = isWriteLock;
- p->zName = zName;
- }else{
- pToplevel->nTableLock = 0;
- pToplevel->db->mallocFailed = 1;
- }
-}
-
-/*
-** Code an OP_TableLock instruction for each table locked by the
-** statement (configured by calls to sqlite3TableLock()).
-*/
-static void codeTableLocks(Parse *pParse){
- int i;
- Vdbe *pVdbe;
-
- pVdbe = sqlite3GetVdbe(pParse);
- assert( pVdbe!=0 ); /* sqlite3GetVdbe cannot fail: VDBE already allocated */
-
- for(i=0; i<pParse->nTableLock; i++){
- TableLock *p = &pParse->aTableLock[i];
- int p1 = p->iDb;
- sqlite3VdbeAddOp4(pVdbe, OP_TableLock, p1, p->iTab, p->isWriteLock,
- p->zName, P4_STATIC);
- }
-}
-#else
- #define codeTableLocks(x)
-#endif
-
-/*
-** This routine is called after a single SQL statement has been
-** parsed and a VDBE program to execute that statement has been
-** prepared. This routine puts the finishing touches on the
-** VDBE program and resets the pParse structure for the next
-** parse.
-**
-** Note that if an error occurred, it might be the case that
-** no VDBE code was generated.
-*/
-SQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){
- sqlite3 *db;
- Vdbe *v;
-
- db = pParse->db;
- if( db->mallocFailed ) return;
- if( pParse->nested ) return;
- if( pParse->nErr ) return;
-
- /* Begin by generating some termination code at the end of the
- ** vdbe program
- */
- v = sqlite3GetVdbe(pParse);
- assert( !pParse->isMultiWrite
- || sqlite3VdbeAssertMayAbort(v, pParse->mayAbort));
- if( v ){
- sqlite3VdbeAddOp0(v, OP_Halt);
-
- /* The cookie mask contains one bit for each database file open.
- ** (Bit 0 is for main, bit 1 is for temp, and so forth.) Bits are
- ** set for each database that is used. Generate code to start a
- ** transaction on each used database and to verify the schema cookie
- ** on each used database.
- */
- if( pParse->cookieGoto>0 ){
- u32 mask;
- int iDb;
- sqlite3VdbeJumpHere(v, pParse->cookieGoto-1);
- for(iDb=0, mask=1; iDb<db->nDb; mask<<=1, iDb++){
- if( (mask & pParse->cookieMask)==0 ) continue;
- sqlite3VdbeUsesBtree(v, iDb);
- sqlite3VdbeAddOp2(v,OP_Transaction, iDb, (mask & pParse->writeMask)!=0);
- if( db->init.busy==0 ){
- sqlite3VdbeAddOp2(v,OP_VerifyCookie, iDb, pParse->cookieValue[iDb]);
- }
- }
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- {
- int i;
- for(i=0; i<pParse->nVtabLock; i++){
- char *vtab = (char *)sqlite3GetVTable(db, pParse->apVtabLock[i]);
- sqlite3VdbeAddOp4(v, OP_VBegin, 0, 0, 0, vtab, P4_VTAB);
- }
- pParse->nVtabLock = 0;
- }
-#endif
-
- /* Once all the cookies have been verified and transactions opened,
- ** obtain the required table-locks. This is a no-op unless the
- ** shared-cache feature is enabled.
- */
- codeTableLocks(pParse);
-
- /* Initialize any AUTOINCREMENT data structures required.
- */
- sqlite3AutoincrementBegin(pParse);
-
- /* Finally, jump back to the beginning of the executable code. */
- sqlite3VdbeAddOp2(v, OP_Goto, 0, pParse->cookieGoto);
- }
- }
-
-
- /* Get the VDBE program ready for execution
- */
- if( v && ALWAYS(pParse->nErr==0) && !db->mallocFailed ){
-#ifdef SQLITE_DEBUG
- FILE *trace = (db->flags & SQLITE_VdbeTrace)!=0 ? stdout : 0;
- sqlite3VdbeTrace(v, trace);
-#endif
- assert( pParse->iCacheLevel==0 ); /* Disables and re-enables match */
- sqlite3VdbeMakeReady(v, pParse->nVar, pParse->nMem,
- pParse->nTab, pParse->nMaxArg, pParse->explain,
- pParse->isMultiWrite && pParse->mayAbort);
- pParse->rc = SQLITE_DONE;
- pParse->colNamesSet = 0;
- }else if( pParse->rc==SQLITE_OK ){
- pParse->rc = SQLITE_ERROR;
- }
- pParse->nTab = 0;
- pParse->nMem = 0;
- pParse->nSet = 0;
- pParse->nVar = 0;
- pParse->cookieMask = 0;
- pParse->cookieGoto = 0;
-}
-
-/*
-** Run the parser and code generator recursively in order to generate
-** code for the SQL statement given onto the end of the pParse context
-** currently under construction. When the parser is run recursively
-** this way, the final OP_Halt is not appended and other initialization
-** and finalization steps are omitted because those are handling by the
-** outermost parser.
-**
-** Not everything is nestable. This facility is designed to permit
-** INSERT, UPDATE, and DELETE operations against SQLITE_MASTER. Use
-** care if you decide to try to use this routine for some other purposes.
-*/
-SQLITE_PRIVATE void sqlite3NestedParse(Parse *pParse, const char *zFormat, ...){
- va_list ap;
- char *zSql;
- char *zErrMsg = 0;
- sqlite3 *db = pParse->db;
-# define SAVE_SZ (sizeof(Parse) - offsetof(Parse,nVar))
- char saveBuf[SAVE_SZ];
-
- if( pParse->nErr ) return;
- assert( pParse->nested<10 ); /* Nesting should only be of limited depth */
- va_start(ap, zFormat);
- zSql = sqlite3VMPrintf(db, zFormat, ap);
- va_end(ap);
- if( zSql==0 ){
- return; /* A malloc must have failed */
- }
- pParse->nested++;
- memcpy(saveBuf, &pParse->nVar, SAVE_SZ);
- memset(&pParse->nVar, 0, SAVE_SZ);
- sqlite3RunParser(pParse, zSql, &zErrMsg);
- sqlite3DbFree(db, zErrMsg);
- sqlite3DbFree(db, zSql);
- memcpy(&pParse->nVar, saveBuf, SAVE_SZ);
- pParse->nested--;
-}
-
-/*
-** Locate the in-memory structure that describes a particular database
-** table given the name of that table and (optionally) the name of the
-** database containing the table. Return NULL if not found.
-**
-** If zDatabase is 0, all databases are searched for the table and the
-** first matching table is returned. (No checking for duplicate table
-** names is done.) The search order is TEMP first, then MAIN, then any
-** auxiliary databases added using the ATTACH command.
-**
-** See also sqlite3LocateTable().
-*/
-SQLITE_PRIVATE Table *sqlite3FindTable(sqlite3 *db, const char *zName, const char *zDatabase){
- Table *p = 0;
- int i;
- int nName;
- assert( zName!=0 );
- nName = sqlite3Strlen30(zName);
- for(i=OMIT_TEMPDB; i<db->nDb; i++){
- int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */
- if( zDatabase!=0 && sqlite3StrICmp(zDatabase, db->aDb[j].zName) ) continue;
- p = sqlite3HashFind(&db->aDb[j].pSchema->tblHash, zName, nName);
- if( p ) break;
- }
- return p;
-}
-
-/*
-** Locate the in-memory structure that describes a particular database
-** table given the name of that table and (optionally) the name of the
-** database containing the table. Return NULL if not found. Also leave an
-** error message in pParse->zErrMsg.
-**
-** The difference between this routine and sqlite3FindTable() is that this
-** routine leaves an error message in pParse->zErrMsg where
-** sqlite3FindTable() does not.
-*/
-SQLITE_PRIVATE Table *sqlite3LocateTable(
- Parse *pParse, /* context in which to report errors */
- int isView, /* True if looking for a VIEW rather than a TABLE */
- const char *zName, /* Name of the table we are looking for */
- const char *zDbase /* Name of the database. Might be NULL */
-){
- Table *p;
-
- /* Read the database schema. If an error occurs, leave an error message
- ** and code in pParse and return NULL. */
- if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
- return 0;
- }
-
- p = sqlite3FindTable(pParse->db, zName, zDbase);
- if( p==0 ){
- const char *zMsg = isView ? "no such view" : "no such table";
- if( zDbase ){
- sqlite3ErrorMsg(pParse, "%s: %s.%s", zMsg, zDbase, zName);
- }else{
- sqlite3ErrorMsg(pParse, "%s: %s", zMsg, zName);
- }
- pParse->checkSchema = 1;
- }
- return p;
-}
-
-/*
-** Locate the in-memory structure that describes
-** a particular index given the name of that index
-** and the name of the database that contains the index.
-** Return NULL if not found.
-**
-** If zDatabase is 0, all databases are searched for the
-** table and the first matching index is returned. (No checking
-** for duplicate index names is done.) The search order is
-** TEMP first, then MAIN, then any auxiliary databases added
-** using the ATTACH command.
-*/
-SQLITE_PRIVATE Index *sqlite3FindIndex(sqlite3 *db, const char *zName, const char *zDb){
- Index *p = 0;
- int i;
- int nName = sqlite3Strlen30(zName);
- for(i=OMIT_TEMPDB; i<db->nDb; i++){
- int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */
- Schema *pSchema = db->aDb[j].pSchema;
- assert( pSchema );
- if( zDb && sqlite3StrICmp(zDb, db->aDb[j].zName) ) continue;
- p = sqlite3HashFind(&pSchema->idxHash, zName, nName);
- if( p ) break;
- }
- return p;
-}
-
-/*
-** Reclaim the memory used by an index
-*/
-static void freeIndex(Index *p){
- sqlite3 *db = p->pTable->dbMem;
-#ifndef SQLITE_OMIT_ANALYZE
- sqlite3DeleteIndexSamples(p);
-#endif
- sqlite3DbFree(db, p->zColAff);
- sqlite3DbFree(db, p);
-}
-
-/*
-** Remove the given index from the index hash table, and free
-** its memory structures.
-**
-** The index is removed from the database hash tables but
-** it is not unlinked from the Table that it indexes.
-** Unlinking from the Table must be done by the calling function.
-*/
-static void sqlite3DeleteIndex(Index *p){
- Index *pOld;
- const char *zName = p->zName;
-
- pOld = sqlite3HashInsert(&p->pSchema->idxHash, zName,
- sqlite3Strlen30(zName), 0);
- assert( pOld==0 || pOld==p );
- freeIndex(p);
-}
-
-/*
-** For the index called zIdxName which is found in the database iDb,
-** unlike that index from its Table then remove the index from
-** the index hash table and free all memory structures associated
-** with the index.
-*/
-SQLITE_PRIVATE void sqlite3UnlinkAndDeleteIndex(sqlite3 *db, int iDb, const char *zIdxName){
- Index *pIndex;
- int len;
- Hash *pHash = &db->aDb[iDb].pSchema->idxHash;
-
- len = sqlite3Strlen30(zIdxName);
- pIndex = sqlite3HashInsert(pHash, zIdxName, len, 0);
- if( pIndex ){
- if( pIndex->pTable->pIndex==pIndex ){
- pIndex->pTable->pIndex = pIndex->pNext;
- }else{
- Index *p;
- /* Justification of ALWAYS(); The index must be on the list of
- ** indices. */
- p = pIndex->pTable->pIndex;
- while( ALWAYS(p) && p->pNext!=pIndex ){ p = p->pNext; }
- if( ALWAYS(p && p->pNext==pIndex) ){
- p->pNext = pIndex->pNext;
- }
- }
- freeIndex(pIndex);
- }
- db->flags |= SQLITE_InternChanges;
-}
-
-/*
-** Erase all schema information from the in-memory hash tables of
-** a single database. This routine is called to reclaim memory
-** before the database closes. It is also called during a rollback
-** if there were schema changes during the transaction or if a
-** schema-cookie mismatch occurs.
-**
-** If iDb==0 then reset the internal schema tables for all database
-** files. If iDb>=1 then reset the internal schema for only the
-** single file indicated.
-*/
-SQLITE_PRIVATE void sqlite3ResetInternalSchema(sqlite3 *db, int iDb){
- int i, j;
- assert( iDb>=0 && iDb<db->nDb );
-
- if( iDb==0 ){
- sqlite3BtreeEnterAll(db);
- }
- for(i=iDb; i<db->nDb; i++){
- Db *pDb = &db->aDb[i];
- if( pDb->pSchema ){
- assert(i==1 || (pDb->pBt && sqlite3BtreeHoldsMutex(pDb->pBt)));
- sqlite3SchemaFree(pDb->pSchema);
- }
- if( iDb>0 ) return;
- }
- assert( iDb==0 );
- db->flags &= ~SQLITE_InternChanges;
- sqlite3VtabUnlockList(db);
- sqlite3BtreeLeaveAll(db);
-
- /* If one or more of the auxiliary database files has been closed,
- ** then remove them from the auxiliary database list. We take the
- ** opportunity to do this here since we have just deleted all of the
- ** schema hash tables and therefore do not have to make any changes
- ** to any of those tables.
- */
- for(i=j=2; i<db->nDb; i++){
- struct Db *pDb = &db->aDb[i];
- if( pDb->pBt==0 ){
- sqlite3DbFree(db, pDb->zName);
- pDb->zName = 0;
- continue;
- }
- if( j<i ){
- db->aDb[j] = db->aDb[i];
- }
- j++;
- }
- memset(&db->aDb[j], 0, (db->nDb-j)*sizeof(db->aDb[j]));
- db->nDb = j;
- if( db->nDb<=2 && db->aDb!=db->aDbStatic ){
- memcpy(db->aDbStatic, db->aDb, 2*sizeof(db->aDb[0]));
- sqlite3DbFree(db, db->aDb);
- db->aDb = db->aDbStatic;
- }
-}
-
-/*
-** This routine is called when a commit occurs.
-*/
-SQLITE_PRIVATE void sqlite3CommitInternalChanges(sqlite3 *db){
- db->flags &= ~SQLITE_InternChanges;
-}
-
-/*
-** Clear the column names from a table or view.
-*/
-static void sqliteResetColumnNames(Table *pTable){
- int i;
- Column *pCol;
- sqlite3 *db = pTable->dbMem;
- testcase( db==0 );
- assert( pTable!=0 );
- if( (pCol = pTable->aCol)!=0 ){
- for(i=0; i<pTable->nCol; i++, pCol++){
- sqlite3DbFree(db, pCol->zName);
- sqlite3ExprDelete(db, pCol->pDflt);
- sqlite3DbFree(db, pCol->zDflt);
- sqlite3DbFree(db, pCol->zType);
- sqlite3DbFree(db, pCol->zColl);
- }
- sqlite3DbFree(db, pTable->aCol);
- }
- pTable->aCol = 0;
- pTable->nCol = 0;
-}
-
-/*
-** Remove the memory data structures associated with the given
-** Table. No changes are made to disk by this routine.
-**
-** This routine just deletes the data structure. It does not unlink
-** the table data structure from the hash table. But it does destroy
-** memory structures of the indices and foreign keys associated with
-** the table.
-*/
-SQLITE_PRIVATE void sqlite3DeleteTable(Table *pTable){
- Index *pIndex, *pNext;
- FKey *pFKey, *pNextFKey;
- sqlite3 *db;
-
- if( pTable==0 ) return;
- db = pTable->dbMem;
- testcase( db==0 );
-
- /* Do not delete the table until the reference count reaches zero. */
- pTable->nRef--;
- if( pTable->nRef>0 ){
- return;
- }
- assert( pTable->nRef==0 );
-
- /* Delete all indices associated with this table
- */
- for(pIndex = pTable->pIndex; pIndex; pIndex=pNext){
- pNext = pIndex->pNext;
- assert( pIndex->pSchema==pTable->pSchema );
- sqlite3DeleteIndex(pIndex);
- }
-
-#ifndef SQLITE_OMIT_FOREIGN_KEY
- /* Delete all foreign keys associated with this table. */
- for(pFKey=pTable->pFKey; pFKey; pFKey=pNextFKey){
- pNextFKey = pFKey->pNextFrom;
- sqlite3DbFree(db, pFKey);
- }
-#endif
-
- /* Delete the Table structure itself.
- */
- sqliteResetColumnNames(pTable);
- sqlite3DbFree(db, pTable->zName);
- sqlite3DbFree(db, pTable->zColAff);
- sqlite3SelectDelete(db, pTable->pSelect);
-#ifndef SQLITE_OMIT_CHECK
- sqlite3ExprDelete(db, pTable->pCheck);
-#endif
- sqlite3VtabClear(pTable);
- sqlite3DbFree(db, pTable);
-}
-
-/*
-** Unlink the given table from the hash tables and the delete the
-** table structure with all its indices and foreign keys.
-*/
-SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTable(sqlite3 *db, int iDb, const char *zTabName){
- Table *p;
- Db *pDb;
-
- assert( db!=0 );
- assert( iDb>=0 && iDb<db->nDb );
- assert( zTabName && zTabName[0] );
- pDb = &db->aDb[iDb];
- p = sqlite3HashInsert(&pDb->pSchema->tblHash, zTabName,
- sqlite3Strlen30(zTabName),0);
- sqlite3DeleteTable(p);
- db->flags |= SQLITE_InternChanges;
-}
-
-/*
-** Given a token, return a string that consists of the text of that
-** token. Space to hold the returned string
-** is obtained from sqliteMalloc() and must be freed by the calling
-** function.
-**
-** Any quotation marks (ex: "name", 'name', [name], or `name`) that
-** surround the body of the token are removed.
-**
-** Tokens are often just pointers into the original SQL text and so
-** are not \000 terminated and are not persistent. The returned string
-** is \000 terminated and is persistent.
-*/
-SQLITE_PRIVATE char *sqlite3NameFromToken(sqlite3 *db, Token *pName){
- char *zName;
- if( pName ){
- zName = sqlite3DbStrNDup(db, (char*)pName->z, pName->n);
- sqlite3Dequote(zName);
- }else{
- zName = 0;
- }
- return zName;
-}
-
-/*
-** Open the sqlite_master table stored in database number iDb for
-** writing. The table is opened using cursor 0.
-*/
-SQLITE_PRIVATE void sqlite3OpenMasterTable(Parse *p, int iDb){
- Vdbe *v = sqlite3GetVdbe(p);
- sqlite3TableLock(p, iDb, MASTER_ROOT, 1, SCHEMA_TABLE(iDb));
- sqlite3VdbeAddOp3(v, OP_OpenWrite, 0, MASTER_ROOT, iDb);
- sqlite3VdbeChangeP4(v, -1, (char *)5, P4_INT32); /* 5 column table */
- if( p->nTab==0 ){
- p->nTab = 1;
- }
-}
-
-/*
-** Parameter zName points to a nul-terminated buffer containing the name
-** of a database ("main", "temp" or the name of an attached db). This
-** function returns the index of the named database in db->aDb[], or
-** -1 if the named db cannot be found.
-*/
-SQLITE_PRIVATE int sqlite3FindDbName(sqlite3 *db, const char *zName){
- int i = -1; /* Database number */
- if( zName ){
- Db *pDb;
- int n = sqlite3Strlen30(zName);
- for(i=(db->nDb-1), pDb=&db->aDb[i]; i>=0; i--, pDb--){
- if( (!OMIT_TEMPDB || i!=1 ) && n==sqlite3Strlen30(pDb->zName) &&
- 0==sqlite3StrICmp(pDb->zName, zName) ){
- break;
- }
- }
- }
- return i;
-}
-
-/*
-** The token *pName contains the name of a database (either "main" or
-** "temp" or the name of an attached db). This routine returns the
-** index of the named database in db->aDb[], or -1 if the named db
-** does not exist.
-*/
-SQLITE_PRIVATE int sqlite3FindDb(sqlite3 *db, Token *pName){
- int i; /* Database number */
- char *zName; /* Name we are searching for */
- zName = sqlite3NameFromToken(db, pName);
- i = sqlite3FindDbName(db, zName);
- sqlite3DbFree(db, zName);
- return i;
-}
-
-/* The table or view or trigger name is passed to this routine via tokens
-** pName1 and pName2. If the table name was fully qualified, for example:
-**
-** CREATE TABLE xxx.yyy (...);
-**
-** Then pName1 is set to "xxx" and pName2 "yyy". On the other hand if
-** the table name is not fully qualified, i.e.:
-**
-** CREATE TABLE yyy(...);
-**
-** Then pName1 is set to "yyy" and pName2 is "".
-**
-** This routine sets the *ppUnqual pointer to point at the token (pName1 or
-** pName2) that stores the unqualified table name. The index of the
-** database "xxx" is returned.
-*/
-SQLITE_PRIVATE int sqlite3TwoPartName(
- Parse *pParse, /* Parsing and code generating context */
- Token *pName1, /* The "xxx" in the name "xxx.yyy" or "xxx" */
- Token *pName2, /* The "yyy" in the name "xxx.yyy" */
- Token **pUnqual /* Write the unqualified object name here */
-){
- int iDb; /* Database holding the object */
- sqlite3 *db = pParse->db;
-
- if( ALWAYS(pName2!=0) && pName2->n>0 ){
- if( db->init.busy ) {
- sqlite3ErrorMsg(pParse, "corrupt database");
- pParse->nErr++;
- return -1;
- }
- *pUnqual = pName2;
- iDb = sqlite3FindDb(db, pName1);
- if( iDb<0 ){
- sqlite3ErrorMsg(pParse, "unknown database %T", pName1);
- pParse->nErr++;
- return -1;
- }
- }else{
- assert( db->init.iDb==0 || db->init.busy );
- iDb = db->init.iDb;
- *pUnqual = pName1;
- }
- return iDb;
-}
-
-/*
-** This routine is used to check if the UTF-8 string zName is a legal
-** unqualified name for a new schema object (table, index, view or
-** trigger). All names are legal except those that begin with the string
-** "sqlite_" (in upper, lower or mixed case). This portion of the namespace
-** is reserved for internal use.
-*/
-SQLITE_PRIVATE int sqlite3CheckObjectName(Parse *pParse, const char *zName){
- if( !pParse->db->init.busy && pParse->nested==0
- && (pParse->db->flags & SQLITE_WriteSchema)==0
- && 0==sqlite3StrNICmp(zName, "sqlite_", 7) ){
- sqlite3ErrorMsg(pParse, "object name reserved for internal use: %s", zName);
- return SQLITE_ERROR;
- }
- return SQLITE_OK;
-}
-
-/*
-** Begin constructing a new table representation in memory. This is
-** the first of several action routines that get called in response
-** to a CREATE TABLE statement. In particular, this routine is called
-** after seeing tokens "CREATE" and "TABLE" and the table name. The isTemp
-** flag is true if the table should be stored in the auxiliary database
-** file instead of in the main database file. This is normally the case
-** when the "TEMP" or "TEMPORARY" keyword occurs in between
-** CREATE and TABLE.
-**
-** The new table record is initialized and put in pParse->pNewTable.
-** As more of the CREATE TABLE statement is parsed, additional action
-** routines will be called to add more information to this record.
-** At the end of the CREATE TABLE statement, the sqlite3EndTable() routine
-** is called to complete the construction of the new table record.
-*/
-SQLITE_PRIVATE void sqlite3StartTable(
- Parse *pParse, /* Parser context */
- Token *pName1, /* First part of the name of the table or view */
- Token *pName2, /* Second part of the name of the table or view */
- int isTemp, /* True if this is a TEMP table */
- int isView, /* True if this is a VIEW */
- int isVirtual, /* True if this is a VIRTUAL table */
- int noErr /* Do nothing if table already exists */
-){
- Table *pTable;
- char *zName = 0; /* The name of the new table */
- sqlite3 *db = pParse->db;
- Vdbe *v;
- int iDb; /* Database number to create the table in */
- Token *pName; /* Unqualified name of the table to create */
-
- /* The table or view name to create is passed to this routine via tokens
- ** pName1 and pName2. If the table name was fully qualified, for example:
- **
- ** CREATE TABLE xxx.yyy (...);
- **
- ** Then pName1 is set to "xxx" and pName2 "yyy". On the other hand if
- ** the table name is not fully qualified, i.e.:
- **
- ** CREATE TABLE yyy(...);
- **
- ** Then pName1 is set to "yyy" and pName2 is "".
- **
- ** The call below sets the pName pointer to point at the token (pName1 or
- ** pName2) that stores the unqualified table name. The variable iDb is
- ** set to the index of the database that the table or view is to be
- ** created in.
- */
- iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pName);
- if( iDb<0 ) return;
- if( !OMIT_TEMPDB && isTemp && iDb>1 ){
- /* If creating a temp table, the name may not be qualified */
- sqlite3ErrorMsg(pParse, "temporary table name must be unqualified");
- return;
- }
- if( !OMIT_TEMPDB && isTemp ) iDb = 1;
-
- pParse->sNameToken = *pName;
- zName = sqlite3NameFromToken(db, pName);
- if( zName==0 ) return;
- if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){
- goto begin_table_error;
- }
- if( db->init.iDb==1 ) isTemp = 1;
-#ifndef SQLITE_OMIT_AUTHORIZATION
- assert( (isTemp & 1)==isTemp );
- {
- int code;
- char *zDb = db->aDb[iDb].zName;
- if( sqlite3AuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(isTemp), 0, zDb) ){
- goto begin_table_error;
- }
- if( isView ){
- if( !OMIT_TEMPDB && isTemp ){
- code = SQLITE_CREATE_TEMP_VIEW;
- }else{
- code = SQLITE_CREATE_VIEW;
- }
- }else{
- if( !OMIT_TEMPDB && isTemp ){
- code = SQLITE_CREATE_TEMP_TABLE;
- }else{
- code = SQLITE_CREATE_TABLE;
- }
- }
- if( !isVirtual && sqlite3AuthCheck(pParse, code, zName, 0, zDb) ){
- goto begin_table_error;
- }
- }
-#endif
-
- /* Make sure the new table name does not collide with an existing
- ** index or table name in the same database. Issue an error message if
- ** it does. The exception is if the statement being parsed was passed
- ** to an sqlite3_declare_vtab() call. In that case only the column names
- ** and types will be used, so there is no need to test for namespace
- ** collisions.
- */
- if( !IN_DECLARE_VTAB ){
- if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
- goto begin_table_error;
- }
- pTable = sqlite3FindTable(db, zName, db->aDb[iDb].zName);
- if( pTable ){
- if( !noErr ){
- sqlite3ErrorMsg(pParse, "table %T already exists", pName);
- }
- goto begin_table_error;
- }
- if( sqlite3FindIndex(db, zName, 0)!=0 && (iDb==0 || !db->init.busy) ){
- sqlite3ErrorMsg(pParse, "there is already an index named %s", zName);
- goto begin_table_error;
- }
- }
-
- pTable = sqlite3DbMallocZero(db, sizeof(Table));
- if( pTable==0 ){
- db->mallocFailed = 1;
- pParse->rc = SQLITE_NOMEM;
- pParse->nErr++;
- goto begin_table_error;
- }
- pTable->zName = zName;
- pTable->iPKey = -1;
- pTable->pSchema = db->aDb[iDb].pSchema;
- pTable->nRef = 1;
- pTable->dbMem = 0;
- assert( pParse->pNewTable==0 );
- pParse->pNewTable = pTable;
-
- /* If this is the magic sqlite_sequence table used by autoincrement,
- ** then record a pointer to this table in the main database structure
- ** so that INSERT can find the table easily.
- */
-#ifndef SQLITE_OMIT_AUTOINCREMENT
- if( !pParse->nested && strcmp(zName, "sqlite_sequence")==0 ){
- pTable->pSchema->pSeqTab = pTable;
- }
-#endif
-
- /* Begin generating the code that will insert the table record into
- ** the SQLITE_MASTER table. Note in particular that we must go ahead
- ** and allocate the record number for the table entry now. Before any
- ** PRIMARY KEY or UNIQUE keywords are parsed. Those keywords will cause
- ** indices to be created and the table record must come before the
- ** indices. Hence, the record number for the table must be allocated
- ** now.
- */
- if( !db->init.busy && (v = sqlite3GetVdbe(pParse))!=0 ){
- int j1;
- int fileFormat;
- int reg1, reg2, reg3;
- sqlite3BeginWriteOperation(pParse, 0, iDb);
-
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- if( isVirtual ){
- sqlite3VdbeAddOp0(v, OP_VBegin);
- }
-#endif
-
- /* If the file format and encoding in the database have not been set,
- ** set them now.
- */
- reg1 = pParse->regRowid = ++pParse->nMem;
- reg2 = pParse->regRoot = ++pParse->nMem;
- reg3 = ++pParse->nMem;
- sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, reg3, BTREE_FILE_FORMAT);
- sqlite3VdbeUsesBtree(v, iDb);
- j1 = sqlite3VdbeAddOp1(v, OP_If, reg3);
- fileFormat = (db->flags & SQLITE_LegacyFileFmt)!=0 ?
- 1 : SQLITE_MAX_FILE_FORMAT;
- sqlite3VdbeAddOp2(v, OP_Integer, fileFormat, reg3);
- sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, reg3);
- sqlite3VdbeAddOp2(v, OP_Integer, ENC(db), reg3);
- sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_TEXT_ENCODING, reg3);
- sqlite3VdbeJumpHere(v, j1);
-
- /* This just creates a place-holder record in the sqlite_master table.
- ** The record created does not contain anything yet. It will be replaced
- ** by the real entry in code generated at sqlite3EndTable().
- **
- ** The rowid for the new entry is left in register pParse->regRowid.
- ** The root page number of the new table is left in reg pParse->regRoot.
- ** The rowid and root page number values are needed by the code that
- ** sqlite3EndTable will generate.
- */
-#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE)
- if( isView || isVirtual ){
- sqlite3VdbeAddOp2(v, OP_Integer, 0, reg2);
- }else
-#endif
- {
- sqlite3VdbeAddOp2(v, OP_CreateTable, iDb, reg2);
- }
- sqlite3OpenMasterTable(pParse, iDb);
- sqlite3VdbeAddOp2(v, OP_NewRowid, 0, reg1);
- sqlite3VdbeAddOp2(v, OP_Null, 0, reg3);
- sqlite3VdbeAddOp3(v, OP_Insert, 0, reg3, reg1);
- sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
- sqlite3VdbeAddOp0(v, OP_Close);
- }
-
- /* Normal (non-error) return. */
- return;
-
- /* If an error occurs, we jump here */
-begin_table_error:
- sqlite3DbFree(db, zName);
- return;
-}
-
-/*
-** This macro is used to compare two strings in a case-insensitive manner.
-** It is slightly faster than calling sqlite3StrICmp() directly, but
-** produces larger code.
-**
-** WARNING: This macro is not compatible with the strcmp() family. It
-** returns true if the two strings are equal, otherwise false.
-*/
-#define STRICMP(x, y) (\
-sqlite3UpperToLower[*(unsigned char *)(x)]== \
-sqlite3UpperToLower[*(unsigned char *)(y)] \
-&& sqlite3StrICmp((x)+1,(y)+1)==0 )
-
-/*
-** Add a new column to the table currently being constructed.
-**
-** The parser calls this routine once for each column declaration
-** in a CREATE TABLE statement. sqlite3StartTable() gets called
-** first to get things going. Then this routine is called for each
-** column.
-*/
-SQLITE_PRIVATE void sqlite3AddColumn(Parse *pParse, Token *pName){
- Table *p;
- int i;
- char *z;
- Column *pCol;
- sqlite3 *db = pParse->db;
- if( (p = pParse->pNewTable)==0 ) return;
-#if SQLITE_MAX_COLUMN
- if( p->nCol+1>db->aLimit[SQLITE_LIMIT_COLUMN] ){
- sqlite3ErrorMsg(pParse, "too many columns on %s", p->zName);
- return;
- }
-#endif
- z = sqlite3NameFromToken(db, pName);
- if( z==0 ) return;
- for(i=0; i<p->nCol; i++){
- if( STRICMP(z, p->aCol[i].zName) ){
- sqlite3ErrorMsg(pParse, "duplicate column name: %s", z);
- sqlite3DbFree(db, z);
- return;
- }
- }
- if( (p->nCol & 0x7)==0 ){
- Column *aNew;
- aNew = sqlite3DbRealloc(db,p->aCol,(p->nCol+8)*sizeof(p->aCol[0]));
- if( aNew==0 ){
- sqlite3DbFree(db, z);
- return;
- }
- p->aCol = aNew;
- }
- pCol = &p->aCol[p->nCol];
- memset(pCol, 0, sizeof(p->aCol[0]));
- pCol->zName = z;
-
- /* If there is no type specified, columns have the default affinity
- ** 'NONE'. If there is a type specified, then sqlite3AddColumnType() will
- ** be called next to set pCol->affinity correctly.
- */
- pCol->affinity = SQLITE_AFF_NONE;
- p->nCol++;
-}
-
-/*
-** This routine is called by the parser while in the middle of
-** parsing a CREATE TABLE statement. A "NOT NULL" constraint has
-** been seen on a column. This routine sets the notNull flag on
-** the column currently under construction.
-*/
-SQLITE_PRIVATE void sqlite3AddNotNull(Parse *pParse, int onError){
- Table *p;
- p = pParse->pNewTable;
- if( p==0 || NEVER(p->nCol<1) ) return;
- p->aCol[p->nCol-1].notNull = (u8)onError;
-}
-
-/*
-** Scan the column type name zType (length nType) and return the
-** associated affinity type.
-**
-** This routine does a case-independent search of zType for the
-** substrings in the following table. If one of the substrings is
-** found, the corresponding affinity is returned. If zType contains
-** more than one of the substrings, entries toward the top of
-** the table take priority. For example, if zType is 'BLOBINT',
-** SQLITE_AFF_INTEGER is returned.
-**
-** Substring | Affinity
-** --------------------------------
-** 'INT' | SQLITE_AFF_INTEGER
-** 'CHAR' | SQLITE_AFF_TEXT
-** 'CLOB' | SQLITE_AFF_TEXT
-** 'TEXT' | SQLITE_AFF_TEXT
-** 'BLOB' | SQLITE_AFF_NONE
-** 'REAL' | SQLITE_AFF_REAL
-** 'FLOA' | SQLITE_AFF_REAL
-** 'DOUB' | SQLITE_AFF_REAL
-**
-** If none of the substrings in the above table are found,
-** SQLITE_AFF_NUMERIC is returned.
-*/
-SQLITE_PRIVATE char sqlite3AffinityType(const char *zIn){
- u32 h = 0;
- char aff = SQLITE_AFF_NUMERIC;
-
- if( zIn ) while( zIn[0] ){
- h = (h<<8) + sqlite3UpperToLower[(*zIn)&0xff];
- zIn++;
- if( h==(('c'<<24)+('h'<<16)+('a'<<8)+'r') ){ /* CHAR */
- aff = SQLITE_AFF_TEXT;
- }else if( h==(('c'<<24)+('l'<<16)+('o'<<8)+'b') ){ /* CLOB */
- aff = SQLITE_AFF_TEXT;
- }else if( h==(('t'<<24)+('e'<<16)+('x'<<8)+'t') ){ /* TEXT */
- aff = SQLITE_AFF_TEXT;
- }else if( h==(('b'<<24)+('l'<<16)+('o'<<8)+'b') /* BLOB */
- && (aff==SQLITE_AFF_NUMERIC || aff==SQLITE_AFF_REAL) ){
- aff = SQLITE_AFF_NONE;
-#ifndef SQLITE_OMIT_FLOATING_POINT
- }else if( h==(('r'<<24)+('e'<<16)+('a'<<8)+'l') /* REAL */
- && aff==SQLITE_AFF_NUMERIC ){
- aff = SQLITE_AFF_REAL;
- }else if( h==(('f'<<24)+('l'<<16)+('o'<<8)+'a') /* FLOA */
- && aff==SQLITE_AFF_NUMERIC ){
- aff = SQLITE_AFF_REAL;
- }else if( h==(('d'<<24)+('o'<<16)+('u'<<8)+'b') /* DOUB */
- && aff==SQLITE_AFF_NUMERIC ){
- aff = SQLITE_AFF_REAL;
-#endif
- }else if( (h&0x00FFFFFF)==(('i'<<16)+('n'<<8)+'t') ){ /* INT */
- aff = SQLITE_AFF_INTEGER;
- break;
- }
- }
-
- return aff;
-}
-
-/*
-** This routine is called by the parser while in the middle of
-** parsing a CREATE TABLE statement. The pFirst token is the first
-** token in the sequence of tokens that describe the type of the
-** column currently under construction. pLast is the last token
-** in the sequence. Use this information to construct a string
-** that contains the typename of the column and store that string
-** in zType.
-*/
-SQLITE_PRIVATE void sqlite3AddColumnType(Parse *pParse, Token *pType){
- Table *p;
- Column *pCol;
-
- p = pParse->pNewTable;
- if( p==0 || NEVER(p->nCol<1) ) return;
- pCol = &p->aCol[p->nCol-1];
- assert( pCol->zType==0 );
- pCol->zType = sqlite3NameFromToken(pParse->db, pType);
- pCol->affinity = sqlite3AffinityType(pCol->zType);
-}
-
-/*
-** The expression is the default value for the most recently added column
-** of the table currently under construction.
-**
-** Default value expressions must be constant. Raise an exception if this
-** is not the case.
-**
-** This routine is called by the parser while in the middle of
-** parsing a CREATE TABLE statement.
-*/
-SQLITE_PRIVATE void sqlite3AddDefaultValue(Parse *pParse, ExprSpan *pSpan){
- Table *p;
- Column *pCol;
- sqlite3 *db = pParse->db;
- p = pParse->pNewTable;
- if( p!=0 ){
- pCol = &(p->aCol[p->nCol-1]);
- if( !sqlite3ExprIsConstantOrFunction(pSpan->pExpr) ){
- sqlite3ErrorMsg(pParse, "default value of column [%s] is not constant",
- pCol->zName);
- }else{
- /* A copy of pExpr is used instead of the original, as pExpr contains
- ** tokens that point to volatile memory. The 'span' of the expression
- ** is required by pragma table_info.
- */
- sqlite3ExprDelete(db, pCol->pDflt);
- pCol->pDflt = sqlite3ExprDup(db, pSpan->pExpr, EXPRDUP_REDUCE);
- sqlite3DbFree(db, pCol->zDflt);
- pCol->zDflt = sqlite3DbStrNDup(db, (char*)pSpan->zStart,
- (int)(pSpan->zEnd - pSpan->zStart));
- }
- }
- sqlite3ExprDelete(db, pSpan->pExpr);
-}
-
-/*
-** Designate the PRIMARY KEY for the table. pList is a list of names
-** of columns that form the primary key. If pList is NULL, then the
-** most recently added column of the table is the primary key.
-**
-** A table can have at most one primary key. If the table already has
-** a primary key (and this is the second primary key) then create an
-** error.
-**
-** If the PRIMARY KEY is on a single column whose datatype is INTEGER,
-** then we will try to use that column as the rowid. Set the Table.iPKey
-** field of the table under construction to be the index of the
-** INTEGER PRIMARY KEY column. Table.iPKey is set to -1 if there is
-** no INTEGER PRIMARY KEY.
-**
-** If the key is not an INTEGER PRIMARY KEY, then create a unique
-** index for the key. No index is created for INTEGER PRIMARY KEYs.
-*/
-SQLITE_PRIVATE void sqlite3AddPrimaryKey(
- Parse *pParse, /* Parsing context */
- ExprList *pList, /* List of field names to be indexed */
- int onError, /* What to do with a uniqueness conflict */
- int autoInc, /* True if the AUTOINCREMENT keyword is present */
- int sortOrder /* SQLITE_SO_ASC or SQLITE_SO_DESC */
-){
- Table *pTab = pParse->pNewTable;
- char *zType = 0;
- int iCol = -1, i;
- if( pTab==0 || IN_DECLARE_VTAB ) goto primary_key_exit;
- if( pTab->tabFlags & TF_HasPrimaryKey ){
- sqlite3ErrorMsg(pParse,
- "table \"%s\" has more than one primary key", pTab->zName);
- goto primary_key_exit;
- }
- pTab->tabFlags |= TF_HasPrimaryKey;
- if( pList==0 ){
- iCol = pTab->nCol - 1;
- pTab->aCol[iCol].isPrimKey = 1;
- }else{
- for(i=0; i<pList->nExpr; i++){
- for(iCol=0; iCol<pTab->nCol; iCol++){
- if( sqlite3StrICmp(pList->a[i].zName, pTab->aCol[iCol].zName)==0 ){
- break;
- }
- }
- if( iCol<pTab->nCol ){
- pTab->aCol[iCol].isPrimKey = 1;
- }
- }
- if( pList->nExpr>1 ) iCol = -1;
- }
- if( iCol>=0 && iCol<pTab->nCol ){
- zType = pTab->aCol[iCol].zType;
- }
- if( zType && sqlite3StrICmp(zType, "INTEGER")==0
- && sortOrder==SQLITE_SO_ASC ){
- pTab->iPKey = iCol;
- pTab->keyConf = (u8)onError;
- assert( autoInc==0 || autoInc==1 );
- pTab->tabFlags |= autoInc*TF_Autoincrement;
- }else if( autoInc ){
-#ifndef SQLITE_OMIT_AUTOINCREMENT
- sqlite3ErrorMsg(pParse, "AUTOINCREMENT is only allowed on an "
- "INTEGER PRIMARY KEY");
-#endif
- }else{
- sqlite3CreateIndex(pParse, 0, 0, 0, pList, onError, 0, 0, sortOrder, 0);
- pList = 0;
- }
-
-primary_key_exit:
- sqlite3ExprListDelete(pParse->db, pList);
- return;
-}
-
-/*
-** Add a new CHECK constraint to the table currently under construction.
-*/
-SQLITE_PRIVATE void sqlite3AddCheckConstraint(
- Parse *pParse, /* Parsing context */
- Expr *pCheckExpr /* The check expression */
-){
- sqlite3 *db = pParse->db;
-#ifndef SQLITE_OMIT_CHECK
- Table *pTab = pParse->pNewTable;
- if( pTab && !IN_DECLARE_VTAB ){
- pTab->pCheck = sqlite3ExprAnd(db, pTab->pCheck, pCheckExpr);
- }else
-#endif
- {
- sqlite3ExprDelete(db, pCheckExpr);
- }
-}
-
-/*
-** Set the collation function of the most recently parsed table column
-** to the CollSeq given.
-*/
-SQLITE_PRIVATE void sqlite3AddCollateType(Parse *pParse, Token *pToken){
- Table *p;
- int i;
- char *zColl; /* Dequoted name of collation sequence */
- sqlite3 *db;
-
- if( (p = pParse->pNewTable)==0 ) return;
- i = p->nCol-1;
- db = pParse->db;
- zColl = sqlite3NameFromToken(db, pToken);
- if( !zColl ) return;
-
- if( sqlite3LocateCollSeq(pParse, zColl) ){
- Index *pIdx;
- p->aCol[i].zColl = zColl;
-
- /* If the column is declared as "<name> PRIMARY KEY COLLATE <type>",
- ** then an index may have been created on this column before the
- ** collation type was added. Correct this if it is the case.
- */
- for(pIdx=p->pIndex; pIdx; pIdx=pIdx->pNext){
- assert( pIdx->nColumn==1 );
- if( pIdx->aiColumn[0]==i ){
- pIdx->azColl[0] = p->aCol[i].zColl;
- }
- }
- }else{
- sqlite3DbFree(db, zColl);
- }
-}
-
-/*
-** This function returns the collation sequence for database native text
-** encoding identified by the string zName, length nName.
-**
-** If the requested collation sequence is not available, or not available
-** in the database native encoding, the collation factory is invoked to
-** request it. If the collation factory does not supply such a sequence,
-** and the sequence is available in another text encoding, then that is
-** returned instead.
-**
-** If no versions of the requested collations sequence are available, or
-** another error occurs, NULL is returned and an error message written into
-** pParse.
-**
-** This routine is a wrapper around sqlite3FindCollSeq(). This routine
-** invokes the collation factory if the named collation cannot be found
-** and generates an error message.
-**
-** See also: sqlite3FindCollSeq(), sqlite3GetCollSeq()
-*/
-SQLITE_PRIVATE CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char *zName){
- sqlite3 *db = pParse->db;
- u8 enc = ENC(db);
- u8 initbusy = db->init.busy;
- CollSeq *pColl;
-
- pColl = sqlite3FindCollSeq(db, enc, zName, initbusy);
- if( !initbusy && (!pColl || !pColl->xCmp) ){
- pColl = sqlite3GetCollSeq(db, enc, pColl, zName);
- if( !pColl ){
- sqlite3ErrorMsg(pParse, "no such collation sequence: %s", zName);
- }
- }
-
- return pColl;
-}
-
-
-/*
-** Generate code that will increment the schema cookie.
-**
-** The schema cookie is used to determine when the schema for the
-** database changes. After each schema change, the cookie value
-** changes. When a process first reads the schema it records the
-** cookie. Thereafter, whenever it goes to access the database,
-** it checks the cookie to make sure the schema has not changed
-** since it was last read.
-**
-** This plan is not completely bullet-proof. It is possible for
-** the schema to change multiple times and for the cookie to be
-** set back to prior value. But schema changes are infrequent
-** and the probability of hitting the same cookie value is only
-** 1 chance in 2^32. So we're safe enough.
-*/
-SQLITE_PRIVATE void sqlite3ChangeCookie(Parse *pParse, int iDb){
- int r1 = sqlite3GetTempReg(pParse);
- sqlite3 *db = pParse->db;
- Vdbe *v = pParse->pVdbe;
- sqlite3VdbeAddOp2(v, OP_Integer, db->aDb[iDb].pSchema->schema_cookie+1, r1);
- sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_SCHEMA_VERSION, r1);
- sqlite3ReleaseTempReg(pParse, r1);
-}
-
-/*
-** Measure the number of characters needed to output the given
-** identifier. The number returned includes any quotes used
-** but does not include the null terminator.
-**
-** The estimate is conservative. It might be larger that what is
-** really needed.
-*/
-static int identLength(const char *z){
- int n;
- for(n=0; *z; n++, z++){
- if( *z=='"' ){ n++; }
- }
- return n + 2;
-}
-
-/*
-** The first parameter is a pointer to an output buffer. The second
-** parameter is a pointer to an integer that contains the offset at
-** which to write into the output buffer. This function copies the
-** nul-terminated string pointed to by the third parameter, zSignedIdent,
-** to the specified offset in the buffer and updates *pIdx to refer
-** to the first byte after the last byte written before returning.
-**
-** If the string zSignedIdent consists entirely of alpha-numeric
-** characters, does not begin with a digit and is not an SQL keyword,
-** then it is copied to the output buffer exactly as it is. Otherwise,
-** it is quoted using double-quotes.
-*/
-static void identPut(char *z, int *pIdx, char *zSignedIdent){
- unsigned char *zIdent = (unsigned char*)zSignedIdent;
- int i, j, needQuote;
- i = *pIdx;
-
- for(j=0; zIdent[j]; j++){
- if( !sqlite3Isalnum(zIdent[j]) && zIdent[j]!='_' ) break;
- }
- needQuote = sqlite3Isdigit(zIdent[0]) || sqlite3KeywordCode(zIdent, j)!=TK_ID;
- if( !needQuote ){
- needQuote = zIdent[j];
- }
-
- if( needQuote ) z[i++] = '"';
- for(j=0; zIdent[j]; j++){
- z[i++] = zIdent[j];
- if( zIdent[j]=='"' ) z[i++] = '"';
- }
- if( needQuote ) z[i++] = '"';
- z[i] = 0;
- *pIdx = i;
-}
-
-/*
-** Generate a CREATE TABLE statement appropriate for the given
-** table. Memory to hold the text of the statement is obtained
-** from sqliteMalloc() and must be freed by the calling function.
-*/
-static char *createTableStmt(sqlite3 *db, Table *p){
- int i, k, n;
- char *zStmt;
- char *zSep, *zSep2, *zEnd;
- Column *pCol;
- n = 0;
- for(pCol = p->aCol, i=0; i<p->nCol; i++, pCol++){
- n += identLength(pCol->zName) + 5;
- }
- n += identLength(p->zName);
- if( n<50 ){
- zSep = "";
- zSep2 = ",";
- zEnd = ")";
- }else{
- zSep = "\n ";
- zSep2 = ",\n ";
- zEnd = "\n)";
- }
- n += 35 + 6*p->nCol;
- zStmt = sqlite3Malloc( n );
- if( zStmt==0 ){
- db->mallocFailed = 1;
- return 0;
- }
- sqlite3_snprintf(n, zStmt, "CREATE TABLE ");
- k = sqlite3Strlen30(zStmt);
- identPut(zStmt, &k, p->zName);
- zStmt[k++] = '(';
- for(pCol=p->aCol, i=0; i<p->nCol; i++, pCol++){
- static const char * const azType[] = {
- /* SQLITE_AFF_TEXT */ " TEXT",
- /* SQLITE_AFF_NONE */ "",
- /* SQLITE_AFF_NUMERIC */ " NUM",
- /* SQLITE_AFF_INTEGER */ " INT",
- /* SQLITE_AFF_REAL */ " REAL"
- };
- int len;
- const char *zType;
-
- sqlite3_snprintf(n-k, &zStmt[k], zSep);
- k += sqlite3Strlen30(&zStmt[k]);
- zSep = zSep2;
- identPut(zStmt, &k, pCol->zName);
- assert( pCol->affinity-SQLITE_AFF_TEXT >= 0 );
- assert( pCol->affinity-SQLITE_AFF_TEXT < sizeof(azType)/sizeof(azType[0]) );
- testcase( pCol->affinity==SQLITE_AFF_TEXT );
- testcase( pCol->affinity==SQLITE_AFF_NONE );
- testcase( pCol->affinity==SQLITE_AFF_NUMERIC );
- testcase( pCol->affinity==SQLITE_AFF_INTEGER );
- testcase( pCol->affinity==SQLITE_AFF_REAL );
-
- zType = azType[pCol->affinity - SQLITE_AFF_TEXT];
- len = sqlite3Strlen30(zType);
- assert( pCol->affinity==SQLITE_AFF_NONE
- || pCol->affinity==sqlite3AffinityType(zType) );
- memcpy(&zStmt[k], zType, len);
- k += len;
- assert( k<=n );
- }
- sqlite3_snprintf(n-k, &zStmt[k], "%s", zEnd);
- return zStmt;
-}
-
-/*
-** This routine is called to report the final ")" that terminates
-** a CREATE TABLE statement.
-**
-** The table structure that other action routines have been building
-** is added to the internal hash tables, assuming no errors have
-** occurred.
-**
-** An entry for the table is made in the master table on disk, unless
-** this is a temporary table or db->init.busy==1. When db->init.busy==1
-** it means we are reading the sqlite_master table because we just
-** connected to the database or because the sqlite_master table has
-** recently changed, so the entry for this table already exists in
-** the sqlite_master table. We do not want to create it again.
-**
-** If the pSelect argument is not NULL, it means that this routine
-** was called to create a table generated from a
-** "CREATE TABLE ... AS SELECT ..." statement. The column names of
-** the new table will match the result set of the SELECT.
-*/
-SQLITE_PRIVATE void sqlite3EndTable(
- Parse *pParse, /* Parse context */
- Token *pCons, /* The ',' token after the last column defn. */
- Token *pEnd, /* The final ')' token in the CREATE TABLE */
- Select *pSelect /* Select from a "CREATE ... AS SELECT" */
-){
- Table *p;
- sqlite3 *db = pParse->db;
- int iDb;
-
- if( (pEnd==0 && pSelect==0) || db->mallocFailed ){
- return;
- }
- p = pParse->pNewTable;
- if( p==0 ) return;
-
- assert( !db->init.busy || !pSelect );
-
- iDb = sqlite3SchemaToIndex(db, p->pSchema);
-
-#ifndef SQLITE_OMIT_CHECK
- /* Resolve names in all CHECK constraint expressions.
- */
- if( p->pCheck ){
- SrcList sSrc; /* Fake SrcList for pParse->pNewTable */
- NameContext sNC; /* Name context for pParse->pNewTable */
-
- memset(&sNC, 0, sizeof(sNC));
- memset(&sSrc, 0, sizeof(sSrc));
- sSrc.nSrc = 1;
- sSrc.a[0].zName = p->zName;
- sSrc.a[0].pTab = p;
- sSrc.a[0].iCursor = -1;
- sNC.pParse = pParse;
- sNC.pSrcList = &sSrc;
- sNC.isCheck = 1;
- if( sqlite3ResolveExprNames(&sNC, p->pCheck) ){
- return;
- }
- }
-#endif /* !defined(SQLITE_OMIT_CHECK) */
-
- /* If the db->init.busy is 1 it means we are reading the SQL off the
- ** "sqlite_master" or "sqlite_temp_master" table on the disk.
- ** So do not write to the disk again. Extract the root page number
- ** for the table from the db->init.newTnum field. (The page number
- ** should have been put there by the sqliteOpenCb routine.)
- */
- if( db->init.busy ){
- p->tnum = db->init.newTnum;
- }
-
- /* If not initializing, then create a record for the new table
- ** in the SQLITE_MASTER table of the database.
- **
- ** If this is a TEMPORARY table, write the entry into the auxiliary
- ** file instead of into the main database file.
- */
- if( !db->init.busy ){
- int n;
- Vdbe *v;
- char *zType; /* "view" or "table" */
- char *zType2; /* "VIEW" or "TABLE" */
- char *zStmt; /* Text of the CREATE TABLE or CREATE VIEW statement */
-
- v = sqlite3GetVdbe(pParse);
- if( NEVER(v==0) ) return;
-
- sqlite3VdbeAddOp1(v, OP_Close, 0);
-
- /*
- ** Initialize zType for the new view or table.
- */
- if( p->pSelect==0 ){
- /* A regular table */
- zType = "table";
- zType2 = "TABLE";
-#ifndef SQLITE_OMIT_VIEW
- }else{
- /* A view */
- zType = "view";
- zType2 = "VIEW";
-#endif
- }
-
- /* If this is a CREATE TABLE xx AS SELECT ..., execute the SELECT
- ** statement to populate the new table. The root-page number for the
- ** new table is in register pParse->regRoot.
- **
- ** Once the SELECT has been coded by sqlite3Select(), it is in a
- ** suitable state to query for the column names and types to be used
- ** by the new table.
- **
- ** A shared-cache write-lock is not required to write to the new table,
- ** as a schema-lock must have already been obtained to create it. Since
- ** a schema-lock excludes all other database users, the write-lock would
- ** be redundant.
- */
- if( pSelect ){
- SelectDest dest;
- Table *pSelTab;
-
- assert(pParse->nTab==1);
- sqlite3VdbeAddOp3(v, OP_OpenWrite, 1, pParse->regRoot, iDb);
- sqlite3VdbeChangeP5(v, 1);
- pParse->nTab = 2;
- sqlite3SelectDestInit(&dest, SRT_Table, 1);
- sqlite3Select(pParse, pSelect, &dest);
- sqlite3VdbeAddOp1(v, OP_Close, 1);
- if( pParse->nErr==0 ){
- pSelTab = sqlite3ResultSetOfSelect(pParse, pSelect);
- if( pSelTab==0 ) return;
- assert( p->aCol==0 );
- p->nCol = pSelTab->nCol;
- p->aCol = pSelTab->aCol;
- pSelTab->nCol = 0;
- pSelTab->aCol = 0;
- sqlite3DeleteTable(pSelTab);
- }
- }
-
- /* Compute the complete text of the CREATE statement */
- if( pSelect ){
- zStmt = createTableStmt(db, p);
- }else{
- n = (int)(pEnd->z - pParse->sNameToken.z) + 1;
- zStmt = sqlite3MPrintf(db,
- "CREATE %s %.*s", zType2, n, pParse->sNameToken.z
- );
- }
-
- /* A slot for the record has already been allocated in the
- ** SQLITE_MASTER table. We just need to update that slot with all
- ** the information we've collected.
- */
- sqlite3NestedParse(pParse,
- "UPDATE %Q.%s "
- "SET type='%s', name=%Q, tbl_name=%Q, rootpage=#%d, sql=%Q "
- "WHERE rowid=#%d",
- db->aDb[iDb].zName, SCHEMA_TABLE(iDb),
- zType,
- p->zName,
- p->zName,
- pParse->regRoot,
- zStmt,
- pParse->regRowid
- );
- sqlite3DbFree(db, zStmt);
- sqlite3ChangeCookie(pParse, iDb);
-
-#ifndef SQLITE_OMIT_AUTOINCREMENT
- /* Check to see if we need to create an sqlite_sequence table for
- ** keeping track of autoincrement keys.
- */
- if( p->tabFlags & TF_Autoincrement ){
- Db *pDb = &db->aDb[iDb];
- if( pDb->pSchema->pSeqTab==0 ){
- sqlite3NestedParse(pParse,
- "CREATE TABLE %Q.sqlite_sequence(name,seq)",
- pDb->zName
- );
- }
- }
-#endif
-
- /* Reparse everything to update our internal data structures */
- sqlite3VdbeAddOp4(v, OP_ParseSchema, iDb, 0, 0,
- sqlite3MPrintf(db, "tbl_name='%q'",p->zName), P4_DYNAMIC);
- }
-
-
- /* Add the table to the in-memory representation of the database.
- */
- if( db->init.busy ){
- Table *pOld;
- Schema *pSchema = p->pSchema;
- pOld = sqlite3HashInsert(&pSchema->tblHash, p->zName,
- sqlite3Strlen30(p->zName),p);
- if( pOld ){
- assert( p==pOld ); /* Malloc must have failed inside HashInsert() */
- db->mallocFailed = 1;
- return;
- }
- pParse->pNewTable = 0;
- db->nTable++;
- db->flags |= SQLITE_InternChanges;
-
-#ifndef SQLITE_OMIT_ALTERTABLE
- if( !p->pSelect ){
- const char *zName = (const char *)pParse->sNameToken.z;
- int nName;
- assert( !pSelect && pCons && pEnd );
- if( pCons->z==0 ){
- pCons = pEnd;
- }
- nName = (int)((const char *)pCons->z - zName);
- p->addColOffset = 13 + sqlite3Utf8CharLen(zName, nName);
- }
-#endif
- }
-}
-
-#ifndef SQLITE_OMIT_VIEW
-/*
-** The parser calls this routine in order to create a new VIEW
-*/
-SQLITE_PRIVATE void sqlite3CreateView(
- Parse *pParse, /* The parsing context */
- Token *pBegin, /* The CREATE token that begins the statement */
- Token *pName1, /* The token that holds the name of the view */
- Token *pName2, /* The token that holds the name of the view */
- Select *pSelect, /* A SELECT statement that will become the new view */
- int isTemp, /* TRUE for a TEMPORARY view */
- int noErr /* Suppress error messages if VIEW already exists */
-){
- Table *p;
- int n;
- const char *z;
- Token sEnd;
- DbFixer sFix;
- Token *pName;
- int iDb;
- sqlite3 *db = pParse->db;
-
- if( pParse->nVar>0 ){
- sqlite3ErrorMsg(pParse, "parameters are not allowed in views");
- sqlite3SelectDelete(db, pSelect);
- return;
- }
- sqlite3StartTable(pParse, pName1, pName2, isTemp, 1, 0, noErr);
- p = pParse->pNewTable;
- if( p==0 ){
- sqlite3SelectDelete(db, pSelect);
- return;
- }
- assert( pParse->nErr==0 ); /* If sqlite3StartTable return non-NULL then
- ** there could not have been an error */
- sqlite3TwoPartName(pParse, pName1, pName2, &pName);
- iDb = sqlite3SchemaToIndex(db, p->pSchema);
- if( sqlite3FixInit(&sFix, pParse, iDb, "view", pName)
- && sqlite3FixSelect(&sFix, pSelect)
- ){
- sqlite3SelectDelete(db, pSelect);
- return;
- }
-
- /* Make a copy of the entire SELECT statement that defines the view.
- ** This will force all the Expr.token.z values to be dynamically
- ** allocated rather than point to the input string - which means that
- ** they will persist after the current sqlite3_exec() call returns.
- */
- p->pSelect = sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE);
- sqlite3SelectDelete(db, pSelect);
- if( db->mallocFailed ){
- return;
- }
- if( !db->init.busy ){
- sqlite3ViewGetColumnNames(pParse, p);
- }
-
- /* Locate the end of the CREATE VIEW statement. Make sEnd point to
- ** the end.
- */
- sEnd = pParse->sLastToken;
- if( ALWAYS(sEnd.z[0]!=0) && sEnd.z[0]!=';' ){
- sEnd.z += sEnd.n;
- }
- sEnd.n = 0;
- n = (int)(sEnd.z - pBegin->z);
- z = pBegin->z;
- while( ALWAYS(n>0) && sqlite3Isspace(z[n-1]) ){ n--; }
- sEnd.z = &z[n-1];
- sEnd.n = 1;
-
- /* Use sqlite3EndTable() to add the view to the SQLITE_MASTER table */
- sqlite3EndTable(pParse, 0, &sEnd, 0);
- return;
-}
-#endif /* SQLITE_OMIT_VIEW */
-
-#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE)
-/*
-** The Table structure pTable is really a VIEW. Fill in the names of
-** the columns of the view in the pTable structure. Return the number
-** of errors. If an error is seen leave an error message in pParse->zErrMsg.
-*/
-SQLITE_PRIVATE int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){
- Table *pSelTab; /* A fake table from which we get the result set */
- Select *pSel; /* Copy of the SELECT that implements the view */
- int nErr = 0; /* Number of errors encountered */
- int n; /* Temporarily holds the number of cursors assigned */
- sqlite3 *db = pParse->db; /* Database connection for malloc errors */
- int (*xAuth)(void*,int,const char*,const char*,const char*,const char*);
-
- assert( pTable );
-
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- if( sqlite3VtabCallConnect(pParse, pTable) ){
- return SQLITE_ERROR;
- }
- if( IsVirtual(pTable) ) return 0;
-#endif
-
-#ifndef SQLITE_OMIT_VIEW
- /* A positive nCol means the columns names for this view are
- ** already known.
- */
- if( pTable->nCol>0 ) return 0;
-
- /* A negative nCol is a special marker meaning that we are currently
- ** trying to compute the column names. If we enter this routine with
- ** a negative nCol, it means two or more views form a loop, like this:
- **
- ** CREATE VIEW one AS SELECT * FROM two;
- ** CREATE VIEW two AS SELECT * FROM one;
- **
- ** Actually, the error above is now caught prior to reaching this point.
- ** But the following test is still important as it does come up
- ** in the following:
- **
- ** CREATE TABLE main.ex1(a);
- ** CREATE TEMP VIEW ex1 AS SELECT a FROM ex1;
- ** SELECT * FROM temp.ex1;
- */
- if( pTable->nCol<0 ){
- sqlite3ErrorMsg(pParse, "view %s is circularly defined", pTable->zName);
- return 1;
- }
- assert( pTable->nCol>=0 );
-
- /* If we get this far, it means we need to compute the table names.
- ** Note that the call to sqlite3ResultSetOfSelect() will expand any
- ** "*" elements in the results set of the view and will assign cursors
- ** to the elements of the FROM clause. But we do not want these changes
- ** to be permanent. So the computation is done on a copy of the SELECT
- ** statement that defines the view.
- */
- assert( pTable->pSelect );
- pSel = sqlite3SelectDup(db, pTable->pSelect, 0);
- if( pSel ){
- u8 enableLookaside = db->lookaside.bEnabled;
- n = pParse->nTab;
- sqlite3SrcListAssignCursors(pParse, pSel->pSrc);
- pTable->nCol = -1;
- db->lookaside.bEnabled = 0;
-#ifndef SQLITE_OMIT_AUTHORIZATION
- xAuth = db->xAuth;
- db->xAuth = 0;
- pSelTab = sqlite3ResultSetOfSelect(pParse, pSel);
- db->xAuth = xAuth;
-#else
- pSelTab = sqlite3ResultSetOfSelect(pParse, pSel);
-#endif
- db->lookaside.bEnabled = enableLookaside;
- pParse->nTab = n;
- if( pSelTab ){
- assert( pTable->aCol==0 );
- pTable->nCol = pSelTab->nCol;
- pTable->aCol = pSelTab->aCol;
- pSelTab->nCol = 0;
- pSelTab->aCol = 0;
- sqlite3DeleteTable(pSelTab);
- pTable->pSchema->flags |= DB_UnresetViews;
- }else{
- pTable->nCol = 0;
- nErr++;
- }
- sqlite3SelectDelete(db, pSel);
- } else {
- nErr++;
- }
-#endif /* SQLITE_OMIT_VIEW */
- return nErr;
-}
-#endif /* !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE) */
-
-#ifndef SQLITE_OMIT_VIEW
-/*
-** Clear the column names from every VIEW in database idx.
-*/
-static void sqliteViewResetAll(sqlite3 *db, int idx){
- HashElem *i;
- if( !DbHasProperty(db, idx, DB_UnresetViews) ) return;
- for(i=sqliteHashFirst(&db->aDb[idx].pSchema->tblHash); i;i=sqliteHashNext(i)){
- Table *pTab = sqliteHashData(i);
- if( pTab->pSelect ){
- sqliteResetColumnNames(pTab);
- }
- }
- DbClearProperty(db, idx, DB_UnresetViews);
-}
-#else
-# define sqliteViewResetAll(A,B)
-#endif /* SQLITE_OMIT_VIEW */
-
-/*
-** This function is called by the VDBE to adjust the internal schema
-** used by SQLite when the btree layer moves a table root page. The
-** root-page of a table or index in database iDb has changed from iFrom
-** to iTo.
-**
-** Ticket #1728: The symbol table might still contain information
-** on tables and/or indices that are the process of being deleted.
-** If you are unlucky, one of those deleted indices or tables might
-** have the same rootpage number as the real table or index that is
-** being moved. So we cannot stop searching after the first match
-** because the first match might be for one of the deleted indices
-** or tables and not the table/index that is actually being moved.
-** We must continue looping until all tables and indices with
-** rootpage==iFrom have been converted to have a rootpage of iTo
-** in order to be certain that we got the right one.
-*/
-#ifndef SQLITE_OMIT_AUTOVACUUM
-SQLITE_PRIVATE void sqlite3RootPageMoved(Db *pDb, int iFrom, int iTo){
- HashElem *pElem;
- Hash *pHash;
-
- pHash = &pDb->pSchema->tblHash;
- for(pElem=sqliteHashFirst(pHash); pElem; pElem=sqliteHashNext(pElem)){
- Table *pTab = sqliteHashData(pElem);
- if( pTab->tnum==iFrom ){
- pTab->tnum = iTo;
- }
- }
- pHash = &pDb->pSchema->idxHash;
- for(pElem=sqliteHashFirst(pHash); pElem; pElem=sqliteHashNext(pElem)){
- Index *pIdx = sqliteHashData(pElem);
- if( pIdx->tnum==iFrom ){
- pIdx->tnum = iTo;
- }
- }
-}
-#endif
-
-/*
-** Write code to erase the table with root-page iTable from database iDb.
-** Also write code to modify the sqlite_master table and internal schema
-** if a root-page of another table is moved by the btree-layer whilst
-** erasing iTable (this can happen with an auto-vacuum database).
-*/
-static void destroyRootPage(Parse *pParse, int iTable, int iDb){
- Vdbe *v = sqlite3GetVdbe(pParse);
- int r1 = sqlite3GetTempReg(pParse);
- sqlite3VdbeAddOp3(v, OP_Destroy, iTable, r1, iDb);
- sqlite3MayAbort(pParse);
-#ifndef SQLITE_OMIT_AUTOVACUUM
- /* OP_Destroy stores an in integer r1. If this integer
- ** is non-zero, then it is the root page number of a table moved to
- ** location iTable. The following code modifies the sqlite_master table to
- ** reflect this.
- **
- ** The "#NNN" in the SQL is a special constant that means whatever value
- ** is in register NNN. See grammar rules associated with the TK_REGISTER
- ** token for additional information.
- */
- sqlite3NestedParse(pParse,
- "UPDATE %Q.%s SET rootpage=%d WHERE #%d AND rootpage=#%d",
- pParse->db->aDb[iDb].zName, SCHEMA_TABLE(iDb), iTable, r1, r1);
-#endif
- sqlite3ReleaseTempReg(pParse, r1);
-}
-
-/*
-** Write VDBE code to erase table pTab and all associated indices on disk.
-** Code to update the sqlite_master tables and internal schema definitions
-** in case a root-page belonging to another table is moved by the btree layer
-** is also added (this can happen with an auto-vacuum database).
-*/
-static void destroyTable(Parse *pParse, Table *pTab){
-#ifdef SQLITE_OMIT_AUTOVACUUM
- Index *pIdx;
- int iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
- destroyRootPage(pParse, pTab->tnum, iDb);
- for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
- destroyRootPage(pParse, pIdx->tnum, iDb);
- }
-#else
- /* If the database may be auto-vacuum capable (if SQLITE_OMIT_AUTOVACUUM
- ** is not defined), then it is important to call OP_Destroy on the
- ** table and index root-pages in order, starting with the numerically
- ** largest root-page number. This guarantees that none of the root-pages
- ** to be destroyed is relocated by an earlier OP_Destroy. i.e. if the
- ** following were coded:
- **
- ** OP_Destroy 4 0
- ** ...
- ** OP_Destroy 5 0
- **
- ** and root page 5 happened to be the largest root-page number in the
- ** database, then root page 5 would be moved to page 4 by the
- ** "OP_Destroy 4 0" opcode. The subsequent "OP_Destroy 5 0" would hit
- ** a free-list page.
- */
- int iTab = pTab->tnum;
- int iDestroyed = 0;
-
- while( 1 ){
- Index *pIdx;
- int iLargest = 0;
-
- if( iDestroyed==0 || iTab<iDestroyed ){
- iLargest = iTab;
- }
- for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
- int iIdx = pIdx->tnum;
- assert( pIdx->pSchema==pTab->pSchema );
- if( (iDestroyed==0 || (iIdx<iDestroyed)) && iIdx>iLargest ){
- iLargest = iIdx;
- }
- }
- if( iLargest==0 ){
- return;
- }else{
- int iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
- destroyRootPage(pParse, iLargest, iDb);
- iDestroyed = iLargest;
- }
- }
-#endif
-}
-
-/*
-** This routine is called to do the work of a DROP TABLE statement.
-** pName is the name of the table to be dropped.
-*/
-SQLITE_PRIVATE void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, int noErr){
- Table *pTab;
- Vdbe *v;
- sqlite3 *db = pParse->db;
- int iDb;
-
- if( db->mallocFailed ){
- goto exit_drop_table;
- }
- assert( pParse->nErr==0 );
- assert( pName->nSrc==1 );
- pTab = sqlite3LocateTable(pParse, isView,
- pName->a[0].zName, pName->a[0].zDatabase);
-
- if( pTab==0 ){
- if( noErr ){
- sqlite3ErrorClear(pParse);
- }
- goto exit_drop_table;
- }
- iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
- assert( iDb>=0 && iDb<db->nDb );
-
- /* If pTab is a virtual table, call ViewGetColumnNames() to ensure
- ** it is initialized.
- */
- if( IsVirtual(pTab) && sqlite3ViewGetColumnNames(pParse, pTab) ){
- goto exit_drop_table;
- }
-#ifndef SQLITE_OMIT_AUTHORIZATION
- {
- int code;
- const char *zTab = SCHEMA_TABLE(iDb);
- const char *zDb = db->aDb[iDb].zName;
- const char *zArg2 = 0;
- if( sqlite3AuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb)){
- goto exit_drop_table;
- }
- if( isView ){
- if( !OMIT_TEMPDB && iDb==1 ){
- code = SQLITE_DROP_TEMP_VIEW;
- }else{
- code = SQLITE_DROP_VIEW;
- }
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- }else if( IsVirtual(pTab) ){
- code = SQLITE_DROP_VTABLE;
- zArg2 = sqlite3GetVTable(db, pTab)->pMod->zName;
-#endif
- }else{
- if( !OMIT_TEMPDB && iDb==1 ){
- code = SQLITE_DROP_TEMP_TABLE;
- }else{
- code = SQLITE_DROP_TABLE;
- }
- }
- if( sqlite3AuthCheck(pParse, code, pTab->zName, zArg2, zDb) ){
- goto exit_drop_table;
- }
- if( sqlite3AuthCheck(pParse, SQLITE_DELETE, pTab->zName, 0, zDb) ){
- goto exit_drop_table;
- }
- }
-#endif
- if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0 ){
- sqlite3ErrorMsg(pParse, "table %s may not be dropped", pTab->zName);
- goto exit_drop_table;
- }
-
-#ifndef SQLITE_OMIT_VIEW
- /* Ensure DROP TABLE is not used on a view, and DROP VIEW is not used
- ** on a table.
- */
- if( isView && pTab->pSelect==0 ){
- sqlite3ErrorMsg(pParse, "use DROP TABLE to delete table %s", pTab->zName);
- goto exit_drop_table;
- }
- if( !isView && pTab->pSelect ){
- sqlite3ErrorMsg(pParse, "use DROP VIEW to delete view %s", pTab->zName);
- goto exit_drop_table;
- }
-#endif
-
- /* Generate code to remove the table from the master table
- ** on disk.
- */
- v = sqlite3GetVdbe(pParse);
- if( v ){
- Trigger *pTrigger;
- Db *pDb = &db->aDb[iDb];
- sqlite3BeginWriteOperation(pParse, 1, iDb);
-
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- if( IsVirtual(pTab) ){
- sqlite3VdbeAddOp0(v, OP_VBegin);
- }
-#endif
-
- /* Drop all triggers associated with the table being dropped. Code
- ** is generated to remove entries from sqlite_master and/or
- ** sqlite_temp_master if required.
- */
- pTrigger = sqlite3TriggerList(pParse, pTab);
- while( pTrigger ){
- assert( pTrigger->pSchema==pTab->pSchema ||
- pTrigger->pSchema==db->aDb[1].pSchema );
- sqlite3DropTriggerPtr(pParse, pTrigger);
- pTrigger = pTrigger->pNext;
- }
-
-#ifndef SQLITE_OMIT_AUTOINCREMENT
- /* Remove any entries of the sqlite_sequence table associated with
- ** the table being dropped. This is done before the table is dropped
- ** at the btree level, in case the sqlite_sequence table needs to
- ** move as a result of the drop (can happen in auto-vacuum mode).
- */
- if( pTab->tabFlags & TF_Autoincrement ){
- sqlite3NestedParse(pParse,
- "DELETE FROM %s.sqlite_sequence WHERE name=%Q",
- pDb->zName, pTab->zName
- );
- }
-#endif
-
- /* Drop all SQLITE_MASTER table and index entries that refer to the
- ** table. The program name loops through the master table and deletes
- ** every row that refers to a table of the same name as the one being
- ** dropped. Triggers are handled seperately because a trigger can be
- ** created in the temp database that refers to a table in another
- ** database.
- */
- sqlite3NestedParse(pParse,
- "DELETE FROM %Q.%s WHERE tbl_name=%Q and type!='trigger'",
- pDb->zName, SCHEMA_TABLE(iDb), pTab->zName);
-
- /* Drop any statistics from the sqlite_stat1 table, if it exists */
- if( sqlite3FindTable(db, "sqlite_stat1", db->aDb[iDb].zName) ){
- sqlite3NestedParse(pParse,
- "DELETE FROM %Q.sqlite_stat1 WHERE tbl=%Q", pDb->zName, pTab->zName
- );
- }
-
- if( !isView && !IsVirtual(pTab) ){
- destroyTable(pParse, pTab);
- }
-
- /* Remove the table entry from SQLite's internal schema and modify
- ** the schema cookie.
- */
- if( IsVirtual(pTab) ){
- sqlite3VdbeAddOp4(v, OP_VDestroy, iDb, 0, 0, pTab->zName, 0);
- }
- sqlite3VdbeAddOp4(v, OP_DropTable, iDb, 0, 0, pTab->zName, 0);
- sqlite3ChangeCookie(pParse, iDb);
- }
- sqliteViewResetAll(db, iDb);
-
-exit_drop_table:
- sqlite3SrcListDelete(db, pName);
-}
-
-/*
-** This routine is called to create a new foreign key on the table
-** currently under construction. pFromCol determines which columns
-** in the current table point to the foreign key. If pFromCol==0 then
-** connect the key to the last column inserted. pTo is the name of
-** the table referred to. pToCol is a list of tables in the other
-** pTo table that the foreign key points to. flags contains all
-** information about the conflict resolution algorithms specified
-** in the ON DELETE, ON UPDATE and ON INSERT clauses.
-**
-** An FKey structure is created and added to the table currently
-** under construction in the pParse->pNewTable field.
-**
-** The foreign key is set for IMMEDIATE processing. A subsequent call
-** to sqlite3DeferForeignKey() might change this to DEFERRED.
-*/
-SQLITE_PRIVATE void sqlite3CreateForeignKey(
- Parse *pParse, /* Parsing context */
- ExprList *pFromCol, /* Columns in this table that point to other table */
- Token *pTo, /* Name of the other table */
- ExprList *pToCol, /* Columns in the other table */
- int flags /* Conflict resolution algorithms. */
-){
- sqlite3 *db = pParse->db;
-#ifndef SQLITE_OMIT_FOREIGN_KEY
- FKey *pFKey = 0;
- Table *p = pParse->pNewTable;
- int nByte;
- int i;
- int nCol;
- char *z;
-
- assert( pTo!=0 );
- if( p==0 || IN_DECLARE_VTAB ) goto fk_end;
- if( pFromCol==0 ){
- int iCol = p->nCol-1;
- if( NEVER(iCol<0) ) goto fk_end;
- if( pToCol && pToCol->nExpr!=1 ){
- sqlite3ErrorMsg(pParse, "foreign key on %s"
- " should reference only one column of table %T",
- p->aCol[iCol].zName, pTo);
- goto fk_end;
- }
- nCol = 1;
- }else if( pToCol && pToCol->nExpr!=pFromCol->nExpr ){
- sqlite3ErrorMsg(pParse,
- "number of columns in foreign key does not match the number of "
- "columns in the referenced table");
- goto fk_end;
- }else{
- nCol = pFromCol->nExpr;
- }
- nByte = sizeof(*pFKey) + (nCol-1)*sizeof(pFKey->aCol[0]) + pTo->n + 1;
- if( pToCol ){
- for(i=0; i<pToCol->nExpr; i++){
- nByte += sqlite3Strlen30(pToCol->a[i].zName) + 1;
- }
- }
- pFKey = sqlite3DbMallocZero(db, nByte );
- if( pFKey==0 ){
- goto fk_end;
- }
- pFKey->pFrom = p;
- pFKey->pNextFrom = p->pFKey;
- z = (char*)&pFKey->aCol[nCol];
- pFKey->zTo = z;
- memcpy(z, pTo->z, pTo->n);
- z[pTo->n] = 0;
- sqlite3Dequote(z);
- z += pTo->n+1;
- pFKey->nCol = nCol;
- if( pFromCol==0 ){
- pFKey->aCol[0].iFrom = p->nCol-1;
- }else{
- for(i=0; i<nCol; i++){
- int j;
- for(j=0; j<p->nCol; j++){
- if( sqlite3StrICmp(p->aCol[j].zName, pFromCol->a[i].zName)==0 ){
- pFKey->aCol[i].iFrom = j;
- break;
- }
- }
- if( j>=p->nCol ){
- sqlite3ErrorMsg(pParse,
- "unknown column \"%s\" in foreign key definition",
- pFromCol->a[i].zName);
- goto fk_end;
- }
- }
- }
- if( pToCol ){
- for(i=0; i<nCol; i++){
- int n = sqlite3Strlen30(pToCol->a[i].zName);
- pFKey->aCol[i].zCol = z;
- memcpy(z, pToCol->a[i].zName, n);
- z[n] = 0;
- z += n+1;
- }
- }
- pFKey->isDeferred = 0;
- pFKey->deleteConf = (u8)(flags & 0xff);
- pFKey->updateConf = (u8)((flags >> 8 ) & 0xff);
- pFKey->insertConf = (u8)((flags >> 16 ) & 0xff);
-
- /* Link the foreign key to the table as the last step.
- */
- p->pFKey = pFKey;
- pFKey = 0;
-
-fk_end:
- sqlite3DbFree(db, pFKey);
-#endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */
- sqlite3ExprListDelete(db, pFromCol);
- sqlite3ExprListDelete(db, pToCol);
-}
-
-/*
-** This routine is called when an INITIALLY IMMEDIATE or INITIALLY DEFERRED
-** clause is seen as part of a foreign key definition. The isDeferred
-** parameter is 1 for INITIALLY DEFERRED and 0 for INITIALLY IMMEDIATE.
-** The behavior of the most recently created foreign key is adjusted
-** accordingly.
-*/
-SQLITE_PRIVATE void sqlite3DeferForeignKey(Parse *pParse, int isDeferred){
-#ifndef SQLITE_OMIT_FOREIGN_KEY
- Table *pTab;
- FKey *pFKey;
- if( (pTab = pParse->pNewTable)==0 || (pFKey = pTab->pFKey)==0 ) return;
- assert( isDeferred==0 || isDeferred==1 );
- pFKey->isDeferred = (u8)isDeferred;
-#endif
-}
-
-/*
-** Generate code that will erase and refill index *pIdx. This is
-** used to initialize a newly created index or to recompute the
-** content of an index in response to a REINDEX command.
-**
-** if memRootPage is not negative, it means that the index is newly
-** created. The register specified by memRootPage contains the
-** root page number of the index. If memRootPage is negative, then
-** the index already exists and must be cleared before being refilled and
-** the root page number of the index is taken from pIndex->tnum.
-*/
-static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
- Table *pTab = pIndex->pTable; /* The table that is indexed */
- int iTab = pParse->nTab++; /* Btree cursor used for pTab */
- int iIdx = pParse->nTab++; /* Btree cursor used for pIndex */
- int addr1; /* Address of top of loop */
- int tnum; /* Root page of index */
- Vdbe *v; /* Generate code into this virtual machine */
- KeyInfo *pKey; /* KeyInfo for index */
- int regIdxKey; /* Registers containing the index key */
- int regRecord; /* Register holding assemblied index record */
- sqlite3 *db = pParse->db; /* The database connection */
- int iDb = sqlite3SchemaToIndex(db, pIndex->pSchema);
-
-#ifndef SQLITE_OMIT_AUTHORIZATION
- if( sqlite3AuthCheck(pParse, SQLITE_REINDEX, pIndex->zName, 0,
- db->aDb[iDb].zName ) ){
- return;
- }
-#endif
-
- /* Require a write-lock on the table to perform this operation */
- sqlite3TableLock(pParse, iDb, pTab->tnum, 1, pTab->zName);
-
- v = sqlite3GetVdbe(pParse);
- if( v==0 ) return;
- if( memRootPage>=0 ){
- tnum = memRootPage;
- }else{
- tnum = pIndex->tnum;
- sqlite3VdbeAddOp2(v, OP_Clear, tnum, iDb);
- }
- pKey = sqlite3IndexKeyinfo(pParse, pIndex);
- sqlite3VdbeAddOp4(v, OP_OpenWrite, iIdx, tnum, iDb,
- (char *)pKey, P4_KEYINFO_HANDOFF);
- if( memRootPage>=0 ){
- sqlite3VdbeChangeP5(v, 1);
- }
- sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead);
- addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iTab, 0);
- regRecord = sqlite3GetTempReg(pParse);
- regIdxKey = sqlite3GenerateIndexKey(pParse, pIndex, iTab, regRecord, 1);
- if( pIndex->onError!=OE_None ){
- const int regRowid = regIdxKey + pIndex->nColumn;
- const int j2 = sqlite3VdbeCurrentAddr(v) + 2;
- void * const pRegKey = SQLITE_INT_TO_PTR(regIdxKey);
-
- /* The registers accessed by the OP_IsUnique opcode were allocated
- ** using sqlite3GetTempRange() inside of the sqlite3GenerateIndexKey()
- ** call above. Just before that function was freed they were released
- ** (made available to the compiler for reuse) using
- ** sqlite3ReleaseTempRange(). So in some ways having the OP_IsUnique
- ** opcode use the values stored within seems dangerous. However, since
- ** we can be sure that no other temp registers have been allocated
- ** since sqlite3ReleaseTempRange() was called, it is safe to do so.
- */
- sqlite3VdbeAddOp4(v, OP_IsUnique, iIdx, j2, regRowid, pRegKey, P4_INT32);
- sqlite3HaltConstraint(
- pParse, OE_Abort, "indexed columns are not unique", P4_STATIC);
- }
- sqlite3VdbeAddOp2(v, OP_IdxInsert, iIdx, regRecord);
- sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
- sqlite3ReleaseTempReg(pParse, regRecord);
- sqlite3VdbeAddOp2(v, OP_Next, iTab, addr1+1);
- sqlite3VdbeJumpHere(v, addr1);
- sqlite3VdbeAddOp1(v, OP_Close, iTab);
- sqlite3VdbeAddOp1(v, OP_Close, iIdx);
-}
-
-/*
-** Create a new index for an SQL table. pName1.pName2 is the name of the index
-** and pTblList is the name of the table that is to be indexed. Both will
-** be NULL for a primary key or an index that is created to satisfy a
-** UNIQUE constraint. If pTable and pIndex are NULL, use pParse->pNewTable
-** as the table to be indexed. pParse->pNewTable is a table that is
-** currently being constructed by a CREATE TABLE statement.
-**
-** pList is a list of columns to be indexed. pList will be NULL if this
-** is a primary key or unique-constraint on the most recent column added
-** to the table currently under construction.
-*/
-SQLITE_PRIVATE void sqlite3CreateIndex(
- Parse *pParse, /* All information about this parse */
- Token *pName1, /* First part of index name. May be NULL */
- Token *pName2, /* Second part of index name. May be NULL */
- SrcList *pTblName, /* Table to index. Use pParse->pNewTable if 0 */
- ExprList *pList, /* A list of columns to be indexed */
- int onError, /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */
- Token *pStart, /* The CREATE token that begins this statement */
- Token *pEnd, /* The ")" that closes the CREATE INDEX statement */
- int sortOrder, /* Sort order of primary key when pList==NULL */
- int ifNotExist /* Omit error if index already exists */
-){
- Table *pTab = 0; /* Table to be indexed */
- Index *pIndex = 0; /* The index to be created */
- char *zName = 0; /* Name of the index */
- int nName; /* Number of characters in zName */
- int i, j;
- Token nullId; /* Fake token for an empty ID list */
- DbFixer sFix; /* For assigning database names to pTable */
- int sortOrderMask; /* 1 to honor DESC in index. 0 to ignore. */
- sqlite3 *db = pParse->db;
- Db *pDb; /* The specific table containing the indexed database */
- int iDb; /* Index of the database that is being written */
- Token *pName = 0; /* Unqualified name of the index to create */
- struct ExprList_item *pListItem; /* For looping over pList */
- int nCol;
- int nExtra = 0;
- char *zExtra;
-
- assert( pStart==0 || pEnd!=0 ); /* pEnd must be non-NULL if pStart is */
- assert( pParse->nErr==0 ); /* Never called with prior errors */
- if( db->mallocFailed || IN_DECLARE_VTAB ){
- goto exit_create_index;
- }
- if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
- goto exit_create_index;
- }
-
- /*
- ** Find the table that is to be indexed. Return early if not found.
- */
- if( pTblName!=0 ){
-
- /* Use the two-part index name to determine the database
- ** to search for the table. 'Fix' the table name to this db
- ** before looking up the table.
- */
- assert( pName1 && pName2 );
- iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pName);
- if( iDb<0 ) goto exit_create_index;
-
-#ifndef SQLITE_OMIT_TEMPDB
- /* If the index name was unqualified, check if the the table
- ** is a temp table. If so, set the database to 1. Do not do this
- ** if initialising a database schema.
- */
- if( !db->init.busy ){
- pTab = sqlite3SrcListLookup(pParse, pTblName);
- if( pName2->n==0 && pTab && pTab->pSchema==db->aDb[1].pSchema ){
- iDb = 1;
- }
- }
-#endif
-
- if( sqlite3FixInit(&sFix, pParse, iDb, "index", pName) &&
- sqlite3FixSrcList(&sFix, pTblName)
- ){
- /* Because the parser constructs pTblName from a single identifier,
- ** sqlite3FixSrcList can never fail. */
- assert(0);
- }
- pTab = sqlite3LocateTable(pParse, 0, pTblName->a[0].zName,
- pTblName->a[0].zDatabase);
- if( !pTab || db->mallocFailed ) goto exit_create_index;
- assert( db->aDb[iDb].pSchema==pTab->pSchema );
- }else{
- assert( pName==0 );
- pTab = pParse->pNewTable;
- if( !pTab ) goto exit_create_index;
- iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
- }
- pDb = &db->aDb[iDb];
-
- assert( pTab!=0 );
- assert( pParse->nErr==0 );
- if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0
- && memcmp(&pTab->zName[7],"altertab_",9)!=0 ){
- sqlite3ErrorMsg(pParse, "table %s may not be indexed", pTab->zName);
- goto exit_create_index;
- }
-#ifndef SQLITE_OMIT_VIEW
- if( pTab->pSelect ){
- sqlite3ErrorMsg(pParse, "views may not be indexed");
- goto exit_create_index;
- }
-#endif
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- if( IsVirtual(pTab) ){
- sqlite3ErrorMsg(pParse, "virtual tables may not be indexed");
- goto exit_create_index;
- }
-#endif
-
- /*
- ** Find the name of the index. Make sure there is not already another
- ** index or table with the same name.
- **
- ** Exception: If we are reading the names of permanent indices from the
- ** sqlite_master table (because some other process changed the schema) and
- ** one of the index names collides with the name of a temporary table or
- ** index, then we will continue to process this index.
- **
- ** If pName==0 it means that we are
- ** dealing with a primary key or UNIQUE constraint. We have to invent our
- ** own name.
- */
- if( pName ){
- zName = sqlite3NameFromToken(db, pName);
- if( zName==0 ) goto exit_create_index;
- if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){
- goto exit_create_index;
- }
- if( !db->init.busy ){
- if( sqlite3FindTable(db, zName, 0)!=0 ){
- sqlite3ErrorMsg(pParse, "there is already a table named %s", zName);
- goto exit_create_index;
- }
- }
- if( sqlite3FindIndex(db, zName, pDb->zName)!=0 ){
- if( !ifNotExist ){
- sqlite3ErrorMsg(pParse, "index %s already exists", zName);
- }
- goto exit_create_index;
- }
- }else{
- int n;
- Index *pLoop;
- for(pLoop=pTab->pIndex, n=1; pLoop; pLoop=pLoop->pNext, n++){}
- zName = sqlite3MPrintf(db, "sqlite_autoindex_%s_%d", pTab->zName, n);
- if( zName==0 ){
- goto exit_create_index;
- }
- }
-
- /* Check for authorization to create an index.
- */
-#ifndef SQLITE_OMIT_AUTHORIZATION
- {
- const char *zDb = pDb->zName;
- if( sqlite3AuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(iDb), 0, zDb) ){
- goto exit_create_index;
- }
- i = SQLITE_CREATE_INDEX;
- if( !OMIT_TEMPDB && iDb==1 ) i = SQLITE_CREATE_TEMP_INDEX;
- if( sqlite3AuthCheck(pParse, i, zName, pTab->zName, zDb) ){
- goto exit_create_index;
- }
- }
-#endif
-
- /* If pList==0, it means this routine was called to make a primary
- ** key out of the last column added to the table under construction.
- ** So create a fake list to simulate this.
- */
- if( pList==0 ){
- nullId.z = pTab->aCol[pTab->nCol-1].zName;
- nullId.n = sqlite3Strlen30((char*)nullId.z);
- pList = sqlite3ExprListAppend(pParse, 0, 0);
- if( pList==0 ) goto exit_create_index;
- sqlite3ExprListSetName(pParse, pList, &nullId, 0);
- pList->a[0].sortOrder = (u8)sortOrder;
- }
-
- /* Figure out how many bytes of space are required to store explicitly
- ** specified collation sequence names.
- */
- for(i=0; i<pList->nExpr; i++){
- Expr *pExpr = pList->a[i].pExpr;
- if( pExpr ){
- CollSeq *pColl = pExpr->pColl;
- /* Either pColl!=0 or there was an OOM failure. But if an OOM
- ** failure we have quit before reaching this point. */
- if( ALWAYS(pColl) ){
- nExtra += (1 + sqlite3Strlen30(pColl->zName));
- }
- }
- }
-
- /*
- ** Allocate the index structure.
- */
- nName = sqlite3Strlen30(zName);
- nCol = pList->nExpr;
- pIndex = sqlite3DbMallocZero(db,
- sizeof(Index) + /* Index structure */
- sizeof(int)*nCol + /* Index.aiColumn */
- sizeof(int)*(nCol+1) + /* Index.aiRowEst */
- sizeof(char *)*nCol + /* Index.azColl */
- sizeof(u8)*nCol + /* Index.aSortOrder */
- nName + 1 + /* Index.zName */
- nExtra /* Collation sequence names */
- );
- if( db->mallocFailed ){
- goto exit_create_index;
- }
- pIndex->azColl = (char**)(&pIndex[1]);
- pIndex->aiColumn = (int *)(&pIndex->azColl[nCol]);
- pIndex->aiRowEst = (unsigned *)(&pIndex->aiColumn[nCol]);
- pIndex->aSortOrder = (u8 *)(&pIndex->aiRowEst[nCol+1]);
- pIndex->zName = (char *)(&pIndex->aSortOrder[nCol]);
- zExtra = (char *)(&pIndex->zName[nName+1]);
- memcpy(pIndex->zName, zName, nName+1);
- pIndex->pTable = pTab;
- pIndex->nColumn = pList->nExpr;
- pIndex->onError = (u8)onError;
- pIndex->autoIndex = (u8)(pName==0);
- pIndex->pSchema = db->aDb[iDb].pSchema;
-
- /* Check to see if we should honor DESC requests on index columns
- */
- if( pDb->pSchema->file_format>=4 ){
- sortOrderMask = -1; /* Honor DESC */
- }else{
- sortOrderMask = 0; /* Ignore DESC */
- }
-
- /* Scan the names of the columns of the table to be indexed and
- ** load the column indices into the Index structure. Report an error
- ** if any column is not found.
- **
- ** TODO: Add a test to make sure that the same column is not named
- ** more than once within the same index. Only the first instance of
- ** the column will ever be used by the optimizer. Note that using the
- ** same column more than once cannot be an error because that would
- ** break backwards compatibility - it needs to be a warning.
- */
- for(i=0, pListItem=pList->a; i<pList->nExpr; i++, pListItem++){
- const char *zColName = pListItem->zName;
- Column *pTabCol;
- int requestedSortOrder;
- char *zColl; /* Collation sequence name */
-
- for(j=0, pTabCol=pTab->aCol; j<pTab->nCol; j++, pTabCol++){
- if( sqlite3StrICmp(zColName, pTabCol->zName)==0 ) break;
- }
- if( j>=pTab->nCol ){
- sqlite3ErrorMsg(pParse, "table %s has no column named %s",
- pTab->zName, zColName);
- goto exit_create_index;
- }
- pIndex->aiColumn[i] = j;
- /* Justification of the ALWAYS(pListItem->pExpr->pColl): Because of
- ** the way the "idxlist" non-terminal is constructed by the parser,
- ** if pListItem->pExpr is not null then either pListItem->pExpr->pColl
- ** must exist or else there must have been an OOM error. But if there
- ** was an OOM error, we would never reach this point. */
- if( pListItem->pExpr && ALWAYS(pListItem->pExpr->pColl) ){
- int nColl;
- zColl = pListItem->pExpr->pColl->zName;
- nColl = sqlite3Strlen30(zColl) + 1;
- assert( nExtra>=nColl );
- memcpy(zExtra, zColl, nColl);
- zColl = zExtra;
- zExtra += nColl;
- nExtra -= nColl;
- }else{
- zColl = pTab->aCol[j].zColl;
- if( !zColl ){
- zColl = db->pDfltColl->zName;
- }
- }
- if( !db->init.busy && !sqlite3LocateCollSeq(pParse, zColl) ){
- goto exit_create_index;
- }
- pIndex->azColl[i] = zColl;
- requestedSortOrder = pListItem->sortOrder & sortOrderMask;
- pIndex->aSortOrder[i] = (u8)requestedSortOrder;
- }
- sqlite3DefaultRowEst(pIndex);
-
- if( pTab==pParse->pNewTable ){
- /* This routine has been called to create an automatic index as a
- ** result of a PRIMARY KEY or UNIQUE clause on a column definition, or
- ** a PRIMARY KEY or UNIQUE clause following the column definitions.
- ** i.e. one of:
- **
- ** CREATE TABLE t(x PRIMARY KEY, y);
- ** CREATE TABLE t(x, y, UNIQUE(x, y));
- **
- ** Either way, check to see if the table already has such an index. If
- ** so, don't bother creating this one. This only applies to
- ** automatically created indices. Users can do as they wish with
- ** explicit indices.
- **
- ** Two UNIQUE or PRIMARY KEY constraints are considered equivalent
- ** (and thus suppressing the second one) even if they have different
- ** sort orders.
- **
- ** If there are different collating sequences or if the columns of
- ** the constraint occur in different orders, then the constraints are
- ** considered distinct and both result in separate indices.
- */
- Index *pIdx;
- for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
- int k;
- assert( pIdx->onError!=OE_None );
- assert( pIdx->autoIndex );
- assert( pIndex->onError!=OE_None );
-
- if( pIdx->nColumn!=pIndex->nColumn ) continue;
- for(k=0; k<pIdx->nColumn; k++){
- const char *z1;
- const char *z2;
- if( pIdx->aiColumn[k]!=pIndex->aiColumn[k] ) break;
- z1 = pIdx->azColl[k];
- z2 = pIndex->azColl[k];
- if( z1!=z2 && sqlite3StrICmp(z1, z2) ) break;
- }
- if( k==pIdx->nColumn ){
- if( pIdx->onError!=pIndex->onError ){
- /* This constraint creates the same index as a previous
- ** constraint specified somewhere in the CREATE TABLE statement.
- ** However the ON CONFLICT clauses are different. If both this
- ** constraint and the previous equivalent constraint have explicit
- ** ON CONFLICT clauses this is an error. Otherwise, use the
- ** explicitly specified behaviour for the index.
- */
- if( !(pIdx->onError==OE_Default || pIndex->onError==OE_Default) ){
- sqlite3ErrorMsg(pParse,
- "conflicting ON CONFLICT clauses specified", 0);
- }
- if( pIdx->onError==OE_Default ){
- pIdx->onError = pIndex->onError;
- }
- }
- goto exit_create_index;
- }
- }
- }
-
- /* Link the new Index structure to its table and to the other
- ** in-memory database structures.
- */
- if( db->init.busy ){
- Index *p;
- p = sqlite3HashInsert(&pIndex->pSchema->idxHash,
- pIndex->zName, sqlite3Strlen30(pIndex->zName),
- pIndex);
- if( p ){
- assert( p==pIndex ); /* Malloc must have failed */
- db->mallocFailed = 1;
- goto exit_create_index;
- }
- db->flags |= SQLITE_InternChanges;
- if( pTblName!=0 ){
- pIndex->tnum = db->init.newTnum;
- }
- }
-
- /* If the db->init.busy is 0 then create the index on disk. This
- ** involves writing the index into the master table and filling in the
- ** index with the current table contents.
- **
- ** The db->init.busy is 0 when the user first enters a CREATE INDEX
- ** command. db->init.busy is 1 when a database is opened and
- ** CREATE INDEX statements are read out of the master table. In
- ** the latter case the index already exists on disk, which is why
- ** we don't want to recreate it.
- **
- ** If pTblName==0 it means this index is generated as a primary key
- ** or UNIQUE constraint of a CREATE TABLE statement. Since the table
- ** has just been created, it contains no data and the index initialization
- ** step can be skipped.
- */
- else{ /* if( db->init.busy==0 ) */
- Vdbe *v;
- char *zStmt;
- int iMem = ++pParse->nMem;
-
- v = sqlite3GetVdbe(pParse);
- if( v==0 ) goto exit_create_index;
-
-
- /* Create the rootpage for the index
- */
- sqlite3BeginWriteOperation(pParse, 1, iDb);
- sqlite3VdbeAddOp2(v, OP_CreateIndex, iDb, iMem);
-
- /* Gather the complete text of the CREATE INDEX statement into
- ** the zStmt variable
- */
- if( pStart ){
- assert( pEnd!=0 );
- /* A named index with an explicit CREATE INDEX statement */
- zStmt = sqlite3MPrintf(db, "CREATE%s INDEX %.*s",
- onError==OE_None ? "" : " UNIQUE",
- pEnd->z - pName->z + 1,
- pName->z);
- }else{
- /* An automatic index created by a PRIMARY KEY or UNIQUE constraint */
- /* zStmt = sqlite3MPrintf(""); */
- zStmt = 0;
- }
-
- /* Add an entry in sqlite_master for this index
- */
- sqlite3NestedParse(pParse,
- "INSERT INTO %Q.%s VALUES('index',%Q,%Q,#%d,%Q);",
- db->aDb[iDb].zName, SCHEMA_TABLE(iDb),
- pIndex->zName,
- pTab->zName,
- iMem,
- zStmt
- );
- sqlite3DbFree(db, zStmt);
-
- /* Fill the index with data and reparse the schema. Code an OP_Expire
- ** to invalidate all pre-compiled statements.
- */
- if( pTblName ){
- sqlite3RefillIndex(pParse, pIndex, iMem);
- sqlite3ChangeCookie(pParse, iDb);
- sqlite3VdbeAddOp4(v, OP_ParseSchema, iDb, 0, 0,
- sqlite3MPrintf(db, "name='%q'", pIndex->zName), P4_DYNAMIC);
- sqlite3VdbeAddOp1(v, OP_Expire, 0);
- }
- }
-
- /* When adding an index to the list of indices for a table, make
- ** sure all indices labeled OE_Replace come after all those labeled
- ** OE_Ignore. This is necessary for the correct constraint check
- ** processing (in sqlite3GenerateConstraintChecks()) as part of
- ** UPDATE and INSERT statements.
- */
- if( db->init.busy || pTblName==0 ){
- if( onError!=OE_Replace || pTab->pIndex==0
- || pTab->pIndex->onError==OE_Replace){
- pIndex->pNext = pTab->pIndex;
- pTab->pIndex = pIndex;
- }else{
- Index *pOther = pTab->pIndex;
- while( pOther->pNext && pOther->pNext->onError!=OE_Replace ){
- pOther = pOther->pNext;
- }
- pIndex->pNext = pOther->pNext;
- pOther->pNext = pIndex;
- }
- pIndex = 0;
- }
-
- /* Clean up before exiting */
-exit_create_index:
- if( pIndex ){
- sqlite3_free(pIndex->zColAff);
- sqlite3DbFree(db, pIndex);
- }
- sqlite3ExprListDelete(db, pList);
- sqlite3SrcListDelete(db, pTblName);
- sqlite3DbFree(db, zName);
- return;
-}
-
-/*
-** Fill the Index.aiRowEst[] array with default information - information
-** to be used when we have not run the ANALYZE command.
-**
-** aiRowEst[0] is suppose to contain the number of elements in the index.
-** Since we do not know, guess 1 million. aiRowEst[1] is an estimate of the
-** number of rows in the table that match any particular value of the
-** first column of the index. aiRowEst[2] is an estimate of the number
-** of rows that match any particular combiniation of the first 2 columns
-** of the index. And so forth. It must always be the case that
-*
-** aiRowEst[N]<=aiRowEst[N-1]
-** aiRowEst[N]>=1
-**
-** Apart from that, we have little to go on besides intuition as to
-** how aiRowEst[] should be initialized. The numbers generated here
-** are based on typical values found in actual indices.
-*/
-SQLITE_PRIVATE void sqlite3DefaultRowEst(Index *pIdx){
- unsigned *a = pIdx->aiRowEst;
- int i;
- assert( a!=0 );
- a[0] = 1000000;
- for(i=pIdx->nColumn; i>=5; i--){
- a[i] = 5;
- }
- while( i>=1 ){
- a[i] = 11 - i;
- i--;
- }
- if( pIdx->onError!=OE_None ){
- a[pIdx->nColumn] = 1;
- }
-}
-
-/*
-** This routine will drop an existing named index. This routine
-** implements the DROP INDEX statement.
-*/
-SQLITE_PRIVATE void sqlite3DropIndex(Parse *pParse, SrcList *pName, int ifExists){
- Index *pIndex;
- Vdbe *v;
- sqlite3 *db = pParse->db;
- int iDb;
-
- assert( pParse->nErr==0 ); /* Never called with prior errors */
- if( db->mallocFailed ){
- goto exit_drop_index;
- }
- assert( pName->nSrc==1 );
- if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
- goto exit_drop_index;
- }
- pIndex = sqlite3FindIndex(db, pName->a[0].zName, pName->a[0].zDatabase);
- if( pIndex==0 ){
- if( !ifExists ){
- sqlite3ErrorMsg(pParse, "no such index: %S", pName, 0);
- }
- pParse->checkSchema = 1;
- goto exit_drop_index;
- }
- if( pIndex->autoIndex ){
- sqlite3ErrorMsg(pParse, "index associated with UNIQUE "
- "or PRIMARY KEY constraint cannot be dropped", 0);
- goto exit_drop_index;
- }
- iDb = sqlite3SchemaToIndex(db, pIndex->pSchema);
-#ifndef SQLITE_OMIT_AUTHORIZATION
- {
- int code = SQLITE_DROP_INDEX;
- Table *pTab = pIndex->pTable;
- const char *zDb = db->aDb[iDb].zName;
- const char *zTab = SCHEMA_TABLE(iDb);
- if( sqlite3AuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb) ){
- goto exit_drop_index;
- }
- if( !OMIT_TEMPDB && iDb ) code = SQLITE_DROP_TEMP_INDEX;
- if( sqlite3AuthCheck(pParse, code, pIndex->zName, pTab->zName, zDb) ){
- goto exit_drop_index;
- }
- }
-#endif
-
- /* Generate code to remove the index and from the master table */
- v = sqlite3GetVdbe(pParse);
- if( v ){
- sqlite3BeginWriteOperation(pParse, 1, iDb);
- sqlite3NestedParse(pParse,
- "DELETE FROM %Q.%s WHERE name=%Q",
- db->aDb[iDb].zName, SCHEMA_TABLE(iDb),
- pIndex->zName
- );
- if( sqlite3FindTable(db, "sqlite_stat1", db->aDb[iDb].zName) ){
- sqlite3NestedParse(pParse,
- "DELETE FROM %Q.sqlite_stat1 WHERE idx=%Q",
- db->aDb[iDb].zName, pIndex->zName
- );
- }
- sqlite3ChangeCookie(pParse, iDb);
- destroyRootPage(pParse, pIndex->tnum, iDb);
- sqlite3VdbeAddOp4(v, OP_DropIndex, iDb, 0, 0, pIndex->zName, 0);
- }
-
-exit_drop_index:
- sqlite3SrcListDelete(db, pName);
-}
-
-/*
-** pArray is a pointer to an array of objects. Each object in the
-** array is szEntry bytes in size. This routine allocates a new
-** object on the end of the array.
-**
-** *pnEntry is the number of entries already in use. *pnAlloc is
-** the previously allocated size of the array. initSize is the
-** suggested initial array size allocation.
-**
-** The index of the new entry is returned in *pIdx.
-**
-** This routine returns a pointer to the array of objects. This
-** might be the same as the pArray parameter or it might be a different
-** pointer if the array was resized.
-*/
-SQLITE_PRIVATE void *sqlite3ArrayAllocate(
- sqlite3 *db, /* Connection to notify of malloc failures */
- void *pArray, /* Array of objects. Might be reallocated */
- int szEntry, /* Size of each object in the array */
- int initSize, /* Suggested initial allocation, in elements */
- int *pnEntry, /* Number of objects currently in use */
- int *pnAlloc, /* Current size of the allocation, in elements */
- int *pIdx /* Write the index of a new slot here */
-){
- char *z;
- if( *pnEntry >= *pnAlloc ){
- void *pNew;
- int newSize;
- newSize = (*pnAlloc)*2 + initSize;
- pNew = sqlite3DbRealloc(db, pArray, newSize*szEntry);
- if( pNew==0 ){
- *pIdx = -1;
- return pArray;
- }
- *pnAlloc = sqlite3DbMallocSize(db, pNew)/szEntry;
- pArray = pNew;
- }
- z = (char*)pArray;
- memset(&z[*pnEntry * szEntry], 0, szEntry);
- *pIdx = *pnEntry;
- ++*pnEntry;
- return pArray;
-}
-
-/*
-** Append a new element to the given IdList. Create a new IdList if
-** need be.
-**
-** A new IdList is returned, or NULL if malloc() fails.
-*/
-SQLITE_PRIVATE IdList *sqlite3IdListAppend(sqlite3 *db, IdList *pList, Token *pToken){
- int i;
- if( pList==0 ){
- pList = sqlite3DbMallocZero(db, sizeof(IdList) );
- if( pList==0 ) return 0;
- pList->nAlloc = 0;
- }
- pList->a = sqlite3ArrayAllocate(
- db,
- pList->a,
- sizeof(pList->a[0]),
- 5,
- &pList->nId,
- &pList->nAlloc,
- &i
- );
- if( i<0 ){
- sqlite3IdListDelete(db, pList);
- return 0;
- }
- pList->a[i].zName = sqlite3NameFromToken(db, pToken);
- return pList;
-}
-
-/*
-** Delete an IdList.
-*/
-SQLITE_PRIVATE void sqlite3IdListDelete(sqlite3 *db, IdList *pList){
- int i;
- if( pList==0 ) return;
- for(i=0; i<pList->nId; i++){
- sqlite3DbFree(db, pList->a[i].zName);
- }
- sqlite3DbFree(db, pList->a);
- sqlite3DbFree(db, pList);
-}
-
-/*
-** Return the index in pList of the identifier named zId. Return -1
-** if not found.
-*/
-SQLITE_PRIVATE int sqlite3IdListIndex(IdList *pList, const char *zName){
- int i;
- if( pList==0 ) return -1;
- for(i=0; i<pList->nId; i++){
- if( sqlite3StrICmp(pList->a[i].zName, zName)==0 ) return i;
- }
- return -1;
-}
-
-/*
-** Expand the space allocated for the given SrcList object by
-** creating nExtra new slots beginning at iStart. iStart is zero based.
-** New slots are zeroed.
-**
-** For example, suppose a SrcList initially contains two entries: A,B.
-** To append 3 new entries onto the end, do this:
-**
-** sqlite3SrcListEnlarge(db, pSrclist, 3, 2);
-**
-** After the call above it would contain: A, B, nil, nil, nil.
-** If the iStart argument had been 1 instead of 2, then the result
-** would have been: A, nil, nil, nil, B. To prepend the new slots,
-** the iStart value would be 0. The result then would
-** be: nil, nil, nil, A, B.
-**
-** If a memory allocation fails the SrcList is unchanged. The
-** db->mallocFailed flag will be set to true.
-*/
-SQLITE_PRIVATE SrcList *sqlite3SrcListEnlarge(
- sqlite3 *db, /* Database connection to notify of OOM errors */
- SrcList *pSrc, /* The SrcList to be enlarged */
- int nExtra, /* Number of new slots to add to pSrc->a[] */
- int iStart /* Index in pSrc->a[] of first new slot */
-){
- int i;
-
- /* Sanity checking on calling parameters */
- assert( iStart>=0 );
- assert( nExtra>=1 );
- assert( pSrc!=0 );
- assert( iStart<=pSrc->nSrc );
-
- /* Allocate additional space if needed */
- if( pSrc->nSrc+nExtra>pSrc->nAlloc ){
- SrcList *pNew;
- int nAlloc = pSrc->nSrc+nExtra;
- int nGot;
- pNew = sqlite3DbRealloc(db, pSrc,
- sizeof(*pSrc) + (nAlloc-1)*sizeof(pSrc->a[0]) );
- if( pNew==0 ){
- assert( db->mallocFailed );
- return pSrc;
- }
- pSrc = pNew;
- nGot = (sqlite3DbMallocSize(db, pNew) - sizeof(*pSrc))/sizeof(pSrc->a[0])+1;
- pSrc->nAlloc = (u16)nGot;
- }
-
- /* Move existing slots that come after the newly inserted slots
- ** out of the way */
- for(i=pSrc->nSrc-1; i>=iStart; i--){
- pSrc->a[i+nExtra] = pSrc->a[i];
- }
- pSrc->nSrc += (i16)nExtra;
-
- /* Zero the newly allocated slots */
- memset(&pSrc->a[iStart], 0, sizeof(pSrc->a[0])*nExtra);
- for(i=iStart; i<iStart+nExtra; i++){
- pSrc->a[i].iCursor = -1;
- }
-
- /* Return a pointer to the enlarged SrcList */
- return pSrc;
-}
-
-
-/*
-** Append a new table name to the given SrcList. Create a new SrcList if
-** need be. A new entry is created in the SrcList even if pTable is NULL.
-**
-** A SrcList is returned, or NULL if there is an OOM error. The returned
-** SrcList might be the same as the SrcList that was input or it might be
-** a new one. If an OOM error does occurs, then the prior value of pList
-** that is input to this routine is automatically freed.
-**
-** If pDatabase is not null, it means that the table has an optional
-** database name prefix. Like this: "database.table". The pDatabase
-** points to the table name and the pTable points to the database name.
-** The SrcList.a[].zName field is filled with the table name which might
-** come from pTable (if pDatabase is NULL) or from pDatabase.
-** SrcList.a[].zDatabase is filled with the database name from pTable,
-** or with NULL if no database is specified.
-**
-** In other words, if call like this:
-**
-** sqlite3SrcListAppend(D,A,B,0);
-**
-** Then B is a table name and the database name is unspecified. If called
-** like this:
-**
-** sqlite3SrcListAppend(D,A,B,C);
-**
-** Then C is the table name and B is the database name. If C is defined
-** then so is B. In other words, we never have a case where:
-**
-** sqlite3SrcListAppend(D,A,0,C);
-**
-** Both pTable and pDatabase are assumed to be quoted. They are dequoted
-** before being added to the SrcList.
-*/
-SQLITE_PRIVATE SrcList *sqlite3SrcListAppend(
- sqlite3 *db, /* Connection to notify of malloc failures */
- SrcList *pList, /* Append to this SrcList. NULL creates a new SrcList */
- Token *pTable, /* Table to append */
- Token *pDatabase /* Database of the table */
-){
- struct SrcList_item *pItem;
- assert( pDatabase==0 || pTable!=0 ); /* Cannot have C without B */
- if( pList==0 ){
- pList = sqlite3DbMallocZero(db, sizeof(SrcList) );
- if( pList==0 ) return 0;
- pList->nAlloc = 1;
- }
- pList = sqlite3SrcListEnlarge(db, pList, 1, pList->nSrc);
- if( db->mallocFailed ){
- sqlite3SrcListDelete(db, pList);
- return 0;
- }
- pItem = &pList->a[pList->nSrc-1];
- if( pDatabase && pDatabase->z==0 ){
- pDatabase = 0;
- }
- if( pDatabase ){
- Token *pTemp = pDatabase;
- pDatabase = pTable;
- pTable = pTemp;
- }
- pItem->zName = sqlite3NameFromToken(db, pTable);
- pItem->zDatabase = sqlite3NameFromToken(db, pDatabase);
- return pList;
-}
-
-/*
-** Assign VdbeCursor index numbers to all tables in a SrcList
-*/
-SQLITE_PRIVATE void sqlite3SrcListAssignCursors(Parse *pParse, SrcList *pList){
- int i;
- struct SrcList_item *pItem;
- assert(pList || pParse->db->mallocFailed );
- if( pList ){
- for(i=0, pItem=pList->a; i<pList->nSrc; i++, pItem++){
- if( pItem->iCursor>=0 ) break;
- pItem->iCursor = pParse->nTab++;
- if( pItem->pSelect ){
- sqlite3SrcListAssignCursors(pParse, pItem->pSelect->pSrc);
- }
- }
- }
-}
-
-/*
-** Delete an entire SrcList including all its substructure.
-*/
-SQLITE_PRIVATE void sqlite3SrcListDelete(sqlite3 *db, SrcList *pList){
- int i;
- struct SrcList_item *pItem;
- if( pList==0 ) return;
- for(pItem=pList->a, i=0; i<pList->nSrc; i++, pItem++){
- sqlite3DbFree(db, pItem->zDatabase);
- sqlite3DbFree(db, pItem->zName);
- sqlite3DbFree(db, pItem->zAlias);
- sqlite3DbFree(db, pItem->zIndex);
- sqlite3DeleteTable(pItem->pTab);
- sqlite3SelectDelete(db, pItem->pSelect);
- sqlite3ExprDelete(db, pItem->pOn);
- sqlite3IdListDelete(db, pItem->pUsing);
- }
- sqlite3DbFree(db, pList);
-}
-
-/*
-** This routine is called by the parser to add a new term to the
-** end of a growing FROM clause. The "p" parameter is the part of
-** the FROM clause that has already been constructed. "p" is NULL
-** if this is the first term of the FROM clause. pTable and pDatabase
-** are the name of the table and database named in the FROM clause term.
-** pDatabase is NULL if the database name qualifier is missing - the
-** usual case. If the term has a alias, then pAlias points to the
-** alias token. If the term is a subquery, then pSubquery is the
-** SELECT statement that the subquery encodes. The pTable and
-** pDatabase parameters are NULL for subqueries. The pOn and pUsing
-** parameters are the content of the ON and USING clauses.
-**
-** Return a new SrcList which encodes is the FROM with the new
-** term added.
-*/
-SQLITE_PRIVATE SrcList *sqlite3SrcListAppendFromTerm(
- Parse *pParse, /* Parsing context */
- SrcList *p, /* The left part of the FROM clause already seen */
- Token *pTable, /* Name of the table to add to the FROM clause */
- Token *pDatabase, /* Name of the database containing pTable */
- Token *pAlias, /* The right-hand side of the AS subexpression */
- Select *pSubquery, /* A subquery used in place of a table name */
- Expr *pOn, /* The ON clause of a join */
- IdList *pUsing /* The USING clause of a join */
-){
- struct SrcList_item *pItem;
- sqlite3 *db = pParse->db;
- if( !p && (pOn || pUsing) ){
- sqlite3ErrorMsg(pParse, "a JOIN clause is required before %s",
- (pOn ? "ON" : "USING")
- );
- goto append_from_error;
- }
- p = sqlite3SrcListAppend(db, p, pTable, pDatabase);
- if( p==0 || NEVER(p->nSrc==0) ){
- goto append_from_error;
- }
- pItem = &p->a[p->nSrc-1];
- assert( pAlias!=0 );
- if( pAlias->n ){
- pItem->zAlias = sqlite3NameFromToken(db, pAlias);
- }
- pItem->pSelect = pSubquery;
- pItem->pOn = pOn;
- pItem->pUsing = pUsing;
- return p;
-
- append_from_error:
- assert( p==0 );
- sqlite3ExprDelete(db, pOn);
- sqlite3IdListDelete(db, pUsing);
- sqlite3SelectDelete(db, pSubquery);
- return 0;
-}
-
-/*
-** Add an INDEXED BY or NOT INDEXED clause to the most recently added
-** element of the source-list passed as the second argument.
-*/
-SQLITE_PRIVATE void sqlite3SrcListIndexedBy(Parse *pParse, SrcList *p, Token *pIndexedBy){
- assert( pIndexedBy!=0 );
- if( p && ALWAYS(p->nSrc>0) ){
- struct SrcList_item *pItem = &p->a[p->nSrc-1];
- assert( pItem->notIndexed==0 && pItem->zIndex==0 );
- if( pIndexedBy->n==1 && !pIndexedBy->z ){
- /* A "NOT INDEXED" clause was supplied. See parse.y
- ** construct "indexed_opt" for details. */
- pItem->notIndexed = 1;
- }else{
- pItem->zIndex = sqlite3NameFromToken(pParse->db, pIndexedBy);
- }
- }
-}
-
-/*
-** When building up a FROM clause in the parser, the join operator
-** is initially attached to the left operand. But the code generator
-** expects the join operator to be on the right operand. This routine
-** Shifts all join operators from left to right for an entire FROM
-** clause.
-**
-** Example: Suppose the join is like this:
-**
-** A natural cross join B
-**
-** The operator is "natural cross join". The A and B operands are stored
-** in p->a[0] and p->a[1], respectively. The parser initially stores the
-** operator with A. This routine shifts that operator over to B.
-*/
-SQLITE_PRIVATE void sqlite3SrcListShiftJoinType(SrcList *p){
- if( p && p->a ){
- int i;
- for(i=p->nSrc-1; i>0; i--){
- p->a[i].jointype = p->a[i-1].jointype;
- }
- p->a[0].jointype = 0;
- }
-}
-
-/*
-** Begin a transaction
-*/
-SQLITE_PRIVATE void sqlite3BeginTransaction(Parse *pParse, int type){
- sqlite3 *db;
- Vdbe *v;
- int i;
-
- assert( pParse!=0 );
- db = pParse->db;
- assert( db!=0 );
-/* if( db->aDb[0].pBt==0 ) return; */
- if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "BEGIN", 0, 0) ){
- return;
- }
- v = sqlite3GetVdbe(pParse);
- if( !v ) return;
- if( type!=TK_DEFERRED ){
- for(i=0; i<db->nDb; i++){
- sqlite3VdbeAddOp2(v, OP_Transaction, i, (type==TK_EXCLUSIVE)+1);
- sqlite3VdbeUsesBtree(v, i);
- }
- }
- sqlite3VdbeAddOp2(v, OP_AutoCommit, 0, 0);
-}
-
-/*
-** Commit a transaction
-*/
-SQLITE_PRIVATE void sqlite3CommitTransaction(Parse *pParse){
- sqlite3 *db;
- Vdbe *v;
-
- assert( pParse!=0 );
- db = pParse->db;
- assert( db!=0 );
-/* if( db->aDb[0].pBt==0 ) return; */
- if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "COMMIT", 0, 0) ){
- return;
- }
- v = sqlite3GetVdbe(pParse);
- if( v ){
- sqlite3VdbeAddOp2(v, OP_AutoCommit, 1, 0);
- }
-}
-
-/*
-** Rollback a transaction
-*/
-SQLITE_PRIVATE void sqlite3RollbackTransaction(Parse *pParse){
- sqlite3 *db;
- Vdbe *v;
-
- assert( pParse!=0 );
- db = pParse->db;
- assert( db!=0 );
-/* if( db->aDb[0].pBt==0 ) return; */
- if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "ROLLBACK", 0, 0) ){
- return;
- }
- v = sqlite3GetVdbe(pParse);
- if( v ){
- sqlite3VdbeAddOp2(v, OP_AutoCommit, 1, 1);
- }
-}
-
-/*
-** This function is called by the parser when it parses a command to create,
-** release or rollback an SQL savepoint.
-*/
-SQLITE_PRIVATE void sqlite3Savepoint(Parse *pParse, int op, Token *pName){
- char *zName = sqlite3NameFromToken(pParse->db, pName);
- if( zName ){
- Vdbe *v = sqlite3GetVdbe(pParse);
-#ifndef SQLITE_OMIT_AUTHORIZATION
- static const char *az[] = { "BEGIN", "RELEASE", "ROLLBACK" };
- assert( !SAVEPOINT_BEGIN && SAVEPOINT_RELEASE==1 && SAVEPOINT_ROLLBACK==2 );
-#endif
- if( !v || sqlite3AuthCheck(pParse, SQLITE_SAVEPOINT, az[op], zName, 0) ){
- sqlite3DbFree(pParse->db, zName);
- return;
- }
- sqlite3VdbeAddOp4(v, OP_Savepoint, op, 0, 0, zName, P4_DYNAMIC);
- }
-}
-
-/*
-** Make sure the TEMP database is open and available for use. Return
-** the number of errors. Leave any error messages in the pParse structure.
-*/
-SQLITE_PRIVATE int sqlite3OpenTempDatabase(Parse *pParse){
- sqlite3 *db = pParse->db;
- if( db->aDb[1].pBt==0 && !pParse->explain ){
- int rc;
- static const int flags =
- SQLITE_OPEN_READWRITE |
- SQLITE_OPEN_CREATE |
- SQLITE_OPEN_EXCLUSIVE |
- SQLITE_OPEN_DELETEONCLOSE |
- SQLITE_OPEN_TEMP_DB;
-
- rc = sqlite3BtreeFactory(db, 0, 0, SQLITE_DEFAULT_CACHE_SIZE, flags,
- &db->aDb[1].pBt);
- if( rc!=SQLITE_OK ){
- sqlite3ErrorMsg(pParse, "unable to open a temporary database "
- "file for storing temporary tables");
- pParse->rc = rc;
- return 1;
- }
- assert( (db->flags & SQLITE_InTrans)==0 || db->autoCommit );
- assert( db->aDb[1].pSchema );
- sqlite3PagerJournalMode(sqlite3BtreePager(db->aDb[1].pBt),
- db->dfltJournalMode);
- }
- return 0;
-}
-
-/*
-** Generate VDBE code that will verify the schema cookie and start
-** a read-transaction for all named database files.
-**
-** It is important that all schema cookies be verified and all
-** read transactions be started before anything else happens in
-** the VDBE program. But this routine can be called after much other
-** code has been generated. So here is what we do:
-**
-** The first time this routine is called, we code an OP_Goto that
-** will jump to a subroutine at the end of the program. Then we
-** record every database that needs its schema verified in the
-** pParse->cookieMask field. Later, after all other code has been
-** generated, the subroutine that does the cookie verifications and
-** starts the transactions will be coded and the OP_Goto P2 value
-** will be made to point to that subroutine. The generation of the
-** cookie verification subroutine code happens in sqlite3FinishCoding().
-**
-** If iDb<0 then code the OP_Goto only - don't set flag to verify the
-** schema on any databases. This can be used to position the OP_Goto
-** early in the code, before we know if any database tables will be used.
-*/
-SQLITE_PRIVATE void sqlite3CodeVerifySchema(Parse *pParse, int iDb){
- Parse *pToplevel = sqlite3ParseToplevel(pParse);
-
- if( pToplevel->cookieGoto==0 ){
- Vdbe *v = sqlite3GetVdbe(pToplevel);
- if( v==0 ) return; /* This only happens if there was a prior error */
- pToplevel->cookieGoto = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0)+1;
- }
- if( iDb>=0 ){
- sqlite3 *db = pToplevel->db;
- int mask;
-
- assert( iDb<db->nDb );
- assert( db->aDb[iDb].pBt!=0 || iDb==1 );
- assert( iDb<SQLITE_MAX_ATTACHED+2 );
- mask = 1<<iDb;
- if( (pToplevel->cookieMask & mask)==0 ){
- pToplevel->cookieMask |= mask;
- pToplevel->cookieValue[iDb] = db->aDb[iDb].pSchema->schema_cookie;
- if( !OMIT_TEMPDB && iDb==1 ){
- sqlite3OpenTempDatabase(pToplevel);
- }
- }
- }
-}
-
-/*
-** Generate VDBE code that prepares for doing an operation that
-** might change the database.
-**
-** This routine starts a new transaction if we are not already within
-** a transaction. If we are already within a transaction, then a checkpoint
-** is set if the setStatement parameter is true. A checkpoint should
-** be set for operations that might fail (due to a constraint) part of
-** the way through and which will need to undo some writes without having to
-** rollback the whole transaction. For operations where all constraints
-** can be checked before any changes are made to the database, it is never
-** necessary to undo a write and the checkpoint should not be set.
-*/
-SQLITE_PRIVATE void sqlite3BeginWriteOperation(Parse *pParse, int setStatement, int iDb){
- Parse *pToplevel = sqlite3ParseToplevel(pParse);
- sqlite3CodeVerifySchema(pParse, iDb);
- pToplevel->writeMask |= 1<<iDb;
- pToplevel->isMultiWrite |= setStatement;
-}
-
-/*
-** Set the "may throw abort exception" flag for the statement currently
-** being coded.
-*/
-SQLITE_PRIVATE void sqlite3MayAbort(Parse *pParse){
- Parse *pToplevel = sqlite3ParseToplevel(pParse);
- pToplevel->mayAbort = 1;
-}
-
-/*
-** Code an OP_Halt that causes the vdbe to return an SQLITE_CONSTRAINT
-** error. The onError parameter determines which (if any) of the statement
-** and/or current transaction is rolled back.
-*/
-SQLITE_PRIVATE void sqlite3HaltConstraint(Parse *pParse, int onError, char *p4, int p4type){
- Vdbe *v = sqlite3GetVdbe(pParse);
- if( onError==OE_Abort ){
- sqlite3MayAbort(pParse);
- }
- sqlite3VdbeAddOp4(v, OP_Halt, SQLITE_CONSTRAINT, onError, 0, p4, p4type);
-}
-
-/*
-** Check to see if pIndex uses the collating sequence pColl. Return
-** true if it does and false if it does not.
-*/
-#ifndef SQLITE_OMIT_REINDEX
-static int collationMatch(const char *zColl, Index *pIndex){
- int i;
- assert( zColl!=0 );
- for(i=0; i<pIndex->nColumn; i++){
- const char *z = pIndex->azColl[i];
- assert( z!=0 );
- if( 0==sqlite3StrICmp(z, zColl) ){
- return 1;
- }
- }
- return 0;
-}
-#endif
-
-/*
-** Recompute all indices of pTab that use the collating sequence pColl.
-** If pColl==0 then recompute all indices of pTab.
-*/
-#ifndef SQLITE_OMIT_REINDEX
-static void reindexTable(Parse *pParse, Table *pTab, char const *zColl){
- Index *pIndex; /* An index associated with pTab */
-
- for(pIndex=pTab->pIndex; pIndex; pIndex=pIndex->pNext){
- if( zColl==0 || collationMatch(zColl, pIndex) ){
- int iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
- sqlite3BeginWriteOperation(pParse, 0, iDb);
- sqlite3RefillIndex(pParse, pIndex, -1);
- }
- }
-}
-#endif
-
-/*
-** Recompute all indices of all tables in all databases where the
-** indices use the collating sequence pColl. If pColl==0 then recompute
-** all indices everywhere.
-*/
-#ifndef SQLITE_OMIT_REINDEX
-static void reindexDatabases(Parse *pParse, char const *zColl){
- Db *pDb; /* A single database */
- int iDb; /* The database index number */
- sqlite3 *db = pParse->db; /* The database connection */
- HashElem *k; /* For looping over tables in pDb */
- Table *pTab; /* A table in the database */
-
- for(iDb=0, pDb=db->aDb; iDb<db->nDb; iDb++, pDb++){
- assert( pDb!=0 );
- for(k=sqliteHashFirst(&pDb->pSchema->tblHash); k; k=sqliteHashNext(k)){
- pTab = (Table*)sqliteHashData(k);
- reindexTable(pParse, pTab, zColl);
- }
- }
-}
-#endif
-
-/*
-** Generate code for the REINDEX command.
-**
-** REINDEX -- 1
-** REINDEX <collation> -- 2
-** REINDEX ?<database>.?<tablename> -- 3
-** REINDEX ?<database>.?<indexname> -- 4
-**
-** Form 1 causes all indices in all attached databases to be rebuilt.
-** Form 2 rebuilds all indices in all databases that use the named
-** collating function. Forms 3 and 4 rebuild the named index or all
-** indices associated with the named table.
-*/
-#ifndef SQLITE_OMIT_REINDEX
-SQLITE_PRIVATE void sqlite3Reindex(Parse *pParse, Token *pName1, Token *pName2){
- CollSeq *pColl; /* Collating sequence to be reindexed, or NULL */
- char *z; /* Name of a table or index */
- const char *zDb; /* Name of the database */
- Table *pTab; /* A table in the database */
- Index *pIndex; /* An index associated with pTab */
- int iDb; /* The database index number */
- sqlite3 *db = pParse->db; /* The database connection */
- Token *pObjName; /* Name of the table or index to be reindexed */
-
- /* Read the database schema. If an error occurs, leave an error message
- ** and code in pParse and return NULL. */
- if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
- return;
- }
-
- if( pName1==0 ){
- reindexDatabases(pParse, 0);
- return;
- }else if( NEVER(pName2==0) || pName2->z==0 ){
- char *zColl;
- assert( pName1->z );
- zColl = sqlite3NameFromToken(pParse->db, pName1);
- if( !zColl ) return;
- pColl = sqlite3FindCollSeq(db, ENC(db), zColl, 0);
- if( pColl ){
- reindexDatabases(pParse, zColl);
- sqlite3DbFree(db, zColl);
- return;
- }
- sqlite3DbFree(db, zColl);
- }
- iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pObjName);
- if( iDb<0 ) return;
- z = sqlite3NameFromToken(db, pObjName);
- if( z==0 ) return;
- zDb = db->aDb[iDb].zName;
- pTab = sqlite3FindTable(db, z, zDb);
- if( pTab ){
- reindexTable(pParse, pTab, 0);
- sqlite3DbFree(db, z);
- return;
- }
- pIndex = sqlite3FindIndex(db, z, zDb);
- sqlite3DbFree(db, z);
- if( pIndex ){
- sqlite3BeginWriteOperation(pParse, 0, iDb);
- sqlite3RefillIndex(pParse, pIndex, -1);
- return;
- }
- sqlite3ErrorMsg(pParse, "unable to identify the object to be reindexed");
-}
-#endif
-
-/*
-** Return a dynamicly allocated KeyInfo structure that can be used
-** with OP_OpenRead or OP_OpenWrite to access database index pIdx.
-**
-** If successful, a pointer to the new structure is returned. In this case
-** the caller is responsible for calling sqlite3DbFree(db, ) on the returned
-** pointer. If an error occurs (out of memory or missing collation
-** sequence), NULL is returned and the state of pParse updated to reflect
-** the error.
-*/
-SQLITE_PRIVATE KeyInfo *sqlite3IndexKeyinfo(Parse *pParse, Index *pIdx){
- int i;
- int nCol = pIdx->nColumn;
- int nBytes = sizeof(KeyInfo) + (nCol-1)*sizeof(CollSeq*) + nCol;
- sqlite3 *db = pParse->db;
- KeyInfo *pKey = (KeyInfo *)sqlite3DbMallocZero(db, nBytes);
-
- if( pKey ){
- pKey->db = pParse->db;
- pKey->aSortOrder = (u8 *)&(pKey->aColl[nCol]);
- assert( &pKey->aSortOrder[nCol]==&(((u8 *)pKey)[nBytes]) );
- for(i=0; i<nCol; i++){
- char *zColl = pIdx->azColl[i];
- assert( zColl );
- pKey->aColl[i] = sqlite3LocateCollSeq(pParse, zColl);
- pKey->aSortOrder[i] = pIdx->aSortOrder[i];
- }
- pKey->nField = (u16)nCol;
- }
-
- if( pParse->nErr ){
- sqlite3DbFree(db, pKey);
- pKey = 0;
- }
- return pKey;
-}
-
-/************** End of build.c ***********************************************/
-/************** Begin file callback.c ****************************************/
-/*
-** 2005 May 23
-**
-** 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 functions used to access the internal hash tables
-** of user defined functions and collation sequences.
-**
-** $Id: callback.c,v 1.42 2009/06/17 00:35:31 drh Exp $
-*/
-
-
-/*
-** Invoke the 'collation needed' callback to request a collation sequence
-** in the encoding enc of name zName, length nName.
-*/
-static void callCollNeeded(sqlite3 *db, int enc, const char *zName){
- assert( !db->xCollNeeded || !db->xCollNeeded16 );
- if( db->xCollNeeded ){
- char *zExternal = sqlite3DbStrDup(db, zName);
- if( !zExternal ) return;
- db->xCollNeeded(db->pCollNeededArg, db, enc, zExternal);
- sqlite3DbFree(db, zExternal);
- }
-#ifndef SQLITE_OMIT_UTF16
- if( db->xCollNeeded16 ){
- char const *zExternal;
- sqlite3_value *pTmp = sqlite3ValueNew(db);
- sqlite3ValueSetStr(pTmp, -1, zName, SQLITE_UTF8, SQLITE_STATIC);
- zExternal = sqlite3ValueText(pTmp, SQLITE_UTF16NATIVE);
- if( zExternal ){
- db->xCollNeeded16(db->pCollNeededArg, db, (int)ENC(db), zExternal);
- }
- sqlite3ValueFree(pTmp);
- }
-#endif
-}
-
-/*
-** This routine is called if the collation factory fails to deliver a
-** collation function in the best encoding but there may be other versions
-** of this collation function (for other text encodings) available. Use one
-** of these instead if they exist. Avoid a UTF-8 <-> UTF-16 conversion if
-** possible.
-*/
-static int synthCollSeq(sqlite3 *db, CollSeq *pColl){
- CollSeq *pColl2;
- char *z = pColl->zName;
- int i;
- static const u8 aEnc[] = { SQLITE_UTF16BE, SQLITE_UTF16LE, SQLITE_UTF8 };
- for(i=0; i<3; i++){
- pColl2 = sqlite3FindCollSeq(db, aEnc[i], z, 0);
- if( pColl2->xCmp!=0 ){
- memcpy(pColl, pColl2, sizeof(CollSeq));
- pColl->xDel = 0; /* Do not copy the destructor */
- return SQLITE_OK;
- }
- }
- return SQLITE_ERROR;
-}
-
-/*
-** This function is responsible for invoking the collation factory callback
-** or substituting a collation sequence of a different encoding when the
-** requested collation sequence is not available in the desired encoding.
-**
-** If it is not NULL, then pColl must point to the database native encoding
-** collation sequence with name zName, length nName.
-**
-** The return value is either the collation sequence to be used in database
-** db for collation type name zName, length nName, or NULL, if no collation
-** sequence can be found.
-**
-** See also: sqlite3LocateCollSeq(), sqlite3FindCollSeq()
-*/
-SQLITE_PRIVATE CollSeq *sqlite3GetCollSeq(
- sqlite3* db, /* The database connection */
- u8 enc, /* The desired encoding for the collating sequence */
- CollSeq *pColl, /* Collating sequence with native encoding, or NULL */
- const char *zName /* Collating sequence name */
-){
- CollSeq *p;
-
- p = pColl;
- if( !p ){
- p = sqlite3FindCollSeq(db, enc, zName, 0);
- }
- if( !p || !p->xCmp ){
- /* No collation sequence of this type for this encoding is registered.
- ** Call the collation factory to see if it can supply us with one.
- */
- callCollNeeded(db, enc, zName);
- p = sqlite3FindCollSeq(db, enc, zName, 0);
- }
- if( p && !p->xCmp && synthCollSeq(db, p) ){
- p = 0;
- }
- assert( !p || p->xCmp );
- return p;
-}
-
-/*
-** This routine is called on a collation sequence before it is used to
-** check that it is defined. An undefined collation sequence exists when
-** a database is loaded that contains references to collation sequences
-** that have not been defined by sqlite3_create_collation() etc.
-**
-** If required, this routine calls the 'collation needed' callback to
-** request a definition of the collating sequence. If this doesn't work,
-** an equivalent collating sequence that uses a text encoding different
-** from the main database is substituted, if one is available.
-*/
-SQLITE_PRIVATE int sqlite3CheckCollSeq(Parse *pParse, CollSeq *pColl){
- if( pColl ){
- const char *zName = pColl->zName;
- sqlite3 *db = pParse->db;
- CollSeq *p = sqlite3GetCollSeq(db, ENC(db), pColl, zName);
- if( !p ){
- sqlite3ErrorMsg(pParse, "no such collation sequence: %s", zName);
- pParse->nErr++;
- return SQLITE_ERROR;
- }
- assert( p==pColl );
- }
- return SQLITE_OK;
-}
-
-
-
-/*
-** Locate and return an entry from the db.aCollSeq hash table. If the entry
-** specified by zName and nName is not found and parameter 'create' is
-** true, then create a new entry. Otherwise return NULL.
-**
-** Each pointer stored in the sqlite3.aCollSeq hash table contains an
-** array of three CollSeq structures. The first is the collation sequence
-** prefferred for UTF-8, the second UTF-16le, and the third UTF-16be.
-**
-** Stored immediately after the three collation sequences is a copy of
-** the collation sequence name. A pointer to this string is stored in
-** each collation sequence structure.
-*/
-static CollSeq *findCollSeqEntry(
- sqlite3 *db, /* Database connection */
- const char *zName, /* Name of the collating sequence */
- int create /* Create a new entry if true */
-){
- CollSeq *pColl;
- int nName = sqlite3Strlen30(zName);
- pColl = sqlite3HashFind(&db->aCollSeq, zName, nName);
-
- if( 0==pColl && create ){
- pColl = sqlite3DbMallocZero(db, 3*sizeof(*pColl) + nName + 1 );
- if( pColl ){
- CollSeq *pDel = 0;
- pColl[0].zName = (char*)&pColl[3];
- pColl[0].enc = SQLITE_UTF8;
- pColl[1].zName = (char*)&pColl[3];
- pColl[1].enc = SQLITE_UTF16LE;
- pColl[2].zName = (char*)&pColl[3];
- pColl[2].enc = SQLITE_UTF16BE;
- memcpy(pColl[0].zName, zName, nName);
- pColl[0].zName[nName] = 0;
- pDel = sqlite3HashInsert(&db->aCollSeq, pColl[0].zName, nName, pColl);
-
- /* If a malloc() failure occurred in sqlite3HashInsert(), it will
- ** return the pColl pointer to be deleted (because it wasn't added
- ** to the hash table).
- */
- assert( pDel==0 || pDel==pColl );
- if( pDel!=0 ){
- db->mallocFailed = 1;
- sqlite3DbFree(db, pDel);
- pColl = 0;
- }
- }
- }
- return pColl;
-}
-
-/*
-** Parameter zName points to a UTF-8 encoded string nName bytes long.
-** Return the CollSeq* pointer for the collation sequence named zName
-** for the encoding 'enc' from the database 'db'.
-**
-** If the entry specified is not found and 'create' is true, then create a
-** new entry. Otherwise return NULL.
-**
-** A separate function sqlite3LocateCollSeq() is a wrapper around
-** this routine. sqlite3LocateCollSeq() invokes the collation factory
-** if necessary and generates an error message if the collating sequence
-** cannot be found.
-**
-** See also: sqlite3LocateCollSeq(), sqlite3GetCollSeq()
-*/
-SQLITE_PRIVATE CollSeq *sqlite3FindCollSeq(
- sqlite3 *db,
- u8 enc,
- const char *zName,
- int create
-){
- CollSeq *pColl;
- if( zName ){
- pColl = findCollSeqEntry(db, zName, create);
- }else{
- pColl = db->pDfltColl;
- }
- assert( SQLITE_UTF8==1 && SQLITE_UTF16LE==2 && SQLITE_UTF16BE==3 );
- assert( enc>=SQLITE_UTF8 && enc<=SQLITE_UTF16BE );
- if( pColl ) pColl += enc-1;
- return pColl;
-}
-
-/* During the search for the best function definition, this procedure
-** is called to test how well the function passed as the first argument
-** matches the request for a function with nArg arguments in a system
-** that uses encoding enc. The value returned indicates how well the
-** request is matched. A higher value indicates a better match.
-**
-** The returned value is always between 0 and 6, as follows:
-**
-** 0: Not a match, or if nArg<0 and the function is has no implementation.
-** 1: A variable arguments function that prefers UTF-8 when a UTF-16
-** encoding is requested, or vice versa.
-** 2: A variable arguments function that uses UTF-16BE when UTF-16LE is
-** requested, or vice versa.
-** 3: A variable arguments function using the same text encoding.
-** 4: A function with the exact number of arguments requested that
-** prefers UTF-8 when a UTF-16 encoding is requested, or vice versa.
-** 5: A function with the exact number of arguments requested that
-** prefers UTF-16LE when UTF-16BE is requested, or vice versa.
-** 6: An exact match.
-**
-*/
-static int matchQuality(FuncDef *p, int nArg, u8 enc){
- int match = 0;
- if( p->nArg==-1 || p->nArg==nArg
- || (nArg==-1 && (p->xFunc!=0 || p->xStep!=0))
- ){
- match = 1;
- if( p->nArg==nArg || nArg==-1 ){
- match = 4;
- }
- if( enc==p->iPrefEnc ){
- match += 2;
- }
- else if( (enc==SQLITE_UTF16LE && p->iPrefEnc==SQLITE_UTF16BE) ||
- (enc==SQLITE_UTF16BE && p->iPrefEnc==SQLITE_UTF16LE) ){
- match += 1;
- }
- }
- return match;
-}
-
-/*
-** Search a FuncDefHash for a function with the given name. Return
-** a pointer to the matching FuncDef if found, or 0 if there is no match.
-*/
-static FuncDef *functionSearch(
- FuncDefHash *pHash, /* Hash table to search */
- int h, /* Hash of the name */
- const char *zFunc, /* Name of function */
- int nFunc /* Number of bytes in zFunc */
-){
- FuncDef *p;
- for(p=pHash->a[h]; p; p=p->pHash){
- if( sqlite3StrNICmp(p->zName, zFunc, nFunc)==0 && p->zName[nFunc]==0 ){
- return p;
- }
- }
- return 0;
-}
-
-/*
-** Insert a new FuncDef into a FuncDefHash hash table.
-*/
-SQLITE_PRIVATE void sqlite3FuncDefInsert(
- FuncDefHash *pHash, /* The hash table into which to insert */
- FuncDef *pDef /* The function definition to insert */
-){
- FuncDef *pOther;
- int nName = sqlite3Strlen30(pDef->zName);
- u8 c1 = (u8)pDef->zName[0];
- int h = (sqlite3UpperToLower[c1] + nName) % ArraySize(pHash->a);
- pOther = functionSearch(pHash, h, pDef->zName, nName);
- if( pOther ){
- assert( pOther!=pDef && pOther->pNext!=pDef );
- pDef->pNext = pOther->pNext;
- pOther->pNext = pDef;
- }else{
- pDef->pNext = 0;
- pDef->pHash = pHash->a[h];
- pHash->a[h] = pDef;
- }
-}
-
-
-
-/*
-** Locate a user function given a name, a number of arguments and a flag
-** indicating whether the function prefers UTF-16 over UTF-8. Return a
-** pointer to the FuncDef structure that defines that function, or return
-** NULL if the function does not exist.
-**
-** If the createFlag argument is true, then a new (blank) FuncDef
-** structure is created and liked into the "db" structure if a
-** no matching function previously existed. When createFlag is true
-** and the nArg parameter is -1, then only a function that accepts
-** any number of arguments will be returned.
-**
-** If createFlag is false and nArg is -1, then the first valid
-** function found is returned. A function is valid if either xFunc
-** or xStep is non-zero.
-**
-** If createFlag is false, then a function with the required name and
-** number of arguments may be returned even if the eTextRep flag does not
-** match that requested.
-*/
-SQLITE_PRIVATE FuncDef *sqlite3FindFunction(
- sqlite3 *db, /* An open database */
- const char *zName, /* Name of the function. Not null-terminated */
- int nName, /* Number of characters in the name */
- int nArg, /* Number of arguments. -1 means any number */
- u8 enc, /* Preferred text encoding */
- int createFlag /* Create new entry if true and does not otherwise exist */
-){
- FuncDef *p; /* Iterator variable */
- FuncDef *pBest = 0; /* Best match found so far */
- int bestScore = 0; /* Score of best match */
- int h; /* Hash value */
-
-
- assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE );
- h = (sqlite3UpperToLower[(u8)zName[0]] + nName) % ArraySize(db->aFunc.a);
-
- /* First search for a match amongst the application-defined functions.
- */
- p = functionSearch(&db->aFunc, h, zName, nName);
- while( p ){
- int score = matchQuality(p, nArg, enc);
- if( score>bestScore ){
- pBest = p;
- bestScore = score;
- }
- p = p->pNext;
- }
-
- /* If no match is found, search the built-in functions.
- **
- ** Except, if createFlag is true, that means that we are trying to
- ** install a new function. Whatever FuncDef structure is returned will
- ** have fields overwritten with new information appropriate for the
- ** new function. But the FuncDefs for built-in functions are read-only.
- ** So we must not search for built-ins when creating a new function.
- */
- if( !createFlag && !pBest ){
- FuncDefHash *pHash = &GLOBAL(FuncDefHash, sqlite3GlobalFunctions);
- p = functionSearch(pHash, h, zName, nName);
- while( p ){
- int score = matchQuality(p, nArg, enc);
- if( score>bestScore ){
- pBest = p;
- bestScore = score;
- }
- p = p->pNext;
- }
- }
-
- /* If the createFlag parameter is true and the search did not reveal an
- ** exact match for the name, number of arguments and encoding, then add a
- ** new entry to the hash table and return it.
- */
- if( createFlag && (bestScore<6 || pBest->nArg!=nArg) &&
- (pBest = sqlite3DbMallocZero(db, sizeof(*pBest)+nName+1))!=0 ){
- pBest->zName = (char *)&pBest[1];
- pBest->nArg = (u16)nArg;
- pBest->iPrefEnc = enc;
- memcpy(pBest->zName, zName, nName);
- pBest->zName[nName] = 0;
- sqlite3FuncDefInsert(&db->aFunc, pBest);
- }
-
- if( pBest && (pBest->xStep || pBest->xFunc || createFlag) ){
- return pBest;
- }
- return 0;
-}
-
-/*
-** Free all resources held by the schema structure. The void* argument points
-** at a Schema struct. This function does not call sqlite3DbFree(db, ) on the
-** pointer itself, it just cleans up subsiduary resources (i.e. the contents
-** of the schema hash tables).
-**
-** The Schema.cache_size variable is not cleared.
-*/
-SQLITE_PRIVATE void sqlite3SchemaFree(void *p){
- Hash temp1;
- Hash temp2;
- HashElem *pElem;
- Schema *pSchema = (Schema *)p;
-
- temp1 = pSchema->tblHash;
- temp2 = pSchema->trigHash;
- sqlite3HashInit(&pSchema->trigHash);
- sqlite3HashClear(&pSchema->idxHash);
- for(pElem=sqliteHashFirst(&temp2); pElem; pElem=sqliteHashNext(pElem)){
- sqlite3DeleteTrigger(0, (Trigger*)sqliteHashData(pElem));
- }
- sqlite3HashClear(&temp2);
- sqlite3HashInit(&pSchema->tblHash);
- for(pElem=sqliteHashFirst(&temp1); pElem; pElem=sqliteHashNext(pElem)){
- Table *pTab = sqliteHashData(pElem);
- assert( pTab->dbMem==0 );
- sqlite3DeleteTable(pTab);
- }
- sqlite3HashClear(&temp1);
- pSchema->pSeqTab = 0;
- pSchema->flags &= ~DB_SchemaLoaded;
-}
-
-/*
-** Find and return the schema associated with a BTree. Create
-** a new one if necessary.
-*/
-SQLITE_PRIVATE Schema *sqlite3SchemaGet(sqlite3 *db, Btree *pBt){
- Schema * p;
- if( pBt ){
- p = (Schema *)sqlite3BtreeSchema(pBt, sizeof(Schema), sqlite3SchemaFree);
- }else{
- p = (Schema *)sqlite3MallocZero(sizeof(Schema));
- }
- if( !p ){
- db->mallocFailed = 1;
- }else if ( 0==p->file_format ){
- sqlite3HashInit(&p->tblHash);
- sqlite3HashInit(&p->idxHash);
- sqlite3HashInit(&p->trigHash);
- p->enc = SQLITE_UTF8;
- }
- return p;
-}
-
-/************** End of callback.c ********************************************/
-/************** Begin file delete.c ******************************************/
-/*
-** 2001 September 15
-**
-** 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 C code routines that are called by the parser
-** in order to generate code for DELETE FROM statements.
-**
-** $Id: delete.c,v 1.207 2009/08/08 18:01:08 drh Exp $
-*/
-
-/*
-** Look up every table that is named in pSrc. If any table is not found,
-** add an error message to pParse->zErrMsg and return NULL. If all tables
-** are found, return a pointer to the last table.
-*/
-SQLITE_PRIVATE Table *sqlite3SrcListLookup(Parse *pParse, SrcList *pSrc){
- struct SrcList_item *pItem = pSrc->a;
- Table *pTab;
- assert( pItem && pSrc->nSrc==1 );
- pTab = sqlite3LocateTable(pParse, 0, pItem->zName, pItem->zDatabase);
- sqlite3DeleteTable(pItem->pTab);
- pItem->pTab = pTab;
- if( pTab ){
- pTab->nRef++;
- }
- if( sqlite3IndexedByLookup(pParse, pItem) ){
- pTab = 0;
- }
- return pTab;
-}
-
-/*
-** Check to make sure the given table is writable. If it is not
-** writable, generate an error message and return 1. If it is
-** writable return 0;
-*/
-SQLITE_PRIVATE int sqlite3IsReadOnly(Parse *pParse, Table *pTab, int viewOk){
- /* A table is not writable under the following circumstances:
- **
- ** 1) It is a virtual table and no implementation of the xUpdate method
- ** has been provided, or
- ** 2) It is a system table (i.e. sqlite_master), this call is not
- ** part of a nested parse and writable_schema pragma has not
- ** been specified.
- **
- ** In either case leave an error message in pParse and return non-zero.
- */
- if( ( IsVirtual(pTab)
- && sqlite3GetVTable(pParse->db, pTab)->pMod->pModule->xUpdate==0 )
- || ( (pTab->tabFlags & TF_Readonly)!=0
- && (pParse->db->flags & SQLITE_WriteSchema)==0
- && pParse->nested==0 )
- ){
- sqlite3ErrorMsg(pParse, "table %s may not be modified", pTab->zName);
- return 1;
- }
-
-#ifndef SQLITE_OMIT_VIEW
- if( !viewOk && pTab->pSelect ){
- sqlite3ErrorMsg(pParse,"cannot modify %s because it is a view",pTab->zName);
- return 1;
- }
-#endif
- return 0;
-}
-
-
-#if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER)
-/*
-** Evaluate a view and store its result in an ephemeral table. The
-** pWhere argument is an optional WHERE clause that restricts the
-** set of rows in the view that are to be added to the ephemeral table.
-*/
-SQLITE_PRIVATE void sqlite3MaterializeView(
- Parse *pParse, /* Parsing context */
- Table *pView, /* View definition */
- Expr *pWhere, /* Optional WHERE clause to be added */
- int iCur /* Cursor number for ephemerial table */
-){
- SelectDest dest;
- Select *pDup;
- sqlite3 *db = pParse->db;
-
- pDup = sqlite3SelectDup(db, pView->pSelect, 0);
- if( pWhere ){
- SrcList *pFrom;
-
- pWhere = sqlite3ExprDup(db, pWhere, 0);
- pFrom = sqlite3SrcListAppend(db, 0, 0, 0);
- if( pFrom ){
- assert( pFrom->nSrc==1 );
- pFrom->a[0].zAlias = sqlite3DbStrDup(db, pView->zName);
- pFrom->a[0].pSelect = pDup;
- assert( pFrom->a[0].pOn==0 );
- assert( pFrom->a[0].pUsing==0 );
- }else{
- sqlite3SelectDelete(db, pDup);
- }
- pDup = sqlite3SelectNew(pParse, 0, pFrom, pWhere, 0, 0, 0, 0, 0, 0);
- }
- sqlite3SelectDestInit(&dest, SRT_EphemTab, iCur);
- sqlite3Select(pParse, pDup, &dest);
- sqlite3SelectDelete(db, pDup);
-}
-#endif /* !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER) */
-
-#if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY)
-/*
-** Generate an expression tree to implement the WHERE, ORDER BY,
-** and LIMIT/OFFSET portion of DELETE and UPDATE statements.
-**
-** DELETE FROM table_wxyz WHERE a<5 ORDER BY a LIMIT 1;
-** \__________________________/
-** pLimitWhere (pInClause)
-*/
-SQLITE_PRIVATE Expr *sqlite3LimitWhere(
- Parse *pParse, /* The parser context */
- SrcList *pSrc, /* the FROM clause -- which tables to scan */
- Expr *pWhere, /* The WHERE clause. May be null */
- ExprList *pOrderBy, /* The ORDER BY clause. May be null */
- Expr *pLimit, /* The LIMIT clause. May be null */
- Expr *pOffset, /* The OFFSET clause. May be null */
- char *zStmtType /* Either DELETE or UPDATE. For error messages. */
-){
- Expr *pWhereRowid = NULL; /* WHERE rowid .. */
- Expr *pInClause = NULL; /* WHERE rowid IN ( select ) */
- Expr *pSelectRowid = NULL; /* SELECT rowid ... */
- ExprList *pEList = NULL; /* Expression list contaning only pSelectRowid */
- SrcList *pSelectSrc = NULL; /* SELECT rowid FROM x ... (dup of pSrc) */
- Select *pSelect = NULL; /* Complete SELECT tree */
-
- /* Check that there isn't an ORDER BY without a LIMIT clause.
- */
- if( pOrderBy && (pLimit == 0) ) {
- sqlite3ErrorMsg(pParse, "ORDER BY without LIMIT on %s", zStmtType);
- pParse->parseError = 1;
- goto limit_where_cleanup_2;
- }
-
- /* We only need to generate a select expression if there
- ** is a limit/offset term to enforce.
- */
- if( pLimit == 0 ) {
- /* if pLimit is null, pOffset will always be null as well. */
- assert( pOffset == 0 );
- return pWhere;
- }
-
- /* Generate a select expression tree to enforce the limit/offset
- ** term for the DELETE or UPDATE statement. For example:
- ** DELETE FROM table_a WHERE col1=1 ORDER BY col2 LIMIT 1 OFFSET 1
- ** becomes:
- ** DELETE FROM table_a WHERE rowid IN (
- ** SELECT rowid FROM table_a WHERE col1=1 ORDER BY col2 LIMIT 1 OFFSET 1
- ** );
- */
-
- pSelectRowid = sqlite3PExpr(pParse, TK_ROW, 0, 0, 0);
- if( pSelectRowid == 0 ) goto limit_where_cleanup_2;
- pEList = sqlite3ExprListAppend(pParse, 0, pSelectRowid);
- if( pEList == 0 ) goto limit_where_cleanup_2;
-
- /* duplicate the FROM clause as it is needed by both the DELETE/UPDATE tree
- ** and the SELECT subtree. */
- pSelectSrc = sqlite3SrcListDup(pParse->db, pSrc, 0);
- if( pSelectSrc == 0 ) {
- sqlite3ExprListDelete(pParse->db, pEList);
- goto limit_where_cleanup_2;
- }
-
- /* generate the SELECT expression tree. */
- pSelect = sqlite3SelectNew(pParse,pEList,pSelectSrc,pWhere,0,0,
- pOrderBy,0,pLimit,pOffset);
- if( pSelect == 0 ) return 0;
-
- /* now generate the new WHERE rowid IN clause for the DELETE/UDPATE */
- pWhereRowid = sqlite3PExpr(pParse, TK_ROW, 0, 0, 0);
- if( pWhereRowid == 0 ) goto limit_where_cleanup_1;
- pInClause = sqlite3PExpr(pParse, TK_IN, pWhereRowid, 0, 0);
- if( pInClause == 0 ) goto limit_where_cleanup_1;
-
- pInClause->x.pSelect = pSelect;
- pInClause->flags |= EP_xIsSelect;
- sqlite3ExprSetHeight(pParse, pInClause);
- return pInClause;
-
- /* something went wrong. clean up anything allocated. */
-limit_where_cleanup_1:
- sqlite3SelectDelete(pParse->db, pSelect);
- return 0;
-
-limit_where_cleanup_2:
- sqlite3ExprDelete(pParse->db, pWhere);
- sqlite3ExprListDelete(pParse->db, pOrderBy);
- sqlite3ExprDelete(pParse->db, pLimit);
- sqlite3ExprDelete(pParse->db, pOffset);
- return 0;
-}
-#endif /* defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY) */
-
-/*
-** Generate code for a DELETE FROM statement.
-**
-** DELETE FROM table_wxyz WHERE a<5 AND b NOT NULL;
-** \________/ \________________/
-** pTabList pWhere
-*/
-SQLITE_PRIVATE void sqlite3DeleteFrom(
- Parse *pParse, /* The parser context */
- SrcList *pTabList, /* The table from which we should delete things */
- Expr *pWhere /* The WHERE clause. May be null */
-){
- Vdbe *v; /* The virtual database engine */
- Table *pTab; /* The table from which records will be deleted */
- const char *zDb; /* Name of database holding pTab */
- int end, addr = 0; /* A couple addresses of generated code */
- int i; /* Loop counter */
- WhereInfo *pWInfo; /* Information about the WHERE clause */
- Index *pIdx; /* For looping over indices of the table */
- int iCur; /* VDBE Cursor number for pTab */
- sqlite3 *db; /* Main database structure */
- AuthContext sContext; /* Authorization context */
- NameContext sNC; /* Name context to resolve expressions in */
- int iDb; /* Database number */
- int memCnt = -1; /* Memory cell used for change counting */
- int rcauth; /* Value returned by authorization callback */
-
-#ifndef SQLITE_OMIT_TRIGGER
- int isView; /* True if attempting to delete from a view */
- Trigger *pTrigger; /* List of table triggers, if required */
-#endif
-
- memset(&sContext, 0, sizeof(sContext));
- db = pParse->db;
- if( pParse->nErr || db->mallocFailed ){
- goto delete_from_cleanup;
- }
- assert( pTabList->nSrc==1 );
-
- /* Locate the table which we want to delete. This table has to be
- ** put in an SrcList structure because some of the subroutines we
- ** will be calling are designed to work with multiple tables and expect
- ** an SrcList* parameter instead of just a Table* parameter.
- */
- pTab = sqlite3SrcListLookup(pParse, pTabList);
- if( pTab==0 ) goto delete_from_cleanup;
-
- /* Figure out if we have any triggers and if the table being
- ** deleted from is a view
- */
-#ifndef SQLITE_OMIT_TRIGGER
- pTrigger = sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0);
- isView = pTab->pSelect!=0;
-#else
-# define pTrigger 0
-# define isView 0
-#endif
-#ifdef SQLITE_OMIT_VIEW
-# undef isView
-# define isView 0
-#endif
-
- /* If pTab is really a view, make sure it has been initialized.
- */
- if( sqlite3ViewGetColumnNames(pParse, pTab) ){
- goto delete_from_cleanup;
- }
-
- if( sqlite3IsReadOnly(pParse, pTab, (pTrigger?1:0)) ){
- goto delete_from_cleanup;
- }
- iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
- assert( iDb<db->nDb );
- zDb = db->aDb[iDb].zName;
- rcauth = sqlite3AuthCheck(pParse, SQLITE_DELETE, pTab->zName, 0, zDb);
- assert( rcauth==SQLITE_OK || rcauth==SQLITE_DENY || rcauth==SQLITE_IGNORE );
- if( rcauth==SQLITE_DENY ){
- goto delete_from_cleanup;
- }
- assert(!isView || pTrigger);
-
- /* Assign cursor number to the table and all its indices.
- */
- assert( pTabList->nSrc==1 );
- iCur = pTabList->a[0].iCursor = pParse->nTab++;
- for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
- pParse->nTab++;
- }
-
- /* Start the view context
- */
- if( isView ){
- sqlite3AuthContextPush(pParse, &sContext, pTab->zName);
- }
-
- /* Begin generating code.
- */
- v = sqlite3GetVdbe(pParse);
- if( v==0 ){
- goto delete_from_cleanup;
- }
- if( pParse->nested==0 ) sqlite3VdbeCountChanges(v);
- sqlite3BeginWriteOperation(pParse, (pTrigger?1:0), iDb);
-
- /* If we are trying to delete from a view, realize that view into
- ** a ephemeral table.
- */
-#if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER)
- if( isView ){
- sqlite3MaterializeView(pParse, pTab, pWhere, iCur);
- }
-#endif
-
- /* Resolve the column names in the WHERE clause.
- */
- memset(&sNC, 0, sizeof(sNC));
- sNC.pParse = pParse;
- sNC.pSrcList = pTabList;
- if( sqlite3ResolveExprNames(&sNC, pWhere) ){
- goto delete_from_cleanup;
- }
-
- /* Initialize the counter of the number of rows deleted, if
- ** we are counting rows.
- */
- if( db->flags & SQLITE_CountRows ){
- memCnt = ++pParse->nMem;
- sqlite3VdbeAddOp2(v, OP_Integer, 0, memCnt);
- }
-
-#ifndef SQLITE_OMIT_TRUNCATE_OPTIMIZATION
- /* Special case: A DELETE without a WHERE clause deletes everything.
- ** It is easier just to erase the whole table. Prior to version 3.6.5,
- ** this optimization caused the row change count (the value returned by
- ** API function sqlite3_count_changes) to be set incorrectly. */
- if( rcauth==SQLITE_OK && pWhere==0 && !pTrigger && !IsVirtual(pTab) ){
- assert( !isView );
- sqlite3VdbeAddOp4(v, OP_Clear, pTab->tnum, iDb, memCnt,
- pTab->zName, P4_STATIC);
- for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
- assert( pIdx->pSchema==pTab->pSchema );
- sqlite3VdbeAddOp2(v, OP_Clear, pIdx->tnum, iDb);
- }
- }else
-#endif /* SQLITE_OMIT_TRUNCATE_OPTIMIZATION */
- /* The usual case: There is a WHERE clause so we have to scan through
- ** the table and pick which records to delete.
- */
- {
- int iRowSet = ++pParse->nMem; /* Register for rowset of rows to delete */
- int iRowid = ++pParse->nMem; /* Used for storing rowid values. */
- int regRowid; /* Actual register containing rowids */
-
- /* Collect rowids of every row to be deleted.
- */
- sqlite3VdbeAddOp2(v, OP_Null, 0, iRowSet);
- pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere,0,WHERE_DUPLICATES_OK);
- if( pWInfo==0 ) goto delete_from_cleanup;
- regRowid = sqlite3ExprCodeGetColumn(pParse, pTab, -1, iCur, iRowid, 0);
- sqlite3VdbeAddOp2(v, OP_RowSetAdd, iRowSet, regRowid);
- if( db->flags & SQLITE_CountRows ){
- sqlite3VdbeAddOp2(v, OP_AddImm, memCnt, 1);
- }
- sqlite3WhereEnd(pWInfo);
-
- /* Delete every item whose key was written to the list during the
- ** database scan. We have to delete items after the scan is complete
- ** because deleting an item can change the scan order. */
- end = sqlite3VdbeMakeLabel(v);
-
- /* Unless this is a view, open cursors for the table we are
- ** deleting from and all its indices. If this is a view, then the
- ** only effect this statement has is to fire the INSTEAD OF
- ** triggers. */
- if( !isView ){
- sqlite3OpenTableAndIndices(pParse, pTab, iCur, OP_OpenWrite);
- }
-
- addr = sqlite3VdbeAddOp3(v, OP_RowSetRead, iRowSet, end, iRowid);
-
- /* Delete the row */
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- if( IsVirtual(pTab) ){
- const char *pVTab = (const char *)sqlite3GetVTable(db, pTab);
- sqlite3VtabMakeWritable(pParse, pTab);
- sqlite3VdbeAddOp4(v, OP_VUpdate, 0, 1, iRowid, pVTab, P4_VTAB);
- sqlite3MayAbort(pParse);
- }else
-#endif
- {
- int count = (pParse->nested==0); /* True to count changes */
- sqlite3GenerateRowDelete(pParse, pTab, iCur, iRowid, count, pTrigger, OE_Default);
- }
-
- /* End of the delete loop */
- sqlite3VdbeAddOp2(v, OP_Goto, 0, addr);
- sqlite3VdbeResolveLabel(v, end);
-
- /* Close the cursors open on the table and its indexes. */
- if( !isView && !IsVirtual(pTab) ){
- for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
- sqlite3VdbeAddOp2(v, OP_Close, iCur + i, pIdx->tnum);
- }
- sqlite3VdbeAddOp1(v, OP_Close, iCur);
- }
- }
-
- /* Update the sqlite_sequence table by storing the content of the
- ** maximum rowid counter values recorded while inserting into
- ** autoincrement tables.
- */
- if( pParse->nested==0 && pParse->pTriggerTab==0 ){
- sqlite3AutoincrementEnd(pParse);
- }
-
- /* Return the number of rows that were deleted. If this routine is
- ** generating code because of a call to sqlite3NestedParse(), do not
- ** invoke the callback function.
- */
- if( (db->flags&SQLITE_CountRows) && !pParse->nested && !pParse->pTriggerTab ){
- sqlite3VdbeAddOp2(v, OP_ResultRow, memCnt, 1);
- sqlite3VdbeSetNumCols(v, 1);
- sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows deleted", SQLITE_STATIC);
- }
-
-delete_from_cleanup:
- sqlite3AuthContextPop(&sContext);
- sqlite3SrcListDelete(db, pTabList);
- sqlite3ExprDelete(db, pWhere);
- return;
-}
-
-/*
-** This routine generates VDBE code that causes a single row of a
-** single table to be deleted.
-**
-** The VDBE must be in a particular state when this routine is called.
-** These are the requirements:
-**
-** 1. A read/write cursor pointing to pTab, the table containing the row
-** to be deleted, must be opened as cursor number "base".
-**
-** 2. Read/write cursors for all indices of pTab must be open as
-** cursor number base+i for the i-th index.
-**
-** 3. The record number of the row to be deleted must be stored in
-** memory cell iRowid.
-**
-** This routine generates code to remove both the table record and all
-** index entries that point to that record.
-*/
-SQLITE_PRIVATE void sqlite3GenerateRowDelete(
- Parse *pParse, /* Parsing context */
- Table *pTab, /* Table containing the row to be deleted */
- int iCur, /* Cursor number for the table */
- int iRowid, /* Memory cell that contains the rowid to delete */
- int count, /* If non-zero, increment the row change counter */
- Trigger *pTrigger, /* List of triggers to (potentially) fire */
- int onconf /* Default ON CONFLICT policy for triggers */
-){
- Vdbe *v = pParse->pVdbe; /* Vdbe */
- int iOld = 0; /* First register in OLD.* array */
- int iLabel; /* Label resolved to end of generated code */
-
- /* Vdbe is guaranteed to have been allocated by this stage. */
- assert( v );
-
- /* Seek cursor iCur to the row to delete. If this row no longer exists
- ** (this can happen if a trigger program has already deleted it), do
- ** not attempt to delete it or fire any DELETE triggers. */
- iLabel = sqlite3VdbeMakeLabel(v);
- sqlite3VdbeAddOp3(v, OP_NotExists, iCur, iLabel, iRowid);
-
- /* If there are any triggers to fire, allocate a range of registers to
- ** use for the old.* references in the triggers. */
- if( pTrigger ){
- u32 mask; /* Mask of OLD.* columns in use */
- int iCol; /* Iterator used while populating OLD.* */
-
- /* TODO: Could use temporary registers here. Also could attempt to
- ** avoid copying the contents of the rowid register. */
- mask = sqlite3TriggerOldmask(pParse, pTrigger, TK_DELETE, 0, pTab, onconf);
- iOld = pParse->nMem+1;
- pParse->nMem += (1 + pTab->nCol);
-
- /* Populate the OLD.* pseudo-table register array. These values will be
- ** used by any BEFORE and AFTER triggers that exist. */
- sqlite3VdbeAddOp2(v, OP_Copy, iRowid, iOld);
- for(iCol=0; iCol<pTab->nCol; iCol++){
- if( mask==0xffffffff || mask&(1<<iCol) ){
- int iTarget = iOld + iCol + 1;
- sqlite3VdbeAddOp3(v, OP_Column, iCur, iCol, iTarget);
- sqlite3ColumnDefault(v, pTab, iCol, iTarget);
- }
- }
-
- /* Invoke any BEFORE trigger programs */
- sqlite3CodeRowTrigger(pParse, pTrigger,
- TK_DELETE, 0, TRIGGER_BEFORE, pTab, -1, iOld, onconf, iLabel
- );
-
- /* Seek the cursor to the row to be deleted again. It may be that
- ** the BEFORE triggers coded above have already removed the row
- ** being deleted. Do not attempt to delete the row a second time, and
- ** do not fire AFTER triggers. */
- sqlite3VdbeAddOp3(v, OP_NotExists, iCur, iLabel, iRowid);
- }
-
- /* Delete the index and table entries. Skip this step if pTab is really
- ** a view (in which case the only effect of the DELETE statement is to
- ** fire the INSTEAD OF triggers). */
- if( pTab->pSelect==0 ){
- sqlite3GenerateRowIndexDelete(pParse, pTab, iCur, 0);
- sqlite3VdbeAddOp2(v, OP_Delete, iCur, (count?OPFLAG_NCHANGE:0));
- if( count ){
- sqlite3VdbeChangeP4(v, -1, pTab->zName, P4_STATIC);
- }
- }
-
- /* Invoke AFTER triggers. */
- if( pTrigger ){
- sqlite3CodeRowTrigger(pParse, pTrigger,
- TK_DELETE, 0, TRIGGER_AFTER, pTab, -1, iOld, onconf, iLabel
- );
- }
-
- /* Jump here if the row had already been deleted before any BEFORE
- ** trigger programs were invoked. Or if a trigger program throws a
- ** RAISE(IGNORE) exception. */
- sqlite3VdbeResolveLabel(v, iLabel);
-}
-
-/*
-** This routine generates VDBE code that causes the deletion of all
-** index entries associated with a single row of a single table.
-**
-** The VDBE must be in a particular state when this routine is called.
-** These are the requirements:
-**
-** 1. A read/write cursor pointing to pTab, the table containing the row
-** to be deleted, must be opened as cursor number "iCur".
-**
-** 2. Read/write cursors for all indices of pTab must be open as
-** cursor number iCur+i for the i-th index.
-**
-** 3. The "iCur" cursor must be pointing to the row that is to be
-** deleted.
-*/
-SQLITE_PRIVATE void sqlite3GenerateRowIndexDelete(
- Parse *pParse, /* Parsing and code generating context */
- Table *pTab, /* Table containing the row to be deleted */
- int iCur, /* Cursor number for the table */
- int *aRegIdx /* Only delete if aRegIdx!=0 && aRegIdx[i]>0 */
-){
- int i;
- Index *pIdx;
- int r1;
-
- for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
- if( aRegIdx!=0 && aRegIdx[i-1]==0 ) continue;
- r1 = sqlite3GenerateIndexKey(pParse, pIdx, iCur, 0, 0);
- sqlite3VdbeAddOp3(pParse->pVdbe, OP_IdxDelete, iCur+i, r1,pIdx->nColumn+1);
- }
-}
-
-/*
-** Generate code that will assemble an index key and put it in register
-** regOut. The key with be for index pIdx which is an index on pTab.
-** iCur is the index of a cursor open on the pTab table and pointing to
-** the entry that needs indexing.
-**
-** Return a register number which is the first in a block of
-** registers that holds the elements of the index key. The
-** block of registers has already been deallocated by the time
-** this routine returns.
-*/
-SQLITE_PRIVATE int sqlite3GenerateIndexKey(
- Parse *pParse, /* Parsing context */
- Index *pIdx, /* The index for which to generate a key */
- int iCur, /* Cursor number for the pIdx->pTable table */
- int regOut, /* Write the new index key to this register */
- int doMakeRec /* Run the OP_MakeRecord instruction if true */
-){
- Vdbe *v = pParse->pVdbe;
- int j;
- Table *pTab = pIdx->pTable;
- int regBase;
- int nCol;
-
- nCol = pIdx->nColumn;
- regBase = sqlite3GetTempRange(pParse, nCol+1);
- sqlite3VdbeAddOp2(v, OP_Rowid, iCur, regBase+nCol);
- for(j=0; j<nCol; j++){
- int idx = pIdx->aiColumn[j];
- if( idx==pTab->iPKey ){
- sqlite3VdbeAddOp2(v, OP_SCopy, regBase+nCol, regBase+j);
- }else{
- sqlite3VdbeAddOp3(v, OP_Column, iCur, idx, regBase+j);
- sqlite3ColumnDefault(v, pTab, idx, -1);
- }
- }
- if( doMakeRec ){
- sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol+1, regOut);
- sqlite3VdbeChangeP4(v, -1, sqlite3IndexAffinityStr(v, pIdx), 0);
- sqlite3ExprCacheAffinityChange(pParse, regBase, nCol+1);
- }
- sqlite3ReleaseTempRange(pParse, regBase, nCol+1);
- return regBase;
-}
-
-/* Make sure "isView" gets undefined in case this file becomes part of
-** the amalgamation - so that subsequent files do not see isView as a
-** macro. */
-#undef isView
-
-/************** End of delete.c **********************************************/
-/************** Begin file func.c ********************************************/
-/*
-** 2002 February 23
-**
-** 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 C functions that implement various SQL
-** functions of SQLite.
-**
-** There is only one exported symbol in this file - the function
-** sqliteRegisterBuildinFunctions() found at the bottom of the file.
-** All other code has file scope.
-*/
-
-/*
-** Return the collating function associated with a function.
-*/
-static CollSeq *sqlite3GetFuncCollSeq(sqlite3_context *context){
- return context->pColl;
-}
-
-/*
-** Implementation of the non-aggregate min() and max() functions
-*/
-static void minmaxFunc(
- sqlite3_context *context,
- int argc,
- sqlite3_value **argv
-){
- int i;
- int mask; /* 0 for min() or 0xffffffff for max() */
- int iBest;
- CollSeq *pColl;
-
- assert( argc>1 );
- mask = sqlite3_user_data(context)==0 ? 0 : -1;
- pColl = sqlite3GetFuncCollSeq(context);
- assert( pColl );
- assert( mask==-1 || mask==0 );
- iBest = 0;
- if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
- for(i=1; i<argc; i++){
- if( sqlite3_value_type(argv[i])==SQLITE_NULL ) return;
- if( (sqlite3MemCompare(argv[iBest], argv[i], pColl)^mask)>=0 ){
- testcase( mask==0 );
- iBest = i;
- }
- }
- sqlite3_result_value(context, argv[iBest]);
-}
-
-/*
-** Return the type of the argument.
-*/
-static void typeofFunc(
- sqlite3_context *context,
- int NotUsed,
- sqlite3_value **argv
-){
- const char *z = 0;
- UNUSED_PARAMETER(NotUsed);
- switch( sqlite3_value_type(argv[0]) ){
- case SQLITE_INTEGER: z = "integer"; break;
- case SQLITE_TEXT: z = "text"; break;
- case SQLITE_FLOAT: z = "real"; break;
- case SQLITE_BLOB: z = "blob"; break;
- default: z = "null"; break;
- }
- sqlite3_result_text(context, z, -1, SQLITE_STATIC);
-}
-
-
-/*
-** Implementation of the length() function
-*/
-static void lengthFunc(
- sqlite3_context *context,
- int argc,
- sqlite3_value **argv
-){
- int len;
-
- assert( argc==1 );
- UNUSED_PARAMETER(argc);
- switch( sqlite3_value_type(argv[0]) ){
- case SQLITE_BLOB:
- case SQLITE_INTEGER:
- case SQLITE_FLOAT: {
- sqlite3_result_int(context, sqlite3_value_bytes(argv[0]));
- break;
- }
- case SQLITE_TEXT: {
- const unsigned char *z = sqlite3_value_text(argv[0]);
- if( z==0 ) return;
- len = 0;
- while( *z ){
- len++;
- SQLITE_SKIP_UTF8(z);
- }
- sqlite3_result_int(context, len);
- break;
- }
- default: {
- sqlite3_result_null(context);
- break;
- }
- }
-}
-
-/*
-** Implementation of the abs() function
-*/
-static void absFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
- assert( argc==1 );
- UNUSED_PARAMETER(argc);
- switch( sqlite3_value_type(argv[0]) ){
- case SQLITE_INTEGER: {
- i64 iVal = sqlite3_value_int64(argv[0]);
- if( iVal<0 ){
- if( (iVal<<1)==0 ){
- sqlite3_result_error(context, "integer overflow", -1);
- return;
- }
- iVal = -iVal;
- }
- sqlite3_result_int64(context, iVal);
- break;
- }
- case SQLITE_NULL: {
- sqlite3_result_null(context);
- break;
- }
- default: {
- double rVal = sqlite3_value_double(argv[0]);
- if( rVal<0 ) rVal = -rVal;
- sqlite3_result_double(context, rVal);
- break;
- }
- }
-}
-
-/*
-** Implementation of the substr() function.
-**
-** substr(x,p1,p2) returns p2 characters of x[] beginning with p1.
-** p1 is 1-indexed. So substr(x,1,1) returns the first character
-** of x. If x is text, then we actually count UTF-8 characters.
-** If x is a blob, then we count bytes.
-**
-** If p1 is negative, then we begin abs(p1) from the end of x[].
-*/
-static void substrFunc(
- sqlite3_context *context,
- int argc,
- sqlite3_value **argv
-){
- const unsigned char *z;
- const unsigned char *z2;
- int len;
- int p0type;
- i64 p1, p2;
- int negP2 = 0;
-
- assert( argc==3 || argc==2 );
- if( sqlite3_value_type(argv[1])==SQLITE_NULL
- || (argc==3 && sqlite3_value_type(argv[2])==SQLITE_NULL)
- ){
- return;
- }
- p0type = sqlite3_value_type(argv[0]);
- if( p0type==SQLITE_BLOB ){
- len = sqlite3_value_bytes(argv[0]);
- z = sqlite3_value_blob(argv[0]);
- if( z==0 ) return;
- assert( len==sqlite3_value_bytes(argv[0]) );
- }else{
- z = sqlite3_value_text(argv[0]);
- if( z==0 ) return;
- len = 0;
- for(z2=z; *z2; len++){
- SQLITE_SKIP_UTF8(z2);
- }
- }
- p1 = sqlite3_value_int(argv[1]);
- if( argc==3 ){
- p2 = sqlite3_value_int(argv[2]);
- if( p2<0 ){
- p2 = -p2;
- negP2 = 1;
- }
- }else{
- p2 = sqlite3_context_db_handle(context)->aLimit[SQLITE_LIMIT_LENGTH];
- }
- if( p1<0 ){
- p1 += len;
- if( p1<0 ){
- p2 += p1;
- if( p2<0 ) p2 = 0;
- p1 = 0;
- }
- }else if( p1>0 ){
- p1--;
- }else if( p2>0 ){
- p2--;
- }
- if( negP2 ){
- p1 -= p2;
- if( p1<0 ){
- p2 += p1;
- p1 = 0;
- }
- }
- assert( p1>=0 && p2>=0 );
- if( p1+p2>len ){
- p2 = len-p1;
- if( p2<0 ) p2 = 0;
- }
- if( p0type!=SQLITE_BLOB ){
- while( *z && p1 ){
- SQLITE_SKIP_UTF8(z);
- p1--;
- }
- for(z2=z; *z2 && p2; p2--){
- SQLITE_SKIP_UTF8(z2);
- }
- sqlite3_result_text(context, (char*)z, (int)(z2-z), SQLITE_TRANSIENT);
- }else{
- sqlite3_result_blob(context, (char*)&z[p1], (int)p2, SQLITE_TRANSIENT);
- }
-}
-
-/*
-** Implementation of the round() function
-*/
-#ifndef SQLITE_OMIT_FLOATING_POINT
-static void roundFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
- int n = 0;
- double r;
- char *zBuf;
- assert( argc==1 || argc==2 );
- if( argc==2 ){
- if( SQLITE_NULL==sqlite3_value_type(argv[1]) ) return;
- n = sqlite3_value_int(argv[1]);
- if( n>30 ) n = 30;
- if( n<0 ) n = 0;
- }
- if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
- r = sqlite3_value_double(argv[0]);
- zBuf = sqlite3_mprintf("%.*f",n,r);
- if( zBuf==0 ){
- sqlite3_result_error_nomem(context);
- }else{
- sqlite3AtoF(zBuf, &r);
- sqlite3_free(zBuf);
- sqlite3_result_double(context, r);
- }
-}
-#endif
-
-/*
-** Allocate nByte bytes of space using sqlite3_malloc(). If the
-** allocation fails, call sqlite3_result_error_nomem() to notify
-** the database handle that malloc() has failed and return NULL.
-** If nByte is larger than the maximum string or blob length, then
-** raise an SQLITE_TOOBIG exception and return NULL.
-*/
-static void *contextMalloc(sqlite3_context *context, i64 nByte){
- char *z;
- sqlite3 *db = sqlite3_context_db_handle(context);
- assert( nByte>0 );
- testcase( nByte==db->aLimit[SQLITE_LIMIT_LENGTH] );
- testcase( nByte==db->aLimit[SQLITE_LIMIT_LENGTH]+1 );
- if( nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){
- sqlite3_result_error_toobig(context);
- z = 0;
- }else{
- z = sqlite3Malloc((int)nByte);
- if( !z ){
- sqlite3_result_error_nomem(context);
- }
- }
- return z;
-}
-
-/*
-** Implementation of the upper() and lower() SQL functions.
-*/
-static void upperFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
- char *z1;
- const char *z2;
- int i, n;
- UNUSED_PARAMETER(argc);
- z2 = (char*)sqlite3_value_text(argv[0]);
- n = sqlite3_value_bytes(argv[0]);
- /* Verify that the call to _bytes() does not invalidate the _text() pointer */
- assert( z2==(char*)sqlite3_value_text(argv[0]) );
- if( z2 ){
- z1 = contextMalloc(context, ((i64)n)+1);
- if( z1 ){
- memcpy(z1, z2, n+1);
- for(i=0; z1[i]; i++){
- z1[i] = (char)sqlite3Toupper(z1[i]);
- }
- sqlite3_result_text(context, z1, -1, sqlite3_free);
- }
- }
-}
-static void lowerFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
- u8 *z1;
- const char *z2;
- int i, n;
- UNUSED_PARAMETER(argc);
- z2 = (char*)sqlite3_value_text(argv[0]);
- n = sqlite3_value_bytes(argv[0]);
- /* Verify that the call to _bytes() does not invalidate the _text() pointer */
- assert( z2==(char*)sqlite3_value_text(argv[0]) );
- if( z2 ){
- z1 = contextMalloc(context, ((i64)n)+1);
- if( z1 ){
- memcpy(z1, z2, n+1);
- for(i=0; z1[i]; i++){
- z1[i] = sqlite3Tolower(z1[i]);
- }
- sqlite3_result_text(context, (char *)z1, -1, sqlite3_free);
- }
- }
-}
-
-/*
-** Implementation of the IFNULL(), NVL(), and COALESCE() functions.
-** All three do the same thing. They return the first non-NULL
-** argument.
-*/
-static void ifnullFunc(
- sqlite3_context *context,
- int argc,
- sqlite3_value **argv
-){
- int i;
- for(i=0; i<argc; i++){
- if( SQLITE_NULL!=sqlite3_value_type(argv[i]) ){
- sqlite3_result_value(context, argv[i]);
- break;
- }
- }
-}
-
-/*
-** Implementation of random(). Return a random integer.
-*/
-static void randomFunc(
- sqlite3_context *context,
- int NotUsed,
- sqlite3_value **NotUsed2
-){
- sqlite_int64 r;
- UNUSED_PARAMETER2(NotUsed, NotUsed2);
- sqlite3_randomness(sizeof(r), &r);
- if( r<0 ){
- /* We need to prevent a random number of 0x8000000000000000
- ** (or -9223372036854775808) since when you do abs() of that
- ** number of you get the same value back again. To do this
- ** in a way that is testable, mask the sign bit off of negative
- ** values, resulting in a positive value. Then take the
- ** 2s complement of that positive value. The end result can
- ** therefore be no less than -9223372036854775807.
- */
- r = -(r ^ (((sqlite3_int64)1)<<63));
- }
- sqlite3_result_int64(context, r);
-}
-
-/*
-** Implementation of randomblob(N). Return a random blob
-** that is N bytes long.
-*/
-static void randomBlob(
- sqlite3_context *context,
- int argc,
- sqlite3_value **argv
-){
- int n;
- unsigned char *p;
- assert( argc==1 );
- UNUSED_PARAMETER(argc);
- n = sqlite3_value_int(argv[0]);
- if( n<1 ){
- n = 1;
- }
- p = contextMalloc(context, n);
- if( p ){
- sqlite3_randomness(n, p);
- sqlite3_result_blob(context, (char*)p, n, sqlite3_free);
- }
-}
-
-/*
-** Implementation of the last_insert_rowid() SQL function. The return
-** value is the same as the sqlite3_last_insert_rowid() API function.
-*/
-static void last_insert_rowid(
- sqlite3_context *context,
- int NotUsed,
- sqlite3_value **NotUsed2
-){
- sqlite3 *db = sqlite3_context_db_handle(context);
- UNUSED_PARAMETER2(NotUsed, NotUsed2);
- sqlite3_result_int64(context, sqlite3_last_insert_rowid(db));
-}
-
-/*
-** Implementation of the changes() SQL function. The return value is the
-** same as the sqlite3_changes() API function.
-*/
-static void changes(
- sqlite3_context *context,
- int NotUsed,
- sqlite3_value **NotUsed2
-){
- sqlite3 *db = sqlite3_context_db_handle(context);
- UNUSED_PARAMETER2(NotUsed, NotUsed2);
- sqlite3_result_int(context, sqlite3_changes(db));
-}
-
-/*
-** Implementation of the total_changes() SQL function. The return value is
-** the same as the sqlite3_total_changes() API function.
-*/
-static void total_changes(
- sqlite3_context *context,
- int NotUsed,
- sqlite3_value **NotUsed2
-){
- sqlite3 *db = sqlite3_context_db_handle(context);
- UNUSED_PARAMETER2(NotUsed, NotUsed2);
- sqlite3_result_int(context, sqlite3_total_changes(db));
-}
-
-/*
-** A structure defining how to do GLOB-style comparisons.
-*/
-struct compareInfo {
- u8 matchAll;
- u8 matchOne;
- u8 matchSet;
- u8 noCase;
-};
-
-/*
-** For LIKE and GLOB matching on EBCDIC machines, assume that every
-** character is exactly one byte in size. Also, all characters are
-** able to participate in upper-case-to-lower-case mappings in EBCDIC
-** whereas only characters less than 0x80 do in ASCII.
-*/
-#if defined(SQLITE_EBCDIC)
-# define sqlite3Utf8Read(A,C) (*(A++))
-# define GlogUpperToLower(A) A = sqlite3UpperToLower[A]
-#else
-# define GlogUpperToLower(A) if( A<0x80 ){ A = sqlite3UpperToLower[A]; }
-#endif
-
-static const struct compareInfo globInfo = { '*', '?', '[', 0 };
-/* The correct SQL-92 behavior is for the LIKE operator to ignore
-** case. Thus 'a' LIKE 'A' would be true. */
-static const struct compareInfo likeInfoNorm = { '%', '_', 0, 1 };
-/* If SQLITE_CASE_SENSITIVE_LIKE is defined, then the LIKE operator
-** is case sensitive causing 'a' LIKE 'A' to be false */
-static const struct compareInfo likeInfoAlt = { '%', '_', 0, 0 };
-
-/*
-** Compare two UTF-8 strings for equality where the first string can
-** potentially be a "glob" expression. Return true (1) if they
-** are the same and false (0) if they are different.
-**
-** Globbing rules:
-**
-** '*' Matches any sequence of zero or more characters.
-**
-** '?' Matches exactly one character.
-**
-** [...] Matches one character from the enclosed list of
-** characters.
-**
-** [^...] Matches one character not in the enclosed list.
-**
-** With the [...] and [^...] matching, a ']' character can be included
-** in the list by making it the first character after '[' or '^'. A
-** range of characters can be specified using '-'. Example:
-** "[a-z]" matches any single lower-case letter. To match a '-', make
-** it the last character in the list.
-**
-** This routine is usually quick, but can be N**2 in the worst case.
-**
-** Hints: to match '*' or '?', put them in "[]". Like this:
-**
-** abc[*]xyz Matches "abc*xyz" only
-*/
-static int patternCompare(
- const u8 *zPattern, /* The glob pattern */
- const u8 *zString, /* The string to compare against the glob */
- const struct compareInfo *pInfo, /* Information about how to do the compare */
- const int esc /* The escape character */
-){
- int c, c2;
- int invert;
- int seen;
- u8 matchOne = pInfo->matchOne;
- u8 matchAll = pInfo->matchAll;
- u8 matchSet = pInfo->matchSet;
- u8 noCase = pInfo->noCase;
- int prevEscape = 0; /* True if the previous character was 'escape' */
-
- while( (c = sqlite3Utf8Read(zPattern,&zPattern))!=0 ){
- if( !prevEscape && c==matchAll ){
- while( (c=sqlite3Utf8Read(zPattern,&zPattern)) == matchAll
- || c == matchOne ){
- if( c==matchOne && sqlite3Utf8Read(zString, &zString)==0 ){
- return 0;
- }
- }
- if( c==0 ){
- return 1;
- }else if( c==esc ){
- c = sqlite3Utf8Read(zPattern, &zPattern);
- if( c==0 ){
- return 0;
- }
- }else if( c==matchSet ){
- assert( esc==0 ); /* This is GLOB, not LIKE */
- assert( matchSet<0x80 ); /* '[' is a single-byte character */
- while( *zString && patternCompare(&zPattern[-1],zString,pInfo,esc)==0 ){
- SQLITE_SKIP_UTF8(zString);
- }
- return *zString!=0;
- }
- while( (c2 = sqlite3Utf8Read(zString,&zString))!=0 ){
- if( noCase ){
- GlogUpperToLower(c2);
- GlogUpperToLower(c);
- while( c2 != 0 && c2 != c ){
- c2 = sqlite3Utf8Read(zString, &zString);
- GlogUpperToLower(c2);
- }
- }else{
- while( c2 != 0 && c2 != c ){
- c2 = sqlite3Utf8Read(zString, &zString);
- }
- }
- if( c2==0 ) return 0;
- if( patternCompare(zPattern,zString,pInfo,esc) ) return 1;
- }
- return 0;
- }else if( !prevEscape && c==matchOne ){
- if( sqlite3Utf8Read(zString, &zString)==0 ){
- return 0;
- }
- }else if( c==matchSet ){
- int prior_c = 0;
- assert( esc==0 ); /* This only occurs for GLOB, not LIKE */
- seen = 0;
- invert = 0;
- c = sqlite3Utf8Read(zString, &zString);
- if( c==0 ) return 0;
- c2 = sqlite3Utf8Read(zPattern, &zPattern);
- if( c2=='^' ){
- invert = 1;
- c2 = sqlite3Utf8Read(zPattern, &zPattern);
- }
- if( c2==']' ){
- if( c==']' ) seen = 1;
- c2 = sqlite3Utf8Read(zPattern, &zPattern);
- }
- while( c2 && c2!=']' ){
- if( c2=='-' && zPattern[0]!=']' && zPattern[0]!=0 && prior_c>0 ){
- c2 = sqlite3Utf8Read(zPattern, &zPattern);
- if( c>=prior_c && c<=c2 ) seen = 1;
- prior_c = 0;
- }else{
- if( c==c2 ){
- seen = 1;
- }
- prior_c = c2;
- }
- c2 = sqlite3Utf8Read(zPattern, &zPattern);
- }
- if( c2==0 || (seen ^ invert)==0 ){
- return 0;
- }
- }else if( esc==c && !prevEscape ){
- prevEscape = 1;
- }else{
- c2 = sqlite3Utf8Read(zString, &zString);
- if( noCase ){
- GlogUpperToLower(c);
- GlogUpperToLower(c2);
- }
- if( c!=c2 ){
- return 0;
- }
- prevEscape = 0;
- }
- }
- return *zString==0;
-}
-
-/*
-** Count the number of times that the LIKE operator (or GLOB which is
-** just a variation of LIKE) gets called. This is used for testing
-** only.
-*/
-#ifdef SQLITE_TEST
-SQLITE_API int sqlite3_like_count = 0;
-#endif
-
-
-/*
-** Implementation of the like() SQL function. This function implements
-** the build-in LIKE operator. The first argument to the function is the
-** pattern and the second argument is the string. So, the SQL statements:
-**
-** A LIKE B
-**
-** is implemented as like(B,A).
-**
-** This same function (with a different compareInfo structure) computes
-** the GLOB operator.
-*/
-static void likeFunc(
- sqlite3_context *context,
- int argc,
- sqlite3_value **argv
-){
- const unsigned char *zA, *zB;
- int escape = 0;
- int nPat;
- sqlite3 *db = sqlite3_context_db_handle(context);
-
- zB = sqlite3_value_text(argv[0]);
- zA = sqlite3_value_text(argv[1]);
-
- /* Limit the length of the LIKE or GLOB pattern to avoid problems
- ** of deep recursion and N*N behavior in patternCompare().
- */
- nPat = sqlite3_value_bytes(argv[0]);
- testcase( nPat==db->aLimit[SQLITE_LIMIT_LIKE_PATTERN_LENGTH] );
- testcase( nPat==db->aLimit[SQLITE_LIMIT_LIKE_PATTERN_LENGTH]+1 );
- if( nPat > db->aLimit[SQLITE_LIMIT_LIKE_PATTERN_LENGTH] ){
- sqlite3_result_error(context, "LIKE or GLOB pattern too complex", -1);
- return;
- }
- assert( zB==sqlite3_value_text(argv[0]) ); /* Encoding did not change */
-
- if( argc==3 ){
- /* The escape character string must consist of a single UTF-8 character.
- ** Otherwise, return an error.
- */
- const unsigned char *zEsc = sqlite3_value_text(argv[2]);
- if( zEsc==0 ) return;
- if( sqlite3Utf8CharLen((char*)zEsc, -1)!=1 ){
- sqlite3_result_error(context,
- "ESCAPE expression must be a single character", -1);
- return;
- }
- escape = sqlite3Utf8Read(zEsc, &zEsc);
- }
- if( zA && zB ){
- struct compareInfo *pInfo = sqlite3_user_data(context);
-#ifdef SQLITE_TEST
- sqlite3_like_count++;
-#endif
-
- sqlite3_result_int(context, patternCompare(zB, zA, pInfo, escape));
- }
-}
-
-/*
-** Implementation of the NULLIF(x,y) function. The result is the first
-** argument if the arguments are different. The result is NULL if the
-** arguments are equal to each other.
-*/
-static void nullifFunc(
- sqlite3_context *context,
- int NotUsed,
- sqlite3_value **argv
-){
- CollSeq *pColl = sqlite3GetFuncCollSeq(context);
- UNUSED_PARAMETER(NotUsed);
- if( sqlite3MemCompare(argv[0], argv[1], pColl)!=0 ){
- sqlite3_result_value(context, argv[0]);
- }
-}
-
-/*
-** Implementation of the sqlite_version() function. The result is the version
-** of the SQLite library that is running.
-*/
-static void versionFunc(
- sqlite3_context *context,
- int NotUsed,
- sqlite3_value **NotUsed2
-){
- UNUSED_PARAMETER2(NotUsed, NotUsed2);
- sqlite3_result_text(context, sqlite3_version, -1, SQLITE_STATIC);
-}
-
-/*
-** Implementation of the sqlite_source_id() function. The result is a string
-** that identifies the particular version of the source code used to build
-** SQLite.
-*/
-static void sourceidFunc(
- sqlite3_context *context,
- int NotUsed,
- sqlite3_value **NotUsed2
-){
- UNUSED_PARAMETER2(NotUsed, NotUsed2);
- sqlite3_result_text(context, SQLITE_SOURCE_ID, -1, SQLITE_STATIC);
-}
-
-/* Array for converting from half-bytes (nybbles) into ASCII hex
-** digits. */
-static const char hexdigits[] = {
- '0', '1', '2', '3', '4', '5', '6', '7',
- '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
-};
-
-/*
-** EXPERIMENTAL - This is not an official function. The interface may
-** change. This function may disappear. Do not write code that depends
-** on this function.
-**
-** Implementation of the QUOTE() function. This function takes a single
-** argument. If the argument is numeric, the return value is the same as
-** the argument. If the argument is NULL, the return value is the string
-** "NULL". Otherwise, the argument is enclosed in single quotes with
-** single-quote escapes.
-*/
-static void quoteFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
- assert( argc==1 );
- UNUSED_PARAMETER(argc);
- switch( sqlite3_value_type(argv[0]) ){
- case SQLITE_INTEGER:
- case SQLITE_FLOAT: {
- sqlite3_result_value(context, argv[0]);
- break;
- }
- case SQLITE_BLOB: {
- char *zText = 0;
- char const *zBlob = sqlite3_value_blob(argv[0]);
- int nBlob = sqlite3_value_bytes(argv[0]);
- assert( zBlob==sqlite3_value_blob(argv[0]) ); /* No encoding change */
- zText = (char *)contextMalloc(context, (2*(i64)nBlob)+4);
- if( zText ){
- int i;
- for(i=0; i<nBlob; i++){
- zText[(i*2)+2] = hexdigits[(zBlob[i]>>4)&0x0F];
- zText[(i*2)+3] = hexdigits[(zBlob[i])&0x0F];
- }
- zText[(nBlob*2)+2] = '\'';
- zText[(nBlob*2)+3] = '\0';
- zText[0] = 'X';
- zText[1] = '\'';
- sqlite3_result_text(context, zText, -1, SQLITE_TRANSIENT);
- sqlite3_free(zText);
- }
- break;
- }
- case SQLITE_TEXT: {
- int i,j;
- u64 n;
- const unsigned char *zArg = sqlite3_value_text(argv[0]);
- char *z;
-
- if( zArg==0 ) return;
- for(i=0, n=0; zArg[i]; i++){ if( zArg[i]=='\'' ) n++; }
- z = contextMalloc(context, ((i64)i)+((i64)n)+3);
- if( z ){
- z[0] = '\'';
- for(i=0, j=1; zArg[i]; i++){
- z[j++] = zArg[i];
- if( zArg[i]=='\'' ){
- z[j++] = '\'';
- }
- }
- z[j++] = '\'';
- z[j] = 0;
- sqlite3_result_text(context, z, j, sqlite3_free);
- }
- break;
- }
- default: {
- assert( sqlite3_value_type(argv[0])==SQLITE_NULL );
- sqlite3_result_text(context, "NULL", 4, SQLITE_STATIC);
- break;
- }
- }
-}
-
-/*
-** The hex() function. Interpret the argument as a blob. Return
-** a hexadecimal rendering as text.
-*/
-static void hexFunc(
- sqlite3_context *context,
- int argc,
- sqlite3_value **argv
-){
- int i, n;
- const unsigned char *pBlob;
- char *zHex, *z;
- assert( argc==1 );
- UNUSED_PARAMETER(argc);
- pBlob = sqlite3_value_blob(argv[0]);
- n = sqlite3_value_bytes(argv[0]);
- assert( pBlob==sqlite3_value_blob(argv[0]) ); /* No encoding change */
- z = zHex = contextMalloc(context, ((i64)n)*2 + 1);
- if( zHex ){
- for(i=0; i<n; i++, pBlob++){
- unsigned char c = *pBlob;
- *(z++) = hexdigits[(c>>4)&0xf];
- *(z++) = hexdigits[c&0xf];
- }
- *z = 0;
- sqlite3_result_text(context, zHex, n*2, sqlite3_free);
- }
-}
-
-/*
-** The zeroblob(N) function returns a zero-filled blob of size N bytes.
-*/
-static void zeroblobFunc(
- sqlite3_context *context,
- int argc,
- sqlite3_value **argv
-){
- i64 n;
- sqlite3 *db = sqlite3_context_db_handle(context);
- assert( argc==1 );
- UNUSED_PARAMETER(argc);
- n = sqlite3_value_int64(argv[0]);
- testcase( n==db->aLimit[SQLITE_LIMIT_LENGTH] );
- testcase( n==db->aLimit[SQLITE_LIMIT_LENGTH]+1 );
- if( n>db->aLimit[SQLITE_LIMIT_LENGTH] ){
- sqlite3_result_error_toobig(context);
- }else{
- sqlite3_result_zeroblob(context, (int)n);
- }
-}
-
-/*
-** The replace() function. Three arguments are all strings: call
-** them A, B, and C. The result is also a string which is derived
-** from A by replacing every occurance of B with C. The match
-** must be exact. Collating sequences are not used.
-*/
-static void replaceFunc(
- sqlite3_context *context,
- int argc,
- sqlite3_value **argv
-){
- const unsigned char *zStr; /* The input string A */
- const unsigned char *zPattern; /* The pattern string B */
- const unsigned char *zRep; /* The replacement string C */
- unsigned char *zOut; /* The output */
- int nStr; /* Size of zStr */
- int nPattern; /* Size of zPattern */
- int nRep; /* Size of zRep */
- i64 nOut; /* Maximum size of zOut */
- int loopLimit; /* Last zStr[] that might match zPattern[] */
- int i, j; /* Loop counters */
-
- assert( argc==3 );
- UNUSED_PARAMETER(argc);
- zStr = sqlite3_value_text(argv[0]);
- if( zStr==0 ) return;
- nStr = sqlite3_value_bytes(argv[0]);
- assert( zStr==sqlite3_value_text(argv[0]) ); /* No encoding change */
- zPattern = sqlite3_value_text(argv[1]);
- if( zPattern==0 ){
- assert( sqlite3_value_type(argv[1])==SQLITE_NULL
- || sqlite3_context_db_handle(context)->mallocFailed );
- return;
- }
- if( zPattern[0]==0 ){
- assert( sqlite3_value_type(argv[1])!=SQLITE_NULL );
- sqlite3_result_value(context, argv[0]);
- return;
- }
- nPattern = sqlite3_value_bytes(argv[1]);
- assert( zPattern==sqlite3_value_text(argv[1]) ); /* No encoding change */
- zRep = sqlite3_value_text(argv[2]);
- if( zRep==0 ) return;
- nRep = sqlite3_value_bytes(argv[2]);
- assert( zRep==sqlite3_value_text(argv[2]) );
- nOut = nStr + 1;
- assert( nOut<SQLITE_MAX_LENGTH );
- zOut = contextMalloc(context, (i64)nOut);
- if( zOut==0 ){
- return;
- }
- loopLimit = nStr - nPattern;
- for(i=j=0; i<=loopLimit; i++){
- if( zStr[i]!=zPattern[0] || memcmp(&zStr[i], zPattern, nPattern) ){
- zOut[j++] = zStr[i];
- }else{
- u8 *zOld;
- sqlite3 *db = sqlite3_context_db_handle(context);
- nOut += nRep - nPattern;
- testcase( nOut-1==db->aLimit[SQLITE_LIMIT_LENGTH] );
- testcase( nOut-2==db->aLimit[SQLITE_LIMIT_LENGTH] );
- if( nOut-1>db->aLimit[SQLITE_LIMIT_LENGTH] ){
- sqlite3_result_error_toobig(context);
- sqlite3DbFree(db, zOut);
- return;
- }
- zOld = zOut;
- zOut = sqlite3_realloc(zOut, (int)nOut);
- if( zOut==0 ){
- sqlite3_result_error_nomem(context);
- sqlite3DbFree(db, zOld);
- return;
- }
- memcpy(&zOut[j], zRep, nRep);
- j += nRep;
- i += nPattern-1;
- }
- }
- assert( j+nStr-i+1==nOut );
- memcpy(&zOut[j], &zStr[i], nStr-i);
- j += nStr - i;
- assert( j<=nOut );
- zOut[j] = 0;
- sqlite3_result_text(context, (char*)zOut, j, sqlite3_free);
-}
-
-/*
-** Implementation of the TRIM(), LTRIM(), and RTRIM() functions.
-** The userdata is 0x1 for left trim, 0x2 for right trim, 0x3 for both.
-*/
-static void trimFunc(
- sqlite3_context *context,
- int argc,
- sqlite3_value **argv
-){
- const unsigned char *zIn; /* Input string */
- const unsigned char *zCharSet; /* Set of characters to trim */
- int nIn; /* Number of bytes in input */
- int flags; /* 1: trimleft 2: trimright 3: trim */
- int i; /* Loop counter */
- unsigned char *aLen = 0; /* Length of each character in zCharSet */
- unsigned char **azChar = 0; /* Individual characters in zCharSet */
- int nChar; /* Number of characters in zCharSet */
-
- if( sqlite3_value_type(argv[0])==SQLITE_NULL ){
- return;
- }
- zIn = sqlite3_value_text(argv[0]);
- if( zIn==0 ) return;
- nIn = sqlite3_value_bytes(argv[0]);
- assert( zIn==sqlite3_value_text(argv[0]) );
- if( argc==1 ){
- static const unsigned char lenOne[] = { 1 };
- static unsigned char * const azOne[] = { (u8*)" " };
- nChar = 1;
- aLen = (u8*)lenOne;
- azChar = (unsigned char **)azOne;
- zCharSet = 0;
- }else if( (zCharSet = sqlite3_value_text(argv[1]))==0 ){
- return;
- }else{
- const unsigned char *z;
- for(z=zCharSet, nChar=0; *z; nChar++){
- SQLITE_SKIP_UTF8(z);
- }
- if( nChar>0 ){
- azChar = contextMalloc(context, ((i64)nChar)*(sizeof(char*)+1));
- if( azChar==0 ){
- return;
- }
- aLen = (unsigned char*)&azChar[nChar];
- for(z=zCharSet, nChar=0; *z; nChar++){
- azChar[nChar] = (unsigned char *)z;
- SQLITE_SKIP_UTF8(z);
- aLen[nChar] = (u8)(z - azChar[nChar]);
- }
- }
- }
- if( nChar>0 ){
- flags = SQLITE_PTR_TO_INT(sqlite3_user_data(context));
- if( flags & 1 ){
- while( nIn>0 ){
- int len = 0;
- for(i=0; i<nChar; i++){
- len = aLen[i];
- if( len<=nIn && memcmp(zIn, azChar[i], len)==0 ) break;
- }
- if( i>=nChar ) break;
- zIn += len;
- nIn -= len;
- }
- }
- if( flags & 2 ){
- while( nIn>0 ){
- int len = 0;
- for(i=0; i<nChar; i++){
- len = aLen[i];
- if( len<=nIn && memcmp(&zIn[nIn-len],azChar[i],len)==0 ) break;
- }
- if( i>=nChar ) break;
- nIn -= len;
- }
- }
- if( zCharSet ){
- sqlite3_free(azChar);
- }
- }
- sqlite3_result_text(context, (char*)zIn, nIn, SQLITE_TRANSIENT);
-}
-
-
-#ifdef SQLITE_SOUNDEX
-/*
-** Compute the soundex encoding of a word.
-*/
-static void soundexFunc(
- sqlite3_context *context,
- int argc,
- sqlite3_value **argv
-){
- char zResult[8];
- const u8 *zIn;
- int i, j;
- static const unsigned char iCode[] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 1, 2, 3, 0, 1, 2, 0, 0, 2, 2, 4, 5, 5, 0,
- 1, 2, 6, 2, 3, 0, 1, 0, 2, 0, 2, 0, 0, 0, 0, 0,
- 0, 0, 1, 2, 3, 0, 1, 2, 0, 0, 2, 2, 4, 5, 5, 0,
- 1, 2, 6, 2, 3, 0, 1, 0, 2, 0, 2, 0, 0, 0, 0, 0,
- };
- assert( argc==1 );
- zIn = (u8*)sqlite3_value_text(argv[0]);
- if( zIn==0 ) zIn = (u8*)"";
- for(i=0; zIn[i] && !sqlite3Isalpha(zIn[i]); i++){}
- if( zIn[i] ){
- u8 prevcode = iCode[zIn[i]&0x7f];
- zResult[0] = sqlite3Toupper(zIn[i]);
- for(j=1; j<4 && zIn[i]; i++){
- int code = iCode[zIn[i]&0x7f];
- if( code>0 ){
- if( code!=prevcode ){
- prevcode = code;
- zResult[j++] = code + '0';
- }
- }else{
- prevcode = 0;
- }
- }
- while( j<4 ){
- zResult[j++] = '0';
- }
- zResult[j] = 0;
- sqlite3_result_text(context, zResult, 4, SQLITE_TRANSIENT);
- }else{
- sqlite3_result_text(context, "?000", 4, SQLITE_STATIC);
- }
-}
-#endif
-
-#ifndef SQLITE_OMIT_LOAD_EXTENSION
-/*
-** A function that loads a shared-library extension then returns NULL.
-*/
-static void loadExt(sqlite3_context *context, int argc, sqlite3_value **argv){
- const char *zFile = (const char *)sqlite3_value_text(argv[0]);
- const char *zProc;
- sqlite3 *db = sqlite3_context_db_handle(context);
- char *zErrMsg = 0;
-
- if( argc==2 ){
- zProc = (const char *)sqlite3_value_text(argv[1]);
- }else{
- zProc = 0;
- }
- if( zFile && sqlite3_load_extension(db, zFile, zProc, &zErrMsg) ){
- sqlite3_result_error(context, zErrMsg, -1);
- sqlite3_free(zErrMsg);
- }
-}
-#endif
-
-
-/*
-** An instance of the following structure holds the context of a
-** sum() or avg() aggregate computation.
-*/
-typedef struct SumCtx SumCtx;
-struct SumCtx {
- double rSum; /* Floating point sum */
- i64 iSum; /* Integer sum */
- i64 cnt; /* Number of elements summed */
- u8 overflow; /* True if integer overflow seen */
- u8 approx; /* True if non-integer value was input to the sum */
-};
-
-/*
-** Routines used to compute the sum, average, and total.
-**
-** The SUM() function follows the (broken) SQL standard which means
-** that it returns NULL if it sums over no inputs. TOTAL returns
-** 0.0 in that case. In addition, TOTAL always returns a float where
-** SUM might return an integer if it never encounters a floating point
-** value. TOTAL never fails, but SUM might through an exception if
-** it overflows an integer.
-*/
-static void sumStep(sqlite3_context *context, int argc, sqlite3_value **argv){
- SumCtx *p;
- int type;
- assert( argc==1 );
- UNUSED_PARAMETER(argc);
- p = sqlite3_aggregate_context(context, sizeof(*p));
- type = sqlite3_value_numeric_type(argv[0]);
- if( p && type!=SQLITE_NULL ){
- p->cnt++;
- if( type==SQLITE_INTEGER ){
- i64 v = sqlite3_value_int64(argv[0]);
- p->rSum += v;
- if( (p->approx|p->overflow)==0 ){
- i64 iNewSum = p->iSum + v;
- int s1 = (int)(p->iSum >> (sizeof(i64)*8-1));
- int s2 = (int)(v >> (sizeof(i64)*8-1));
- int s3 = (int)(iNewSum >> (sizeof(i64)*8-1));
- p->overflow = ((s1&s2&~s3) | (~s1&~s2&s3))?1:0;
- p->iSum = iNewSum;
- }
- }else{
- p->rSum += sqlite3_value_double(argv[0]);
- p->approx = 1;
- }
- }
-}
-static void sumFinalize(sqlite3_context *context){
- SumCtx *p;
- p = sqlite3_aggregate_context(context, 0);
- if( p && p->cnt>0 ){
- if( p->overflow ){
- sqlite3_result_error(context,"integer overflow",-1);
- }else if( p->approx ){
- sqlite3_result_double(context, p->rSum);
- }else{
- sqlite3_result_int64(context, p->iSum);
- }
- }
-}
-static void avgFinalize(sqlite3_context *context){
- SumCtx *p;
- p = sqlite3_aggregate_context(context, 0);
- if( p && p->cnt>0 ){
- sqlite3_result_double(context, p->rSum/(double)p->cnt);
- }
-}
-static void totalFinalize(sqlite3_context *context){
- SumCtx *p;
- p = sqlite3_aggregate_context(context, 0);
- /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */
- sqlite3_result_double(context, p ? p->rSum : (double)0);
-}
-
-/*
-** The following structure keeps track of state information for the
-** count() aggregate function.
-*/
-typedef struct CountCtx CountCtx;
-struct CountCtx {
- i64 n;
-};
-
-/*
-** Routines to implement the count() aggregate function.
-*/
-static void countStep(sqlite3_context *context, int argc, sqlite3_value **argv){
- CountCtx *p;
- p = sqlite3_aggregate_context(context, sizeof(*p));
- if( (argc==0 || SQLITE_NULL!=sqlite3_value_type(argv[0])) && p ){
- p->n++;
- }
-
-#ifndef SQLITE_OMIT_DEPRECATED
- /* The sqlite3_aggregate_count() function is deprecated. But just to make
- ** sure it still operates correctly, verify that its count agrees with our
- ** internal count when using count(*) and when the total count can be
- ** expressed as a 32-bit integer. */
- assert( argc==1 || p==0 || p->n>0x7fffffff
- || p->n==sqlite3_aggregate_count(context) );
-#endif
-}
-static void countFinalize(sqlite3_context *context){
- CountCtx *p;
- p = sqlite3_aggregate_context(context, 0);
- sqlite3_result_int64(context, p ? p->n : 0);
-}
-
-/*
-** Routines to implement min() and max() aggregate functions.
-*/
-static void minmaxStep(
- sqlite3_context *context,
- int NotUsed,
- sqlite3_value **argv
-){
- Mem *pArg = (Mem *)argv[0];
- Mem *pBest;
- UNUSED_PARAMETER(NotUsed);
-
- if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
- pBest = (Mem *)sqlite3_aggregate_context(context, sizeof(*pBest));
- if( !pBest ) return;
-
- if( pBest->flags ){
- int max;
- int cmp;
- CollSeq *pColl = sqlite3GetFuncCollSeq(context);
- /* This step function is used for both the min() and max() aggregates,
- ** the only difference between the two being that the sense of the
- ** comparison is inverted. For the max() aggregate, the
- ** sqlite3_user_data() function returns (void *)-1. For min() it
- ** returns (void *)db, where db is the sqlite3* database pointer.
- ** Therefore the next statement sets variable 'max' to 1 for the max()
- ** aggregate, or 0 for min().
- */
- max = sqlite3_user_data(context)!=0;
- cmp = sqlite3MemCompare(pBest, pArg, pColl);
- if( (max && cmp<0) || (!max && cmp>0) ){
- sqlite3VdbeMemCopy(pBest, pArg);
- }
- }else{
- sqlite3VdbeMemCopy(pBest, pArg);
- }
-}
-static void minMaxFinalize(sqlite3_context *context){
- sqlite3_value *pRes;
- pRes = (sqlite3_value *)sqlite3_aggregate_context(context, 0);
- if( pRes ){
- if( ALWAYS(pRes->flags) ){
- sqlite3_result_value(context, pRes);
- }
- sqlite3VdbeMemRelease(pRes);
- }
-}
-
-/*
-** group_concat(EXPR, ?SEPARATOR?)
-*/
-static void groupConcatStep(
- sqlite3_context *context,
- int argc,
- sqlite3_value **argv
-){
- const char *zVal;
- StrAccum *pAccum;
- const char *zSep;
- int nVal, nSep;
- assert( argc==1 || argc==2 );
- if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
- pAccum = (StrAccum*)sqlite3_aggregate_context(context, sizeof(*pAccum));
-
- if( pAccum ){
- sqlite3 *db = sqlite3_context_db_handle(context);
- int firstTerm = pAccum->useMalloc==0;
- pAccum->useMalloc = 1;
- pAccum->mxAlloc = db->aLimit[SQLITE_LIMIT_LENGTH];
- if( !firstTerm ){
- if( argc==2 ){
- zSep = (char*)sqlite3_value_text(argv[1]);
- nSep = sqlite3_value_bytes(argv[1]);
- }else{
- zSep = ",";
- nSep = 1;
- }
- sqlite3StrAccumAppend(pAccum, zSep, nSep);
- }
- zVal = (char*)sqlite3_value_text(argv[0]);
- nVal = sqlite3_value_bytes(argv[0]);
- sqlite3StrAccumAppend(pAccum, zVal, nVal);
- }
-}
-static void groupConcatFinalize(sqlite3_context *context){
- StrAccum *pAccum;
- pAccum = sqlite3_aggregate_context(context, 0);
- if( pAccum ){
- if( pAccum->tooBig ){
- sqlite3_result_error_toobig(context);
- }else if( pAccum->mallocFailed ){
- sqlite3_result_error_nomem(context);
- }else{
- sqlite3_result_text(context, sqlite3StrAccumFinish(pAccum), -1,
- sqlite3_free);
- }
- }
-}
-
-/*
-** This function registered all of the above C functions as SQL
-** functions. This should be the only routine in this file with
-** external linkage.
-*/
-SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(sqlite3 *db){
-#ifndef SQLITE_OMIT_ALTERTABLE
- sqlite3AlterFunctions(db);
-#endif
- if( !db->mallocFailed ){
- int rc = sqlite3_overload_function(db, "MATCH", 2);
- assert( rc==SQLITE_NOMEM || rc==SQLITE_OK );
- if( rc==SQLITE_NOMEM ){
- db->mallocFailed = 1;
- }
- }
-}
-
-/*
-** Set the LIKEOPT flag on the 2-argument function with the given name.
-*/
-static void setLikeOptFlag(sqlite3 *db, const char *zName, u8 flagVal){
- FuncDef *pDef;
- pDef = sqlite3FindFunction(db, zName, sqlite3Strlen30(zName),
- 2, SQLITE_UTF8, 0);
- if( ALWAYS(pDef) ){
- pDef->flags = flagVal;
- }
-}
-
-/*
-** Register the built-in LIKE and GLOB functions. The caseSensitive
-** parameter determines whether or not the LIKE operator is case
-** sensitive. GLOB is always case sensitive.
-*/
-SQLITE_PRIVATE void sqlite3RegisterLikeFunctions(sqlite3 *db, int caseSensitive){
- struct compareInfo *pInfo;
- if( caseSensitive ){
- pInfo = (struct compareInfo*)&likeInfoAlt;
- }else{
- pInfo = (struct compareInfo*)&likeInfoNorm;
- }
- sqlite3CreateFunc(db, "like", 2, SQLITE_ANY, pInfo, likeFunc, 0, 0);
- sqlite3CreateFunc(db, "like", 3, SQLITE_ANY, pInfo, likeFunc, 0, 0);
- sqlite3CreateFunc(db, "glob", 2, SQLITE_ANY,
- (struct compareInfo*)&globInfo, likeFunc, 0,0);
- setLikeOptFlag(db, "glob", SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE);
- setLikeOptFlag(db, "like",
- caseSensitive ? (SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE) : SQLITE_FUNC_LIKE);
-}
-
-/*
-** pExpr points to an expression which implements a function. If
-** it is appropriate to apply the LIKE optimization to that function
-** then set aWc[0] through aWc[2] to the wildcard characters and
-** return TRUE. If the function is not a LIKE-style function then
-** return FALSE.
-*/
-SQLITE_PRIVATE int sqlite3IsLikeFunction(sqlite3 *db, Expr *pExpr, int *pIsNocase, char *aWc){
- FuncDef *pDef;
- if( pExpr->op!=TK_FUNCTION
- || !pExpr->x.pList
- || pExpr->x.pList->nExpr!=2
- ){
- return 0;
- }
- assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
- pDef = sqlite3FindFunction(db, pExpr->u.zToken,
- sqlite3Strlen30(pExpr->u.zToken),
- 2, SQLITE_UTF8, 0);
- if( NEVER(pDef==0) || (pDef->flags & SQLITE_FUNC_LIKE)==0 ){
- return 0;
- }
-
- /* The memcpy() statement assumes that the wildcard characters are
- ** the first three statements in the compareInfo structure. The
- ** asserts() that follow verify that assumption
- */
- memcpy(aWc, pDef->pUserData, 3);
- assert( (char*)&likeInfoAlt == (char*)&likeInfoAlt.matchAll );
- assert( &((char*)&likeInfoAlt)[1] == (char*)&likeInfoAlt.matchOne );
- assert( &((char*)&likeInfoAlt)[2] == (char*)&likeInfoAlt.matchSet );
- *pIsNocase = (pDef->flags & SQLITE_FUNC_CASE)==0;
- return 1;
-}
-
-/*
-** All all of the FuncDef structures in the aBuiltinFunc[] array above
-** to the global function hash table. This occurs at start-time (as
-** a consequence of calling sqlite3_initialize()).
-**
-** After this routine runs
-*/
-SQLITE_PRIVATE void sqlite3RegisterGlobalFunctions(void){
- /*
- ** The following array holds FuncDef structures for all of the functions
- ** defined in this file.
- **
- ** The array cannot be constant since changes are made to the
- ** FuncDef.pHash elements at start-time. The elements of this array
- ** are read-only after initialization is complete.
- */
- static SQLITE_WSD FuncDef aBuiltinFunc[] = {
- FUNCTION(ltrim, 1, 1, 0, trimFunc ),
- FUNCTION(ltrim, 2, 1, 0, trimFunc ),
- FUNCTION(rtrim, 1, 2, 0, trimFunc ),
- FUNCTION(rtrim, 2, 2, 0, trimFunc ),
- FUNCTION(trim, 1, 3, 0, trimFunc ),
- FUNCTION(trim, 2, 3, 0, trimFunc ),
- FUNCTION(min, -1, 0, 1, minmaxFunc ),
- FUNCTION(min, 0, 0, 1, 0 ),
- AGGREGATE(min, 1, 0, 1, minmaxStep, minMaxFinalize ),
- FUNCTION(max, -1, 1, 1, minmaxFunc ),
- FUNCTION(max, 0, 1, 1, 0 ),
- AGGREGATE(max, 1, 1, 1, minmaxStep, minMaxFinalize ),
- FUNCTION(typeof, 1, 0, 0, typeofFunc ),
- FUNCTION(length, 1, 0, 0, lengthFunc ),
- FUNCTION(substr, 2, 0, 0, substrFunc ),
- FUNCTION(substr, 3, 0, 0, substrFunc ),
- FUNCTION(abs, 1, 0, 0, absFunc ),
-#ifndef SQLITE_OMIT_FLOATING_POINT
- FUNCTION(round, 1, 0, 0, roundFunc ),
- FUNCTION(round, 2, 0, 0, roundFunc ),
-#endif
- FUNCTION(upper, 1, 0, 0, upperFunc ),
- FUNCTION(lower, 1, 0, 0, lowerFunc ),
- FUNCTION(coalesce, 1, 0, 0, 0 ),
- FUNCTION(coalesce, -1, 0, 0, ifnullFunc ),
- FUNCTION(coalesce, 0, 0, 0, 0 ),
- FUNCTION(hex, 1, 0, 0, hexFunc ),
- FUNCTION(ifnull, 2, 0, 1, ifnullFunc ),
- FUNCTION(random, 0, 0, 0, randomFunc ),
- FUNCTION(randomblob, 1, 0, 0, randomBlob ),
- FUNCTION(nullif, 2, 0, 1, nullifFunc ),
- FUNCTION(sqlite_version, 0, 0, 0, versionFunc ),
- FUNCTION(sqlite_source_id, 0, 0, 0, sourceidFunc ),
- FUNCTION(quote, 1, 0, 0, quoteFunc ),
- FUNCTION(last_insert_rowid, 0, 0, 0, last_insert_rowid),
- FUNCTION(changes, 0, 0, 0, changes ),
- FUNCTION(total_changes, 0, 0, 0, total_changes ),
- FUNCTION(replace, 3, 0, 0, replaceFunc ),
- FUNCTION(zeroblob, 1, 0, 0, zeroblobFunc ),
- #ifdef SQLITE_SOUNDEX
- FUNCTION(soundex, 1, 0, 0, soundexFunc ),
- #endif
- #ifndef SQLITE_OMIT_LOAD_EXTENSION
- FUNCTION(load_extension, 1, 0, 0, loadExt ),
- FUNCTION(load_extension, 2, 0, 0, loadExt ),
- #endif
- AGGREGATE(sum, 1, 0, 0, sumStep, sumFinalize ),
- AGGREGATE(total, 1, 0, 0, sumStep, totalFinalize ),
- AGGREGATE(avg, 1, 0, 0, sumStep, avgFinalize ),
- /* AGGREGATE(count, 0, 0, 0, countStep, countFinalize ), */
- {0,SQLITE_UTF8,SQLITE_FUNC_COUNT,0,0,0,countStep,countFinalize,"count",0},
- AGGREGATE(count, 1, 0, 0, countStep, countFinalize ),
- AGGREGATE(group_concat, 1, 0, 0, groupConcatStep, groupConcatFinalize),
- AGGREGATE(group_concat, 2, 0, 0, groupConcatStep, groupConcatFinalize),
-
- LIKEFUNC(glob, 2, &globInfo, SQLITE_FUNC_LIKE|SQLITE_FUNC_CASE),
- #ifdef SQLITE_CASE_SENSITIVE_LIKE
- LIKEFUNC(like, 2, &likeInfoAlt, SQLITE_FUNC_LIKE|SQLITE_FUNC_CASE),
- LIKEFUNC(like, 3, &likeInfoAlt, SQLITE_FUNC_LIKE|SQLITE_FUNC_CASE),
- #else
- LIKEFUNC(like, 2, &likeInfoNorm, SQLITE_FUNC_LIKE),
- LIKEFUNC(like, 3, &likeInfoNorm, SQLITE_FUNC_LIKE),
- #endif
- };
-
- int i;
- FuncDefHash *pHash = &GLOBAL(FuncDefHash, sqlite3GlobalFunctions);
- FuncDef *aFunc = (FuncDef*)&GLOBAL(FuncDef, aBuiltinFunc);
-
- for(i=0; i<ArraySize(aBuiltinFunc); i++){
- sqlite3FuncDefInsert(pHash, &aFunc[i]);
- }
- sqlite3RegisterDateTimeFunctions();
-}
-
-/************** End of func.c ************************************************/
-/************** Begin file insert.c ******************************************/
-/*
-** 2001 September 15
-**
-** 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 C code routines that are called by the parser
-** to handle INSERT statements in SQLite.
-**
-** $Id: insert.c,v 1.270 2009/07/24 17:58:53 danielk1977 Exp $
-*/
-
-/*
-** Generate code that will open a table for reading.
-*/
-SQLITE_PRIVATE void sqlite3OpenTable(
- Parse *p, /* Generate code into this VDBE */
- int iCur, /* The cursor number of the table */
- int iDb, /* The database index in sqlite3.aDb[] */
- Table *pTab, /* The table to be opened */
- int opcode /* OP_OpenRead or OP_OpenWrite */
-){
- Vdbe *v;
- if( IsVirtual(pTab) ) return;
- v = sqlite3GetVdbe(p);
- assert( opcode==OP_OpenWrite || opcode==OP_OpenRead );
- sqlite3TableLock(p, iDb, pTab->tnum, (opcode==OP_OpenWrite)?1:0, pTab->zName);
- sqlite3VdbeAddOp3(v, opcode, iCur, pTab->tnum, iDb);
- sqlite3VdbeChangeP4(v, -1, SQLITE_INT_TO_PTR(pTab->nCol), P4_INT32);
- VdbeComment((v, "%s", pTab->zName));
-}
-
-/*
-** Return a pointer to the column affinity string associated with index
-** pIdx. A column affinity string has one character for each column in
-** the table, according to the affinity of the column:
-**
-** Character Column affinity
-** ------------------------------
-** 'a' TEXT
-** 'b' NONE
-** 'c' NUMERIC
-** 'd' INTEGER
-** 'e' REAL
-**
-** An extra 'b' 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
-** is managed along with the rest of the Index structure. It will be
-** released when sqlite3DeleteIndex() is called.
-*/
-SQLITE_PRIVATE const char *sqlite3IndexAffinityStr(Vdbe *v, Index *pIdx){
- if( !pIdx->zColAff ){
- /* The first time a column affinity string for a particular index is
- ** required, it is allocated and populated here. It is then stored as
- ** a member of the Index structure for subsequent use.
- **
- ** The column affinity string will eventually be deleted by
- ** sqliteDeleteIndex() when the Index structure itself is cleaned
- ** up.
- */
- int n;
- Table *pTab = pIdx->pTable;
- sqlite3 *db = sqlite3VdbeDb(v);
- pIdx->zColAff = (char *)sqlite3Malloc(pIdx->nColumn+2);
- if( !pIdx->zColAff ){
- db->mallocFailed = 1;
- return 0;
- }
- for(n=0; n<pIdx->nColumn; n++){
- pIdx->zColAff[n] = pTab->aCol[pIdx->aiColumn[n]].affinity;
- }
- pIdx->zColAff[n++] = SQLITE_AFF_NONE;
- pIdx->zColAff[n] = 0;
- }
-
- return pIdx->zColAff;
-}
-
-/*
-** Set P4 of the most recently inserted opcode to a column affinity
-** string for table pTab. A column affinity string has one character
-** for each column indexed by the index, according to the affinity of the
-** column:
-**
-** Character Column affinity
-** ------------------------------
-** 'a' TEXT
-** 'b' NONE
-** 'c' NUMERIC
-** 'd' INTEGER
-** 'e' REAL
-*/
-SQLITE_PRIVATE void sqlite3TableAffinityStr(Vdbe *v, Table *pTab){
- /* The first time a column affinity string for a particular table
- ** is required, it is allocated and populated here. It is then
- ** stored as a member of the Table structure for subsequent use.
- **
- ** The column affinity string will eventually be deleted by
- ** sqlite3DeleteTable() when the Table structure itself is cleaned up.
- */
- if( !pTab->zColAff ){
- char *zColAff;
- int i;
- sqlite3 *db = sqlite3VdbeDb(v);
-
- zColAff = (char *)sqlite3Malloc(pTab->nCol+1);
- if( !zColAff ){
- db->mallocFailed = 1;
- return;
- }
-
- for(i=0; i<pTab->nCol; i++){
- zColAff[i] = pTab->aCol[i].affinity;
- }
- zColAff[pTab->nCol] = '\0';
-
- pTab->zColAff = zColAff;
- }
-
- sqlite3VdbeChangeP4(v, -1, pTab->zColAff, 0);
-}
-
-/*
-** Return non-zero if the table pTab in database iDb or any of its indices
-** have been opened at any point in the VDBE program beginning at location
-** iStartAddr throught the end of the program. This is used to see if
-** a statement of the form "INSERT INTO <iDb, pTab> SELECT ..." can
-** run without using temporary table for the results of the SELECT.
-*/
-static int readsTable(Parse *p, int iStartAddr, int iDb, Table *pTab){
- Vdbe *v = sqlite3GetVdbe(p);
- int i;
- int iEnd = sqlite3VdbeCurrentAddr(v);
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- VTable *pVTab = IsVirtual(pTab) ? sqlite3GetVTable(p->db, pTab) : 0;
-#endif
-
- for(i=iStartAddr; i<iEnd; i++){
- VdbeOp *pOp = sqlite3VdbeGetOp(v, i);
- assert( pOp!=0 );
- if( pOp->opcode==OP_OpenRead && pOp->p3==iDb ){
- Index *pIndex;
- int tnum = pOp->p2;
- if( tnum==pTab->tnum ){
- return 1;
- }
- for(pIndex=pTab->pIndex; pIndex; pIndex=pIndex->pNext){
- if( tnum==pIndex->tnum ){
- return 1;
- }
- }
- }
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- if( pOp->opcode==OP_VOpen && pOp->p4.pVtab==pVTab ){
- assert( pOp->p4.pVtab!=0 );
- assert( pOp->p4type==P4_VTAB );
- return 1;
- }
-#endif
- }
- return 0;
-}
-
-#ifndef SQLITE_OMIT_AUTOINCREMENT
-/*
-** Locate or create an AutoincInfo structure associated with table pTab
-** which is in database iDb. Return the register number for the register
-** that holds the maximum rowid.
-**
-** There is at most one AutoincInfo structure per table even if the
-** same table is autoincremented multiple times due to inserts within
-** triggers. A new AutoincInfo structure is created if this is the
-** first use of table pTab. On 2nd and subsequent uses, the original
-** AutoincInfo structure is used.
-**
-** Three memory locations are allocated:
-**
-** (1) Register to hold the name of the pTab table.
-** (2) Register to hold the maximum ROWID of pTab.
-** (3) Register to hold the rowid in sqlite_sequence of pTab
-**
-** The 2nd register is the one that is returned. That is all the
-** insert routine needs to know about.
-*/
-static int autoIncBegin(
- Parse *pParse, /* Parsing context */
- int iDb, /* Index of the database holding pTab */
- Table *pTab /* The table we are writing to */
-){
- int memId = 0; /* Register holding maximum rowid */
- if( pTab->tabFlags & TF_Autoincrement ){
- Parse *pToplevel = sqlite3ParseToplevel(pParse);
- AutoincInfo *pInfo;
-
- pInfo = pToplevel->pAinc;
- while( pInfo && pInfo->pTab!=pTab ){ pInfo = pInfo->pNext; }
- if( pInfo==0 ){
- pInfo = sqlite3DbMallocRaw(pParse->db, sizeof(*pInfo));
- if( pInfo==0 ) return 0;
- pInfo->pNext = pToplevel->pAinc;
- pToplevel->pAinc = pInfo;
- pInfo->pTab = pTab;
- pInfo->iDb = iDb;
- pToplevel->nMem++; /* Register to hold name of table */
- pInfo->regCtr = ++pToplevel->nMem; /* Max rowid register */
- pToplevel->nMem++; /* Rowid in sqlite_sequence */
- }
- memId = pInfo->regCtr;
- }
- return memId;
-}
-
-/*
-** This routine generates code that will initialize all of the
-** register used by the autoincrement tracker.
-*/
-SQLITE_PRIVATE void sqlite3AutoincrementBegin(Parse *pParse){
- AutoincInfo *p; /* Information about an AUTOINCREMENT */
- sqlite3 *db = pParse->db; /* The database connection */
- Db *pDb; /* Database only autoinc table */
- int memId; /* Register holding max rowid */
- int addr; /* A VDBE address */
- Vdbe *v = pParse->pVdbe; /* VDBE under construction */
-
- /* This routine is never called during trigger-generation. It is
- ** only called from the top-level */
- assert( pParse->pTriggerTab==0 );
- assert( pParse==sqlite3ParseToplevel(pParse) );
-
- assert( v ); /* We failed long ago if this is not so */
- for(p = pParse->pAinc; p; p = p->pNext){
- pDb = &db->aDb[p->iDb];
- memId = p->regCtr;
- sqlite3OpenTable(pParse, 0, p->iDb, pDb->pSchema->pSeqTab, OP_OpenRead);
- addr = sqlite3VdbeCurrentAddr(v);
- sqlite3VdbeAddOp4(v, OP_String8, 0, memId-1, 0, p->pTab->zName, 0);
- sqlite3VdbeAddOp2(v, OP_Rewind, 0, addr+9);
- sqlite3VdbeAddOp3(v, OP_Column, 0, 0, memId);
- sqlite3VdbeAddOp3(v, OP_Ne, memId-1, addr+7, memId);
- sqlite3VdbeChangeP5(v, SQLITE_JUMPIFNULL);
- sqlite3VdbeAddOp2(v, OP_Rowid, 0, memId+1);
- sqlite3VdbeAddOp3(v, OP_Column, 0, 1, memId);
- sqlite3VdbeAddOp2(v, OP_Goto, 0, addr+9);
- sqlite3VdbeAddOp2(v, OP_Next, 0, addr+2);
- sqlite3VdbeAddOp2(v, OP_Integer, 0, memId);
- sqlite3VdbeAddOp0(v, OP_Close);
- }
-}
-
-/*
-** Update the maximum rowid for an autoincrement calculation.
-**
-** This routine should be called when the top of the stack holds a
-** new rowid that is about to be inserted. If that new rowid is
-** larger than the maximum rowid in the memId memory cell, then the
-** memory cell is updated. The stack is unchanged.
-*/
-static void autoIncStep(Parse *pParse, int memId, int regRowid){
- if( memId>0 ){
- sqlite3VdbeAddOp2(pParse->pVdbe, OP_MemMax, memId, regRowid);
- }
-}
-
-/*
-** This routine generates the code needed to write autoincrement
-** maximum rowid values back into the sqlite_sequence register.
-** Every statement that might do an INSERT into an autoincrement
-** table (either directly or through triggers) needs to call this
-** routine just before the "exit" code.
-*/
-SQLITE_PRIVATE void sqlite3AutoincrementEnd(Parse *pParse){
- AutoincInfo *p;
- Vdbe *v = pParse->pVdbe;
- sqlite3 *db = pParse->db;
-
- assert( v );
- for(p = pParse->pAinc; p; p = p->pNext){
- Db *pDb = &db->aDb[p->iDb];
- int j1, j2, j3, j4, j5;
- int iRec;
- int memId = p->regCtr;
-
- iRec = sqlite3GetTempReg(pParse);
- sqlite3OpenTable(pParse, 0, p->iDb, pDb->pSchema->pSeqTab, OP_OpenWrite);
- j1 = sqlite3VdbeAddOp1(v, OP_NotNull, memId+1);
- j2 = sqlite3VdbeAddOp0(v, OP_Rewind);
- j3 = sqlite3VdbeAddOp3(v, OP_Column, 0, 0, iRec);
- j4 = sqlite3VdbeAddOp3(v, OP_Eq, memId-1, 0, iRec);
- sqlite3VdbeAddOp2(v, OP_Next, 0, j3);
- sqlite3VdbeJumpHere(v, j2);
- sqlite3VdbeAddOp2(v, OP_NewRowid, 0, memId+1);
- j5 = sqlite3VdbeAddOp0(v, OP_Goto);
- sqlite3VdbeJumpHere(v, j4);
- sqlite3VdbeAddOp2(v, OP_Rowid, 0, memId+1);
- sqlite3VdbeJumpHere(v, j1);
- sqlite3VdbeJumpHere(v, j5);
- sqlite3VdbeAddOp3(v, OP_MakeRecord, memId-1, 2, iRec);
- sqlite3VdbeAddOp3(v, OP_Insert, 0, iRec, memId+1);
- sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
- sqlite3VdbeAddOp0(v, OP_Close);
- sqlite3ReleaseTempReg(pParse, iRec);
- }
-}
-#else
-/*
-** If SQLITE_OMIT_AUTOINCREMENT is defined, then the three routines
-** above are all no-ops
-*/
-# define autoIncBegin(A,B,C) (0)
-# define autoIncStep(A,B,C)
-#endif /* SQLITE_OMIT_AUTOINCREMENT */
-
-
-/* Forward declaration */
-static int xferOptimization(
- Parse *pParse, /* Parser context */
- Table *pDest, /* The table we are inserting into */
- Select *pSelect, /* A SELECT statement to use as the data source */
- int onError, /* How to handle constraint errors */
- int iDbDest /* The database of pDest */
-);
-
-/*
-** This routine is call to handle SQL of the following forms:
-**
-** insert into TABLE (IDLIST) values(EXPRLIST)
-** insert into TABLE (IDLIST) select
-**
-** The IDLIST following the table name is always optional. If omitted,
-** then a list of all columns for the table is substituted. The IDLIST
-** appears in the pColumn parameter. pColumn is NULL if IDLIST is omitted.
-**
-** The pList parameter holds EXPRLIST in the first form of the INSERT
-** statement above, and pSelect is NULL. For the second form, pList is
-** NULL and pSelect is a pointer to the select statement used to generate
-** data for the insert.
-**
-** The code generated follows one of four templates. For a simple
-** select with data coming from a VALUES clause, the code executes
-** once straight down through. Pseudo-code follows (we call this
-** the "1st template"):
-**
-** open write cursor to <table> and its indices
-** puts VALUES clause expressions onto the stack
-** write the resulting record into <table>
-** cleanup
-**
-** The three remaining templates assume the statement is of the form
-**
-** INSERT INTO <table> SELECT ...
-**
-** If the SELECT clause is of the restricted form "SELECT * FROM <table2>" -
-** in other words if the SELECT pulls all columns from a single table
-** and there is no WHERE or LIMIT or GROUP BY or ORDER BY clauses, and
-** if <table2> and <table1> are distinct tables but have identical
-** schemas, including all the same indices, then a special optimization
-** is invoked that copies raw records from <table2> over to <table1>.
-** See the xferOptimization() function for the implementation of this
-** template. This is the 2nd template.
-**
-** open a write cursor to <table>
-** open read cursor on <table2>
-** transfer all records in <table2> over to <table>
-** close cursors
-** foreach index on <table>
-** open a write cursor on the <table> index
-** open a read cursor on the corresponding <table2> index
-** transfer all records from the read to the write cursors
-** close cursors
-** end foreach
-**
-** The 3rd template is for when the second template does not apply
-** and the SELECT clause does not read from <table> at any time.
-** The generated code follows this template:
-**
-** EOF <- 0
-** X <- A
-** goto B
-** A: setup for the SELECT
-** loop over the rows in the SELECT
-** load values into registers R..R+n
-** yield X
-** end loop
-** cleanup after the SELECT
-** EOF <- 1
-** yield X
-** goto A
-** B: open write cursor to <table> and its indices
-** C: yield X
-** if EOF goto D
-** insert the select result into <table> from R..R+n
-** goto C
-** D: cleanup
-**
-** The 4th template is used if the insert statement takes its
-** values from a SELECT but the data is being inserted into a table
-** that is also read as part of the SELECT. In the third form,
-** we have to use a intermediate table to store the results of
-** the select. The template is like this:
-**
-** EOF <- 0
-** X <- A
-** goto B
-** A: setup for the SELECT
-** loop over the tables in the SELECT
-** load value into register R..R+n
-** yield X
-** end loop
-** cleanup after the SELECT
-** EOF <- 1
-** yield X
-** halt-error
-** B: open temp table
-** L: yield X
-** if EOF goto M
-** insert row from R..R+n into temp table
-** goto L
-** M: open write cursor to <table> and its indices
-** rewind temp table
-** C: loop over rows of intermediate table
-** transfer values form intermediate table into <table>
-** end loop
-** D: cleanup
-*/
-SQLITE_PRIVATE void sqlite3Insert(
- Parse *pParse, /* Parser context */
- SrcList *pTabList, /* Name of table into which we are inserting */
- ExprList *pList, /* List of values to be inserted */
- Select *pSelect, /* A SELECT statement to use as the data source */
- IdList *pColumn, /* Column names corresponding to IDLIST. */
- int onError /* How to handle constraint errors */
-){
- sqlite3 *db; /* The main database structure */
- Table *pTab; /* The table to insert into. aka TABLE */
- char *zTab; /* Name of the table into which we are inserting */
- const char *zDb; /* Name of the database holding this table */
- int i, j, idx; /* Loop counters */
- Vdbe *v; /* Generate code into this virtual machine */
- Index *pIdx; /* For looping over indices of the table */
- int nColumn; /* Number of columns in the data */
- int nHidden = 0; /* Number of hidden columns if TABLE is virtual */
- int baseCur = 0; /* VDBE Cursor number for pTab */
- int keyColumn = -1; /* Column that is the INTEGER PRIMARY KEY */
- int endOfLoop; /* Label for the end of the insertion loop */
- int useTempTable = 0; /* Store SELECT results in intermediate table */
- int srcTab = 0; /* Data comes from this temporary cursor if >=0 */
- int addrInsTop = 0; /* Jump to label "D" */
- int addrCont = 0; /* Top of insert loop. Label "C" in templates 3 and 4 */
- int addrSelect = 0; /* Address of coroutine that implements the SELECT */
- SelectDest dest; /* Destination for SELECT on rhs of INSERT */
- int iDb; /* Index of database holding TABLE */
- Db *pDb; /* The database containing table being inserted into */
- int appendFlag = 0; /* True if the insert is likely to be an append */
-
- /* Register allocations */
- int regFromSelect = 0;/* Base register for data coming from SELECT */
- int regAutoinc = 0; /* Register holding the AUTOINCREMENT counter */
- int regRowCount = 0; /* Memory cell used for the row counter */
- int regIns; /* Block of regs holding rowid+data being inserted */
- int regRowid; /* registers holding insert rowid */
- int regData; /* register holding first column to insert */
- int regRecord; /* Holds the assemblied row record */
- int regEof = 0; /* Register recording end of SELECT data */
- int *aRegIdx = 0; /* One register allocated to each index */
-
-#ifndef SQLITE_OMIT_TRIGGER
- int isView; /* True if attempting to insert into a view */
- Trigger *pTrigger; /* List of triggers on pTab, if required */
- int tmask; /* Mask of trigger times */
-#endif
-
- db = pParse->db;
- memset(&dest, 0, sizeof(dest));
- if( pParse->nErr || db->mallocFailed ){
- goto insert_cleanup;
- }
-
- /* Locate the table into which we will be inserting new information.
- */
- assert( pTabList->nSrc==1 );
- zTab = pTabList->a[0].zName;
- if( NEVER(zTab==0) ) goto insert_cleanup;
- pTab = sqlite3SrcListLookup(pParse, pTabList);
- if( pTab==0 ){
- goto insert_cleanup;
- }
- iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
- assert( iDb<db->nDb );
- pDb = &db->aDb[iDb];
- zDb = pDb->zName;
- if( sqlite3AuthCheck(pParse, SQLITE_INSERT, pTab->zName, 0, zDb) ){
- goto insert_cleanup;
- }
-
- /* Figure out if we have any triggers and if the table being
- ** inserted into is a view
- */
-#ifndef SQLITE_OMIT_TRIGGER
- pTrigger = sqlite3TriggersExist(pParse, pTab, TK_INSERT, 0, &tmask);
- isView = pTab->pSelect!=0;
-#else
-# define pTrigger 0
-# define tmask 0
-# define isView 0
-#endif
-#ifdef SQLITE_OMIT_VIEW
-# undef isView
-# define isView 0
-#endif
- assert( (pTrigger && tmask) || (pTrigger==0 && tmask==0) );
-
- /* If pTab is really a view, make sure it has been initialized.
- ** ViewGetColumnNames() is a no-op if pTab is not a view (or virtual
- ** module table).
- */
- if( sqlite3ViewGetColumnNames(pParse, pTab) ){
- goto insert_cleanup;
- }
-
- /* Ensure that:
- * (a) the table is not read-only,
- * (b) that if it is a view then ON INSERT triggers exist
- */
- if( sqlite3IsReadOnly(pParse, pTab, tmask) ){
- goto insert_cleanup;
- }
-
- /* Allocate a VDBE
- */
- v = sqlite3GetVdbe(pParse);
- if( v==0 ) goto insert_cleanup;
- if( pParse->nested==0 ) sqlite3VdbeCountChanges(v);
- sqlite3BeginWriteOperation(pParse, pSelect || pTrigger, iDb);
-
-#ifndef SQLITE_OMIT_XFER_OPT
- /* If the statement is of the form
- **
- ** INSERT INTO <table1> SELECT * FROM <table2>;
- **
- ** Then special optimizations can be applied that make the transfer
- ** very fast and which reduce fragmentation of indices.
- **
- ** This is the 2nd template.
- */
- if( pColumn==0 && xferOptimization(pParse, pTab, pSelect, onError, iDb) ){
- assert( !pTrigger );
- assert( pList==0 );
- goto insert_end;
- }
-#endif /* SQLITE_OMIT_XFER_OPT */
-
- /* If this is an AUTOINCREMENT table, look up the sequence number in the
- ** sqlite_sequence table and store it in memory cell regAutoinc.
- */
- regAutoinc = autoIncBegin(pParse, iDb, pTab);
-
- /* Figure out how many columns of data are supplied. If the data
- ** is coming from a SELECT statement, then generate a co-routine that
- ** produces a single row of the SELECT on each invocation. The
- ** co-routine is the common header to the 3rd and 4th templates.
- */
- if( pSelect ){
- /* Data is coming from a SELECT. Generate code to implement that SELECT
- ** as a co-routine. The code is common to both the 3rd and 4th
- ** templates:
- **
- ** EOF <- 0
- ** X <- A
- ** goto B
- ** A: setup for the SELECT
- ** loop over the tables in the SELECT
- ** load value into register R..R+n
- ** yield X
- ** end loop
- ** cleanup after the SELECT
- ** EOF <- 1
- ** yield X
- ** halt-error
- **
- ** On each invocation of the co-routine, it puts a single row of the
- ** SELECT result into registers dest.iMem...dest.iMem+dest.nMem-1.
- ** (These output registers are allocated by sqlite3Select().) When
- ** the SELECT completes, it sets the EOF flag stored in regEof.
- */
- int rc, j1;
-
- regEof = ++pParse->nMem;
- sqlite3VdbeAddOp2(v, OP_Integer, 0, regEof); /* EOF <- 0 */
- VdbeComment((v, "SELECT eof flag"));
- sqlite3SelectDestInit(&dest, SRT_Coroutine, ++pParse->nMem);
- addrSelect = sqlite3VdbeCurrentAddr(v)+2;
- sqlite3VdbeAddOp2(v, OP_Integer, addrSelect-1, dest.iParm);
- j1 = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0);
- VdbeComment((v, "Jump over SELECT coroutine"));
-
- /* Resolve the expressions in the SELECT statement and execute it. */
- rc = sqlite3Select(pParse, pSelect, &dest);
- assert( pParse->nErr==0 || rc );
- if( rc || NEVER(pParse->nErr) || db->mallocFailed ){
- goto insert_cleanup;
- }
- sqlite3VdbeAddOp2(v, OP_Integer, 1, regEof); /* EOF <- 1 */
- sqlite3VdbeAddOp1(v, OP_Yield, dest.iParm); /* yield X */
- sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_INTERNAL, OE_Abort);
- VdbeComment((v, "End of SELECT coroutine"));
- sqlite3VdbeJumpHere(v, j1); /* label B: */
-
- regFromSelect = dest.iMem;
- assert( pSelect->pEList );
- nColumn = pSelect->pEList->nExpr;
- assert( dest.nMem==nColumn );
-
- /* Set useTempTable to TRUE if the result of the SELECT statement
- ** should be written into a temporary table (template 4). Set to
- ** FALSE if each* row of the SELECT can be written directly into
- ** the destination table (template 3).
- **
- ** A temp table must be used if the table being updated is also one
- ** of the tables being read by the SELECT statement. Also use a
- ** temp table in the case of row triggers.
- */
- if( pTrigger || readsTable(pParse, addrSelect, iDb, pTab) ){
- useTempTable = 1;
- }
-
- if( useTempTable ){
- /* Invoke the coroutine to extract information from the SELECT
- ** and add it to a transient table srcTab. The code generated
- ** here is from the 4th template:
- **
- ** B: open temp table
- ** L: yield X
- ** if EOF goto M
- ** insert row from R..R+n into temp table
- ** goto L
- ** M: ...
- */
- int regRec; /* Register to hold packed record */
- int regTempRowid; /* Register to hold temp table ROWID */
- int addrTop; /* Label "L" */
- int addrIf; /* Address of jump to M */
-
- srcTab = pParse->nTab++;
- regRec = sqlite3GetTempReg(pParse);
- regTempRowid = sqlite3GetTempReg(pParse);
- sqlite3VdbeAddOp2(v, OP_OpenEphemeral, srcTab, nColumn);
- addrTop = sqlite3VdbeAddOp1(v, OP_Yield, dest.iParm);
- addrIf = sqlite3VdbeAddOp1(v, OP_If, regEof);
- sqlite3VdbeAddOp3(v, OP_MakeRecord, regFromSelect, nColumn, regRec);
- sqlite3VdbeAddOp2(v, OP_NewRowid, srcTab, regTempRowid);
- sqlite3VdbeAddOp3(v, OP_Insert, srcTab, regRec, regTempRowid);
- sqlite3VdbeAddOp2(v, OP_Goto, 0, addrTop);
- sqlite3VdbeJumpHere(v, addrIf);
- sqlite3ReleaseTempReg(pParse, regRec);
- sqlite3ReleaseTempReg(pParse, regTempRowid);
- }
- }else{
- /* This is the case if the data for the INSERT is coming from a VALUES
- ** clause
- */
- NameContext sNC;
- memset(&sNC, 0, sizeof(sNC));
- sNC.pParse = pParse;
- srcTab = -1;
- assert( useTempTable==0 );
- nColumn = pList ? pList->nExpr : 0;
- for(i=0; i<nColumn; i++){
- if( sqlite3ResolveExprNames(&sNC, pList->a[i].pExpr) ){
- goto insert_cleanup;
- }
- }
- }
-
- /* Make sure the number of columns in the source data matches the number
- ** of columns to be inserted into the table.
- */
- if( IsVirtual(pTab) ){
- for(i=0; i<pTab->nCol; i++){
- nHidden += (IsHiddenColumn(&pTab->aCol[i]) ? 1 : 0);
- }
- }
- if( pColumn==0 && nColumn && nColumn!=(pTab->nCol-nHidden) ){
- sqlite3ErrorMsg(pParse,
- "table %S has %d columns but %d values were supplied",
- pTabList, 0, pTab->nCol-nHidden, nColumn);
- goto insert_cleanup;
- }
- if( pColumn!=0 && nColumn!=pColumn->nId ){
- sqlite3ErrorMsg(pParse, "%d values for %d columns", nColumn, pColumn->nId);
- goto insert_cleanup;
- }
-
- /* If the INSERT statement included an IDLIST term, then make sure
- ** all elements of the IDLIST really are columns of the table and
- ** remember the column indices.
- **
- ** If the table has an INTEGER PRIMARY KEY column and that column
- ** is named in the IDLIST, then record in the keyColumn variable
- ** the index into IDLIST of the primary key column. keyColumn is
- ** the index of the primary key as it appears in IDLIST, not as
- ** is appears in the original table. (The index of the primary
- ** key in the original table is pTab->iPKey.)
- */
- if( pColumn ){
- for(i=0; i<pColumn->nId; i++){
- pColumn->a[i].idx = -1;
- }
- for(i=0; i<pColumn->nId; i++){
- for(j=0; j<pTab->nCol; j++){
- if( sqlite3StrICmp(pColumn->a[i].zName, pTab->aCol[j].zName)==0 ){
- pColumn->a[i].idx = j;
- if( j==pTab->iPKey ){
- keyColumn = i;
- }
- break;
- }
- }
- if( j>=pTab->nCol ){
- if( sqlite3IsRowid(pColumn->a[i].zName) ){
- keyColumn = i;
- }else{
- sqlite3ErrorMsg(pParse, "table %S has no column named %s",
- pTabList, 0, pColumn->a[i].zName);
- pParse->nErr++;
- goto insert_cleanup;
- }
- }
- }
- }
-
- /* If there is no IDLIST term but the table has an integer primary
- ** key, the set the keyColumn variable to the primary key column index
- ** in the original table definition.
- */
- if( pColumn==0 && nColumn>0 ){
- keyColumn = pTab->iPKey;
- }
-
- /* Initialize the count of rows to be inserted
- */
- if( db->flags & SQLITE_CountRows ){
- regRowCount = ++pParse->nMem;
- sqlite3VdbeAddOp2(v, OP_Integer, 0, regRowCount);
- }
-
- /* If this is not a view, open the table and and all indices */
- if( !isView ){
- int nIdx;
-
- baseCur = pParse->nTab;
- nIdx = sqlite3OpenTableAndIndices(pParse, pTab, baseCur, OP_OpenWrite);
- aRegIdx = sqlite3DbMallocRaw(db, sizeof(int)*(nIdx+1));
- if( aRegIdx==0 ){
- goto insert_cleanup;
- }
- for(i=0; i<nIdx; i++){
- aRegIdx[i] = ++pParse->nMem;
- }
- }
-
- /* This is the top of the main insertion loop */
- if( useTempTable ){
- /* This block codes the top of loop only. The complete loop is the
- ** following pseudocode (template 4):
- **
- ** rewind temp table
- ** C: loop over rows of intermediate table
- ** transfer values form intermediate table into <table>
- ** end loop
- ** D: ...
- */
- addrInsTop = sqlite3VdbeAddOp1(v, OP_Rewind, srcTab);
- addrCont = sqlite3VdbeCurrentAddr(v);
- }else if( pSelect ){
- /* This block codes the top of loop only. The complete loop is the
- ** following pseudocode (template 3):
- **
- ** C: yield X
- ** if EOF goto D
- ** insert the select result into <table> from R..R+n
- ** goto C
- ** D: ...
- */
- addrCont = sqlite3VdbeAddOp1(v, OP_Yield, dest.iParm);
- addrInsTop = sqlite3VdbeAddOp1(v, OP_If, regEof);
- }
-
- /* Allocate registers for holding the rowid of the new row,
- ** the content of the new row, and the assemblied row record.
- */
- regRecord = ++pParse->nMem;
- regRowid = regIns = pParse->nMem+1;
- pParse->nMem += pTab->nCol + 1;
- if( IsVirtual(pTab) ){
- regRowid++;
- pParse->nMem++;
- }
- regData = regRowid+1;
-
- /* Run the BEFORE and INSTEAD OF triggers, if there are any
- */
- endOfLoop = sqlite3VdbeMakeLabel(v);
- if( tmask & TRIGGER_BEFORE ){
- int regCols = sqlite3GetTempRange(pParse, pTab->nCol+1);
-
- /* build the NEW.* reference row. Note that if there is an INTEGER
- ** PRIMARY KEY into which a NULL is being inserted, that NULL will be
- ** translated into a unique ID for the row. But on a BEFORE trigger,
- ** we do not know what the unique ID will be (because the insert has
- ** not happened yet) so we substitute a rowid of -1
- */
- if( keyColumn<0 ){
- sqlite3VdbeAddOp2(v, OP_Integer, -1, regCols);
- }else{
- int j1;
- if( useTempTable ){
- sqlite3VdbeAddOp3(v, OP_Column, srcTab, keyColumn, regCols);
- }else{
- assert( pSelect==0 ); /* Otherwise useTempTable is true */
- sqlite3ExprCode(pParse, pList->a[keyColumn].pExpr, regCols);
- }
- j1 = sqlite3VdbeAddOp1(v, OP_NotNull, regCols);
- sqlite3VdbeAddOp2(v, OP_Integer, -1, regCols);
- sqlite3VdbeJumpHere(v, j1);
- sqlite3VdbeAddOp1(v, OP_MustBeInt, regCols);
- }
-
- /* Cannot have triggers on a virtual table. If it were possible,
- ** this block would have to account for hidden column.
- */
- assert( !IsVirtual(pTab) );
-
- /* Create the new column data
- */
- for(i=0; i<pTab->nCol; i++){
- if( pColumn==0 ){
- j = i;
- }else{
- for(j=0; j<pColumn->nId; j++){
- if( pColumn->a[j].idx==i ) break;
- }
- }
- if( pColumn && j>=pColumn->nId ){
- sqlite3ExprCode(pParse, pTab->aCol[i].pDflt, regCols+i+1);
- }else if( useTempTable ){
- sqlite3VdbeAddOp3(v, OP_Column, srcTab, j, regCols+i+1);
- }else{
- assert( pSelect==0 ); /* Otherwise useTempTable is true */
- sqlite3ExprCodeAndCache(pParse, pList->a[j].pExpr, regCols+i+1);
- }
- }
-
- /* If this is an INSERT on a view with an INSTEAD OF INSERT trigger,
- ** do not attempt any conversions before assembling the record.
- ** If this is a real table, attempt conversions as required by the
- ** table column affinities.
- */
- if( !isView ){
- sqlite3VdbeAddOp2(v, OP_Affinity, regCols+1, pTab->nCol);
- sqlite3TableAffinityStr(v, pTab);
- }
-
- /* Fire BEFORE or INSTEAD OF triggers */
- sqlite3CodeRowTrigger(pParse, pTrigger, TK_INSERT, 0, TRIGGER_BEFORE,
- pTab, -1, regCols-pTab->nCol-1, onError, endOfLoop);
-
- sqlite3ReleaseTempRange(pParse, regCols, pTab->nCol+1);
- }
-
- /* Push the record number for the new entry onto the stack. The
- ** record number is a randomly generate integer created by NewRowid
- ** except when the table has an INTEGER PRIMARY KEY column, in which
- ** case the record number is the same as that column.
- */
- if( !isView ){
- if( IsVirtual(pTab) ){
- /* The row that the VUpdate opcode will delete: none */
- sqlite3VdbeAddOp2(v, OP_Null, 0, regIns);
- }
- if( keyColumn>=0 ){
- if( useTempTable ){
- sqlite3VdbeAddOp3(v, OP_Column, srcTab, keyColumn, regRowid);
- }else if( pSelect ){
- sqlite3VdbeAddOp2(v, OP_SCopy, regFromSelect+keyColumn, regRowid);
- }else{
- VdbeOp *pOp;
- sqlite3ExprCode(pParse, pList->a[keyColumn].pExpr, regRowid);
- pOp = sqlite3VdbeGetOp(v, -1);
- if( ALWAYS(pOp) && pOp->opcode==OP_Null && !IsVirtual(pTab) ){
- appendFlag = 1;
- pOp->opcode = OP_NewRowid;
- pOp->p1 = baseCur;
- pOp->p2 = regRowid;
- pOp->p3 = regAutoinc;
- }
- }
- /* If the PRIMARY KEY expression is NULL, then use OP_NewRowid
- ** to generate a unique primary key value.
- */
- if( !appendFlag ){
- int j1;
- if( !IsVirtual(pTab) ){
- j1 = sqlite3VdbeAddOp1(v, OP_NotNull, regRowid);
- sqlite3VdbeAddOp3(v, OP_NewRowid, baseCur, regRowid, regAutoinc);
- sqlite3VdbeJumpHere(v, j1);
- }else{
- j1 = sqlite3VdbeCurrentAddr(v);
- sqlite3VdbeAddOp2(v, OP_IsNull, regRowid, j1+2);
- }
- sqlite3VdbeAddOp1(v, OP_MustBeInt, regRowid);
- }
- }else if( IsVirtual(pTab) ){
- sqlite3VdbeAddOp2(v, OP_Null, 0, regRowid);
- }else{
- sqlite3VdbeAddOp3(v, OP_NewRowid, baseCur, regRowid, regAutoinc);
- appendFlag = 1;
- }
- autoIncStep(pParse, regAutoinc, regRowid);
-
- /* Push onto the stack, data for all columns of the new entry, beginning
- ** with the first column.
- */
- nHidden = 0;
- for(i=0; i<pTab->nCol; i++){
- int iRegStore = regRowid+1+i;
- if( i==pTab->iPKey ){
- /* The value of the INTEGER PRIMARY KEY column is always a NULL.
- ** Whenever this column is read, the record number will be substituted
- ** in its place. So will fill this column with a NULL to avoid
- ** taking up data space with information that will never be used. */
- sqlite3VdbeAddOp2(v, OP_Null, 0, iRegStore);
- continue;
- }
- if( pColumn==0 ){
- if( IsHiddenColumn(&pTab->aCol[i]) ){
- assert( IsVirtual(pTab) );
- j = -1;
- nHidden++;
- }else{
- j = i - nHidden;
- }
- }else{
- for(j=0; j<pColumn->nId; j++){
- if( pColumn->a[j].idx==i ) break;
- }
- }
- if( j<0 || nColumn==0 || (pColumn && j>=pColumn->nId) ){
- sqlite3ExprCode(pParse, pTab->aCol[i].pDflt, iRegStore);
- }else if( useTempTable ){
- sqlite3VdbeAddOp3(v, OP_Column, srcTab, j, iRegStore);
- }else if( pSelect ){
- sqlite3VdbeAddOp2(v, OP_SCopy, regFromSelect+j, iRegStore);
- }else{
- sqlite3ExprCode(pParse, pList->a[j].pExpr, iRegStore);
- }
- }
-
- /* Generate code to check constraints and generate index keys and
- ** do the insertion.
- */
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- if( IsVirtual(pTab) ){
- const char *pVTab = (const char *)sqlite3GetVTable(db, pTab);
- sqlite3VtabMakeWritable(pParse, pTab);
- sqlite3VdbeAddOp4(v, OP_VUpdate, 1, pTab->nCol+2, regIns, pVTab, P4_VTAB);
- sqlite3MayAbort(pParse);
- }else
-#endif
- {
- int isReplace; /* Set to true if constraints may cause a replace */
- sqlite3GenerateConstraintChecks(pParse, pTab, baseCur, regIns, aRegIdx,
- keyColumn>=0, 0, onError, endOfLoop, &isReplace
- );
- sqlite3CompleteInsertion(
- pParse, pTab, baseCur, regIns, aRegIdx, 0, appendFlag, isReplace==0
- );
- }
- }
-
- /* Update the count of rows that are inserted
- */
- if( (db->flags & SQLITE_CountRows)!=0 ){
- sqlite3VdbeAddOp2(v, OP_AddImm, regRowCount, 1);
- }
-
- if( pTrigger ){
- /* Code AFTER triggers */
- sqlite3CodeRowTrigger(pParse, pTrigger, TK_INSERT, 0, TRIGGER_AFTER,
- pTab, -1, regData-2-pTab->nCol, onError, endOfLoop);
- }
-
- /* The bottom of the main insertion loop, if the data source
- ** is a SELECT statement.
- */
- sqlite3VdbeResolveLabel(v, endOfLoop);
- if( useTempTable ){
- sqlite3VdbeAddOp2(v, OP_Next, srcTab, addrCont);
- sqlite3VdbeJumpHere(v, addrInsTop);
- sqlite3VdbeAddOp1(v, OP_Close, srcTab);
- }else if( pSelect ){
- sqlite3VdbeAddOp2(v, OP_Goto, 0, addrCont);
- sqlite3VdbeJumpHere(v, addrInsTop);
- }
-
- if( !IsVirtual(pTab) && !isView ){
- /* Close all tables opened */
- sqlite3VdbeAddOp1(v, OP_Close, baseCur);
- for(idx=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, idx++){
- sqlite3VdbeAddOp1(v, OP_Close, idx+baseCur);
- }
- }
-
-insert_end:
- /* Update the sqlite_sequence table by storing the content of the
- ** maximum rowid counter values recorded while inserting into
- ** autoincrement tables.
- */
- if( pParse->nested==0 && pParse->pTriggerTab==0 ){
- sqlite3AutoincrementEnd(pParse);
- }
-
- /*
- ** Return the number of rows inserted. If this routine is
- ** generating code because of a call to sqlite3NestedParse(), do not
- ** invoke the callback function.
- */
- if( (db->flags&SQLITE_CountRows) && !pParse->nested && !pParse->pTriggerTab ){
- sqlite3VdbeAddOp2(v, OP_ResultRow, regRowCount, 1);
- sqlite3VdbeSetNumCols(v, 1);
- sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows inserted", SQLITE_STATIC);
- }
-
-insert_cleanup:
- sqlite3SrcListDelete(db, pTabList);
- sqlite3ExprListDelete(db, pList);
- sqlite3SelectDelete(db, pSelect);
- sqlite3IdListDelete(db, pColumn);
- sqlite3DbFree(db, aRegIdx);
-}
-
-/*
-** Generate code to do constraint checks prior to an INSERT or an UPDATE.
-**
-** The input is a range of consecutive registers as follows:
-**
-** 1. The rowid of the row after the update.
-**
-** 2. The data in the first column of the entry after the update.
-**
-** i. Data from middle columns...
-**
-** N. The data in the last column of the entry after the update.
-**
-** The regRowid parameter is the index of the register containing (1).
-**
-** If isUpdate is true and rowidChng is non-zero, then rowidChng contains
-** the address of a register containing the rowid before the update takes
-** place. isUpdate is true for UPDATEs and false for INSERTs. If isUpdate
-** is false, indicating an INSERT statement, then a non-zero rowidChng
-** indicates that the rowid was explicitly specified as part of the
-** INSERT statement. If rowidChng is false, it means that the rowid is
-** computed automatically in an insert or that the rowid value is not
-** modified by an update.
-**
-** The code generated by this routine store new index entries into
-** registers identified by aRegIdx[]. No index entry is created for
-** indices where aRegIdx[i]==0. The order of indices in aRegIdx[] is
-** the same as the order of indices on the linked list of indices
-** attached to the table.
-**
-** This routine also generates code to check constraints. NOT NULL,
-** CHECK, and UNIQUE constraints are all checked. If a constraint fails,
-** then the appropriate action is performed. There are five possible
-** actions: ROLLBACK, ABORT, FAIL, REPLACE, and IGNORE.
-**
-** Constraint type Action What Happens
-** --------------- ---------- ----------------------------------------
-** any ROLLBACK The current transaction is rolled back and
-** sqlite3_exec() returns immediately with a
-** return code of SQLITE_CONSTRAINT.
-**
-** any ABORT Back out changes from the current command
-** only (do not do a complete rollback) then
-** cause sqlite3_exec() to return immediately
-** with SQLITE_CONSTRAINT.
-**
-** any FAIL Sqlite_exec() returns immediately with a
-** return code of SQLITE_CONSTRAINT. The
-** transaction is not rolled back and any
-** prior changes are retained.
-**
-** any IGNORE The record number and data is popped from
-** the stack and there is an immediate jump
-** to label ignoreDest.
-**
-** NOT NULL REPLACE The NULL value is replace by the default
-** value for that column. If the default value
-** is NULL, the action is the same as ABORT.
-**
-** UNIQUE REPLACE The other row that conflicts with the row
-** being inserted is removed.
-**
-** CHECK REPLACE Illegal. The results in an exception.
-**
-** Which action to take is determined by the overrideError parameter.
-** Or if overrideError==OE_Default, then the pParse->onError parameter
-** is used. Or if pParse->onError==OE_Default then the onError value
-** for the constraint is used.
-**
-** The calling routine must open a read/write cursor for pTab with
-** cursor number "baseCur". All indices of pTab must also have open
-** read/write cursors with cursor number baseCur+i for the i-th cursor.
-** Except, if there is no possibility of a REPLACE action then
-** cursors do not need to be open for indices where aRegIdx[i]==0.
-*/
-SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
- Parse *pParse, /* The parser context */
- Table *pTab, /* the table into which we are inserting */
- int baseCur, /* Index of a read/write cursor pointing at pTab */
- int regRowid, /* Index of the range of input registers */
- int *aRegIdx, /* Register used by each index. 0 for unused indices */
- int rowidChng, /* True if the rowid might collide with existing entry */
- int isUpdate, /* True for UPDATE, False for INSERT */
- int overrideError, /* Override onError to this if not OE_Default */
- int ignoreDest, /* Jump to this label on an OE_Ignore resolution */
- int *pbMayReplace /* OUT: Set to true if constraint may cause a replace */
-){
- int i; /* loop counter */
- Vdbe *v; /* VDBE under constrution */
- int nCol; /* Number of columns */
- int onError; /* Conflict resolution strategy */
- int j1; /* Addresss of jump instruction */
- int j2 = 0, j3; /* Addresses of jump instructions */
- int regData; /* Register containing first data column */
- int iCur; /* Table cursor number */
- Index *pIdx; /* Pointer to one of the indices */
- int seenReplace = 0; /* True if REPLACE is used to resolve INT PK conflict */
- int regOldRowid = (rowidChng && isUpdate) ? rowidChng : regRowid;
-
- v = sqlite3GetVdbe(pParse);
- assert( v!=0 );
- assert( pTab->pSelect==0 ); /* This table is not a VIEW */
- nCol = pTab->nCol;
- regData = regRowid + 1;
-
- /* Test all NOT NULL constraints.
- */
- for(i=0; i<nCol; i++){
- if( i==pTab->iPKey ){
- continue;
- }
- onError = pTab->aCol[i].notNull;
- if( onError==OE_None ) continue;
- if( overrideError!=OE_Default ){
- onError = overrideError;
- }else if( onError==OE_Default ){
- onError = OE_Abort;
- }
- if( onError==OE_Replace && pTab->aCol[i].pDflt==0 ){
- onError = OE_Abort;
- }
- assert( onError==OE_Rollback || onError==OE_Abort || onError==OE_Fail
- || onError==OE_Ignore || onError==OE_Replace );
- switch( onError ){
- case OE_Abort:
- sqlite3MayAbort(pParse);
- case OE_Rollback:
- case OE_Fail: {
- char *zMsg;
- j1 = sqlite3VdbeAddOp3(v, OP_HaltIfNull,
- SQLITE_CONSTRAINT, onError, regData+i);
- zMsg = sqlite3MPrintf(pParse->db, "%s.%s may not be NULL",
- pTab->zName, pTab->aCol[i].zName);
- sqlite3VdbeChangeP4(v, -1, zMsg, P4_DYNAMIC);
- break;
- }
- case OE_Ignore: {
- sqlite3VdbeAddOp2(v, OP_IsNull, regData+i, ignoreDest);
- break;
- }
- default: {
- assert( onError==OE_Replace );
- j1 = sqlite3VdbeAddOp1(v, OP_NotNull, regData+i);
- sqlite3ExprCode(pParse, pTab->aCol[i].pDflt, regData+i);
- sqlite3VdbeJumpHere(v, j1);
- break;
- }
- }
- }
-
- /* Test all CHECK constraints
- */
-#ifndef SQLITE_OMIT_CHECK
- if( pTab->pCheck && (pParse->db->flags & SQLITE_IgnoreChecks)==0 ){
- int allOk = sqlite3VdbeMakeLabel(v);
- pParse->ckBase = regData;
- sqlite3ExprIfTrue(pParse, pTab->pCheck, allOk, SQLITE_JUMPIFNULL);
- onError = overrideError!=OE_Default ? overrideError : OE_Abort;
- if( onError==OE_Ignore ){
- sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest);
- }else{
- sqlite3HaltConstraint(pParse, onError, 0, 0);
- }
- sqlite3VdbeResolveLabel(v, allOk);
- }
-#endif /* !defined(SQLITE_OMIT_CHECK) */
-
- /* If we have an INTEGER PRIMARY KEY, make sure the primary key
- ** of the new record does not previously exist. Except, if this
- ** is an UPDATE and the primary key is not changing, that is OK.
- */
- if( rowidChng ){
- onError = pTab->keyConf;
- if( overrideError!=OE_Default ){
- onError = overrideError;
- }else if( onError==OE_Default ){
- onError = OE_Abort;
- }
-
- if( onError!=OE_Replace || pTab->pIndex ){
- if( isUpdate ){
- j2 = sqlite3VdbeAddOp3(v, OP_Eq, regRowid, 0, rowidChng);
- }
- j3 = sqlite3VdbeAddOp3(v, OP_NotExists, baseCur, 0, regRowid);
- switch( onError ){
- default: {
- onError = OE_Abort;
- /* Fall thru into the next case */
- }
- case OE_Rollback:
- case OE_Abort:
- case OE_Fail: {
- sqlite3HaltConstraint(
- pParse, onError, "PRIMARY KEY must be unique", P4_STATIC);
- break;
- }
- case OE_Replace: {
- /* If there are DELETE triggers on this table and the
- ** recursive-triggers flag is set, call GenerateRowDelete() to
- ** remove the conflicting row from the the table. This will fire
- ** the triggers and remove both the table and index b-tree entries.
- **
- ** Otherwise, if there are no triggers or the recursive-triggers
- ** flag is not set, call GenerateRowIndexDelete(). This removes
- ** the index b-tree entries only. The table b-tree entry will be
- ** replaced by the new entry when it is inserted. */
- Trigger *pTrigger = 0;
- if( pParse->db->flags&SQLITE_RecTriggers ){
- pTrigger = sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0);
- }
- if( pTrigger ){
- sqlite3GenerateRowDelete(
- pParse, pTab, baseCur, regRowid, 0, pTrigger, OE_Replace
- );
- }else{
- sqlite3GenerateRowIndexDelete(pParse, pTab, baseCur, 0);
- }
- seenReplace = 1;
- break;
- }
- case OE_Ignore: {
- assert( seenReplace==0 );
- sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest);
- break;
- }
- }
- sqlite3VdbeJumpHere(v, j3);
- if( isUpdate ){
- sqlite3VdbeJumpHere(v, j2);
- }
- }
- }
-
- /* Test all UNIQUE constraints by creating entries for each UNIQUE
- ** index and making sure that duplicate entries do not already exist.
- ** Add the new records to the indices as we go.
- */
- for(iCur=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, iCur++){
- int regIdx;
- int regR;
-
- if( aRegIdx[iCur]==0 ) continue; /* Skip unused indices */
-
- /* Create a key for accessing the index entry */
- regIdx = sqlite3GetTempRange(pParse, pIdx->nColumn+1);
- for(i=0; i<pIdx->nColumn; i++){
- int idx = pIdx->aiColumn[i];
- if( idx==pTab->iPKey ){
- sqlite3VdbeAddOp2(v, OP_SCopy, regRowid, regIdx+i);
- }else{
- sqlite3VdbeAddOp2(v, OP_SCopy, regData+idx, regIdx+i);
- }
- }
- sqlite3VdbeAddOp2(v, OP_SCopy, regRowid, regIdx+i);
- sqlite3VdbeAddOp3(v, OP_MakeRecord, regIdx, pIdx->nColumn+1, aRegIdx[iCur]);
- sqlite3VdbeChangeP4(v, -1, sqlite3IndexAffinityStr(v, pIdx), 0);
- sqlite3ExprCacheAffinityChange(pParse, regIdx, pIdx->nColumn+1);
-
- /* Find out what action to take in case there is an indexing conflict */
- onError = pIdx->onError;
- if( onError==OE_None ){
- sqlite3ReleaseTempRange(pParse, regIdx, pIdx->nColumn+1);
- continue; /* pIdx is not a UNIQUE index */
- }
- if( overrideError!=OE_Default ){
- onError = overrideError;
- }else if( onError==OE_Default ){
- onError = OE_Abort;
- }
- if( seenReplace ){
- if( onError==OE_Ignore ) onError = OE_Replace;
- else if( onError==OE_Fail ) onError = OE_Abort;
- }
-
- /* Check to see if the new index entry will be unique */
- regR = sqlite3GetTempReg(pParse);
- sqlite3VdbeAddOp2(v, OP_SCopy, regOldRowid, regR);
- j3 = sqlite3VdbeAddOp4(v, OP_IsUnique, baseCur+iCur+1, 0,
- regR, SQLITE_INT_TO_PTR(regIdx),
- P4_INT32);
- sqlite3ReleaseTempRange(pParse, regIdx, pIdx->nColumn+1);
-
- /* Generate code that executes if the new index entry is not unique */
- assert( onError==OE_Rollback || onError==OE_Abort || onError==OE_Fail
- || onError==OE_Ignore || onError==OE_Replace );
- switch( onError ){
- case OE_Rollback:
- case OE_Abort:
- case OE_Fail: {
- int j;
- StrAccum errMsg;
- const char *zSep;
- char *zErr;
-
- sqlite3StrAccumInit(&errMsg, 0, 0, 200);
- errMsg.db = pParse->db;
- zSep = pIdx->nColumn>1 ? "columns " : "column ";
- for(j=0; j<pIdx->nColumn; j++){
- char *zCol = pTab->aCol[pIdx->aiColumn[j]].zName;
- sqlite3StrAccumAppend(&errMsg, zSep, -1);
- zSep = ", ";
- sqlite3StrAccumAppend(&errMsg, zCol, -1);
- }
- sqlite3StrAccumAppend(&errMsg,
- pIdx->nColumn>1 ? " are not unique" : " is not unique", -1);
- zErr = sqlite3StrAccumFinish(&errMsg);
- sqlite3HaltConstraint(pParse, onError, zErr, 0);
- sqlite3DbFree(errMsg.db, zErr);
- break;
- }
- case OE_Ignore: {
- assert( seenReplace==0 );
- sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest);
- break;
- }
- default: {
- Trigger *pTrigger = 0;
- assert( onError==OE_Replace );
- if( pParse->db->flags&SQLITE_RecTriggers ){
- pTrigger = sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0);
- }
- sqlite3GenerateRowDelete(
- pParse, pTab, baseCur, regR, 0, pTrigger, OE_Replace
- );
- seenReplace = 1;
- break;
- }
- }
- sqlite3VdbeJumpHere(v, j3);
- sqlite3ReleaseTempReg(pParse, regR);
- }
-
- if( pbMayReplace ){
- *pbMayReplace = seenReplace;
- }
-}
-
-/*
-** This routine generates code to finish the INSERT or UPDATE operation
-** that was started by a prior call to sqlite3GenerateConstraintChecks.
-** A consecutive range of registers starting at regRowid contains the
-** rowid and the content to be inserted.
-**
-** The arguments to this routine should be the same as the first six
-** arguments to sqlite3GenerateConstraintChecks.
-*/
-SQLITE_PRIVATE void sqlite3CompleteInsertion(
- Parse *pParse, /* The parser context */
- Table *pTab, /* the table into which we are inserting */
- int baseCur, /* Index of a read/write cursor pointing at pTab */
- int regRowid, /* Range of content */
- int *aRegIdx, /* Register used by each index. 0 for unused indices */
- int isUpdate, /* True for UPDATE, False for INSERT */
- int appendBias, /* True if this is likely to be an append */
- int useSeekResult /* True to set the USESEEKRESULT flag on OP_[Idx]Insert */
-){
- int i;
- Vdbe *v;
- int nIdx;
- Index *pIdx;
- u8 pik_flags;
- int regData;
- int regRec;
-
- v = sqlite3GetVdbe(pParse);
- assert( v!=0 );
- assert( pTab->pSelect==0 ); /* This table is not a VIEW */
- for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){}
- for(i=nIdx-1; i>=0; i--){
- if( aRegIdx[i]==0 ) continue;
- sqlite3VdbeAddOp2(v, OP_IdxInsert, baseCur+i+1, aRegIdx[i]);
- if( useSeekResult ){
- sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
- }
- }
- regData = regRowid + 1;
- regRec = sqlite3GetTempReg(pParse);
- sqlite3VdbeAddOp3(v, OP_MakeRecord, regData, pTab->nCol, regRec);
- sqlite3TableAffinityStr(v, pTab);
- sqlite3ExprCacheAffinityChange(pParse, regData, pTab->nCol);
- if( pParse->nested ){
- pik_flags = 0;
- }else{
- pik_flags = OPFLAG_NCHANGE;
- pik_flags |= (isUpdate?OPFLAG_ISUPDATE:OPFLAG_LASTROWID);
- }
- if( appendBias ){
- pik_flags |= OPFLAG_APPEND;
- }
- if( useSeekResult ){
- pik_flags |= OPFLAG_USESEEKRESULT;
- }
- sqlite3VdbeAddOp3(v, OP_Insert, baseCur, regRec, regRowid);
- if( !pParse->nested ){
- sqlite3VdbeChangeP4(v, -1, pTab->zName, P4_STATIC);
- }
- sqlite3VdbeChangeP5(v, pik_flags);
-}
-
-/*
-** Generate code that will open cursors for a table and for all
-** indices of that table. The "baseCur" parameter is the cursor number used
-** for the table. Indices are opened on subsequent cursors.
-**
-** Return the number of indices on the table.
-*/
-SQLITE_PRIVATE int sqlite3OpenTableAndIndices(
- Parse *pParse, /* Parsing context */
- Table *pTab, /* Table to be opened */
- int baseCur, /* Cursor number assigned to the table */
- int op /* OP_OpenRead or OP_OpenWrite */
-){
- int i;
- int iDb;
- Index *pIdx;
- Vdbe *v;
-
- if( IsVirtual(pTab) ) return 0;
- iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
- v = sqlite3GetVdbe(pParse);
- assert( v!=0 );
- sqlite3OpenTable(pParse, baseCur, iDb, pTab, op);
- for(i=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
- KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx);
- assert( pIdx->pSchema==pTab->pSchema );
- sqlite3VdbeAddOp4(v, op, i+baseCur, pIdx->tnum, iDb,
- (char*)pKey, P4_KEYINFO_HANDOFF);
- VdbeComment((v, "%s", pIdx->zName));
- }
- if( pParse->nTab<baseCur+i ){
- pParse->nTab = baseCur+i;
- }
- return i-1;
-}
-
-
-#ifdef SQLITE_TEST
-/*
-** The following global variable is incremented whenever the
-** transfer optimization is used. This is used for testing
-** purposes only - to make sure the transfer optimization really
-** is happening when it is suppose to.
-*/
-SQLITE_API int sqlite3_xferopt_count;
-#endif /* SQLITE_TEST */
-
-
-#ifndef SQLITE_OMIT_XFER_OPT
-/*
-** Check to collation names to see if they are compatible.
-*/
-static int xferCompatibleCollation(const char *z1, const char *z2){
- if( z1==0 ){
- return z2==0;
- }
- if( z2==0 ){
- return 0;
- }
- return sqlite3StrICmp(z1, z2)==0;
-}
-
-
-/*
-** Check to see if index pSrc is compatible as a source of data
-** for index pDest in an insert transfer optimization. The rules
-** for a compatible index:
-**
-** * The index is over the same set of columns
-** * The same DESC and ASC markings occurs on all columns
-** * The same onError processing (OE_Abort, OE_Ignore, etc)
-** * The same collating sequence on each column
-*/
-static int xferCompatibleIndex(Index *pDest, Index *pSrc){
- int i;
- assert( pDest && pSrc );
- assert( pDest->pTable!=pSrc->pTable );
- if( pDest->nColumn!=pSrc->nColumn ){
- return 0; /* Different number of columns */
- }
- if( pDest->onError!=pSrc->onError ){
- return 0; /* Different conflict resolution strategies */
- }
- for(i=0; i<pSrc->nColumn; i++){
- if( pSrc->aiColumn[i]!=pDest->aiColumn[i] ){
- return 0; /* Different columns indexed */
- }
- if( pSrc->aSortOrder[i]!=pDest->aSortOrder[i] ){
- return 0; /* Different sort orders */
- }
- if( !xferCompatibleCollation(pSrc->azColl[i],pDest->azColl[i]) ){
- return 0; /* Different collating sequences */
- }
- }
-
- /* If no test above fails then the indices must be compatible */
- return 1;
-}
-
-/*
-** Attempt the transfer optimization on INSERTs of the form
-**
-** INSERT INTO tab1 SELECT * FROM tab2;
-**
-** This optimization is only attempted if
-**
-** (1) tab1 and tab2 have identical schemas including all the
-** same indices and constraints
-**
-** (2) tab1 and tab2 are different tables
-**
-** (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.
-*/
-static int xferOptimization(
- Parse *pParse, /* Parser context */
- Table *pDest, /* The table we are inserting into */
- Select *pSelect, /* A SELECT statement to use as the data source */
- int onError, /* How to handle constraint errors */
- int iDbDest /* The database of pDest */
-){
- ExprList *pEList; /* The result set of the SELECT */
- Table *pSrc; /* The table in the FROM clause of SELECT */
- Index *pSrcIdx, *pDestIdx; /* Source and destination indices */
- struct SrcList_item *pItem; /* An element of pSelect->pSrc */
- int i; /* Loop counter */
- int iDbSrc; /* The database of pSrc */
- int iSrc, iDest; /* Cursors from source and destination */
- int addr1, addr2; /* Loop addresses */
- int emptyDestTest; /* Address of test for empty pDest */
- int emptySrcTest; /* Address of test for empty pSrc */
- Vdbe *v; /* The VDBE we are building */
- KeyInfo *pKey; /* Key information for an index */
- int regAutoinc; /* Memory register used by AUTOINC */
- int destHasUniqueIdx = 0; /* True if pDest has a UNIQUE index */
- int regData, regRowid; /* Registers holding data and rowid */
-
- if( pSelect==0 ){
- return 0; /* Must be of the form INSERT INTO ... SELECT ... */
- }
- if( sqlite3TriggerList(pParse, pDest) ){
- return 0; /* tab1 must not have triggers */
- }
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- if( pDest->tabFlags & TF_Virtual ){
- return 0; /* tab1 must not be a virtual table */
- }
-#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 */
- }
- assert(pSelect->pSrc); /* allocated even if there is no FROM clause */
- if( pSelect->pSrc->nSrc!=1 ){
- return 0; /* FROM clause must have exactly one term */
- }
- if( pSelect->pSrc->a[0].pSelect ){
- return 0; /* FROM clause cannot contain a subquery */
- }
- if( pSelect->pWhere ){
- return 0; /* SELECT may not have a WHERE clause */
- }
- if( pSelect->pOrderBy ){
- return 0; /* SELECT may not have an ORDER BY clause */
- }
- /* Do not need to test for a HAVING clause. If HAVING is present but
- ** there is no ORDER BY, we will get an error. */
- if( pSelect->pGroupBy ){
- return 0; /* SELECT may not have a GROUP BY clause */
- }
- if( pSelect->pLimit ){
- return 0; /* SELECT may not have a LIMIT clause */
- }
- assert( pSelect->pOffset==0 ); /* Must be so if pLimit==0 */
- if( pSelect->pPrior ){
- return 0; /* SELECT may not be a compound query */
- }
- if( pSelect->selFlags & SF_Distinct ){
- return 0; /* SELECT may not be DISTINCT */
- }
- pEList = pSelect->pEList;
- assert( pEList!=0 );
- if( pEList->nExpr!=1 ){
- return 0; /* The result set must have exactly one column */
- }
- assert( pEList->a[0].pExpr );
- if( pEList->a[0].pExpr->op!=TK_ALL ){
- return 0; /* The result set must be the special operator "*" */
- }
-
- /* At this point we have established that the statement is of the
- ** correct syntactic form to participate in this optimization. Now
- ** we have to check the semantics.
- */
- pItem = pSelect->pSrc->a;
- pSrc = sqlite3LocateTable(pParse, 0, pItem->zName, pItem->zDatabase);
- if( pSrc==0 ){
- return 0; /* FROM clause does not contain a real table */
- }
- if( pSrc==pDest ){
- return 0; /* tab1 and tab2 may not be the same table */
- }
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- if( pSrc->tabFlags & TF_Virtual ){
- return 0; /* tab2 must not be a virtual table */
- }
-#endif
- if( pSrc->pSelect ){
- return 0; /* tab2 may not be a view */
- }
- if( pDest->nCol!=pSrc->nCol ){
- return 0; /* Number of columns must be the same in tab1 and tab2 */
- }
- if( pDest->iPKey!=pSrc->iPKey ){
- return 0; /* Both tables must have the same INTEGER PRIMARY KEY */
- }
- for(i=0; i<pDest->nCol; i++){
- if( pDest->aCol[i].affinity!=pSrc->aCol[i].affinity ){
- return 0; /* Affinity must be the same on all columns */
- }
- if( !xferCompatibleCollation(pDest->aCol[i].zColl, pSrc->aCol[i].zColl) ){
- return 0; /* Collating sequence must be the same on all columns */
- }
- if( pDest->aCol[i].notNull && !pSrc->aCol[i].notNull ){
- return 0; /* tab2 must be NOT NULL if tab1 is */
- }
- }
- for(pDestIdx=pDest->pIndex; pDestIdx; pDestIdx=pDestIdx->pNext){
- if( pDestIdx->onError!=OE_None ){
- destHasUniqueIdx = 1;
- }
- for(pSrcIdx=pSrc->pIndex; pSrcIdx; pSrcIdx=pSrcIdx->pNext){
- if( xferCompatibleIndex(pDestIdx, pSrcIdx) ) break;
- }
- if( pSrcIdx==0 ){
- return 0; /* pDestIdx has no corresponding index in pSrc */
- }
- }
-#ifndef SQLITE_OMIT_CHECK
- if( pDest->pCheck && !sqlite3ExprCompare(pSrc->pCheck, pDest->pCheck) ){
- return 0; /* Tables have different CHECK constraints. Ticket #2252 */
- }
-#endif
-
- /* 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.
- */
-#ifdef SQLITE_TEST
- sqlite3_xferopt_count++;
-#endif
- iDbSrc = sqlite3SchemaToIndex(pParse->db, pSrc->pSchema);
- v = sqlite3GetVdbe(pParse);
- sqlite3CodeVerifySchema(pParse, iDbSrc);
- iSrc = pParse->nTab++;
- 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.
- **
- ** 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.
- */
- addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iDest, 0);
- emptyDestTest = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0);
- sqlite3VdbeJumpHere(v, addr1);
- }else{
- emptyDestTest = 0;
- }
- sqlite3OpenTable(pParse, iSrc, iDbSrc, pSrc, OP_OpenRead);
- emptySrcTest = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0);
- regData = sqlite3GetTempReg(pParse);
- regRowid = sqlite3GetTempReg(pParse);
- if( pDest->iPKey>=0 ){
- addr1 = sqlite3VdbeAddOp2(v, OP_Rowid, iSrc, regRowid);
- addr2 = sqlite3VdbeAddOp3(v, OP_NotExists, iDest, 0, regRowid);
- sqlite3HaltConstraint(
- pParse, onError, "PRIMARY KEY must be unique", P4_STATIC);
- sqlite3VdbeJumpHere(v, addr2);
- autoIncStep(pParse, regAutoinc, regRowid);
- }else if( pDest->pIndex==0 ){
- addr1 = sqlite3VdbeAddOp2(v, OP_NewRowid, iDest, regRowid);
- }else{
- addr1 = sqlite3VdbeAddOp2(v, OP_Rowid, iSrc, regRowid);
- assert( (pDest->tabFlags & TF_Autoincrement)==0 );
- }
- sqlite3VdbeAddOp2(v, OP_RowData, iSrc, regData);
- sqlite3VdbeAddOp3(v, OP_Insert, iDest, regData, regRowid);
- sqlite3VdbeChangeP5(v, OPFLAG_NCHANGE|OPFLAG_LASTROWID|OPFLAG_APPEND);
- sqlite3VdbeChangeP4(v, -1, pDest->zName, 0);
- sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1);
- for(pDestIdx=pDest->pIndex; pDestIdx; pDestIdx=pDestIdx->pNext){
- for(pSrcIdx=pSrc->pIndex; ALWAYS(pSrcIdx); pSrcIdx=pSrcIdx->pNext){
- if( xferCompatibleIndex(pDestIdx, pSrcIdx) ) break;
- }
- assert( pSrcIdx );
- sqlite3VdbeAddOp2(v, OP_Close, iSrc, 0);
- sqlite3VdbeAddOp2(v, OP_Close, iDest, 0);
- pKey = sqlite3IndexKeyinfo(pParse, pSrcIdx);
- sqlite3VdbeAddOp4(v, OP_OpenRead, iSrc, pSrcIdx->tnum, iDbSrc,
- (char*)pKey, P4_KEYINFO_HANDOFF);
- VdbeComment((v, "%s", pSrcIdx->zName));
- pKey = sqlite3IndexKeyinfo(pParse, pDestIdx);
- sqlite3VdbeAddOp4(v, OP_OpenWrite, iDest, pDestIdx->tnum, iDbDest,
- (char*)pKey, P4_KEYINFO_HANDOFF);
- VdbeComment((v, "%s", pDestIdx->zName));
- addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0);
- sqlite3VdbeAddOp2(v, OP_RowKey, iSrc, regData);
- sqlite3VdbeAddOp3(v, OP_IdxInsert, iDest, regData, 1);
- sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1+1);
- sqlite3VdbeJumpHere(v, addr1);
- }
- sqlite3VdbeJumpHere(v, emptySrcTest);
- sqlite3ReleaseTempReg(pParse, regRowid);
- sqlite3ReleaseTempReg(pParse, regData);
- sqlite3VdbeAddOp2(v, OP_Close, iSrc, 0);
- sqlite3VdbeAddOp2(v, OP_Close, iDest, 0);
- if( emptyDestTest ){
- sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_OK, 0);
- sqlite3VdbeJumpHere(v, emptyDestTest);
- sqlite3VdbeAddOp2(v, OP_Close, iDest, 0);
- return 0;
- }else{
- return 1;
- }
-}
-#endif /* SQLITE_OMIT_XFER_OPT */
-
-/* Make sure "isView" gets undefined in case this file becomes part of
-** the amalgamation - so that subsequent files do not see isView as a
-** macro. */
-#undef isView
-
-/************** End of insert.c **********************************************/
-/************** Begin file legacy.c ******************************************/
-/*
-** 2001 September 15
-**
-** 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.
-**
-*************************************************************************
-** Main file for the SQLite library. The routines in this file
-** implement the programmer interface to the library. Routines in
-** other files are for internal use by SQLite and should not be
-** accessed by users of the library.
-**
-** $Id: legacy.c,v 1.35 2009/08/07 16:56:00 danielk1977 Exp $
-*/
-
-
-/*
-** Execute SQL code. Return one of the SQLITE_ success/failure
-** codes. Also write an error message into memory obtained from
-** malloc() and make *pzErrMsg point to that message.
-**
-** If the SQL is a query, then for each row in the query result
-** the xCallback() function is called. pArg becomes the first
-** argument to xCallback(). If xCallback=NULL then no callback
-** is invoked, even for queries.
-*/
-SQLITE_API int sqlite3_exec(
- sqlite3 *db, /* The database on which the SQL executes */
- const char *zSql, /* The SQL to be executed */
- sqlite3_callback xCallback, /* Invoke this callback routine */
- void *pArg, /* First argument to xCallback() */
- char **pzErrMsg /* Write error messages here */
-){
- int rc = SQLITE_OK; /* Return code */
- const char *zLeftover; /* Tail of unprocessed SQL */
- sqlite3_stmt *pStmt = 0; /* The current SQL statement */
- char **azCols = 0; /* Names of result columns */
- int nRetry = 0; /* Number of retry attempts */
- int callbackIsInit; /* True if callback data is initialized */
-
- if( zSql==0 ) zSql = "";
-
- sqlite3_mutex_enter(db->mutex);
- sqlite3Error(db, SQLITE_OK, 0);
- while( (rc==SQLITE_OK || (rc==SQLITE_SCHEMA && (++nRetry)<2)) && zSql[0] ){
- int nCol;
- char **azVals = 0;
-
- pStmt = 0;
- rc = sqlite3_prepare(db, zSql, -1, &pStmt, &zLeftover);
- assert( rc==SQLITE_OK || pStmt==0 );
- if( rc!=SQLITE_OK ){
- continue;
- }
- if( !pStmt ){
- /* this happens for a comment or white-space */
- zSql = zLeftover;
- continue;
- }
-
- callbackIsInit = 0;
- nCol = sqlite3_column_count(pStmt);
-
- while( 1 ){
- int i;
- rc = sqlite3_step(pStmt);
-
- /* Invoke the callback function if required */
- if( xCallback && (SQLITE_ROW==rc ||
- (SQLITE_DONE==rc && !callbackIsInit
- && db->flags&SQLITE_NullCallback)) ){
- if( !callbackIsInit ){
- azCols = sqlite3DbMallocZero(db, 2*nCol*sizeof(const char*) + 1);
- if( azCols==0 ){
- goto exec_out;
- }
- for(i=0; i<nCol; i++){
- azCols[i] = (char *)sqlite3_column_name(pStmt, i);
- /* sqlite3VdbeSetColName() installs column names as UTF8
- ** strings so there is no way for sqlite3_column_name() to fail. */
- assert( azCols[i]!=0 );
- }
- callbackIsInit = 1;
- }
- if( rc==SQLITE_ROW ){
- azVals = &azCols[nCol];
- for(i=0; i<nCol; i++){
- azVals[i] = (char *)sqlite3_column_text(pStmt, i);
- if( !azVals[i] && sqlite3_column_type(pStmt, i)!=SQLITE_NULL ){
- db->mallocFailed = 1;
- goto exec_out;
- }
- }
- }
- if( xCallback(pArg, nCol, azVals, azCols) ){
- rc = SQLITE_ABORT;
- sqlite3VdbeFinalize((Vdbe *)pStmt);
- pStmt = 0;
- sqlite3Error(db, SQLITE_ABORT, 0);
- goto exec_out;
- }
- }
-
- if( rc!=SQLITE_ROW ){
- rc = sqlite3VdbeFinalize((Vdbe *)pStmt);
- pStmt = 0;
- if( rc!=SQLITE_SCHEMA ){
- nRetry = 0;
- zSql = zLeftover;
- while( sqlite3Isspace(zSql[0]) ) zSql++;
- }
- break;
- }
- }
-
- sqlite3DbFree(db, azCols);
- azCols = 0;
- }
-
-exec_out:
- if( pStmt ) sqlite3VdbeFinalize((Vdbe *)pStmt);
- sqlite3DbFree(db, azCols);
-
- rc = sqlite3ApiExit(db, rc);
- if( rc!=SQLITE_OK && ALWAYS(rc==sqlite3_errcode(db)) && pzErrMsg ){
- int nErrMsg = 1 + sqlite3Strlen30(sqlite3_errmsg(db));
- *pzErrMsg = sqlite3Malloc(nErrMsg);
- if( *pzErrMsg ){
- memcpy(*pzErrMsg, sqlite3_errmsg(db), nErrMsg);
- }else{
- rc = SQLITE_NOMEM;
- sqlite3Error(db, SQLITE_NOMEM, 0);
- }
- }else if( pzErrMsg ){
- *pzErrMsg = 0;
- }
-
- assert( (rc&db->errMask)==rc );
- sqlite3_mutex_leave(db->mutex);
- return rc;
-}
-
-/************** End of legacy.c **********************************************/
-/************** Begin file loadext.c *****************************************/
-/*
-** 2006 June 7
-**
-** 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 code used to dynamically load extensions into
-** the SQLite library.
-**
-** $Id: loadext.c,v 1.60 2009/06/03 01:24:54 drh Exp $
-*/
-
-#ifndef SQLITE_CORE
- #define SQLITE_CORE 1 /* Disable the API redefinition in sqlite3ext.h */
-#endif
-/************** Include sqlite3ext.h in the middle of loadext.c **************/
-/************** Begin file sqlite3ext.h **************************************/
-/*
-** 2006 June 7
-**
-** 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 header file defines the SQLite interface for use by
-** shared libraries that want to be imported as extensions into
-** an SQLite instance. Shared libraries that intend to be loaded
-** as extensions by SQLite should #include this file instead of
-** sqlite3.h.
-**
-** @(#) $Id: sqlite3ext.h,v 1.25 2008/10/12 00:27:54 shane Exp $
-*/
-#ifndef _SQLITE3EXT_H_
-#define _SQLITE3EXT_H_
-
-typedef struct sqlite3_api_routines sqlite3_api_routines;
-
-/*
-** The following structure holds pointers to all of the SQLite API
-** routines.
-**
-** WARNING: In order to maintain backwards compatibility, add new
-** interfaces to the end of this structure only. If you insert new
-** interfaces in the middle of this structure, then older different
-** versions of SQLite will not be able to load each others' shared
-** libraries!
-*/
-struct sqlite3_api_routines {
- void * (*aggregate_context)(sqlite3_context*,int nBytes);
- int (*aggregate_count)(sqlite3_context*);
- int (*bind_blob)(sqlite3_stmt*,int,const void*,int n,void(*)(void*));
- int (*bind_double)(sqlite3_stmt*,int,double);
- int (*bind_int)(sqlite3_stmt*,int,int);
- int (*bind_int64)(sqlite3_stmt*,int,sqlite_int64);
- int (*bind_null)(sqlite3_stmt*,int);
- int (*bind_parameter_count)(sqlite3_stmt*);
- int (*bind_parameter_index)(sqlite3_stmt*,const char*zName);
- const char * (*bind_parameter_name)(sqlite3_stmt*,int);
- int (*bind_text)(sqlite3_stmt*,int,const char*,int n,void(*)(void*));
- int (*bind_text16)(sqlite3_stmt*,int,const void*,int,void(*)(void*));
- int (*bind_value)(sqlite3_stmt*,int,const sqlite3_value*);
- int (*busy_handler)(sqlite3*,int(*)(void*,int),void*);
- int (*busy_timeout)(sqlite3*,int ms);
- int (*changes)(sqlite3*);
- int (*close)(sqlite3*);
- int (*collation_needed)(sqlite3*,void*,void(*)(void*,sqlite3*,int eTextRep,const char*));
- int (*collation_needed16)(sqlite3*,void*,void(*)(void*,sqlite3*,int eTextRep,const void*));
- const void * (*column_blob)(sqlite3_stmt*,int iCol);
- int (*column_bytes)(sqlite3_stmt*,int iCol);
- int (*column_bytes16)(sqlite3_stmt*,int iCol);
- int (*column_count)(sqlite3_stmt*pStmt);
- const char * (*column_database_name)(sqlite3_stmt*,int);
- const void * (*column_database_name16)(sqlite3_stmt*,int);
- const char * (*column_decltype)(sqlite3_stmt*,int i);
- const void * (*column_decltype16)(sqlite3_stmt*,int);
- double (*column_double)(sqlite3_stmt*,int iCol);
- int (*column_int)(sqlite3_stmt*,int iCol);
- sqlite_int64 (*column_int64)(sqlite3_stmt*,int iCol);
- const char * (*column_name)(sqlite3_stmt*,int);
- const void * (*column_name16)(sqlite3_stmt*,int);
- const char * (*column_origin_name)(sqlite3_stmt*,int);
- const void * (*column_origin_name16)(sqlite3_stmt*,int);
- const char * (*column_table_name)(sqlite3_stmt*,int);
- const void * (*column_table_name16)(sqlite3_stmt*,int);
- const unsigned char * (*column_text)(sqlite3_stmt*,int iCol);
- const void * (*column_text16)(sqlite3_stmt*,int iCol);
- int (*column_type)(sqlite3_stmt*,int iCol);
- sqlite3_value* (*column_value)(sqlite3_stmt*,int iCol);
- void * (*commit_hook)(sqlite3*,int(*)(void*),void*);
- int (*complete)(const char*sql);
- int (*complete16)(const void*sql);
- int (*create_collation)(sqlite3*,const char*,int,void*,int(*)(void*,int,const void*,int,const void*));
- int (*create_collation16)(sqlite3*,const void*,int,void*,int(*)(void*,int,const void*,int,const void*));
- int (*create_function)(sqlite3*,const char*,int,int,void*,void (*xFunc)(sqlite3_context*,int,sqlite3_value**),void (*xStep)(sqlite3_context*,int,sqlite3_value**),void (*xFinal)(sqlite3_context*));
- int (*create_function16)(sqlite3*,const void*,int,int,void*,void (*xFunc)(sqlite3_context*,int,sqlite3_value**),void (*xStep)(sqlite3_context*,int,sqlite3_value**),void (*xFinal)(sqlite3_context*));
- int (*create_module)(sqlite3*,const char*,const sqlite3_module*,void*);
- int (*data_count)(sqlite3_stmt*pStmt);
- sqlite3 * (*db_handle)(sqlite3_stmt*);
- int (*declare_vtab)(sqlite3*,const char*);
- int (*enable_shared_cache)(int);
- int (*errcode)(sqlite3*db);
- const char * (*errmsg)(sqlite3*);
- const void * (*errmsg16)(sqlite3*);
- int (*exec)(sqlite3*,const char*,sqlite3_callback,void*,char**);
- int (*expired)(sqlite3_stmt*);
- int (*finalize)(sqlite3_stmt*pStmt);
- void (*free)(void*);
- void (*free_table)(char**result);
- int (*get_autocommit)(sqlite3*);
- void * (*get_auxdata)(sqlite3_context*,int);
- int (*get_table)(sqlite3*,const char*,char***,int*,int*,char**);
- int (*global_recover)(void);
- void (*interruptx)(sqlite3*);
- sqlite_int64 (*last_insert_rowid)(sqlite3*);
- const char * (*libversion)(void);
- int (*libversion_number)(void);
- void *(*malloc)(int);
- char * (*mprintf)(const char*,...);
- int (*open)(const char*,sqlite3**);
- int (*open16)(const void*,sqlite3**);
- int (*prepare)(sqlite3*,const char*,int,sqlite3_stmt**,const char**);
- int (*prepare16)(sqlite3*,const void*,int,sqlite3_stmt**,const void**);
- void * (*profile)(sqlite3*,void(*)(void*,const char*,sqlite_uint64),void*);
- void (*progress_handler)(sqlite3*,int,int(*)(void*),void*);
- void *(*realloc)(void*,int);
- int (*reset)(sqlite3_stmt*pStmt);
- void (*result_blob)(sqlite3_context*,const void*,int,void(*)(void*));
- void (*result_double)(sqlite3_context*,double);
- void (*result_error)(sqlite3_context*,const char*,int);
- void (*result_error16)(sqlite3_context*,const void*,int);
- void (*result_int)(sqlite3_context*,int);
- void (*result_int64)(sqlite3_context*,sqlite_int64);
- void (*result_null)(sqlite3_context*);
- void (*result_text)(sqlite3_context*,const char*,int,void(*)(void*));
- void (*result_text16)(sqlite3_context*,const void*,int,void(*)(void*));
- void (*result_text16be)(sqlite3_context*,const void*,int,void(*)(void*));
- void (*result_text16le)(sqlite3_context*,const void*,int,void(*)(void*));
- void (*result_value)(sqlite3_context*,sqlite3_value*);
- void * (*rollback_hook)(sqlite3*,void(*)(void*),void*);
- int (*set_authorizer)(sqlite3*,int(*)(void*,int,const char*,const char*,const char*,const char*),void*);
- void (*set_auxdata)(sqlite3_context*,int,void*,void (*)(void*));
- char * (*snprintf)(int,char*,const char*,...);
- int (*step)(sqlite3_stmt*);
- int (*table_column_metadata)(sqlite3*,const char*,const char*,const char*,char const**,char const**,int*,int*,int*);
- void (*thread_cleanup)(void);
- int (*total_changes)(sqlite3*);
- void * (*trace)(sqlite3*,void(*xTrace)(void*,const char*),void*);
- int (*transfer_bindings)(sqlite3_stmt*,sqlite3_stmt*);
- void * (*update_hook)(sqlite3*,void(*)(void*,int ,char const*,char const*,sqlite_int64),void*);
- void * (*user_data)(sqlite3_context*);
- const void * (*value_blob)(sqlite3_value*);
- int (*value_bytes)(sqlite3_value*);
- int (*value_bytes16)(sqlite3_value*);
- double (*value_double)(sqlite3_value*);
- int (*value_int)(sqlite3_value*);
- sqlite_int64 (*value_int64)(sqlite3_value*);
- int (*value_numeric_type)(sqlite3_value*);
- const unsigned char * (*value_text)(sqlite3_value*);
- const void * (*value_text16)(sqlite3_value*);
- const void * (*value_text16be)(sqlite3_value*);
- const void * (*value_text16le)(sqlite3_value*);
- int (*value_type)(sqlite3_value*);
- char *(*vmprintf)(const char*,va_list);
- /* Added ??? */
- int (*overload_function)(sqlite3*, const char *zFuncName, int nArg);
- /* Added by 3.3.13 */
- int (*prepare_v2)(sqlite3*,const char*,int,sqlite3_stmt**,const char**);
- int (*prepare16_v2)(sqlite3*,const void*,int,sqlite3_stmt**,const void**);
- int (*clear_bindings)(sqlite3_stmt*);
- /* Added by 3.4.1 */
- int (*create_module_v2)(sqlite3*,const char*,const sqlite3_module*,void*,void (*xDestroy)(void *));
- /* Added by 3.5.0 */
- int (*bind_zeroblob)(sqlite3_stmt*,int,int);
- int (*blob_bytes)(sqlite3_blob*);
- int (*blob_close)(sqlite3_blob*);
- int (*blob_open)(sqlite3*,const char*,const char*,const char*,sqlite3_int64,int,sqlite3_blob**);
- int (*blob_read)(sqlite3_blob*,void*,int,int);
- int (*blob_write)(sqlite3_blob*,const void*,int,int);
- int (*create_collation_v2)(sqlite3*,const char*,int,void*,int(*)(void*,int,const void*,int,const void*),void(*)(void*));
- int (*file_control)(sqlite3*,const char*,int,void*);
- sqlite3_int64 (*memory_highwater)(int);
- sqlite3_int64 (*memory_used)(void);
- sqlite3_mutex *(*mutex_alloc)(int);
- void (*mutex_enter)(sqlite3_mutex*);
- void (*mutex_free)(sqlite3_mutex*);
- void (*mutex_leave)(sqlite3_mutex*);
- int (*mutex_try)(sqlite3_mutex*);
- int (*open_v2)(const char*,sqlite3**,int,const char*);
- int (*release_memory)(int);
- void (*result_error_nomem)(sqlite3_context*);
- void (*result_error_toobig)(sqlite3_context*);
- int (*sleep)(int);
- void (*soft_heap_limit)(int);
- sqlite3_vfs *(*vfs_find)(const char*);
- int (*vfs_register)(sqlite3_vfs*,int);
- int (*vfs_unregister)(sqlite3_vfs*);
- int (*xthreadsafe)(void);
- void (*result_zeroblob)(sqlite3_context*,int);
- void (*result_error_code)(sqlite3_context*,int);
- int (*test_control)(int, ...);
- void (*randomness)(int,void*);
- sqlite3 *(*context_db_handle)(sqlite3_context*);
- int (*extended_result_codes)(sqlite3*,int);
- int (*limit)(sqlite3*,int,int);
- sqlite3_stmt *(*next_stmt)(sqlite3*,sqlite3_stmt*);
- const char *(*sql)(sqlite3_stmt*);
- int (*status)(int,int*,int*,int);
-};
-
-/*
-** The following macros redefine the API routines so that they are
-** redirected throught the global sqlite3_api structure.
-**
-** This header file is also used by the loadext.c source file
-** (part of the main SQLite library - not an extension) so that
-** it can get access to the sqlite3_api_routines structure
-** definition. But the main library does not want to redefine
-** the API. So the redefinition macros are only valid if the
-** SQLITE_CORE macros is undefined.
-*/
-#ifndef SQLITE_CORE
-#define sqlite3_aggregate_context sqlite3_api->aggregate_context
-#ifndef SQLITE_OMIT_DEPRECATED
-#define sqlite3_aggregate_count sqlite3_api->aggregate_count
-#endif
-#define sqlite3_bind_blob sqlite3_api->bind_blob
-#define sqlite3_bind_double sqlite3_api->bind_double
-#define sqlite3_bind_int sqlite3_api->bind_int
-#define sqlite3_bind_int64 sqlite3_api->bind_int64
-#define sqlite3_bind_null sqlite3_api->bind_null
-#define sqlite3_bind_parameter_count sqlite3_api->bind_parameter_count
-#define sqlite3_bind_parameter_index sqlite3_api->bind_parameter_index
-#define sqlite3_bind_parameter_name sqlite3_api->bind_parameter_name
-#define sqlite3_bind_text sqlite3_api->bind_text
-#define sqlite3_bind_text16 sqlite3_api->bind_text16
-#define sqlite3_bind_value sqlite3_api->bind_value
-#define sqlite3_busy_handler sqlite3_api->busy_handler
-#define sqlite3_busy_timeout sqlite3_api->busy_timeout
-#define sqlite3_changes sqlite3_api->changes
-#define sqlite3_close sqlite3_api->close
-#define sqlite3_collation_needed sqlite3_api->collation_needed
-#define sqlite3_collation_needed16 sqlite3_api->collation_needed16
-#define sqlite3_column_blob sqlite3_api->column_blob
-#define sqlite3_column_bytes sqlite3_api->column_bytes
-#define sqlite3_column_bytes16 sqlite3_api->column_bytes16
-#define sqlite3_column_count sqlite3_api->column_count
-#define sqlite3_column_database_name sqlite3_api->column_database_name
-#define sqlite3_column_database_name16 sqlite3_api->column_database_name16
-#define sqlite3_column_decltype sqlite3_api->column_decltype
-#define sqlite3_column_decltype16 sqlite3_api->column_decltype16
-#define sqlite3_column_double sqlite3_api->column_double
-#define sqlite3_column_int sqlite3_api->column_int
-#define sqlite3_column_int64 sqlite3_api->column_int64
-#define sqlite3_column_name sqlite3_api->column_name
-#define sqlite3_column_name16 sqlite3_api->column_name16
-#define sqlite3_column_origin_name sqlite3_api->column_origin_name
-#define sqlite3_column_origin_name16 sqlite3_api->column_origin_name16
-#define sqlite3_column_table_name sqlite3_api->column_table_name
-#define sqlite3_column_table_name16 sqlite3_api->column_table_name16
-#define sqlite3_column_text sqlite3_api->column_text
-#define sqlite3_column_text16 sqlite3_api->column_text16
-#define sqlite3_column_type sqlite3_api->column_type
-#define sqlite3_column_value sqlite3_api->column_value
-#define sqlite3_commit_hook sqlite3_api->commit_hook
-#define sqlite3_complete sqlite3_api->complete
-#define sqlite3_complete16 sqlite3_api->complete16
-#define sqlite3_create_collation sqlite3_api->create_collation
-#define sqlite3_create_collation16 sqlite3_api->create_collation16
-#define sqlite3_create_function sqlite3_api->create_function
-#define sqlite3_create_function16 sqlite3_api->create_function16
-#define sqlite3_create_module sqlite3_api->create_module
-#define sqlite3_create_module_v2 sqlite3_api->create_module_v2
-#define sqlite3_data_count sqlite3_api->data_count
-#define sqlite3_db_handle sqlite3_api->db_handle
-#define sqlite3_declare_vtab sqlite3_api->declare_vtab
-#define sqlite3_enable_shared_cache sqlite3_api->enable_shared_cache
-#define sqlite3_errcode sqlite3_api->errcode
-#define sqlite3_errmsg sqlite3_api->errmsg
-#define sqlite3_errmsg16 sqlite3_api->errmsg16
-#define sqlite3_exec sqlite3_api->exec
-#ifndef SQLITE_OMIT_DEPRECATED
-#define sqlite3_expired sqlite3_api->expired
-#endif
-#define sqlite3_finalize sqlite3_api->finalize
-#define sqlite3_free sqlite3_api->free
-#define sqlite3_free_table sqlite3_api->free_table
-#define sqlite3_get_autocommit sqlite3_api->get_autocommit
-#define sqlite3_get_auxdata sqlite3_api->get_auxdata
-#define sqlite3_get_table sqlite3_api->get_table
-#ifndef SQLITE_OMIT_DEPRECATED
-#define sqlite3_global_recover sqlite3_api->global_recover
-#endif
-#define sqlite3_interrupt sqlite3_api->interruptx
-#define sqlite3_last_insert_rowid sqlite3_api->last_insert_rowid
-#define sqlite3_libversion sqlite3_api->libversion
-#define sqlite3_libversion_number sqlite3_api->libversion_number
-#define sqlite3_malloc sqlite3_api->malloc
-#define sqlite3_mprintf sqlite3_api->mprintf
-#define sqlite3_open sqlite3_api->open
-#define sqlite3_open16 sqlite3_api->open16
-#define sqlite3_prepare sqlite3_api->prepare
-#define sqlite3_prepare16 sqlite3_api->prepare16
-#define sqlite3_prepare_v2 sqlite3_api->prepare_v2
-#define sqlite3_prepare16_v2 sqlite3_api->prepare16_v2
-#define sqlite3_profile sqlite3_api->profile
-#define sqlite3_progress_handler sqlite3_api->progress_handler
-#define sqlite3_realloc sqlite3_api->realloc
-#define sqlite3_reset sqlite3_api->reset
-#define sqlite3_result_blob sqlite3_api->result_blob
-#define sqlite3_result_double sqlite3_api->result_double
-#define sqlite3_result_error sqlite3_api->result_error
-#define sqlite3_result_error16 sqlite3_api->result_error16
-#define sqlite3_result_int sqlite3_api->result_int
-#define sqlite3_result_int64 sqlite3_api->result_int64
-#define sqlite3_result_null sqlite3_api->result_null
-#define sqlite3_result_text sqlite3_api->result_text
-#define sqlite3_result_text16 sqlite3_api->result_text16
-#define sqlite3_result_text16be sqlite3_api->result_text16be
-#define sqlite3_result_text16le sqlite3_api->result_text16le
-#define sqlite3_result_value sqlite3_api->result_value
-#define sqlite3_rollback_hook sqlite3_api->rollback_hook
-#define sqlite3_set_authorizer sqlite3_api->set_authorizer
-#define sqlite3_set_auxdata sqlite3_api->set_auxdata
-#define sqlite3_snprintf sqlite3_api->snprintf
-#define sqlite3_step sqlite3_api->step
-#define sqlite3_table_column_metadata sqlite3_api->table_column_metadata
-#define sqlite3_thread_cleanup sqlite3_api->thread_cleanup
-#define sqlite3_total_changes sqlite3_api->total_changes
-#define sqlite3_trace sqlite3_api->trace
-#ifndef SQLITE_OMIT_DEPRECATED
-#define sqlite3_transfer_bindings sqlite3_api->transfer_bindings
-#endif
-#define sqlite3_update_hook sqlite3_api->update_hook
-#define sqlite3_user_data sqlite3_api->user_data
-#define sqlite3_value_blob sqlite3_api->value_blob
-#define sqlite3_value_bytes sqlite3_api->value_bytes
-#define sqlite3_value_bytes16 sqlite3_api->value_bytes16
-#define sqlite3_value_double sqlite3_api->value_double
-#define sqlite3_value_int sqlite3_api->value_int
-#define sqlite3_value_int64 sqlite3_api->value_int64
-#define sqlite3_value_numeric_type sqlite3_api->value_numeric_type
-#define sqlite3_value_text sqlite3_api->value_text
-#define sqlite3_value_text16 sqlite3_api->value_text16
-#define sqlite3_value_text16be sqlite3_api->value_text16be
-#define sqlite3_value_text16le sqlite3_api->value_text16le
-#define sqlite3_value_type sqlite3_api->value_type
-#define sqlite3_vmprintf sqlite3_api->vmprintf
-#define sqlite3_overload_function sqlite3_api->overload_function
-#define sqlite3_prepare_v2 sqlite3_api->prepare_v2
-#define sqlite3_prepare16_v2 sqlite3_api->prepare16_v2
-#define sqlite3_clear_bindings sqlite3_api->clear_bindings
-#define sqlite3_bind_zeroblob sqlite3_api->bind_zeroblob
-#define sqlite3_blob_bytes sqlite3_api->blob_bytes
-#define sqlite3_blob_close sqlite3_api->blob_close
-#define sqlite3_blob_open sqlite3_api->blob_open
-#define sqlite3_blob_read sqlite3_api->blob_read
-#define sqlite3_blob_write sqlite3_api->blob_write
-#define sqlite3_create_collation_v2 sqlite3_api->create_collation_v2
-#define sqlite3_file_control sqlite3_api->file_control
-#define sqlite3_memory_highwater sqlite3_api->memory_highwater
-#define sqlite3_memory_used sqlite3_api->memory_used
-#define sqlite3_mutex_alloc sqlite3_api->mutex_alloc
-#define sqlite3_mutex_enter sqlite3_api->mutex_enter
-#define sqlite3_mutex_free sqlite3_api->mutex_free
-#define sqlite3_mutex_leave sqlite3_api->mutex_leave
-#define sqlite3_mutex_try sqlite3_api->mutex_try
-#define sqlite3_open_v2 sqlite3_api->open_v2
-#define sqlite3_release_memory sqlite3_api->release_memory
-#define sqlite3_result_error_nomem sqlite3_api->result_error_nomem
-#define sqlite3_result_error_toobig sqlite3_api->result_error_toobig
-#define sqlite3_sleep sqlite3_api->sleep
-#define sqlite3_soft_heap_limit sqlite3_api->soft_heap_limit
-#define sqlite3_vfs_find sqlite3_api->vfs_find
-#define sqlite3_vfs_register sqlite3_api->vfs_register
-#define sqlite3_vfs_unregister sqlite3_api->vfs_unregister
-#define sqlite3_threadsafe sqlite3_api->xthreadsafe
-#define sqlite3_result_zeroblob sqlite3_api->result_zeroblob
-#define sqlite3_result_error_code sqlite3_api->result_error_code
-#define sqlite3_test_control sqlite3_api->test_control
-#define sqlite3_randomness sqlite3_api->randomness
-#define sqlite3_context_db_handle sqlite3_api->context_db_handle
-#define sqlite3_extended_result_codes sqlite3_api->extended_result_codes
-#define sqlite3_limit sqlite3_api->limit
-#define sqlite3_next_stmt sqlite3_api->next_stmt
-#define sqlite3_sql sqlite3_api->sql
-#define sqlite3_status sqlite3_api->status
-#endif /* SQLITE_CORE */
-
-#define SQLITE_EXTENSION_INIT1 const sqlite3_api_routines *sqlite3_api = 0;
-#define SQLITE_EXTENSION_INIT2(v) sqlite3_api = v;
-
-#endif /* _SQLITE3EXT_H_ */
-
-/************** End of sqlite3ext.h ******************************************/
-/************** Continuing where we left off in loadext.c ********************/
-
-#ifndef SQLITE_OMIT_LOAD_EXTENSION
-
-/*
-** Some API routines are omitted when various features are
-** excluded from a build of SQLite. Substitute a NULL pointer
-** for any missing APIs.
-*/
-#ifndef SQLITE_ENABLE_COLUMN_METADATA
-# define sqlite3_column_database_name 0
-# define sqlite3_column_database_name16 0
-# define sqlite3_column_table_name 0
-# define sqlite3_column_table_name16 0
-# define sqlite3_column_origin_name 0
-# define sqlite3_column_origin_name16 0
-# define sqlite3_table_column_metadata 0
-#endif
-
-#ifdef SQLITE_OMIT_AUTHORIZATION
-# define sqlite3_set_authorizer 0
-#endif
-
-#ifdef SQLITE_OMIT_UTF16
-# define sqlite3_bind_text16 0
-# define sqlite3_collation_needed16 0
-# define sqlite3_column_decltype16 0
-# define sqlite3_column_name16 0
-# define sqlite3_column_text16 0
-# define sqlite3_complete16 0
-# define sqlite3_create_collation16 0
-# define sqlite3_create_function16 0
-# define sqlite3_errmsg16 0
-# define sqlite3_open16 0
-# define sqlite3_prepare16 0
-# define sqlite3_prepare16_v2 0
-# define sqlite3_result_error16 0
-# define sqlite3_result_text16 0
-# define sqlite3_result_text16be 0
-# define sqlite3_result_text16le 0
-# define sqlite3_value_text16 0
-# define sqlite3_value_text16be 0
-# define sqlite3_value_text16le 0
-# define sqlite3_column_database_name16 0
-# define sqlite3_column_table_name16 0
-# define sqlite3_column_origin_name16 0
-#endif
-
-#ifdef SQLITE_OMIT_COMPLETE
-# define sqlite3_complete 0
-# define sqlite3_complete16 0
-#endif
-
-#ifdef SQLITE_OMIT_PROGRESS_CALLBACK
-# define sqlite3_progress_handler 0
-#endif
-
-#ifdef SQLITE_OMIT_VIRTUALTABLE
-# define sqlite3_create_module 0
-# define sqlite3_create_module_v2 0
-# define sqlite3_declare_vtab 0
-#endif
-
-#ifdef SQLITE_OMIT_SHARED_CACHE
-# define sqlite3_enable_shared_cache 0
-#endif
-
-#ifdef SQLITE_OMIT_TRACE
-# define sqlite3_profile 0
-# define sqlite3_trace 0
-#endif
-
-#ifdef SQLITE_OMIT_GET_TABLE
-# define sqlite3_free_table 0
-# define sqlite3_get_table 0
-#endif
-
-#ifdef SQLITE_OMIT_INCRBLOB
-#define sqlite3_bind_zeroblob 0
-#define sqlite3_blob_bytes 0
-#define sqlite3_blob_close 0
-#define sqlite3_blob_open 0
-#define sqlite3_blob_read 0
-#define sqlite3_blob_write 0
-#endif
-
-/*
-** The following structure contains pointers to all SQLite API routines.
-** A pointer to this structure is passed into extensions when they are
-** loaded so that the extension can make calls back into the SQLite
-** library.
-**
-** When adding new APIs, add them to the bottom of this structure
-** in order to preserve backwards compatibility.
-**
-** Extensions that use newer APIs should first call the
-** sqlite3_libversion_number() to make sure that the API they
-** intend to use is supported by the library. Extensions should
-** also check to make sure that the pointer to the function is
-** not NULL before calling it.
-*/
-static const sqlite3_api_routines sqlite3Apis = {
- sqlite3_aggregate_context,
-#ifndef SQLITE_OMIT_DEPRECATED
- sqlite3_aggregate_count,
-#else
- 0,
-#endif
- sqlite3_bind_blob,
- sqlite3_bind_double,
- sqlite3_bind_int,
- sqlite3_bind_int64,
- sqlite3_bind_null,
- sqlite3_bind_parameter_count,
- sqlite3_bind_parameter_index,
- sqlite3_bind_parameter_name,
- sqlite3_bind_text,
- sqlite3_bind_text16,
- sqlite3_bind_value,
- sqlite3_busy_handler,
- sqlite3_busy_timeout,
- sqlite3_changes,
- sqlite3_close,
- sqlite3_collation_needed,
- sqlite3_collation_needed16,
- sqlite3_column_blob,
- sqlite3_column_bytes,
- sqlite3_column_bytes16,
- sqlite3_column_count,
- sqlite3_column_database_name,
- sqlite3_column_database_name16,
- sqlite3_column_decltype,
- sqlite3_column_decltype16,
- sqlite3_column_double,
- sqlite3_column_int,
- sqlite3_column_int64,
- sqlite3_column_name,
- sqlite3_column_name16,
- sqlite3_column_origin_name,
- sqlite3_column_origin_name16,
- sqlite3_column_table_name,
- sqlite3_column_table_name16,
- sqlite3_column_text,
- sqlite3_column_text16,
- sqlite3_column_type,
- sqlite3_column_value,
- sqlite3_commit_hook,
- sqlite3_complete,
- sqlite3_complete16,
- sqlite3_create_collation,
- sqlite3_create_collation16,
- sqlite3_create_function,
- sqlite3_create_function16,
- sqlite3_create_module,
- sqlite3_data_count,
- sqlite3_db_handle,
- sqlite3_declare_vtab,
- sqlite3_enable_shared_cache,
- sqlite3_errcode,
- sqlite3_errmsg,
- sqlite3_errmsg16,
- sqlite3_exec,
-#ifndef SQLITE_OMIT_DEPRECATED
- sqlite3_expired,
-#else
- 0,
-#endif
- sqlite3_finalize,
- sqlite3_free,
- sqlite3_free_table,
- sqlite3_get_autocommit,
- sqlite3_get_auxdata,
- sqlite3_get_table,
- 0, /* Was sqlite3_global_recover(), but that function is deprecated */
- sqlite3_interrupt,
- sqlite3_last_insert_rowid,
- sqlite3_libversion,
- sqlite3_libversion_number,
- sqlite3_malloc,
- sqlite3_mprintf,
- sqlite3_open,
- sqlite3_open16,
- sqlite3_prepare,
- sqlite3_prepare16,
- sqlite3_profile,
- sqlite3_progress_handler,
- sqlite3_realloc,
- sqlite3_reset,
- sqlite3_result_blob,
- sqlite3_result_double,
- sqlite3_result_error,
- sqlite3_result_error16,
- sqlite3_result_int,
- sqlite3_result_int64,
- sqlite3_result_null,
- sqlite3_result_text,
- sqlite3_result_text16,
- sqlite3_result_text16be,
- sqlite3_result_text16le,
- sqlite3_result_value,
- sqlite3_rollback_hook,
- sqlite3_set_authorizer,
- sqlite3_set_auxdata,
- sqlite3_snprintf,
- sqlite3_step,
- sqlite3_table_column_metadata,
-#ifndef SQLITE_OMIT_DEPRECATED
- sqlite3_thread_cleanup,
-#else
- 0,
-#endif
- sqlite3_total_changes,
- sqlite3_trace,
-#ifndef SQLITE_OMIT_DEPRECATED
- sqlite3_transfer_bindings,
-#else
- 0,
-#endif
- sqlite3_update_hook,
- sqlite3_user_data,
- sqlite3_value_blob,
- sqlite3_value_bytes,
- sqlite3_value_bytes16,
- sqlite3_value_double,
- sqlite3_value_int,
- sqlite3_value_int64,
- sqlite3_value_numeric_type,
- sqlite3_value_text,
- sqlite3_value_text16,
- sqlite3_value_text16be,
- sqlite3_value_text16le,
- sqlite3_value_type,
- sqlite3_vmprintf,
- /*
- ** The original API set ends here. All extensions can call any
- ** of the APIs above provided that the pointer is not NULL. But
- ** before calling APIs that follow, extension should check the
- ** sqlite3_libversion_number() to make sure they are dealing with
- ** a library that is new enough to support that API.
- *************************************************************************
- */
- sqlite3_overload_function,
-
- /*
- ** Added after 3.3.13
- */
- sqlite3_prepare_v2,
- sqlite3_prepare16_v2,
- sqlite3_clear_bindings,
-
- /*
- ** Added for 3.4.1
- */
- sqlite3_create_module_v2,
-
- /*
- ** Added for 3.5.0
- */
- sqlite3_bind_zeroblob,
- sqlite3_blob_bytes,
- sqlite3_blob_close,
- sqlite3_blob_open,
- sqlite3_blob_read,
- sqlite3_blob_write,
- sqlite3_create_collation_v2,
- sqlite3_file_control,
- sqlite3_memory_highwater,
- sqlite3_memory_used,
-#ifdef SQLITE_MUTEX_OMIT
- 0,
- 0,
- 0,
- 0,
- 0,
-#else
- sqlite3_mutex_alloc,
- sqlite3_mutex_enter,
- sqlite3_mutex_free,
- sqlite3_mutex_leave,
- sqlite3_mutex_try,
-#endif
- sqlite3_open_v2,
- sqlite3_release_memory,
- sqlite3_result_error_nomem,
- sqlite3_result_error_toobig,
- sqlite3_sleep,
- sqlite3_soft_heap_limit,
- sqlite3_vfs_find,
- sqlite3_vfs_register,
- sqlite3_vfs_unregister,
-
- /*
- ** Added for 3.5.8
- */
- sqlite3_threadsafe,
- sqlite3_result_zeroblob,
- sqlite3_result_error_code,
- sqlite3_test_control,
- sqlite3_randomness,
- sqlite3_context_db_handle,
-
- /*
- ** Added for 3.6.0
- */
- sqlite3_extended_result_codes,
- sqlite3_limit,
- sqlite3_next_stmt,
- sqlite3_sql,
- sqlite3_status,
-};
-
-/*
-** Attempt to load an SQLite extension library contained in the file
-** zFile. The entry point is zProc. zProc may be 0 in which case a
-** default entry point name (sqlite3_extension_init) is used. Use
-** of the default name is recommended.
-**
-** Return SQLITE_OK on success and SQLITE_ERROR if something goes wrong.
-**
-** If an error occurs and pzErrMsg is not 0, then fill *pzErrMsg with
-** error message text. The calling function should free this memory
-** by calling sqlite3DbFree(db, ).
-*/
-static int sqlite3LoadExtension(
- sqlite3 *db, /* Load the extension into this database connection */
- const char *zFile, /* Name of the shared library containing extension */
- const char *zProc, /* Entry point. Use "sqlite3_extension_init" if 0 */
- char **pzErrMsg /* Put error message here if not 0 */
-){
- sqlite3_vfs *pVfs = db->pVfs;
- void *handle;
- int (*xInit)(sqlite3*,char**,const sqlite3_api_routines*);
- char *zErrmsg = 0;
- void **aHandle;
- const int nMsg = 300;
-
- if( pzErrMsg ) *pzErrMsg = 0;
-
- /* Ticket #1863. To avoid a creating security problems for older
- ** applications that relink against newer versions of SQLite, the
- ** ability to run load_extension is turned off by default. One
- ** must call sqlite3_enable_load_extension() to turn on extension
- ** loading. Otherwise you get the following error.
- */
- if( (db->flags & SQLITE_LoadExtension)==0 ){
- if( pzErrMsg ){
- *pzErrMsg = sqlite3_mprintf("not authorized");
- }
- return SQLITE_ERROR;
- }
-
- if( zProc==0 ){
- zProc = "sqlite3_extension_init";
- }
-
- handle = sqlite3OsDlOpen(pVfs, zFile);
- if( handle==0 ){
- if( pzErrMsg ){
- zErrmsg = sqlite3StackAllocZero(db, nMsg);
- if( zErrmsg ){
- sqlite3_snprintf(nMsg, zErrmsg,
- "unable to open shared library [%s]", zFile);
- sqlite3OsDlError(pVfs, nMsg-1, zErrmsg);
- *pzErrMsg = sqlite3DbStrDup(0, zErrmsg);
- sqlite3StackFree(db, zErrmsg);
- }
- }
- return SQLITE_ERROR;
- }
- xInit = (int(*)(sqlite3*,char**,const sqlite3_api_routines*))
- sqlite3OsDlSym(pVfs, handle, zProc);
- if( xInit==0 ){
- if( pzErrMsg ){
- zErrmsg = sqlite3StackAllocZero(db, nMsg);
- if( zErrmsg ){
- sqlite3_snprintf(nMsg, zErrmsg,
- "no entry point [%s] in shared library [%s]", zProc,zFile);
- sqlite3OsDlError(pVfs, nMsg-1, zErrmsg);
- *pzErrMsg = sqlite3DbStrDup(0, zErrmsg);
- sqlite3StackFree(db, zErrmsg);
- }
- sqlite3OsDlClose(pVfs, handle);
- }
- return SQLITE_ERROR;
- }else if( xInit(db, &zErrmsg, &sqlite3Apis) ){
- if( pzErrMsg ){
- *pzErrMsg = sqlite3_mprintf("error during initialization: %s", zErrmsg);
- }
- sqlite3_free(zErrmsg);
- sqlite3OsDlClose(pVfs, handle);
- return SQLITE_ERROR;
- }
-
- /* Append the new shared library handle to the db->aExtension array. */
- aHandle = sqlite3DbMallocZero(db, sizeof(handle)*(db->nExtension+1));
- if( aHandle==0 ){
- return SQLITE_NOMEM;
- }
- if( db->nExtension>0 ){
- memcpy(aHandle, db->aExtension, sizeof(handle)*db->nExtension);
- }
- sqlite3DbFree(db, db->aExtension);
- db->aExtension = aHandle;
-
- db->aExtension[db->nExtension++] = handle;
- return SQLITE_OK;
-}
-SQLITE_API int sqlite3_load_extension(
- sqlite3 *db, /* Load the extension into this database connection */
- const char *zFile, /* Name of the shared library containing extension */
- const char *zProc, /* Entry point. Use "sqlite3_extension_init" if 0 */
- char **pzErrMsg /* Put error message here if not 0 */
-){
- int rc;
- sqlite3_mutex_enter(db->mutex);
- rc = sqlite3LoadExtension(db, zFile, zProc, pzErrMsg);
- rc = sqlite3ApiExit(db, rc);
- sqlite3_mutex_leave(db->mutex);
- return rc;
-}
-
-/*
-** Call this routine when the database connection is closing in order
-** to clean up loaded extensions
-*/
-SQLITE_PRIVATE void sqlite3CloseExtensions(sqlite3 *db){
- int i;
- assert( sqlite3_mutex_held(db->mutex) );
- for(i=0; i<db->nExtension; i++){
- sqlite3OsDlClose(db->pVfs, db->aExtension[i]);
- }
- sqlite3DbFree(db, db->aExtension);
-}
-
-/*
-** Enable or disable extension loading. Extension loading is disabled by
-** default so as not to open security holes in older applications.
-*/
-SQLITE_API int sqlite3_enable_load_extension(sqlite3 *db, int onoff){
- sqlite3_mutex_enter(db->mutex);
- if( onoff ){
- db->flags |= SQLITE_LoadExtension;
- }else{
- db->flags &= ~SQLITE_LoadExtension;
- }
- sqlite3_mutex_leave(db->mutex);
- return SQLITE_OK;
-}
-
-#endif /* SQLITE_OMIT_LOAD_EXTENSION */
-
-/*
-** The auto-extension code added regardless of whether or not extension
-** loading is supported. We need a dummy sqlite3Apis pointer for that
-** code if regular extension loading is not available. This is that
-** dummy pointer.
-*/
-#ifdef SQLITE_OMIT_LOAD_EXTENSION
-static const sqlite3_api_routines sqlite3Apis = { 0 };
-#endif
-
-
-/*
-** The following object holds the list of automatically loaded
-** extensions.
-**
-** This list is shared across threads. The SQLITE_MUTEX_STATIC_MASTER
-** mutex must be held while accessing this list.
-*/
-typedef struct sqlite3AutoExtList sqlite3AutoExtList;
-static SQLITE_WSD struct sqlite3AutoExtList {
- int nExt; /* Number of entries in aExt[] */
- void (**aExt)(void); /* Pointers to the extension init functions */
-} sqlite3Autoext = { 0, 0 };
-
-/* The "wsdAutoext" macro will resolve to the autoextension
-** state vector. If writable static data is unsupported on the target,
-** we have to locate the state vector at run-time. In the more common
-** case where writable static data is supported, wsdStat can refer directly
-** to the "sqlite3Autoext" state vector declared above.
-*/
-#ifdef SQLITE_OMIT_WSD
-# define wsdAutoextInit \
- sqlite3AutoExtList *x = &GLOBAL(sqlite3AutoExtList,sqlite3Autoext)
-# define wsdAutoext x[0]
-#else
-# define wsdAutoextInit
-# define wsdAutoext sqlite3Autoext
-#endif
-
-
-/*
-** Register a statically linked extension that is automatically
-** loaded by every new database connection.
-*/
-SQLITE_API int sqlite3_auto_extension(void (*xInit)(void)){
- int rc = SQLITE_OK;
-#ifndef SQLITE_OMIT_AUTOINIT
- rc = sqlite3_initialize();
- if( rc ){
- return rc;
- }else
-#endif
- {
- int i;
-#if SQLITE_THREADSAFE
- sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
-#endif
- wsdAutoextInit;
- sqlite3_mutex_enter(mutex);
- for(i=0; i<wsdAutoext.nExt; i++){
- if( wsdAutoext.aExt[i]==xInit ) break;
- }
- if( i==wsdAutoext.nExt ){
- int nByte = (wsdAutoext.nExt+1)*sizeof(wsdAutoext.aExt[0]);
- void (**aNew)(void);
- aNew = sqlite3_realloc(wsdAutoext.aExt, nByte);
- if( aNew==0 ){
- rc = SQLITE_NOMEM;
- }else{
- wsdAutoext.aExt = aNew;
- wsdAutoext.aExt[wsdAutoext.nExt] = xInit;
- wsdAutoext.nExt++;
- }
- }
- sqlite3_mutex_leave(mutex);
- assert( (rc&0xff)==rc );
- return rc;
- }
-}
-
-/*
-** Reset the automatic extension loading mechanism.
-*/
-SQLITE_API void sqlite3_reset_auto_extension(void){
-#ifndef SQLITE_OMIT_AUTOINIT
- if( sqlite3_initialize()==SQLITE_OK )
-#endif
- {
-#if SQLITE_THREADSAFE
- sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
-#endif
- wsdAutoextInit;
- sqlite3_mutex_enter(mutex);
- sqlite3_free(wsdAutoext.aExt);
- wsdAutoext.aExt = 0;
- wsdAutoext.nExt = 0;
- sqlite3_mutex_leave(mutex);
- }
-}
-
-/*
-** Load all automatic extensions.
-**
-** If anything goes wrong, set an error in the database connection.
-*/
-SQLITE_PRIVATE void sqlite3AutoLoadExtensions(sqlite3 *db){
- int i;
- int go = 1;
- int (*xInit)(sqlite3*,char**,const sqlite3_api_routines*);
-
- wsdAutoextInit;
- if( wsdAutoext.nExt==0 ){
- /* Common case: early out without every having to acquire a mutex */
- return;
- }
- for(i=0; go; i++){
- char *zErrmsg;
-#if SQLITE_THREADSAFE
- sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
-#endif
- sqlite3_mutex_enter(mutex);
- if( i>=wsdAutoext.nExt ){
- xInit = 0;
- go = 0;
- }else{
- xInit = (int(*)(sqlite3*,char**,const sqlite3_api_routines*))
- wsdAutoext.aExt[i];
- }
- sqlite3_mutex_leave(mutex);
- zErrmsg = 0;
- if( xInit && xInit(db, &zErrmsg, &sqlite3Apis) ){
- sqlite3Error(db, SQLITE_ERROR,
- "automatic extension loading failed: %s", zErrmsg);
- go = 0;
- }
- sqlite3_free(zErrmsg);
- }
-}
-
-/************** End of loadext.c *********************************************/
-/************** Begin file pragma.c ******************************************/
-/*
-** 2003 April 6
-**
-** 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 code used to implement the PRAGMA command.
-**
-** $Id: pragma.c,v 1.214 2009/07/02 07:47:33 danielk1977 Exp $
-*/
-
-/* Ignore this whole file if pragmas are disabled
-*/
-#if !defined(SQLITE_OMIT_PRAGMA)
-
-/*
-** Interpret the given string as a safety level. Return 0 for OFF,
-** 1 for ON or NORMAL and 2 for FULL. Return 1 for an empty or
-** unrecognized string argument.
-**
-** Note that the values returned are one less that the values that
-** should be passed into sqlite3BtreeSetSafetyLevel(). The is done
-** to support legacy SQL code. The safety level used to be boolean
-** and older scripts may have used numbers 0 for OFF and 1 for ON.
-*/
-static u8 getSafetyLevel(const char *z){
- /* 123456789 123456789 */
- static const char zText[] = "onoffalseyestruefull";
- static const u8 iOffset[] = {0, 1, 2, 4, 9, 12, 16};
- static const u8 iLength[] = {2, 2, 3, 5, 3, 4, 4};
- static const u8 iValue[] = {1, 0, 0, 0, 1, 1, 2};
- int i, n;
- if( sqlite3Isdigit(*z) ){
- return (u8)atoi(z);
- }
- n = sqlite3Strlen30(z);
- for(i=0; i<ArraySize(iLength); i++){
- if( iLength[i]==n && sqlite3StrNICmp(&zText[iOffset[i]],z,n)==0 ){
- return iValue[i];
- }
- }
- return 1;
-}
-
-/*
-** Interpret the given string as a boolean value.
-*/
-static u8 getBoolean(const char *z){
- return getSafetyLevel(z)&1;
-}
-
-/*
-** Interpret the given string as a locking mode value.
-*/
-static int getLockingMode(const char *z){
- if( z ){
- if( 0==sqlite3StrICmp(z, "exclusive") ) return PAGER_LOCKINGMODE_EXCLUSIVE;
- if( 0==sqlite3StrICmp(z, "normal") ) return PAGER_LOCKINGMODE_NORMAL;
- }
- return PAGER_LOCKINGMODE_QUERY;
-}
-
-#ifndef SQLITE_OMIT_AUTOVACUUM
-/*
-** Interpret the given string as an auto-vacuum mode value.
-**
-** The following strings, "none", "full" and "incremental" are
-** acceptable, as are their numeric equivalents: 0, 1 and 2 respectively.
-*/
-static int getAutoVacuum(const char *z){
- int i;
- if( 0==sqlite3StrICmp(z, "none") ) return BTREE_AUTOVACUUM_NONE;
- if( 0==sqlite3StrICmp(z, "full") ) return BTREE_AUTOVACUUM_FULL;
- if( 0==sqlite3StrICmp(z, "incremental") ) return BTREE_AUTOVACUUM_INCR;
- i = atoi(z);
- return (u8)((i>=0&&i<=2)?i:0);
-}
-#endif /* ifndef SQLITE_OMIT_AUTOVACUUM */
-
-#ifndef SQLITE_OMIT_PAGER_PRAGMAS
-/*
-** Interpret the given string as a temp db location. Return 1 for file
-** backed temporary databases, 2 for the Red-Black tree in memory database
-** and 0 to use the compile-time default.
-*/
-static int getTempStore(const char *z){
- if( z[0]>='0' && z[0]<='2' ){
- return z[0] - '0';
- }else if( sqlite3StrICmp(z, "file")==0 ){
- return 1;
- }else if( sqlite3StrICmp(z, "memory")==0 ){
- return 2;
- }else{
- return 0;
- }
-}
-#endif /* SQLITE_PAGER_PRAGMAS */
-
-#ifndef SQLITE_OMIT_PAGER_PRAGMAS
-/*
-** Invalidate temp storage, either when the temp storage is changed
-** from default, or when 'file' and the temp_store_directory has changed
-*/
-static int invalidateTempStorage(Parse *pParse){
- sqlite3 *db = pParse->db;
- if( db->aDb[1].pBt!=0 ){
- if( !db->autoCommit || sqlite3BtreeIsInReadTrans(db->aDb[1].pBt) ){
- sqlite3ErrorMsg(pParse, "temporary storage cannot be changed "
- "from within a transaction");
- return SQLITE_ERROR;
- }
- sqlite3BtreeClose(db->aDb[1].pBt);
- db->aDb[1].pBt = 0;
- sqlite3ResetInternalSchema(db, 0);
- }
- return SQLITE_OK;
-}
-#endif /* SQLITE_PAGER_PRAGMAS */
-
-#ifndef SQLITE_OMIT_PAGER_PRAGMAS
-/*
-** If the TEMP database is open, close it and mark the database schema
-** as needing reloading. This must be done when using the SQLITE_TEMP_STORE
-** or DEFAULT_TEMP_STORE pragmas.
-*/
-static int changeTempStorage(Parse *pParse, const char *zStorageType){
- int ts = getTempStore(zStorageType);
- sqlite3 *db = pParse->db;
- if( db->temp_store==ts ) return SQLITE_OK;
- if( invalidateTempStorage( pParse ) != SQLITE_OK ){
- return SQLITE_ERROR;
- }
- db->temp_store = (u8)ts;
- return SQLITE_OK;
-}
-#endif /* SQLITE_PAGER_PRAGMAS */
-
-/*
-** Generate code to return a single integer value.
-*/
-static void returnSingleInt(Parse *pParse, const char *zLabel, i64 value){
- Vdbe *v = sqlite3GetVdbe(pParse);
- int mem = ++pParse->nMem;
- i64 *pI64 = sqlite3DbMallocRaw(pParse->db, sizeof(value));
- if( pI64 ){
- memcpy(pI64, &value, sizeof(value));
- }
- sqlite3VdbeAddOp4(v, OP_Int64, 0, mem, 0, (char*)pI64, P4_INT64);
- sqlite3VdbeSetNumCols(v, 1);
- sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLabel, SQLITE_STATIC);
- sqlite3VdbeAddOp2(v, OP_ResultRow, mem, 1);
-}
-
-#ifndef SQLITE_OMIT_FLAG_PRAGMAS
-/*
-** Check to see if zRight and zLeft refer to a pragma that queries
-** or changes one of the flags in db->flags. Return 1 if so and 0 if not.
-** Also, implement the pragma.
-*/
-static int flagPragma(Parse *pParse, const char *zLeft, const char *zRight){
- static const struct sPragmaType {
- const char *zName; /* Name of the pragma */
- int mask; /* Mask for the db->flags value */
- } aPragma[] = {
- { "full_column_names", SQLITE_FullColNames },
- { "short_column_names", SQLITE_ShortColNames },
- { "count_changes", SQLITE_CountRows },
- { "empty_result_callbacks", SQLITE_NullCallback },
- { "legacy_file_format", SQLITE_LegacyFileFmt },
- { "fullfsync", SQLITE_FullFSync },
- { "reverse_unordered_selects", SQLITE_ReverseOrder },
-#ifdef SQLITE_DEBUG
- { "sql_trace", SQLITE_SqlTrace },
- { "vdbe_listing", SQLITE_VdbeListing },
- { "vdbe_trace", SQLITE_VdbeTrace },
-#endif
-#ifndef SQLITE_OMIT_CHECK
- { "ignore_check_constraints", SQLITE_IgnoreChecks },
-#endif
- /* The following is VERY experimental */
- { "writable_schema", SQLITE_WriteSchema|SQLITE_RecoveryMode },
- { "omit_readlock", SQLITE_NoReadlock },
-
- /* TODO: Maybe it shouldn't be possible to change the ReadUncommitted
- ** flag if there are any active statements. */
- { "read_uncommitted", SQLITE_ReadUncommitted },
- { "recursive_triggers", SQLITE_RecTriggers },
- };
- int i;
- const struct sPragmaType *p;
- for(i=0, p=aPragma; i<ArraySize(aPragma); i++, p++){
- if( sqlite3StrICmp(zLeft, p->zName)==0 ){
- sqlite3 *db = pParse->db;
- Vdbe *v;
- v = sqlite3GetVdbe(pParse);
- assert( v!=0 ); /* Already allocated by sqlite3Pragma() */
- if( ALWAYS(v) ){
- if( zRight==0 ){
- returnSingleInt(pParse, p->zName, (db->flags & p->mask)!=0 );
- }else{
- if( getBoolean(zRight) ){
- db->flags |= p->mask;
- }else{
- db->flags &= ~p->mask;
- }
-
- /* Many of the flag-pragmas modify the code generated by the SQL
- ** compiler (eg. count_changes). So add an opcode to expire all
- ** compiled SQL statements after modifying a pragma value.
- */
- sqlite3VdbeAddOp2(v, OP_Expire, 0, 0);
- }
- }
-
- return 1;
- }
- }
- return 0;
-}
-#endif /* SQLITE_OMIT_FLAG_PRAGMAS */
-
-/*
-** Return a human-readable name for a constraint resolution action.
-*/
-static const char *actionName(u8 action){
- const char *zName;
- switch( action ){
- case OE_SetNull: zName = "SET NULL"; break;
- case OE_SetDflt: zName = "SET DEFAULT"; break;
- case OE_Cascade: zName = "CASCADE"; break;
- default: zName = "RESTRICT";
- assert( action==OE_Restrict ); break;
- }
- return zName;
-}
-
-/*
-** Process a pragma statement.
-**
-** Pragmas are of this form:
-**
-** PRAGMA [database.]id [= value]
-**
-** The identifier might also be a string. The value is a string, and
-** identifier, or a number. If minusFlag is true, then the value is
-** a number that was preceded by a minus sign.
-**
-** If the left side is "database.id" then pId1 is the database name
-** and pId2 is the id. If the left side is just "id" then pId1 is the
-** id and pId2 is any empty string.
-*/
-SQLITE_PRIVATE void sqlite3Pragma(
- Parse *pParse,
- Token *pId1, /* First part of [database.]id field */
- Token *pId2, /* Second part of [database.]id field, or NULL */
- Token *pValue, /* Token for <value>, or NULL */
- int minusFlag /* True if a '-' sign preceded <value> */
-){
- char *zLeft = 0; /* Nul-terminated UTF-8 string <id> */
- char *zRight = 0; /* Nul-terminated UTF-8 string <value>, or NULL */
- const char *zDb = 0; /* The database name */
- Token *pId; /* Pointer to <id> token */
- int iDb; /* Database index for <database> */
- sqlite3 *db = pParse->db;
- Db *pDb;
- Vdbe *v = pParse->pVdbe = sqlite3VdbeCreate(db);
- if( v==0 ) return;
- pParse->nMem = 2;
-
- /* Interpret the [database.] part of the pragma statement. iDb is the
- ** index of the database this pragma is being applied to in db.aDb[]. */
- iDb = sqlite3TwoPartName(pParse, pId1, pId2, &pId);
- if( iDb<0 ) return;
- pDb = &db->aDb[iDb];
-
- /* If the temp database has been explicitly named as part of the
- ** pragma, make sure it is open.
- */
- if( iDb==1 && sqlite3OpenTempDatabase(pParse) ){
- return;
- }
-
- zLeft = sqlite3NameFromToken(db, pId);
- if( !zLeft ) return;
- if( minusFlag ){
- zRight = sqlite3MPrintf(db, "-%T", pValue);
- }else{
- zRight = sqlite3NameFromToken(db, pValue);
- }
-
- assert( pId2 );
- zDb = pId2->n>0 ? pDb->zName : 0;
- if( sqlite3AuthCheck(pParse, SQLITE_PRAGMA, zLeft, zRight, zDb) ){
- goto pragma_out;
- }
-
-#ifndef SQLITE_OMIT_PAGER_PRAGMAS
- /*
- ** PRAGMA [database.]default_cache_size
- ** PRAGMA [database.]default_cache_size=N
- **
- ** The first form reports the current persistent setting for the
- ** page cache size. The value returned is the maximum number of
- ** pages in the page cache. The second form sets both the current
- ** page cache size value and the persistent page cache size value
- ** stored in the database file.
- **
- ** The default cache size is stored in meta-value 2 of page 1 of the
- ** database file. The cache size is actually the absolute value of
- ** this memory location. The sign of meta-value 2 determines the
- ** synchronous setting. A negative value means synchronous is off
- ** and a positive value means synchronous is on.
- */
- if( sqlite3StrICmp(zLeft,"default_cache_size")==0 ){
- static const VdbeOpList getCacheSize[] = {
- { OP_Transaction, 0, 0, 0}, /* 0 */
- { OP_ReadCookie, 0, 1, BTREE_DEFAULT_CACHE_SIZE}, /* 1 */
- { OP_IfPos, 1, 7, 0},
- { OP_Integer, 0, 2, 0},
- { OP_Subtract, 1, 2, 1},
- { OP_IfPos, 1, 7, 0},
- { OP_Integer, 0, 1, 0}, /* 6 */
- { OP_ResultRow, 1, 1, 0},
- };
- int addr;
- if( sqlite3ReadSchema(pParse) ) goto pragma_out;
- sqlite3VdbeUsesBtree(v, iDb);
- if( !zRight ){
- sqlite3VdbeSetNumCols(v, 1);
- sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "cache_size", SQLITE_STATIC);
- pParse->nMem += 2;
- addr = sqlite3VdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize);
- sqlite3VdbeChangeP1(v, addr, iDb);
- sqlite3VdbeChangeP1(v, addr+1, iDb);
- sqlite3VdbeChangeP1(v, addr+6, SQLITE_DEFAULT_CACHE_SIZE);
- }else{
- int size = atoi(zRight);
- if( size<0 ) size = -size;
- sqlite3BeginWriteOperation(pParse, 0, iDb);
- sqlite3VdbeAddOp2(v, OP_Integer, size, 1);
- sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, 2, BTREE_DEFAULT_CACHE_SIZE);
- addr = sqlite3VdbeAddOp2(v, OP_IfPos, 2, 0);
- sqlite3VdbeAddOp2(v, OP_Integer, -size, 1);
- sqlite3VdbeJumpHere(v, addr);
- sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_DEFAULT_CACHE_SIZE, 1);
- pDb->pSchema->cache_size = size;
- sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size);
- }
- }else
-
- /*
- ** PRAGMA [database.]page_size
- ** PRAGMA [database.]page_size=N
- **
- ** The first form reports the current setting for the
- ** database page size in bytes. The second form sets the
- ** database page size value. The value can only be set if
- ** the database has not yet been created.
- */
- if( sqlite3StrICmp(zLeft,"page_size")==0 ){
- Btree *pBt = pDb->pBt;
- assert( pBt!=0 );
- if( !zRight ){
- int size = ALWAYS(pBt) ? sqlite3BtreeGetPageSize(pBt) : 0;
- returnSingleInt(pParse, "page_size", size);
- }else{
- /* Malloc may fail when setting the page-size, as there is an internal
- ** buffer that the pager module resizes using sqlite3_realloc().
- */
- db->nextPagesize = atoi(zRight);
- if( SQLITE_NOMEM==sqlite3BtreeSetPageSize(pBt, db->nextPagesize, -1, 0) ){
- db->mallocFailed = 1;
- }
- }
- }else
-
- /*
- ** PRAGMA [database.]max_page_count
- ** PRAGMA [database.]max_page_count=N
- **
- ** The first form reports the current setting for the
- ** maximum number of pages in the database file. The
- ** second form attempts to change this setting. Both
- ** forms return the current setting.
- */
- if( sqlite3StrICmp(zLeft,"max_page_count")==0 ){
- Btree *pBt = pDb->pBt;
- int newMax = 0;
- assert( pBt!=0 );
- if( zRight ){
- newMax = atoi(zRight);
- }
- if( ALWAYS(pBt) ){
- newMax = sqlite3BtreeMaxPageCount(pBt, newMax);
- }
- returnSingleInt(pParse, "max_page_count", newMax);
- }else
-
- /*
- ** PRAGMA [database.]page_count
- **
- ** Return the number of pages in the specified database.
- */
- if( sqlite3StrICmp(zLeft,"page_count")==0 ){
- int iReg;
- if( sqlite3ReadSchema(pParse) ) goto pragma_out;
- sqlite3CodeVerifySchema(pParse, iDb);
- iReg = ++pParse->nMem;
- sqlite3VdbeAddOp2(v, OP_Pagecount, iDb, iReg);
- sqlite3VdbeAddOp2(v, OP_ResultRow, iReg, 1);
- sqlite3VdbeSetNumCols(v, 1);
- sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "page_count", SQLITE_STATIC);
- }else
-
- /*
- ** PRAGMA [database.]locking_mode
- ** PRAGMA [database.]locking_mode = (normal|exclusive)
- */
- if( sqlite3StrICmp(zLeft,"locking_mode")==0 ){
- const char *zRet = "normal";
- int eMode = getLockingMode(zRight);
-
- if( pId2->n==0 && eMode==PAGER_LOCKINGMODE_QUERY ){
- /* Simple "PRAGMA locking_mode;" statement. This is a query for
- ** the current default locking mode (which may be different to
- ** the locking-mode of the main database).
- */
- eMode = db->dfltLockMode;
- }else{
- Pager *pPager;
- if( pId2->n==0 ){
- /* This indicates that no database name was specified as part
- ** of the PRAGMA command. In this case the locking-mode must be
- ** set on all attached databases, as well as the main db file.
- **
- ** Also, the sqlite3.dfltLockMode variable is set so that
- ** any subsequently attached databases also use the specified
- ** locking mode.
- */
- int ii;
- assert(pDb==&db->aDb[0]);
- for(ii=2; ii<db->nDb; ii++){
- pPager = sqlite3BtreePager(db->aDb[ii].pBt);
- sqlite3PagerLockingMode(pPager, eMode);
- }
- db->dfltLockMode = (u8)eMode;
- }
- pPager = sqlite3BtreePager(pDb->pBt);
- eMode = sqlite3PagerLockingMode(pPager, eMode);
- }
-
- assert(eMode==PAGER_LOCKINGMODE_NORMAL||eMode==PAGER_LOCKINGMODE_EXCLUSIVE);
- if( eMode==PAGER_LOCKINGMODE_EXCLUSIVE ){
- zRet = "exclusive";
- }
- sqlite3VdbeSetNumCols(v, 1);
- sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "locking_mode", SQLITE_STATIC);
- sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, zRet, 0);
- sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
- }else
-
- /*
- ** PRAGMA [database.]journal_mode
- ** PRAGMA [database.]journal_mode = (delete|persist|off|truncate|memory)
- */
- if( sqlite3StrICmp(zLeft,"journal_mode")==0 ){
- int eMode;
- static char * const azModeName[] = {
- "delete", "persist", "off", "truncate", "memory"
- };
-
- if( zRight==0 ){
- eMode = PAGER_JOURNALMODE_QUERY;
- }else{
- int n = sqlite3Strlen30(zRight);
- eMode = sizeof(azModeName)/sizeof(azModeName[0]) - 1;
- while( eMode>=0 && sqlite3StrNICmp(zRight, azModeName[eMode], n)!=0 ){
- eMode--;
- }
- }
- if( pId2->n==0 && eMode==PAGER_JOURNALMODE_QUERY ){
- /* Simple "PRAGMA journal_mode;" statement. This is a query for
- ** the current default journal mode (which may be different to
- ** the journal-mode of the main database).
- */
- eMode = db->dfltJournalMode;
- }else{
- Pager *pPager;
- if( pId2->n==0 ){
- /* This indicates that no database name was specified as part
- ** of the PRAGMA command. In this case the journal-mode must be
- ** set on all attached databases, as well as the main db file.
- **
- ** Also, the sqlite3.dfltJournalMode variable is set so that
- ** any subsequently attached databases also use the specified
- ** journal mode.
- */
- int ii;
- assert(pDb==&db->aDb[0]);
- for(ii=1; ii<db->nDb; ii++){
- if( db->aDb[ii].pBt ){
- pPager = sqlite3BtreePager(db->aDb[ii].pBt);
- sqlite3PagerJournalMode(pPager, eMode);
- }
- }
- db->dfltJournalMode = (u8)eMode;
- }
- pPager = sqlite3BtreePager(pDb->pBt);
- eMode = sqlite3PagerJournalMode(pPager, eMode);
- }
- assert( eMode==PAGER_JOURNALMODE_DELETE
- || eMode==PAGER_JOURNALMODE_TRUNCATE
- || eMode==PAGER_JOURNALMODE_PERSIST
- || eMode==PAGER_JOURNALMODE_OFF
- || eMode==PAGER_JOURNALMODE_MEMORY );
- sqlite3VdbeSetNumCols(v, 1);
- sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "journal_mode", SQLITE_STATIC);
- sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0,
- azModeName[eMode], P4_STATIC);
- sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
- }else
-
- /*
- ** PRAGMA [database.]journal_size_limit
- ** PRAGMA [database.]journal_size_limit=N
- **
- ** Get or set the size limit on rollback journal files.
- */
- if( sqlite3StrICmp(zLeft,"journal_size_limit")==0 ){
- Pager *pPager = sqlite3BtreePager(pDb->pBt);
- i64 iLimit = -2;
- if( zRight ){
- sqlite3Atoi64(zRight, &iLimit);
- if( iLimit<-1 ) iLimit = -1;
- }
- iLimit = sqlite3PagerJournalSizeLimit(pPager, iLimit);
- returnSingleInt(pParse, "journal_size_limit", iLimit);
- }else
-
-#endif /* SQLITE_OMIT_PAGER_PRAGMAS */
-
- /*
- ** PRAGMA [database.]auto_vacuum
- ** PRAGMA [database.]auto_vacuum=N
- **
- ** Get or set the value of the database 'auto-vacuum' parameter.
- ** The value is one of: 0 NONE 1 FULL 2 INCREMENTAL
- */
-#ifndef SQLITE_OMIT_AUTOVACUUM
- if( sqlite3StrICmp(zLeft,"auto_vacuum")==0 ){
- Btree *pBt = pDb->pBt;
- assert( pBt!=0 );
- if( sqlite3ReadSchema(pParse) ){
- goto pragma_out;
- }
- if( !zRight ){
- int auto_vacuum;
- if( ALWAYS(pBt) ){
- auto_vacuum = sqlite3BtreeGetAutoVacuum(pBt);
- }else{
- auto_vacuum = SQLITE_DEFAULT_AUTOVACUUM;
- }
- returnSingleInt(pParse, "auto_vacuum", auto_vacuum);
- }else{
- int eAuto = getAutoVacuum(zRight);
- assert( eAuto>=0 && eAuto<=2 );
- db->nextAutovac = (u8)eAuto;
- if( ALWAYS(eAuto>=0) ){
- /* Call SetAutoVacuum() to set initialize the internal auto and
- ** incr-vacuum flags. This is required in case this connection
- ** creates the database file. It is important that it is created
- ** as an auto-vacuum capable db.
- */
- int rc = sqlite3BtreeSetAutoVacuum(pBt, eAuto);
- if( rc==SQLITE_OK && (eAuto==1 || eAuto==2) ){
- /* When setting the auto_vacuum mode to either "full" or
- ** "incremental", write the value of meta[6] in the database
- ** file. Before writing to meta[6], check that meta[3] indicates
- ** that this really is an auto-vacuum capable database.
- */
- static const VdbeOpList setMeta6[] = {
- { OP_Transaction, 0, 1, 0}, /* 0 */
- { OP_ReadCookie, 0, 1, BTREE_LARGEST_ROOT_PAGE},
- { OP_If, 1, 0, 0}, /* 2 */
- { OP_Halt, SQLITE_OK, OE_Abort, 0}, /* 3 */
- { OP_Integer, 0, 1, 0}, /* 4 */
- { OP_SetCookie, 0, BTREE_INCR_VACUUM, 1}, /* 5 */
- };
- int iAddr;
- iAddr = sqlite3VdbeAddOpList(v, ArraySize(setMeta6), setMeta6);
- sqlite3VdbeChangeP1(v, iAddr, iDb);
- sqlite3VdbeChangeP1(v, iAddr+1, iDb);
- sqlite3VdbeChangeP2(v, iAddr+2, iAddr+4);
- sqlite3VdbeChangeP1(v, iAddr+4, eAuto-1);
- sqlite3VdbeChangeP1(v, iAddr+5, iDb);
- sqlite3VdbeUsesBtree(v, iDb);
- }
- }
- }
- }else
-#endif
-
- /*
- ** PRAGMA [database.]incremental_vacuum(N)
- **
- ** Do N steps of incremental vacuuming on a database.
- */
-#ifndef SQLITE_OMIT_AUTOVACUUM
- if( sqlite3StrICmp(zLeft,"incremental_vacuum")==0 ){
- int iLimit, addr;
- if( sqlite3ReadSchema(pParse) ){
- goto pragma_out;
- }
- if( zRight==0 || !sqlite3GetInt32(zRight, &iLimit) || iLimit<=0 ){
- iLimit = 0x7fffffff;
- }
- sqlite3BeginWriteOperation(pParse, 0, iDb);
- sqlite3VdbeAddOp2(v, OP_Integer, iLimit, 1);
- addr = sqlite3VdbeAddOp1(v, OP_IncrVacuum, iDb);
- sqlite3VdbeAddOp1(v, OP_ResultRow, 1);
- sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1);
- sqlite3VdbeAddOp2(v, OP_IfPos, 1, addr);
- sqlite3VdbeJumpHere(v, addr);
- }else
-#endif
-
-#ifndef SQLITE_OMIT_PAGER_PRAGMAS
- /*
- ** PRAGMA [database.]cache_size
- ** 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.
- */
- if( sqlite3StrICmp(zLeft,"cache_size")==0 ){
- if( sqlite3ReadSchema(pParse) ) goto pragma_out;
- if( !zRight ){
- returnSingleInt(pParse, "cache_size", pDb->pSchema->cache_size);
- }else{
- int size = atoi(zRight);
- if( size<0 ) size = -size;
- pDb->pSchema->cache_size = size;
- sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size);
- }
- }else
-
- /*
- ** PRAGMA temp_store
- ** PRAGMA temp_store = "default"|"memory"|"file"
- **
- ** Return or set the local value of the temp_store flag. Changing
- ** the local value does not make changes to the disk file and the default
- ** value will be restored the next time the database is opened.
- **
- ** Note that it is possible for the library compile-time options to
- ** override this setting
- */
- if( sqlite3StrICmp(zLeft, "temp_store")==0 ){
- if( !zRight ){
- returnSingleInt(pParse, "temp_store", db->temp_store);
- }else{
- changeTempStorage(pParse, zRight);
- }
- }else
-
- /*
- ** PRAGMA temp_store_directory
- ** PRAGMA temp_store_directory = ""|"directory_name"
- **
- ** Return or set the local value of the temp_store_directory flag. Changing
- ** the value sets a specific directory to be used for temporary files.
- ** Setting to a null string reverts to the default temporary directory search.
- ** If temporary directory is changed, then invalidateTempStorage.
- **
- */
- if( sqlite3StrICmp(zLeft, "temp_store_directory")==0 ){
- if( !zRight ){
- if( sqlite3_temp_directory ){
- sqlite3VdbeSetNumCols(v, 1);
- sqlite3VdbeSetColName(v, 0, COLNAME_NAME,
- "temp_store_directory", SQLITE_STATIC);
- sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, sqlite3_temp_directory, 0);
- sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
- }
- }else{
-#ifndef SQLITE_OMIT_WSD
- if( zRight[0] ){
- int rc;
- int res;
- rc = sqlite3OsAccess(db->pVfs, zRight, SQLITE_ACCESS_READWRITE, &res);
- if( rc!=SQLITE_OK || res==0 ){
- sqlite3ErrorMsg(pParse, "not a writable directory");
- goto pragma_out;
- }
- }
- if( SQLITE_TEMP_STORE==0
- || (SQLITE_TEMP_STORE==1 && db->temp_store<=1)
- || (SQLITE_TEMP_STORE==2 && db->temp_store==1)
- ){
- invalidateTempStorage(pParse);
- }
- sqlite3_free(sqlite3_temp_directory);
- if( zRight[0] ){
- sqlite3_temp_directory = sqlite3DbStrDup(0, zRight);
- }else{
- sqlite3_temp_directory = 0;
- }
-#endif /* SQLITE_OMIT_WSD */
- }
- }else
-
-#if !defined(SQLITE_ENABLE_LOCKING_STYLE)
-# if defined(__APPLE__)
-# define SQLITE_ENABLE_LOCKING_STYLE 1
-# else
-# define SQLITE_ENABLE_LOCKING_STYLE 0
-# endif
-#endif
-#if SQLITE_ENABLE_LOCKING_STYLE
- /*
- ** PRAGMA [database.]lock_proxy_file
- ** PRAGMA [database.]lock_proxy_file = ":auto:"|"lock_file_path"
- **
- ** Return or set the value of the lock_proxy_file flag. Changing
- ** the value sets a specific file to be used for database access locks.
- **
- */
- if( sqlite3StrICmp(zLeft, "lock_proxy_file")==0 ){
- if( !zRight ){
- Pager *pPager = sqlite3BtreePager(pDb->pBt);
- char *proxy_file_path = NULL;
- sqlite3_file *pFile = sqlite3PagerFile(pPager);
- sqlite3OsFileControl(pFile, SQLITE_GET_LOCKPROXYFILE,
- &proxy_file_path);
-
- if( proxy_file_path ){
- sqlite3VdbeSetNumCols(v, 1);
- sqlite3VdbeSetColName(v, 0, COLNAME_NAME,
- "lock_proxy_file", SQLITE_STATIC);
- sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, proxy_file_path, 0);
- sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
- }
- }else{
- Pager *pPager = sqlite3BtreePager(pDb->pBt);
- sqlite3_file *pFile = sqlite3PagerFile(pPager);
- int res;
- if( zRight[0] ){
- res=sqlite3OsFileControl(pFile, SQLITE_SET_LOCKPROXYFILE,
- zRight);
- } else {
- res=sqlite3OsFileControl(pFile, SQLITE_SET_LOCKPROXYFILE,
- NULL);
- }
- if( res!=SQLITE_OK ){
- sqlite3ErrorMsg(pParse, "failed to set lock proxy file");
- goto pragma_out;
- }
- }
- }else
-#endif /* SQLITE_ENABLE_LOCKING_STYLE */
-
- /*
- ** PRAGMA [database.]synchronous
- ** PRAGMA [database.]synchronous=OFF|ON|NORMAL|FULL
- **
- ** Return or set the local value of the synchronous flag. Changing
- ** the local value does not make changes to the disk file and the
- ** default value will be restored the next time the database is
- ** opened.
- */
- if( sqlite3StrICmp(zLeft,"synchronous")==0 ){
- if( sqlite3ReadSchema(pParse) ) goto pragma_out;
- if( !zRight ){
- returnSingleInt(pParse, "synchronous", pDb->safety_level-1);
- }else{
- if( !db->autoCommit ){
- sqlite3ErrorMsg(pParse,
- "Safety level may not be changed inside a transaction");
- }else{
- pDb->safety_level = getSafetyLevel(zRight)+1;
- }
- }
- }else
-#endif /* SQLITE_OMIT_PAGER_PRAGMAS */
-
-#ifndef SQLITE_OMIT_FLAG_PRAGMAS
- if( flagPragma(pParse, zLeft, zRight) ){
- /* The flagPragma() subroutine also generates any necessary code
- ** there is nothing more to do here */
- }else
-#endif /* SQLITE_OMIT_FLAG_PRAGMAS */
-
-#ifndef SQLITE_OMIT_SCHEMA_PRAGMAS
- /*
- ** PRAGMA table_info(<table>)
- **
- ** Return a single row for each column of the named table. The columns of
- ** the returned data set are:
- **
- ** cid: Column id (numbered from left to right, starting at 0)
- ** name: Column name
- ** type: Column declaration type.
- ** notnull: True if 'NOT NULL' is part of column declaration
- ** dflt_value: The default value for the column, if any.
- */
- if( sqlite3StrICmp(zLeft, "table_info")==0 && zRight ){
- Table *pTab;
- if( sqlite3ReadSchema(pParse) ) goto pragma_out;
- pTab = sqlite3FindTable(db, zRight, zDb);
- if( pTab ){
- int i;
- int nHidden = 0;
- Column *pCol;
- sqlite3VdbeSetNumCols(v, 6);
- pParse->nMem = 6;
- sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "cid", SQLITE_STATIC);
- sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", SQLITE_STATIC);
- sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "type", SQLITE_STATIC);
- sqlite3VdbeSetColName(v, 3, COLNAME_NAME, "notnull", SQLITE_STATIC);
- sqlite3VdbeSetColName(v, 4, COLNAME_NAME, "dflt_value", SQLITE_STATIC);
- sqlite3VdbeSetColName(v, 5, COLNAME_NAME, "pk", SQLITE_STATIC);
- sqlite3ViewGetColumnNames(pParse, pTab);
- for(i=0, pCol=pTab->aCol; i<pTab->nCol; i++, pCol++){
- if( IsHiddenColumn(pCol) ){
- nHidden++;
- continue;
- }
- sqlite3VdbeAddOp2(v, OP_Integer, i-nHidden, 1);
- sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, pCol->zName, 0);
- sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0,
- pCol->zType ? pCol->zType : "", 0);
- sqlite3VdbeAddOp2(v, OP_Integer, (pCol->notNull ? 1 : 0), 4);
- if( pCol->zDflt ){
- sqlite3VdbeAddOp4(v, OP_String8, 0, 5, 0, (char*)pCol->zDflt, 0);
- }else{
- sqlite3VdbeAddOp2(v, OP_Null, 0, 5);
- }
- sqlite3VdbeAddOp2(v, OP_Integer, pCol->isPrimKey, 6);
- sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 6);
- }
- }
- }else
-
- if( sqlite3StrICmp(zLeft, "index_info")==0 && zRight ){
- Index *pIdx;
- Table *pTab;
- if( sqlite3ReadSchema(pParse) ) goto pragma_out;
- pIdx = sqlite3FindIndex(db, zRight, zDb);
- if( pIdx ){
- int i;
- pTab = pIdx->pTable;
- sqlite3VdbeSetNumCols(v, 3);
- pParse->nMem = 3;
- sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seqno", SQLITE_STATIC);
- sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "cid", SQLITE_STATIC);
- sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "name", SQLITE_STATIC);
- for(i=0; i<pIdx->nColumn; i++){
- int cnum = pIdx->aiColumn[i];
- sqlite3VdbeAddOp2(v, OP_Integer, i, 1);
- sqlite3VdbeAddOp2(v, OP_Integer, cnum, 2);
- assert( pTab->nCol>cnum );
- sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, pTab->aCol[cnum].zName, 0);
- sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 3);
- }
- }
- }else
-
- if( sqlite3StrICmp(zLeft, "index_list")==0 && zRight ){
- Index *pIdx;
- Table *pTab;
- if( sqlite3ReadSchema(pParse) ) goto pragma_out;
- pTab = sqlite3FindTable(db, zRight, zDb);
- if( pTab ){
- v = sqlite3GetVdbe(pParse);
- pIdx = pTab->pIndex;
- if( pIdx ){
- int i = 0;
- sqlite3VdbeSetNumCols(v, 3);
- pParse->nMem = 3;
- sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seq", SQLITE_STATIC);
- sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", SQLITE_STATIC);
- sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "unique", SQLITE_STATIC);
- while(pIdx){
- sqlite3VdbeAddOp2(v, OP_Integer, i, 1);
- sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, pIdx->zName, 0);
- sqlite3VdbeAddOp2(v, OP_Integer, pIdx->onError!=OE_None, 3);
- sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 3);
- ++i;
- pIdx = pIdx->pNext;
- }
- }
- }
- }else
-
- if( sqlite3StrICmp(zLeft, "database_list")==0 ){
- int i;
- if( sqlite3ReadSchema(pParse) ) goto pragma_out;
- sqlite3VdbeSetNumCols(v, 3);
- pParse->nMem = 3;
- sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seq", SQLITE_STATIC);
- sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", SQLITE_STATIC);
- sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "file", SQLITE_STATIC);
- for(i=0; i<db->nDb; i++){
- if( db->aDb[i].pBt==0 ) continue;
- assert( db->aDb[i].zName!=0 );
- sqlite3VdbeAddOp2(v, OP_Integer, i, 1);
- sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, db->aDb[i].zName, 0);
- sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0,
- sqlite3BtreeGetFilename(db->aDb[i].pBt), 0);
- sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 3);
- }
- }else
-
- if( sqlite3StrICmp(zLeft, "collation_list")==0 ){
- int i = 0;
- HashElem *p;
- sqlite3VdbeSetNumCols(v, 2);
- pParse->nMem = 2;
- sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seq", SQLITE_STATIC);
- sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", SQLITE_STATIC);
- for(p=sqliteHashFirst(&db->aCollSeq); p; p=sqliteHashNext(p)){
- CollSeq *pColl = (CollSeq *)sqliteHashData(p);
- sqlite3VdbeAddOp2(v, OP_Integer, i++, 1);
- sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, pColl->zName, 0);
- sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 2);
- }
- }else
-#endif /* SQLITE_OMIT_SCHEMA_PRAGMAS */
-
-#ifndef SQLITE_OMIT_FOREIGN_KEY
- if( sqlite3StrICmp(zLeft, "foreign_key_list")==0 && zRight ){
- FKey *pFK;
- Table *pTab;
- if( sqlite3ReadSchema(pParse) ) goto pragma_out;
- pTab = sqlite3FindTable(db, zRight, zDb);
- if( pTab ){
- v = sqlite3GetVdbe(pParse);
- pFK = pTab->pFKey;
- if( pFK ){
- int i = 0;
- sqlite3VdbeSetNumCols(v, 8);
- pParse->nMem = 8;
- sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "id", SQLITE_STATIC);
- sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "seq", SQLITE_STATIC);
- sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "table", SQLITE_STATIC);
- sqlite3VdbeSetColName(v, 3, COLNAME_NAME, "from", SQLITE_STATIC);
- sqlite3VdbeSetColName(v, 4, COLNAME_NAME, "to", SQLITE_STATIC);
- sqlite3VdbeSetColName(v, 5, COLNAME_NAME, "on_update", SQLITE_STATIC);
- sqlite3VdbeSetColName(v, 6, COLNAME_NAME, "on_delete", SQLITE_STATIC);
- sqlite3VdbeSetColName(v, 7, COLNAME_NAME, "match", SQLITE_STATIC);
- while(pFK){
- int j;
- for(j=0; j<pFK->nCol; j++){
- char *zCol = pFK->aCol[j].zCol;
- char *zOnUpdate = (char *)actionName(pFK->updateConf);
- char *zOnDelete = (char *)actionName(pFK->deleteConf);
- sqlite3VdbeAddOp2(v, OP_Integer, i, 1);
- sqlite3VdbeAddOp2(v, OP_Integer, j, 2);
- sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, pFK->zTo, 0);
- sqlite3VdbeAddOp4(v, OP_String8, 0, 4, 0,
- pTab->aCol[pFK->aCol[j].iFrom].zName, 0);
- sqlite3VdbeAddOp4(v, zCol ? OP_String8 : OP_Null, 0, 5, 0, zCol, 0);
- sqlite3VdbeAddOp4(v, OP_String8, 0, 6, 0, zOnUpdate, 0);
- sqlite3VdbeAddOp4(v, OP_String8, 0, 7, 0, zOnDelete, 0);
- sqlite3VdbeAddOp4(v, OP_String8, 0, 8, 0, "NONE", 0);
- sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 8);
- }
- ++i;
- pFK = pFK->pNextFrom;
- }
- }
- }
- }else
-#endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */
-
-#ifndef NDEBUG
- if( sqlite3StrICmp(zLeft, "parser_trace")==0 ){
- if( zRight ){
- if( getBoolean(zRight) ){
- sqlite3ParserTrace(stderr, "parser: ");
- }else{
- sqlite3ParserTrace(0, 0);
- }
- }
- }else
-#endif
-
- /* Reinstall the LIKE and GLOB functions. The variant of LIKE
- ** used will be case sensitive or not depending on the RHS.
- */
- if( sqlite3StrICmp(zLeft, "case_sensitive_like")==0 ){
- if( zRight ){
- sqlite3RegisterLikeFunctions(db, getBoolean(zRight));
- }
- }else
-
-#ifndef SQLITE_INTEGRITY_CHECK_ERROR_MAX
-# define SQLITE_INTEGRITY_CHECK_ERROR_MAX 100
-#endif
-
-#ifndef SQLITE_OMIT_INTEGRITY_CHECK
- /* Pragma "quick_check" is an experimental reduced version of
- ** integrity_check designed to detect most database corruption
- ** without most of the overhead of a full integrity-check.
- */
- if( sqlite3StrICmp(zLeft, "integrity_check")==0
- || sqlite3StrICmp(zLeft, "quick_check")==0
- ){
- int i, j, addr, mxErr;
-
- /* Code that appears at the end of the integrity check. If no error
- ** messages have been generated, output OK. Otherwise output the
- ** error message
- */
- static const VdbeOpList endCode[] = {
- { OP_AddImm, 1, 0, 0}, /* 0 */
- { OP_IfNeg, 1, 0, 0}, /* 1 */
- { OP_String8, 0, 3, 0}, /* 2 */
- { OP_ResultRow, 3, 1, 0},
- };
-
- int isQuick = (zLeft[0]=='q');
-
- /* Initialize the VDBE program */
- if( sqlite3ReadSchema(pParse) ) goto pragma_out;
- pParse->nMem = 6;
- sqlite3VdbeSetNumCols(v, 1);
- sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "integrity_check", SQLITE_STATIC);
-
- /* Set the maximum error count */
- mxErr = SQLITE_INTEGRITY_CHECK_ERROR_MAX;
- if( zRight ){
- mxErr = atoi(zRight);
- if( mxErr<=0 ){
- mxErr = SQLITE_INTEGRITY_CHECK_ERROR_MAX;
- }
- }
- sqlite3VdbeAddOp2(v, OP_Integer, mxErr, 1); /* reg[1] holds errors left */
-
- /* Do an integrity check on each database file */
- for(i=0; i<db->nDb; i++){
- HashElem *x;
- Hash *pTbls;
- int cnt = 0;
-
- if( OMIT_TEMPDB && i==1 ) continue;
-
- sqlite3CodeVerifySchema(pParse, i);
- addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1); /* Halt if out of errors */
- sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
- sqlite3VdbeJumpHere(v, addr);
-
- /* Do an integrity check of the B-Tree
- **
- ** Begin by filling registers 2, 3, ... with the root pages numbers
- ** for all tables and indices in the database.
- */
- pTbls = &db->aDb[i].pSchema->tblHash;
- for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){
- Table *pTab = sqliteHashData(x);
- Index *pIdx;
- sqlite3VdbeAddOp2(v, OP_Integer, pTab->tnum, 2+cnt);
- cnt++;
- for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
- sqlite3VdbeAddOp2(v, OP_Integer, pIdx->tnum, 2+cnt);
- cnt++;
- }
- }
-
- /* Make sure sufficient number of registers have been allocated */
- if( pParse->nMem < cnt+4 ){
- pParse->nMem = cnt+4;
- }
-
- /* Do the b-tree integrity checks */
- sqlite3VdbeAddOp3(v, OP_IntegrityCk, 2, cnt, 1);
- sqlite3VdbeChangeP5(v, (u8)i);
- addr = sqlite3VdbeAddOp1(v, OP_IsNull, 2);
- sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0,
- sqlite3MPrintf(db, "*** in database %s ***\n", db->aDb[i].zName),
- P4_DYNAMIC);
- sqlite3VdbeAddOp3(v, OP_Move, 2, 4, 1);
- sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 2);
- sqlite3VdbeAddOp2(v, OP_ResultRow, 2, 1);
- sqlite3VdbeJumpHere(v, addr);
-
- /* Make sure all the indices are constructed correctly.
- */
- for(x=sqliteHashFirst(pTbls); x && !isQuick; x=sqliteHashNext(x)){
- Table *pTab = sqliteHashData(x);
- Index *pIdx;
- int loopTop;
-
- if( pTab->pIndex==0 ) continue;
- addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1); /* Stop if out of errors */
- sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
- sqlite3VdbeJumpHere(v, addr);
- sqlite3OpenTableAndIndices(pParse, pTab, 1, OP_OpenRead);
- sqlite3VdbeAddOp2(v, OP_Integer, 0, 2); /* reg(2) will count entries */
- loopTop = sqlite3VdbeAddOp2(v, OP_Rewind, 1, 0);
- sqlite3VdbeAddOp2(v, OP_AddImm, 2, 1); /* increment entry count */
- for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
- int jmp2;
- static const VdbeOpList idxErr[] = {
- { OP_AddImm, 1, -1, 0},
- { OP_String8, 0, 3, 0}, /* 1 */
- { OP_Rowid, 1, 4, 0},
- { OP_String8, 0, 5, 0}, /* 3 */
- { OP_String8, 0, 6, 0}, /* 4 */
- { OP_Concat, 4, 3, 3},
- { OP_Concat, 5, 3, 3},
- { OP_Concat, 6, 3, 3},
- { OP_ResultRow, 3, 1, 0},
- { OP_IfPos, 1, 0, 0}, /* 9 */
- { OP_Halt, 0, 0, 0},
- };
- sqlite3GenerateIndexKey(pParse, pIdx, 1, 3, 1);
- jmp2 = sqlite3VdbeAddOp3(v, OP_Found, j+2, 0, 3);
- addr = sqlite3VdbeAddOpList(v, ArraySize(idxErr), idxErr);
- sqlite3VdbeChangeP4(v, addr+1, "rowid ", P4_STATIC);
- sqlite3VdbeChangeP4(v, addr+3, " missing from index ", P4_STATIC);
- sqlite3VdbeChangeP4(v, addr+4, pIdx->zName, P4_STATIC);
- sqlite3VdbeJumpHere(v, addr+9);
- sqlite3VdbeJumpHere(v, jmp2);
- }
- sqlite3VdbeAddOp2(v, OP_Next, 1, loopTop+1);
- sqlite3VdbeJumpHere(v, loopTop);
- for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
- static const VdbeOpList cntIdx[] = {
- { OP_Integer, 0, 3, 0},
- { OP_Rewind, 0, 0, 0}, /* 1 */
- { OP_AddImm, 3, 1, 0},
- { OP_Next, 0, 0, 0}, /* 3 */
- { OP_Eq, 2, 0, 3}, /* 4 */
- { OP_AddImm, 1, -1, 0},
- { OP_String8, 0, 2, 0}, /* 6 */
- { OP_String8, 0, 3, 0}, /* 7 */
- { OP_Concat, 3, 2, 2},
- { OP_ResultRow, 2, 1, 0},
- };
- addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1);
- sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
- sqlite3VdbeJumpHere(v, addr);
- addr = sqlite3VdbeAddOpList(v, ArraySize(cntIdx), cntIdx);
- sqlite3VdbeChangeP1(v, addr+1, j+2);
- sqlite3VdbeChangeP2(v, addr+1, addr+4);
- sqlite3VdbeChangeP1(v, addr+3, j+2);
- sqlite3VdbeChangeP2(v, addr+3, addr+2);
- sqlite3VdbeJumpHere(v, addr+4);
- sqlite3VdbeChangeP4(v, addr+6,
- "wrong # of entries in index ", P4_STATIC);
- sqlite3VdbeChangeP4(v, addr+7, pIdx->zName, P4_STATIC);
- }
- }
- }
- addr = sqlite3VdbeAddOpList(v, ArraySize(endCode), endCode);
- sqlite3VdbeChangeP2(v, addr, -mxErr);
- sqlite3VdbeJumpHere(v, addr+1);
- sqlite3VdbeChangeP4(v, addr+2, "ok", P4_STATIC);
- }else
-#endif /* SQLITE_OMIT_INTEGRITY_CHECK */
-
-#ifndef SQLITE_OMIT_UTF16
- /*
- ** PRAGMA encoding
- ** PRAGMA encoding = "utf-8"|"utf-16"|"utf-16le"|"utf-16be"
- **
- ** In its first form, this pragma returns the encoding of the main
- ** database. If the database is not initialized, it is initialized now.
- **
- ** The second form of this pragma is a no-op if the main database file
- ** has not already been initialized. In this case it sets the default
- ** encoding that will be used for the main database file if a new file
- ** is created. If an existing main database file is opened, then the
- ** default text encoding for the existing database is used.
- **
- ** In all cases new databases created using the ATTACH command are
- ** created to use the same default text encoding as the main database. If
- ** the main database has not been initialized and/or created when ATTACH
- ** is executed, this is done before the ATTACH operation.
- **
- ** In the second form this pragma sets the text encoding to be used in
- ** new database files created using this database handle. It is only
- ** useful if invoked immediately after the main database i
- */
- if( sqlite3StrICmp(zLeft, "encoding")==0 ){
- static const struct EncName {
- char *zName;
- u8 enc;
- } encnames[] = {
- { "UTF8", SQLITE_UTF8 },
- { "UTF-8", SQLITE_UTF8 }, /* Must be element [1] */
- { "UTF-16le", SQLITE_UTF16LE }, /* Must be element [2] */
- { "UTF-16be", SQLITE_UTF16BE }, /* Must be element [3] */
- { "UTF16le", SQLITE_UTF16LE },
- { "UTF16be", SQLITE_UTF16BE },
- { "UTF-16", 0 }, /* SQLITE_UTF16NATIVE */
- { "UTF16", 0 }, /* SQLITE_UTF16NATIVE */
- { 0, 0 }
- };
- const struct EncName *pEnc;
- if( !zRight ){ /* "PRAGMA encoding" */
- if( sqlite3ReadSchema(pParse) ) goto pragma_out;
- sqlite3VdbeSetNumCols(v, 1);
- sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "encoding", SQLITE_STATIC);
- sqlite3VdbeAddOp2(v, OP_String8, 0, 1);
- assert( encnames[SQLITE_UTF8].enc==SQLITE_UTF8 );
- assert( encnames[SQLITE_UTF16LE].enc==SQLITE_UTF16LE );
- assert( encnames[SQLITE_UTF16BE].enc==SQLITE_UTF16BE );
- sqlite3VdbeChangeP4(v, -1, encnames[ENC(pParse->db)].zName, P4_STATIC);
- sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
- }else{ /* "PRAGMA encoding = XXX" */
- /* Only change the value of sqlite.enc if the database handle is not
- ** initialized. If the main database exists, the new sqlite.enc value
- ** will be overwritten when the schema is next loaded. If it does not
- ** already exists, it will be created to use the new encoding value.
- */
- if(
- !(DbHasProperty(db, 0, DB_SchemaLoaded)) ||
- DbHasProperty(db, 0, DB_Empty)
- ){
- for(pEnc=&encnames[0]; pEnc->zName; pEnc++){
- if( 0==sqlite3StrICmp(zRight, pEnc->zName) ){
- ENC(pParse->db) = pEnc->enc ? pEnc->enc : SQLITE_UTF16NATIVE;
- break;
- }
- }
- if( !pEnc->zName ){
- sqlite3ErrorMsg(pParse, "unsupported encoding: %s", zRight);
- }
- }
- }
- }else
-#endif /* SQLITE_OMIT_UTF16 */
-
-#ifndef SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS
- /*
- ** PRAGMA [database.]schema_version
- ** PRAGMA [database.]schema_version = <integer>
- **
- ** PRAGMA [database.]user_version
- ** PRAGMA [database.]user_version = <integer>
- **
- ** The pragma's schema_version and user_version are used to set or get
- ** the value of the schema-version and user-version, respectively. Both
- ** the schema-version and the user-version are 32-bit signed integers
- ** stored in the database header.
- **
- ** The schema-cookie is usually only manipulated internally by SQLite. It
- ** is incremented by SQLite whenever the database schema is modified (by
- ** creating or dropping a table or index). The schema version is used by
- ** SQLite each time a query is executed to ensure that the internal cache
- ** of the schema used when compiling the SQL query matches the schema of
- ** the database against which the compiled query is actually executed.
- ** Subverting this mechanism by using "PRAGMA schema_version" to modify
- ** the schema-version is potentially dangerous and may lead to program
- ** crashes or database corruption. Use with caution!
- **
- ** The user-version is not used internally by SQLite. It may be used by
- ** applications for any purpose.
- */
- if( sqlite3StrICmp(zLeft, "schema_version")==0
- || sqlite3StrICmp(zLeft, "user_version")==0
- || sqlite3StrICmp(zLeft, "freelist_count")==0
- ){
- int iCookie; /* Cookie index. 1 for schema-cookie, 6 for user-cookie. */
- sqlite3VdbeUsesBtree(v, iDb);
- switch( zLeft[0] ){
- case 'f': case 'F':
- iCookie = BTREE_FREE_PAGE_COUNT;
- break;
- case 's': case 'S':
- iCookie = BTREE_SCHEMA_VERSION;
- break;
- default:
- iCookie = BTREE_USER_VERSION;
- break;
- }
-
- if( zRight && iCookie!=BTREE_FREE_PAGE_COUNT ){
- /* Write the specified cookie value */
- static const VdbeOpList setCookie[] = {
- { OP_Transaction, 0, 1, 0}, /* 0 */
- { OP_Integer, 0, 1, 0}, /* 1 */
- { OP_SetCookie, 0, 0, 1}, /* 2 */
- };
- int addr = sqlite3VdbeAddOpList(v, ArraySize(setCookie), setCookie);
- sqlite3VdbeChangeP1(v, addr, iDb);
- sqlite3VdbeChangeP1(v, addr+1, atoi(zRight));
- sqlite3VdbeChangeP1(v, addr+2, iDb);
- sqlite3VdbeChangeP2(v, addr+2, iCookie);
- }else{
- /* Read the specified cookie value */
- static const VdbeOpList readCookie[] = {
- { OP_Transaction, 0, 0, 0}, /* 0 */
- { OP_ReadCookie, 0, 1, 0}, /* 1 */
- { OP_ResultRow, 1, 1, 0}
- };
- int addr = sqlite3VdbeAddOpList(v, ArraySize(readCookie), readCookie);
- sqlite3VdbeChangeP1(v, addr, iDb);
- sqlite3VdbeChangeP1(v, addr+1, iDb);
- sqlite3VdbeChangeP3(v, addr+1, iCookie);
- sqlite3VdbeSetNumCols(v, 1);
- sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLeft, SQLITE_TRANSIENT);
- }
- }else
-#endif /* SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS */
-
-#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
- /*
- ** Report the current state of file logs for all databases
- */
- if( sqlite3StrICmp(zLeft, "lock_status")==0 ){
- static const char *const azLockName[] = {
- "unlocked", "shared", "reserved", "pending", "exclusive"
- };
- int i;
- sqlite3VdbeSetNumCols(v, 2);
- pParse->nMem = 2;
- sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "database", SQLITE_STATIC);
- sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "status", SQLITE_STATIC);
- for(i=0; i<db->nDb; i++){
- Btree *pBt;
- Pager *pPager;
- const char *zState = "unknown";
- int j;
- if( db->aDb[i].zName==0 ) continue;
- sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, db->aDb[i].zName, P4_STATIC);
- pBt = db->aDb[i].pBt;
- if( pBt==0 || (pPager = sqlite3BtreePager(pBt))==0 ){
- zState = "closed";
- }else if( sqlite3_file_control(db, i ? db->aDb[i].zName : 0,
- SQLITE_FCNTL_LOCKSTATE, &j)==SQLITE_OK ){
- zState = azLockName[j];
- }
- sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, zState, P4_STATIC);
- sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 2);
- }
-
- }else
-#endif
-
-#ifdef SQLITE_HAS_CODEC
- if( sqlite3StrICmp(zLeft, "key")==0 && zRight ){
- sqlite3_key(db, zRight, sqlite3Strlen30(zRight));
- }else
- if( sqlite3StrICmp(zLeft, "rekey")==0 && zRight ){
- sqlite3_rekey(db, zRight, sqlite3Strlen30(zRight));
- }else
- if( zRight && (sqlite3StrICmp(zLeft, "hexkey")==0 ||
- sqlite3StrICmp(zLeft, "hexrekey")==0) ){
- int i, h1, h2;
- char zKey[40];
- for(i=0; (h1 = zRight[i])!=0 && (h2 = zRight[i+1])!=0; i+=2){
- h1 += 9*(1&(h1>>6));
- h2 += 9*(1&(h2>>6));
- zKey[i/2] = (h2 & 0x0f) | ((h1 & 0xf)<<4);
- }
- if( (zLeft[3] & 0xf)==0xb ){
- sqlite3_key(db, zKey, i/2);
- }else{
- sqlite3_rekey(db, zKey, i/2);
- }
- }else
-#endif
-#if defined(SQLITE_HAS_CODEC) || defined(SQLITE_ENABLE_CEROD)
- if( sqlite3StrICmp(zLeft, "activate_extensions")==0 ){
-#ifdef SQLITE_HAS_CODEC
- if( sqlite3StrNICmp(zRight, "see-", 4)==0 ){
- extern void sqlite3_activate_see(const char*);
- sqlite3_activate_see(&zRight[4]);
- }
-#endif
-#ifdef SQLITE_ENABLE_CEROD
- if( sqlite3StrNICmp(zRight, "cerod-", 6)==0 ){
- extern void sqlite3_activate_cerod(const char*);
- sqlite3_activate_cerod(&zRight[6]);
- }
-#endif
- }else
-#endif
-
-
- {/* Empty ELSE clause */}
-
- /* Code an OP_Expire at the end of each PRAGMA program to cause
- ** the VDBE implementing the pragma to expire. Most (all?) pragmas
- ** are only valid for a single execution.
- */
- sqlite3VdbeAddOp2(v, OP_Expire, 1, 0);
-
- /*
- ** Reset the safety level, in case the fullfsync flag or synchronous
- ** setting changed.
- */
-#ifndef SQLITE_OMIT_PAGER_PRAGMAS
- if( db->autoCommit ){
- sqlite3BtreeSetSafetyLevel(pDb->pBt, pDb->safety_level,
- (db->flags&SQLITE_FullFSync)!=0);
- }
-#endif
-pragma_out:
- sqlite3DbFree(db, zLeft);
- sqlite3DbFree(db, zRight);
-}
-
-#endif /* SQLITE_OMIT_PRAGMA */
-
-/************** End of pragma.c **********************************************/
-/************** Begin file prepare.c *****************************************/
-/*
-** 2005 May 25
-**
-** 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 implementation of the sqlite3_prepare()
-** interface, and routines that contribute to loading the database schema
-** from disk.
-**
-** $Id: prepare.c,v 1.131 2009/08/06 17:43:31 drh Exp $
-*/
-
-/*
-** Fill the InitData structure with an error message that indicates
-** that the database is corrupt.
-*/
-static void corruptSchema(
- InitData *pData, /* Initialization context */
- const char *zObj, /* Object being parsed at the point of error */
- const char *zExtra /* Error information */
-){
- sqlite3 *db = pData->db;
- if( !db->mallocFailed && (db->flags & SQLITE_RecoveryMode)==0 ){
- if( zObj==0 ) zObj = "?";
- sqlite3SetString(pData->pzErrMsg, db,
- "malformed database schema (%s)", zObj);
- if( zExtra ){
- *pData->pzErrMsg = sqlite3MAppendf(db, *pData->pzErrMsg,
- "%s - %s", *pData->pzErrMsg, zExtra);
- }
- }
- pData->rc = db->mallocFailed ? SQLITE_NOMEM : SQLITE_CORRUPT;
-}
-
-/*
-** This is the callback routine for the code that initializes the
-** database. See sqlite3Init() below for additional information.
-** This routine is also called from the OP_ParseSchema opcode of the VDBE.
-**
-** Each callback contains the following information:
-**
-** argv[0] = name of thing being created
-** argv[1] = root page number for table or index. 0 for trigger or view.
-** argv[2] = SQL text for the CREATE statement.
-**
-*/
-SQLITE_PRIVATE int sqlite3InitCallback(void *pInit, int argc, char **argv, char **NotUsed){
- InitData *pData = (InitData*)pInit;
- sqlite3 *db = pData->db;
- int iDb = pData->iDb;
-
- assert( argc==3 );
- UNUSED_PARAMETER2(NotUsed, argc);
- assert( sqlite3_mutex_held(db->mutex) );
- DbClearProperty(db, iDb, DB_Empty);
- if( db->mallocFailed ){
- corruptSchema(pData, argv[0], 0);
- return 1;
- }
-
- assert( iDb>=0 && iDb<db->nDb );
- if( argv==0 ) return 0; /* Might happen if EMPTY_RESULT_CALLBACKS are on */
- if( argv[1]==0 ){
- corruptSchema(pData, argv[0], 0);
- }else if( argv[2] && argv[2][0] ){
- /* Call the parser to process a CREATE TABLE, INDEX or VIEW.
- ** But because db->init.busy is set to 1, no VDBE code is generated
- ** or executed. All the parser does is build the internal data
- ** structures that describe the table, index, or view.
- */
- char *zErr;
- int rc;
- assert( db->init.busy );
- db->init.iDb = iDb;
- db->init.newTnum = atoi(argv[1]);
- db->init.orphanTrigger = 0;
- rc = sqlite3_exec(db, argv[2], 0, 0, &zErr);
- db->init.iDb = 0;
- assert( rc!=SQLITE_OK || zErr==0 );
- if( SQLITE_OK!=rc ){
- if( db->init.orphanTrigger ){
- assert( iDb==1 );
- }else{
- pData->rc = rc;
- if( rc==SQLITE_NOMEM ){
- db->mallocFailed = 1;
- }else if( rc!=SQLITE_INTERRUPT && rc!=SQLITE_LOCKED ){
- corruptSchema(pData, argv[0], zErr);
- }
- }
- sqlite3DbFree(db, zErr);
- }
- }else if( argv[0]==0 ){
- corruptSchema(pData, 0, 0);
- }else{
- /* If the SQL column is blank it means this is an index that
- ** was created to be the PRIMARY KEY or to fulfill a UNIQUE
- ** constraint for a CREATE TABLE. The index should have already
- ** been created when we processed the CREATE TABLE. All we have
- ** to do here is record the root page number for that index.
- */
- Index *pIndex;
- pIndex = sqlite3FindIndex(db, argv[0], db->aDb[iDb].zName);
- if( pIndex==0 ){
- /* This can occur if there exists an index on a TEMP table which
- ** has the same name as another index on a permanent index. Since
- ** the permanent table is hidden by the TEMP table, we can also
- ** safely ignore the index on the permanent table.
- */
- /* Do Nothing */;
- }else if( sqlite3GetInt32(argv[1], &pIndex->tnum)==0 ){
- corruptSchema(pData, argv[0], "invalid rootpage");
- }
- }
- return 0;
-}
-
-/*
-** Attempt to read the database schema and initialize internal
-** data structures for a single database file. The index of the
-** database file is given by iDb. iDb==0 is used for the main
-** database. iDb==1 should never be used. iDb>=2 is used for
-** auxiliary databases. Return one of the SQLITE_ error codes to
-** indicate success or failure.
-*/
-static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){
- int rc;
- int i;
- int size;
- Table *pTab;
- Db *pDb;
- char const *azArg[4];
- int meta[5];
- InitData initData;
- char const *zMasterSchema;
- char const *zMasterName = SCHEMA_TABLE(iDb);
- int openedTransaction = 0;
-
- /*
- ** The master database table has a structure like this
- */
- static const char master_schema[] =
- "CREATE TABLE sqlite_master(\n"
- " type text,\n"
- " name text,\n"
- " tbl_name text,\n"
- " rootpage integer,\n"
- " sql text\n"
- ")"
- ;
-#ifndef SQLITE_OMIT_TEMPDB
- static const char temp_master_schema[] =
- "CREATE TEMP TABLE sqlite_temp_master(\n"
- " type text,\n"
- " name text,\n"
- " tbl_name text,\n"
- " rootpage integer,\n"
- " sql text\n"
- ")"
- ;
-#else
- #define temp_master_schema 0
-#endif
-
- assert( iDb>=0 && iDb<db->nDb );
- assert( db->aDb[iDb].pSchema );
- assert( sqlite3_mutex_held(db->mutex) );
- assert( iDb==1 || sqlite3BtreeHoldsMutex(db->aDb[iDb].pBt) );
-
- /* zMasterSchema and zInitScript are set to point at the master schema
- ** and initialisation script appropriate for the database being
- ** initialised. zMasterName is the name of the master table.
- */
- if( !OMIT_TEMPDB && iDb==1 ){
- zMasterSchema = temp_master_schema;
- }else{
- zMasterSchema = master_schema;
- }
- zMasterName = SCHEMA_TABLE(iDb);
-
- /* Construct the schema tables. */
- azArg[0] = zMasterName;
- azArg[1] = "1";
- azArg[2] = zMasterSchema;
- azArg[3] = 0;
- initData.db = db;
- initData.iDb = iDb;
- initData.rc = SQLITE_OK;
- initData.pzErrMsg = pzErrMsg;
- (void)sqlite3SafetyOff(db);
- sqlite3InitCallback(&initData, 3, (char **)azArg, 0);
- (void)sqlite3SafetyOn(db);
- if( initData.rc ){
- rc = initData.rc;
- goto error_out;
- }
- pTab = sqlite3FindTable(db, zMasterName, db->aDb[iDb].zName);
- if( ALWAYS(pTab) ){
- pTab->tabFlags |= TF_Readonly;
- }
-
- /* Create a cursor to hold the database open
- */
- pDb = &db->aDb[iDb];
- if( pDb->pBt==0 ){
- if( !OMIT_TEMPDB && ALWAYS(iDb==1) ){
- DbSetProperty(db, 1, DB_SchemaLoaded);
- }
- return SQLITE_OK;
- }
-
- /* If there is not already a read-only (or read-write) transaction opened
- ** on the b-tree database, open one now. If a transaction is opened, it
- ** will be closed before this function returns. */
- sqlite3BtreeEnter(pDb->pBt);
- if( !sqlite3BtreeIsInReadTrans(pDb->pBt) ){
- rc = sqlite3BtreeBeginTrans(pDb->pBt, 0);
- if( rc!=SQLITE_OK ){
- sqlite3SetString(pzErrMsg, db, "%s", sqlite3ErrStr(rc));
- goto initone_error_out;
- }
- openedTransaction = 1;
- }
-
- /* Get the database meta information.
- **
- ** Meta values are as follows:
- ** meta[0] Schema cookie. Changes with each schema change.
- ** meta[1] File format of schema layer.
- ** meta[2] Size of the page cache.
- ** meta[3] Largest rootpage (auto/incr_vacuum mode)
- ** meta[4] Db text encoding. 1:UTF-8 2:UTF-16LE 3:UTF-16BE
- ** meta[5] User version
- ** meta[6] Incremental vacuum mode
- ** meta[7] unused
- ** meta[8] unused
- ** meta[9] unused
- **
- ** Note: The #defined SQLITE_UTF* symbols in sqliteInt.h correspond to
- ** the possible values of meta[4].
- */
- for(i=0; i<ArraySize(meta); i++){
- sqlite3BtreeGetMeta(pDb->pBt, i+1, (u32 *)&meta[i]);
- }
- pDb->pSchema->schema_cookie = meta[BTREE_SCHEMA_VERSION-1];
-
- /* If opening a non-empty database, check the text encoding. For the
- ** main database, set sqlite3.enc to the encoding of the main database.
- ** For an attached db, it is an error if the encoding is not the same
- ** as sqlite3.enc.
- */
- if( meta[BTREE_TEXT_ENCODING-1] ){ /* text encoding */
- if( iDb==0 ){
- u8 encoding;
- /* If opening the main database, set ENC(db). */
- encoding = (u8)meta[BTREE_TEXT_ENCODING-1] & 3;
- if( encoding==0 ) encoding = SQLITE_UTF8;
- ENC(db) = encoding;
- db->pDfltColl = sqlite3FindCollSeq(db, SQLITE_UTF8, "BINARY", 0);
- }else{
- /* If opening an attached database, the encoding much match ENC(db) */
- if( meta[BTREE_TEXT_ENCODING-1]!=ENC(db) ){
- sqlite3SetString(pzErrMsg, db, "attached databases must use the same"
- " text encoding as main database");
- rc = SQLITE_ERROR;
- goto initone_error_out;
- }
- }
- }else{
- DbSetProperty(db, iDb, DB_Empty);
- }
- pDb->pSchema->enc = ENC(db);
-
- if( pDb->pSchema->cache_size==0 ){
- size = meta[BTREE_DEFAULT_CACHE_SIZE-1];
- if( size==0 ){ size = SQLITE_DEFAULT_CACHE_SIZE; }
- if( size<0 ) size = -size;
- pDb->pSchema->cache_size = size;
- sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size);
- }
-
- /*
- ** file_format==1 Version 3.0.0.
- ** file_format==2 Version 3.1.3. // ALTER TABLE ADD COLUMN
- ** file_format==3 Version 3.1.4. // ditto but with non-NULL defaults
- ** file_format==4 Version 3.3.0. // DESC indices. Boolean constants
- */
- pDb->pSchema->file_format = (u8)meta[BTREE_FILE_FORMAT-1];
- if( pDb->pSchema->file_format==0 ){
- pDb->pSchema->file_format = 1;
- }
- if( pDb->pSchema->file_format>SQLITE_MAX_FILE_FORMAT ){
- sqlite3SetString(pzErrMsg, db, "unsupported file format");
- rc = SQLITE_ERROR;
- goto initone_error_out;
- }
-
- /* Ticket #2804: When we open a database in the newer file format,
- ** clear the legacy_file_format pragma flag so that a VACUUM will
- ** not downgrade the database and thus invalidate any descending
- ** indices that the user might have created.
- */
- if( iDb==0 && meta[BTREE_FILE_FORMAT-1]>=4 ){
- db->flags &= ~SQLITE_LegacyFileFmt;
- }
-
- /* Read the schema information out of the schema tables
- */
- assert( db->init.busy );
- {
- char *zSql;
- zSql = sqlite3MPrintf(db,
- "SELECT name, rootpage, sql FROM '%q'.%s",
- db->aDb[iDb].zName, zMasterName);
- (void)sqlite3SafetyOff(db);
-#ifndef SQLITE_OMIT_AUTHORIZATION
- {
- int (*xAuth)(void*,int,const char*,const char*,const char*,const char*);
- xAuth = db->xAuth;
- db->xAuth = 0;
-#endif
- rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0);
-#ifndef SQLITE_OMIT_AUTHORIZATION
- db->xAuth = xAuth;
- }
-#endif
- if( rc==SQLITE_OK ) rc = initData.rc;
- (void)sqlite3SafetyOn(db);
- sqlite3DbFree(db, zSql);
-#ifndef SQLITE_OMIT_ANALYZE
- if( rc==SQLITE_OK ){
- sqlite3AnalysisLoad(db, iDb);
- }
-#endif
- }
- if( db->mallocFailed ){
- rc = SQLITE_NOMEM;
- sqlite3ResetInternalSchema(db, 0);
- }
- if( rc==SQLITE_OK || (db->flags&SQLITE_RecoveryMode)){
- /* Black magic: If the SQLITE_RecoveryMode flag is set, then consider
- ** the schema loaded, even if errors occurred. In this situation the
- ** current sqlite3_prepare() operation will fail, but the following one
- ** will attempt to compile the supplied statement against whatever subset
- ** of the schema was loaded before the error occurred. The primary
- ** purpose of this is to allow access to the sqlite_master table
- ** even when its contents have been corrupted.
- */
- DbSetProperty(db, iDb, DB_SchemaLoaded);
- rc = SQLITE_OK;
- }
-
- /* Jump here for an error that occurs after successfully allocating
- ** curMain and calling sqlite3BtreeEnter(). For an error that occurs
- ** before that point, jump to error_out.
- */
-initone_error_out:
- if( openedTransaction ){
- sqlite3BtreeCommit(pDb->pBt);
- }
- sqlite3BtreeLeave(pDb->pBt);
-
-error_out:
- if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){
- db->mallocFailed = 1;
- }
- return rc;
-}
-
-/*
-** Initialize all database files - the main database file, the file
-** used to store temporary tables, and any additional database files
-** created using ATTACH statements. Return a success code. If an
-** error occurs, write an error message into *pzErrMsg.
-**
-** After a database is initialized, the DB_SchemaLoaded bit is set
-** bit is set in the flags field of the Db structure. If the database
-** file was of zero-length, then the DB_Empty flag is also set.
-*/
-SQLITE_PRIVATE int sqlite3Init(sqlite3 *db, char **pzErrMsg){
- int i, rc;
- int commit_internal = !(db->flags&SQLITE_InternChanges);
-
- assert( sqlite3_mutex_held(db->mutex) );
- rc = SQLITE_OK;
- db->init.busy = 1;
- for(i=0; rc==SQLITE_OK && i<db->nDb; i++){
- if( DbHasProperty(db, i, DB_SchemaLoaded) || i==1 ) continue;
- rc = sqlite3InitOne(db, i, pzErrMsg);
- if( rc ){
- sqlite3ResetInternalSchema(db, i);
- }
- }
-
- /* Once all the other databases have been initialised, load the schema
- ** for the TEMP database. This is loaded last, as the TEMP database
- ** schema may contain references to objects in other databases.
- */
-#ifndef SQLITE_OMIT_TEMPDB
- if( rc==SQLITE_OK && ALWAYS(db->nDb>1)
- && !DbHasProperty(db, 1, DB_SchemaLoaded) ){
- rc = sqlite3InitOne(db, 1, pzErrMsg);
- if( rc ){
- sqlite3ResetInternalSchema(db, 1);
- }
- }
-#endif
-
- db->init.busy = 0;
- if( rc==SQLITE_OK && commit_internal ){
- sqlite3CommitInternalChanges(db);
- }
-
- return rc;
-}
-
-/*
-** This routine is a no-op if the database schema is already initialised.
-** Otherwise, the schema is loaded. An error code is returned.
-*/
-SQLITE_PRIVATE int sqlite3ReadSchema(Parse *pParse){
- int rc = SQLITE_OK;
- sqlite3 *db = pParse->db;
- assert( sqlite3_mutex_held(db->mutex) );
- if( !db->init.busy ){
- rc = sqlite3Init(db, &pParse->zErrMsg);
- }
- if( rc!=SQLITE_OK ){
- pParse->rc = rc;
- pParse->nErr++;
- }
- return rc;
-}
-
-
-/*
-** Check schema cookies in all databases. If any cookie is out
-** of date set pParse->rc to SQLITE_SCHEMA. If all schema cookies
-** make no changes to pParse->rc.
-*/
-static void schemaIsValid(Parse *pParse){
- sqlite3 *db = pParse->db;
- int iDb;
- int rc;
- int cookie;
-
- assert( pParse->checkSchema );
- assert( sqlite3_mutex_held(db->mutex) );
- for(iDb=0; iDb<db->nDb; iDb++){
- int openedTransaction = 0; /* True if a transaction is opened */
- Btree *pBt = db->aDb[iDb].pBt; /* Btree database to read cookie from */
- if( pBt==0 ) continue;
-
- /* If there is not already a read-only (or read-write) transaction opened
- ** on the b-tree database, open one now. If a transaction is opened, it
- ** will be closed immediately after reading the meta-value. */
- if( !sqlite3BtreeIsInReadTrans(pBt) ){
- rc = sqlite3BtreeBeginTrans(pBt, 0);
- if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){
- db->mallocFailed = 1;
- }
- if( rc!=SQLITE_OK ) return;
- openedTransaction = 1;
- }
-
- /* Read the schema cookie from the database. If it does not match the
- ** value stored as part of the in the in-memory schema representation,
- ** set Parse.rc to SQLITE_SCHEMA. */
- sqlite3BtreeGetMeta(pBt, BTREE_SCHEMA_VERSION, (u32 *)&cookie);
- if( cookie!=db->aDb[iDb].pSchema->schema_cookie ){
- pParse->rc = SQLITE_SCHEMA;
- }
-
- /* Close the transaction, if one was opened. */
- if( openedTransaction ){
- sqlite3BtreeCommit(pBt);
- }
- }
-}
-
-/*
-** Convert a schema pointer into the iDb index that indicates
-** which database file in db->aDb[] the schema refers to.
-**
-** If the same database is attached more than once, the first
-** attached database is returned.
-*/
-SQLITE_PRIVATE int sqlite3SchemaToIndex(sqlite3 *db, Schema *pSchema){
- int i = -1000000;
-
- /* If pSchema is NULL, then return -1000000. This happens when code in
- ** expr.c is trying to resolve a reference to a transient table (i.e. one
- ** created by a sub-select). In this case the return value of this
- ** function should never be used.
- **
- ** We return -1000000 instead of the more usual -1 simply because using
- ** -1000000 as the incorrect index into db->aDb[] is much
- ** more likely to cause a segfault than -1 (of course there are assert()
- ** statements too, but it never hurts to play the odds).
- */
- assert( sqlite3_mutex_held(db->mutex) );
- if( pSchema ){
- for(i=0; ALWAYS(i<db->nDb); i++){
- if( db->aDb[i].pSchema==pSchema ){
- break;
- }
- }
- assert( i>=0 && i<db->nDb );
- }
- return i;
-}
-
-/*
-** Compile the UTF-8 encoded SQL statement zSql into a statement handle.
-*/
-static int sqlite3Prepare(
- sqlite3 *db, /* Database handle. */
- const char *zSql, /* UTF-8 encoded SQL statement. */
- int nBytes, /* Length of zSql in bytes. */
- int saveSqlFlag, /* True to copy SQL text into the sqlite3_stmt */
- sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */
- const char **pzTail /* OUT: End of parsed string */
-){
- Parse *pParse; /* Parsing context */
- char *zErrMsg = 0; /* Error message */
- int rc = SQLITE_OK; /* Result code */
- int i; /* Loop counter */
-
- /* Allocate the parsing context */
- pParse = sqlite3StackAllocZero(db, sizeof(*pParse));
- if( pParse==0 ){
- rc = SQLITE_NOMEM;
- goto end_prepare;
- }
-
- if( sqlite3SafetyOn(db) ){
- rc = SQLITE_MISUSE;
- goto end_prepare;
- }
- assert( ppStmt && *ppStmt==0 );
- assert( !db->mallocFailed );
- assert( sqlite3_mutex_held(db->mutex) );
-
- /* Check to verify that it is possible to get a read lock on all
- ** database schemas. The inability to get a read lock indicates that
- ** some other database connection is holding a write-lock, which in
- ** turn means that the other connection has made uncommitted changes
- ** to the schema.
- **
- ** Were we to proceed and prepare the statement against the uncommitted
- ** schema changes and if those schema changes are subsequently rolled
- ** back and different changes are made in their place, then when this
- ** prepared statement goes to run the schema cookie would fail to detect
- ** the schema change. Disaster would follow.
- **
- ** This thread is currently holding mutexes on all Btrees (because
- ** of the sqlite3BtreeEnterAll() in sqlite3LockAndPrepare()) so it
- ** is not possible for another thread to start a new schema change
- ** while this routine is running. Hence, we do not need to hold
- ** locks on the schema, we just need to make sure nobody else is
- ** holding them.
- **
- ** Note that setting READ_UNCOMMITTED overrides most lock detection,
- ** but it does *not* override schema lock detection, so this all still
- ** works even if READ_UNCOMMITTED is set.
- */
- for(i=0; i<db->nDb; i++) {
- Btree *pBt = db->aDb[i].pBt;
- if( pBt ){
- assert( sqlite3BtreeHoldsMutex(pBt) );
- rc = sqlite3BtreeSchemaLocked(pBt);
- if( rc ){
- const char *zDb = db->aDb[i].zName;
- sqlite3Error(db, rc, "database schema is locked: %s", zDb);
- (void)sqlite3SafetyOff(db);
- testcase( db->flags & SQLITE_ReadUncommitted );
- goto end_prepare;
- }
- }
- }
-
- sqlite3VtabUnlockList(db);
-
- pParse->db = db;
- if( nBytes>=0 && (nBytes==0 || zSql[nBytes-1]!=0) ){
- char *zSqlCopy;
- int mxLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH];
- testcase( nBytes==mxLen );
- testcase( nBytes==mxLen+1 );
- if( nBytes>mxLen ){
- sqlite3Error(db, SQLITE_TOOBIG, "statement too long");
- (void)sqlite3SafetyOff(db);
- rc = sqlite3ApiExit(db, SQLITE_TOOBIG);
- goto end_prepare;
- }
- zSqlCopy = sqlite3DbStrNDup(db, zSql, nBytes);
- if( zSqlCopy ){
- sqlite3RunParser(pParse, zSqlCopy, &zErrMsg);
- sqlite3DbFree(db, zSqlCopy);
- pParse->zTail = &zSql[pParse->zTail-zSqlCopy];
- }else{
- pParse->zTail = &zSql[nBytes];
- }
- }else{
- sqlite3RunParser(pParse, zSql, &zErrMsg);
- }
-
- if( db->mallocFailed ){
- pParse->rc = SQLITE_NOMEM;
- }
- if( pParse->rc==SQLITE_DONE ) pParse->rc = SQLITE_OK;
- if( pParse->checkSchema ){
- schemaIsValid(pParse);
- }
- if( pParse->rc==SQLITE_SCHEMA ){
- sqlite3ResetInternalSchema(db, 0);
- }
- if( db->mallocFailed ){
- pParse->rc = SQLITE_NOMEM;
- }
- if( pzTail ){
- *pzTail = pParse->zTail;
- }
- rc = pParse->rc;
-
-#ifndef SQLITE_OMIT_EXPLAIN
- if( rc==SQLITE_OK && pParse->pVdbe && pParse->explain ){
- static const char * const azColName[] = {
- "addr", "opcode", "p1", "p2", "p3", "p4", "p5", "comment",
- "order", "from", "detail"
- };
- int iFirst, mx;
- if( pParse->explain==2 ){
- sqlite3VdbeSetNumCols(pParse->pVdbe, 3);
- iFirst = 8;
- mx = 11;
- }else{
- sqlite3VdbeSetNumCols(pParse->pVdbe, 8);
- iFirst = 0;
- mx = 8;
- }
- for(i=iFirst; i<mx; i++){
- sqlite3VdbeSetColName(pParse->pVdbe, i-iFirst, COLNAME_NAME,
- azColName[i], SQLITE_STATIC);
- }
- }
-#endif
-
- if( sqlite3SafetyOff(db) ){
- rc = SQLITE_MISUSE;
- }
-
- assert( db->init.busy==0 || saveSqlFlag==0 );
- if( db->init.busy==0 ){
- Vdbe *pVdbe = pParse->pVdbe;
- sqlite3VdbeSetSql(pVdbe, zSql, (int)(pParse->zTail-zSql), saveSqlFlag);
- }
- if( pParse->pVdbe && (rc!=SQLITE_OK || db->mallocFailed) ){
- sqlite3VdbeFinalize(pParse->pVdbe);
- assert(!(*ppStmt));
- }else{
- *ppStmt = (sqlite3_stmt*)pParse->pVdbe;
- }
-
- if( zErrMsg ){
- sqlite3Error(db, rc, "%s", zErrMsg);
- sqlite3DbFree(db, zErrMsg);
- }else{
- sqlite3Error(db, rc, 0);
- }
-
- /* Delete any TriggerPrg structures allocated while parsing this statement. */
- while( pParse->pTriggerPrg ){
- TriggerPrg *pT = pParse->pTriggerPrg;
- pParse->pTriggerPrg = pT->pNext;
- sqlite3VdbeProgramDelete(db, pT->pProgram, 0);
- sqlite3DbFree(db, pT);
- }
-
-end_prepare:
-
- sqlite3StackFree(db, pParse);
- rc = sqlite3ApiExit(db, rc);
- assert( (rc&db->errMask)==rc );
- return rc;
-}
-static int sqlite3LockAndPrepare(
- sqlite3 *db, /* Database handle. */
- const char *zSql, /* UTF-8 encoded SQL statement. */
- int nBytes, /* Length of zSql in bytes. */
- int saveSqlFlag, /* True to copy SQL text into the sqlite3_stmt */
- sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */
- const char **pzTail /* OUT: End of parsed string */
-){
- int rc;
- assert( ppStmt!=0 );
- *ppStmt = 0;
- if( !sqlite3SafetyCheckOk(db) ){
- return SQLITE_MISUSE;
- }
- sqlite3_mutex_enter(db->mutex);
- sqlite3BtreeEnterAll(db);
- rc = sqlite3Prepare(db, zSql, nBytes, saveSqlFlag, ppStmt, pzTail);
- if( rc==SQLITE_SCHEMA ){
- sqlite3_finalize(*ppStmt);
- rc = sqlite3Prepare(db, zSql, nBytes, saveSqlFlag, ppStmt, pzTail);
- }
- sqlite3BtreeLeaveAll(db);
- sqlite3_mutex_leave(db->mutex);
- return rc;
-}
-
-/*
-** Rerun the compilation of a statement after a schema change.
-**
-** If the statement is successfully recompiled, return SQLITE_OK. Otherwise,
-** if the statement cannot be recompiled because another connection has
-** locked the sqlite3_master table, return SQLITE_LOCKED. If any other error
-** occurs, return SQLITE_SCHEMA.
-*/
-SQLITE_PRIVATE int sqlite3Reprepare(Vdbe *p){
- int rc;
- sqlite3_stmt *pNew;
- const char *zSql;
- sqlite3 *db;
-
- assert( sqlite3_mutex_held(sqlite3VdbeDb(p)->mutex) );
- zSql = sqlite3_sql((sqlite3_stmt *)p);
- assert( zSql!=0 ); /* Reprepare only called for prepare_v2() statements */
- db = sqlite3VdbeDb(p);
- assert( sqlite3_mutex_held(db->mutex) );
- rc = sqlite3LockAndPrepare(db, zSql, -1, 0, &pNew, 0);
- if( rc ){
- if( rc==SQLITE_NOMEM ){
- db->mallocFailed = 1;
- }
- assert( pNew==0 );
- return (rc==SQLITE_LOCKED) ? SQLITE_LOCKED : SQLITE_SCHEMA;
- }else{
- assert( pNew!=0 );
- }
- sqlite3VdbeSwap((Vdbe*)pNew, p);
- sqlite3TransferBindings(pNew, (sqlite3_stmt*)p);
- sqlite3VdbeResetStepResult((Vdbe*)pNew);
- sqlite3VdbeFinalize((Vdbe*)pNew);
- return SQLITE_OK;
-}
-
-
-/*
-** Two versions of the official API. Legacy and new use. In the legacy
-** version, the original SQL text is not saved in the prepared statement
-** and so if a schema change occurs, SQLITE_SCHEMA is returned by
-** sqlite3_step(). In the new version, the original SQL text is retained
-** and the statement is automatically recompiled if an schema change
-** occurs.
-*/
-SQLITE_API int sqlite3_prepare(
- sqlite3 *db, /* Database handle. */
- const char *zSql, /* UTF-8 encoded SQL statement. */
- int nBytes, /* Length of zSql in bytes. */
- sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */
- const char **pzTail /* OUT: End of parsed string */
-){
- int rc;
- rc = sqlite3LockAndPrepare(db,zSql,nBytes,0,ppStmt,pzTail);
- assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 ); /* VERIFY: F13021 */
- return rc;
-}
-SQLITE_API int sqlite3_prepare_v2(
- sqlite3 *db, /* Database handle. */
- const char *zSql, /* UTF-8 encoded SQL statement. */
- int nBytes, /* Length of zSql in bytes. */
- sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */
- const char **pzTail /* OUT: End of parsed string */
-){
- int rc;
- rc = sqlite3LockAndPrepare(db,zSql,nBytes,1,ppStmt,pzTail);
- assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 ); /* VERIFY: F13021 */
- return rc;
-}
-
-
-#ifndef SQLITE_OMIT_UTF16
-/*
-** Compile the UTF-16 encoded SQL statement zSql into a statement handle.
-*/
-static int sqlite3Prepare16(
- sqlite3 *db, /* Database handle. */
- const void *zSql, /* UTF-8 encoded SQL statement. */
- int nBytes, /* Length of zSql in bytes. */
- int saveSqlFlag, /* True to save SQL text into the sqlite3_stmt */
- sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */
- const void **pzTail /* OUT: End of parsed string */
-){
- /* This function currently works by first transforming the UTF-16
- ** encoded string to UTF-8, then invoking sqlite3_prepare(). The
- ** tricky bit is figuring out the pointer to return in *pzTail.
- */
- char *zSql8;
- const char *zTail8 = 0;
- int rc = SQLITE_OK;
-
- assert( ppStmt );
- *ppStmt = 0;
- if( !sqlite3SafetyCheckOk(db) ){
- return SQLITE_MISUSE;
- }
- sqlite3_mutex_enter(db->mutex);
- zSql8 = sqlite3Utf16to8(db, zSql, nBytes);
- if( zSql8 ){
- rc = sqlite3LockAndPrepare(db, zSql8, -1, saveSqlFlag, ppStmt, &zTail8);
- }
-
- if( zTail8 && pzTail ){
- /* If sqlite3_prepare returns a tail pointer, we calculate the
- ** equivalent pointer into the UTF-16 string by counting the unicode
- ** characters between zSql8 and zTail8, and then returning a pointer
- ** the same number of characters into the UTF-16 string.
- */
- int chars_parsed = sqlite3Utf8CharLen(zSql8, (int)(zTail8-zSql8));
- *pzTail = (u8 *)zSql + sqlite3Utf16ByteLen(zSql, chars_parsed);
- }
- sqlite3DbFree(db, zSql8);
- rc = sqlite3ApiExit(db, rc);
- sqlite3_mutex_leave(db->mutex);
- return rc;
-}
-
-/*
-** Two versions of the official API. Legacy and new use. In the legacy
-** version, the original SQL text is not saved in the prepared statement
-** and so if a schema change occurs, SQLITE_SCHEMA is returned by
-** sqlite3_step(). In the new version, the original SQL text is retained
-** and the statement is automatically recompiled if an schema change
-** occurs.
-*/
-SQLITE_API int sqlite3_prepare16(
- sqlite3 *db, /* Database handle. */
- const void *zSql, /* UTF-8 encoded SQL statement. */
- int nBytes, /* Length of zSql in bytes. */
- sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */
- const void **pzTail /* OUT: End of parsed string */
-){
- int rc;
- rc = sqlite3Prepare16(db,zSql,nBytes,0,ppStmt,pzTail);
- assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 ); /* VERIFY: F13021 */
- return rc;
-}
-SQLITE_API int sqlite3_prepare16_v2(
- sqlite3 *db, /* Database handle. */
- const void *zSql, /* UTF-8 encoded SQL statement. */
- int nBytes, /* Length of zSql in bytes. */
- sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */
- const void **pzTail /* OUT: End of parsed string */
-){
- int rc;
- rc = sqlite3Prepare16(db,zSql,nBytes,1,ppStmt,pzTail);
- assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 ); /* VERIFY: F13021 */
- return rc;
-}
-
-#endif /* SQLITE_OMIT_UTF16 */
-
-/************** End of prepare.c *********************************************/
-/************** Begin file select.c ******************************************/
-/*
-** 2001 September 15
-**
-** 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 C code routines that are called by the parser
-** to handle SELECT statements in SQLite.
-**
-** $Id: select.c,v 1.526 2009/08/01 15:09:58 drh Exp $
-*/
-
-
-/*
-** Delete all the content of a Select structure but do not deallocate
-** the select structure itself.
-*/
-static void clearSelect(sqlite3 *db, Select *p){
- sqlite3ExprListDelete(db, p->pEList);
- sqlite3SrcListDelete(db, p->pSrc);
- sqlite3ExprDelete(db, p->pWhere);
- sqlite3ExprListDelete(db, p->pGroupBy);
- sqlite3ExprDelete(db, p->pHaving);
- sqlite3ExprListDelete(db, p->pOrderBy);
- sqlite3SelectDelete(db, p->pPrior);
- sqlite3ExprDelete(db, p->pLimit);
- sqlite3ExprDelete(db, p->pOffset);
-}
-
-/*
-** Initialize a SelectDest structure.
-*/
-SQLITE_PRIVATE void sqlite3SelectDestInit(SelectDest *pDest, int eDest, int iParm){
- pDest->eDest = (u8)eDest;
- pDest->iParm = iParm;
- pDest->affinity = 0;
- pDest->iMem = 0;
- pDest->nMem = 0;
-}
-
-
-/*
-** Allocate a new Select structure and return a pointer to that
-** structure.
-*/
-SQLITE_PRIVATE Select *sqlite3SelectNew(
- Parse *pParse, /* Parsing context */
- ExprList *pEList, /* which columns to include in the result */
- SrcList *pSrc, /* the FROM clause -- which tables to scan */
- Expr *pWhere, /* the WHERE clause */
- ExprList *pGroupBy, /* the GROUP BY clause */
- Expr *pHaving, /* the HAVING clause */
- ExprList *pOrderBy, /* the ORDER BY clause */
- int isDistinct, /* true if the DISTINCT keyword is present */
- Expr *pLimit, /* LIMIT value. NULL means not used */
- Expr *pOffset /* OFFSET value. NULL means no offset */
-){
- Select *pNew;
- Select standin;
- sqlite3 *db = pParse->db;
- pNew = sqlite3DbMallocZero(db, sizeof(*pNew) );
- assert( db->mallocFailed || !pOffset || pLimit ); /* OFFSET implies LIMIT */
- if( pNew==0 ){
- pNew = &standin;
- memset(pNew, 0, sizeof(*pNew));
- }
- if( pEList==0 ){
- pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db,TK_ALL,0));
- }
- pNew->pEList = pEList;
- pNew->pSrc = pSrc;
- pNew->pWhere = pWhere;
- pNew->pGroupBy = pGroupBy;
- pNew->pHaving = pHaving;
- pNew->pOrderBy = pOrderBy;
- pNew->selFlags = isDistinct ? SF_Distinct : 0;
- pNew->op = TK_SELECT;
- pNew->pLimit = pLimit;
- pNew->pOffset = pOffset;
- assert( pOffset==0 || pLimit!=0 );
- pNew->addrOpenEphm[0] = -1;
- pNew->addrOpenEphm[1] = -1;
- pNew->addrOpenEphm[2] = -1;
- if( db->mallocFailed ) {
- clearSelect(db, pNew);
- if( pNew!=&standin ) sqlite3DbFree(db, pNew);
- pNew = 0;
- }
- return pNew;
-}
-
-/*
-** Delete the given Select structure and all of its substructures.
-*/
-SQLITE_PRIVATE void sqlite3SelectDelete(sqlite3 *db, Select *p){
- if( p ){
- clearSelect(db, p);
- sqlite3DbFree(db, p);
- }
-}
-
-/*
-** Given 1 to 3 identifiers preceeding the JOIN keyword, determine the
-** type of join. Return an integer constant that expresses that type
-** in terms of the following bit values:
-**
-** JT_INNER
-** JT_CROSS
-** JT_OUTER
-** JT_NATURAL
-** JT_LEFT
-** JT_RIGHT
-**
-** A full outer join is the combination of JT_LEFT and JT_RIGHT.
-**
-** If an illegal or unsupported join type is seen, then still return
-** a join type, but put an error in the pParse structure.
-*/
-SQLITE_PRIVATE int sqlite3JoinType(Parse *pParse, Token *pA, Token *pB, Token *pC){
- int jointype = 0;
- Token *apAll[3];
- Token *p;
- /* 0123456789 123456789 123456789 123 */
- static const char zKeyText[] = "naturaleftouterightfullinnercross";
- static const struct {
- u8 i; /* Beginning of keyword text in zKeyText[] */
- u8 nChar; /* Length of the keyword in characters */
- u8 code; /* Join type mask */
- } aKeyword[] = {
- /* natural */ { 0, 7, JT_NATURAL },
- /* left */ { 6, 4, JT_LEFT|JT_OUTER },
- /* outer */ { 10, 5, JT_OUTER },
- /* right */ { 14, 5, JT_RIGHT|JT_OUTER },
- /* full */ { 19, 4, JT_LEFT|JT_RIGHT|JT_OUTER },
- /* inner */ { 23, 5, JT_INNER },
- /* cross */ { 28, 5, JT_INNER|JT_CROSS },
- };
- int i, j;
- apAll[0] = pA;
- apAll[1] = pB;
- apAll[2] = pC;
- for(i=0; i<3 && apAll[i]; i++){
- p = apAll[i];
- for(j=0; j<ArraySize(aKeyword); j++){
- if( p->n==aKeyword[j].nChar
- && sqlite3StrNICmp((char*)p->z, &zKeyText[aKeyword[j].i], p->n)==0 ){
- jointype |= aKeyword[j].code;
- break;
- }
- }
- testcase( j==0 || j==1 || j==2 || j==3 || j==4 || j==5 || j==6 );
- if( j>=ArraySize(aKeyword) ){
- jointype |= JT_ERROR;
- break;
- }
- }
- if(
- (jointype & (JT_INNER|JT_OUTER))==(JT_INNER|JT_OUTER) ||
- (jointype & JT_ERROR)!=0
- ){
- const char *zSp = " ";
- assert( pB!=0 );
- if( pC==0 ){ zSp++; }
- sqlite3ErrorMsg(pParse, "unknown or unsupported join type: "
- "%T %T%s%T", pA, pB, zSp, pC);
- jointype = JT_INNER;
- }else if( (jointype & JT_OUTER)!=0
- && (jointype & (JT_LEFT|JT_RIGHT))!=JT_LEFT ){
- sqlite3ErrorMsg(pParse,
- "RIGHT and FULL OUTER JOINs are not currently supported");
- jointype = JT_INNER;
- }
- return jointype;
-}
-
-/*
-** Return the index of a column in a table. Return -1 if the column
-** is not contained in the table.
-*/
-static int columnIndex(Table *pTab, const char *zCol){
- int i;
- for(i=0; i<pTab->nCol; i++){
- if( sqlite3StrICmp(pTab->aCol[i].zName, zCol)==0 ) return i;
- }
- return -1;
-}
-
-/*
-** Create an expression node for an identifier with the name of zName
-*/
-SQLITE_PRIVATE Expr *sqlite3CreateIdExpr(Parse *pParse, const char *zName){
- return sqlite3Expr(pParse->db, TK_ID, zName);
-}
-
-/*
-** Add a term to the WHERE expression in *ppExpr that requires the
-** zCol column to be equal in the two tables pTab1 and pTab2.
-*/
-static void addWhereTerm(
- Parse *pParse, /* Parsing context */
- const char *zCol, /* Name of the column */
- const Table *pTab1, /* First table */
- const char *zAlias1, /* Alias for first table. May be NULL */
- const Table *pTab2, /* Second table */
- const char *zAlias2, /* Alias for second table. May be NULL */
- int iRightJoinTable, /* VDBE cursor for the right table */
- Expr **ppExpr, /* Add the equality term to this expression */
- int isOuterJoin /* True if dealing with an OUTER join */
-){
- Expr *pE1a, *pE1b, *pE1c;
- Expr *pE2a, *pE2b, *pE2c;
- Expr *pE;
-
- pE1a = sqlite3CreateIdExpr(pParse, zCol);
- pE2a = sqlite3CreateIdExpr(pParse, zCol);
- if( zAlias1==0 ){
- zAlias1 = pTab1->zName;
- }
- pE1b = sqlite3CreateIdExpr(pParse, zAlias1);
- if( zAlias2==0 ){
- zAlias2 = pTab2->zName;
- }
- pE2b = sqlite3CreateIdExpr(pParse, zAlias2);
- pE1c = sqlite3PExpr(pParse, TK_DOT, pE1b, pE1a, 0);
- pE2c = sqlite3PExpr(pParse, TK_DOT, pE2b, pE2a, 0);
- pE = sqlite3PExpr(pParse, TK_EQ, pE1c, pE2c, 0);
- if( pE && isOuterJoin ){
- ExprSetProperty(pE, EP_FromJoin);
- assert( !ExprHasAnyProperty(pE, EP_TokenOnly|EP_Reduced) );
- ExprSetIrreducible(pE);
- pE->iRightJoinTable = (i16)iRightJoinTable;
- }
- *ppExpr = sqlite3ExprAnd(pParse->db,*ppExpr, pE);
-}
-
-/*
-** Set the EP_FromJoin property on all terms of the given expression.
-** And set the Expr.iRightJoinTable to iTable for every term in the
-** expression.
-**
-** The EP_FromJoin property is used on terms of an expression to tell
-** the LEFT OUTER JOIN processing logic that this term is part of the
-** join restriction specified in the ON or USING clause and not a part
-** of the more general WHERE clause. These terms are moved over to the
-** WHERE clause during join processing but we need to remember that they
-** originated in the ON or USING clause.
-**
-** The Expr.iRightJoinTable tells the WHERE clause processing that the
-** expression depends on table iRightJoinTable even if that table is not
-** explicitly mentioned in the expression. That information is needed
-** for cases like this:
-**
-** SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.b AND t1.x=5
-**
-** The where clause needs to defer the handling of the t1.x=5
-** term until after the t2 loop of the join. In that way, a
-** NULL t2 row will be inserted whenever t1.x!=5. If we do not
-** defer the handling of t1.x=5, it will be processed immediately
-** after the t1 loop and rows with t1.x!=5 will never appear in
-** the output, which is incorrect.
-*/
-static void setJoinExpr(Expr *p, int iTable){
- while( p ){
- ExprSetProperty(p, EP_FromJoin);
- assert( !ExprHasAnyProperty(p, EP_TokenOnly|EP_Reduced) );
- ExprSetIrreducible(p);
- p->iRightJoinTable = (i16)iTable;
- setJoinExpr(p->pLeft, iTable);
- p = p->pRight;
- }
-}
-
-/*
-** This routine processes the join information for a SELECT statement.
-** ON and USING clauses are converted into extra terms of the WHERE clause.
-** NATURAL joins also create extra WHERE clause terms.
-**
-** The terms of a FROM clause are contained in the Select.pSrc structure.
-** The left most table is the first entry in Select.pSrc. The right-most
-** table is the last entry. The join operator is held in the entry to
-** the left. Thus entry 0 contains the join operator for the join between
-** entries 0 and 1. Any ON or USING clauses associated with the join are
-** also attached to the left entry.
-**
-** This routine returns the number of errors encountered.
-*/
-static int sqliteProcessJoin(Parse *pParse, Select *p){
- SrcList *pSrc; /* All tables in the FROM clause */
- int i, j; /* Loop counters */
- struct SrcList_item *pLeft; /* Left table being joined */
- struct SrcList_item *pRight; /* Right table being joined */
-
- pSrc = p->pSrc;
- pLeft = &pSrc->a[0];
- pRight = &pLeft[1];
- for(i=0; i<pSrc->nSrc-1; i++, pRight++, pLeft++){
- Table *pLeftTab = pLeft->pTab;
- Table *pRightTab = pRight->pTab;
- int isOuter;
-
- if( NEVER(pLeftTab==0 || pRightTab==0) ) continue;
- isOuter = (pRight->jointype & JT_OUTER)!=0;
-
- /* When the NATURAL keyword is present, add WHERE clause terms for
- ** every column that the two tables have in common.
- */
- if( pRight->jointype & JT_NATURAL ){
- if( pRight->pOn || pRight->pUsing ){
- sqlite3ErrorMsg(pParse, "a NATURAL join may not have "
- "an ON or USING clause", 0);
- return 1;
- }
- for(j=0; j<pLeftTab->nCol; j++){
- char *zName = pLeftTab->aCol[j].zName;
- if( columnIndex(pRightTab, zName)>=0 ){
- addWhereTerm(pParse, zName, pLeftTab, pLeft->zAlias,
- pRightTab, pRight->zAlias,
- pRight->iCursor, &p->pWhere, isOuter);
-
- }
- }
- }
-
- /* Disallow both ON and USING clauses in the same join
- */
- if( pRight->pOn && pRight->pUsing ){
- sqlite3ErrorMsg(pParse, "cannot have both ON and USING "
- "clauses in the same join");
- return 1;
- }
-
- /* Add the ON clause to the end of the WHERE clause, connected by
- ** an AND operator.
- */
- if( pRight->pOn ){
- if( isOuter ) setJoinExpr(pRight->pOn, pRight->iCursor);
- p->pWhere = sqlite3ExprAnd(pParse->db, p->pWhere, pRight->pOn);
- pRight->pOn = 0;
- }
-
- /* Create extra terms on the WHERE clause for each column named
- ** in the USING clause. Example: If the two tables to be joined are
- ** A and B and the USING clause names X, Y, and Z, then add this
- ** to the WHERE clause: A.X=B.X AND A.Y=B.Y AND A.Z=B.Z
- ** Report an error if any column mentioned in the USING clause is
- ** not contained in both tables to be joined.
- */
- if( pRight->pUsing ){
- IdList *pList = pRight->pUsing;
- for(j=0; j<pList->nId; j++){
- char *zName = pList->a[j].zName;
- if( columnIndex(pLeftTab, zName)<0 || columnIndex(pRightTab, zName)<0 ){
- sqlite3ErrorMsg(pParse, "cannot join using column %s - column "
- "not present in both tables", zName);
- return 1;
- }
- addWhereTerm(pParse, zName, pLeftTab, pLeft->zAlias,
- pRightTab, pRight->zAlias,
- pRight->iCursor, &p->pWhere, isOuter);
- }
- }
- }
- return 0;
-}
-
-/*
-** Insert code into "v" that will push the record on the top of the
-** stack into the sorter.
-*/
-static void pushOntoSorter(
- Parse *pParse, /* Parser context */
- ExprList *pOrderBy, /* The ORDER BY clause */
- Select *pSelect, /* The whole SELECT statement */
- int regData /* Register holding data to be sorted */
-){
- Vdbe *v = pParse->pVdbe;
- int nExpr = pOrderBy->nExpr;
- int regBase = sqlite3GetTempRange(pParse, nExpr+2);
- int regRecord = sqlite3GetTempReg(pParse);
- sqlite3ExprCacheClear(pParse);
- sqlite3ExprCodeExprList(pParse, pOrderBy, regBase, 0);
- sqlite3VdbeAddOp2(v, OP_Sequence, pOrderBy->iECursor, regBase+nExpr);
- sqlite3ExprCodeMove(pParse, regData, regBase+nExpr+1, 1);
- sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nExpr + 2, regRecord);
- sqlite3VdbeAddOp2(v, OP_IdxInsert, pOrderBy->iECursor, regRecord);
- sqlite3ReleaseTempReg(pParse, regRecord);
- sqlite3ReleaseTempRange(pParse, regBase, nExpr+2);
- if( pSelect->iLimit ){
- int addr1, addr2;
- int iLimit;
- if( pSelect->iOffset ){
- iLimit = pSelect->iOffset+1;
- }else{
- iLimit = pSelect->iLimit;
- }
- addr1 = sqlite3VdbeAddOp1(v, OP_IfZero, iLimit);
- sqlite3VdbeAddOp2(v, OP_AddImm, iLimit, -1);
- addr2 = sqlite3VdbeAddOp0(v, OP_Goto);
- sqlite3VdbeJumpHere(v, addr1);
- sqlite3VdbeAddOp1(v, OP_Last, pOrderBy->iECursor);
- sqlite3VdbeAddOp1(v, OP_Delete, pOrderBy->iECursor);
- sqlite3VdbeJumpHere(v, addr2);
- pSelect->iLimit = 0;
- }
-}
-
-/*
-** Add code to implement the OFFSET
-*/
-static void codeOffset(
- Vdbe *v, /* Generate code into this VM */
- Select *p, /* The SELECT statement being coded */
- int iContinue /* Jump here to skip the current record */
-){
- if( p->iOffset && iContinue!=0 ){
- int addr;
- sqlite3VdbeAddOp2(v, OP_AddImm, p->iOffset, -1);
- addr = sqlite3VdbeAddOp1(v, OP_IfNeg, p->iOffset);
- sqlite3VdbeAddOp2(v, OP_Goto, 0, iContinue);
- VdbeComment((v, "skip OFFSET records"));
- sqlite3VdbeJumpHere(v, addr);
- }
-}
-
-/*
-** Add code that will check to make sure the N registers starting at iMem
-** form a distinct entry. iTab is a sorting index that holds previously
-** seen combinations of the N values. A new entry is made in iTab
-** if the current N values are new.
-**
-** A jump to addrRepeat is made and the N+1 values are popped from the
-** stack if the top N elements are not distinct.
-*/
-static void codeDistinct(
- Parse *pParse, /* Parsing and code generating context */
- int iTab, /* A sorting index used to test for distinctness */
- int addrRepeat, /* Jump to here if not distinct */
- int N, /* Number of elements */
- int iMem /* First element */
-){
- Vdbe *v;
- int r1;
-
- v = pParse->pVdbe;
- r1 = sqlite3GetTempReg(pParse);
- sqlite3VdbeAddOp3(v, OP_MakeRecord, iMem, N, r1);
- sqlite3VdbeAddOp3(v, OP_Found, iTab, addrRepeat, r1);
- sqlite3VdbeAddOp2(v, OP_IdxInsert, iTab, r1);
- sqlite3ReleaseTempReg(pParse, r1);
-}
-
-/*
-** Generate an error message when a SELECT is used within a subexpression
-** (example: "a IN (SELECT * FROM table)") but it has more than 1 result
-** column. We do this in a subroutine because the error occurs in multiple
-** places.
-*/
-static int checkForMultiColumnSelectError(
- Parse *pParse, /* Parse context. */
- SelectDest *pDest, /* Destination of SELECT results */
- int nExpr /* Number of result columns returned by SELECT */
-){
- int eDest = pDest->eDest;
- if( nExpr>1 && (eDest==SRT_Mem || eDest==SRT_Set) ){
- sqlite3ErrorMsg(pParse, "only a single result allowed for "
- "a SELECT that is part of an expression");
- return 1;
- }else{
- return 0;
- }
-}
-
-/*
-** This routine generates the code for the inside of the inner loop
-** of a SELECT.
-**
-** If srcTab and nColumn are both zero, then the pEList expressions
-** are evaluated in order to get the data for this row. If nColumn>0
-** then data is pulled from srcTab and pEList is used only to get the
-** datatypes for each column.
-*/
-static void selectInnerLoop(
- Parse *pParse, /* The parser context */
- Select *p, /* The complete select statement being coded */
- ExprList *pEList, /* List of values being extracted */
- int srcTab, /* Pull data from this table */
- int nColumn, /* Number of columns in the source table */
- ExprList *pOrderBy, /* If not NULL, sort results using this key */
- int distinct, /* If >=0, make sure results are distinct */
- SelectDest *pDest, /* How to dispose of the results */
- int iContinue, /* Jump here to continue with next row */
- int iBreak /* Jump here to break out of the inner loop */
-){
- Vdbe *v = pParse->pVdbe;
- int i;
- int hasDistinct; /* True if the DISTINCT keyword is present */
- int regResult; /* Start of memory holding result set */
- int eDest = pDest->eDest; /* How to dispose of results */
- int iParm = pDest->iParm; /* First argument to disposal method */
- int nResultCol; /* Number of result columns */
-
- assert( v );
- if( NEVER(v==0) ) return;
- assert( pEList!=0 );
- hasDistinct = distinct>=0;
- if( pOrderBy==0 && !hasDistinct ){
- codeOffset(v, p, iContinue);
- }
-
- /* Pull the requested columns.
- */
- if( nColumn>0 ){
- nResultCol = nColumn;
- }else{
- nResultCol = pEList->nExpr;
- }
- if( pDest->iMem==0 ){
- pDest->iMem = pParse->nMem+1;
- pDest->nMem = nResultCol;
- pParse->nMem += nResultCol;
- }else{
- assert( pDest->nMem==nResultCol );
- }
- regResult = pDest->iMem;
- if( nColumn>0 ){
- for(i=0; i<nColumn; i++){
- sqlite3VdbeAddOp3(v, OP_Column, srcTab, i, regResult+i);
- }
- }else if( eDest!=SRT_Exists ){
- /* If the destination is an EXISTS(...) expression, the actual
- ** values returned by the SELECT are not required.
- */
- sqlite3ExprCacheClear(pParse);
- sqlite3ExprCodeExprList(pParse, pEList, regResult, eDest==SRT_Output);
- }
- nColumn = nResultCol;
-
- /* If the DISTINCT keyword was present on the SELECT statement
- ** and this row has been seen before, then do not make this row
- ** part of the result.
- */
- if( hasDistinct ){
- assert( pEList!=0 );
- assert( pEList->nExpr==nColumn );
- codeDistinct(pParse, distinct, iContinue, nColumn, regResult);
- if( pOrderBy==0 ){
- codeOffset(v, p, iContinue);
- }
- }
-
- if( checkForMultiColumnSelectError(pParse, pDest, pEList->nExpr) ){
- return;
- }
-
- switch( eDest ){
- /* In this mode, write each query result to the key of the temporary
- ** table iParm.
- */
-#ifndef SQLITE_OMIT_COMPOUND_SELECT
- case SRT_Union: {
- int r1;
- r1 = sqlite3GetTempReg(pParse);
- sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nColumn, r1);
- sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm, r1);
- sqlite3ReleaseTempReg(pParse, r1);
- break;
- }
-
- /* Construct a record from the query result, but instead of
- ** saving that record, use it as a key to delete elements from
- ** the temporary table iParm.
- */
- case SRT_Except: {
- sqlite3VdbeAddOp3(v, OP_IdxDelete, iParm, regResult, nColumn);
- break;
- }
-#endif
-
- /* Store the result as data using a unique key.
- */
- case SRT_Table:
- case SRT_EphemTab: {
- int r1 = sqlite3GetTempReg(pParse);
- testcase( eDest==SRT_Table );
- testcase( eDest==SRT_EphemTab );
- sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nColumn, r1);
- if( pOrderBy ){
- pushOntoSorter(pParse, pOrderBy, p, r1);
- }else{
- int r2 = sqlite3GetTempReg(pParse);
- sqlite3VdbeAddOp2(v, OP_NewRowid, iParm, r2);
- sqlite3VdbeAddOp3(v, OP_Insert, iParm, r1, r2);
- sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
- sqlite3ReleaseTempReg(pParse, r2);
- }
- sqlite3ReleaseTempReg(pParse, r1);
- break;
- }
-
-#ifndef SQLITE_OMIT_SUBQUERY
- /* If we are creating a set for an "expr IN (SELECT ...)" construct,
- ** then there should be a single item on the stack. Write this
- ** item into the set table with bogus data.
- */
- case SRT_Set: {
- assert( nColumn==1 );
- p->affinity = sqlite3CompareAffinity(pEList->a[0].pExpr, pDest->affinity);
- if( pOrderBy ){
- /* At first glance you would think we could optimize out the
- ** ORDER BY in this case since the order of entries in the set
- ** does not matter. But there might be a LIMIT clause, in which
- ** case the order does matter */
- pushOntoSorter(pParse, pOrderBy, p, regResult);
- }else{
- int r1 = sqlite3GetTempReg(pParse);
- sqlite3VdbeAddOp4(v, OP_MakeRecord, regResult, 1, r1, &p->affinity, 1);
- sqlite3ExprCacheAffinityChange(pParse, regResult, 1);
- sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm, r1);
- sqlite3ReleaseTempReg(pParse, r1);
- }
- break;
- }
-
- /* If any row exist in the result set, record that fact and abort.
- */
- case SRT_Exists: {
- sqlite3VdbeAddOp2(v, OP_Integer, 1, iParm);
- /* The LIMIT clause will terminate the loop for us */
- break;
- }
-
- /* If this is a scalar select that is part of an expression, then
- ** store the results in the appropriate memory cell and break out
- ** of the scan loop.
- */
- case SRT_Mem: {
- assert( nColumn==1 );
- if( pOrderBy ){
- pushOntoSorter(pParse, pOrderBy, p, regResult);
- }else{
- sqlite3ExprCodeMove(pParse, regResult, iParm, 1);
- /* The LIMIT clause will jump out of the loop for us */
- }
- break;
- }
-#endif /* #ifndef SQLITE_OMIT_SUBQUERY */
-
- /* Send the data to the callback function or to a subroutine. In the
- ** case of a subroutine, the subroutine itself is responsible for
- ** popping the data from the stack.
- */
- case SRT_Coroutine:
- case SRT_Output: {
- testcase( eDest==SRT_Coroutine );
- testcase( eDest==SRT_Output );
- if( pOrderBy ){
- int r1 = sqlite3GetTempReg(pParse);
- sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nColumn, r1);
- pushOntoSorter(pParse, pOrderBy, p, r1);
- sqlite3ReleaseTempReg(pParse, r1);
- }else if( eDest==SRT_Coroutine ){
- sqlite3VdbeAddOp1(v, OP_Yield, pDest->iParm);
- }else{
- sqlite3VdbeAddOp2(v, OP_ResultRow, regResult, nColumn);
- sqlite3ExprCacheAffinityChange(pParse, regResult, nColumn);
- }
- break;
- }
-
-#if !defined(SQLITE_OMIT_TRIGGER)
- /* Discard the results. This is used for SELECT statements inside
- ** the body of a TRIGGER. The purpose of such selects is to call
- ** user-defined functions that have side effects. We do not care
- ** about the actual results of the select.
- */
- default: {
- assert( eDest==SRT_Discard );
- break;
- }
-#endif
- }
-
- /* Jump to the end of the loop if the LIMIT is reached.
- */
- if( p->iLimit ){
- assert( pOrderBy==0 ); /* If there is an ORDER BY, the call to
- ** pushOntoSorter() would have cleared p->iLimit */
- sqlite3VdbeAddOp2(v, OP_AddImm, p->iLimit, -1);
- sqlite3VdbeAddOp2(v, OP_IfZero, p->iLimit, iBreak);
- }
-}
-
-/*
-** Given an expression list, generate a KeyInfo structure that records
-** the collating sequence for each expression in that expression list.
-**
-** If the ExprList is an ORDER BY or GROUP BY clause then the resulting
-** KeyInfo structure is appropriate for initializing a virtual index to
-** implement that clause. If the ExprList is the result set of a SELECT
-** then the KeyInfo structure is appropriate for initializing a virtual
-** index to implement a DISTINCT test.
-**
-** Space to hold the KeyInfo structure is obtain from malloc. The calling
-** function is responsible for seeing that this structure is eventually
-** freed. Add the KeyInfo structure to the P4 field of an opcode using
-** P4_KEYINFO_HANDOFF is the usual way of dealing with this.
-*/
-static KeyInfo *keyInfoFromExprList(Parse *pParse, ExprList *pList){
- sqlite3 *db = pParse->db;
- int nExpr;
- KeyInfo *pInfo;
- struct ExprList_item *pItem;
- int i;
-
- nExpr = pList->nExpr;
- pInfo = sqlite3DbMallocZero(db, sizeof(*pInfo) + nExpr*(sizeof(CollSeq*)+1) );
- if( pInfo ){
- pInfo->aSortOrder = (u8*)&pInfo->aColl[nExpr];
- pInfo->nField = (u16)nExpr;
- pInfo->enc = ENC(db);
- pInfo->db = db;
- for(i=0, pItem=pList->a; i<nExpr; i++, pItem++){
- CollSeq *pColl;
- pColl = sqlite3ExprCollSeq(pParse, pItem->pExpr);
- if( !pColl ){
- pColl = db->pDfltColl;
- }
- pInfo->aColl[i] = pColl;
- pInfo->aSortOrder[i] = pItem->sortOrder;
- }
- }
- return pInfo;
-}
-
-
-/*
-** If the inner loop was generated using a non-null pOrderBy argument,
-** then the results were placed in a sorter. After the loop is terminated
-** we need to run the sorter and output the results. The following
-** routine generates the code needed to do that.
-*/
-static void generateSortTail(
- Parse *pParse, /* Parsing context */
- Select *p, /* The SELECT statement */
- Vdbe *v, /* Generate code into this VDBE */
- int nColumn, /* Number of columns of data */
- SelectDest *pDest /* Write the sorted results here */
-){
- int addrBreak = sqlite3VdbeMakeLabel(v); /* Jump here to exit loop */
- int addrContinue = sqlite3VdbeMakeLabel(v); /* Jump here for next cycle */
- int addr;
- int iTab;
- int pseudoTab = 0;
- ExprList *pOrderBy = p->pOrderBy;
-
- int eDest = pDest->eDest;
- int iParm = pDest->iParm;
-
- int regRow;
- int regRowid;
-
- iTab = pOrderBy->iECursor;
- regRow = sqlite3GetTempReg(pParse);
- if( eDest==SRT_Output || eDest==SRT_Coroutine ){
- pseudoTab = pParse->nTab++;
- sqlite3VdbeAddOp3(v, OP_OpenPseudo, pseudoTab, regRow, nColumn);
- regRowid = 0;
- }else{
- regRowid = sqlite3GetTempReg(pParse);
- }
- addr = 1 + sqlite3VdbeAddOp2(v, OP_Sort, iTab, addrBreak);
- codeOffset(v, p, addrContinue);
- sqlite3VdbeAddOp3(v, OP_Column, iTab, pOrderBy->nExpr + 1, regRow);
- switch( eDest ){
- case SRT_Table:
- case SRT_EphemTab: {
- testcase( eDest==SRT_Table );
- testcase( eDest==SRT_EphemTab );
- sqlite3VdbeAddOp2(v, OP_NewRowid, iParm, regRowid);
- sqlite3VdbeAddOp3(v, OP_Insert, iParm, regRow, regRowid);
- sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
- break;
- }
-#ifndef SQLITE_OMIT_SUBQUERY
- case SRT_Set: {
- assert( nColumn==1 );
- sqlite3VdbeAddOp4(v, OP_MakeRecord, regRow, 1, regRowid, &p->affinity, 1);
- sqlite3ExprCacheAffinityChange(pParse, regRow, 1);
- sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm, regRowid);
- break;
- }
- case SRT_Mem: {
- assert( nColumn==1 );
- sqlite3ExprCodeMove(pParse, regRow, iParm, 1);
- /* The LIMIT clause will terminate the loop for us */
- break;
- }
-#endif
- default: {
- int i;
- assert( eDest==SRT_Output || eDest==SRT_Coroutine );
- testcase( eDest==SRT_Output );
- testcase( eDest==SRT_Coroutine );
- for(i=0; i<nColumn; i++){
- assert( regRow!=pDest->iMem+i );
- sqlite3VdbeAddOp3(v, OP_Column, pseudoTab, i, pDest->iMem+i);
- if( i==0 ){
- sqlite3VdbeChangeP5(v, OPFLAG_CLEARCACHE);
- }
- }
- if( eDest==SRT_Output ){
- sqlite3VdbeAddOp2(v, OP_ResultRow, pDest->iMem, nColumn);
- sqlite3ExprCacheAffinityChange(pParse, pDest->iMem, nColumn);
- }else{
- sqlite3VdbeAddOp1(v, OP_Yield, pDest->iParm);
- }
- break;
- }
- }
- sqlite3ReleaseTempReg(pParse, regRow);
- sqlite3ReleaseTempReg(pParse, regRowid);
-
- /* LIMIT has been implemented by the pushOntoSorter() routine.
- */
- assert( p->iLimit==0 );
-
- /* The bottom of the loop
- */
- sqlite3VdbeResolveLabel(v, addrContinue);
- sqlite3VdbeAddOp2(v, OP_Next, iTab, addr);
- sqlite3VdbeResolveLabel(v, addrBreak);
- if( eDest==SRT_Output || eDest==SRT_Coroutine ){
- sqlite3VdbeAddOp2(v, OP_Close, pseudoTab, 0);
- }
-}
-
-/*
-** Return a pointer to a string containing the 'declaration type' of the
-** expression pExpr. The string may be treated as static by the caller.
-**
-** The declaration type is the exact datatype definition extracted from the
-** original CREATE TABLE statement if the expression is a column. The
-** declaration type for a ROWID field is INTEGER. Exactly when an expression
-** is considered a column can be complex in the presence of subqueries. The
-** result-set expression in all of the following SELECT statements is
-** considered a column by this function.
-**
-** SELECT col FROM tbl;
-** SELECT (SELECT col FROM tbl;
-** SELECT (SELECT col FROM tbl);
-** SELECT abc FROM (SELECT col AS abc FROM tbl);
-**
-** The declaration type for any expression other than a column is NULL.
-*/
-static const char *columnType(
- NameContext *pNC,
- Expr *pExpr,
- const char **pzOriginDb,
- const char **pzOriginTab,
- const char **pzOriginCol
-){
- char const *zType = 0;
- char const *zOriginDb = 0;
- char const *zOriginTab = 0;
- char const *zOriginCol = 0;
- int j;
- if( NEVER(pExpr==0) || pNC->pSrcList==0 ) return 0;
-
- switch( pExpr->op ){
- case TK_AGG_COLUMN:
- case TK_COLUMN: {
- /* The expression is a column. Locate the table the column is being
- ** extracted from in NameContext.pSrcList. This table may be real
- ** database table or a subquery.
- */
- Table *pTab = 0; /* Table structure column is extracted from */
- Select *pS = 0; /* Select the column is extracted from */
- int iCol = pExpr->iColumn; /* Index of column in pTab */
- testcase( pExpr->op==TK_AGG_COLUMN );
- testcase( pExpr->op==TK_COLUMN );
- while( pNC && !pTab ){
- SrcList *pTabList = pNC->pSrcList;
- for(j=0;j<pTabList->nSrc && pTabList->a[j].iCursor!=pExpr->iTable;j++);
- if( j<pTabList->nSrc ){
- pTab = pTabList->a[j].pTab;
- pS = pTabList->a[j].pSelect;
- }else{
- pNC = pNC->pNext;
- }
- }
-
- if( pTab==0 ){
- /* At one time, code such as "SELECT new.x" within a trigger would
- ** cause this condition to run. Since then, we have restructured how
- ** trigger code is generated and so this condition is no longer
- ** possible. However, it can still be true for statements like
- ** the following:
- **
- ** CREATE TABLE t1(col INTEGER);
- ** SELECT (SELECT t1.col) FROM FROM t1;
- **
- ** when columnType() is called on the expression "t1.col" in the
- ** sub-select. In this case, set the column type to NULL, even
- ** though it should really be "INTEGER".
- **
- ** This is not a problem, as the column type of "t1.col" is never
- ** used. When columnType() is called on the expression
- ** "(SELECT t1.col)", the correct type is returned (see the TK_SELECT
- ** branch below. */
- break;
- }
-
- assert( pTab && pExpr->pTab==pTab );
- if( pS ){
- /* The "table" is actually a sub-select or a view in the FROM clause
- ** of the SELECT statement. Return the declaration type and origin
- ** data for the result-set column of the sub-select.
- */
- if( ALWAYS(iCol>=0 && iCol<pS->pEList->nExpr) ){
- /* If iCol is less than zero, then the expression requests the
- ** rowid of the sub-select or view. This expression is legal (see
- ** test case misc2.2.2) - it always evaluates to NULL.
- */
- NameContext sNC;
- Expr *p = pS->pEList->a[iCol].pExpr;
- sNC.pSrcList = pS->pSrc;
- sNC.pNext = pNC;
- sNC.pParse = pNC->pParse;
- zType = columnType(&sNC, p, &zOriginDb, &zOriginTab, &zOriginCol);
- }
- }else if( ALWAYS(pTab->pSchema) ){
- /* A real table */
- assert( !pS );
- if( iCol<0 ) iCol = pTab->iPKey;
- assert( iCol==-1 || (iCol>=0 && iCol<pTab->nCol) );
- if( iCol<0 ){
- zType = "INTEGER";
- zOriginCol = "rowid";
- }else{
- zType = pTab->aCol[iCol].zType;
- zOriginCol = pTab->aCol[iCol].zName;
- }
- zOriginTab = pTab->zName;
- if( pNC->pParse ){
- int iDb = sqlite3SchemaToIndex(pNC->pParse->db, pTab->pSchema);
- zOriginDb = pNC->pParse->db->aDb[iDb].zName;
- }
- }
- break;
- }
-#ifndef SQLITE_OMIT_SUBQUERY
- case TK_SELECT: {
- /* The expression is a sub-select. Return the declaration type and
- ** origin info for the single column in the result set of the SELECT
- ** statement.
- */
- NameContext sNC;
- Select *pS = pExpr->x.pSelect;
- Expr *p = pS->pEList->a[0].pExpr;
- assert( ExprHasProperty(pExpr, EP_xIsSelect) );
- sNC.pSrcList = pS->pSrc;
- sNC.pNext = pNC;
- sNC.pParse = pNC->pParse;
- zType = columnType(&sNC, p, &zOriginDb, &zOriginTab, &zOriginCol);
- break;
- }
-#endif
- }
-
- if( pzOriginDb ){
- assert( pzOriginTab && pzOriginCol );
- *pzOriginDb = zOriginDb;
- *pzOriginTab = zOriginTab;
- *pzOriginCol = zOriginCol;
- }
- return zType;
-}
-
-/*
-** Generate code that will tell the VDBE the declaration types of columns
-** in the result set.
-*/
-static void generateColumnTypes(
- Parse *pParse, /* Parser context */
- SrcList *pTabList, /* List of tables */
- ExprList *pEList /* Expressions defining the result set */
-){
-#ifndef SQLITE_OMIT_DECLTYPE
- Vdbe *v = pParse->pVdbe;
- int i;
- NameContext sNC;
- sNC.pSrcList = pTabList;
- sNC.pParse = pParse;
- for(i=0; i<pEList->nExpr; i++){
- Expr *p = pEList->a[i].pExpr;
- const char *zType;
-#ifdef SQLITE_ENABLE_COLUMN_METADATA
- const char *zOrigDb = 0;
- const char *zOrigTab = 0;
- const char *zOrigCol = 0;
- zType = columnType(&sNC, p, &zOrigDb, &zOrigTab, &zOrigCol);
-
- /* The vdbe must make its own copy of the column-type and other
- ** column specific strings, in case the schema is reset before this
- ** virtual machine is deleted.
- */
- sqlite3VdbeSetColName(v, i, COLNAME_DATABASE, zOrigDb, SQLITE_TRANSIENT);
- sqlite3VdbeSetColName(v, i, COLNAME_TABLE, zOrigTab, SQLITE_TRANSIENT);
- sqlite3VdbeSetColName(v, i, COLNAME_COLUMN, zOrigCol, SQLITE_TRANSIENT);
-#else
- zType = columnType(&sNC, p, 0, 0, 0);
-#endif
- sqlite3VdbeSetColName(v, i, COLNAME_DECLTYPE, zType, SQLITE_TRANSIENT);
- }
-#endif /* SQLITE_OMIT_DECLTYPE */
-}
-
-/*
-** Generate code that will tell the VDBE the names of columns
-** in the result set. This information is used to provide the
-** azCol[] values in the callback.
-*/
-static void generateColumnNames(
- Parse *pParse, /* Parser context */
- SrcList *pTabList, /* List of tables */
- ExprList *pEList /* Expressions defining the result set */
-){
- Vdbe *v = pParse->pVdbe;
- int i, j;
- sqlite3 *db = pParse->db;
- int fullNames, shortNames;
-
-#ifndef SQLITE_OMIT_EXPLAIN
- /* If this is an EXPLAIN, skip this step */
- if( pParse->explain ){
- return;
- }
-#endif
-
- if( pParse->colNamesSet || NEVER(v==0) || db->mallocFailed ) return;
- pParse->colNamesSet = 1;
- fullNames = (db->flags & SQLITE_FullColNames)!=0;
- shortNames = (db->flags & SQLITE_ShortColNames)!=0;
- sqlite3VdbeSetNumCols(v, pEList->nExpr);
- for(i=0; i<pEList->nExpr; i++){
- Expr *p;
- p = pEList->a[i].pExpr;
- if( NEVER(p==0) ) continue;
- if( pEList->a[i].zName ){
- char *zName = pEList->a[i].zName;
- sqlite3VdbeSetColName(v, i, COLNAME_NAME, zName, SQLITE_TRANSIENT);
- }else if( (p->op==TK_COLUMN || p->op==TK_AGG_COLUMN) && pTabList ){
- Table *pTab;
- char *zCol;
- int iCol = p->iColumn;
- for(j=0; ALWAYS(j<pTabList->nSrc); j++){
- if( pTabList->a[j].iCursor==p->iTable ) break;
- }
- assert( j<pTabList->nSrc );
- pTab = pTabList->a[j].pTab;
- if( iCol<0 ) iCol = pTab->iPKey;
- assert( iCol==-1 || (iCol>=0 && iCol<pTab->nCol) );
- if( iCol<0 ){
- zCol = "rowid";
- }else{
- zCol = pTab->aCol[iCol].zName;
- }
- if( !shortNames && !fullNames ){
- sqlite3VdbeSetColName(v, i, COLNAME_NAME,
- sqlite3DbStrDup(db, pEList->a[i].zSpan), SQLITE_DYNAMIC);
- }else if( fullNames ){
- char *zName = 0;
- zName = sqlite3MPrintf(db, "%s.%s", pTab->zName, zCol);
- sqlite3VdbeSetColName(v, i, COLNAME_NAME, zName, SQLITE_DYNAMIC);
- }else{
- sqlite3VdbeSetColName(v, i, COLNAME_NAME, zCol, SQLITE_TRANSIENT);
- }
- }else{
- sqlite3VdbeSetColName(v, i, COLNAME_NAME,
- sqlite3DbStrDup(db, pEList->a[i].zSpan), SQLITE_DYNAMIC);
- }
- }
- generateColumnTypes(pParse, pTabList, pEList);
-}
-
-#ifndef SQLITE_OMIT_COMPOUND_SELECT
-/*
-** Name of the connection operator, used for error messages.
-*/
-static const char *selectOpName(int id){
- char *z;
- switch( id ){
- case TK_ALL: z = "UNION ALL"; break;
- case TK_INTERSECT: z = "INTERSECT"; break;
- case TK_EXCEPT: z = "EXCEPT"; break;
- default: z = "UNION"; break;
- }
- return z;
-}
-#endif /* SQLITE_OMIT_COMPOUND_SELECT */
-
-/*
-** Given a an expression list (which is really the list of expressions
-** that form the result set of a SELECT statement) compute appropriate
-** column names for a table that would hold the expression list.
-**
-** All column names will be unique.
-**
-** Only the column names are computed. Column.zType, Column.zColl,
-** and other fields of Column are zeroed.
-**
-** Return SQLITE_OK on success. If a memory allocation error occurs,
-** store NULL in *paCol and 0 in *pnCol and return SQLITE_NOMEM.
-*/
-static int selectColumnsFromExprList(
- Parse *pParse, /* Parsing context */
- ExprList *pEList, /* Expr list from which to derive column names */
- int *pnCol, /* Write the number of columns here */
- Column **paCol /* Write the new column list here */
-){
- sqlite3 *db = pParse->db; /* Database connection */
- int i, j; /* Loop counters */
- int cnt; /* Index added to make the name unique */
- Column *aCol, *pCol; /* For looping over result columns */
- int nCol; /* Number of columns in the result set */
- Expr *p; /* Expression for a single result column */
- char *zName; /* Column name */
- int nName; /* Size of name in zName[] */
-
- *pnCol = nCol = pEList->nExpr;
- aCol = *paCol = sqlite3DbMallocZero(db, sizeof(aCol[0])*nCol);
- if( aCol==0 ) return SQLITE_NOMEM;
- for(i=0, pCol=aCol; i<nCol; i++, pCol++){
- /* Get an appropriate name for the column
- */
- p = pEList->a[i].pExpr;
- assert( p->pRight==0 || ExprHasProperty(p->pRight, EP_IntValue)
- || p->pRight->u.zToken==0 || p->pRight->u.zToken[0]!=0 );
- if( (zName = pEList->a[i].zName)!=0 ){
- /* If the column contains an "AS <name>" phrase, use <name> as the name */
- zName = sqlite3DbStrDup(db, zName);
- }else{
- Expr *pColExpr = p; /* The expression that is the result column name */
- Table *pTab; /* Table associated with this expression */
- while( pColExpr->op==TK_DOT ) pColExpr = pColExpr->pRight;
- if( pColExpr->op==TK_COLUMN && ALWAYS(pColExpr->pTab!=0) ){
- /* For columns use the column name name */
- int iCol = pColExpr->iColumn;
- pTab = pColExpr->pTab;
- if( iCol<0 ) iCol = pTab->iPKey;
- zName = sqlite3MPrintf(db, "%s",
- iCol>=0 ? pTab->aCol[iCol].zName : "rowid");
- }else if( pColExpr->op==TK_ID ){
- assert( !ExprHasProperty(pColExpr, EP_IntValue) );
- zName = sqlite3MPrintf(db, "%s", pColExpr->u.zToken);
- }else{
- /* Use the original text of the column expression as its name */
- zName = sqlite3MPrintf(db, "%s", pEList->a[i].zSpan);
- }
- }
- if( db->mallocFailed ){
- sqlite3DbFree(db, zName);
- break;
- }
-
- /* Make sure the column name is unique. If the name is not unique,
- ** append a integer to the name so that it becomes unique.
- */
- nName = sqlite3Strlen30(zName);
- for(j=cnt=0; j<i; j++){
- if( sqlite3StrICmp(aCol[j].zName, zName)==0 ){
- char *zNewName;
- zName[nName] = 0;
- zNewName = sqlite3MPrintf(db, "%s:%d", zName, ++cnt);
- sqlite3DbFree(db, zName);
- zName = zNewName;
- j = -1;
- if( zName==0 ) break;
- }
- }
- pCol->zName = zName;
- }
- if( db->mallocFailed ){
- for(j=0; j<i; j++){
- sqlite3DbFree(db, aCol[j].zName);
- }
- sqlite3DbFree(db, aCol);
- *paCol = 0;
- *pnCol = 0;
- return SQLITE_NOMEM;
- }
- return SQLITE_OK;
-}
-
-/*
-** Add type and collation information to a column list based on
-** a SELECT statement.
-**
-** The column list presumably came from selectColumnNamesFromExprList().
-** The column list has only names, not types or collations. This
-** routine goes through and adds the types and collations.
-**
-** This routine requires that all identifiers in the SELECT
-** statement be resolved.
-*/
-static void selectAddColumnTypeAndCollation(
- Parse *pParse, /* Parsing contexts */
- int nCol, /* Number of columns */
- Column *aCol, /* List of columns */
- Select *pSelect /* SELECT used to determine types and collations */
-){
- sqlite3 *db = pParse->db;
- NameContext sNC;
- Column *pCol;
- CollSeq *pColl;
- int i;
- Expr *p;
- struct ExprList_item *a;
-
- assert( pSelect!=0 );
- assert( (pSelect->selFlags & SF_Resolved)!=0 );
- assert( nCol==pSelect->pEList->nExpr || db->mallocFailed );
- if( db->mallocFailed ) return;
- memset(&sNC, 0, sizeof(sNC));
- sNC.pSrcList = pSelect->pSrc;
- a = pSelect->pEList->a;
- for(i=0, pCol=aCol; i<nCol; i++, pCol++){
- p = a[i].pExpr;
- pCol->zType = sqlite3DbStrDup(db, columnType(&sNC, p, 0, 0, 0));
- pCol->affinity = sqlite3ExprAffinity(p);
- if( pCol->affinity==0 ) pCol->affinity = SQLITE_AFF_NONE;
- pColl = sqlite3ExprCollSeq(pParse, p);
- if( pColl ){
- pCol->zColl = sqlite3DbStrDup(db, pColl->zName);
- }
- }
-}
-
-/*
-** Given a SELECT statement, generate a Table structure that describes
-** the result set of that SELECT.
-*/
-SQLITE_PRIVATE Table *sqlite3ResultSetOfSelect(Parse *pParse, Select *pSelect){
- Table *pTab;
- sqlite3 *db = pParse->db;
- int savedFlags;
-
- savedFlags = db->flags;
- db->flags &= ~SQLITE_FullColNames;
- db->flags |= SQLITE_ShortColNames;
- sqlite3SelectPrep(pParse, pSelect, 0);
- if( pParse->nErr ) return 0;
- while( pSelect->pPrior ) pSelect = pSelect->pPrior;
- db->flags = savedFlags;
- pTab = sqlite3DbMallocZero(db, sizeof(Table) );
- if( pTab==0 ){
- return 0;
- }
- /* The sqlite3ResultSetOfSelect() is only used n contexts where lookaside
- ** is disabled, so we might as well hard-code pTab->dbMem to NULL. */
- assert( db->lookaside.bEnabled==0 );
- pTab->dbMem = 0;
- pTab->nRef = 1;
- pTab->zName = 0;
- selectColumnsFromExprList(pParse, pSelect->pEList, &pTab->nCol, &pTab->aCol);
- selectAddColumnTypeAndCollation(pParse, pTab->nCol, pTab->aCol, pSelect);
- pTab->iPKey = -1;
- if( db->mallocFailed ){
- sqlite3DeleteTable(pTab);
- return 0;
- }
- return pTab;
-}
-
-/*
-** Get a VDBE for the given parser context. Create a new one if necessary.
-** If an error occurs, return NULL and leave a message in pParse.
-*/
-SQLITE_PRIVATE Vdbe *sqlite3GetVdbe(Parse *pParse){
- Vdbe *v = pParse->pVdbe;
- if( v==0 ){
- v = pParse->pVdbe = sqlite3VdbeCreate(pParse->db);
-#ifndef SQLITE_OMIT_TRACE
- if( v ){
- sqlite3VdbeAddOp0(v, OP_Trace);
- }
-#endif
- }
- return v;
-}
-
-
-/*
-** Compute the iLimit and iOffset fields of the SELECT based on the
-** pLimit and pOffset expressions. pLimit and pOffset hold the expressions
-** that appear in the original SQL statement after the LIMIT and OFFSET
-** keywords. Or NULL if those keywords are omitted. iLimit and iOffset
-** are the integer memory register numbers for counters used to compute
-** the limit and offset. If there is no limit and/or offset, then
-** iLimit and iOffset are negative.
-**
-** This routine changes the values of iLimit and iOffset only if
-** a limit or offset is defined by pLimit and pOffset. iLimit and
-** iOffset should have been preset to appropriate default values
-** (usually but not always -1) prior to calling this routine.
-** Only if pLimit!=0 or pOffset!=0 do the limit registers get
-** redefined. The UNION ALL operator uses this property to force
-** the reuse of the same limit and offset registers across multiple
-** SELECT statements.
-*/
-static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){
- Vdbe *v = 0;
- int iLimit = 0;
- int iOffset;
- int addr1;
- if( p->iLimit ) return;
-
- /*
- ** "LIMIT -1" always shows all rows. There is some
- ** contraversy about what the correct behavior should be.
- ** The current implementation interprets "LIMIT 0" to mean
- ** no rows.
- */
- sqlite3ExprCacheClear(pParse);
- assert( p->pOffset==0 || p->pLimit!=0 );
- if( p->pLimit ){
- p->iLimit = iLimit = ++pParse->nMem;
- v = sqlite3GetVdbe(pParse);
- if( NEVER(v==0) ) return; /* VDBE should have already been allocated */
- sqlite3ExprCode(pParse, p->pLimit, iLimit);
- sqlite3VdbeAddOp1(v, OP_MustBeInt, iLimit);
- VdbeComment((v, "LIMIT counter"));
- sqlite3VdbeAddOp2(v, OP_IfZero, iLimit, iBreak);
- if( p->pOffset ){
- p->iOffset = iOffset = ++pParse->nMem;
- pParse->nMem++; /* Allocate an extra register for limit+offset */
- sqlite3ExprCode(pParse, p->pOffset, iOffset);
- sqlite3VdbeAddOp1(v, OP_MustBeInt, iOffset);
- VdbeComment((v, "OFFSET counter"));
- addr1 = sqlite3VdbeAddOp1(v, OP_IfPos, iOffset);
- sqlite3VdbeAddOp2(v, OP_Integer, 0, iOffset);
- sqlite3VdbeJumpHere(v, addr1);
- sqlite3VdbeAddOp3(v, OP_Add, iLimit, iOffset, iOffset+1);
- VdbeComment((v, "LIMIT+OFFSET"));
- addr1 = sqlite3VdbeAddOp1(v, OP_IfPos, iLimit);
- sqlite3VdbeAddOp2(v, OP_Integer, -1, iOffset+1);
- sqlite3VdbeJumpHere(v, addr1);
- }
- }
-}
-
-#ifndef SQLITE_OMIT_COMPOUND_SELECT
-/*
-** Return the appropriate collating sequence for the iCol-th column of
-** the result set for the compound-select statement "p". Return NULL if
-** the column has no default collating sequence.
-**
-** The collating sequence for the compound select is taken from the
-** left-most term of the select that has a collating sequence.
-*/
-static CollSeq *multiSelectCollSeq(Parse *pParse, Select *p, int iCol){
- CollSeq *pRet;
- if( p->pPrior ){
- pRet = multiSelectCollSeq(pParse, p->pPrior, iCol);
- }else{
- pRet = 0;
- }
- assert( iCol>=0 );
- if( pRet==0 && iCol<p->pEList->nExpr ){
- pRet = sqlite3ExprCollSeq(pParse, p->pEList->a[iCol].pExpr);
- }
- return pRet;
-}
-#endif /* SQLITE_OMIT_COMPOUND_SELECT */
-
-/* Forward reference */
-static int multiSelectOrderBy(
- Parse *pParse, /* Parsing context */
- Select *p, /* The right-most of SELECTs to be coded */
- SelectDest *pDest /* What to do with query results */
-);
-
-
-#ifndef SQLITE_OMIT_COMPOUND_SELECT
-/*
-** This routine is called to process a compound query form from
-** two or more separate queries using UNION, UNION ALL, EXCEPT, or
-** INTERSECT
-**
-** "p" points to the right-most of the two queries. the query on the
-** left is p->pPrior. The left query could also be a compound query
-** in which case this routine will be called recursively.
-**
-** The results of the total query are to be written into a destination
-** of type eDest with parameter iParm.
-**
-** Example 1: Consider a three-way compound SQL statement.
-**
-** SELECT a FROM t1 UNION SELECT b FROM t2 UNION SELECT c FROM t3
-**
-** This statement is parsed up as follows:
-**
-** SELECT c FROM t3
-** |
-** `-----> SELECT b FROM t2
-** |
-** `------> SELECT a FROM t1
-**
-** The arrows in the diagram above represent the Select.pPrior pointer.
-** So if this routine is called with p equal to the t3 query, then
-** pPrior will be the t2 query. p->op will be TK_UNION in this case.
-**
-** Notice that because of the way SQLite parses compound SELECTs, the
-** individual selects always group from left to right.
-*/
-static int multiSelect(
- Parse *pParse, /* Parsing context */
- Select *p, /* The right-most of SELECTs to be coded */
- SelectDest *pDest /* What to do with query results */
-){
- int rc = SQLITE_OK; /* Success code from a subroutine */
- Select *pPrior; /* Another SELECT immediately to our left */
- Vdbe *v; /* Generate code to this VDBE */
- SelectDest dest; /* Alternative data destination */
- Select *pDelete = 0; /* Chain of simple selects to delete */
- sqlite3 *db; /* Database connection */
-
- /* Make sure there is no ORDER BY or LIMIT clause on prior SELECTs. Only
- ** the last (right-most) SELECT in the series may have an ORDER BY or LIMIT.
- */
- assert( p && p->pPrior ); /* Calling function guarantees this much */
- db = pParse->db;
- pPrior = p->pPrior;
- assert( pPrior->pRightmost!=pPrior );
- assert( pPrior->pRightmost==p->pRightmost );
- dest = *pDest;
- if( pPrior->pOrderBy ){
- sqlite3ErrorMsg(pParse,"ORDER BY clause should come after %s not before",
- selectOpName(p->op));
- rc = 1;
- goto multi_select_end;
- }
- if( pPrior->pLimit ){
- sqlite3ErrorMsg(pParse,"LIMIT clause should come after %s not before",
- selectOpName(p->op));
- rc = 1;
- goto multi_select_end;
- }
-
- v = sqlite3GetVdbe(pParse);
- assert( v!=0 ); /* The VDBE already created by calling function */
-
- /* Create the destination temporary table if necessary
- */
- if( dest.eDest==SRT_EphemTab ){
- assert( p->pEList );
- sqlite3VdbeAddOp2(v, OP_OpenEphemeral, dest.iParm, p->pEList->nExpr);
- dest.eDest = SRT_Table;
- }
-
- /* Make sure all SELECTs in the statement have the same number of elements
- ** in their result sets.
- */
- assert( p->pEList && pPrior->pEList );
- if( p->pEList->nExpr!=pPrior->pEList->nExpr ){
- sqlite3ErrorMsg(pParse, "SELECTs to the left and right of %s"
- " do not have the same number of result columns", selectOpName(p->op));
- rc = 1;
- goto multi_select_end;
- }
-
- /* Compound SELECTs that have an ORDER BY clause are handled separately.
- */
- if( p->pOrderBy ){
- return multiSelectOrderBy(pParse, p, pDest);
- }
-
- /* Generate code for the left and right SELECT statements.
- */
- switch( p->op ){
- case TK_ALL: {
- int addr = 0;
- assert( !pPrior->pLimit );
- pPrior->pLimit = p->pLimit;
- pPrior->pOffset = p->pOffset;
- rc = sqlite3Select(pParse, pPrior, &dest);
- p->pLimit = 0;
- p->pOffset = 0;
- if( rc ){
- goto multi_select_end;
- }
- p->pPrior = 0;
- p->iLimit = pPrior->iLimit;
- p->iOffset = pPrior->iOffset;
- if( p->iLimit ){
- addr = sqlite3VdbeAddOp1(v, OP_IfZero, p->iLimit);
- VdbeComment((v, "Jump ahead if LIMIT reached"));
- }
- rc = sqlite3Select(pParse, p, &dest);
- testcase( rc!=SQLITE_OK );
- pDelete = p->pPrior;
- p->pPrior = pPrior;
- if( addr ){
- sqlite3VdbeJumpHere(v, addr);
- }
- break;
- }
- case TK_EXCEPT:
- case TK_UNION: {
- int unionTab; /* Cursor number of the temporary table holding result */
- u8 op = 0; /* One of the SRT_ operations to apply to self */
- int priorOp; /* The SRT_ operation to apply to prior selects */
- Expr *pLimit, *pOffset; /* Saved values of p->nLimit and p->nOffset */
- int addr;
- SelectDest uniondest;
-
- testcase( p->op==TK_EXCEPT );
- testcase( p->op==TK_UNION );
- priorOp = SRT_Union;
- if( dest.eDest==priorOp && ALWAYS(!p->pLimit &&!p->pOffset) ){
- /* We can reuse a temporary table generated by a SELECT to our
- ** right.
- */
- assert( p->pRightmost!=p ); /* Can only happen for leftward elements
- ** of a 3-way or more compound */
- assert( p->pLimit==0 ); /* Not allowed on leftward elements */
- assert( p->pOffset==0 ); /* Not allowed on leftward elements */
- unionTab = dest.iParm;
- }else{
- /* We will need to create our own temporary table to hold the
- ** intermediate results.
- */
- unionTab = pParse->nTab++;
- assert( p->pOrderBy==0 );
- addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, unionTab, 0);
- assert( p->addrOpenEphm[0] == -1 );
- p->addrOpenEphm[0] = addr;
- p->pRightmost->selFlags |= SF_UsesEphemeral;
- assert( p->pEList );
- }
-
- /* Code the SELECT statements to our left
- */
- assert( !pPrior->pOrderBy );
- sqlite3SelectDestInit(&uniondest, priorOp, unionTab);
- rc = sqlite3Select(pParse, pPrior, &uniondest);
- if( rc ){
- goto multi_select_end;
- }
-
- /* Code the current SELECT statement
- */
- if( p->op==TK_EXCEPT ){
- op = SRT_Except;
- }else{
- assert( p->op==TK_UNION );
- op = SRT_Union;
- }
- p->pPrior = 0;
- pLimit = p->pLimit;
- p->pLimit = 0;
- pOffset = p->pOffset;
- p->pOffset = 0;
- uniondest.eDest = op;
- rc = sqlite3Select(pParse, p, &uniondest);
- testcase( rc!=SQLITE_OK );
- /* Query flattening in sqlite3Select() might refill p->pOrderBy.
- ** Be sure to delete p->pOrderBy, therefore, to avoid a memory leak. */
- sqlite3ExprListDelete(db, p->pOrderBy);
- pDelete = p->pPrior;
- p->pPrior = pPrior;
- p->pOrderBy = 0;
- sqlite3ExprDelete(db, p->pLimit);
- p->pLimit = pLimit;
- p->pOffset = pOffset;
- p->iLimit = 0;
- p->iOffset = 0;
-
- /* Convert the data in the temporary table into whatever form
- ** it is that we currently need.
- */
- assert( unionTab==dest.iParm || dest.eDest!=priorOp );
- if( dest.eDest!=priorOp ){
- int iCont, iBreak, iStart;
- assert( p->pEList );
- if( dest.eDest==SRT_Output ){
- Select *pFirst = p;
- while( pFirst->pPrior ) pFirst = pFirst->pPrior;
- generateColumnNames(pParse, 0, pFirst->pEList);
- }
- iBreak = sqlite3VdbeMakeLabel(v);
- iCont = sqlite3VdbeMakeLabel(v);
- computeLimitRegisters(pParse, p, iBreak);
- sqlite3VdbeAddOp2(v, OP_Rewind, unionTab, iBreak);
- iStart = sqlite3VdbeCurrentAddr(v);
- selectInnerLoop(pParse, p, p->pEList, unionTab, p->pEList->nExpr,
- 0, -1, &dest, iCont, iBreak);
- sqlite3VdbeResolveLabel(v, iCont);
- sqlite3VdbeAddOp2(v, OP_Next, unionTab, iStart);
- sqlite3VdbeResolveLabel(v, iBreak);
- sqlite3VdbeAddOp2(v, OP_Close, unionTab, 0);
- }
- break;
- }
- default: assert( p->op==TK_INTERSECT ); {
- int tab1, tab2;
- int iCont, iBreak, iStart;
- Expr *pLimit, *pOffset;
- int addr;
- SelectDest intersectdest;
- int r1;
-
- /* INTERSECT is different from the others since it requires
- ** two temporary tables. Hence it has its own case. Begin
- ** by allocating the tables we will need.
- */
- tab1 = pParse->nTab++;
- tab2 = pParse->nTab++;
- assert( p->pOrderBy==0 );
-
- addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, tab1, 0);
- assert( p->addrOpenEphm[0] == -1 );
- p->addrOpenEphm[0] = addr;
- p->pRightmost->selFlags |= SF_UsesEphemeral;
- assert( p->pEList );
-
- /* Code the SELECTs to our left into temporary table "tab1".
- */
- sqlite3SelectDestInit(&intersectdest, SRT_Union, tab1);
- rc = sqlite3Select(pParse, pPrior, &intersectdest);
- if( rc ){
- goto multi_select_end;
- }
-
- /* Code the current SELECT into temporary table "tab2"
- */
- addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, tab2, 0);
- assert( p->addrOpenEphm[1] == -1 );
- p->addrOpenEphm[1] = addr;
- p->pPrior = 0;
- pLimit = p->pLimit;
- p->pLimit = 0;
- pOffset = p->pOffset;
- p->pOffset = 0;
- intersectdest.iParm = tab2;
- rc = sqlite3Select(pParse, p, &intersectdest);
- testcase( rc!=SQLITE_OK );
- pDelete = p->pPrior;
- p->pPrior = pPrior;
- sqlite3ExprDelete(db, p->pLimit);
- p->pLimit = pLimit;
- p->pOffset = pOffset;
-
- /* Generate code to take the intersection of the two temporary
- ** tables.
- */
- assert( p->pEList );
- if( dest.eDest==SRT_Output ){
- Select *pFirst = p;
- while( pFirst->pPrior ) pFirst = pFirst->pPrior;
- generateColumnNames(pParse, 0, pFirst->pEList);
- }
- iBreak = sqlite3VdbeMakeLabel(v);
- iCont = sqlite3VdbeMakeLabel(v);
- computeLimitRegisters(pParse, p, iBreak);
- sqlite3VdbeAddOp2(v, OP_Rewind, tab1, iBreak);
- r1 = sqlite3GetTempReg(pParse);
- iStart = sqlite3VdbeAddOp2(v, OP_RowKey, tab1, r1);
- sqlite3VdbeAddOp3(v, OP_NotFound, tab2, iCont, r1);
- sqlite3ReleaseTempReg(pParse, r1);
- selectInnerLoop(pParse, p, p->pEList, tab1, p->pEList->nExpr,
- 0, -1, &dest, iCont, iBreak);
- sqlite3VdbeResolveLabel(v, iCont);
- sqlite3VdbeAddOp2(v, OP_Next, tab1, iStart);
- sqlite3VdbeResolveLabel(v, iBreak);
- sqlite3VdbeAddOp2(v, OP_Close, tab2, 0);
- sqlite3VdbeAddOp2(v, OP_Close, tab1, 0);
- break;
- }
- }
-
- /* Compute collating sequences used by
- ** temporary tables needed to implement the compound select.
- ** Attach the KeyInfo structure to all temporary tables.
- **
- ** This section is run by the right-most SELECT statement only.
- ** SELECT statements to the left always skip this part. The right-most
- ** SELECT might also skip this part if it has no ORDER BY clause and
- ** no temp tables are required.
- */
- if( p->selFlags & SF_UsesEphemeral ){
- int i; /* Loop counter */
- KeyInfo *pKeyInfo; /* Collating sequence for the result set */
- Select *pLoop; /* For looping through SELECT statements */
- CollSeq **apColl; /* For looping through pKeyInfo->aColl[] */
- int nCol; /* Number of columns in result set */
-
- assert( p->pRightmost==p );
- nCol = p->pEList->nExpr;
- pKeyInfo = sqlite3DbMallocZero(db,
- sizeof(*pKeyInfo)+nCol*(sizeof(CollSeq*) + 1));
- if( !pKeyInfo ){
- rc = SQLITE_NOMEM;
- goto multi_select_end;
- }
-
- pKeyInfo->enc = ENC(db);
- pKeyInfo->nField = (u16)nCol;
-
- for(i=0, apColl=pKeyInfo->aColl; i<nCol; i++, apColl++){
- *apColl = multiSelectCollSeq(pParse, p, i);
- if( 0==*apColl ){
- *apColl = db->pDfltColl;
- }
- }
-
- for(pLoop=p; pLoop; pLoop=pLoop->pPrior){
- for(i=0; i<2; i++){
- int addr = pLoop->addrOpenEphm[i];
- if( addr<0 ){
- /* If [0] is unused then [1] is also unused. So we can
- ** always safely abort as soon as the first unused slot is found */
- assert( pLoop->addrOpenEphm[1]<0 );
- break;
- }
- sqlite3VdbeChangeP2(v, addr, nCol);
- sqlite3VdbeChangeP4(v, addr, (char*)pKeyInfo, P4_KEYINFO);
- pLoop->addrOpenEphm[i] = -1;
- }
- }
- sqlite3DbFree(db, pKeyInfo);
- }
-
-multi_select_end:
- pDest->iMem = dest.iMem;
- pDest->nMem = dest.nMem;
- sqlite3SelectDelete(db, pDelete);
- return rc;
-}
-#endif /* SQLITE_OMIT_COMPOUND_SELECT */
-
-/*
-** Code an output subroutine for a coroutine implementation of a
-** SELECT statment.
-**
-** The data to be output is contained in pIn->iMem. There are
-** pIn->nMem columns to be output. pDest is where the output should
-** be sent.
-**
-** regReturn is the number of the register holding the subroutine
-** return address.
-**
-** If regPrev>0 then it is a the first register in a vector that
-** records the previous output. mem[regPrev] is a flag that is false
-** if there has been no previous output. If regPrev>0 then code is
-** generated to suppress duplicates. pKeyInfo is used for comparing
-** keys.
-**
-** If the LIMIT found in p->iLimit is reached, jump immediately to
-** iBreak.
-*/
-static int generateOutputSubroutine(
- Parse *pParse, /* Parsing context */
- Select *p, /* The SELECT statement */
- SelectDest *pIn, /* Coroutine supplying data */
- SelectDest *pDest, /* Where to send the data */
- int regReturn, /* The return address register */
- int regPrev, /* Previous result register. No uniqueness if 0 */
- KeyInfo *pKeyInfo, /* For comparing with previous entry */
- int p4type, /* The p4 type for pKeyInfo */
- int iBreak /* Jump here if we hit the LIMIT */
-){
- Vdbe *v = pParse->pVdbe;
- int iContinue;
- int addr;
-
- addr = sqlite3VdbeCurrentAddr(v);
- iContinue = sqlite3VdbeMakeLabel(v);
-
- /* Suppress duplicates for UNION, EXCEPT, and INTERSECT
- */
- if( regPrev ){
- int j1, j2;
- j1 = sqlite3VdbeAddOp1(v, OP_IfNot, regPrev);
- j2 = sqlite3VdbeAddOp4(v, OP_Compare, pIn->iMem, regPrev+1, pIn->nMem,
- (char*)pKeyInfo, p4type);
- sqlite3VdbeAddOp3(v, OP_Jump, j2+2, iContinue, j2+2);
- sqlite3VdbeJumpHere(v, j1);
- sqlite3ExprCodeCopy(pParse, pIn->iMem, regPrev+1, pIn->nMem);
- sqlite3VdbeAddOp2(v, OP_Integer, 1, regPrev);
- }
- if( pParse->db->mallocFailed ) return 0;
-
- /* Suppress the the first OFFSET entries if there is an OFFSET clause
- */
- codeOffset(v, p, iContinue);
-
- switch( pDest->eDest ){
- /* Store the result as data using a unique key.
- */
- case SRT_Table:
- case SRT_EphemTab: {
- int r1 = sqlite3GetTempReg(pParse);
- int r2 = sqlite3GetTempReg(pParse);
- testcase( pDest->eDest==SRT_Table );
- testcase( pDest->eDest==SRT_EphemTab );
- sqlite3VdbeAddOp3(v, OP_MakeRecord, pIn->iMem, pIn->nMem, r1);
- sqlite3VdbeAddOp2(v, OP_NewRowid, pDest->iParm, r2);
- sqlite3VdbeAddOp3(v, OP_Insert, pDest->iParm, r1, r2);
- sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
- sqlite3ReleaseTempReg(pParse, r2);
- sqlite3ReleaseTempReg(pParse, r1);
- break;
- }
-
-#ifndef SQLITE_OMIT_SUBQUERY
- /* If we are creating a set for an "expr IN (SELECT ...)" construct,
- ** then there should be a single item on the stack. Write this
- ** item into the set table with bogus data.
- */
- case SRT_Set: {
- int r1;
- assert( pIn->nMem==1 );
- p->affinity =
- sqlite3CompareAffinity(p->pEList->a[0].pExpr, pDest->affinity);
- r1 = sqlite3GetTempReg(pParse);
- sqlite3VdbeAddOp4(v, OP_MakeRecord, pIn->iMem, 1, r1, &p->affinity, 1);
- sqlite3ExprCacheAffinityChange(pParse, pIn->iMem, 1);
- sqlite3VdbeAddOp2(v, OP_IdxInsert, pDest->iParm, r1);
- sqlite3ReleaseTempReg(pParse, r1);
- break;
- }
-
-#if 0 /* Never occurs on an ORDER BY query */
- /* If any row exist in the result set, record that fact and abort.
- */
- case SRT_Exists: {
- sqlite3VdbeAddOp2(v, OP_Integer, 1, pDest->iParm);
- /* The LIMIT clause will terminate the loop for us */
- break;
- }
-#endif
-
- /* If this is a scalar select that is part of an expression, then
- ** store the results in the appropriate memory cell and break out
- ** of the scan loop.
- */
- case SRT_Mem: {
- assert( pIn->nMem==1 );
- sqlite3ExprCodeMove(pParse, pIn->iMem, pDest->iParm, 1);
- /* The LIMIT clause will jump out of the loop for us */
- break;
- }
-#endif /* #ifndef SQLITE_OMIT_SUBQUERY */
-
- /* The results are stored in a sequence of registers
- ** starting at pDest->iMem. Then the co-routine yields.
- */
- case SRT_Coroutine: {
- if( pDest->iMem==0 ){
- pDest->iMem = sqlite3GetTempRange(pParse, pIn->nMem);
- pDest->nMem = pIn->nMem;
- }
- sqlite3ExprCodeMove(pParse, pIn->iMem, pDest->iMem, pDest->nMem);
- sqlite3VdbeAddOp1(v, OP_Yield, pDest->iParm);
- break;
- }
-
- /* If none of the above, then the result destination must be
- ** SRT_Output. This routine is never called with any other
- ** destination other than the ones handled above or SRT_Output.
- **
- ** For SRT_Output, results are stored in a sequence of registers.
- ** Then the OP_ResultRow opcode is used to cause sqlite3_step() to
- ** return the next row of result.
- */
- default: {
- assert( pDest->eDest==SRT_Output );
- sqlite3VdbeAddOp2(v, OP_ResultRow, pIn->iMem, pIn->nMem);
- sqlite3ExprCacheAffinityChange(pParse, pIn->iMem, pIn->nMem);
- break;
- }
- }
-
- /* Jump to the end of the loop if the LIMIT is reached.
- */
- if( p->iLimit ){
- sqlite3VdbeAddOp2(v, OP_AddImm, p->iLimit, -1);
- sqlite3VdbeAddOp2(v, OP_IfZero, p->iLimit, iBreak);
- }
-
- /* Generate the subroutine return
- */
- sqlite3VdbeResolveLabel(v, iContinue);
- sqlite3VdbeAddOp1(v, OP_Return, regReturn);
-
- return addr;
-}
-
-/*
-** Alternative compound select code generator for cases when there
-** is an ORDER BY clause.
-**
-** We assume a query of the following form:
-**
-** <selectA> <operator> <selectB> ORDER BY <orderbylist>
-**
-** <operator> is one of UNION ALL, UNION, EXCEPT, or INTERSECT. The idea
-** is to code both <selectA> and <selectB> with the ORDER BY clause as
-** co-routines. Then run the co-routines in parallel and merge the results
-** into the output. In addition to the two coroutines (called selectA and
-** selectB) there are 7 subroutines:
-**
-** outA: Move the output of the selectA coroutine into the output
-** of the compound query.
-**
-** outB: Move the output of the selectB coroutine into the output
-** of the compound query. (Only generated for UNION and
-** UNION ALL. EXCEPT and INSERTSECT never output a row that
-** appears only in B.)
-**
-** AltB: Called when there is data from both coroutines and A<B.
-**
-** AeqB: Called when there is data from both coroutines and A==B.
-**
-** AgtB: Called when there is data from both coroutines and A>B.
-**
-** EofA: Called when data is exhausted from selectA.
-**
-** EofB: Called when data is exhausted from selectB.
-**
-** The implementation of the latter five subroutines depend on which
-** <operator> is used:
-**
-**
-** UNION ALL UNION EXCEPT INTERSECT
-** ------------- ----------------- -------------- -----------------
-** AltB: outA, nextA outA, nextA outA, nextA nextA
-**
-** AeqB: outA, nextA nextA nextA outA, nextA
-**
-** AgtB: outB, nextB outB, nextB nextB nextB
-**
-** EofA: outB, nextB outB, nextB halt halt
-**
-** EofB: outA, nextA outA, nextA outA, nextA halt
-**
-** In the AltB, AeqB, and AgtB subroutines, an EOF on A following nextA
-** causes an immediate jump to EofA and an EOF on B following nextB causes
-** an immediate jump to EofB. Within EofA and EofB, and EOF on entry or
-** following nextX causes a jump to the end of the select processing.
-**
-** Duplicate removal in the UNION, EXCEPT, and INTERSECT cases is handled
-** within the output subroutine. The regPrev register set holds the previously
-** output value. A comparison is made against this value and the output
-** is skipped if the next results would be the same as the previous.
-**
-** The implementation plan is to implement the two coroutines and seven
-** subroutines first, then put the control logic at the bottom. Like this:
-**
-** goto Init
-** coA: coroutine for left query (A)
-** coB: coroutine for right query (B)
-** outA: output one row of A
-** outB: output one row of B (UNION and UNION ALL only)
-** EofA: ...
-** EofB: ...
-** AltB: ...
-** AeqB: ...
-** AgtB: ...
-** Init: initialize coroutine registers
-** yield coA
-** if eof(A) goto EofA
-** yield coB
-** if eof(B) goto EofB
-** Cmpr: Compare A, B
-** Jump AltB, AeqB, AgtB
-** End: ...
-**
-** We call AltB, AeqB, AgtB, EofA, and EofB "subroutines" but they are not
-** actually called using Gosub and they do not Return. EofA and EofB loop
-** until all data is exhausted then jump to the "end" labe. AltB, AeqB,
-** and AgtB jump to either L2 or to one of EofA or EofB.
-*/
-#ifndef SQLITE_OMIT_COMPOUND_SELECT
-static int multiSelectOrderBy(
- Parse *pParse, /* Parsing context */
- Select *p, /* The right-most of SELECTs to be coded */
- SelectDest *pDest /* What to do with query results */
-){
- int i, j; /* Loop counters */
- Select *pPrior; /* Another SELECT immediately to our left */
- Vdbe *v; /* Generate code to this VDBE */
- SelectDest destA; /* Destination for coroutine A */
- SelectDest destB; /* Destination for coroutine B */
- int regAddrA; /* Address register for select-A coroutine */
- int regEofA; /* Flag to indicate when select-A is complete */
- int regAddrB; /* Address register for select-B coroutine */
- int regEofB; /* Flag to indicate when select-B is complete */
- int addrSelectA; /* Address of the select-A coroutine */
- int addrSelectB; /* Address of the select-B coroutine */
- int regOutA; /* Address register for the output-A subroutine */
- int regOutB; /* Address register for the output-B subroutine */
- int addrOutA; /* Address of the output-A subroutine */
- int addrOutB = 0; /* Address of the output-B subroutine */
- int addrEofA; /* Address of the select-A-exhausted subroutine */
- int addrEofB; /* Address of the select-B-exhausted subroutine */
- int addrAltB; /* Address of the A<B subroutine */
- int addrAeqB; /* Address of the A==B subroutine */
- int addrAgtB; /* Address of the A>B subroutine */
- int regLimitA; /* Limit register for select-A */
- int regLimitB; /* Limit register for select-A */
- int regPrev; /* A range of registers to hold previous output */
- int savedLimit; /* Saved value of p->iLimit */
- int savedOffset; /* Saved value of p->iOffset */
- int labelCmpr; /* Label for the start of the merge algorithm */
- int labelEnd; /* Label for the end of the overall SELECT stmt */
- int j1; /* Jump instructions that get retargetted */
- int op; /* One of TK_ALL, TK_UNION, TK_EXCEPT, TK_INTERSECT */
- KeyInfo *pKeyDup = 0; /* Comparison information for duplicate removal */
- KeyInfo *pKeyMerge; /* Comparison information for merging rows */
- sqlite3 *db; /* Database connection */
- ExprList *pOrderBy; /* The ORDER BY clause */
- int nOrderBy; /* Number of terms in the ORDER BY clause */
- int *aPermute; /* Mapping from ORDER BY terms to result set columns */
-
- assert( p->pOrderBy!=0 );
- assert( pKeyDup==0 ); /* "Managed" code needs this. Ticket #3382. */
- db = pParse->db;
- v = pParse->pVdbe;
- assert( v!=0 ); /* Already thrown the error if VDBE alloc failed */
- labelEnd = sqlite3VdbeMakeLabel(v);
- labelCmpr = sqlite3VdbeMakeLabel(v);
-
-
- /* Patch up the ORDER BY clause
- */
- op = p->op;
- pPrior = p->pPrior;
- assert( pPrior->pOrderBy==0 );
- pOrderBy = p->pOrderBy;
- assert( pOrderBy );
- nOrderBy = pOrderBy->nExpr;
-
- /* For operators other than UNION ALL we have to make sure that
- ** the ORDER BY clause covers every term of the result set. Add
- ** terms to the ORDER BY clause as necessary.
- */
- if( op!=TK_ALL ){
- for(i=1; db->mallocFailed==0 && i<=p->pEList->nExpr; i++){
- struct ExprList_item *pItem;
- for(j=0, pItem=pOrderBy->a; j<nOrderBy; j++, pItem++){
- assert( pItem->iCol>0 );
- if( pItem->iCol==i ) break;
- }
- if( j==nOrderBy ){
- Expr *pNew = sqlite3Expr(db, TK_INTEGER, 0);
- if( pNew==0 ) return SQLITE_NOMEM;
- pNew->flags |= EP_IntValue;
- pNew->u.iValue = i;
- pOrderBy = sqlite3ExprListAppend(pParse, pOrderBy, pNew);
- pOrderBy->a[nOrderBy++].iCol = (u16)i;
- }
- }
- }
-
- /* Compute the comparison permutation and keyinfo that is used with
- ** the permutation used to determine if the next
- ** row of results comes from selectA or selectB. Also add explicit
- ** collations to the ORDER BY clause terms so that when the subqueries
- ** to the right and the left are evaluated, they use the correct
- ** collation.
- */
- aPermute = sqlite3DbMallocRaw(db, sizeof(int)*nOrderBy);
- if( aPermute ){
- struct ExprList_item *pItem;
- for(i=0, pItem=pOrderBy->a; i<nOrderBy; i++, pItem++){
- assert( pItem->iCol>0 && pItem->iCol<=p->pEList->nExpr );
- aPermute[i] = pItem->iCol - 1;
- }
- pKeyMerge =
- sqlite3DbMallocRaw(db, sizeof(*pKeyMerge)+nOrderBy*(sizeof(CollSeq*)+1));
- if( pKeyMerge ){
- pKeyMerge->aSortOrder = (u8*)&pKeyMerge->aColl[nOrderBy];
- pKeyMerge->nField = (u16)nOrderBy;
- pKeyMerge->enc = ENC(db);
- for(i=0; i<nOrderBy; i++){
- CollSeq *pColl;
- Expr *pTerm = pOrderBy->a[i].pExpr;
- if( pTerm->flags & EP_ExpCollate ){
- pColl = pTerm->pColl;
- }else{
- pColl = multiSelectCollSeq(pParse, p, aPermute[i]);
- pTerm->flags |= EP_ExpCollate;
- pTerm->pColl = pColl;
- }
- pKeyMerge->aColl[i] = pColl;
- pKeyMerge->aSortOrder[i] = pOrderBy->a[i].sortOrder;
- }
- }
- }else{
- pKeyMerge = 0;
- }
-
- /* Reattach the ORDER BY clause to the query.
- */
- p->pOrderBy = pOrderBy;
- pPrior->pOrderBy = sqlite3ExprListDup(pParse->db, pOrderBy, 0);
-
- /* Allocate a range of temporary registers and the KeyInfo needed
- ** for the logic that removes duplicate result rows when the
- ** operator is UNION, EXCEPT, or INTERSECT (but not UNION ALL).
- */
- if( op==TK_ALL ){
- regPrev = 0;
- }else{
- int nExpr = p->pEList->nExpr;
- assert( nOrderBy>=nExpr || db->mallocFailed );
- regPrev = sqlite3GetTempRange(pParse, nExpr+1);
- sqlite3VdbeAddOp2(v, OP_Integer, 0, regPrev);
- pKeyDup = sqlite3DbMallocZero(db,
- sizeof(*pKeyDup) + nExpr*(sizeof(CollSeq*)+1) );
- if( pKeyDup ){
- pKeyDup->aSortOrder = (u8*)&pKeyDup->aColl[nExpr];
- pKeyDup->nField = (u16)nExpr;
- pKeyDup->enc = ENC(db);
- for(i=0; i<nExpr; i++){
- pKeyDup->aColl[i] = multiSelectCollSeq(pParse, p, i);
- pKeyDup->aSortOrder[i] = 0;
- }
- }
- }
-
- /* Separate the left and the right query from one another
- */
- p->pPrior = 0;
- pPrior->pRightmost = 0;
- sqlite3ResolveOrderGroupBy(pParse, p, p->pOrderBy, "ORDER");
- if( pPrior->pPrior==0 ){
- sqlite3ResolveOrderGroupBy(pParse, pPrior, pPrior->pOrderBy, "ORDER");
- }
-
- /* Compute the limit registers */
- computeLimitRegisters(pParse, p, labelEnd);
- if( p->iLimit && op==TK_ALL ){
- regLimitA = ++pParse->nMem;
- regLimitB = ++pParse->nMem;
- sqlite3VdbeAddOp2(v, OP_Copy, p->iOffset ? p->iOffset+1 : p->iLimit,
- regLimitA);
- sqlite3VdbeAddOp2(v, OP_Copy, regLimitA, regLimitB);
- }else{
- regLimitA = regLimitB = 0;
- }
- sqlite3ExprDelete(db, p->pLimit);
- p->pLimit = 0;
- sqlite3ExprDelete(db, p->pOffset);
- p->pOffset = 0;
-
- regAddrA = ++pParse->nMem;
- regEofA = ++pParse->nMem;
- regAddrB = ++pParse->nMem;
- regEofB = ++pParse->nMem;
- regOutA = ++pParse->nMem;
- regOutB = ++pParse->nMem;
- sqlite3SelectDestInit(&destA, SRT_Coroutine, regAddrA);
- sqlite3SelectDestInit(&destB, SRT_Coroutine, regAddrB);
-
- /* Jump past the various subroutines and coroutines to the main
- ** merge loop
- */
- j1 = sqlite3VdbeAddOp0(v, OP_Goto);
- addrSelectA = sqlite3VdbeCurrentAddr(v);
-
-
- /* Generate a coroutine to evaluate the SELECT statement to the
- ** left of the compound operator - the "A" select.
- */
- VdbeNoopComment((v, "Begin coroutine for left SELECT"));
- pPrior->iLimit = regLimitA;
- sqlite3Select(pParse, pPrior, &destA);
- sqlite3VdbeAddOp2(v, OP_Integer, 1, regEofA);
- sqlite3VdbeAddOp1(v, OP_Yield, regAddrA);
- VdbeNoopComment((v, "End coroutine for left SELECT"));
-
- /* Generate a coroutine to evaluate the SELECT statement on
- ** the right - the "B" select
- */
- addrSelectB = sqlite3VdbeCurrentAddr(v);
- VdbeNoopComment((v, "Begin coroutine for right SELECT"));
- savedLimit = p->iLimit;
- savedOffset = p->iOffset;
- p->iLimit = regLimitB;
- p->iOffset = 0;
- sqlite3Select(pParse, p, &destB);
- p->iLimit = savedLimit;
- p->iOffset = savedOffset;
- sqlite3VdbeAddOp2(v, OP_Integer, 1, regEofB);
- sqlite3VdbeAddOp1(v, OP_Yield, regAddrB);
- VdbeNoopComment((v, "End coroutine for right SELECT"));
-
- /* Generate a subroutine that outputs the current row of the A
- ** select as the next output row of the compound select.
- */
- VdbeNoopComment((v, "Output routine for A"));
- addrOutA = generateOutputSubroutine(pParse,
- p, &destA, pDest, regOutA,
- regPrev, pKeyDup, P4_KEYINFO_HANDOFF, labelEnd);
-
- /* Generate a subroutine that outputs the current row of the B
- ** select as the next output row of the compound select.
- */
- if( op==TK_ALL || op==TK_UNION ){
- VdbeNoopComment((v, "Output routine for B"));
- addrOutB = generateOutputSubroutine(pParse,
- p, &destB, pDest, regOutB,
- regPrev, pKeyDup, P4_KEYINFO_STATIC, labelEnd);
- }
-
- /* Generate a subroutine to run when the results from select A
- ** are exhausted and only data in select B remains.
- */
- VdbeNoopComment((v, "eof-A subroutine"));
- if( op==TK_EXCEPT || op==TK_INTERSECT ){
- addrEofA = sqlite3VdbeAddOp2(v, OP_Goto, 0, labelEnd);
- }else{
- addrEofA = sqlite3VdbeAddOp2(v, OP_If, regEofB, labelEnd);
- sqlite3VdbeAddOp2(v, OP_Gosub, regOutB, addrOutB);
- sqlite3VdbeAddOp1(v, OP_Yield, regAddrB);
- sqlite3VdbeAddOp2(v, OP_Goto, 0, addrEofA);
- }
-
- /* Generate a subroutine to run when the results from select B
- ** are exhausted and only data in select A remains.
- */
- if( op==TK_INTERSECT ){
- addrEofB = addrEofA;
- }else{
- VdbeNoopComment((v, "eof-B subroutine"));
- addrEofB = sqlite3VdbeAddOp2(v, OP_If, regEofA, labelEnd);
- sqlite3VdbeAddOp2(v, OP_Gosub, regOutA, addrOutA);
- sqlite3VdbeAddOp1(v, OP_Yield, regAddrA);
- sqlite3VdbeAddOp2(v, OP_Goto, 0, addrEofB);
- }
-
- /* Generate code to handle the case of A<B
- */
- VdbeNoopComment((v, "A-lt-B subroutine"));
- addrAltB = sqlite3VdbeAddOp2(v, OP_Gosub, regOutA, addrOutA);
- sqlite3VdbeAddOp1(v, OP_Yield, regAddrA);
- sqlite3VdbeAddOp2(v, OP_If, regEofA, addrEofA);
- sqlite3VdbeAddOp2(v, OP_Goto, 0, labelCmpr);
-
- /* Generate code to handle the case of A==B
- */
- if( op==TK_ALL ){
- addrAeqB = addrAltB;
- }else if( op==TK_INTERSECT ){
- addrAeqB = addrAltB;
- addrAltB++;
- }else{
- VdbeNoopComment((v, "A-eq-B subroutine"));
- addrAeqB =
- sqlite3VdbeAddOp1(v, OP_Yield, regAddrA);
- sqlite3VdbeAddOp2(v, OP_If, regEofA, addrEofA);
- sqlite3VdbeAddOp2(v, OP_Goto, 0, labelCmpr);
- }
-
- /* Generate code to handle the case of A>B
- */
- VdbeNoopComment((v, "A-gt-B subroutine"));
- addrAgtB = sqlite3VdbeCurrentAddr(v);
- if( op==TK_ALL || op==TK_UNION ){
- sqlite3VdbeAddOp2(v, OP_Gosub, regOutB, addrOutB);
- }
- sqlite3VdbeAddOp1(v, OP_Yield, regAddrB);
- sqlite3VdbeAddOp2(v, OP_If, regEofB, addrEofB);
- sqlite3VdbeAddOp2(v, OP_Goto, 0, labelCmpr);
-
- /* This code runs once to initialize everything.
- */
- sqlite3VdbeJumpHere(v, j1);
- sqlite3VdbeAddOp2(v, OP_Integer, 0, regEofA);
- sqlite3VdbeAddOp2(v, OP_Integer, 0, regEofB);
- sqlite3VdbeAddOp2(v, OP_Gosub, regAddrA, addrSelectA);
- sqlite3VdbeAddOp2(v, OP_Gosub, regAddrB, addrSelectB);
- sqlite3VdbeAddOp2(v, OP_If, regEofA, addrEofA);
- sqlite3VdbeAddOp2(v, OP_If, regEofB, addrEofB);
-
- /* Implement the main merge loop
- */
- sqlite3VdbeResolveLabel(v, labelCmpr);
- sqlite3VdbeAddOp4(v, OP_Permutation, 0, 0, 0, (char*)aPermute, P4_INTARRAY);
- sqlite3VdbeAddOp4(v, OP_Compare, destA.iMem, destB.iMem, nOrderBy,
- (char*)pKeyMerge, P4_KEYINFO_HANDOFF);
- sqlite3VdbeAddOp3(v, OP_Jump, addrAltB, addrAeqB, addrAgtB);
-
- /* Release temporary registers
- */
- if( regPrev ){
- sqlite3ReleaseTempRange(pParse, regPrev, nOrderBy+1);
- }
-
- /* Jump to the this point in order to terminate the query.
- */
- sqlite3VdbeResolveLabel(v, labelEnd);
-
- /* Set the number of output columns
- */
- if( pDest->eDest==SRT_Output ){
- Select *pFirst = pPrior;
- while( pFirst->pPrior ) pFirst = pFirst->pPrior;
- generateColumnNames(pParse, 0, pFirst->pEList);
- }
-
- /* Reassembly the compound query so that it will be freed correctly
- ** by the calling function */
- if( p->pPrior ){
- sqlite3SelectDelete(db, p->pPrior);
- }
- p->pPrior = pPrior;
-
- /*** TBD: Insert subroutine calls to close cursors on incomplete
- **** subqueries ****/
- return SQLITE_OK;
-}
-#endif
-
-#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
-/* Forward Declarations */
-static void substExprList(sqlite3*, ExprList*, int, ExprList*);
-static void substSelect(sqlite3*, Select *, int, ExprList *);
-
-/*
-** Scan through the expression pExpr. Replace every reference to
-** a column in table number iTable with a copy of the iColumn-th
-** entry in pEList. (But leave references to the ROWID column
-** unchanged.)
-**
-** This routine is part of the flattening procedure. A subquery
-** whose result set is defined by pEList appears as entry in the
-** FROM clause of a SELECT such that the VDBE cursor assigned to that
-** FORM clause entry is iTable. This routine make the necessary
-** changes to pExpr so that it refers directly to the source table
-** of the subquery rather the result set of the subquery.
-*/
-static Expr *substExpr(
- sqlite3 *db, /* Report malloc errors to this connection */
- Expr *pExpr, /* Expr in which substitution occurs */
- int iTable, /* Table to be substituted */
- ExprList *pEList /* Substitute expressions */
-){
- if( pExpr==0 ) return 0;
- if( pExpr->op==TK_COLUMN && pExpr->iTable==iTable ){
- if( pExpr->iColumn<0 ){
- pExpr->op = TK_NULL;
- }else{
- Expr *pNew;
- assert( pEList!=0 && pExpr->iColumn<pEList->nExpr );
- assert( pExpr->pLeft==0 && pExpr->pRight==0 );
- pNew = sqlite3ExprDup(db, pEList->a[pExpr->iColumn].pExpr, 0);
- if( pNew && pExpr->pColl ){
- pNew->pColl = pExpr->pColl;
- }
- sqlite3ExprDelete(db, pExpr);
- pExpr = pNew;
- }
- }else{
- pExpr->pLeft = substExpr(db, pExpr->pLeft, iTable, pEList);
- pExpr->pRight = substExpr(db, pExpr->pRight, iTable, pEList);
- if( ExprHasProperty(pExpr, EP_xIsSelect) ){
- substSelect(db, pExpr->x.pSelect, iTable, pEList);
- }else{
- substExprList(db, pExpr->x.pList, iTable, pEList);
- }
- }
- return pExpr;
-}
-static void substExprList(
- sqlite3 *db, /* Report malloc errors here */
- ExprList *pList, /* List to scan and in which to make substitutes */
- int iTable, /* Table to be substituted */
- ExprList *pEList /* Substitute values */
-){
- int i;
- if( pList==0 ) return;
- for(i=0; i<pList->nExpr; i++){
- pList->a[i].pExpr = substExpr(db, pList->a[i].pExpr, iTable, pEList);
- }
-}
-static void substSelect(
- sqlite3 *db, /* Report malloc errors here */
- Select *p, /* SELECT statement in which to make substitutions */
- int iTable, /* Table to be replaced */
- ExprList *pEList /* Substitute values */
-){
- SrcList *pSrc;
- struct SrcList_item *pItem;
- int i;
- if( !p ) return;
- substExprList(db, p->pEList, iTable, pEList);
- substExprList(db, p->pGroupBy, iTable, pEList);
- substExprList(db, p->pOrderBy, iTable, pEList);
- p->pHaving = substExpr(db, p->pHaving, iTable, pEList);
- p->pWhere = substExpr(db, p->pWhere, iTable, pEList);
- substSelect(db, p->pPrior, iTable, pEList);
- pSrc = p->pSrc;
- assert( pSrc ); /* Even for (SELECT 1) we have: pSrc!=0 but pSrc->nSrc==0 */
- if( ALWAYS(pSrc) ){
- for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){
- substSelect(db, pItem->pSelect, iTable, pEList);
- }
- }
-}
-#endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */
-
-#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.
-**
-** To understand the concept of flattening, consider the following
-** query:
-**
-** SELECT a FROM (SELECT x+y AS a FROM t1 WHERE z<100) WHERE a>5
-**
-** The default way of implementing this query is to execute the
-** subquery first and store the results in a temporary table, then
-** run the outer query on that temporary table. This requires two
-** passes over the data. Furthermore, because the temporary table
-** has no indices, the WHERE clause on the outer query cannot be
-** optimized.
-**
-** This routine attempts to rewrite queries such as the above into
-** a single flat select, like this:
-**
-** SELECT x+y AS a FROM t1 WHERE z<100 AND a>5
-**
-** The code generated for this simpification gives the same result
-** but only has to scan the data once. And because indices might
-** exist on the table t1, a complete scan of the data might be
-** avoided.
-**
-** Flattening is only attempted if all of the following are true:
-**
-** (1) The subquery and the outer query do not both use aggregates.
-**
-** (2) The subquery is not an aggregate or the outer query is not a join.
-**
-** (3) The subquery is not the right operand of a left outer join
-** (Originally ticket #306. Strenghtened by ticket #3300)
-**
-** (4) The subquery is not DISTINCT or the outer query is not a join.
-**
-** (5) The subquery is not DISTINCT or the outer query does not use
-** aggregates.
-**
-** (6) The subquery does not use aggregates or the outer query is not
-** DISTINCT.
-**
-** (7) The subquery has a FROM clause.
-**
-** (8) The subquery does not use LIMIT or the outer query is not a join.
-**
-** (9) The subquery does not use LIMIT or the outer query does not use
-** aggregates.
-**
-** (10) The subquery does not use aggregates or the outer query does not
-** use LIMIT.
-**
-** (11) The subquery and the outer query do not both have ORDER BY clauses.
-**
-** (12) Not implemented. Subsumed into restriction (3). Was previously
-** a separate restriction deriving from ticket #350.
-**
-** (13) The subquery and outer query do not both use LIMIT
-**
-** (14) The subquery does not use OFFSET
-**
-** (15) The outer query is not part of a compound select or the
-** subquery does not have both an ORDER BY and a LIMIT clause.
-** (See ticket #2339)
-**
-** (16) The outer query is not an aggregate or the subquery does
-** not contain ORDER BY. (Ticket #2942) This used to not matter
-** until we introduced the group_concat() function.
-**
-** (17) The sub-query is not a compound select, or it is a UNION ALL
-** compound clause made up entirely of non-aggregate queries, and
-** the parent query:
-**
-** * 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.
-**
-** 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.
-**
-** (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
-** columns of the sub-query.
-**
-** (19) The subquery does not use LIMIT or the outer query does not
-** have a WHERE clause.
-**
-** (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
-** have other optimizations in mind to deal with that case.
-**
-** In this routine, the "p" parameter is a pointer to the outer query.
-** The subquery is p->pSrc->a[iFrom]. isAgg is true if the outer query
-** uses aggregates and subqueryIsAgg is true if the subquery uses aggregates.
-**
-** If flattening is not attempted, this routine is a no-op and returns 0.
-** If flattening is attempted this routine returns 1.
-**
-** All of the expression analysis must occur on both the outer query and
-** the subquery before this routine runs.
-*/
-static int flattenSubquery(
- Parse *pParse, /* Parsing context */
- Select *p, /* The parent or outer SELECT statement */
- int iFrom, /* Index in p->pSrc->a[] of the inner subquery */
- int isAgg, /* True if outer SELECT uses aggregate functions */
- int subqueryIsAgg /* True if the subquery uses aggregate functions */
-){
- const char *zSavedAuthContext = pParse->zAuthContext;
- Select *pParent;
- Select *pSub; /* The inner query or "subquery" */
- Select *pSub1; /* Pointer to the rightmost select in sub-query */
- SrcList *pSrc; /* The FROM clause of the outer query */
- SrcList *pSubSrc; /* The FROM clause of the subquery */
- ExprList *pList; /* The result set of the outer query */
- int iParent; /* VDBE cursor number of the pSub result set temp table */
- int i; /* Loop counter */
- Expr *pWhere; /* The WHERE clause */
- struct SrcList_item *pSubitem; /* The subquery */
- sqlite3 *db = pParse->db;
-
- /* Check to see if flattening is permitted. Return 0 if not.
- */
- assert( p!=0 );
- assert( p->pPrior==0 ); /* Unable to flatten compound queries */
- pSrc = p->pSrc;
- assert( pSrc && iFrom>=0 && iFrom<pSrc->nSrc );
- pSubitem = &pSrc->a[iFrom];
- iParent = pSubitem->iCursor;
- pSub = pSubitem->pSelect;
- assert( pSub!=0 );
- if( isAgg && subqueryIsAgg ) return 0; /* Restriction (1) */
- if( subqueryIsAgg && pSrc->nSrc>1 ) return 0; /* Restriction (2) */
- pSubSrc = pSub->pSrc;
- assert( pSubSrc );
- /* Prior to version 3.1.2, when LIMIT and OFFSET had to be simple constants,
- ** not arbitrary expresssions, we allowed some combining of LIMIT and OFFSET
- ** because they could be computed at compile-time. But when LIMIT and OFFSET
- ** became arbitrary expressions, we were forced to add restrictions (13)
- ** and (14). */
- if( pSub->pLimit && p->pLimit ) return 0; /* Restriction (13) */
- if( pSub->pOffset ) return 0; /* Restriction (14) */
- if( p->pRightmost && pSub->pLimit && pSub->pOrderBy ){
- return 0; /* Restriction (15) */
- }
- if( pSubSrc->nSrc==0 ) return 0; /* Restriction (7) */
- if( ((pSub->selFlags & SF_Distinct)!=0 || pSub->pLimit)
- && (pSrc->nSrc>1 || isAgg) ){ /* Restrictions (4)(5)(8)(9) */
- return 0;
- }
- if( (p->selFlags & SF_Distinct)!=0 && subqueryIsAgg ){
- return 0; /* Restriction (6) */
- }
- if( p->pOrderBy && pSub->pOrderBy ){
- return 0; /* Restriction (11) */
- }
- if( isAgg && pSub->pOrderBy ) return 0; /* Restriction (16) */
- if( pSub->pLimit && p->pWhere ) return 0; /* Restriction (19) */
-
- /* OBSOLETE COMMENT 1:
- ** Restriction 3: If the subquery is a join, make sure the subquery is
- ** not used as the right operand of an outer join. Examples of why this
- ** is not allowed:
- **
- ** t1 LEFT OUTER JOIN (t2 JOIN t3)
- **
- ** If we flatten the above, we would get
- **
- ** (t1 LEFT OUTER JOIN t2) JOIN t3
- **
- ** which is not at all the same thing.
- **
- ** OBSOLETE COMMENT 2:
- ** Restriction 12: If the subquery is the right operand of a left outer
- ** join, make sure the subquery has no WHERE clause.
- ** An examples of why this is not allowed:
- **
- ** t1 LEFT OUTER JOIN (SELECT * FROM t2 WHERE t2.x>0)
- **
- ** If we flatten the above, we would get
- **
- ** (t1 LEFT OUTER JOIN t2) WHERE t2.x>0
- **
- ** But the t2.x>0 test will always fail on a NULL row of t2, which
- ** effectively converts the OUTER JOIN into an INNER JOIN.
- **
- ** THIS OVERRIDES OBSOLETE COMMENTS 1 AND 2 ABOVE:
- ** Ticket #3300 shows that flattening the right term of a LEFT JOIN
- ** is fraught with danger. Best to avoid the whole thing. If the
- ** subquery is the right term of a LEFT JOIN, then do not flatten.
- */
- if( (pSubitem->jointype & JT_OUTER)!=0 ){
- return 0;
- }
-
- /* Restriction 17: If the sub-query is a compound SELECT, then it must
- ** use only the UNION ALL operator. And none of the simple select queries
- ** that make up the compound SELECT are allowed to be aggregate or distinct
- ** queries.
- */
- if( pSub->pPrior ){
- if( pSub->pOrderBy ){
- return 0; /* Restriction 20 */
- }
- if( isAgg || (p->selFlags & SF_Distinct)!=0 || pSrc->nSrc!=1 ){
- return 0;
- }
- 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 );
- if( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))!=0
- || (pSub1->pPrior && pSub1->op!=TK_ALL)
- || NEVER(pSub1->pSrc==0) || pSub1->pSrc->nSrc!=1
- ){
- return 0;
- }
- }
-
- /* Restriction 18. */
- if( p->pOrderBy ){
- int ii;
- for(ii=0; ii<p->pOrderBy->nExpr; ii++){
- if( p->pOrderBy->a[ii].iCol==0 ) return 0;
- }
- }
- }
-
- /***** If we reach this point, flattening is permitted. *****/
-
- /* Authorize the subquery */
- pParse->zAuthContext = pSubitem->zName;
- sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0);
- pParse->zAuthContext = zSavedAuthContext;
-
- /* If the sub-query is a compound SELECT statement, then (by restrictions
- ** 17 and 18 above) it must be a UNION ALL and the parent query must
- ** be of the form:
- **
- ** SELECT <expr-list> FROM (<sub-query>) <where-clause>
- **
- ** followed by any ORDER BY, LIMIT and/or OFFSET clauses. This block
- ** creates N-1 copies of the parent query without any ORDER BY, LIMIT or
- ** OFFSET clauses and joins them to the left-hand-side of the original
- ** using UNION ALL operators. In this case N is the number of simple
- ** select statements in the compound sub-query.
- **
- ** Example:
- **
- ** SELECT a+1 FROM (
- ** SELECT x FROM tab
- ** UNION ALL
- ** SELECT y FROM tab
- ** UNION ALL
- ** SELECT abs(z*2) FROM tab2
- ** ) WHERE a!=5 ORDER BY 1
- **
- ** Transformed into:
- **
- ** SELECT x+1 FROM tab WHERE x+1!=5
- ** UNION ALL
- ** SELECT y+1 FROM tab WHERE y+1!=5
- ** UNION ALL
- ** SELECT abs(z*2)+1 FROM tab2 WHERE abs(z*2)+1!=5
- ** ORDER BY 1
- **
- ** We call this the "compound-subquery flattening".
- */
- for(pSub=pSub->pPrior; pSub; pSub=pSub->pPrior){
- Select *pNew;
- ExprList *pOrderBy = p->pOrderBy;
- Expr *pLimit = p->pLimit;
- Select *pPrior = p->pPrior;
- p->pOrderBy = 0;
- p->pSrc = 0;
- p->pPrior = 0;
- p->pLimit = 0;
- pNew = sqlite3SelectDup(db, p, 0);
- p->pLimit = pLimit;
- p->pOrderBy = pOrderBy;
- p->pSrc = pSrc;
- p->op = TK_ALL;
- p->pRightmost = 0;
- if( pNew==0 ){
- pNew = pPrior;
- }else{
- pNew->pPrior = pPrior;
- pNew->pRightmost = 0;
- }
- p->pPrior = pNew;
- if( db->mallocFailed ) return 1;
- }
-
- /* Begin flattening the iFrom-th entry of the FROM clause
- ** in the outer query.
- */
- pSub = pSub1 = pSubitem->pSelect;
-
- /* Delete the transient table structure associated with the
- ** subquery
- */
- sqlite3DbFree(db, pSubitem->zDatabase);
- sqlite3DbFree(db, pSubitem->zName);
- sqlite3DbFree(db, pSubitem->zAlias);
- pSubitem->zDatabase = 0;
- pSubitem->zName = 0;
- pSubitem->zAlias = 0;
- pSubitem->pSelect = 0;
-
- /* Defer deleting the Table object associated with the
- ** subquery until code generation is
- ** complete, since there may still exist Expr.pTab entries that
- ** refer to the subquery even after flattening. Ticket #3346.
- **
- ** pSubitem->pTab is always non-NULL by test restrictions and tests above.
- */
- if( ALWAYS(pSubitem->pTab!=0) ){
- Table *pTabToDel = pSubitem->pTab;
- if( pTabToDel->nRef==1 ){
- Parse *pToplevel = sqlite3ParseToplevel(pParse);
- pTabToDel->pNextZombie = pToplevel->pZombieTab;
- pToplevel->pZombieTab = pTabToDel;
- }else{
- pTabToDel->nRef--;
- }
- pSubitem->pTab = 0;
- }
-
- /* The following loop runs once for each term in a compound-subquery
- ** flattening (as described above). If we are doing a different kind
- ** of flattening - a flattening other than a compound-subquery flattening -
- ** then this loop only runs once.
- **
- ** This loop moves all of the FROM elements of the subquery into the
- ** the FROM clause of the outer query. Before doing this, remember
- ** the cursor number for the original outer query FROM element in
- ** iParent. The iParent cursor will never be used. Subsequent code
- ** will scan expressions looking for iParent references and replace
- ** those references with expressions that resolve to the subquery FROM
- ** elements we are now copying in.
- */
- for(pParent=p; pParent; pParent=pParent->pPrior, pSub=pSub->pPrior){
- int nSubSrc;
- u8 jointype = 0;
- pSubSrc = pSub->pSrc; /* FROM clause of subquery */
- nSubSrc = pSubSrc->nSrc; /* Number of terms in subquery FROM clause */
- pSrc = pParent->pSrc; /* FROM clause of the outer query */
-
- if( pSrc ){
- assert( pParent==p ); /* First time through the loop */
- jointype = pSubitem->jointype;
- }else{
- assert( pParent!=p ); /* 2nd and subsequent times through the loop */
- pSrc = pParent->pSrc = sqlite3SrcListAppend(db, 0, 0, 0);
- if( pSrc==0 ){
- assert( db->mallocFailed );
- break;
- }
- }
-
- /* The subquery uses a single slot of the FROM clause of the outer
- ** query. If the subquery has more than one element in its FROM clause,
- ** then expand the outer query to make space for it to hold all elements
- ** of the subquery.
- **
- ** Example:
- **
- ** SELECT * FROM tabA, (SELECT * FROM sub1, sub2), tabB;
- **
- ** The outer query has 3 slots in its FROM clause. One slot of the
- ** outer query (the middle slot) is used by the subquery. The next
- ** block of code will expand the out query to 4 slots. The middle
- ** slot is expanded to two slots in order to make space for the
- ** two elements in the FROM clause of the subquery.
- */
- if( nSubSrc>1 ){
- pParent->pSrc = pSrc = sqlite3SrcListEnlarge(db, pSrc, nSubSrc-1,iFrom+1);
- if( db->mallocFailed ){
- break;
- }
- }
-
- /* Transfer the FROM clause terms from the subquery into the
- ** outer query.
- */
- for(i=0; i<nSubSrc; i++){
- sqlite3IdListDelete(db, pSrc->a[i+iFrom].pUsing);
- pSrc->a[i+iFrom] = pSubSrc->a[i];
- memset(&pSubSrc->a[i], 0, sizeof(pSubSrc->a[i]));
- }
- pSrc->a[iFrom].jointype = jointype;
-
- /* Now begin substituting subquery result set expressions for
- ** references to the iParent in the outer query.
- **
- ** Example:
- **
- ** SELECT a+5, b*10 FROM (SELECT x*3 AS a, y+10 AS b FROM t1) WHERE a>b;
- ** \ \_____________ subquery __________/ /
- ** \_____________________ outer query ______________________________/
- **
- ** We look at every expression in the outer query and every place we see
- ** "a" we substitute "x*3" and every place we see "b" we substitute "y+10".
- */
- pList = pParent->pEList;
- for(i=0; i<pList->nExpr; i++){
- if( pList->a[i].zName==0 ){
- const char *zSpan = pList->a[i].zSpan;
- if( ALWAYS(zSpan) ){
- pList->a[i].zName = sqlite3DbStrDup(db, zSpan);
- }
- }
- }
- substExprList(db, pParent->pEList, iParent, pSub->pEList);
- if( isAgg ){
- substExprList(db, pParent->pGroupBy, iParent, pSub->pEList);
- pParent->pHaving = substExpr(db, pParent->pHaving, iParent, pSub->pEList);
- }
- if( pSub->pOrderBy ){
- assert( pParent->pOrderBy==0 );
- pParent->pOrderBy = pSub->pOrderBy;
- pSub->pOrderBy = 0;
- }else if( pParent->pOrderBy ){
- substExprList(db, pParent->pOrderBy, iParent, pSub->pEList);
- }
- if( pSub->pWhere ){
- pWhere = sqlite3ExprDup(db, pSub->pWhere, 0);
- }else{
- pWhere = 0;
- }
- if( subqueryIsAgg ){
- assert( pParent->pHaving==0 );
- pParent->pHaving = pParent->pWhere;
- pParent->pWhere = pWhere;
- pParent->pHaving = substExpr(db, pParent->pHaving, iParent, pSub->pEList);
- pParent->pHaving = sqlite3ExprAnd(db, pParent->pHaving,
- sqlite3ExprDup(db, pSub->pHaving, 0));
- assert( pParent->pGroupBy==0 );
- pParent->pGroupBy = sqlite3ExprListDup(db, pSub->pGroupBy, 0);
- }else{
- pParent->pWhere = substExpr(db, pParent->pWhere, iParent, pSub->pEList);
- pParent->pWhere = sqlite3ExprAnd(db, pParent->pWhere, pWhere);
- }
-
- /* The flattened query is distinct if either the inner or the
- ** outer query is distinct.
- */
- pParent->selFlags |= pSub->selFlags & SF_Distinct;
-
- /*
- ** SELECT ... FROM (SELECT ... LIMIT a OFFSET b) LIMIT x OFFSET y;
- **
- ** One is tempted to try to add a and b to combine the limits. But this
- ** does not work if either limit is negative.
- */
- if( pSub->pLimit ){
- pParent->pLimit = pSub->pLimit;
- pSub->pLimit = 0;
- }
- }
-
- /* Finially, delete what is left of the subquery and return
- ** success.
- */
- sqlite3SelectDelete(db, pSub1);
-
- return 1;
-}
-#endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */
-
-/*
-** Analyze the SELECT statement passed as an argument to see if it
-** is a min() or max() query. Return WHERE_ORDERBY_MIN or WHERE_ORDERBY_MAX if
-** it is, or 0 otherwise. At present, a query is considered to be
-** a min()/max() query if:
-**
-** 1. There is a single object in the FROM clause.
-**
-** 2. There is a single expression in the result set, and it is
-** either min(x) or max(x), where x is a column reference.
-*/
-static u8 minMaxQuery(Select *p){
- Expr *pExpr;
- ExprList *pEList = p->pEList;
-
- if( pEList->nExpr!=1 ) return WHERE_ORDERBY_NORMAL;
- pExpr = pEList->a[0].pExpr;
- if( pExpr->op!=TK_AGG_FUNCTION ) return 0;
- if( NEVER(ExprHasProperty(pExpr, EP_xIsSelect)) ) return 0;
- pEList = pExpr->x.pList;
- if( pEList==0 || pEList->nExpr!=1 ) return 0;
- if( pEList->a[0].pExpr->op!=TK_AGG_COLUMN ) return WHERE_ORDERBY_NORMAL;
- assert( !ExprHasProperty(pExpr, EP_IntValue) );
- if( sqlite3StrICmp(pExpr->u.zToken,"min")==0 ){
- return WHERE_ORDERBY_MIN;
- }else if( sqlite3StrICmp(pExpr->u.zToken,"max")==0 ){
- return WHERE_ORDERBY_MAX;
- }
- return WHERE_ORDERBY_NORMAL;
-}
-
-/*
-** The select statement passed as the first argument is an aggregate query.
-** The second argment is the associated aggregate-info object. This
-** function tests if the SELECT is of the form:
-**
-** SELECT count(*) FROM <tbl>
-**
-** where table is a database table, not a sub-select or view. If the query
-** does match this pattern, then a pointer to the Table object representing
-** <tbl> is returned. Otherwise, 0 is returned.
-*/
-static Table *isSimpleCount(Select *p, AggInfo *pAggInfo){
- Table *pTab;
- Expr *pExpr;
-
- assert( !p->pGroupBy );
-
- if( p->pWhere || p->pEList->nExpr!=1
- || p->pSrc->nSrc!=1 || p->pSrc->a[0].pSelect
- ){
- return 0;
- }
- pTab = p->pSrc->a[0].pTab;
- pExpr = p->pEList->a[0].pExpr;
- assert( pTab && !pTab->pSelect && pExpr );
-
- if( IsVirtual(pTab) ) return 0;
- if( pExpr->op!=TK_AGG_FUNCTION ) return 0;
- if( (pAggInfo->aFunc[0].pFunc->flags&SQLITE_FUNC_COUNT)==0 ) return 0;
- if( pExpr->flags&EP_Distinct ) return 0;
-
- return pTab;
-}
-
-/*
-** If the source-list item passed as an argument was augmented with an
-** INDEXED BY clause, then try to locate the specified index. If there
-** was such a clause and the named index cannot be found, return
-** SQLITE_ERROR and leave an error in pParse. Otherwise, populate
-** pFrom->pIndex and return SQLITE_OK.
-*/
-SQLITE_PRIVATE int sqlite3IndexedByLookup(Parse *pParse, struct SrcList_item *pFrom){
- if( pFrom->pTab && pFrom->zIndex ){
- Table *pTab = pFrom->pTab;
- char *zIndex = pFrom->zIndex;
- Index *pIdx;
- for(pIdx=pTab->pIndex;
- pIdx && sqlite3StrICmp(pIdx->zName, zIndex);
- pIdx=pIdx->pNext
- );
- if( !pIdx ){
- sqlite3ErrorMsg(pParse, "no such index: %s", zIndex, 0);
- return SQLITE_ERROR;
- }
- pFrom->pIndex = pIdx;
- }
- return SQLITE_OK;
-}
-
-/*
-** This routine is a Walker callback for "expanding" a SELECT statement.
-** "Expanding" means to do the following:
-**
-** (1) Make sure VDBE cursor numbers have been assigned to every
-** element of the FROM clause.
-**
-** (2) Fill in the pTabList->a[].pTab fields in the SrcList that
-** defines FROM clause. When views appear in the FROM clause,
-** fill pTabList->a[].pSelect with a copy of the SELECT statement
-** that implements the view. A copy is made of the view's SELECT
-** statement so that we can freely modify or delete that statement
-** without worrying about messing up the presistent representation
-** of the view.
-**
-** (3) Add terms to the WHERE clause to accomodate the NATURAL keyword
-** on joins and the ON and USING clause of joins.
-**
-** (4) Scan the list of columns in the result set (pEList) looking
-** for instances of the "*" operator or the TABLE.* operator.
-** If found, expand each "*" to be every column in every table
-** and TABLE.* to be every column in TABLE.
-**
-*/
-static int selectExpander(Walker *pWalker, Select *p){
- Parse *pParse = pWalker->pParse;
- int i, j, k;
- SrcList *pTabList;
- ExprList *pEList;
- struct SrcList_item *pFrom;
- sqlite3 *db = pParse->db;
-
- if( db->mallocFailed ){
- return WRC_Abort;
- }
- if( NEVER(p->pSrc==0) || (p->selFlags & SF_Expanded)!=0 ){
- return WRC_Prune;
- }
- p->selFlags |= SF_Expanded;
- pTabList = p->pSrc;
- pEList = p->pEList;
-
- /* Make sure cursor numbers have been assigned to all entries in
- ** the FROM clause of the SELECT statement.
- */
- sqlite3SrcListAssignCursors(pParse, pTabList);
-
- /* Look up every table named in the FROM clause of the select. If
- ** an entry of the FROM clause is a subquery instead of a table or view,
- ** then create a transient table structure to describe the subquery.
- */
- for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){
- Table *pTab;
- if( pFrom->pTab!=0 ){
- /* This statement has already been prepared. There is no need
- ** to go further. */
- assert( i==0 );
- return WRC_Prune;
- }
- if( pFrom->zName==0 ){
-#ifndef SQLITE_OMIT_SUBQUERY
- Select *pSel = pFrom->pSelect;
- /* A sub-query in the FROM clause of a SELECT */
- assert( pSel!=0 );
- assert( pFrom->pTab==0 );
- sqlite3WalkSelect(pWalker, pSel);
- pFrom->pTab = pTab = sqlite3DbMallocZero(db, sizeof(Table));
- if( pTab==0 ) return WRC_Abort;
- pTab->dbMem = db->lookaside.bEnabled ? db : 0;
- pTab->nRef = 1;
- pTab->zName = sqlite3MPrintf(db, "sqlite_subquery_%p_", (void*)pTab);
- while( pSel->pPrior ){ pSel = pSel->pPrior; }
- selectColumnsFromExprList(pParse, pSel->pEList, &pTab->nCol, &pTab->aCol);
- pTab->iPKey = -1;
- pTab->tabFlags |= TF_Ephemeral;
-#endif
- }else{
- /* An ordinary table or view name in the FROM clause */
- assert( pFrom->pTab==0 );
- pFrom->pTab = pTab =
- sqlite3LocateTable(pParse,0,pFrom->zName,pFrom->zDatabase);
- if( pTab==0 ) return WRC_Abort;
- pTab->nRef++;
-#if !defined(SQLITE_OMIT_VIEW) || !defined (SQLITE_OMIT_VIRTUALTABLE)
- if( pTab->pSelect || IsVirtual(pTab) ){
- /* We reach here if the named table is a really a view */
- if( sqlite3ViewGetColumnNames(pParse, pTab) ) return WRC_Abort;
- assert( pFrom->pSelect==0 );
- pFrom->pSelect = sqlite3SelectDup(db, pTab->pSelect, 0);
- sqlite3WalkSelect(pWalker, pFrom->pSelect);
- }
-#endif
- }
-
- /* Locate the index named by the INDEXED BY clause, if any. */
- if( sqlite3IndexedByLookup(pParse, pFrom) ){
- return WRC_Abort;
- }
- }
-
- /* Process NATURAL keywords, and ON and USING clauses of joins.
- */
- if( db->mallocFailed || sqliteProcessJoin(pParse, p) ){
- return WRC_Abort;
- }
-
- /* For every "*" that occurs in the column list, insert the names of
- ** all columns in all tables. And for every TABLE.* insert the names
- ** of all columns in TABLE. The parser inserted a special expression
- ** with the TK_ALL operator for each "*" that it found in the column list.
- ** The following code just has to locate the TK_ALL expressions and expand
- ** each one to the list of all columns in all tables.
- **
- ** The first loop just checks to see if there are any "*" operators
- ** that need expanding.
- */
- for(k=0; k<pEList->nExpr; k++){
- Expr *pE = pEList->a[k].pExpr;
- if( pE->op==TK_ALL ) break;
- assert( pE->op!=TK_DOT || pE->pRight!=0 );
- assert( pE->op!=TK_DOT || (pE->pLeft!=0 && pE->pLeft->op==TK_ID) );
- if( pE->op==TK_DOT && pE->pRight->op==TK_ALL ) break;
- }
- if( k<pEList->nExpr ){
- /*
- ** If we get here it means the result set contains one or more "*"
- ** operators that need to be expanded. Loop through each expression
- ** in the result set and expand them one by one.
- */
- struct ExprList_item *a = pEList->a;
- ExprList *pNew = 0;
- int flags = pParse->db->flags;
- int longNames = (flags & SQLITE_FullColNames)!=0
- && (flags & SQLITE_ShortColNames)==0;
-
- for(k=0; k<pEList->nExpr; k++){
- Expr *pE = a[k].pExpr;
- assert( pE->op!=TK_DOT || pE->pRight!=0 );
- if( pE->op!=TK_ALL && (pE->op!=TK_DOT || pE->pRight->op!=TK_ALL) ){
- /* This particular expression does not need to be expanded.
- */
- pNew = sqlite3ExprListAppend(pParse, pNew, a[k].pExpr);
- if( pNew ){
- pNew->a[pNew->nExpr-1].zName = a[k].zName;
- pNew->a[pNew->nExpr-1].zSpan = a[k].zSpan;
- a[k].zName = 0;
- a[k].zSpan = 0;
- }
- a[k].pExpr = 0;
- }else{
- /* This expression is a "*" or a "TABLE.*" and needs to be
- ** expanded. */
- int tableSeen = 0; /* Set to 1 when TABLE matches */
- char *zTName; /* text of name of TABLE */
- if( pE->op==TK_DOT ){
- assert( pE->pLeft!=0 );
- assert( !ExprHasProperty(pE->pLeft, EP_IntValue) );
- zTName = pE->pLeft->u.zToken;
- }else{
- zTName = 0;
- }
- for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){
- Table *pTab = pFrom->pTab;
- char *zTabName = pFrom->zAlias;
- if( zTabName==0 ){
- zTabName = pTab->zName;
- }
- if( db->mallocFailed ) break;
- if( zTName && sqlite3StrICmp(zTName, zTabName)!=0 ){
- continue;
- }
- tableSeen = 1;
- for(j=0; j<pTab->nCol; j++){
- Expr *pExpr, *pRight;
- char *zName = pTab->aCol[j].zName;
- char *zColname; /* The computed column name */
- char *zToFree; /* Malloced string that needs to be freed */
- Token sColname; /* Computed column name as a token */
-
- /* If a column is marked as 'hidden' (currently only possible
- ** for virtual tables), do not include it in the expanded
- ** result-set list.
- */
- if( IsHiddenColumn(&pTab->aCol[j]) ){
- assert(IsVirtual(pTab));
- continue;
- }
-
- if( i>0 && zTName==0 ){
- struct SrcList_item *pLeft = &pTabList->a[i-1];
- if( (pLeft[1].jointype & JT_NATURAL)!=0 &&
- columnIndex(pLeft->pTab, zName)>=0 ){
- /* In a NATURAL join, omit the join columns from the
- ** table on the right */
- continue;
- }
- if( sqlite3IdListIndex(pLeft[1].pUsing, zName)>=0 ){
- /* In a join with a USING clause, omit columns in the
- ** using clause from the table on the right. */
- continue;
- }
- }
- pRight = sqlite3Expr(db, TK_ID, zName);
- zColname = zName;
- zToFree = 0;
- if( longNames || pTabList->nSrc>1 ){
- Expr *pLeft;
- pLeft = sqlite3Expr(db, TK_ID, zTabName);
- pExpr = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight, 0);
- if( longNames ){
- zColname = sqlite3MPrintf(db, "%s.%s", zTabName, zName);
- zToFree = zColname;
- }
- }else{
- pExpr = pRight;
- }
- pNew = sqlite3ExprListAppend(pParse, pNew, pExpr);
- sColname.z = zColname;
- sColname.n = sqlite3Strlen30(zColname);
- sqlite3ExprListSetName(pParse, pNew, &sColname, 0);
- sqlite3DbFree(db, zToFree);
- }
- }
- if( !tableSeen ){
- if( zTName ){
- sqlite3ErrorMsg(pParse, "no such table: %s", zTName);
- }else{
- sqlite3ErrorMsg(pParse, "no tables specified");
- }
- }
- }
- }
- sqlite3ExprListDelete(db, pEList);
- p->pEList = pNew;
- }
-#if SQLITE_MAX_COLUMN
- if( p->pEList && p->pEList->nExpr>db->aLimit[SQLITE_LIMIT_COLUMN] ){
- sqlite3ErrorMsg(pParse, "too many columns in result set");
- }
-#endif
- return WRC_Continue;
-}
-
-/*
-** No-op routine for the parse-tree walker.
-**
-** When this routine is the Walker.xExprCallback then expression trees
-** are walked without any actions being taken at each node. Presumably,
-** when this routine is used for Walker.xExprCallback then
-** Walker.xSelectCallback is set to do something useful for every
-** subquery in the parser tree.
-*/
-static int exprWalkNoop(Walker *NotUsed, Expr *NotUsed2){
- UNUSED_PARAMETER2(NotUsed, NotUsed2);
- return WRC_Continue;
-}
-
-/*
-** This routine "expands" a SELECT statement and all of its subqueries.
-** For additional information on what it means to "expand" a SELECT
-** statement, see the comment on the selectExpand worker callback above.
-**
-** Expanding a SELECT statement is the first step in processing a
-** SELECT statement. The SELECT statement must be expanded before
-** name resolution is performed.
-**
-** If anything goes wrong, an error message is written into pParse.
-** The calling function can detect the problem by looking at pParse->nErr
-** and/or pParse->db->mallocFailed.
-*/
-static void sqlite3SelectExpand(Parse *pParse, Select *pSelect){
- Walker w;
- w.xSelectCallback = selectExpander;
- w.xExprCallback = exprWalkNoop;
- w.pParse = pParse;
- sqlite3WalkSelect(&w, pSelect);
-}
-
-
-#ifndef SQLITE_OMIT_SUBQUERY
-/*
-** This is a Walker.xSelectCallback callback for the sqlite3SelectTypeInfo()
-** interface.
-**
-** For each FROM-clause subquery, add Column.zType and Column.zColl
-** information to the Table structure that represents the result set
-** of that subquery.
-**
-** The Table structure that represents the result set was constructed
-** by selectExpander() but the type and collation information was omitted
-** at that point because identifiers had not yet been resolved. This
-** routine is called after identifier resolution.
-*/
-static int selectAddSubqueryTypeInfo(Walker *pWalker, Select *p){
- Parse *pParse;
- int i;
- SrcList *pTabList;
- struct SrcList_item *pFrom;
-
- assert( p->selFlags & SF_Resolved );
- assert( (p->selFlags & SF_HasTypeInfo)==0 );
- p->selFlags |= SF_HasTypeInfo;
- pParse = pWalker->pParse;
- pTabList = p->pSrc;
- for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){
- Table *pTab = pFrom->pTab;
- if( ALWAYS(pTab!=0) && (pTab->tabFlags & TF_Ephemeral)!=0 ){
- /* A sub-query in the FROM clause of a SELECT */
- Select *pSel = pFrom->pSelect;
- assert( pSel );
- while( pSel->pPrior ) pSel = pSel->pPrior;
- selectAddColumnTypeAndCollation(pParse, pTab->nCol, pTab->aCol, pSel);
- }
- }
- return WRC_Continue;
-}
-#endif
-
-
-/*
-** This routine adds datatype and collating sequence information to
-** the Table structures of all FROM-clause subqueries in a
-** SELECT statement.
-**
-** Use this routine after name resolution.
-*/
-static void sqlite3SelectAddTypeInfo(Parse *pParse, Select *pSelect){
-#ifndef SQLITE_OMIT_SUBQUERY
- Walker w;
- w.xSelectCallback = selectAddSubqueryTypeInfo;
- w.xExprCallback = exprWalkNoop;
- w.pParse = pParse;
- sqlite3WalkSelect(&w, pSelect);
-#endif
-}
-
-
-/*
-** This routine sets of a SELECT statement for processing. The
-** following is accomplished:
-**
-** * VDBE Cursor numbers are assigned to all FROM-clause terms.
-** * Ephemeral Table objects are created for all FROM-clause subqueries.
-** * ON and USING clauses are shifted into WHERE statements
-** * Wildcards "*" and "TABLE.*" in result sets are expanded.
-** * Identifiers in expression are matched to tables.
-**
-** This routine acts recursively on all subqueries within the SELECT.
-*/
-SQLITE_PRIVATE void sqlite3SelectPrep(
- Parse *pParse, /* The parser context */
- Select *p, /* The SELECT statement being coded. */
- NameContext *pOuterNC /* Name context for container */
-){
- sqlite3 *db;
- if( NEVER(p==0) ) return;
- db = pParse->db;
- if( p->selFlags & SF_HasTypeInfo ) return;
- sqlite3SelectExpand(pParse, p);
- if( pParse->nErr || db->mallocFailed ) return;
- sqlite3ResolveSelectNames(pParse, p, pOuterNC);
- if( pParse->nErr || db->mallocFailed ) return;
- sqlite3SelectAddTypeInfo(pParse, p);
-}
-
-/*
-** Reset the aggregate accumulator.
-**
-** The aggregate accumulator is a set of memory cells that hold
-** intermediate results while calculating an aggregate. This
-** routine simply stores NULLs in all of those memory cells.
-*/
-static void resetAccumulator(Parse *pParse, AggInfo *pAggInfo){
- Vdbe *v = pParse->pVdbe;
- int i;
- struct AggInfo_func *pFunc;
- if( pAggInfo->nFunc+pAggInfo->nColumn==0 ){
- return;
- }
- for(i=0; i<pAggInfo->nColumn; i++){
- sqlite3VdbeAddOp2(v, OP_Null, 0, pAggInfo->aCol[i].iMem);
- }
- for(pFunc=pAggInfo->aFunc, i=0; i<pAggInfo->nFunc; i++, pFunc++){
- sqlite3VdbeAddOp2(v, OP_Null, 0, pFunc->iMem);
- if( pFunc->iDistinct>=0 ){
- Expr *pE = pFunc->pExpr;
- assert( !ExprHasProperty(pE, EP_xIsSelect) );
- if( pE->x.pList==0 || pE->x.pList->nExpr!=1 ){
- sqlite3ErrorMsg(pParse, "DISTINCT aggregates must have exactly one "
- "argument");
- pFunc->iDistinct = -1;
- }else{
- KeyInfo *pKeyInfo = keyInfoFromExprList(pParse, pE->x.pList);
- sqlite3VdbeAddOp4(v, OP_OpenEphemeral, pFunc->iDistinct, 0, 0,
- (char*)pKeyInfo, P4_KEYINFO_HANDOFF);
- }
- }
- }
-}
-
-/*
-** Invoke the OP_AggFinalize opcode for every aggregate function
-** in the AggInfo structure.
-*/
-static void finalizeAggFunctions(Parse *pParse, AggInfo *pAggInfo){
- Vdbe *v = pParse->pVdbe;
- int i;
- struct AggInfo_func *pF;
- for(i=0, pF=pAggInfo->aFunc; i<pAggInfo->nFunc; i++, pF++){
- ExprList *pList = pF->pExpr->x.pList;
- assert( !ExprHasProperty(pF->pExpr, EP_xIsSelect) );
- sqlite3VdbeAddOp4(v, OP_AggFinal, pF->iMem, pList ? pList->nExpr : 0, 0,
- (void*)pF->pFunc, P4_FUNCDEF);
- }
-}
-
-/*
-** Update the accumulator memory cells for an aggregate based on
-** the current cursor position.
-*/
-static void updateAccumulator(Parse *pParse, AggInfo *pAggInfo){
- Vdbe *v = pParse->pVdbe;
- int i;
- struct AggInfo_func *pF;
- struct AggInfo_col *pC;
-
- pAggInfo->directMode = 1;
- sqlite3ExprCacheClear(pParse);
- for(i=0, pF=pAggInfo->aFunc; i<pAggInfo->nFunc; i++, pF++){
- int nArg;
- int addrNext = 0;
- int regAgg;
- ExprList *pList = pF->pExpr->x.pList;
- assert( !ExprHasProperty(pF->pExpr, EP_xIsSelect) );
- if( pList ){
- nArg = pList->nExpr;
- regAgg = sqlite3GetTempRange(pParse, nArg);
- sqlite3ExprCodeExprList(pParse, pList, regAgg, 0);
- }else{
- nArg = 0;
- regAgg = 0;
- }
- if( pF->iDistinct>=0 ){
- addrNext = sqlite3VdbeMakeLabel(v);
- assert( nArg==1 );
- codeDistinct(pParse, pF->iDistinct, addrNext, 1, regAgg);
- }
- if( pF->pFunc->flags & SQLITE_FUNC_NEEDCOLL ){
- CollSeq *pColl = 0;
- struct ExprList_item *pItem;
- int j;
- assert( pList!=0 ); /* pList!=0 if pF->pFunc has NEEDCOLL */
- for(j=0, pItem=pList->a; !pColl && j<nArg; j++, pItem++){
- pColl = sqlite3ExprCollSeq(pParse, pItem->pExpr);
- }
- if( !pColl ){
- pColl = pParse->db->pDfltColl;
- }
- sqlite3VdbeAddOp4(v, OP_CollSeq, 0, 0, 0, (char *)pColl, P4_COLLSEQ);
- }
- sqlite3VdbeAddOp4(v, OP_AggStep, 0, regAgg, pF->iMem,
- (void*)pF->pFunc, P4_FUNCDEF);
- sqlite3VdbeChangeP5(v, (u8)nArg);
- sqlite3ReleaseTempRange(pParse, regAgg, nArg);
- sqlite3ExprCacheAffinityChange(pParse, regAgg, nArg);
- if( addrNext ){
- sqlite3VdbeResolveLabel(v, addrNext);
- sqlite3ExprCacheClear(pParse);
- }
- }
- for(i=0, pC=pAggInfo->aCol; i<pAggInfo->nAccumulator; i++, pC++){
- sqlite3ExprCode(pParse, pC->pExpr, pC->iMem);
- }
- pAggInfo->directMode = 0;
- sqlite3ExprCacheClear(pParse);
-}
-
-/*
-** Generate code for the SELECT statement given in the p argument.
-**
-** The results are distributed in various ways depending on the
-** contents of the SelectDest structure pointed to by argument pDest
-** as follows:
-**
-** pDest->eDest Result
-** ------------ -------------------------------------------
-** SRT_Output Generate a row of output (using the OP_ResultRow
-** opcode) for each row in the result set.
-**
-** SRT_Mem Only valid if the result is a single column.
-** Store the first column of the first result row
-** in register pDest->iParm then abandon the rest
-** of the query. This destination implies "LIMIT 1".
-**
-** SRT_Set The result must be a single column. Store each
-** row of result as the key in table pDest->iParm.
-** Apply the affinity pDest->affinity before storing
-** results. Used to implement "IN (SELECT ...)".
-**
-** SRT_Union Store results as a key in a temporary table pDest->iParm.
-**
-** SRT_Except Remove results from the temporary table pDest->iParm.
-**
-** SRT_Table Store results in temporary table pDest->iParm.
-** This is like SRT_EphemTab except that the table
-** is assumed to already be open.
-**
-** SRT_EphemTab Create an temporary table pDest->iParm and store
-** the result there. The cursor is left open after
-** returning. This is like SRT_Table except that
-** this destination uses OP_OpenEphemeral to create
-** the table first.
-**
-** SRT_Coroutine Generate a co-routine that returns a new row of
-** results each time it is invoked. The entry point
-** of the co-routine is stored in register pDest->iParm.
-**
-** SRT_Exists Store a 1 in memory cell pDest->iParm if the result
-** set is not empty.
-**
-** SRT_Discard Throw the results away. This is used by SELECT
-** statements within triggers whose only purpose is
-** the side-effects of functions.
-**
-** This routine returns the number of errors. If any errors are
-** encountered, then an appropriate error message is left in
-** pParse->zErrMsg.
-**
-** This routine does NOT free the Select structure passed in. The
-** calling function needs to do that.
-*/
-SQLITE_PRIVATE int sqlite3Select(
- Parse *pParse, /* The parser context */
- Select *p, /* The SELECT statement being coded. */
- SelectDest *pDest /* What to do with the query results */
-){
- int i, j; /* Loop counters */
- WhereInfo *pWInfo; /* Return from sqlite3WhereBegin() */
- Vdbe *v; /* The virtual machine under construction */
- int isAgg; /* True for select lists like "count(*)" */
- ExprList *pEList; /* List of columns to extract. */
- SrcList *pTabList; /* List of tables to select from */
- Expr *pWhere; /* The WHERE clause. May be NULL */
- ExprList *pOrderBy; /* The ORDER BY clause. May be NULL */
- ExprList *pGroupBy; /* The GROUP BY clause. May be NULL */
- Expr *pHaving; /* The HAVING clause. May be NULL */
- int isDistinct; /* True if the DISTINCT keyword is present */
- int distinct; /* Table to use for the distinct set */
- int rc = 1; /* Value to return from this function */
- int addrSortIndex; /* Address of an OP_OpenEphemeral instruction */
- AggInfo sAggInfo; /* Information used by aggregate queries */
- int iEnd; /* Address of the end of the query */
- sqlite3 *db; /* The database connection */
-
- db = pParse->db;
- if( p==0 || db->mallocFailed || pParse->nErr ){
- return 1;
- }
- if( sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0) ) return 1;
- memset(&sAggInfo, 0, sizeof(sAggInfo));
-
- if( IgnorableOrderby(pDest) ){
- assert(pDest->eDest==SRT_Exists || pDest->eDest==SRT_Union ||
- pDest->eDest==SRT_Except || pDest->eDest==SRT_Discard);
- /* If ORDER BY makes no difference in the output then neither does
- ** DISTINCT so it can be removed too. */
- sqlite3ExprListDelete(db, p->pOrderBy);
- p->pOrderBy = 0;
- p->selFlags &= ~SF_Distinct;
- }
- sqlite3SelectPrep(pParse, p, 0);
- pOrderBy = p->pOrderBy;
- pTabList = p->pSrc;
- pEList = p->pEList;
- if( pParse->nErr || db->mallocFailed ){
- goto select_end;
- }
- isAgg = (p->selFlags & SF_Aggregate)!=0;
- assert( pEList!=0 );
-
- /* Begin generating code.
- */
- v = sqlite3GetVdbe(pParse);
- if( v==0 ) goto select_end;
-
- /* Generate code for all sub-queries in the FROM clause
- */
-#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
- for(i=0; !p->pPrior && i<pTabList->nSrc; i++){
- struct SrcList_item *pItem = &pTabList->a[i];
- SelectDest dest;
- Select *pSub = pItem->pSelect;
- int isAggSub;
-
- if( pSub==0 || pItem->isPopulated ) continue;
-
- /* Increment Parse.nHeight by the height of the largest expression
- ** tree refered to by this, the parent select. The child select
- ** may contain expression trees of at most
- ** (SQLITE_MAX_EXPR_DEPTH-Parse.nHeight) height. This is a bit
- ** more conservative than necessary, but much easier than enforcing
- ** an exact limit.
- */
- pParse->nHeight += sqlite3SelectExprHeight(p);
-
- /* Check to see if the subquery can be absorbed into the parent. */
- isAggSub = (pSub->selFlags & SF_Aggregate)!=0;
- if( flattenSubquery(pParse, p, i, isAgg, isAggSub) ){
- if( isAggSub ){
- isAgg = 1;
- p->selFlags |= SF_Aggregate;
- }
- i = -1;
- }else{
- sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor);
- assert( pItem->isPopulated==0 );
- sqlite3Select(pParse, pSub, &dest);
- pItem->isPopulated = 1;
- }
- if( /*pParse->nErr ||*/ db->mallocFailed ){
- goto select_end;
- }
- pParse->nHeight -= sqlite3SelectExprHeight(p);
- pTabList = p->pSrc;
- if( !IgnorableOrderby(pDest) ){
- pOrderBy = p->pOrderBy;
- }
- }
- pEList = p->pEList;
-#endif
- pWhere = p->pWhere;
- pGroupBy = p->pGroupBy;
- pHaving = p->pHaving;
- isDistinct = (p->selFlags & SF_Distinct)!=0;
-
-#ifndef SQLITE_OMIT_COMPOUND_SELECT
- /* If there is are a sequence of queries, do the earlier ones first.
- */
- if( p->pPrior ){
- if( p->pRightmost==0 ){
- Select *pLoop, *pRight = 0;
- int cnt = 0;
- int mxSelect;
- for(pLoop=p; pLoop; pLoop=pLoop->pPrior, cnt++){
- pLoop->pRightmost = p;
- pLoop->pNext = pRight;
- pRight = pLoop;
- }
- mxSelect = db->aLimit[SQLITE_LIMIT_COMPOUND_SELECT];
- if( mxSelect && cnt>mxSelect ){
- sqlite3ErrorMsg(pParse, "too many terms in compound SELECT");
- return 1;
- }
- }
- return multiSelect(pParse, p, pDest);
- }
-#endif
-
- /* If writing to memory or generating a set
- ** only a single column may be output.
- */
-#ifndef SQLITE_OMIT_SUBQUERY
- if( checkForMultiColumnSelectError(pParse, pDest, pEList->nExpr) ){
- goto select_end;
- }
-#endif
-
- /* If possible, rewrite the query to use GROUP BY instead of DISTINCT.
- ** GROUP BY might use an index, DISTINCT never does.
- */
- assert( p->pGroupBy==0 || (p->selFlags & SF_Aggregate)!=0 );
- if( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct ){
- p->pGroupBy = sqlite3ExprListDup(db, p->pEList, 0);
- pGroupBy = p->pGroupBy;
- p->selFlags &= ~SF_Distinct;
- isDistinct = 0;
- }
-
- /* If there is an ORDER BY clause, then this sorting
- ** index might end up being unused if the data can be
- ** extracted in pre-sorted order. If that is the case, then the
- ** OP_OpenEphemeral instruction will be changed to an OP_Noop once
- ** we figure out that the sorting index is not needed. The addrSortIndex
- ** variable is used to facilitate that change.
- */
- if( pOrderBy ){
- KeyInfo *pKeyInfo;
- pKeyInfo = keyInfoFromExprList(pParse, pOrderBy);
- pOrderBy->iECursor = pParse->nTab++;
- p->addrOpenEphm[2] = addrSortIndex =
- sqlite3VdbeAddOp4(v, OP_OpenEphemeral,
- pOrderBy->iECursor, pOrderBy->nExpr+2, 0,
- (char*)pKeyInfo, P4_KEYINFO_HANDOFF);
- }else{
- addrSortIndex = -1;
- }
-
- /* If the output is destined for a temporary table, open that table.
- */
- if( pDest->eDest==SRT_EphemTab ){
- sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pDest->iParm, pEList->nExpr);
- }
-
- /* Set the limiter.
- */
- iEnd = sqlite3VdbeMakeLabel(v);
- computeLimitRegisters(pParse, p, iEnd);
-
- /* Open a virtual index to use for the distinct set.
- */
- if( isDistinct ){
- KeyInfo *pKeyInfo;
- assert( isAgg || pGroupBy );
- distinct = pParse->nTab++;
- pKeyInfo = keyInfoFromExprList(pParse, p->pEList);
- sqlite3VdbeAddOp4(v, OP_OpenEphemeral, distinct, 0, 0,
- (char*)pKeyInfo, P4_KEYINFO_HANDOFF);
- }else{
- distinct = -1;
- }
-
- /* Aggregate and non-aggregate queries are handled differently */
- if( !isAgg && pGroupBy==0 ){
- /* This case is for non-aggregate queries
- ** Begin the database scan
- */
- pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, &pOrderBy, 0);
- if( pWInfo==0 ) goto select_end;
-
- /* If sorting index that was created by a prior OP_OpenEphemeral
- ** instruction ended up not being needed, then change the OP_OpenEphemeral
- ** into an OP_Noop.
- */
- if( addrSortIndex>=0 && pOrderBy==0 ){
- sqlite3VdbeChangeToNoop(v, addrSortIndex, 1);
- p->addrOpenEphm[2] = -1;
- }
-
- /* Use the standard inner loop
- */
- assert(!isDistinct);
- selectInnerLoop(pParse, p, pEList, 0, 0, pOrderBy, -1, pDest,
- pWInfo->iContinue, pWInfo->iBreak);
-
- /* End the database scan loop.
- */
- sqlite3WhereEnd(pWInfo);
- }else{
- /* This is the processing for aggregate queries */
- NameContext sNC; /* Name context for processing aggregate information */
- int iAMem; /* First Mem address for storing current GROUP BY */
- int iBMem; /* First Mem address for previous GROUP BY */
- int iUseFlag; /* Mem address holding flag indicating that at least
- ** one row of the input to the aggregator has been
- ** processed */
- int iAbortFlag; /* Mem address which causes query abort if positive */
- int groupBySort; /* Rows come from source in GROUP BY order */
- int addrEnd; /* End of processing for this SELECT */
-
- /* Remove any and all aliases between the result set and the
- ** GROUP BY clause.
- */
- if( pGroupBy ){
- int k; /* Loop counter */
- struct ExprList_item *pItem; /* For looping over expression in a list */
-
- for(k=p->pEList->nExpr, pItem=p->pEList->a; k>0; k--, pItem++){
- pItem->iAlias = 0;
- }
- for(k=pGroupBy->nExpr, pItem=pGroupBy->a; k>0; k--, pItem++){
- pItem->iAlias = 0;
- }
- }
-
-
- /* Create a label to jump to when we want to abort the query */
- addrEnd = sqlite3VdbeMakeLabel(v);
-
- /* Convert TK_COLUMN nodes into TK_AGG_COLUMN and make entries in
- ** sAggInfo for all TK_AGG_FUNCTION nodes in expressions of the
- ** SELECT statement.
- */
- memset(&sNC, 0, sizeof(sNC));
- sNC.pParse = pParse;
- sNC.pSrcList = pTabList;
- sNC.pAggInfo = &sAggInfo;
- sAggInfo.nSortingColumn = pGroupBy ? pGroupBy->nExpr+1 : 0;
- sAggInfo.pGroupBy = pGroupBy;
- sqlite3ExprAnalyzeAggList(&sNC, pEList);
- sqlite3ExprAnalyzeAggList(&sNC, pOrderBy);
- if( pHaving ){
- sqlite3ExprAnalyzeAggregates(&sNC, pHaving);
- }
- sAggInfo.nAccumulator = sAggInfo.nColumn;
- for(i=0; i<sAggInfo.nFunc; i++){
- assert( !ExprHasProperty(sAggInfo.aFunc[i].pExpr, EP_xIsSelect) );
- sqlite3ExprAnalyzeAggList(&sNC, sAggInfo.aFunc[i].pExpr->x.pList);
- }
- if( db->mallocFailed ) goto select_end;
-
- /* Processing for aggregates with GROUP BY is very different and
- ** much more complex than aggregates without a GROUP BY.
- */
- if( pGroupBy ){
- KeyInfo *pKeyInfo; /* Keying information for the group by clause */
- int j1; /* A-vs-B comparision jump */
- int addrOutputRow; /* Start of subroutine that outputs a result row */
- int regOutputRow; /* Return address register for output subroutine */
- int addrSetAbort; /* Set the abort flag and return */
- int addrTopOfLoop; /* Top of the input loop */
- int addrSortingIdx; /* The OP_OpenEphemeral for the sorting index */
- int addrReset; /* Subroutine for resetting the accumulator */
- int regReset; /* Return address register for reset subroutine */
-
- /* If there is a GROUP BY clause we might need a sorting index to
- ** implement it. Allocate that sorting index now. If it turns out
- ** that we do not need it after all, the OpenEphemeral instruction
- ** will be converted into a Noop.
- */
- sAggInfo.sortingIdx = pParse->nTab++;
- pKeyInfo = keyInfoFromExprList(pParse, pGroupBy);
- addrSortingIdx = sqlite3VdbeAddOp4(v, OP_OpenEphemeral,
- sAggInfo.sortingIdx, sAggInfo.nSortingColumn,
- 0, (char*)pKeyInfo, P4_KEYINFO_HANDOFF);
-
- /* Initialize memory locations used by GROUP BY aggregate processing
- */
- iUseFlag = ++pParse->nMem;
- iAbortFlag = ++pParse->nMem;
- regOutputRow = ++pParse->nMem;
- addrOutputRow = sqlite3VdbeMakeLabel(v);
- regReset = ++pParse->nMem;
- addrReset = sqlite3VdbeMakeLabel(v);
- iAMem = pParse->nMem + 1;
- pParse->nMem += pGroupBy->nExpr;
- iBMem = pParse->nMem + 1;
- pParse->nMem += pGroupBy->nExpr;
- sqlite3VdbeAddOp2(v, OP_Integer, 0, iAbortFlag);
- VdbeComment((v, "clear abort flag"));
- sqlite3VdbeAddOp2(v, OP_Integer, 0, iUseFlag);
- VdbeComment((v, "indicate accumulator empty"));
-
- /* 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
- ** it might be a single loop that uses an index to extract information
- ** in the right order to begin with.
- */
- sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset);
- pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, &pGroupBy, 0);
- if( pWInfo==0 ) goto select_end;
- if( pGroupBy==0 ){
- /* The optimizer is able to deliver rows in group by order so
- ** we do not have to sort. The OP_OpenEphemeral table will be
- ** cancelled later because we still need to use the pKeyInfo
- */
- pGroupBy = p->pGroupBy;
- groupBySort = 0;
- }else{
- /* Rows are coming out in undetermined order. We have to push
- ** each row into a sorting index, terminate the first loop,
- ** then loop over the sorting index in order to get the output
- ** in sorted order
- */
- int regBase;
- int regRecord;
- int nCol;
- int nGroupBy;
-
- groupBySort = 1;
- nGroupBy = pGroupBy->nExpr;
- nCol = nGroupBy + 1;
- j = nGroupBy+1;
- for(i=0; i<sAggInfo.nColumn; i++){
- if( sAggInfo.aCol[i].iSorterColumn>=j ){
- nCol++;
- j++;
- }
- }
- regBase = sqlite3GetTempRange(pParse, nCol);
- sqlite3ExprCacheClear(pParse);
- sqlite3ExprCodeExprList(pParse, pGroupBy, regBase, 0);
- sqlite3VdbeAddOp2(v, OP_Sequence, sAggInfo.sortingIdx,regBase+nGroupBy);
- j = nGroupBy+1;
- for(i=0; i<sAggInfo.nColumn; i++){
- struct AggInfo_col *pCol = &sAggInfo.aCol[i];
- if( pCol->iSorterColumn>=j ){
- int r1 = j + regBase;
- int r2;
-
- r2 = sqlite3ExprCodeGetColumn(pParse,
- pCol->pTab, pCol->iColumn, pCol->iTable, r1, 0);
- if( r1!=r2 ){
- sqlite3VdbeAddOp2(v, OP_SCopy, r2, r1);
- }
- j++;
- }
- }
- regRecord = sqlite3GetTempReg(pParse);
- sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol, regRecord);
- sqlite3VdbeAddOp2(v, OP_IdxInsert, sAggInfo.sortingIdx, regRecord);
- sqlite3ReleaseTempReg(pParse, regRecord);
- sqlite3ReleaseTempRange(pParse, regBase, nCol);
- sqlite3WhereEnd(pWInfo);
- sqlite3VdbeAddOp2(v, OP_Sort, sAggInfo.sortingIdx, addrEnd);
- VdbeComment((v, "GROUP BY sort"));
- sAggInfo.useSortingIdx = 1;
- sqlite3ExprCacheClear(pParse);
- }
-
- /* Evaluate the current GROUP BY terms and store in b0, b1, b2...
- ** (b0 is memory location iBMem+0, b1 is iBMem+1, and so forth)
- ** Then compare the current GROUP BY terms against the GROUP BY terms
- ** from the previous row currently stored in a0, a1, a2...
- */
- addrTopOfLoop = sqlite3VdbeCurrentAddr(v);
- sqlite3ExprCacheClear(pParse);
- for(j=0; j<pGroupBy->nExpr; j++){
- if( groupBySort ){
- sqlite3VdbeAddOp3(v, OP_Column, sAggInfo.sortingIdx, j, iBMem+j);
- }else{
- sAggInfo.directMode = 1;
- sqlite3ExprCode(pParse, pGroupBy->a[j].pExpr, iBMem+j);
- }
- }
- sqlite3VdbeAddOp4(v, OP_Compare, iAMem, iBMem, pGroupBy->nExpr,
- (char*)pKeyInfo, P4_KEYINFO);
- j1 = sqlite3VdbeCurrentAddr(v);
- sqlite3VdbeAddOp3(v, OP_Jump, j1+1, 0, j1+1);
-
- /* Generate code that runs whenever the GROUP BY changes.
- ** Changes in the GROUP BY are detected by the previous code
- ** block. If there were no changes, this block is skipped.
- **
- ** This code copies current group by terms in b0,b1,b2,...
- ** over to a0,a1,a2. It then calls the output subroutine
- ** and resets the aggregate accumulator registers in preparation
- ** for the next GROUP BY batch.
- */
- sqlite3ExprCodeMove(pParse, iBMem, iAMem, pGroupBy->nExpr);
- sqlite3VdbeAddOp2(v, OP_Gosub, regOutputRow, addrOutputRow);
- VdbeComment((v, "output one row"));
- sqlite3VdbeAddOp2(v, OP_IfPos, iAbortFlag, addrEnd);
- VdbeComment((v, "check abort flag"));
- sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset);
- VdbeComment((v, "reset accumulator"));
-
- /* Update the aggregate accumulators based on the content of
- ** the current row
- */
- sqlite3VdbeJumpHere(v, j1);
- updateAccumulator(pParse, &sAggInfo);
- sqlite3VdbeAddOp2(v, OP_Integer, 1, iUseFlag);
- VdbeComment((v, "indicate data in accumulator"));
-
- /* End of the loop
- */
- if( groupBySort ){
- sqlite3VdbeAddOp2(v, OP_Next, sAggInfo.sortingIdx, addrTopOfLoop);
- }else{
- sqlite3WhereEnd(pWInfo);
- sqlite3VdbeChangeToNoop(v, addrSortingIdx, 1);
- }
-
- /* Output the final row of result
- */
- sqlite3VdbeAddOp2(v, OP_Gosub, regOutputRow, addrOutputRow);
- VdbeComment((v, "output final row"));
-
- /* Jump over the subroutines
- */
- sqlite3VdbeAddOp2(v, OP_Goto, 0, addrEnd);
-
- /* Generate a subroutine that outputs a single row of the result
- ** set. This subroutine first looks at the iUseFlag. If iUseFlag
- ** is less than or equal to zero, the subroutine is a no-op. If
- ** the processing calls for the query to abort, this subroutine
- ** increments the iAbortFlag memory location before returning in
- ** order to signal the caller to abort.
- */
- addrSetAbort = sqlite3VdbeCurrentAddr(v);
- sqlite3VdbeAddOp2(v, OP_Integer, 1, iAbortFlag);
- VdbeComment((v, "set abort flag"));
- sqlite3VdbeAddOp1(v, OP_Return, regOutputRow);
- sqlite3VdbeResolveLabel(v, addrOutputRow);
- addrOutputRow = sqlite3VdbeCurrentAddr(v);
- sqlite3VdbeAddOp2(v, OP_IfPos, iUseFlag, addrOutputRow+2);
- VdbeComment((v, "Groupby result generator entry point"));
- sqlite3VdbeAddOp1(v, OP_Return, regOutputRow);
- finalizeAggFunctions(pParse, &sAggInfo);
- sqlite3ExprIfFalse(pParse, pHaving, addrOutputRow+1, SQLITE_JUMPIFNULL);
- selectInnerLoop(pParse, p, p->pEList, 0, 0, pOrderBy,
- distinct, pDest,
- addrOutputRow+1, addrSetAbort);
- sqlite3VdbeAddOp1(v, OP_Return, regOutputRow);
- VdbeComment((v, "end groupby result generator"));
-
- /* Generate a subroutine that will reset the group-by accumulator
- */
- sqlite3VdbeResolveLabel(v, addrReset);
- resetAccumulator(pParse, &sAggInfo);
- sqlite3VdbeAddOp1(v, OP_Return, regReset);
-
- } /* endif pGroupBy. Begin aggregate queries without GROUP BY: */
- else {
- ExprList *pDel = 0;
-#ifndef SQLITE_OMIT_BTREECOUNT
- Table *pTab;
- if( (pTab = isSimpleCount(p, &sAggInfo))!=0 ){
- /* If isSimpleCount() returns a pointer to a Table structure, then
- ** the SQL statement is of the form:
- **
- ** SELECT count(*) FROM <tbl>
- **
- ** where the Table structure returned represents table <tbl>.
- **
- ** This statement is so common that it is optimized specially. The
- ** OP_Count instruction is executed either on the intkey table that
- ** contains the data for table <tbl> or on one of its indexes. It
- ** is better to execute the op on an index, as indexes are almost
- ** always spread across less pages than their corresponding tables.
- */
- const int iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
- const int iCsr = pParse->nTab++; /* Cursor to scan b-tree */
- Index *pIdx; /* Iterator variable */
- KeyInfo *pKeyInfo = 0; /* Keyinfo for scanned index */
- Index *pBest = 0; /* Best index found so far */
- int iRoot = pTab->tnum; /* Root page of scanned b-tree */
-
- sqlite3CodeVerifySchema(pParse, iDb);
- sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
-
- /* Search for the index that has the least amount of columns. If
- ** there is such an index, and it has less columns than the table
- ** does, then we can assume that it consumes less space on disk and
- ** will therefore be cheaper to scan to determine the query result.
- ** In this case set iRoot to the root page number of the index b-tree
- ** and pKeyInfo to the KeyInfo structure required to navigate the
- ** index.
- **
- ** In practice the KeyInfo structure will not be used. It is only
- ** passed to keep OP_OpenRead happy.
- */
- for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
- if( !pBest || pIdx->nColumn<pBest->nColumn ){
- pBest = pIdx;
- }
- }
- if( pBest && pBest->nColumn<pTab->nCol ){
- iRoot = pBest->tnum;
- pKeyInfo = sqlite3IndexKeyinfo(pParse, pBest);
- }
-
- /* Open a read-only cursor, execute the OP_Count, close the cursor. */
- sqlite3VdbeAddOp3(v, OP_OpenRead, iCsr, iRoot, iDb);
- if( pKeyInfo ){
- sqlite3VdbeChangeP4(v, -1, (char *)pKeyInfo, P4_KEYINFO_HANDOFF);
- }
- sqlite3VdbeAddOp2(v, OP_Count, iCsr, sAggInfo.aFunc[0].iMem);
- sqlite3VdbeAddOp1(v, OP_Close, iCsr);
- }else
-#endif /* SQLITE_OMIT_BTREECOUNT */
- {
- /* Check if the query is of one of the following forms:
- **
- ** SELECT min(x) FROM ...
- ** SELECT max(x) FROM ...
- **
- ** If it is, then ask the code in where.c to attempt to sort results
- ** as if there was an "ORDER ON x" or "ORDER ON x DESC" clause.
- ** If where.c is able to produce results sorted in this order, then
- ** add vdbe code to break out of the processing loop after the
- ** first iteration (since the first iteration of the loop is
- ** guaranteed to operate on the row with the minimum or maximum
- ** value of x, the only row required).
- **
- ** A special flag must be passed to sqlite3WhereBegin() to slightly
- ** modify behaviour as follows:
- **
- ** + If the query is a "SELECT min(x)", then the loop coded by
- ** where.c should not iterate over any values with a NULL value
- ** for x.
- **
- ** + The optimizer code in where.c (the thing that decides which
- ** index or indices to use) should place a different priority on
- ** satisfying the 'ORDER BY' clause than it does in other cases.
- ** Refer to code and comments in where.c for details.
- */
- ExprList *pMinMax = 0;
- u8 flag = minMaxQuery(p);
- if( flag ){
- assert( !ExprHasProperty(p->pEList->a[0].pExpr, EP_xIsSelect) );
- pMinMax = sqlite3ExprListDup(db, p->pEList->a[0].pExpr->x.pList,0);
- pDel = pMinMax;
- if( pMinMax && !db->mallocFailed ){
- pMinMax->a[0].sortOrder = flag!=WHERE_ORDERBY_MIN ?1:0;
- pMinMax->a[0].pExpr->op = TK_COLUMN;
- }
- }
-
- /* This case runs if the aggregate has no GROUP BY clause. The
- ** processing is much simpler since there is only a single row
- ** of output.
- */
- resetAccumulator(pParse, &sAggInfo);
- pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, &pMinMax, flag);
- if( pWInfo==0 ){
- sqlite3ExprListDelete(db, pDel);
- goto select_end;
- }
- updateAccumulator(pParse, &sAggInfo);
- if( !pMinMax && flag ){
- sqlite3VdbeAddOp2(v, OP_Goto, 0, pWInfo->iBreak);
- VdbeComment((v, "%s() by index",
- (flag==WHERE_ORDERBY_MIN?"min":"max")));
- }
- sqlite3WhereEnd(pWInfo);
- finalizeAggFunctions(pParse, &sAggInfo);
- }
-
- pOrderBy = 0;
- sqlite3ExprIfFalse(pParse, pHaving, addrEnd, SQLITE_JUMPIFNULL);
- selectInnerLoop(pParse, p, p->pEList, 0, 0, 0, -1,
- pDest, addrEnd, addrEnd);
- sqlite3ExprListDelete(db, pDel);
- }
- sqlite3VdbeResolveLabel(v, addrEnd);
-
- } /* endif aggregate query */
-
- /* If there is an ORDER BY clause, then we need to sort the results
- ** and send them to the callback one by one.
- */
- if( pOrderBy ){
- generateSortTail(pParse, p, v, pEList->nExpr, pDest);
- }
-
- /* Jump here to skip this query
- */
- sqlite3VdbeResolveLabel(v, iEnd);
-
- /* The SELECT was successfully coded. Set the return code to 0
- ** to indicate no errors.
- */
- rc = 0;
-
- /* Control jumps to here if an error is encountered above, or upon
- ** successful coding of the SELECT.
- */
-select_end:
-
- /* Identify column names if results of the SELECT are to be output.
- */
- if( rc==SQLITE_OK && pDest->eDest==SRT_Output ){
- generateColumnNames(pParse, pTabList, pEList);
- }
-
- sqlite3DbFree(db, sAggInfo.aCol);
- sqlite3DbFree(db, sAggInfo.aFunc);
- return rc;
-}
-
-#if defined(SQLITE_DEBUG)
-/*
-*******************************************************************************
-** 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.
-*/
-SQLITE_PRIVATE 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(")");
-}
-SQLITE_PRIVATE void sqlite3PrintExprList(ExprList *pList){
- int i;
- for(i=0; i<pList->nExpr; i++){
- sqlite3PrintExpr(pList->a[i].pExpr);
- if( i<pList->nExpr-1 ){
- sqlite3DebugPrintf(", ");
- }
- }
-}
-SQLITE_PRIVATE void sqlite3PrintSelect(Select *p, int indent){
- sqlite3DebugPrintf("%*sSELECT(%p) ", indent, "", p);
- sqlite3PrintExprList(p->pEList);
- sqlite3DebugPrintf("\n");
- if( p->pSrc ){
- char *zPrefix;
- int i;
- zPrefix = "FROM";
- for(i=0; i<p->pSrc->nSrc; i++){
- struct SrcList_item *pItem = &p->pSrc->a[i];
- sqlite3DebugPrintf("%*s ", indent+6, zPrefix);
- zPrefix = "";
- if( pItem->pSelect ){
- sqlite3DebugPrintf("(\n");
- sqlite3PrintSelect(pItem->pSelect, indent+10);
- sqlite3DebugPrintf("%*s)", indent+8, "");
- }else if( pItem->zName ){
- sqlite3DebugPrintf("%s", pItem->zName);
- }
- if( pItem->pTab ){
- sqlite3DebugPrintf("(table: %s)", pItem->pTab->zName);
- }
- if( pItem->zAlias ){
- sqlite3DebugPrintf(" AS %s", pItem->zAlias);
- }
- if( i<p->pSrc->nSrc-1 ){
- sqlite3DebugPrintf(",");
- }
- sqlite3DebugPrintf("\n");
- }
- }
- if( p->pWhere ){
- sqlite3DebugPrintf("%*s WHERE ", indent, "");
- sqlite3PrintExpr(p->pWhere);
- sqlite3DebugPrintf("\n");
- }
- if( p->pGroupBy ){
- sqlite3DebugPrintf("%*s GROUP BY ", indent, "");
- sqlite3PrintExprList(p->pGroupBy);
- sqlite3DebugPrintf("\n");
- }
- if( p->pHaving ){
- sqlite3DebugPrintf("%*s HAVING ", indent, "");
- sqlite3PrintExpr(p->pHaving);
- sqlite3DebugPrintf("\n");
- }
- if( p->pOrderBy ){
- sqlite3DebugPrintf("%*s ORDER BY ", indent, "");
- sqlite3PrintExprList(p->pOrderBy);
- sqlite3DebugPrintf("\n");
- }
-}
-/* End of the structure debug printing code
-*****************************************************************************/
-#endif /* defined(SQLITE_TEST) || defined(SQLITE_DEBUG) */
-
-/************** End of select.c **********************************************/
-/************** Begin file table.c *******************************************/
-/*
-** 2001 September 15
-**
-** 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 sqlite3_get_table() and sqlite3_free_table()
-** interface routines. These are just wrappers around the main
-** interface routine of sqlite3_exec().
-**
-** These routines are in a separate files so that they will not be linked
-** if they are not used.
-**
-** $Id: table.c,v 1.40 2009/04/10 14:28:00 drh Exp $
-*/
-
-#ifndef SQLITE_OMIT_GET_TABLE
-
-/*
-** This structure is used to pass data from sqlite3_get_table() through
-** to the callback function is uses to build the result.
-*/
-typedef struct TabResult {
- char **azResult; /* Accumulated output */
- char *zErrMsg; /* Error message text, if an error occurs */
- int nAlloc; /* Slots allocated for azResult[] */
- int nRow; /* Number of rows in the result */
- int nColumn; /* Number of columns in the result */
- int nData; /* Slots used in azResult[]. (nRow+1)*nColumn */
- int rc; /* Return code from sqlite3_exec() */
-} TabResult;
-
-/*
-** This routine is called once for each row in the result table. Its job
-** is to fill in the TabResult structure appropriately, allocating new
-** memory as necessary.
-*/
-static int sqlite3_get_table_cb(void *pArg, int nCol, char **argv, char **colv){
- TabResult *p = (TabResult*)pArg; /* Result accumulator */
- int need; /* Slots needed in p->azResult[] */
- int i; /* Loop counter */
- char *z; /* A single column of result */
-
- /* Make sure there is enough space in p->azResult to hold everything
- ** we need to remember from this invocation of the callback.
- */
- if( p->nRow==0 && argv!=0 ){
- need = nCol*2;
- }else{
- need = nCol;
- }
- if( p->nData + need > p->nAlloc ){
- char **azNew;
- p->nAlloc = p->nAlloc*2 + need;
- azNew = sqlite3_realloc( p->azResult, sizeof(char*)*p->nAlloc );
- if( azNew==0 ) goto malloc_failed;
- p->azResult = azNew;
- }
-
- /* If this is the first row, then generate an extra row containing
- ** the names of all columns.
- */
- if( p->nRow==0 ){
- p->nColumn = nCol;
- for(i=0; i<nCol; i++){
- z = sqlite3_mprintf("%s", colv[i]);
- if( z==0 ) goto malloc_failed;
- p->azResult[p->nData++] = z;
- }
- }else if( p->nColumn!=nCol ){
- sqlite3_free(p->zErrMsg);
- p->zErrMsg = sqlite3_mprintf(
- "sqlite3_get_table() called with two or more incompatible queries"
- );
- p->rc = SQLITE_ERROR;
- return 1;
- }
-
- /* Copy over the row data
- */
- if( argv!=0 ){
- for(i=0; i<nCol; i++){
- if( argv[i]==0 ){
- z = 0;
- }else{
- int n = sqlite3Strlen30(argv[i])+1;
- z = sqlite3_malloc( n );
- if( z==0 ) goto malloc_failed;
- memcpy(z, argv[i], n);
- }
- p->azResult[p->nData++] = z;
- }
- p->nRow++;
- }
- return 0;
-
-malloc_failed:
- p->rc = SQLITE_NOMEM;
- return 1;
-}
-
-/*
-** Query the database. But instead of invoking a callback for each row,
-** malloc() for space to hold the result and return the entire results
-** at the conclusion of the call.
-**
-** The result that is written to ***pazResult is held in memory obtained
-** from malloc(). But the caller cannot free this memory directly.
-** Instead, the entire table should be passed to sqlite3_free_table() when
-** the calling procedure is finished using it.
-*/
-SQLITE_API int sqlite3_get_table(
- sqlite3 *db, /* The database on which the SQL executes */
- const char *zSql, /* The SQL to be executed */
- char ***pazResult, /* Write the result table here */
- int *pnRow, /* Write the number of rows in the result here */
- int *pnColumn, /* Write the number of columns of result here */
- char **pzErrMsg /* Write error messages here */
-){
- int rc;
- TabResult res;
-
- *pazResult = 0;
- if( pnColumn ) *pnColumn = 0;
- if( pnRow ) *pnRow = 0;
- if( pzErrMsg ) *pzErrMsg = 0;
- res.zErrMsg = 0;
- res.nRow = 0;
- res.nColumn = 0;
- res.nData = 1;
- res.nAlloc = 20;
- res.rc = SQLITE_OK;
- res.azResult = sqlite3_malloc(sizeof(char*)*res.nAlloc );
- if( res.azResult==0 ){
- db->errCode = SQLITE_NOMEM;
- return SQLITE_NOMEM;
- }
- res.azResult[0] = 0;
- rc = sqlite3_exec(db, zSql, sqlite3_get_table_cb, &res, pzErrMsg);
- assert( sizeof(res.azResult[0])>= sizeof(res.nData) );
- res.azResult[0] = SQLITE_INT_TO_PTR(res.nData);
- if( (rc&0xff)==SQLITE_ABORT ){
- sqlite3_free_table(&res.azResult[1]);
- if( res.zErrMsg ){
- if( pzErrMsg ){
- sqlite3_free(*pzErrMsg);
- *pzErrMsg = sqlite3_mprintf("%s",res.zErrMsg);
- }
- sqlite3_free(res.zErrMsg);
- }
- db->errCode = res.rc; /* Assume 32-bit assignment is atomic */
- return res.rc;
- }
- sqlite3_free(res.zErrMsg);
- if( rc!=SQLITE_OK ){
- sqlite3_free_table(&res.azResult[1]);
- return rc;
- }
- if( res.nAlloc>res.nData ){
- char **azNew;
- azNew = sqlite3_realloc( res.azResult, sizeof(char*)*res.nData );
- if( azNew==0 ){
- sqlite3_free_table(&res.azResult[1]);
- db->errCode = SQLITE_NOMEM;
- return SQLITE_NOMEM;
- }
- res.azResult = azNew;
- }
- *pazResult = &res.azResult[1];
- if( pnColumn ) *pnColumn = res.nColumn;
- if( pnRow ) *pnRow = res.nRow;
- return rc;
-}
-
-/*
-** This routine frees the space the sqlite3_get_table() malloced.
-*/
-SQLITE_API void sqlite3_free_table(
- char **azResult /* Result returned from from sqlite3_get_table() */
-){
- if( azResult ){
- int i, n;
- azResult--;
- assert( azResult!=0 );
- n = SQLITE_PTR_TO_INT(azResult[0]);
- for(i=1; i<n; i++){ if( azResult[i] ) sqlite3_free(azResult[i]); }
- sqlite3_free(azResult);
- }
-}
-
-#endif /* SQLITE_OMIT_GET_TABLE */
-
-/************** End of table.c ***********************************************/
-/************** Begin file trigger.c *****************************************/
-/*
-**
-** 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.
-**
-*************************************************************************
-**
-**
-** $Id: trigger.c,v 1.143 2009/08/10 03:57:58 shane Exp $
-*/
-
-#ifndef SQLITE_OMIT_TRIGGER
-/*
-** Delete a linked list of TriggerStep structures.
-*/
-SQLITE_PRIVATE void sqlite3DeleteTriggerStep(sqlite3 *db, TriggerStep *pTriggerStep){
- while( pTriggerStep ){
- TriggerStep * pTmp = pTriggerStep;
- pTriggerStep = pTriggerStep->pNext;
-
- sqlite3ExprDelete(db, pTmp->pWhere);
- sqlite3ExprListDelete(db, pTmp->pExprList);
- sqlite3SelectDelete(db, pTmp->pSelect);
- sqlite3IdListDelete(db, pTmp->pIdList);
-
- sqlite3DbFree(db, pTmp);
- }
-}
-
-/*
-** Given table pTab, return a list of all the triggers attached to
-** the table. The list is connected by Trigger.pNext pointers.
-**
-** All of the triggers on pTab that are in the same database as pTab
-** are already attached to pTab->pTrigger. But there might be additional
-** triggers on pTab in the TEMP schema. This routine prepends all
-** TEMP triggers on pTab to the beginning of the pTab->pTrigger list
-** and returns the combined list.
-**
-** To state it another way: This routine returns a list of all triggers
-** that fire off of pTab. The list will include any TEMP triggers on
-** pTab as well as the triggers lised in pTab->pTrigger.
-*/
-SQLITE_PRIVATE Trigger *sqlite3TriggerList(Parse *pParse, Table *pTab){
- Schema * const pTmpSchema = pParse->db->aDb[1].pSchema;
- Trigger *pList = 0; /* List of triggers to return */
-
- if( pTmpSchema!=pTab->pSchema ){
- HashElem *p;
- for(p=sqliteHashFirst(&pTmpSchema->trigHash); p; p=sqliteHashNext(p)){
- Trigger *pTrig = (Trigger *)sqliteHashData(p);
- if( pTrig->pTabSchema==pTab->pSchema
- && 0==sqlite3StrICmp(pTrig->table, pTab->zName)
- ){
- pTrig->pNext = (pList ? pList : pTab->pTrigger);
- pList = pTrig;
- }
- }
- }
-
- return (pList ? pList : pTab->pTrigger);
-}
-
-/*
-** This is called by the parser when it sees a CREATE TRIGGER statement
-** up to the point of the BEGIN before the trigger actions. A Trigger
-** structure is generated based on the information available and stored
-** in pParse->pNewTrigger. After the trigger actions have been parsed, the
-** sqlite3FinishTrigger() function is called to complete the trigger
-** construction process.
-*/
-SQLITE_PRIVATE void sqlite3BeginTrigger(
- Parse *pParse, /* The parse context of the CREATE TRIGGER statement */
- Token *pName1, /* The name of the trigger */
- Token *pName2, /* The name of the trigger */
- int tr_tm, /* One of TK_BEFORE, TK_AFTER, TK_INSTEAD */
- int op, /* One of TK_INSERT, TK_UPDATE, TK_DELETE */
- IdList *pColumns, /* column list if this is an UPDATE OF trigger */
- SrcList *pTableName,/* The name of the table/view the trigger applies to */
- Expr *pWhen, /* WHEN clause */
- int isTemp, /* True if the TEMPORARY keyword is present */
- int noErr /* Suppress errors if the trigger already exists */
-){
- Trigger *pTrigger = 0; /* The new trigger */
- Table *pTab; /* Table that the trigger fires off of */
- char *zName = 0; /* Name of the trigger */
- sqlite3 *db = pParse->db; /* The database connection */
- int iDb; /* The database to store the trigger in */
- Token *pName; /* The unqualified db name */
- DbFixer sFix; /* State vector for the DB fixer */
- int iTabDb; /* Index of the database holding pTab */
-
- assert( pName1!=0 ); /* pName1->z might be NULL, but not pName1 itself */
- assert( pName2!=0 );
- assert( op==TK_INSERT || op==TK_UPDATE || op==TK_DELETE );
- assert( op>0 && op<0xff );
- if( isTemp ){
- /* If TEMP was specified, then the trigger name may not be qualified. */
- if( pName2->n>0 ){
- sqlite3ErrorMsg(pParse, "temporary trigger may not have qualified name");
- goto trigger_cleanup;
- }
- iDb = 1;
- pName = pName1;
- }else{
- /* Figure out the db that the the trigger will be created in */
- iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pName);
- if( iDb<0 ){
- goto trigger_cleanup;
- }
- }
-
- /* If the trigger name was unqualified, and the table is a temp table,
- ** then set iDb to 1 to create the trigger in the temporary database.
- ** If sqlite3SrcListLookup() returns 0, indicating the table does not
- ** exist, the error is caught by the block below.
- */
- if( !pTableName || db->mallocFailed ){
- goto trigger_cleanup;
- }
- pTab = sqlite3SrcListLookup(pParse, pTableName);
- if( pName2->n==0 && pTab && pTab->pSchema==db->aDb[1].pSchema ){
- iDb = 1;
- }
-
- /* Ensure the table name matches database name and that the table exists */
- if( db->mallocFailed ) goto trigger_cleanup;
- assert( pTableName->nSrc==1 );
- if( sqlite3FixInit(&sFix, pParse, iDb, "trigger", pName) &&
- sqlite3FixSrcList(&sFix, pTableName) ){
- goto trigger_cleanup;
- }
- pTab = sqlite3SrcListLookup(pParse, pTableName);
- if( !pTab ){
- /* The table does not exist. */
- if( db->init.iDb==1 ){
- /* Ticket #3810.
- ** Normally, whenever a table is dropped, all associated triggers are
- ** dropped too. But if a TEMP trigger is created on a non-TEMP table
- ** and the table is dropped by a different database connection, the
- ** trigger is not visible to the database connection that does the
- ** drop so the trigger cannot be dropped. This results in an
- ** "orphaned trigger" - a trigger whose associated table is missing.
- */
- db->init.orphanTrigger = 1;
- }
- goto trigger_cleanup;
- }
- if( IsVirtual(pTab) ){
- sqlite3ErrorMsg(pParse, "cannot create triggers on virtual tables");
- goto trigger_cleanup;
- }
-
- /* Check that the trigger name is not reserved and that no trigger of the
- ** specified name exists */
- zName = sqlite3NameFromToken(db, pName);
- if( !zName || SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){
- goto trigger_cleanup;
- }
- if( sqlite3HashFind(&(db->aDb[iDb].pSchema->trigHash),
- zName, sqlite3Strlen30(zName)) ){
- if( !noErr ){
- sqlite3ErrorMsg(pParse, "trigger %T already exists", pName);
- }
- goto trigger_cleanup;
- }
-
- /* Do not create a trigger on a system table */
- if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0 ){
- sqlite3ErrorMsg(pParse, "cannot create trigger on system table");
- pParse->nErr++;
- goto trigger_cleanup;
- }
-
- /* INSTEAD of triggers are only for views and views only support INSTEAD
- ** of triggers.
- */
- if( pTab->pSelect && tr_tm!=TK_INSTEAD ){
- sqlite3ErrorMsg(pParse, "cannot create %s trigger on view: %S",
- (tr_tm == TK_BEFORE)?"BEFORE":"AFTER", pTableName, 0);
- goto trigger_cleanup;
- }
- if( !pTab->pSelect && tr_tm==TK_INSTEAD ){
- sqlite3ErrorMsg(pParse, "cannot create INSTEAD OF"
- " trigger on table: %S", pTableName, 0);
- goto trigger_cleanup;
- }
- iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema);
-
-#ifndef SQLITE_OMIT_AUTHORIZATION
- {
- int code = SQLITE_CREATE_TRIGGER;
- const char *zDb = db->aDb[iTabDb].zName;
- const char *zDbTrig = isTemp ? db->aDb[1].zName : zDb;
- if( iTabDb==1 || isTemp ) code = SQLITE_CREATE_TEMP_TRIGGER;
- if( sqlite3AuthCheck(pParse, code, zName, pTab->zName, zDbTrig) ){
- goto trigger_cleanup;
- }
- if( sqlite3AuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(iTabDb),0,zDb)){
- goto trigger_cleanup;
- }
- }
-#endif
-
- /* INSTEAD OF triggers can only appear on views and BEFORE triggers
- ** cannot appear on views. So we might as well translate every
- ** INSTEAD OF trigger into a BEFORE trigger. It simplifies code
- ** elsewhere.
- */
- if (tr_tm == TK_INSTEAD){
- tr_tm = TK_BEFORE;
- }
-
- /* Build the Trigger object */
- pTrigger = (Trigger*)sqlite3DbMallocZero(db, sizeof(Trigger));
- if( pTrigger==0 ) goto trigger_cleanup;
- pTrigger->zName = zName;
- zName = 0;
- pTrigger->table = sqlite3DbStrDup(db, pTableName->a[0].zName);
- pTrigger->pSchema = db->aDb[iDb].pSchema;
- pTrigger->pTabSchema = pTab->pSchema;
- pTrigger->op = (u8)op;
- pTrigger->tr_tm = tr_tm==TK_BEFORE ? TRIGGER_BEFORE : TRIGGER_AFTER;
- pTrigger->pWhen = sqlite3ExprDup(db, pWhen, EXPRDUP_REDUCE);
- pTrigger->pColumns = sqlite3IdListDup(db, pColumns);
- assert( pParse->pNewTrigger==0 );
- pParse->pNewTrigger = pTrigger;
-
-trigger_cleanup:
- sqlite3DbFree(db, zName);
- sqlite3SrcListDelete(db, pTableName);
- sqlite3IdListDelete(db, pColumns);
- sqlite3ExprDelete(db, pWhen);
- if( !pParse->pNewTrigger ){
- sqlite3DeleteTrigger(db, pTrigger);
- }else{
- assert( pParse->pNewTrigger==pTrigger );
- }
-}
-
-/*
-** This routine is called after all of the trigger actions have been parsed
-** in order to complete the process of building the trigger.
-*/
-SQLITE_PRIVATE void sqlite3FinishTrigger(
- Parse *pParse, /* Parser context */
- TriggerStep *pStepList, /* The triggered program */
- Token *pAll /* Token that describes the complete CREATE TRIGGER */
-){
- Trigger *pTrig = pParse->pNewTrigger; /* Trigger being finished */
- char *zName; /* Name of trigger */
- sqlite3 *db = pParse->db; /* The database */
- DbFixer sFix;
- int iDb; /* Database containing the trigger */
- Token nameToken; /* Trigger name for error reporting */
-
- pTrig = pParse->pNewTrigger;
- pParse->pNewTrigger = 0;
- if( NEVER(pParse->nErr) || !pTrig ) goto triggerfinish_cleanup;
- zName = pTrig->zName;
- iDb = sqlite3SchemaToIndex(pParse->db, pTrig->pSchema);
- pTrig->step_list = pStepList;
- while( pStepList ){
- pStepList->pTrig = pTrig;
- pStepList = pStepList->pNext;
- }
- nameToken.z = pTrig->zName;
- nameToken.n = sqlite3Strlen30(nameToken.z);
- if( sqlite3FixInit(&sFix, pParse, iDb, "trigger", &nameToken)
- && sqlite3FixTriggerStep(&sFix, pTrig->step_list) ){
- goto triggerfinish_cleanup;
- }
-
- /* if we are not initializing, and this trigger is not on a TEMP table,
- ** build the sqlite_master entry
- */
- if( !db->init.busy ){
- Vdbe *v;
- char *z;
-
- /* Make an entry in the sqlite_master table */
- v = sqlite3GetVdbe(pParse);
- if( v==0 ) goto triggerfinish_cleanup;
- sqlite3BeginWriteOperation(pParse, 0, iDb);
- z = sqlite3DbStrNDup(db, (char*)pAll->z, pAll->n);
- sqlite3NestedParse(pParse,
- "INSERT INTO %Q.%s VALUES('trigger',%Q,%Q,0,'CREATE TRIGGER %q')",
- db->aDb[iDb].zName, SCHEMA_TABLE(iDb), zName,
- pTrig->table, z);
- sqlite3DbFree(db, z);
- sqlite3ChangeCookie(pParse, iDb);
- sqlite3VdbeAddOp4(v, OP_ParseSchema, iDb, 0, 0, sqlite3MPrintf(
- db, "type='trigger' AND name='%q'", zName), P4_DYNAMIC
- );
- }
-
- if( db->init.busy ){
- Trigger *pLink = pTrig;
- Hash *pHash = &db->aDb[iDb].pSchema->trigHash;
- pTrig = sqlite3HashInsert(pHash, zName, sqlite3Strlen30(zName), pTrig);
- if( pTrig ){
- db->mallocFailed = 1;
- }else if( pLink->pSchema==pLink->pTabSchema ){
- Table *pTab;
- int n = sqlite3Strlen30(pLink->table);
- pTab = sqlite3HashFind(&pLink->pTabSchema->tblHash, pLink->table, n);
- assert( pTab!=0 );
- pLink->pNext = pTab->pTrigger;
- pTab->pTrigger = pLink;
- }
- }
-
-triggerfinish_cleanup:
- sqlite3DeleteTrigger(db, pTrig);
- assert( !pParse->pNewTrigger );
- sqlite3DeleteTriggerStep(db, pStepList);
-}
-
-/*
-** Turn a SELECT statement (that the pSelect parameter points to) into
-** a trigger step. Return a pointer to a TriggerStep structure.
-**
-** The parser calls this routine when it finds a SELECT statement in
-** body of a TRIGGER.
-*/
-SQLITE_PRIVATE TriggerStep *sqlite3TriggerSelectStep(sqlite3 *db, Select *pSelect){
- TriggerStep *pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep));
- if( pTriggerStep==0 ) {
- sqlite3SelectDelete(db, pSelect);
- return 0;
- }
- pTriggerStep->op = TK_SELECT;
- pTriggerStep->pSelect = pSelect;
- pTriggerStep->orconf = OE_Default;
- return pTriggerStep;
-}
-
-/*
-** Allocate space to hold a new trigger step. The allocated space
-** holds both the TriggerStep object and the TriggerStep.target.z string.
-**
-** If an OOM error occurs, NULL is returned and db->mallocFailed is set.
-*/
-static TriggerStep *triggerStepAllocate(
- sqlite3 *db, /* Database connection */
- u8 op, /* Trigger opcode */
- Token *pName /* The target name */
-){
- TriggerStep *pTriggerStep;
-
- pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep) + pName->n);
- if( pTriggerStep ){
- char *z = (char*)&pTriggerStep[1];
- memcpy(z, pName->z, pName->n);
- pTriggerStep->target.z = z;
- pTriggerStep->target.n = pName->n;
- pTriggerStep->op = op;
- }
- return pTriggerStep;
-}
-
-/*
-** Build a trigger step out of an INSERT statement. Return a pointer
-** to the new trigger step.
-**
-** The parser calls this routine when it sees an INSERT inside the
-** body of a trigger.
-*/
-SQLITE_PRIVATE TriggerStep *sqlite3TriggerInsertStep(
- sqlite3 *db, /* The database connection */
- Token *pTableName, /* Name of the table into which we insert */
- IdList *pColumn, /* List of columns in pTableName to insert into */
- ExprList *pEList, /* The VALUE clause: a list of values to be inserted */
- Select *pSelect, /* A SELECT statement that supplies values */
- u8 orconf /* The conflict algorithm (OE_Abort, OE_Replace, etc.) */
-){
- TriggerStep *pTriggerStep;
-
- assert(pEList == 0 || pSelect == 0);
- assert(pEList != 0 || pSelect != 0 || db->mallocFailed);
-
- pTriggerStep = triggerStepAllocate(db, TK_INSERT, pTableName);
- if( pTriggerStep ){
- pTriggerStep->pSelect = sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE);
- pTriggerStep->pIdList = pColumn;
- pTriggerStep->pExprList = sqlite3ExprListDup(db, pEList, EXPRDUP_REDUCE);
- pTriggerStep->orconf = orconf;
- }else{
- sqlite3IdListDelete(db, pColumn);
- }
- sqlite3ExprListDelete(db, pEList);
- sqlite3SelectDelete(db, pSelect);
-
- return pTriggerStep;
-}
-
-/*
-** Construct a trigger step that implements an UPDATE statement and return
-** a pointer to that trigger step. The parser calls this routine when it
-** sees an UPDATE statement inside the body of a CREATE TRIGGER.
-*/
-SQLITE_PRIVATE TriggerStep *sqlite3TriggerUpdateStep(
- sqlite3 *db, /* The database connection */
- Token *pTableName, /* Name of the table to be updated */
- ExprList *pEList, /* The SET clause: list of column and new values */
- Expr *pWhere, /* The WHERE clause */
- u8 orconf /* The conflict algorithm. (OE_Abort, OE_Ignore, etc) */
-){
- TriggerStep *pTriggerStep;
-
- pTriggerStep = triggerStepAllocate(db, TK_UPDATE, pTableName);
- if( pTriggerStep ){
- pTriggerStep->pExprList = sqlite3ExprListDup(db, pEList, EXPRDUP_REDUCE);
- pTriggerStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE);
- pTriggerStep->orconf = orconf;
- }
- sqlite3ExprListDelete(db, pEList);
- sqlite3ExprDelete(db, pWhere);
- return pTriggerStep;
-}
-
-/*
-** Construct a trigger step that implements a DELETE statement and return
-** a pointer to that trigger step. The parser calls this routine when it
-** sees a DELETE statement inside the body of a CREATE TRIGGER.
-*/
-SQLITE_PRIVATE TriggerStep *sqlite3TriggerDeleteStep(
- sqlite3 *db, /* Database connection */
- Token *pTableName, /* The table from which rows are deleted */
- Expr *pWhere /* The WHERE clause */
-){
- TriggerStep *pTriggerStep;
-
- pTriggerStep = triggerStepAllocate(db, TK_DELETE, pTableName);
- if( pTriggerStep ){
- pTriggerStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE);
- pTriggerStep->orconf = OE_Default;
- }
- sqlite3ExprDelete(db, pWhere);
- return pTriggerStep;
-}
-
-/*
-** Recursively delete a Trigger structure
-*/
-SQLITE_PRIVATE void sqlite3DeleteTrigger(sqlite3 *db, Trigger *pTrigger){
- if( pTrigger==0 ) return;
- sqlite3DeleteTriggerStep(db, pTrigger->step_list);
- sqlite3DbFree(db, pTrigger->zName);
- sqlite3DbFree(db, pTrigger->table);
- sqlite3ExprDelete(db, pTrigger->pWhen);
- sqlite3IdListDelete(db, pTrigger->pColumns);
- sqlite3DbFree(db, pTrigger);
-}
-
-/*
-** This function is called to drop a trigger from the database schema.
-**
-** This may be called directly from the parser and therefore identifies
-** the trigger by name. The sqlite3DropTriggerPtr() routine does the
-** same job as this routine except it takes a pointer to the trigger
-** instead of the trigger name.
-**/
-SQLITE_PRIVATE void sqlite3DropTrigger(Parse *pParse, SrcList *pName, int noErr){
- Trigger *pTrigger = 0;
- int i;
- const char *zDb;
- const char *zName;
- int nName;
- sqlite3 *db = pParse->db;
-
- if( db->mallocFailed ) goto drop_trigger_cleanup;
- if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
- goto drop_trigger_cleanup;
- }
-
- assert( pName->nSrc==1 );
- zDb = pName->a[0].zDatabase;
- zName = pName->a[0].zName;
- nName = sqlite3Strlen30(zName);
- for(i=OMIT_TEMPDB; i<db->nDb; i++){
- int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */
- if( zDb && sqlite3StrICmp(db->aDb[j].zName, zDb) ) continue;
- pTrigger = sqlite3HashFind(&(db->aDb[j].pSchema->trigHash), zName, nName);
- if( pTrigger ) break;
- }
- if( !pTrigger ){
- if( !noErr ){
- sqlite3ErrorMsg(pParse, "no such trigger: %S", pName, 0);
- }
- goto drop_trigger_cleanup;
- }
- sqlite3DropTriggerPtr(pParse, pTrigger);
-
-drop_trigger_cleanup:
- sqlite3SrcListDelete(db, pName);
-}
-
-/*
-** Return a pointer to the Table structure for the table that a trigger
-** is set on.
-*/
-static Table *tableOfTrigger(Trigger *pTrigger){
- int n = sqlite3Strlen30(pTrigger->table);
- return sqlite3HashFind(&pTrigger->pTabSchema->tblHash, pTrigger->table, n);
-}
-
-
-/*
-** Drop a trigger given a pointer to that trigger.
-*/
-SQLITE_PRIVATE void sqlite3DropTriggerPtr(Parse *pParse, Trigger *pTrigger){
- Table *pTable;
- Vdbe *v;
- sqlite3 *db = pParse->db;
- int iDb;
-
- iDb = sqlite3SchemaToIndex(pParse->db, pTrigger->pSchema);
- assert( iDb>=0 && iDb<db->nDb );
- pTable = tableOfTrigger(pTrigger);
- assert( pTable );
- assert( pTable->pSchema==pTrigger->pSchema || iDb==1 );
-#ifndef SQLITE_OMIT_AUTHORIZATION
- {
- int code = SQLITE_DROP_TRIGGER;
- const char *zDb = db->aDb[iDb].zName;
- const char *zTab = SCHEMA_TABLE(iDb);
- if( iDb==1 ) code = SQLITE_DROP_TEMP_TRIGGER;
- if( sqlite3AuthCheck(pParse, code, pTrigger->zName, pTable->zName, zDb) ||
- sqlite3AuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb) ){
- return;
- }
- }
-#endif
-
- /* Generate code to destroy the database record of the trigger.
- */
- assert( pTable!=0 );
- if( (v = sqlite3GetVdbe(pParse))!=0 ){
- int base;
- static const VdbeOpList dropTrigger[] = {
- { OP_Rewind, 0, ADDR(9), 0},
- { OP_String8, 0, 1, 0}, /* 1 */
- { OP_Column, 0, 1, 2},
- { OP_Ne, 2, ADDR(8), 1},
- { OP_String8, 0, 1, 0}, /* 4: "trigger" */
- { OP_Column, 0, 0, 2},
- { OP_Ne, 2, ADDR(8), 1},
- { OP_Delete, 0, 0, 0},
- { OP_Next, 0, ADDR(1), 0}, /* 8 */
- };
-
- sqlite3BeginWriteOperation(pParse, 0, iDb);
- sqlite3OpenMasterTable(pParse, iDb);
- base = sqlite3VdbeAddOpList(v, ArraySize(dropTrigger), dropTrigger);
- sqlite3VdbeChangeP4(v, base+1, pTrigger->zName, 0);
- sqlite3VdbeChangeP4(v, base+4, "trigger", P4_STATIC);
- sqlite3ChangeCookie(pParse, iDb);
- sqlite3VdbeAddOp2(v, OP_Close, 0, 0);
- sqlite3VdbeAddOp4(v, OP_DropTrigger, iDb, 0, 0, pTrigger->zName, 0);
- if( pParse->nMem<3 ){
- pParse->nMem = 3;
- }
- }
-}
-
-/*
-** Remove a trigger from the hash tables of the sqlite* pointer.
-*/
-SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTrigger(sqlite3 *db, int iDb, const char *zName){
- Hash *pHash = &(db->aDb[iDb].pSchema->trigHash);
- Trigger *pTrigger;
- pTrigger = sqlite3HashInsert(pHash, zName, sqlite3Strlen30(zName), 0);
- if( ALWAYS(pTrigger) ){
- if( pTrigger->pSchema==pTrigger->pTabSchema ){
- Table *pTab = tableOfTrigger(pTrigger);
- Trigger **pp;
- for(pp=&pTab->pTrigger; *pp!=pTrigger; pp=&((*pp)->pNext));
- *pp = (*pp)->pNext;
- }
- sqlite3DeleteTrigger(db, pTrigger);
- db->flags |= SQLITE_InternChanges;
- }
-}
-
-/*
-** pEList is the SET clause of an UPDATE statement. Each entry
-** in pEList is of the format <id>=<expr>. If any of the entries
-** in pEList have an <id> which matches an identifier in pIdList,
-** then return TRUE. If pIdList==NULL, then it is considered a
-** wildcard that matches anything. Likewise if pEList==NULL then
-** it matches anything so always return true. Return false only
-** if there is no match.
-*/
-static int checkColumnOverlap(IdList *pIdList, ExprList *pEList){
- int e;
- if( pIdList==0 || NEVER(pEList==0) ) return 1;
- for(e=0; e<pEList->nExpr; e++){
- if( sqlite3IdListIndex(pIdList, pEList->a[e].zName)>=0 ) return 1;
- }
- return 0;
-}
-
-/*
-** Return a list of all triggers on table pTab if there exists at least
-** one trigger that must be fired when an operation of type 'op' is
-** performed on the table, and, if that operation is an UPDATE, if at
-** least one of the columns in pChanges is being modified.
-*/
-SQLITE_PRIVATE Trigger *sqlite3TriggersExist(
- Parse *pParse, /* Parse context */
- Table *pTab, /* The table the contains the triggers */
- int op, /* one of TK_DELETE, TK_INSERT, TK_UPDATE */
- ExprList *pChanges, /* Columns that change in an UPDATE statement */
- int *pMask /* OUT: Mask of TRIGGER_BEFORE|TRIGGER_AFTER */
-){
- int mask = 0;
- Trigger *pList = sqlite3TriggerList(pParse, pTab);
- Trigger *p;
- assert( pList==0 || IsVirtual(pTab)==0 );
- for(p=pList; p; p=p->pNext){
- if( p->op==op && checkColumnOverlap(p->pColumns, pChanges) ){
- mask |= p->tr_tm;
- }
- }
- if( pMask ){
- *pMask = mask;
- }
- return (mask ? pList : 0);
-}
-
-/*
-** Convert the pStep->target token into a SrcList and return a pointer
-** to that SrcList.
-**
-** This routine adds a specific database name, if needed, to the target when
-** forming the SrcList. This prevents a trigger in one database from
-** referring to a target in another database. An exception is when the
-** trigger is in TEMP in which case it can refer to any other database it
-** wants.
-*/
-static SrcList *targetSrcList(
- Parse *pParse, /* The parsing context */
- TriggerStep *pStep /* The trigger containing the target token */
-){
- int iDb; /* Index of the database to use */
- SrcList *pSrc; /* SrcList to be returned */
-
- pSrc = sqlite3SrcListAppend(pParse->db, 0, &pStep->target, 0);
- if( pSrc ){
- assert( pSrc->nSrc>0 );
- assert( pSrc->a!=0 );
- iDb = sqlite3SchemaToIndex(pParse->db, pStep->pTrig->pSchema);
- if( iDb==0 || iDb>=2 ){
- sqlite3 *db = pParse->db;
- assert( iDb<pParse->db->nDb );
- pSrc->a[pSrc->nSrc-1].zDatabase = sqlite3DbStrDup(db, db->aDb[iDb].zName);
- }
- }
- return pSrc;
-}
-
-/*
-** Generate VDBE code for the statements inside the body of a single
-** trigger.
-*/
-static int codeTriggerProgram(
- Parse *pParse, /* The parser context */
- TriggerStep *pStepList, /* List of statements inside the trigger body */
- int orconf /* Conflict algorithm. (OE_Abort, etc) */
-){
- TriggerStep *pStep;
- Vdbe *v = pParse->pVdbe;
- sqlite3 *db = pParse->db;
-
- assert( pParse->pTriggerTab && pParse->pToplevel );
- assert( pStepList );
- assert( v!=0 );
- for(pStep=pStepList; pStep; pStep=pStep->pNext){
- /* Figure out the ON CONFLICT policy that will be used for this step
- ** of the trigger program. If the statement that caused this trigger
- ** to fire had an explicit ON CONFLICT, then use it. Otherwise, use
- ** the ON CONFLICT policy that was specified as part of the trigger
- ** step statement. Example:
- **
- ** CREATE TRIGGER AFTER INSERT ON t1 BEGIN;
- ** INSERT OR REPLACE INTO t2 VALUES(new.a, new.b);
- ** END;
- **
- ** INSERT INTO t1 ... ; -- insert into t2 uses REPLACE policy
- ** INSERT OR IGNORE INTO t1 ... ; -- insert into t2 uses IGNORE policy
- */
- pParse->eOrconf = (orconf==OE_Default)?pStep->orconf:(u8)orconf;
-
- switch( pStep->op ){
- case TK_UPDATE: {
- sqlite3Update(pParse,
- targetSrcList(pParse, pStep),
- sqlite3ExprListDup(db, pStep->pExprList, 0),
- sqlite3ExprDup(db, pStep->pWhere, 0),
- pParse->eOrconf
- );
- break;
- }
- case TK_INSERT: {
- sqlite3Insert(pParse,
- targetSrcList(pParse, pStep),
- sqlite3ExprListDup(db, pStep->pExprList, 0),
- sqlite3SelectDup(db, pStep->pSelect, 0),
- sqlite3IdListDup(db, pStep->pIdList),
- pParse->eOrconf
- );
- break;
- }
- case TK_DELETE: {
- sqlite3DeleteFrom(pParse,
- targetSrcList(pParse, pStep),
- sqlite3ExprDup(db, pStep->pWhere, 0)
- );
- break;
- }
- default: assert( pStep->op==TK_SELECT ); {
- SelectDest sDest;
- Select *pSelect = sqlite3SelectDup(db, pStep->pSelect, 0);
- sqlite3SelectDestInit(&sDest, SRT_Discard, 0);
- sqlite3Select(pParse, pSelect, &sDest);
- sqlite3SelectDelete(db, pSelect);
- break;
- }
- }
- if( pStep->op!=TK_SELECT ){
- sqlite3VdbeAddOp0(v, OP_ResetCount);
- }
- }
-
- return 0;
-}
-
-#ifdef SQLITE_DEBUG
-/*
-** This function is used to add VdbeComment() annotations to a VDBE
-** program. It is not used in production code, only for debugging.
-*/
-static const char *onErrorText(int onError){
- switch( onError ){
- case OE_Abort: return "abort";
- case OE_Rollback: return "rollback";
- case OE_Fail: return "fail";
- case OE_Replace: return "replace";
- case OE_Ignore: return "ignore";
- case OE_Default: return "default";
- }
- return "n/a";
-}
-#endif
-
-/*
-** Parse context structure pFrom has just been used to create a sub-vdbe
-** (trigger program). If an error has occurred, transfer error information
-** from pFrom to pTo.
-*/
-static void transferParseError(Parse *pTo, Parse *pFrom){
- assert( pFrom->zErrMsg==0 || pFrom->nErr );
- assert( pTo->zErrMsg==0 || pTo->nErr );
- if( pTo->nErr==0 ){
- pTo->zErrMsg = pFrom->zErrMsg;
- pTo->nErr = pFrom->nErr;
- }else{
- sqlite3DbFree(pFrom->db, pFrom->zErrMsg);
- }
-}
-
-/*
-** Create and populate a new TriggerPrg object with a sub-program
-** implementing trigger pTrigger with ON CONFLICT policy orconf.
-*/
-static TriggerPrg *codeRowTrigger(
- Parse *pParse, /* Current parse context */
- Trigger *pTrigger, /* Trigger to code */
- Table *pTab, /* The table pTrigger is attached to */
- int orconf /* ON CONFLICT policy to code trigger program with */
-){
- Parse *pTop = sqlite3ParseToplevel(pParse);
- sqlite3 *db = pParse->db; /* Database handle */
- TriggerPrg *pPrg; /* Value to return */
- Expr *pWhen = 0; /* Duplicate of trigger WHEN expression */
- Vdbe *v; /* Temporary VM */
- NameContext sNC; /* Name context for sub-vdbe */
- SubProgram *pProgram = 0; /* Sub-vdbe for trigger program */
- Parse *pSubParse; /* Parse context for sub-vdbe */
- int iEndTrigger = 0; /* Label to jump to if WHEN is false */
-
- assert( pTab==tableOfTrigger(pTrigger) );
-
- /* Allocate the TriggerPrg and SubProgram objects. To ensure that they
- ** are freed if an error occurs, link them into the Parse.pTriggerPrg
- ** list of the top-level Parse object sooner rather than later. */
- pPrg = sqlite3DbMallocZero(db, sizeof(TriggerPrg));
- if( !pPrg ) return 0;
- pPrg->pNext = pTop->pTriggerPrg;
- pTop->pTriggerPrg = pPrg;
- pPrg->pProgram = pProgram = sqlite3DbMallocZero(db, sizeof(SubProgram));
- if( !pProgram ) return 0;
- pProgram->nRef = 1;
- pPrg->pTrigger = pTrigger;
- pPrg->orconf = orconf;
-
- /* Allocate and populate a new Parse context to use for coding the
- ** trigger sub-program. */
- pSubParse = sqlite3StackAllocZero(db, sizeof(Parse));
- if( !pSubParse ) return 0;
- memset(&sNC, 0, sizeof(sNC));
- sNC.pParse = pSubParse;
- pSubParse->db = db;
- pSubParse->pTriggerTab = pTab;
- pSubParse->pToplevel = pTop;
- pSubParse->zAuthContext = pTrigger->zName;
- pSubParse->eTriggerOp = pTrigger->op;
-
- v = sqlite3GetVdbe(pSubParse);
- if( v ){
- VdbeComment((v, "Start: %s.%s (%s %s%s%s ON %s)",
- pTrigger->zName, onErrorText(orconf),
- (pTrigger->tr_tm==TRIGGER_BEFORE ? "BEFORE" : "AFTER"),
- (pTrigger->op==TK_UPDATE ? "UPDATE" : ""),
- (pTrigger->op==TK_INSERT ? "INSERT" : ""),
- (pTrigger->op==TK_DELETE ? "DELETE" : ""),
- pTab->zName
- ));
-#ifndef SQLITE_OMIT_TRACE
- sqlite3VdbeChangeP4(v, -1,
- sqlite3MPrintf(db, "-- TRIGGER %s", pTrigger->zName), P4_DYNAMIC
- );
-#endif
-
- /* If one was specified, code the WHEN clause. If it evaluates to false
- ** (or NULL) the sub-vdbe is immediately halted by jumping to the
- ** OP_Halt inserted at the end of the program. */
- if( pTrigger->pWhen ){
- pWhen = sqlite3ExprDup(db, pTrigger->pWhen, 0);
- if( SQLITE_OK==sqlite3ResolveExprNames(&sNC, pWhen)
- && db->mallocFailed==0
- ){
- iEndTrigger = sqlite3VdbeMakeLabel(v);
- sqlite3ExprIfFalse(pSubParse, pWhen, iEndTrigger, SQLITE_JUMPIFNULL);
- }
- sqlite3ExprDelete(db, pWhen);
- }
-
- /* Code the trigger program into the sub-vdbe. */
- codeTriggerProgram(pSubParse, pTrigger->step_list, orconf);
-
- /* Insert an OP_Halt at the end of the sub-program. */
- if( iEndTrigger ){
- sqlite3VdbeResolveLabel(v, iEndTrigger);
- }
- sqlite3VdbeAddOp0(v, OP_Halt);
- VdbeComment((v, "End: %s.%s", pTrigger->zName, onErrorText(orconf)));
-
- transferParseError(pParse, pSubParse);
- if( db->mallocFailed==0 ){
- pProgram->aOp = sqlite3VdbeTakeOpArray(v, &pProgram->nOp, &pTop->nMaxArg);
- }
- pProgram->nMem = pSubParse->nMem;
- pProgram->nCsr = pSubParse->nTab;
- pProgram->token = (void *)pTrigger;
- pPrg->oldmask = pSubParse->oldmask;
- sqlite3VdbeDelete(v);
- }
-
- assert( !pSubParse->pAinc && !pSubParse->pZombieTab );
- assert( !pSubParse->pTriggerPrg && !pSubParse->nMaxArg );
- sqlite3StackFree(db, pSubParse);
-
- return pPrg;
-}
-
-/*
-** Return a pointer to a TriggerPrg object containing the sub-program for
-** trigger pTrigger with default ON CONFLICT algorithm orconf. If no such
-** TriggerPrg object exists, a new object is allocated and populated before
-** being returned.
-*/
-static TriggerPrg *getRowTrigger(
- Parse *pParse, /* Current parse context */
- Trigger *pTrigger, /* Trigger to code */
- Table *pTab, /* The table trigger pTrigger is attached to */
- int orconf /* ON CONFLICT algorithm. */
-){
- Parse *pRoot = sqlite3ParseToplevel(pParse);
- TriggerPrg *pPrg;
-
- assert( pTab==tableOfTrigger(pTrigger) );
-
- /* It may be that this trigger has already been coded (or is in the
- ** process of being coded). If this is the case, then an entry with
- ** a matching TriggerPrg.pTrigger field will be present somewhere
- ** in the Parse.pTriggerPrg list. Search for such an entry. */
- for(pPrg=pRoot->pTriggerPrg;
- pPrg && (pPrg->pTrigger!=pTrigger || pPrg->orconf!=orconf);
- pPrg=pPrg->pNext
- );
-
- /* If an existing TriggerPrg could not be located, create a new one. */
- if( !pPrg ){
- pPrg = codeRowTrigger(pParse, pTrigger, pTab, orconf);
- }
-
- return pPrg;
-}
-
-/*
-** This is called to code FOR EACH ROW triggers.
-**
-** When the code that this function generates is executed, the following
-** must be true:
-**
-** 1. No cursors may be open in the main database. (But newIdx and oldIdx
-** can be indices of cursors in temporary tables. See below.)
-**
-** 2. If the triggers being coded are ON INSERT or ON UPDATE triggers, then
-** a temporary vdbe cursor (index newIdx) must be open and pointing at
-** a row containing values to be substituted for new.* expressions in the
-** trigger program(s).
-**
-** 3. If the triggers being coded are ON DELETE or ON UPDATE triggers, then
-** a temporary vdbe cursor (index oldIdx) must be open and pointing at
-** a row containing values to be substituted for old.* expressions in the
-** trigger program(s).
-**
-** If they are not NULL, the piOldColMask and piNewColMask output variables
-** are set to values that describe the columns used by the trigger program
-** in the OLD.* and NEW.* tables respectively. If column N of the
-** pseudo-table is read at least once, the corresponding bit of the output
-** mask is set. If a column with an index greater than 32 is read, the
-** output mask is set to the special value 0xffffffff.
-**
-*/
-SQLITE_PRIVATE void sqlite3CodeRowTrigger(
- Parse *pParse, /* Parse context */
- Trigger *pTrigger, /* List of triggers on table pTab */
- int op, /* One of TK_UPDATE, TK_INSERT, TK_DELETE */
- ExprList *pChanges, /* Changes list for any UPDATE OF triggers */
- int tr_tm, /* One of TRIGGER_BEFORE, TRIGGER_AFTER */
- Table *pTab, /* The table to code triggers from */
- int newIdx, /* The indice of the "new" row to access */
- int oldIdx, /* The indice of the "old" row to access */
- int orconf, /* ON CONFLICT policy */
- int ignoreJump /* Instruction to jump to for RAISE(IGNORE) */
-){
- Trigger *p;
-
- UNUSED_PARAMETER(newIdx);
-
- assert(op == TK_UPDATE || op == TK_INSERT || op == TK_DELETE);
- assert(tr_tm == TRIGGER_BEFORE || tr_tm == TRIGGER_AFTER );
-
- for(p=pTrigger; p; p=p->pNext){
-
- /* Sanity checking: The schema for the trigger and for the table are
- ** always defined. The trigger must be in the same schema as the table
- ** or else it must be a TEMP trigger. */
- assert( p->pSchema!=0 );
- assert( p->pTabSchema!=0 );
- assert( p->pSchema==p->pTabSchema
- || p->pSchema==pParse->db->aDb[1].pSchema );
-
- /* Determine whether we should code this trigger */
- if( p->op==op
- && p->tr_tm==tr_tm
- && checkColumnOverlap(p->pColumns,pChanges)
- ){
- Vdbe *v = sqlite3GetVdbe(pParse); /* Main VM */
- TriggerPrg *pPrg;
- pPrg = getRowTrigger(pParse, p, pTab, orconf);
- assert( pPrg || pParse->nErr || pParse->db->mallocFailed );
-
- /* Code the OP_Program opcode in the parent VDBE. P4 of the OP_Program
- ** is a pointer to the sub-vdbe containing the trigger program. */
- if( pPrg ){
- sqlite3VdbeAddOp3(v, OP_Program, oldIdx, ignoreJump, ++pParse->nMem);
- pPrg->pProgram->nRef++;
- sqlite3VdbeChangeP4(v, -1, (const char *)pPrg->pProgram, P4_SUBPROGRAM);
- VdbeComment((v, "Call: %s.%s", p->zName, onErrorText(orconf)));
- }
- }
- }
-}
-
-/*
-** Triggers fired by UPDATE or DELETE statements may access values stored
-** in the old.* pseudo-table. This function returns a 32-bit bitmask
-** indicating which columns of the old.* table actually are used by
-** triggers. This information may be used by the caller to avoid having
-** to load the entire old.* record into memory when executing an UPDATE
-** or DELETE command.
-**
-** Bit 0 of the returned mask is set if the left-most column of the
-** table may be accessed using an old.<col> reference. Bit 1 is set if
-** the second leftmost column value is required, and so on. If there
-** are more than 32 columns in the table, and at least one of the columns
-** with an index greater than 32 may be accessed, 0xffffffff is returned.
-**
-** It is not possible to determine if the old.rowid column is accessed
-** by triggers. The caller must always assume that it is.
-**
-** There is no equivalent function for new.* references.
-*/
-SQLITE_PRIVATE u32 sqlite3TriggerOldmask(
- Parse *pParse, /* Parse context */
- Trigger *pTrigger, /* List of triggers on table pTab */
- int op, /* Either TK_UPDATE or TK_DELETE */
- ExprList *pChanges, /* Changes list for any UPDATE OF triggers */
- Table *pTab, /* The table to code triggers from */
- int orconf /* Default ON CONFLICT policy for trigger steps */
-){
- u32 mask = 0;
- Trigger *p;
-
- assert(op==TK_UPDATE || op==TK_DELETE);
- for(p=pTrigger; p; p=p->pNext){
- if( p->op==op && checkColumnOverlap(p->pColumns,pChanges) ){
- TriggerPrg *pPrg;
- pPrg = getRowTrigger(pParse, p, pTab, orconf);
- if( pPrg ){
- mask |= pPrg->oldmask;
- }
- }
- }
-
- return mask;
-}
-
-#endif /* !defined(SQLITE_OMIT_TRIGGER) */
-
-/************** End of trigger.c *********************************************/
-/************** Begin file update.c ******************************************/
-/*
-** 2001 September 15
-**
-** 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 C code routines that are called by the parser
-** to handle UPDATE statements.
-**
-** $Id: update.c,v 1.207 2009/08/08 18:01:08 drh Exp $
-*/
-
-#ifndef SQLITE_OMIT_VIRTUALTABLE
-/* Forward declaration */
-static void updateVirtualTable(
- Parse *pParse, /* The parsing context */
- SrcList *pSrc, /* The virtual table to be modified */
- Table *pTab, /* The virtual table */
- ExprList *pChanges, /* The columns to change in the UPDATE statement */
- Expr *pRowidExpr, /* Expression used to recompute the rowid */
- int *aXRef, /* Mapping from columns of pTab to entries in pChanges */
- Expr *pWhere /* WHERE clause of the UPDATE statement */
-);
-#endif /* SQLITE_OMIT_VIRTUALTABLE */
-
-/*
-** The most recently coded instruction was an OP_Column to retrieve the
-** i-th column of table pTab. This routine sets the P4 parameter of the
-** OP_Column to the default value, if any.
-**
-** The default value of a column is specified by a DEFAULT clause in the
-** column definition. This was either supplied by the user when the table
-** was created, or added later to the table definition by an ALTER TABLE
-** command. If the latter, then the row-records in the table btree on disk
-** may not contain a value for the column and the default value, taken
-** from the P4 parameter of the OP_Column instruction, is returned instead.
-** If the former, then all row-records are guaranteed to include a value
-** for the column and the P4 value is not required.
-**
-** Column definitions created by an ALTER TABLE command may only have
-** literal default values specified: a number, null or a string. (If a more
-** complicated default expression value was provided, it is evaluated
-** when the ALTER TABLE is executed and one of the literal values written
-** into the sqlite_master table.)
-**
-** Therefore, the P4 parameter is only required if the default value for
-** the column is a literal number, string or null. The sqlite3ValueFromExpr()
-** function is capable of transforming these types of expressions into
-** sqlite3_value objects.
-**
-** If parameter iReg is not negative, code an OP_RealAffinity instruction
-** on register iReg. This is used when an equivalent integer value is
-** stored in place of an 8-byte floating point value in order to save
-** space.
-*/
-SQLITE_PRIVATE void sqlite3ColumnDefault(Vdbe *v, Table *pTab, int i, int iReg){
- assert( pTab!=0 );
- if( !pTab->pSelect ){
- sqlite3_value *pValue;
- u8 enc = ENC(sqlite3VdbeDb(v));
- Column *pCol = &pTab->aCol[i];
- VdbeComment((v, "%s.%s", pTab->zName, pCol->zName));
- assert( i<pTab->nCol );
- sqlite3ValueFromExpr(sqlite3VdbeDb(v), pCol->pDflt, enc,
- pCol->affinity, &pValue);
- if( pValue ){
- sqlite3VdbeChangeP4(v, -1, (const char *)pValue, P4_MEM);
- }
-#ifndef SQLITE_OMIT_FLOATING_POINT
- if( iReg>=0 && pTab->aCol[i].affinity==SQLITE_AFF_REAL ){
- sqlite3VdbeAddOp1(v, OP_RealAffinity, iReg);
- }
-#endif
- }
-}
-
-/*
-** Process an UPDATE statement.
-**
-** UPDATE OR IGNORE table_wxyz SET a=b, c=d WHERE e<5 AND f NOT NULL;
-** \_______/ \________/ \______/ \________________/
-* onError pTabList pChanges pWhere
-*/
-SQLITE_PRIVATE void sqlite3Update(
- Parse *pParse, /* The parser context */
- SrcList *pTabList, /* The table in which we should change things */
- ExprList *pChanges, /* Things to be changed */
- Expr *pWhere, /* The WHERE clause. May be null */
- int onError /* How to handle constraint errors */
-){
- int i, j; /* Loop counters */
- Table *pTab; /* The table to be updated */
- int addr = 0; /* VDBE instruction address of the start of the loop */
- WhereInfo *pWInfo; /* Information about the WHERE clause */
- Vdbe *v; /* The virtual database engine */
- Index *pIdx; /* For looping over indices */
- int nIdx; /* Number of indices that need updating */
- int iCur; /* VDBE Cursor number of pTab */
- sqlite3 *db; /* The database structure */
- int *aRegIdx = 0; /* One register assigned to each index to be updated */
- int *aXRef = 0; /* aXRef[i] is the index in pChanges->a[] of the
- ** an expression for the i-th column of the table.
- ** aXRef[i]==-1 if the i-th column is not changed. */
- int chngRowid; /* True if the record number is being changed */
- Expr *pRowidExpr = 0; /* Expression defining the new record number */
- int openAll = 0; /* True if all indices need to be opened */
- AuthContext sContext; /* The authorization context */
- NameContext sNC; /* The name-context to resolve expressions in */
- int iDb; /* Database containing the table being updated */
- int j1; /* Addresses of jump instructions */
- int okOnePass; /* True for one-pass algorithm without the FIFO */
-
-#ifndef SQLITE_OMIT_TRIGGER
- int isView; /* Trying to update a view */
- Trigger *pTrigger; /* List of triggers on pTab, if required */
-#endif
- u32 oldmask = 0; /* Mask of OLD.* columns in use */
-
- /* Register Allocations */
- int regRowCount = 0; /* A count of rows changed */
- int regOldRowid; /* The old rowid */
- int regNewRowid; /* The new rowid */
- int regNew;
- int regOld = 0;
- int regRowSet = 0; /* Rowset of rows to be updated */
- int regRec; /* Register used for new table record to insert */
-
- memset(&sContext, 0, sizeof(sContext));
- db = pParse->db;
- if( pParse->nErr || db->mallocFailed ){
- goto update_cleanup;
- }
- assert( pTabList->nSrc==1 );
-
- /* Locate the table which we want to update.
- */
- pTab = sqlite3SrcListLookup(pParse, pTabList);
- if( pTab==0 ) goto update_cleanup;
- iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
-
- /* Figure out if we have any triggers and if the table being
- ** updated is a view.
- */
-#ifndef SQLITE_OMIT_TRIGGER
- pTrigger = sqlite3TriggersExist(pParse, pTab, TK_UPDATE, pChanges, 0);
- isView = pTab->pSelect!=0;
-#else
-# define pTrigger 0
-# define isView 0
-#endif
-#ifdef SQLITE_OMIT_VIEW
-# undef isView
-# define isView 0
-#endif
-
- if( sqlite3ViewGetColumnNames(pParse, pTab) ){
- goto update_cleanup;
- }
- if( sqlite3IsReadOnly(pParse, pTab, (pTrigger?1:0)) ){
- goto update_cleanup;
- }
- aXRef = sqlite3DbMallocRaw(db, sizeof(int) * pTab->nCol );
- if( aXRef==0 ) goto update_cleanup;
- for(i=0; i<pTab->nCol; i++) aXRef[i] = -1;
-
- /* Allocate a cursors for the main database table and for all indices.
- ** The index cursors might not be used, but if they are used they
- ** need to occur right after the database cursor. So go ahead and
- ** allocate enough space, just in case.
- */
- pTabList->a[0].iCursor = iCur = pParse->nTab++;
- for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
- pParse->nTab++;
- }
-
- /* Initialize the name-context */
- memset(&sNC, 0, sizeof(sNC));
- sNC.pParse = pParse;
- sNC.pSrcList = pTabList;
-
- /* Resolve the column names in all the expressions of the
- ** of the UPDATE statement. Also find the column index
- ** for each column to be updated in the pChanges array. For each
- ** column to be updated, make sure we have authorization to change
- ** that column.
- */
- chngRowid = 0;
- for(i=0; i<pChanges->nExpr; i++){
- if( sqlite3ResolveExprNames(&sNC, pChanges->a[i].pExpr) ){
- goto update_cleanup;
- }
- for(j=0; j<pTab->nCol; j++){
- if( sqlite3StrICmp(pTab->aCol[j].zName, pChanges->a[i].zName)==0 ){
- if( j==pTab->iPKey ){
- chngRowid = 1;
- pRowidExpr = pChanges->a[i].pExpr;
- }
- aXRef[j] = i;
- break;
- }
- }
- if( j>=pTab->nCol ){
- if( sqlite3IsRowid(pChanges->a[i].zName) ){
- chngRowid = 1;
- pRowidExpr = pChanges->a[i].pExpr;
- }else{
- sqlite3ErrorMsg(pParse, "no such column: %s", pChanges->a[i].zName);
- goto update_cleanup;
- }
- }
-#ifndef SQLITE_OMIT_AUTHORIZATION
- {
- int rc;
- rc = sqlite3AuthCheck(pParse, SQLITE_UPDATE, pTab->zName,
- pTab->aCol[j].zName, db->aDb[iDb].zName);
- if( rc==SQLITE_DENY ){
- goto update_cleanup;
- }else if( rc==SQLITE_IGNORE ){
- aXRef[j] = -1;
- }
- }
-#endif
- }
-
- /* Allocate memory for the array aRegIdx[]. There is one entry in the
- ** array for each index associated with table being updated. Fill in
- ** the value with a register number for indices that are to be used
- ** and with zero for unused indices.
- */
- for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){}
- if( nIdx>0 ){
- aRegIdx = sqlite3DbMallocRaw(db, sizeof(Index*) * nIdx );
- if( aRegIdx==0 ) goto update_cleanup;
- }
- for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
- int reg;
- if( chngRowid ){
- reg = ++pParse->nMem;
- }else{
- reg = 0;
- for(i=0; i<pIdx->nColumn; i++){
- if( aXRef[pIdx->aiColumn[i]]>=0 ){
- reg = ++pParse->nMem;
- break;
- }
- }
- }
- aRegIdx[j] = reg;
- }
-
- /* Begin generating code. */
- v = sqlite3GetVdbe(pParse);
- if( v==0 ) goto update_cleanup;
- if( pParse->nested==0 ) sqlite3VdbeCountChanges(v);
- sqlite3BeginWriteOperation(pParse, 1, iDb);
-
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- /* Virtual tables must be handled separately */
- if( IsVirtual(pTab) ){
- updateVirtualTable(pParse, pTabList, pTab, pChanges, pRowidExpr, aXRef,
- pWhere);
- pWhere = 0;
- pTabList = 0;
- goto update_cleanup;
- }
-#endif
-
- /* Allocate required registers. */
- regOldRowid = regNewRowid = ++pParse->nMem;
- if( pTrigger ){
- regOld = pParse->nMem + 1;
- pParse->nMem += pTab->nCol;
- }
- if( chngRowid || pTrigger ){
- regNewRowid = ++pParse->nMem;
- }
- regNew = pParse->nMem + 1;
- pParse->nMem += pTab->nCol;
- regRec = ++pParse->nMem;
-
- /* Start the view context. */
- if( isView ){
- sqlite3AuthContextPush(pParse, &sContext, pTab->zName);
- }
-
- /* If there are any triggers, set oldmask and new_col_mask. */
- oldmask = sqlite3TriggerOldmask(
- pParse, pTrigger, TK_UPDATE, pChanges, pTab, onError);
-
- /* If we are trying to update a view, realize that view into
- ** a ephemeral table.
- */
-#if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER)
- if( isView ){
- sqlite3MaterializeView(pParse, pTab, pWhere, iCur);
- }
-#endif
-
- /* Resolve the column names in all the expressions in the
- ** WHERE clause.
- */
- if( sqlite3ResolveExprNames(&sNC, pWhere) ){
- goto update_cleanup;
- }
-
- /* Begin the database scan
- */
- sqlite3VdbeAddOp2(v, OP_Null, 0, regOldRowid);
- pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere,0, WHERE_ONEPASS_DESIRED);
- if( pWInfo==0 ) goto update_cleanup;
- okOnePass = pWInfo->okOnePass;
-
- /* Remember the rowid of every item to be updated.
- */
- sqlite3VdbeAddOp2(v, OP_Rowid, iCur, regOldRowid);
- if( !okOnePass ){
- regRowSet = ++pParse->nMem;
- sqlite3VdbeAddOp2(v, OP_RowSetAdd, regRowSet, regOldRowid);
- }
-
- /* End the database scan loop.
- */
- sqlite3WhereEnd(pWInfo);
-
- /* Initialize the count of updated rows
- */
- if( (db->flags & SQLITE_CountRows) && !pParse->pTriggerTab ){
- regRowCount = ++pParse->nMem;
- sqlite3VdbeAddOp2(v, OP_Integer, 0, regRowCount);
- }
-
- if( !isView ){
- /*
- ** Open every index that needs updating. Note that if any
- ** index could potentially invoke a REPLACE conflict resolution
- ** action, then we need to open all indices because we might need
- ** to be deleting some records.
- */
- if( !okOnePass ) sqlite3OpenTable(pParse, iCur, iDb, pTab, OP_OpenWrite);
- if( onError==OE_Replace ){
- openAll = 1;
- }else{
- openAll = 0;
- for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
- if( pIdx->onError==OE_Replace ){
- openAll = 1;
- break;
- }
- }
- }
- for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
- if( openAll || aRegIdx[i]>0 ){
- KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx);
- sqlite3VdbeAddOp4(v, OP_OpenWrite, iCur+i+1, pIdx->tnum, iDb,
- (char*)pKey, P4_KEYINFO_HANDOFF);
- assert( pParse->nTab>iCur+i+1 );
- }
- }
- }
-
- /* Top of the update loop */
- if( okOnePass ){
- int a1 = sqlite3VdbeAddOp1(v, OP_NotNull, regOldRowid);
- addr = sqlite3VdbeAddOp0(v, OP_Goto);
- sqlite3VdbeJumpHere(v, a1);
- }else{
- addr = sqlite3VdbeAddOp3(v, OP_RowSetRead, regRowSet, 0, regOldRowid);
- }
-
- /* Make cursor iCur point to the record that is being updated. If
- ** this record does not exist for some reason (deleted by a trigger,
- ** for example, then jump to the next iteration of the RowSet loop. */
- sqlite3VdbeAddOp3(v, OP_NotExists, iCur, addr, regOldRowid);
-
- /* If there are triggers on this table, populate an array of registers
- ** with the required old.* column data. */
- if( pTrigger ){
- for(i=0; i<pTab->nCol; i++){
- if( aXRef[i]<0 || oldmask==0xffffffff || (oldmask & (1<<i)) ){
- sqlite3VdbeAddOp3(v, OP_Column, iCur, i, regOld+i);
- sqlite3ColumnDefault(v, pTab, i, regOld+i);
- }else{
- sqlite3VdbeAddOp2(v, OP_Null, 0, regOld+i);
- }
- }
- }
-
- /* If the record number will change, set register regNewRowid to
- ** contain the new value. If the record number is not being modified,
- ** then regNewRowid is the same register as regOldRowid, which is
- ** already populated. */
- assert( chngRowid || pTrigger || regOldRowid==regNewRowid );
- if( chngRowid ){
- sqlite3ExprCode(pParse, pRowidExpr, regNewRowid);
- sqlite3VdbeAddOp1(v, OP_MustBeInt, regNewRowid);
- }else if( pTrigger ){
- sqlite3VdbeAddOp2(v, OP_Copy, regOldRowid, regNewRowid);
- }
-
- /* Populate the array of registers beginning at regNew with the new
- ** row data. This array is used to check constaints, create the new
- ** table and index records, and as the values for any new.* references
- ** made by triggers. */
- for(i=0; i<pTab->nCol; i++){
- if( i==pTab->iPKey ){
- sqlite3VdbeAddOp2(v, OP_Null, 0, regNew+i);
- }else{
- j = aXRef[i];
- if( j<0 ){
- sqlite3VdbeAddOp3(v, OP_Column, iCur, i, regNew+i);
- sqlite3ColumnDefault(v, pTab, i, regNew+i);
- }else{
- sqlite3ExprCode(pParse, pChanges->a[j].pExpr, regNew+i);
- }
- }
- }
-
- /* Fire any BEFORE UPDATE triggers. This happens before constraints are
- ** verified. One could argue that this is wrong. */
- if( pTrigger ){
- sqlite3VdbeAddOp2(v, OP_Affinity, regNew, pTab->nCol);
- sqlite3TableAffinityStr(v, pTab);
- sqlite3CodeRowTrigger(pParse, pTrigger, TK_UPDATE, pChanges,
- TRIGGER_BEFORE, pTab, -1, regOldRowid, onError, addr);
-
- /* The row-trigger may have deleted the row being updated. In this
- ** case, jump to the next row. No updates or AFTER triggers are
- ** required. This behaviour - what happens when the row being updated
- ** is deleted or renamed by a BEFORE trigger - is left undefined in the
- ** documentation. */
- sqlite3VdbeAddOp3(v, OP_NotExists, iCur, addr, regOldRowid);
- }
-
- if( !isView ){
-
- /* Do constraint checks. */
- sqlite3GenerateConstraintChecks(pParse, pTab, iCur, regNewRowid,
- aRegIdx, (chngRowid?regOldRowid:0), 1, onError, addr, 0);
-
- /* Delete the index entries associated with the current record. */
- j1 = sqlite3VdbeAddOp3(v, OP_NotExists, iCur, 0, regOldRowid);
- sqlite3GenerateRowIndexDelete(pParse, pTab, iCur, aRegIdx);
-
- /* If changing the record number, delete the old record. */
- if( chngRowid ){
- sqlite3VdbeAddOp2(v, OP_Delete, iCur, 0);
- }
- sqlite3VdbeJumpHere(v, j1);
-
- /* Insert the new index entries and the new record. */
- sqlite3CompleteInsertion(pParse, pTab, iCur, regNewRowid, aRegIdx, 1, 0, 0);
- }
-
- /* Increment the row counter
- */
- if( (db->flags & SQLITE_CountRows) && !pParse->pTriggerTab){
- sqlite3VdbeAddOp2(v, OP_AddImm, regRowCount, 1);
- }
-
- sqlite3CodeRowTrigger(pParse, pTrigger, TK_UPDATE, pChanges,
- TRIGGER_AFTER, pTab, -1, regOldRowid, onError, addr);
-
- /* Repeat the above with the next record to be updated, until
- ** all record selected by the WHERE clause have been updated.
- */
- sqlite3VdbeAddOp2(v, OP_Goto, 0, addr);
- sqlite3VdbeJumpHere(v, addr);
-
- /* Close all tables */
- for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
- if( openAll || aRegIdx[i]>0 ){
- sqlite3VdbeAddOp2(v, OP_Close, iCur+i+1, 0);
- }
- }
- sqlite3VdbeAddOp2(v, OP_Close, iCur, 0);
-
- /* Update the sqlite_sequence table by storing the content of the
- ** maximum rowid counter values recorded while inserting into
- ** autoincrement tables.
- */
- if( pParse->nested==0 && pParse->pTriggerTab==0 ){
- sqlite3AutoincrementEnd(pParse);
- }
-
- /*
- ** Return the number of rows that were changed. If this routine is
- ** generating code because of a call to sqlite3NestedParse(), do not
- ** invoke the callback function.
- */
- if( (db->flags&SQLITE_CountRows) && !pParse->pTriggerTab && !pParse->nested ){
- sqlite3VdbeAddOp2(v, OP_ResultRow, regRowCount, 1);
- sqlite3VdbeSetNumCols(v, 1);
- sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows updated", SQLITE_STATIC);
- }
-
-update_cleanup:
- sqlite3AuthContextPop(&sContext);
- sqlite3DbFree(db, aRegIdx);
- sqlite3DbFree(db, aXRef);
- sqlite3SrcListDelete(db, pTabList);
- sqlite3ExprListDelete(db, pChanges);
- sqlite3ExprDelete(db, pWhere);
- return;
-}
-
-#ifndef SQLITE_OMIT_VIRTUALTABLE
-/*
-** Generate code for an UPDATE of a virtual table.
-**
-** The strategy is that we create an ephemerial table that contains
-** for each row to be changed:
-**
-** (A) The original rowid of that row.
-** (B) The revised rowid for the row. (note1)
-** (C) The content of every column in the row.
-**
-** Then we loop over this ephemeral table and for each row in
-** the ephermeral table call VUpdate.
-**
-** When finished, drop the ephemeral table.
-**
-** (note1) Actually, if we know in advance that (A) is always the same
-** as (B) we only store (A), then duplicate (A) when pulling
-** it out of the ephemeral table before calling VUpdate.
-*/
-static void updateVirtualTable(
- Parse *pParse, /* The parsing context */
- SrcList *pSrc, /* The virtual table to be modified */
- Table *pTab, /* The virtual table */
- ExprList *pChanges, /* The columns to change in the UPDATE statement */
- Expr *pRowid, /* Expression used to recompute the rowid */
- int *aXRef, /* Mapping from columns of pTab to entries in pChanges */
- Expr *pWhere /* WHERE clause of the UPDATE statement */
-){
- Vdbe *v = pParse->pVdbe; /* Virtual machine under construction */
- ExprList *pEList = 0; /* The result set of the SELECT statement */
- Select *pSelect = 0; /* The SELECT statement */
- Expr *pExpr; /* Temporary expression */
- int ephemTab; /* Table holding the result of the SELECT */
- int i; /* Loop counter */
- int addr; /* Address of top of loop */
- int iReg; /* First register in set passed to OP_VUpdate */
- sqlite3 *db = pParse->db; /* Database connection */
- const char *pVTab = (const char*)sqlite3GetVTable(db, pTab);
- SelectDest dest;
-
- /* Construct the SELECT statement that will find the new values for
- ** all updated rows.
- */
- pEList = sqlite3ExprListAppend(pParse, 0,
- sqlite3CreateIdExpr(pParse, "_rowid_"));
- if( pRowid ){
- pEList = sqlite3ExprListAppend(pParse, pEList,
- sqlite3ExprDup(db, pRowid, 0));
- }
- assert( pTab->iPKey<0 );
- for(i=0; i<pTab->nCol; i++){
- if( aXRef[i]>=0 ){
- pExpr = sqlite3ExprDup(db, pChanges->a[aXRef[i]].pExpr, 0);
- }else{
- pExpr = sqlite3CreateIdExpr(pParse, pTab->aCol[i].zName);
- }
- pEList = sqlite3ExprListAppend(pParse, pEList, pExpr);
- }
- pSelect = sqlite3SelectNew(pParse, pEList, pSrc, pWhere, 0, 0, 0, 0, 0, 0);
-
- /* Create the ephemeral table into which the update results will
- ** be stored.
- */
- assert( v );
- ephemTab = pParse->nTab++;
- sqlite3VdbeAddOp2(v, OP_OpenEphemeral, ephemTab, pTab->nCol+1+(pRowid!=0));
-
- /* fill the ephemeral table
- */
- sqlite3SelectDestInit(&dest, SRT_Table, ephemTab);
- sqlite3Select(pParse, pSelect, &dest);
-
- /* Generate code to scan the ephemeral table and call VUpdate. */
- iReg = ++pParse->nMem;
- pParse->nMem += pTab->nCol+1;
- addr = sqlite3VdbeAddOp2(v, OP_Rewind, ephemTab, 0);
- sqlite3VdbeAddOp3(v, OP_Column, ephemTab, 0, iReg);
- sqlite3VdbeAddOp3(v, OP_Column, ephemTab, (pRowid?1:0), iReg+1);
- for(i=0; i<pTab->nCol; i++){
- sqlite3VdbeAddOp3(v, OP_Column, ephemTab, i+1+(pRowid!=0), iReg+2+i);
- }
- sqlite3VtabMakeWritable(pParse, pTab);
- sqlite3VdbeAddOp4(v, OP_VUpdate, 0, pTab->nCol+2, iReg, pVTab, P4_VTAB);
- sqlite3MayAbort(pParse);
- sqlite3VdbeAddOp2(v, OP_Next, ephemTab, addr+1);
- sqlite3VdbeJumpHere(v, addr);
- sqlite3VdbeAddOp2(v, OP_Close, ephemTab, 0);
-
- /* Cleanup */
- sqlite3SelectDelete(db, pSelect);
-}
-#endif /* SQLITE_OMIT_VIRTUALTABLE */
-
-/* Make sure "isView" gets undefined in case this file becomes part of
-** the amalgamation - so that subsequent files do not see isView as a
-** macro. */
-#undef isView
-
-/************** End of update.c **********************************************/
-/************** Begin file vacuum.c ******************************************/
-/*
-** 2003 April 6
-**
-** 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 code used to implement the VACUUM command.
-**
-** Most of the code in this file may be omitted by defining the
-** SQLITE_OMIT_VACUUM macro.
-**
-** $Id: vacuum.c,v 1.91 2009/07/02 07:47:33 danielk1977 Exp $
-*/
-
-#if !defined(SQLITE_OMIT_VACUUM) && !defined(SQLITE_OMIT_ATTACH)
-/*
-** Execute zSql on database db. Return an error code.
-*/
-static int execSql(sqlite3 *db, const char *zSql){
- sqlite3_stmt *pStmt;
- VVA_ONLY( int rc; )
- if( !zSql ){
- return SQLITE_NOMEM;
- }
- if( SQLITE_OK!=sqlite3_prepare(db, zSql, -1, &pStmt, 0) ){
- return sqlite3_errcode(db);
- }
- VVA_ONLY( rc = ) sqlite3_step(pStmt);
- assert( rc!=SQLITE_ROW );
- return sqlite3_finalize(pStmt);
-}
-
-/*
-** Execute zSql on database db. The statement returns exactly
-** one column. Execute this as SQL on the same database.
-*/
-static int execExecSql(sqlite3 *db, const char *zSql){
- sqlite3_stmt *pStmt;
- int rc;
-
- rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0);
- if( rc!=SQLITE_OK ) return rc;
-
- while( SQLITE_ROW==sqlite3_step(pStmt) ){
- rc = execSql(db, (char*)sqlite3_column_text(pStmt, 0));
- if( rc!=SQLITE_OK ){
- sqlite3_finalize(pStmt);
- return rc;
- }
- }
-
- return sqlite3_finalize(pStmt);
-}
-
-/*
-** The non-standard VACUUM command is used to clean up the database,
-** collapse free space, etc. It is modelled after the VACUUM command
-** in PostgreSQL.
-**
-** In version 1.0.x of SQLite, the VACUUM command would call
-** gdbm_reorganize() on all the database tables. But beginning
-** with 2.0.0, SQLite no longer uses GDBM so this command has
-** become a no-op.
-*/
-SQLITE_PRIVATE void sqlite3Vacuum(Parse *pParse){
- Vdbe *v = sqlite3GetVdbe(pParse);
- if( v ){
- sqlite3VdbeAddOp2(v, OP_Vacuum, 0, 0);
- }
- return;
-}
-
-/*
-** This routine implements the OP_Vacuum opcode of the VDBE.
-*/
-SQLITE_PRIVATE int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){
- int rc = SQLITE_OK; /* Return code from service routines */
- Btree *pMain; /* The database being vacuumed */
- Btree *pTemp; /* The temporary database we vacuum into */
- char *zSql = 0; /* SQL statements */
- int saved_flags; /* Saved value of the db->flags */
- int saved_nChange; /* Saved value of db->nChange */
- int saved_nTotalChange; /* Saved value of db->nTotalChange */
- Db *pDb = 0; /* Database to detach at end of vacuum */
- int isMemDb; /* True if vacuuming a :memory: database */
- int nRes;
-
- if( !db->autoCommit ){
- sqlite3SetString(pzErrMsg, db, "cannot VACUUM from within a transaction");
- return SQLITE_ERROR;
- }
-
- /* Save the current value of the write-schema flag before setting it. */
- saved_flags = db->flags;
- saved_nChange = db->nChange;
- saved_nTotalChange = db->nTotalChange;
- db->flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks;
-
- pMain = db->aDb[0].pBt;
- isMemDb = sqlite3PagerIsMemdb(sqlite3BtreePager(pMain));
-
- /* Attach the temporary database as 'vacuum_db'. The synchronous pragma
- ** can be set to 'off' for this file, as it is not recovered if a crash
- ** occurs anyway. The integrity of the database is maintained by a
- ** (possibly synchronous) transaction opened on the main database before
- ** sqlite3BtreeCopyFile() is called.
- **
- ** An optimisation would be to use a non-journaled pager.
- ** (Later:) I tried setting "PRAGMA vacuum_db.journal_mode=OFF" but
- ** that actually made the VACUUM run slower. Very little journalling
- ** actually occurs when doing a vacuum since the vacuum_db is initially
- ** empty. Only the journal header is written. Apparently it takes more
- ** time to parse and run the PRAGMA to turn journalling off than it does
- ** to write the journal header file.
- */
- zSql = "ATTACH '' AS vacuum_db;";
- rc = execSql(db, zSql);
- if( rc!=SQLITE_OK ) goto end_of_vacuum;
- pDb = &db->aDb[db->nDb-1];
- assert( strcmp(db->aDb[db->nDb-1].zName,"vacuum_db")==0 );
- pTemp = db->aDb[db->nDb-1].pBt;
-
- nRes = sqlite3BtreeGetReserve(pMain);
-
- /* A VACUUM cannot change the pagesize of an encrypted database. */
-#ifdef SQLITE_HAS_CODEC
- if( db->nextPagesize ){
- extern void sqlite3CodecGetKey(sqlite3*, int, void**, int*);
- int nKey;
- char *zKey;
- sqlite3CodecGetKey(db, 0, (void**)&zKey, &nKey);
- if( nKey ) db->nextPagesize = 0;
- }
-#endif
-
- if( sqlite3BtreeSetPageSize(pTemp, sqlite3BtreeGetPageSize(pMain), nRes, 0)
- || (!isMemDb && sqlite3BtreeSetPageSize(pTemp, db->nextPagesize, nRes, 0))
- || NEVER(db->mallocFailed)
- ){
- rc = SQLITE_NOMEM;
- goto end_of_vacuum;
- }
- rc = execSql(db, "PRAGMA vacuum_db.synchronous=OFF");
- if( rc!=SQLITE_OK ){
- goto end_of_vacuum;
- }
-
-#ifndef SQLITE_OMIT_AUTOVACUUM
- sqlite3BtreeSetAutoVacuum(pTemp, db->nextAutovac>=0 ? db->nextAutovac :
- sqlite3BtreeGetAutoVacuum(pMain));
-#endif
-
- /* Begin a transaction */
- rc = execSql(db, "BEGIN EXCLUSIVE;");
- if( rc!=SQLITE_OK ) goto end_of_vacuum;
-
- /* Query the schema of the main database. Create a mirror schema
- ** in the temporary database.
- */
- rc = execExecSql(db,
- "SELECT 'CREATE TABLE vacuum_db.' || substr(sql,14) "
- " FROM sqlite_master WHERE type='table' AND name!='sqlite_sequence'"
- " AND rootpage>0"
- );
- if( rc!=SQLITE_OK ) goto end_of_vacuum;
- rc = execExecSql(db,
- "SELECT 'CREATE INDEX vacuum_db.' || substr(sql,14)"
- " FROM sqlite_master WHERE sql LIKE 'CREATE INDEX %' ");
- if( rc!=SQLITE_OK ) goto end_of_vacuum;
- rc = execExecSql(db,
- "SELECT 'CREATE UNIQUE INDEX vacuum_db.' || substr(sql,21) "
- " FROM sqlite_master WHERE sql LIKE 'CREATE UNIQUE INDEX %'");
- if( rc!=SQLITE_OK ) goto end_of_vacuum;
-
- /* Loop through the tables in the main database. For each, do
- ** an "INSERT INTO vacuum_db.xxx SELECT * FROM xxx;" to copy
- ** the contents to the temporary database.
- */
- rc = execExecSql(db,
- "SELECT 'INSERT INTO vacuum_db.' || quote(name) "
- "|| ' SELECT * FROM ' || quote(name) || ';'"
- "FROM sqlite_master "
- "WHERE type = 'table' AND name!='sqlite_sequence' "
- " AND rootpage>0"
-
- );
- if( rc!=SQLITE_OK ) goto end_of_vacuum;
-
- /* Copy over the sequence table
- */
- rc = execExecSql(db,
- "SELECT 'DELETE FROM vacuum_db.' || quote(name) || ';' "
- "FROM vacuum_db.sqlite_master WHERE name='sqlite_sequence' "
- );
- if( rc!=SQLITE_OK ) goto end_of_vacuum;
- rc = execExecSql(db,
- "SELECT 'INSERT INTO vacuum_db.' || quote(name) "
- "|| ' SELECT * FROM ' || quote(name) || ';' "
- "FROM vacuum_db.sqlite_master WHERE name=='sqlite_sequence';"
- );
- if( rc!=SQLITE_OK ) goto end_of_vacuum;
-
-
- /* Copy the triggers, views, and virtual tables from the main database
- ** over to the temporary database. None of these objects has any
- ** associated storage, so all we have to do is copy their entries
- ** from the SQLITE_MASTER table.
- */
- rc = execSql(db,
- "INSERT INTO vacuum_db.sqlite_master "
- " SELECT type, name, tbl_name, rootpage, sql"
- " FROM sqlite_master"
- " WHERE type='view' OR type='trigger'"
- " OR (type='table' AND rootpage=0)"
- );
- if( rc ) goto end_of_vacuum;
-
- /* At this point, unless the main db was completely empty, there is now a
- ** transaction open on the vacuum database, but not on the main database.
- ** Open a btree level transaction on the main database. This allows a
- ** call to sqlite3BtreeCopyFile(). The main database btree level
- ** transaction is then committed, so the SQL level never knows it was
- ** opened for writing. This way, the SQL transaction used to create the
- ** temporary database never needs to be committed.
- */
- {
- u32 meta;
- int i;
-
- /* This array determines which meta meta values are preserved in the
- ** vacuum. Even entries are the meta value number and odd entries
- ** are an increment to apply to the meta value after the vacuum.
- ** The increment is used to increase the schema cookie so that other
- ** connections to the same database will know to reread the schema.
- */
- static const unsigned char aCopy[] = {
- BTREE_SCHEMA_VERSION, 1, /* Add one to the old schema cookie */
- BTREE_DEFAULT_CACHE_SIZE, 0, /* Preserve the default page cache size */
- BTREE_TEXT_ENCODING, 0, /* Preserve the text encoding */
- BTREE_USER_VERSION, 0, /* Preserve the user version */
- };
-
- assert( 1==sqlite3BtreeIsInTrans(pTemp) );
- assert( 1==sqlite3BtreeIsInTrans(pMain) );
-
- /* Copy Btree meta values */
- for(i=0; i<ArraySize(aCopy); i+=2){
- /* GetMeta() and UpdateMeta() cannot fail in this context because
- ** we already have page 1 loaded into cache and marked dirty. */
- sqlite3BtreeGetMeta(pMain, aCopy[i], &meta);
- rc = sqlite3BtreeUpdateMeta(pTemp, aCopy[i], meta+aCopy[i+1]);
- if( NEVER(rc!=SQLITE_OK) ) goto end_of_vacuum;
- }
-
- rc = sqlite3BtreeCopyFile(pMain, pTemp);
- if( rc!=SQLITE_OK ) goto end_of_vacuum;
- rc = sqlite3BtreeCommit(pTemp);
- if( rc!=SQLITE_OK ) goto end_of_vacuum;
-#ifndef SQLITE_OMIT_AUTOVACUUM
- sqlite3BtreeSetAutoVacuum(pMain, sqlite3BtreeGetAutoVacuum(pTemp));
-#endif
- }
-
- assert( rc==SQLITE_OK );
- rc = sqlite3BtreeSetPageSize(pMain, sqlite3BtreeGetPageSize(pTemp), nRes,1);
-
-end_of_vacuum:
- /* Restore the original value of db->flags */
- db->flags = saved_flags;
- db->nChange = saved_nChange;
- db->nTotalChange = saved_nTotalChange;
-
- /* Currently there is an SQL level transaction open on the vacuum
- ** database. No locks are held on any other files (since the main file
- ** was committed at the btree level). So it safe to end the transaction
- ** by manually setting the autoCommit flag to true and detaching the
- ** vacuum database. The vacuum_db journal file is deleted when the pager
- ** is closed by the DETACH.
- */
- db->autoCommit = 1;
-
- if( pDb ){
- sqlite3BtreeClose(pDb->pBt);
- pDb->pBt = 0;
- pDb->pSchema = 0;
- }
-
- sqlite3ResetInternalSchema(db, 0);
-
- return rc;
-}
-#endif /* SQLITE_OMIT_VACUUM && SQLITE_OMIT_ATTACH */
-
-/************** End of vacuum.c **********************************************/
-/************** Begin file vtab.c ********************************************/
-/*
-** 2006 June 10
-**
-** 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 code used to help implement virtual tables.
-**
-** $Id: vtab.c,v 1.94 2009/08/08 18:01:08 drh Exp $
-*/
-#ifndef SQLITE_OMIT_VIRTUALTABLE
-
-/*
-** The actual function that does the work of creating a new module.
-** This function implements the sqlite3_create_module() and
-** sqlite3_create_module_v2() interfaces.
-*/
-static int createModule(
- sqlite3 *db, /* Database in which module is registered */
- const char *zName, /* Name assigned to this module */
- const sqlite3_module *pModule, /* The definition of the module */
- void *pAux, /* Context pointer for xCreate/xConnect */
- void (*xDestroy)(void *) /* Module destructor function */
-){
- int rc, nName;
- Module *pMod;
-
- sqlite3_mutex_enter(db->mutex);
- nName = sqlite3Strlen30(zName);
- pMod = (Module *)sqlite3DbMallocRaw(db, sizeof(Module) + nName + 1);
- if( pMod ){
- Module *pDel;
- char *zCopy = (char *)(&pMod[1]);
- memcpy(zCopy, zName, nName+1);
- pMod->zName = zCopy;
- pMod->pModule = pModule;
- pMod->pAux = pAux;
- pMod->xDestroy = xDestroy;
- pDel = (Module *)sqlite3HashInsert(&db->aModule, zCopy, nName, (void*)pMod);
- if( pDel && pDel->xDestroy ){
- pDel->xDestroy(pDel->pAux);
- }
- sqlite3DbFree(db, pDel);
- if( pDel==pMod ){
- db->mallocFailed = 1;
- }
- sqlite3ResetInternalSchema(db, 0);
- }else if( xDestroy ){
- xDestroy(pAux);
- }
- rc = sqlite3ApiExit(db, SQLITE_OK);
- sqlite3_mutex_leave(db->mutex);
- return rc;
-}
-
-
-/*
-** External API function used to create a new virtual-table module.
-*/
-SQLITE_API int sqlite3_create_module(
- sqlite3 *db, /* Database in which module is registered */
- const char *zName, /* Name assigned to this module */
- const sqlite3_module *pModule, /* The definition of the module */
- void *pAux /* Context pointer for xCreate/xConnect */
-){
- return createModule(db, zName, pModule, pAux, 0);
-}
-
-/*
-** External API function used to create a new virtual-table module.
-*/
-SQLITE_API int sqlite3_create_module_v2(
- sqlite3 *db, /* Database in which module is registered */
- const char *zName, /* Name assigned to this module */
- const sqlite3_module *pModule, /* The definition of the module */
- void *pAux, /* Context pointer for xCreate/xConnect */
- void (*xDestroy)(void *) /* Module destructor function */
-){
- return createModule(db, zName, pModule, pAux, xDestroy);
-}
-
-/*
-** Lock the virtual table so that it cannot be disconnected.
-** Locks nest. Every lock should have a corresponding unlock.
-** If an unlock is omitted, resources leaks will occur.
-**
-** If a disconnect is attempted while a virtual table is locked,
-** the disconnect is deferred until all locks have been removed.
-*/
-SQLITE_PRIVATE void sqlite3VtabLock(VTable *pVTab){
- pVTab->nRef++;
-}
-
-
-/*
-** pTab is a pointer to a Table structure representing a virtual-table.
-** Return a pointer to the VTable object used by connection db to access
-** this virtual-table, if one has been created, or NULL otherwise.
-*/
-SQLITE_PRIVATE VTable *sqlite3GetVTable(sqlite3 *db, Table *pTab){
- VTable *pVtab;
- assert( IsVirtual(pTab) );
- for(pVtab=pTab->pVTable; pVtab && pVtab->db!=db; pVtab=pVtab->pNext);
- return pVtab;
-}
-
-/*
-** Decrement the ref-count on a virtual table object. When the ref-count
-** reaches zero, call the xDisconnect() method to delete the object.
-*/
-SQLITE_PRIVATE void sqlite3VtabUnlock(VTable *pVTab){
- sqlite3 *db = pVTab->db;
-
- assert( db );
- assert( pVTab->nRef>0 );
- assert( sqlite3SafetyCheckOk(db) );
-
- pVTab->nRef--;
- if( pVTab->nRef==0 ){
- sqlite3_vtab *p = pVTab->pVtab;
- if( p ){
-#ifdef SQLITE_DEBUG
- if( pVTab->db->magic==SQLITE_MAGIC_BUSY ){
- (void)sqlite3SafetyOff(db);
- p->pModule->xDisconnect(p);
- (void)sqlite3SafetyOn(db);
- } else
-#endif
- {
- p->pModule->xDisconnect(p);
- }
- }
- sqlite3DbFree(db, pVTab);
- }
-}
-
-/*
-** Table p is a virtual table. This function moves all elements in the
-** p->pVTable list to the sqlite3.pDisconnect lists of their associated
-** database connections to be disconnected at the next opportunity.
-** Except, if argument db is not NULL, then the entry associated with
-** connection db is left in the p->pVTable list.
-*/
-static VTable *vtabDisconnectAll(sqlite3 *db, Table *p){
- VTable *pRet = 0;
- VTable *pVTable = p->pVTable;
- p->pVTable = 0;
-
- /* Assert that the mutex (if any) associated with the BtShared database
- ** that contains table p is held by the caller. See header comments
- ** above function sqlite3VtabUnlockList() for an explanation of why
- ** this makes it safe to access the sqlite3.pDisconnect list of any
- ** database connection that may have an entry in the p->pVTable list. */
- assert( db==0 ||
- sqlite3BtreeHoldsMutex(db->aDb[sqlite3SchemaToIndex(db, p->pSchema)].pBt)
- );
-
- while( pVTable ){
- sqlite3 *db2 = pVTable->db;
- VTable *pNext = pVTable->pNext;
- assert( db2 );
- if( db2==db ){
- pRet = pVTable;
- p->pVTable = pRet;
- pRet->pNext = 0;
- }else{
- pVTable->pNext = db2->pDisconnect;
- db2->pDisconnect = pVTable;
- }
- pVTable = pNext;
- }
-
- assert( !db || pRet );
- return pRet;
-}
-
-
-/*
-** Disconnect all the virtual table objects in the sqlite3.pDisconnect list.
-**
-** This function may only be called when the mutexes associated with all
-** shared b-tree databases opened using connection db are held by the
-** caller. This is done to protect the sqlite3.pDisconnect list. The
-** sqlite3.pDisconnect list is accessed only as follows:
-**
-** 1) By this function. In this case, all BtShared mutexes and the mutex
-** associated with the database handle itself must be held.
-**
-** 2) By function vtabDisconnectAll(), when it adds a VTable entry to
-** the sqlite3.pDisconnect list. In this case either the BtShared mutex
-** associated with the database the virtual table is stored in is held
-** or, if the virtual table is stored in a non-sharable database, then
-** the database handle mutex is held.
-**
-** As a result, a sqlite3.pDisconnect cannot be accessed simultaneously
-** by multiple threads. It is thread-safe.
-*/
-SQLITE_PRIVATE void sqlite3VtabUnlockList(sqlite3 *db){
- VTable *p = db->pDisconnect;
- db->pDisconnect = 0;
-
- assert( sqlite3BtreeHoldsAllMutexes(db) );
- assert( sqlite3_mutex_held(db->mutex) );
-
- if( p ){
- sqlite3ExpirePreparedStatements(db);
- do {
- VTable *pNext = p->pNext;
- sqlite3VtabUnlock(p);
- p = pNext;
- }while( p );
- }
-}
-
-/*
-** Clear any and all virtual-table information from the Table record.
-** This routine is called, for example, just before deleting the Table
-** record.
-**
-** Since it is a virtual-table, the Table structure contains a pointer
-** to the head of a linked list of VTable structures. Each VTable
-** structure is associated with a single sqlite3* user of the schema.
-** The reference count of the VTable structure associated with database
-** connection db is decremented immediately (which may lead to the
-** structure being xDisconnected and free). Any other VTable structures
-** in the list are moved to the sqlite3.pDisconnect list of the associated
-** database connection.
-*/
-SQLITE_PRIVATE void sqlite3VtabClear(Table *p){
- vtabDisconnectAll(0, p);
- if( p->azModuleArg ){
- int i;
- for(i=0; i<p->nModuleArg; i++){
- sqlite3DbFree(p->dbMem, p->azModuleArg[i]);
- }
- sqlite3DbFree(p->dbMem, p->azModuleArg);
- }
-}
-
-/*
-** Add a new module argument to pTable->azModuleArg[].
-** The string is not copied - the pointer is stored. The
-** string will be freed automatically when the table is
-** deleted.
-*/
-static void addModuleArgument(sqlite3 *db, Table *pTable, char *zArg){
- int i = pTable->nModuleArg++;
- int nBytes = sizeof(char *)*(1+pTable->nModuleArg);
- char **azModuleArg;
- azModuleArg = sqlite3DbRealloc(db, pTable->azModuleArg, nBytes);
- if( azModuleArg==0 ){
- int j;
- for(j=0; j<i; j++){
- sqlite3DbFree(db, pTable->azModuleArg[j]);
- }
- sqlite3DbFree(db, zArg);
- sqlite3DbFree(db, pTable->azModuleArg);
- pTable->nModuleArg = 0;
- }else{
- azModuleArg[i] = zArg;
- azModuleArg[i+1] = 0;
- }
- pTable->azModuleArg = azModuleArg;
-}
-
-/*
-** The parser calls this routine when it first sees a CREATE VIRTUAL TABLE
-** statement. The module name has been parsed, but the optional list
-** of parameters that follow the module name are still pending.
-*/
-SQLITE_PRIVATE void sqlite3VtabBeginParse(
- Parse *pParse, /* Parsing context */
- Token *pName1, /* Name of new table, or database name */
- Token *pName2, /* Name of new table or NULL */
- Token *pModuleName /* Name of the module for the virtual table */
-){
- int iDb; /* The database the table is being created in */
- Table *pTable; /* The new virtual table */
- sqlite3 *db; /* Database connection */
-
- sqlite3StartTable(pParse, pName1, pName2, 0, 0, 1, 0);
- pTable = pParse->pNewTable;
- if( pTable==0 ) return;
- assert( 0==pTable->pIndex );
-
- db = pParse->db;
- iDb = sqlite3SchemaToIndex(db, pTable->pSchema);
- assert( iDb>=0 );
-
- pTable->tabFlags |= TF_Virtual;
- pTable->nModuleArg = 0;
- addModuleArgument(db, pTable, sqlite3NameFromToken(db, pModuleName));
- addModuleArgument(db, pTable, sqlite3DbStrDup(db, db->aDb[iDb].zName));
- addModuleArgument(db, pTable, sqlite3DbStrDup(db, pTable->zName));
- pParse->sNameToken.n = (int)(&pModuleName->z[pModuleName->n] - pName1->z);
-
-#ifndef SQLITE_OMIT_AUTHORIZATION
- /* Creating a virtual table invokes the authorization callback twice.
- ** The first invocation, to obtain permission to INSERT a row into the
- ** sqlite_master table, has already been made by sqlite3StartTable().
- ** The second call, to obtain permission to create the table, is made now.
- */
- if( pTable->azModuleArg ){
- sqlite3AuthCheck(pParse, SQLITE_CREATE_VTABLE, pTable->zName,
- pTable->azModuleArg[0], pParse->db->aDb[iDb].zName);
- }
-#endif
-}
-
-/*
-** This routine takes the module argument that has been accumulating
-** in pParse->zArg[] and appends it to the list of arguments on the
-** virtual table currently under construction in pParse->pTable.
-*/
-static void addArgumentToVtab(Parse *pParse){
- if( pParse->sArg.z && ALWAYS(pParse->pNewTable) ){
- const char *z = (const char*)pParse->sArg.z;
- int n = pParse->sArg.n;
- sqlite3 *db = pParse->db;
- addModuleArgument(db, pParse->pNewTable, sqlite3DbStrNDup(db, z, n));
- }
-}
-
-/*
-** The parser calls this routine after the CREATE VIRTUAL TABLE statement
-** has been completely parsed.
-*/
-SQLITE_PRIVATE void sqlite3VtabFinishParse(Parse *pParse, Token *pEnd){
- Table *pTab = pParse->pNewTable; /* The table being constructed */
- sqlite3 *db = pParse->db; /* The database connection */
-
- if( pTab==0 ) return;
- addArgumentToVtab(pParse);
- pParse->sArg.z = 0;
- if( pTab->nModuleArg<1 ) return;
-
- /* If the CREATE VIRTUAL TABLE statement is being entered for the
- ** first time (in other words if the virtual table is actually being
- ** created now instead of just being read out of sqlite_master) then
- ** do additional initialization work and store the statement text
- ** in the sqlite_master table.
- */
- if( !db->init.busy ){
- char *zStmt;
- char *zWhere;
- int iDb;
- Vdbe *v;
-
- /* Compute the complete text of the CREATE VIRTUAL TABLE statement */
- if( pEnd ){
- pParse->sNameToken.n = (int)(pEnd->z - pParse->sNameToken.z) + pEnd->n;
- }
- zStmt = sqlite3MPrintf(db, "CREATE VIRTUAL TABLE %T", &pParse->sNameToken);
-
- /* A slot for the record has already been allocated in the
- ** SQLITE_MASTER table. We just need to update that slot with all
- ** the information we've collected.
- **
- ** The VM register number pParse->regRowid holds the rowid of an
- ** entry in the sqlite_master table tht was created for this vtab
- ** by sqlite3StartTable().
- */
- iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
- sqlite3NestedParse(pParse,
- "UPDATE %Q.%s "
- "SET type='table', name=%Q, tbl_name=%Q, rootpage=0, sql=%Q "
- "WHERE rowid=#%d",
- db->aDb[iDb].zName, SCHEMA_TABLE(iDb),
- pTab->zName,
- pTab->zName,
- zStmt,
- pParse->regRowid
- );
- sqlite3DbFree(db, zStmt);
- v = sqlite3GetVdbe(pParse);
- sqlite3ChangeCookie(pParse, iDb);
-
- sqlite3VdbeAddOp2(v, OP_Expire, 0, 0);
- zWhere = sqlite3MPrintf(db, "name='%q'", pTab->zName);
- sqlite3VdbeAddOp4(v, OP_ParseSchema, iDb, 1, 0, zWhere, P4_DYNAMIC);
- sqlite3VdbeAddOp4(v, OP_VCreate, iDb, 0, 0,
- pTab->zName, sqlite3Strlen30(pTab->zName) + 1);
- }
-
- /* If we are rereading the sqlite_master table create the in-memory
- ** record of the table. The xConnect() method is not called until
- ** the first time the virtual table is used in an SQL statement. This
- ** allows a schema that contains virtual tables to be loaded before
- ** the required virtual table implementations are registered. */
- else {
- Table *pOld;
- Schema *pSchema = pTab->pSchema;
- const char *zName = pTab->zName;
- int nName = sqlite3Strlen30(zName);
- pOld = sqlite3HashInsert(&pSchema->tblHash, zName, nName, pTab);
- if( pOld ){
- db->mallocFailed = 1;
- assert( pTab==pOld ); /* Malloc must have failed inside HashInsert() */
- return;
- }
- pSchema->db = pParse->db;
- pParse->pNewTable = 0;
- }
-}
-
-/*
-** The parser calls this routine when it sees the first token
-** of an argument to the module name in a CREATE VIRTUAL TABLE statement.
-*/
-SQLITE_PRIVATE void sqlite3VtabArgInit(Parse *pParse){
- addArgumentToVtab(pParse);
- pParse->sArg.z = 0;
- pParse->sArg.n = 0;
-}
-
-/*
-** The parser calls this routine for each token after the first token
-** in an argument to the module name in a CREATE VIRTUAL TABLE statement.
-*/
-SQLITE_PRIVATE void sqlite3VtabArgExtend(Parse *pParse, Token *p){
- Token *pArg = &pParse->sArg;
- if( pArg->z==0 ){
- pArg->z = p->z;
- pArg->n = p->n;
- }else{
- assert(pArg->z < p->z);
- pArg->n = (int)(&p->z[p->n] - pArg->z);
- }
-}
-
-/*
-** Invoke a virtual table constructor (either xCreate or xConnect). The
-** pointer to the function to invoke is passed as the fourth parameter
-** to this procedure.
-*/
-static int vtabCallConstructor(
- sqlite3 *db,
- Table *pTab,
- Module *pMod,
- int (*xConstruct)(sqlite3*,void*,int,const char*const*,sqlite3_vtab**,char**),
- char **pzErr
-){
- VTable *pVTable;
- int rc;
- const char *const*azArg = (const char *const*)pTab->azModuleArg;
- int nArg = pTab->nModuleArg;
- char *zErr = 0;
- char *zModuleName = sqlite3MPrintf(db, "%s", pTab->zName);
-
- if( !zModuleName ){
- return SQLITE_NOMEM;
- }
-
- pVTable = sqlite3DbMallocZero(db, sizeof(VTable));
- if( !pVTable ){
- sqlite3DbFree(db, zModuleName);
- return SQLITE_NOMEM;
- }
- pVTable->db = db;
- pVTable->pMod = pMod;
-
- assert( !db->pVTab );
- assert( xConstruct );
- db->pVTab = pTab;
-
- /* Invoke the virtual table constructor */
- (void)sqlite3SafetyOff(db);
- rc = xConstruct(db, pMod->pAux, nArg, azArg, &pVTable->pVtab, &zErr);
- (void)sqlite3SafetyOn(db);
- if( rc==SQLITE_NOMEM ) db->mallocFailed = 1;
-
- if( SQLITE_OK!=rc ){
- if( zErr==0 ){
- *pzErr = sqlite3MPrintf(db, "vtable constructor failed: %s", zModuleName);
- }else {
- *pzErr = sqlite3MPrintf(db, "%s", zErr);
- sqlite3DbFree(db, zErr);
- }
- sqlite3DbFree(db, pVTable);
- }else if( ALWAYS(pVTable->pVtab) ){
- /* Justification of ALWAYS(): A correct vtab constructor must allocate
- ** the sqlite3_vtab object if successful. */
- pVTable->pVtab->pModule = pMod->pModule;
- pVTable->nRef = 1;
- if( db->pVTab ){
- const char *zFormat = "vtable constructor did not declare schema: %s";
- *pzErr = sqlite3MPrintf(db, zFormat, pTab->zName);
- sqlite3VtabUnlock(pVTable);
- rc = SQLITE_ERROR;
- }else{
- int iCol;
- /* If everything went according to plan, link the new VTable structure
- ** into the linked list headed by pTab->pVTable. Then loop through the
- ** columns of the table to see if any of them contain the token "hidden".
- ** If so, set the Column.isHidden flag and remove the token from
- ** the type string. */
- pVTable->pNext = pTab->pVTable;
- pTab->pVTable = pVTable;
-
- for(iCol=0; iCol<pTab->nCol; iCol++){
- char *zType = pTab->aCol[iCol].zType;
- int nType;
- int i = 0;
- if( !zType ) continue;
- nType = sqlite3Strlen30(zType);
- if( sqlite3StrNICmp("hidden", zType, 6)||(zType[6] && zType[6]!=' ') ){
- for(i=0; i<nType; i++){
- if( (0==sqlite3StrNICmp(" hidden", &zType[i], 7))
- && (zType[i+7]=='\0' || zType[i+7]==' ')
- ){
- i++;
- break;
- }
- }
- }
- if( i<nType ){
- int j;
- int nDel = 6 + (zType[i+6] ? 1 : 0);
- for(j=i; (j+nDel)<=nType; j++){
- zType[j] = zType[j+nDel];
- }
- if( zType[i]=='\0' && i>0 ){
- assert(zType[i-1]==' ');
- zType[i-1] = '\0';
- }
- pTab->aCol[iCol].isHidden = 1;
- }
- }
- }
- }
-
- sqlite3DbFree(db, zModuleName);
- db->pVTab = 0;
- return rc;
-}
-
-/*
-** This function is invoked by the parser to call the xConnect() method
-** of the virtual table pTab. If an error occurs, an error code is returned
-** and an error left in pParse.
-**
-** This call is a no-op if table pTab is not a virtual table.
-*/
-SQLITE_PRIVATE int sqlite3VtabCallConnect(Parse *pParse, Table *pTab){
- sqlite3 *db = pParse->db;
- const char *zMod;
- Module *pMod;
- int rc;
-
- assert( pTab );
- if( (pTab->tabFlags & TF_Virtual)==0 || sqlite3GetVTable(db, pTab) ){
- return SQLITE_OK;
- }
-
- /* Locate the required virtual table module */
- zMod = pTab->azModuleArg[0];
- pMod = (Module*)sqlite3HashFind(&db->aModule, zMod, sqlite3Strlen30(zMod));
-
- if( !pMod ){
- const char *zModule = pTab->azModuleArg[0];
- sqlite3ErrorMsg(pParse, "no such module: %s", zModule);
- rc = SQLITE_ERROR;
- }else{
- char *zErr = 0;
- rc = vtabCallConstructor(db, pTab, pMod, pMod->pModule->xConnect, &zErr);
- if( rc!=SQLITE_OK ){
- sqlite3ErrorMsg(pParse, "%s", zErr);
- }
- sqlite3DbFree(db, zErr);
- }
-
- return rc;
-}
-
-/*
-** Add the virtual table pVTab to the array sqlite3.aVTrans[].
-*/
-static int addToVTrans(sqlite3 *db, VTable *pVTab){
- const int ARRAY_INCR = 5;
-
- /* Grow the sqlite3.aVTrans array if required */
- if( (db->nVTrans%ARRAY_INCR)==0 ){
- VTable **aVTrans;
- int nBytes = sizeof(sqlite3_vtab *) * (db->nVTrans + ARRAY_INCR);
- aVTrans = sqlite3DbRealloc(db, (void *)db->aVTrans, nBytes);
- if( !aVTrans ){
- return SQLITE_NOMEM;
- }
- memset(&aVTrans[db->nVTrans], 0, sizeof(sqlite3_vtab *)*ARRAY_INCR);
- db->aVTrans = aVTrans;
- }
-
- /* Add pVtab to the end of sqlite3.aVTrans */
- db->aVTrans[db->nVTrans++] = pVTab;
- sqlite3VtabLock(pVTab);
- return SQLITE_OK;
-}
-
-/*
-** This function is invoked by the vdbe to call the xCreate method
-** of the virtual table named zTab in database iDb.
-**
-** If an error occurs, *pzErr is set to point an an English language
-** description of the error and an SQLITE_XXX error code is returned.
-** In this case the caller must call sqlite3DbFree(db, ) on *pzErr.
-*/
-SQLITE_PRIVATE int sqlite3VtabCallCreate(sqlite3 *db, int iDb, const char *zTab, char **pzErr){
- int rc = SQLITE_OK;
- Table *pTab;
- Module *pMod;
- const char *zMod;
-
- pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zName);
- assert( pTab && (pTab->tabFlags & TF_Virtual)!=0 && !pTab->pVTable );
-
- /* Locate the required virtual table module */
- zMod = pTab->azModuleArg[0];
- pMod = (Module*)sqlite3HashFind(&db->aModule, zMod, sqlite3Strlen30(zMod));
-
- /* If the module has been registered and includes a Create method,
- ** invoke it now. If the module has not been registered, return an
- ** error. Otherwise, do nothing.
- */
- if( !pMod ){
- *pzErr = sqlite3MPrintf(db, "no such module: %s", zMod);
- rc = SQLITE_ERROR;
- }else{
- rc = vtabCallConstructor(db, pTab, pMod, pMod->pModule->xCreate, pzErr);
- }
-
- /* Justification of ALWAYS(): The xConstructor method is required to
- ** create a valid sqlite3_vtab if it returns SQLITE_OK. */
- if( rc==SQLITE_OK && ALWAYS(sqlite3GetVTable(db, pTab)) ){
- rc = addToVTrans(db, sqlite3GetVTable(db, pTab));
- }
-
- return rc;
-}
-
-/*
-** This function is used to set the schema of a virtual table. It is only
-** valid to call this function from within the xCreate() or xConnect() of a
-** virtual table module.
-*/
-SQLITE_API int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){
- Parse *pParse;
-
- int rc = SQLITE_OK;
- Table *pTab;
- char *zErr = 0;
-
- sqlite3_mutex_enter(db->mutex);
- pTab = db->pVTab;
- if( !pTab ){
- sqlite3Error(db, SQLITE_MISUSE, 0);
- sqlite3_mutex_leave(db->mutex);
- return SQLITE_MISUSE;
- }
- assert( (pTab->tabFlags & TF_Virtual)!=0 );
-
- pParse = sqlite3StackAllocZero(db, sizeof(*pParse));
- if( pParse==0 ){
- rc = SQLITE_NOMEM;
- }else{
- pParse->declareVtab = 1;
- pParse->db = db;
-
- if(
- SQLITE_OK == sqlite3RunParser(pParse, zCreateTable, &zErr) &&
- pParse->pNewTable &&
- !pParse->pNewTable->pSelect &&
- (pParse->pNewTable->tabFlags & TF_Virtual)==0
- ){
- if( !pTab->aCol ){
- pTab->aCol = pParse->pNewTable->aCol;
- pTab->nCol = pParse->pNewTable->nCol;
- pParse->pNewTable->nCol = 0;
- pParse->pNewTable->aCol = 0;
- }
- db->pVTab = 0;
- } else {
- sqlite3Error(db, SQLITE_ERROR, zErr);
- sqlite3DbFree(db, zErr);
- rc = SQLITE_ERROR;
- }
- pParse->declareVtab = 0;
-
- if( pParse->pVdbe ){
- sqlite3VdbeFinalize(pParse->pVdbe);
- }
- sqlite3DeleteTable(pParse->pNewTable);
- sqlite3StackFree(db, pParse);
- }
-
- assert( (rc&0xff)==rc );
- rc = sqlite3ApiExit(db, rc);
- sqlite3_mutex_leave(db->mutex);
- return rc;
-}
-
-/*
-** This function is invoked by the vdbe to call the xDestroy method
-** of the virtual table named zTab in database iDb. This occurs
-** when a DROP TABLE is mentioned.
-**
-** This call is a no-op if zTab is not a virtual table.
-*/
-SQLITE_PRIVATE int sqlite3VtabCallDestroy(sqlite3 *db, int iDb, const char *zTab){
- int rc = SQLITE_OK;
- Table *pTab;
-
- pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zName);
- if( ALWAYS(pTab!=0 && pTab->pVTable!=0) ){
- VTable *p = vtabDisconnectAll(db, pTab);
-
- rc = sqlite3SafetyOff(db);
- assert( rc==SQLITE_OK );
- rc = p->pMod->pModule->xDestroy(p->pVtab);
- (void)sqlite3SafetyOn(db);
-
- /* Remove the sqlite3_vtab* from the aVTrans[] array, if applicable */
- if( rc==SQLITE_OK ){
- assert( pTab->pVTable==p && p->pNext==0 );
- p->pVtab = 0;
- pTab->pVTable = 0;
- sqlite3VtabUnlock(p);
- }
- }
-
- return rc;
-}
-
-/*
-** This function invokes either the xRollback or xCommit method
-** of each of the virtual tables in the sqlite3.aVTrans array. The method
-** called is identified by the second argument, "offset", which is
-** the offset of the method to call in the sqlite3_module structure.
-**
-** The array is cleared after invoking the callbacks.
-*/
-static void callFinaliser(sqlite3 *db, int offset){
- int i;
- if( db->aVTrans ){
- for(i=0; i<db->nVTrans; i++){
- VTable *pVTab = db->aVTrans[i];
- sqlite3_vtab *p = pVTab->pVtab;
- if( p ){
- int (*x)(sqlite3_vtab *);
- x = *(int (**)(sqlite3_vtab *))((char *)p->pModule + offset);
- if( x ) x(p);
- }
- sqlite3VtabUnlock(pVTab);
- }
- sqlite3DbFree(db, db->aVTrans);
- db->nVTrans = 0;
- db->aVTrans = 0;
- }
-}
-
-/*
-** Invoke the xSync method of all virtual tables in the sqlite3.aVTrans
-** array. Return the error code for the first error that occurs, or
-** SQLITE_OK if all xSync operations are successful.
-**
-** Set *pzErrmsg to point to a buffer that should be released using
-** sqlite3DbFree() containing an error message, if one is available.
-*/
-SQLITE_PRIVATE int sqlite3VtabSync(sqlite3 *db, char **pzErrmsg){
- int i;
- int rc = SQLITE_OK;
- int rcsafety;
- VTable **aVTrans = db->aVTrans;
-
- rc = sqlite3SafetyOff(db);
- db->aVTrans = 0;
- for(i=0; rc==SQLITE_OK && i<db->nVTrans; i++){
- int (*x)(sqlite3_vtab *);
- sqlite3_vtab *pVtab = aVTrans[i]->pVtab;
- if( pVtab && (x = pVtab->pModule->xSync)!=0 ){
- rc = x(pVtab);
- sqlite3DbFree(db, *pzErrmsg);
- *pzErrmsg = pVtab->zErrMsg;
- pVtab->zErrMsg = 0;
- }
- }
- db->aVTrans = aVTrans;
- rcsafety = sqlite3SafetyOn(db);
-
- if( rc==SQLITE_OK ){
- rc = rcsafety;
- }
- return rc;
-}
-
-/*
-** Invoke the xRollback method of all virtual tables in the
-** sqlite3.aVTrans array. Then clear the array itself.
-*/
-SQLITE_PRIVATE int sqlite3VtabRollback(sqlite3 *db){
- callFinaliser(db, offsetof(sqlite3_module,xRollback));
- return SQLITE_OK;
-}
-
-/*
-** Invoke the xCommit method of all virtual tables in the
-** sqlite3.aVTrans array. Then clear the array itself.
-*/
-SQLITE_PRIVATE int sqlite3VtabCommit(sqlite3 *db){
- callFinaliser(db, offsetof(sqlite3_module,xCommit));
- return SQLITE_OK;
-}
-
-/*
-** If the virtual table pVtab supports the transaction interface
-** (xBegin/xRollback/xCommit and optionally xSync) and a transaction is
-** not currently open, invoke the xBegin method now.
-**
-** If the xBegin call is successful, place the sqlite3_vtab pointer
-** in the sqlite3.aVTrans array.
-*/
-SQLITE_PRIVATE int sqlite3VtabBegin(sqlite3 *db, VTable *pVTab){
- int rc = SQLITE_OK;
- const sqlite3_module *pModule;
-
- /* Special case: If db->aVTrans is NULL and db->nVTrans is greater
- ** than zero, then this function is being called from within a
- ** virtual module xSync() callback. It is illegal to write to
- ** virtual module tables in this case, so return SQLITE_LOCKED.
- */
- if( sqlite3VtabInSync(db) ){
- return SQLITE_LOCKED;
- }
- if( !pVTab ){
- return SQLITE_OK;
- }
- pModule = pVTab->pVtab->pModule;
-
- if( pModule->xBegin ){
- int i;
-
-
- /* If pVtab is already in the aVTrans array, return early */
- for(i=0; i<db->nVTrans; i++){
- if( db->aVTrans[i]==pVTab ){
- return SQLITE_OK;
- }
- }
-
- /* Invoke the xBegin method */
- rc = pModule->xBegin(pVTab->pVtab);
- if( rc==SQLITE_OK ){
- rc = addToVTrans(db, pVTab);
- }
- }
- return rc;
-}
-
-/*
-** The first parameter (pDef) is a function implementation. The
-** second parameter (pExpr) is the first argument to this function.
-** If pExpr is a column in a virtual table, then let the virtual
-** table implementation have an opportunity to overload the function.
-**
-** This routine is used to allow virtual table implementations to
-** overload MATCH, LIKE, GLOB, and REGEXP operators.
-**
-** Return either the pDef argument (indicating no change) or a
-** new FuncDef structure that is marked as ephemeral using the
-** SQLITE_FUNC_EPHEM flag.
-*/
-SQLITE_PRIVATE FuncDef *sqlite3VtabOverloadFunction(
- sqlite3 *db, /* Database connection for reporting malloc problems */
- FuncDef *pDef, /* Function to possibly overload */
- int nArg, /* Number of arguments to the function */
- Expr *pExpr /* First argument to the function */
-){
- Table *pTab;
- sqlite3_vtab *pVtab;
- sqlite3_module *pMod;
- void (*xFunc)(sqlite3_context*,int,sqlite3_value**) = 0;
- void *pArg = 0;
- FuncDef *pNew;
- int rc = 0;
- char *zLowerName;
- unsigned char *z;
-
-
- /* Check to see the left operand is a column in a virtual table */
- if( NEVER(pExpr==0) ) return pDef;
- if( pExpr->op!=TK_COLUMN ) return pDef;
- pTab = pExpr->pTab;
- if( NEVER(pTab==0) ) return pDef;
- if( (pTab->tabFlags & TF_Virtual)==0 ) return pDef;
- pVtab = sqlite3GetVTable(db, pTab)->pVtab;
- assert( pVtab!=0 );
- assert( pVtab->pModule!=0 );
- pMod = (sqlite3_module *)pVtab->pModule;
- if( pMod->xFindFunction==0 ) return pDef;
-
- /* Call the xFindFunction method on the virtual table implementation
- ** to see if the implementation wants to overload this function
- */
- zLowerName = sqlite3DbStrDup(db, pDef->zName);
- if( zLowerName ){
- for(z=(unsigned char*)zLowerName; *z; z++){
- *z = sqlite3UpperToLower[*z];
- }
- rc = pMod->xFindFunction(pVtab, nArg, zLowerName, &xFunc, &pArg);
- sqlite3DbFree(db, zLowerName);
- }
- if( rc==0 ){
- return pDef;
- }
-
- /* Create a new ephemeral function definition for the overloaded
- ** function */
- pNew = sqlite3DbMallocZero(db, sizeof(*pNew)
- + sqlite3Strlen30(pDef->zName) + 1);
- if( pNew==0 ){
- return pDef;
- }
- *pNew = *pDef;
- pNew->zName = (char *)&pNew[1];
- memcpy(pNew->zName, pDef->zName, sqlite3Strlen30(pDef->zName)+1);
- pNew->xFunc = xFunc;
- pNew->pUserData = pArg;
- pNew->flags |= SQLITE_FUNC_EPHEM;
- return pNew;
-}
-
-/*
-** Make sure virtual table pTab is contained in the pParse->apVirtualLock[]
-** array so that an OP_VBegin will get generated for it. Add pTab to the
-** array if it is missing. If pTab is already in the array, this routine
-** is a no-op.
-*/
-SQLITE_PRIVATE void sqlite3VtabMakeWritable(Parse *pParse, Table *pTab){
- Parse *pToplevel = sqlite3ParseToplevel(pParse);
- int i, n;
- Table **apVtabLock;
-
- assert( IsVirtual(pTab) );
- for(i=0; i<pToplevel->nVtabLock; i++){
- if( pTab==pToplevel->apVtabLock[i] ) return;
- }
- n = (pToplevel->nVtabLock+1)*sizeof(pToplevel->apVtabLock[0]);
- apVtabLock = sqlite3_realloc(pToplevel->apVtabLock, n);
- if( apVtabLock ){
- pToplevel->apVtabLock = apVtabLock;
- pToplevel->apVtabLock[pToplevel->nVtabLock++] = pTab;
- }else{
- pToplevel->db->mallocFailed = 1;
- }
-}
-
-#endif /* SQLITE_OMIT_VIRTUALTABLE */
-
-/************** End of vtab.c ************************************************/
-/************** Begin file where.c *******************************************/
-/*
-** 2001 September 15
-**
-** 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 module contains C code that generates VDBE code used to process
-** the WHERE clause of SQL statements. This module is responsible for
-** generating the code that loops through a table looking for applicable
-** rows. Indices are selected and used to speed the search when doing
-** so is applicable. Because this module is responsible for selecting
-** indices, you might also think of this module as the "query optimizer".
-**
-** $Id: where.c,v 1.411 2009/07/31 06:14:52 danielk1977 Exp $
-*/
-
-/*
-** Trace output macros
-*/
-#if defined(SQLITE_TEST) || defined(SQLITE_DEBUG)
-SQLITE_PRIVATE int sqlite3WhereTrace = 0;
-#endif
-#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG)
-# define WHERETRACE(X) if(sqlite3WhereTrace) sqlite3DebugPrintf X
-#else
-# define WHERETRACE(X)
-#endif
-
-/* Forward reference
-*/
-typedef struct WhereClause WhereClause;
-typedef struct WhereMaskSet WhereMaskSet;
-typedef struct WhereOrInfo WhereOrInfo;
-typedef struct WhereAndInfo WhereAndInfo;
-typedef struct WhereCost WhereCost;
-
-/*
-** The query generator uses an array of instances of this structure to
-** help it analyze the subexpressions of the WHERE clause. Each WHERE
-** clause subexpression is separated from the others by AND operators,
-** usually, or sometimes subexpressions separated by OR.
-**
-** All WhereTerms are collected into a single WhereClause structure.
-** The following identity holds:
-**
-** WhereTerm.pWC->a[WhereTerm.idx] == WhereTerm
-**
-** When a term is of the form:
-**
-** X <op> <expr>
-**
-** where X is a column name and <op> is one of certain operators,
-** then WhereTerm.leftCursor and WhereTerm.u.leftColumn record the
-** cursor number and column number for X. WhereTerm.eOperator records
-** the <op> using a bitmask encoding defined by WO_xxx below. The
-** use of a bitmask encoding for the operator allows us to search
-** quickly for terms that match any of several different operators.
-**
-** A WhereTerm might also be two or more subterms connected by OR:
-**
-** (t1.X <op> <expr>) OR (t1.Y <op> <expr>) OR ....
-**
-** In this second case, wtFlag as the TERM_ORINFO set and eOperator==WO_OR
-** and the WhereTerm.u.pOrInfo field points to auxiliary information that
-** is collected about the
-**
-** If a term in the WHERE clause does not match either of the two previous
-** categories, then eOperator==0. The WhereTerm.pExpr field is still set
-** to the original subexpression content and wtFlags is set up appropriately
-** but no other fields in the WhereTerm object are meaningful.
-**
-** When eOperator!=0, prereqRight and prereqAll record sets of cursor numbers,
-** but they do so indirectly. A single WhereMaskSet structure translates
-** cursor number into bits and the translated bit is stored in the prereq
-** fields. The translation is used in order to maximize the number of
-** bits that will fit in a Bitmask. The VDBE cursor numbers might be
-** spread out over the non-negative integers. For example, the cursor
-** numbers might be 3, 8, 9, 10, 20, 23, 41, and 45. The WhereMaskSet
-** translates these sparse cursor numbers into consecutive integers
-** beginning with 0 in order to make the best possible use of the available
-** bits in the Bitmask. So, in the example above, the cursor numbers
-** would be mapped into integers 0 through 7.
-**
-** The number of terms in a join is limited by the number of bits
-** in prereqRight and prereqAll. The default is 64 bits, hence SQLite
-** is only able to process joins with 64 or fewer tables.
-*/
-typedef struct WhereTerm WhereTerm;
-struct WhereTerm {
- Expr *pExpr; /* Pointer to the subexpression that is this term */
- int iParent; /* Disable pWC->a[iParent] when this term disabled */
- int leftCursor; /* Cursor number of X in "X <op> <expr>" */
- union {
- int leftColumn; /* Column number of X in "X <op> <expr>" */
- WhereOrInfo *pOrInfo; /* Extra information if eOperator==WO_OR */
- WhereAndInfo *pAndInfo; /* Extra information if eOperator==WO_AND */
- } u;
- u16 eOperator; /* A WO_xx value describing <op> */
- u8 wtFlags; /* TERM_xxx bit flags. See below */
- u8 nChild; /* Number of children that must disable us */
- WhereClause *pWC; /* The clause this term is part of */
- Bitmask prereqRight; /* Bitmask of tables used by pExpr->pRight */
- Bitmask prereqAll; /* Bitmask of tables referenced by pExpr */
-};
-
-/*
-** Allowed values of WhereTerm.wtFlags
-*/
-#define TERM_DYNAMIC 0x01 /* Need to call sqlite3ExprDelete(db, pExpr) */
-#define TERM_VIRTUAL 0x02 /* Added by the optimizer. Do not code */
-#define TERM_CODED 0x04 /* This term is already coded */
-#define TERM_COPIED 0x08 /* Has a child */
-#define TERM_ORINFO 0x10 /* Need to free the WhereTerm.u.pOrInfo object */
-#define TERM_ANDINFO 0x20 /* Need to free the WhereTerm.u.pAndInfo obj */
-#define TERM_OR_OK 0x40 /* Used during OR-clause processing */
-
-/*
-** An instance of the following structure holds all information about a
-** WHERE clause. Mostly this is a container for one or more WhereTerms.
-*/
-struct WhereClause {
- Parse *pParse; /* The parser context */
- WhereMaskSet *pMaskSet; /* Mapping of table cursor numbers to bitmasks */
- Bitmask vmask; /* Bitmask identifying virtual table cursors */
- u8 op; /* Split operator. TK_AND or TK_OR */
- int nTerm; /* Number of terms */
- int nSlot; /* Number of entries in a[] */
- WhereTerm *a; /* Each a[] describes a term of the WHERE cluase */
-#if defined(SQLITE_SMALL_STACK)
- WhereTerm aStatic[1]; /* Initial static space for a[] */
-#else
- WhereTerm aStatic[8]; /* Initial static space for a[] */
-#endif
-};
-
-/*
-** A WhereTerm with eOperator==WO_OR has its u.pOrInfo pointer set to
-** a dynamically allocated instance of the following structure.
-*/
-struct WhereOrInfo {
- WhereClause wc; /* Decomposition into subterms */
- Bitmask indexable; /* Bitmask of all indexable tables in the clause */
-};
-
-/*
-** A WhereTerm with eOperator==WO_AND has its u.pAndInfo pointer set to
-** a dynamically allocated instance of the following structure.
-*/
-struct WhereAndInfo {
- WhereClause wc; /* The subexpression broken out */
-};
-
-/*
-** An instance of the following structure keeps track of a mapping
-** between VDBE cursor numbers and bits of the bitmasks in WhereTerm.
-**
-** The VDBE cursor numbers are small integers contained in
-** SrcList_item.iCursor and Expr.iTable fields. For any given WHERE
-** clause, the cursor numbers might not begin with 0 and they might
-** contain gaps in the numbering sequence. But we want to make maximum
-** use of the bits in our bitmasks. This structure provides a mapping
-** from the sparse cursor numbers into consecutive integers beginning
-** with 0.
-**
-** If WhereMaskSet.ix[A]==B it means that The A-th bit of a Bitmask
-** corresponds VDBE cursor number B. The A-th bit of a bitmask is 1<<A.
-**
-** For example, if the WHERE clause expression used these VDBE
-** cursors: 4, 5, 8, 29, 57, 73. Then the WhereMaskSet structure
-** would map those cursor numbers into bits 0 through 5.
-**
-** Note that the mapping is not necessarily ordered. In the example
-** above, the mapping might go like this: 4->3, 5->1, 8->2, 29->0,
-** 57->5, 73->4. Or one of 719 other combinations might be used. It
-** does not really matter. What is important is that sparse cursor
-** numbers all get mapped into bit numbers that begin with 0 and contain
-** no gaps.
-*/
-struct WhereMaskSet {
- int n; /* Number of assigned cursor values */
- int ix[BMS]; /* Cursor assigned to each bit */
-};
-
-/*
-** A WhereCost object records a lookup strategy and the estimated
-** cost of pursuing that strategy.
-*/
-struct WhereCost {
- WherePlan plan; /* The lookup strategy */
- double rCost; /* Overall cost of pursuing this search strategy */
- double nRow; /* Estimated number of output rows */
- Bitmask used; /* Bitmask of cursors used by this plan */
-};
-
-/*
-** Bitmasks for the operators that indices are able to exploit. An
-** OR-ed combination of these values can be used when searching for
-** terms in the where clause.
-*/
-#define WO_IN 0x001
-#define WO_EQ 0x002
-#define WO_LT (WO_EQ<<(TK_LT-TK_EQ))
-#define WO_LE (WO_EQ<<(TK_LE-TK_EQ))
-#define WO_GT (WO_EQ<<(TK_GT-TK_EQ))
-#define WO_GE (WO_EQ<<(TK_GE-TK_EQ))
-#define WO_MATCH 0x040
-#define WO_ISNULL 0x080
-#define WO_OR 0x100 /* Two or more OR-connected terms */
-#define WO_AND 0x200 /* Two or more AND-connected terms */
-
-#define WO_ALL 0xfff /* Mask of all possible WO_* values */
-#define WO_SINGLE 0x0ff /* Mask of all non-compound WO_* values */
-
-/*
-** Value for wsFlags returned by bestIndex() and stored in
-** WhereLevel.wsFlags. These flags determine which search
-** strategies are appropriate.
-**
-** The least significant 12 bits is reserved as a mask for WO_ values above.
-** The WhereLevel.wsFlags field is usually set to WO_IN|WO_EQ|WO_ISNULL.
-** But if the table is the right table of a left join, WhereLevel.wsFlags
-** is set to WO_IN|WO_EQ. The WhereLevel.wsFlags field can then be used as
-** the "op" parameter to findTerm when we are resolving equality constraints.
-** ISNULL constraints will then not be used on the right table of a left
-** join. Tickets #2177 and #2189.
-*/
-#define WHERE_ROWID_EQ 0x00001000 /* rowid=EXPR or rowid IN (...) */
-#define WHERE_ROWID_RANGE 0x00002000 /* rowid<EXPR and/or rowid>EXPR */
-#define WHERE_COLUMN_EQ 0x00010000 /* x=EXPR or x IN (...) or x IS NULL */
-#define WHERE_COLUMN_RANGE 0x00020000 /* x<EXPR and/or x>EXPR */
-#define WHERE_COLUMN_IN 0x00040000 /* x IN (...) */
-#define WHERE_COLUMN_NULL 0x00080000 /* x IS NULL */
-#define WHERE_INDEXED 0x000f0000 /* Anything that uses an index */
-#define WHERE_IN_ABLE 0x000f1000 /* Able to support an IN operator */
-#define WHERE_TOP_LIMIT 0x00100000 /* x<EXPR or x<=EXPR constraint */
-#define WHERE_BTM_LIMIT 0x00200000 /* x>EXPR or x>=EXPR constraint */
-#define WHERE_IDX_ONLY 0x00800000 /* Use index only - omit table */
-#define WHERE_ORDERBY 0x01000000 /* Output will appear in correct order */
-#define WHERE_REVERSE 0x02000000 /* Scan in reverse order */
-#define WHERE_UNIQUE 0x04000000 /* Selects no more than one row */
-#define WHERE_VIRTUALTABLE 0x08000000 /* Use virtual-table processing */
-#define WHERE_MULTI_OR 0x10000000 /* OR using multiple indices */
-
-/*
-** Initialize a preallocated WhereClause structure.
-*/
-static void whereClauseInit(
- WhereClause *pWC, /* The WhereClause to be initialized */
- Parse *pParse, /* The parsing context */
- WhereMaskSet *pMaskSet /* Mapping from table cursor numbers to bitmasks */
-){
- pWC->pParse = pParse;
- pWC->pMaskSet = pMaskSet;
- pWC->nTerm = 0;
- pWC->nSlot = ArraySize(pWC->aStatic);
- pWC->a = pWC->aStatic;
- pWC->vmask = 0;
-}
-
-/* Forward reference */
-static void whereClauseClear(WhereClause*);
-
-/*
-** Deallocate all memory associated with a WhereOrInfo object.
-*/
-static void whereOrInfoDelete(sqlite3 *db, WhereOrInfo *p){
- whereClauseClear(&p->wc);
- sqlite3DbFree(db, p);
-}
-
-/*
-** Deallocate all memory associated with a WhereAndInfo object.
-*/
-static void whereAndInfoDelete(sqlite3 *db, WhereAndInfo *p){
- whereClauseClear(&p->wc);
- sqlite3DbFree(db, p);
-}
-
-/*
-** Deallocate a WhereClause structure. The WhereClause structure
-** itself is not freed. This routine is the inverse of whereClauseInit().
-*/
-static void whereClauseClear(WhereClause *pWC){
- int i;
- WhereTerm *a;
- sqlite3 *db = pWC->pParse->db;
- for(i=pWC->nTerm-1, a=pWC->a; i>=0; i--, a++){
- if( a->wtFlags & TERM_DYNAMIC ){
- sqlite3ExprDelete(db, a->pExpr);
- }
- if( a->wtFlags & TERM_ORINFO ){
- whereOrInfoDelete(db, a->u.pOrInfo);
- }else if( a->wtFlags & TERM_ANDINFO ){
- whereAndInfoDelete(db, a->u.pAndInfo);
- }
- }
- if( pWC->a!=pWC->aStatic ){
- sqlite3DbFree(db, pWC->a);
- }
-}
-
-/*
-** Add a single new WhereTerm entry to the WhereClause object pWC.
-** The new WhereTerm object is constructed from Expr p and with wtFlags.
-** The index in pWC->a[] of the new WhereTerm is returned on success.
-** 0 is returned if the new WhereTerm could not be added due to a memory
-** allocation error. The memory allocation failure will be recorded in
-** the db->mallocFailed flag so that higher-level functions can detect it.
-**
-** This routine will increase the size of the pWC->a[] array as necessary.
-**
-** If the wtFlags argument includes TERM_DYNAMIC, then responsibility
-** for freeing the expression p is assumed by the WhereClause object pWC.
-** This is true even if this routine fails to allocate a new WhereTerm.
-**
-** WARNING: This routine might reallocate the space used to store
-** WhereTerms. All pointers to WhereTerms should be invalidated after
-** calling this routine. Such pointers may be reinitialized by referencing
-** the pWC->a[] array.
-*/
-static int whereClauseInsert(WhereClause *pWC, Expr *p, u8 wtFlags){
- WhereTerm *pTerm;
- int idx;
- if( pWC->nTerm>=pWC->nSlot ){
- WhereTerm *pOld = pWC->a;
- sqlite3 *db = pWC->pParse->db;
- pWC->a = sqlite3DbMallocRaw(db, sizeof(pWC->a[0])*pWC->nSlot*2 );
- if( pWC->a==0 ){
- if( wtFlags & TERM_DYNAMIC ){
- sqlite3ExprDelete(db, p);
- }
- pWC->a = pOld;
- return 0;
- }
- memcpy(pWC->a, pOld, sizeof(pWC->a[0])*pWC->nTerm);
- if( pOld!=pWC->aStatic ){
- sqlite3DbFree(db, pOld);
- }
- pWC->nSlot = sqlite3DbMallocSize(db, pWC->a)/sizeof(pWC->a[0]);
- }
- pTerm = &pWC->a[idx = pWC->nTerm++];
- pTerm->pExpr = p;
- pTerm->wtFlags = wtFlags;
- pTerm->pWC = pWC;
- pTerm->iParent = -1;
- return idx;
-}
-
-/*
-** This routine identifies subexpressions in the WHERE clause where
-** each subexpression is separated by the AND operator or some other
-** operator specified in the op parameter. The WhereClause structure
-** is filled with pointers to subexpressions. For example:
-**
-** WHERE a=='hello' AND coalesce(b,11)<10 AND (c+12!=d OR c==22)
-** \________/ \_______________/ \________________/
-** slot[0] slot[1] slot[2]
-**
-** The original WHERE clause in pExpr is unaltered. All this routine
-** does is make slot[] entries point to substructure within pExpr.
-**
-** In the previous sentence and in the diagram, "slot[]" refers to
-** the WhereClause.a[] array. The slot[] array grows as needed to contain
-** all terms of the WHERE clause.
-*/
-static void whereSplit(WhereClause *pWC, Expr *pExpr, int op){
- pWC->op = (u8)op;
- if( pExpr==0 ) return;
- if( pExpr->op!=op ){
- whereClauseInsert(pWC, pExpr, 0);
- }else{
- whereSplit(pWC, pExpr->pLeft, op);
- whereSplit(pWC, pExpr->pRight, op);
- }
-}
-
-/*
-** Initialize an expression mask set (a WhereMaskSet object)
-*/
-#define initMaskSet(P) memset(P, 0, sizeof(*P))
-
-/*
-** Return the bitmask for the given cursor number. Return 0 if
-** iCursor is not in the set.
-*/
-static Bitmask getMask(WhereMaskSet *pMaskSet, int iCursor){
- int i;
- assert( pMaskSet->n<=sizeof(Bitmask)*8 );
- for(i=0; i<pMaskSet->n; i++){
- if( pMaskSet->ix[i]==iCursor ){
- return ((Bitmask)1)<<i;
- }
- }
- return 0;
-}
-
-/*
-** Create a new mask for cursor iCursor.
-**
-** There is one cursor per table in the FROM clause. The number of
-** tables in the FROM clause is limited by a test early in the
-** sqlite3WhereBegin() routine. So we know that the pMaskSet->ix[]
-** array will never overflow.
-*/
-static void createMask(WhereMaskSet *pMaskSet, int iCursor){
- assert( pMaskSet->n < ArraySize(pMaskSet->ix) );
- pMaskSet->ix[pMaskSet->n++] = iCursor;
-}
-
-/*
-** This routine walks (recursively) an expression tree and generates
-** a bitmask indicating which tables are used in that expression
-** tree.
-**
-** In order for this routine to work, the calling function must have
-** previously invoked sqlite3ResolveExprNames() on the expression. See
-** the header comment on that routine for additional information.
-** The sqlite3ResolveExprNames() routines looks for column names and
-** sets their opcodes to TK_COLUMN and their Expr.iTable fields to
-** the VDBE cursor number of the table. This routine just has to
-** translate the cursor numbers into bitmask values and OR all
-** the bitmasks together.
-*/
-static Bitmask exprListTableUsage(WhereMaskSet*, ExprList*);
-static Bitmask exprSelectTableUsage(WhereMaskSet*, Select*);
-static Bitmask exprTableUsage(WhereMaskSet *pMaskSet, Expr *p){
- Bitmask mask = 0;
- if( p==0 ) return 0;
- if( p->op==TK_COLUMN ){
- mask = getMask(pMaskSet, p->iTable);
- return mask;
- }
- mask = exprTableUsage(pMaskSet, p->pRight);
- mask |= exprTableUsage(pMaskSet, p->pLeft);
- if( ExprHasProperty(p, EP_xIsSelect) ){
- mask |= exprSelectTableUsage(pMaskSet, p->x.pSelect);
- }else{
- mask |= exprListTableUsage(pMaskSet, p->x.pList);
- }
- return mask;
-}
-static Bitmask exprListTableUsage(WhereMaskSet *pMaskSet, ExprList *pList){
- int i;
- Bitmask mask = 0;
- if( pList ){
- for(i=0; i<pList->nExpr; i++){
- mask |= exprTableUsage(pMaskSet, pList->a[i].pExpr);
- }
- }
- return mask;
-}
-static Bitmask exprSelectTableUsage(WhereMaskSet *pMaskSet, Select *pS){
- Bitmask mask = 0;
- while( pS ){
- mask |= exprListTableUsage(pMaskSet, pS->pEList);
- mask |= exprListTableUsage(pMaskSet, pS->pGroupBy);
- mask |= exprListTableUsage(pMaskSet, pS->pOrderBy);
- mask |= exprTableUsage(pMaskSet, pS->pWhere);
- mask |= exprTableUsage(pMaskSet, pS->pHaving);
- pS = pS->pPrior;
- }
- return mask;
-}
-
-/*
-** Return TRUE if the given operator is one of the operators that is
-** allowed for an indexable WHERE clause term. The allowed operators are
-** "=", "<", ">", "<=", ">=", and "IN".
-*/
-static int allowedOp(int op){
- assert( TK_GT>TK_EQ && TK_GT<TK_GE );
- assert( TK_LT>TK_EQ && TK_LT<TK_GE );
- assert( TK_LE>TK_EQ && TK_LE<TK_GE );
- assert( TK_GE==TK_EQ+4 );
- return op==TK_IN || (op>=TK_EQ && op<=TK_GE) || op==TK_ISNULL;
-}
-
-/*
-** Swap two objects of type TYPE.
-*/
-#define SWAP(TYPE,A,B) {TYPE t=A; A=B; B=t;}
-
-/*
-** Commute a comparison operator. Expressions of the form "X op Y"
-** are converted into "Y op X".
-**
-** If a collation sequence is associated with either the left or right
-** side of the comparison, it remains associated with the same side after
-** the commutation. So "Y collate NOCASE op X" becomes
-** "X collate NOCASE op Y". This is because any collation sequence on
-** the left hand side of a comparison overrides any collation sequence
-** attached to the right. For the same reason the EP_ExpCollate flag
-** is not commuted.
-*/
-static void exprCommute(Parse *pParse, Expr *pExpr){
- u16 expRight = (pExpr->pRight->flags & EP_ExpCollate);
- u16 expLeft = (pExpr->pLeft->flags & EP_ExpCollate);
- assert( allowedOp(pExpr->op) && pExpr->op!=TK_IN );
- pExpr->pRight->pColl = sqlite3ExprCollSeq(pParse, pExpr->pRight);
- pExpr->pLeft->pColl = sqlite3ExprCollSeq(pParse, pExpr->pLeft);
- SWAP(CollSeq*,pExpr->pRight->pColl,pExpr->pLeft->pColl);
- pExpr->pRight->flags = (pExpr->pRight->flags & ~EP_ExpCollate) | expLeft;
- pExpr->pLeft->flags = (pExpr->pLeft->flags & ~EP_ExpCollate) | expRight;
- SWAP(Expr*,pExpr->pRight,pExpr->pLeft);
- if( pExpr->op>=TK_GT ){
- assert( TK_LT==TK_GT+2 );
- assert( TK_GE==TK_LE+2 );
- assert( TK_GT>TK_EQ );
- assert( TK_GT<TK_LE );
- assert( pExpr->op>=TK_GT && pExpr->op<=TK_GE );
- pExpr->op = ((pExpr->op-TK_GT)^2)+TK_GT;
- }
-}
-
-/*
-** Translate from TK_xx operator to WO_xx bitmask.
-*/
-static u16 operatorMask(int op){
- u16 c;
- assert( allowedOp(op) );
- if( op==TK_IN ){
- c = WO_IN;
- }else if( op==TK_ISNULL ){
- c = WO_ISNULL;
- }else{
- assert( (WO_EQ<<(op-TK_EQ)) < 0x7fff );
- c = (u16)(WO_EQ<<(op-TK_EQ));
- }
- assert( op!=TK_ISNULL || c==WO_ISNULL );
- assert( op!=TK_IN || c==WO_IN );
- assert( op!=TK_EQ || c==WO_EQ );
- assert( op!=TK_LT || c==WO_LT );
- assert( op!=TK_LE || c==WO_LE );
- assert( op!=TK_GT || c==WO_GT );
- assert( op!=TK_GE || c==WO_GE );
- return c;
-}
-
-/*
-** Search for a term in the WHERE clause that is of the form "X <op> <expr>"
-** where X is a reference to the iColumn of table iCur and <op> is one of
-** the WO_xx operator codes specified by the op parameter.
-** Return a pointer to the term. Return 0 if not found.
-*/
-static WhereTerm *findTerm(
- WhereClause *pWC, /* The WHERE clause to be searched */
- int iCur, /* Cursor number of LHS */
- int iColumn, /* Column number of LHS */
- Bitmask notReady, /* RHS must not overlap with this mask */
- u32 op, /* Mask of WO_xx values describing operator */
- Index *pIdx /* Must be compatible with this index, if not NULL */
-){
- WhereTerm *pTerm;
- int k;
- assert( iCur>=0 );
- op &= WO_ALL;
- for(pTerm=pWC->a, k=pWC->nTerm; k; k--, pTerm++){
- if( pTerm->leftCursor==iCur
- && (pTerm->prereqRight & notReady)==0
- && pTerm->u.leftColumn==iColumn
- && (pTerm->eOperator & op)!=0
- ){
- if( pIdx && pTerm->eOperator!=WO_ISNULL ){
- Expr *pX = pTerm->pExpr;
- CollSeq *pColl;
- char idxaff;
- int j;
- Parse *pParse = pWC->pParse;
-
- idxaff = pIdx->pTable->aCol[iColumn].affinity;
- if( !sqlite3IndexAffinityOk(pX, idxaff) ) continue;
-
- /* Figure out the collation sequence required from an index for
- ** it to be useful for optimising expression pX. Store this
- ** value in variable pColl.
- */
- assert(pX->pLeft);
- pColl = sqlite3BinaryCompareCollSeq(pParse, pX->pLeft, pX->pRight);
- assert(pColl || pParse->nErr);
-
- for(j=0; pIdx->aiColumn[j]!=iColumn; j++){
- if( NEVER(j>=pIdx->nColumn) ) return 0;
- }
- if( pColl && sqlite3StrICmp(pColl->zName, pIdx->azColl[j]) ) continue;
- }
- return pTerm;
- }
- }
- return 0;
-}
-
-/* Forward reference */
-static void exprAnalyze(SrcList*, WhereClause*, int);
-
-/*
-** Call exprAnalyze on all terms in a WHERE clause.
-**
-**
-*/
-static void exprAnalyzeAll(
- SrcList *pTabList, /* the FROM clause */
- WhereClause *pWC /* the WHERE clause to be analyzed */
-){
- int i;
- for(i=pWC->nTerm-1; i>=0; i--){
- exprAnalyze(pTabList, pWC, i);
- }
-}
-
-#ifndef SQLITE_OMIT_LIKE_OPTIMIZATION
-/*
-** Check to see if the given expression is a LIKE or GLOB operator that
-** can be optimized using inequality constraints. Return TRUE if it is
-** so and false if not.
-**
-** In order for the operator to be optimizible, the RHS must be a string
-** literal that does not begin with a wildcard.
-*/
-static int isLikeOrGlob(
- Parse *pParse, /* Parsing and code generating context */
- Expr *pExpr, /* Test this expression */
- int *pnPattern, /* Number of non-wildcard prefix characters */
- int *pisComplete, /* True if the only wildcard is % in the last character */
- int *pnoCase /* True if uppercase is equivalent to lowercase */
-){
- const char *z; /* String on RHS of LIKE operator */
- Expr *pRight, *pLeft; /* Right and left size of LIKE operator */
- ExprList *pList; /* List of operands to the LIKE operator */
- int c; /* One character in z[] */
- int cnt; /* Number of non-wildcard prefix characters */
- char wc[3]; /* Wildcard characters */
- CollSeq *pColl; /* Collating sequence for LHS */
- sqlite3 *db = pParse->db; /* Database connection */
-
- if( !sqlite3IsLikeFunction(db, pExpr, pnoCase, wc) ){
- return 0;
- }
-#ifdef SQLITE_EBCDIC
- if( *pnoCase ) return 0;
-#endif
- pList = pExpr->x.pList;
- pRight = pList->a[0].pExpr;
- if( pRight->op!=TK_STRING ){
- return 0;
- }
- pLeft = pList->a[1].pExpr;
- if( pLeft->op!=TK_COLUMN ){
- return 0;
- }
- pColl = sqlite3ExprCollSeq(pParse, pLeft);
- assert( pColl!=0 || pLeft->iColumn==-1 );
- if( pColl==0 ) return 0;
- if( (pColl->type!=SQLITE_COLL_BINARY || *pnoCase) &&
- (pColl->type!=SQLITE_COLL_NOCASE || !*pnoCase) ){
- return 0;
- }
- if( sqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT ) return 0;
- z = pRight->u.zToken;
- if( ALWAYS(z) ){
- cnt = 0;
- while( (c=z[cnt])!=0 && c!=wc[0] && c!=wc[1] && c!=wc[2] ){
- cnt++;
- }
- if( cnt!=0 && c!=0 && 255!=(u8)z[cnt-1] ){
- *pisComplete = z[cnt]==wc[0] && z[cnt+1]==0;
- *pnPattern = cnt;
- return 1;
- }
- }
- return 0;
-}
-#endif /* SQLITE_OMIT_LIKE_OPTIMIZATION */
-
-
-#ifndef SQLITE_OMIT_VIRTUALTABLE
-/*
-** Check to see if the given expression is of the form
-**
-** column MATCH expr
-**
-** If it is then return TRUE. If not, return FALSE.
-*/
-static int isMatchOfColumn(
- Expr *pExpr /* Test this expression */
-){
- ExprList *pList;
-
- if( pExpr->op!=TK_FUNCTION ){
- return 0;
- }
- if( sqlite3StrICmp(pExpr->u.zToken,"match")!=0 ){
- return 0;
- }
- pList = pExpr->x.pList;
- if( pList->nExpr!=2 ){
- return 0;
- }
- if( pList->a[1].pExpr->op != TK_COLUMN ){
- return 0;
- }
- return 1;
-}
-#endif /* SQLITE_OMIT_VIRTUALTABLE */
-
-/*
-** If the pBase expression originated in the ON or USING clause of
-** a join, then transfer the appropriate markings over to derived.
-*/
-static void transferJoinMarkings(Expr *pDerived, Expr *pBase){
- pDerived->flags |= pBase->flags & EP_FromJoin;
- pDerived->iRightJoinTable = pBase->iRightJoinTable;
-}
-
-#if !defined(SQLITE_OMIT_OR_OPTIMIZATION) && !defined(SQLITE_OMIT_SUBQUERY)
-/*
-** Analyze a term that consists of two or more OR-connected
-** subterms. So in:
-**
-** ... WHERE (a=5) AND (b=7 OR c=9 OR d=13) AND (d=13)
-** ^^^^^^^^^^^^^^^^^^^^
-**
-** This routine analyzes terms such as the middle term in the above example.
-** A WhereOrTerm object is computed and attached to the term under
-** analysis, regardless of the outcome of the analysis. Hence:
-**
-** WhereTerm.wtFlags |= TERM_ORINFO
-** WhereTerm.u.pOrInfo = a dynamically allocated WhereOrTerm object
-**
-** The term being analyzed must have two or more of OR-connected subterms.
-** A single subterm might be a set of AND-connected sub-subterms.
-** Examples of terms under analysis:
-**
-** (A) t1.x=t2.y OR t1.x=t2.z OR t1.y=15 OR t1.z=t3.a+5
-** (B) x=expr1 OR expr2=x OR x=expr3
-** (C) t1.x=t2.y OR (t1.x=t2.z AND t1.y=15)
-** (D) x=expr1 OR (y>11 AND y<22 AND z LIKE '*hello*')
-** (E) (p.a=1 AND q.b=2 AND r.c=3) OR (p.x=4 AND q.y=5 AND r.z=6)
-**
-** CASE 1:
-**
-** If all subterms are of the form T.C=expr for some single column of C
-** a single table T (as shown in example B above) then create a new virtual
-** term that is an equivalent IN expression. In other words, if the term
-** being analyzed is:
-**
-** x = expr1 OR expr2 = x OR x = expr3
-**
-** then create a new virtual term like this:
-**
-** x IN (expr1,expr2,expr3)
-**
-** CASE 2:
-**
-** If all subterms are indexable by a single table T, then set
-**
-** WhereTerm.eOperator = WO_OR
-** WhereTerm.u.pOrInfo->indexable |= the cursor number for table T
-**
-** A subterm is "indexable" if it is of the form
-** "T.C <op> <expr>" where C is any column of table T and
-** <op> is one of "=", "<", "<=", ">", ">=", "IS NULL", or "IN".
-** A subterm is also indexable if it is an AND of two or more
-** subsubterms at least one of which is indexable. Indexable AND
-** subterms have their eOperator set to WO_AND and they have
-** u.pAndInfo set to a dynamically allocated WhereAndTerm object.
-**
-** From another point of view, "indexable" means that the subterm could
-** potentially be used with an index if an appropriate index exists.
-** This analysis does not consider whether or not the index exists; that
-** is something the bestIndex() routine will determine. This analysis
-** only looks at whether subterms appropriate for indexing exist.
-**
-** All examples A through E above all satisfy case 2. But if a term
-** also statisfies case 1 (such as B) we know that the optimizer will
-** always prefer case 1, so in that case we pretend that case 2 is not
-** satisfied.
-**
-** It might be the case that multiple tables are indexable. For example,
-** (E) above is indexable on tables P, Q, and R.
-**
-** Terms that satisfy case 2 are candidates for lookup by using
-** separate indices to find rowids for each subterm and composing
-** the union of all rowids using a RowSet object. This is similar
-** to "bitmap indices" in other database engines.
-**
-** OTHERWISE:
-**
-** If neither case 1 nor case 2 apply, then leave the eOperator set to
-** zero. This term is not useful for search.
-*/
-static void exprAnalyzeOrTerm(
- SrcList *pSrc, /* the FROM clause */
- WhereClause *pWC, /* the complete WHERE clause */
- int idxTerm /* Index of the OR-term to be analyzed */
-){
- Parse *pParse = pWC->pParse; /* Parser context */
- sqlite3 *db = pParse->db; /* Database connection */
- WhereTerm *pTerm = &pWC->a[idxTerm]; /* The term to be analyzed */
- Expr *pExpr = pTerm->pExpr; /* The expression of the term */
- WhereMaskSet *pMaskSet = pWC->pMaskSet; /* Table use masks */
- int i; /* Loop counters */
- WhereClause *pOrWc; /* Breakup of pTerm into subterms */
- WhereTerm *pOrTerm; /* A Sub-term within the pOrWc */
- WhereOrInfo *pOrInfo; /* Additional information associated with pTerm */
- Bitmask chngToIN; /* Tables that might satisfy case 1 */
- Bitmask indexable; /* Tables that are indexable, satisfying case 2 */
-
- /*
- ** Break the OR clause into its separate subterms. The subterms are
- ** stored in a WhereClause structure containing within the WhereOrInfo
- ** object that is attached to the original OR clause term.
- */
- assert( (pTerm->wtFlags & (TERM_DYNAMIC|TERM_ORINFO|TERM_ANDINFO))==0 );
- assert( pExpr->op==TK_OR );
- pTerm->u.pOrInfo = pOrInfo = sqlite3DbMallocZero(db, sizeof(*pOrInfo));
- if( pOrInfo==0 ) return;
- pTerm->wtFlags |= TERM_ORINFO;
- pOrWc = &pOrInfo->wc;
- whereClauseInit(pOrWc, pWC->pParse, pMaskSet);
- whereSplit(pOrWc, pExpr, TK_OR);
- exprAnalyzeAll(pSrc, pOrWc);
- if( db->mallocFailed ) return;
- assert( pOrWc->nTerm>=2 );
-
- /*
- ** Compute the set of tables that might satisfy cases 1 or 2.
- */
- indexable = ~(Bitmask)0;
- chngToIN = ~(pWC->vmask);
- for(i=pOrWc->nTerm-1, pOrTerm=pOrWc->a; i>=0 && indexable; i--, pOrTerm++){
- if( (pOrTerm->eOperator & WO_SINGLE)==0 ){
- WhereAndInfo *pAndInfo;
- assert( pOrTerm->eOperator==0 );
- assert( (pOrTerm->wtFlags & (TERM_ANDINFO|TERM_ORINFO))==0 );
- chngToIN = 0;
- pAndInfo = sqlite3DbMallocRaw(db, sizeof(*pAndInfo));
- if( pAndInfo ){
- WhereClause *pAndWC;
- WhereTerm *pAndTerm;
- int j;
- Bitmask b = 0;
- pOrTerm->u.pAndInfo = pAndInfo;
- pOrTerm->wtFlags |= TERM_ANDINFO;
- pOrTerm->eOperator = WO_AND;
- pAndWC = &pAndInfo->wc;
- whereClauseInit(pAndWC, pWC->pParse, pMaskSet);
- whereSplit(pAndWC, pOrTerm->pExpr, TK_AND);
- exprAnalyzeAll(pSrc, pAndWC);
- testcase( db->mallocFailed );
- if( !db->mallocFailed ){
- for(j=0, pAndTerm=pAndWC->a; j<pAndWC->nTerm; j++, pAndTerm++){
- assert( pAndTerm->pExpr );
- if( allowedOp(pAndTerm->pExpr->op) ){
- b |= getMask(pMaskSet, pAndTerm->leftCursor);
- }
- }
- }
- indexable &= b;
- }
- }else if( pOrTerm->wtFlags & TERM_COPIED ){
- /* Skip this term for now. We revisit it when we process the
- ** corresponding TERM_VIRTUAL term */
- }else{
- Bitmask b;
- b = getMask(pMaskSet, pOrTerm->leftCursor);
- if( pOrTerm->wtFlags & TERM_VIRTUAL ){
- WhereTerm *pOther = &pOrWc->a[pOrTerm->iParent];
- b |= getMask(pMaskSet, pOther->leftCursor);
- }
- indexable &= b;
- if( pOrTerm->eOperator!=WO_EQ ){
- chngToIN = 0;
- }else{
- chngToIN &= b;
- }
- }
- }
-
- /*
- ** Record the set of tables that satisfy case 2. The set might be
- ** empty.
- */
- pOrInfo->indexable = indexable;
- pTerm->eOperator = indexable==0 ? 0 : WO_OR;
-
- /*
- ** chngToIN holds a set of tables that *might* satisfy case 1. But
- ** we have to do some additional checking to see if case 1 really
- ** is satisfied.
- **
- ** chngToIN will hold either 0, 1, or 2 bits. The 0-bit case means
- ** that there is no possibility of transforming the OR clause into an
- ** IN operator because one or more terms in the OR clause contain
- ** something other than == on a column in the single table. The 1-bit
- ** case means that every term of the OR clause is of the form
- ** "table.column=expr" for some single table. The one bit that is set
- ** will correspond to the common table. We still need to check to make
- ** sure the same column is used on all terms. The 2-bit case is when
- ** the all terms are of the form "table1.column=table2.column". It
- ** might be possible to form an IN operator with either table1.column
- ** or table2.column as the LHS if either is common to every term of
- ** the OR clause.
- **
- ** Note that terms of the form "table.column1=table.column2" (the
- ** same table on both sizes of the ==) cannot be optimized.
- */
- if( chngToIN ){
- int okToChngToIN = 0; /* True if the conversion to IN is valid */
- int iColumn = -1; /* Column index on lhs of IN operator */
- int iCursor = -1; /* Table cursor common to all terms */
- int j = 0; /* Loop counter */
-
- /* Search for a table and column that appears on one side or the
- ** other of the == operator in every subterm. That table and column
- ** will be recorded in iCursor and iColumn. There might not be any
- ** such table and column. Set okToChngToIN if an appropriate table
- ** and column is found but leave okToChngToIN false if not found.
- */
- for(j=0; j<2 && !okToChngToIN; j++){
- pOrTerm = pOrWc->a;
- for(i=pOrWc->nTerm-1; i>=0; i--, pOrTerm++){
- assert( pOrTerm->eOperator==WO_EQ );
- pOrTerm->wtFlags &= ~TERM_OR_OK;
- if( pOrTerm->leftCursor==iCursor ){
- /* This is the 2-bit case and we are on the second iteration and
- ** current term is from the first iteration. So skip this term. */
- assert( j==1 );
- continue;
- }
- if( (chngToIN & getMask(pMaskSet, pOrTerm->leftCursor))==0 ){
- /* This term must be of the form t1.a==t2.b where t2 is in the
- ** chngToIN set but t1 is not. This term will be either preceeded
- ** or follwed by an inverted copy (t2.b==t1.a). Skip this term
- ** and use its inversion. */
- testcase( pOrTerm->wtFlags & TERM_COPIED );
- testcase( pOrTerm->wtFlags & TERM_VIRTUAL );
- assert( pOrTerm->wtFlags & (TERM_COPIED|TERM_VIRTUAL) );
- continue;
- }
- iColumn = pOrTerm->u.leftColumn;
- iCursor = pOrTerm->leftCursor;
- break;
- }
- if( i<0 ){
- /* No candidate table+column was found. This can only occur
- ** on the second iteration */
- assert( j==1 );
- assert( (chngToIN&(chngToIN-1))==0 );
- assert( chngToIN==getMask(pMaskSet, iCursor) );
- break;
- }
- testcase( j==1 );
-
- /* We have found a candidate table and column. Check to see if that
- ** table and column is common to every term in the OR clause */
- okToChngToIN = 1;
- for(; i>=0 && okToChngToIN; i--, pOrTerm++){
- assert( pOrTerm->eOperator==WO_EQ );
- if( pOrTerm->leftCursor!=iCursor ){
- pOrTerm->wtFlags &= ~TERM_OR_OK;
- }else if( pOrTerm->u.leftColumn!=iColumn ){
- okToChngToIN = 0;
- }else{
- int affLeft, affRight;
- /* If the right-hand side is also a column, then the affinities
- ** of both right and left sides must be such that no type
- ** conversions are required on the right. (Ticket #2249)
- */
- affRight = sqlite3ExprAffinity(pOrTerm->pExpr->pRight);
- affLeft = sqlite3ExprAffinity(pOrTerm->pExpr->pLeft);
- if( affRight!=0 && affRight!=affLeft ){
- okToChngToIN = 0;
- }else{
- pOrTerm->wtFlags |= TERM_OR_OK;
- }
- }
- }
- }
-
- /* At this point, okToChngToIN is true if original pTerm satisfies
- ** case 1. In that case, construct a new virtual term that is
- ** pTerm converted into an IN operator.
- */
- if( okToChngToIN ){
- Expr *pDup; /* A transient duplicate expression */
- ExprList *pList = 0; /* The RHS of the IN operator */
- Expr *pLeft = 0; /* The LHS of the IN operator */
- Expr *pNew; /* The complete IN operator */
-
- for(i=pOrWc->nTerm-1, pOrTerm=pOrWc->a; i>=0; i--, pOrTerm++){
- if( (pOrTerm->wtFlags & TERM_OR_OK)==0 ) continue;
- assert( pOrTerm->eOperator==WO_EQ );
- assert( pOrTerm->leftCursor==iCursor );
- assert( pOrTerm->u.leftColumn==iColumn );
- pDup = sqlite3ExprDup(db, pOrTerm->pExpr->pRight, 0);
- pList = sqlite3ExprListAppend(pWC->pParse, pList, pDup);
- pLeft = pOrTerm->pExpr->pLeft;
- }
- assert( pLeft!=0 );
- pDup = sqlite3ExprDup(db, pLeft, 0);
- pNew = sqlite3PExpr(pParse, TK_IN, pDup, 0, 0);
- if( pNew ){
- int idxNew;
- transferJoinMarkings(pNew, pExpr);
- assert( !ExprHasProperty(pNew, EP_xIsSelect) );
- pNew->x.pList = pList;
- idxNew = whereClauseInsert(pWC, pNew, TERM_VIRTUAL|TERM_DYNAMIC);
- testcase( idxNew==0 );
- exprAnalyze(pSrc, pWC, idxNew);
- pTerm = &pWC->a[idxTerm];
- pWC->a[idxNew].iParent = idxTerm;
- pTerm->nChild = 1;
- }else{
- sqlite3ExprListDelete(db, pList);
- }
- pTerm->eOperator = 0; /* case 1 trumps case 2 */
- }
- }
-}
-#endif /* !SQLITE_OMIT_OR_OPTIMIZATION && !SQLITE_OMIT_SUBQUERY */
-
-
-/*
-** The input to this routine is an WhereTerm structure with only the
-** "pExpr" field filled in. The job of this routine is to analyze the
-** subexpression and populate all the other fields of the WhereTerm
-** structure.
-**
-** If the expression is of the form "<expr> <op> X" it gets commuted
-** to the standard form of "X <op> <expr>".
-**
-** If the expression is of the form "X <op> Y" where both X and Y are
-** columns, then the original expression is unchanged and a new virtual
-** term of the form "Y <op> X" is added to the WHERE clause and
-** analyzed separately. The original term is marked with TERM_COPIED
-** and the new term is marked with TERM_DYNAMIC (because it's pExpr
-** needs to be freed with the WhereClause) and TERM_VIRTUAL (because it
-** is a commuted copy of a prior term.) The original term has nChild=1
-** and the copy has idxParent set to the index of the original term.
-*/
-static void exprAnalyze(
- SrcList *pSrc, /* the FROM clause */
- WhereClause *pWC, /* the WHERE clause */
- int idxTerm /* Index of the term to be analyzed */
-){
- WhereTerm *pTerm; /* The term to be analyzed */
- WhereMaskSet *pMaskSet; /* Set of table index masks */
- Expr *pExpr; /* The expression to be analyzed */
- Bitmask prereqLeft; /* Prerequesites of the pExpr->pLeft */
- Bitmask prereqAll; /* Prerequesites of pExpr */
- Bitmask extraRight = 0;
- int nPattern;
- int isComplete;
- int noCase;
- int op; /* Top-level operator. pExpr->op */
- Parse *pParse = pWC->pParse; /* Parsing context */
- sqlite3 *db = pParse->db; /* Database connection */
-
- if( db->mallocFailed ){
- return;
- }
- pTerm = &pWC->a[idxTerm];
- pMaskSet = pWC->pMaskSet;
- pExpr = pTerm->pExpr;
- prereqLeft = exprTableUsage(pMaskSet, pExpr->pLeft);
- op = pExpr->op;
- if( op==TK_IN ){
- assert( pExpr->pRight==0 );
- if( ExprHasProperty(pExpr, EP_xIsSelect) ){
- pTerm->prereqRight = exprSelectTableUsage(pMaskSet, pExpr->x.pSelect);
- }else{
- pTerm->prereqRight = exprListTableUsage(pMaskSet, pExpr->x.pList);
- }
- }else if( op==TK_ISNULL ){
- pTerm->prereqRight = 0;
- }else{
- pTerm->prereqRight = exprTableUsage(pMaskSet, pExpr->pRight);
- }
- prereqAll = exprTableUsage(pMaskSet, pExpr);
- if( ExprHasProperty(pExpr, EP_FromJoin) ){
- Bitmask x = getMask(pMaskSet, pExpr->iRightJoinTable);
- prereqAll |= x;
- extraRight = x-1; /* ON clause terms may not be used with an index
- ** on left table of a LEFT JOIN. Ticket #3015 */
- }
- pTerm->prereqAll = prereqAll;
- pTerm->leftCursor = -1;
- pTerm->iParent = -1;
- pTerm->eOperator = 0;
- if( allowedOp(op) && (pTerm->prereqRight & prereqLeft)==0 ){
- Expr *pLeft = pExpr->pLeft;
- Expr *pRight = pExpr->pRight;
- if( pLeft->op==TK_COLUMN ){
- pTerm->leftCursor = pLeft->iTable;
- pTerm->u.leftColumn = pLeft->iColumn;
- pTerm->eOperator = operatorMask(op);
- }
- if( pRight && pRight->op==TK_COLUMN ){
- WhereTerm *pNew;
- Expr *pDup;
- if( pTerm->leftCursor>=0 ){
- int idxNew;
- pDup = sqlite3ExprDup(db, pExpr, 0);
- if( db->mallocFailed ){
- sqlite3ExprDelete(db, pDup);
- return;
- }
- idxNew = whereClauseInsert(pWC, pDup, TERM_VIRTUAL|TERM_DYNAMIC);
- if( idxNew==0 ) return;
- pNew = &pWC->a[idxNew];
- pNew->iParent = idxTerm;
- pTerm = &pWC->a[idxTerm];
- pTerm->nChild = 1;
- pTerm->wtFlags |= TERM_COPIED;
- }else{
- pDup = pExpr;
- pNew = pTerm;
- }
- exprCommute(pParse, pDup);
- pLeft = pDup->pLeft;
- pNew->leftCursor = pLeft->iTable;
- pNew->u.leftColumn = pLeft->iColumn;
- pNew->prereqRight = prereqLeft;
- pNew->prereqAll = prereqAll;
- pNew->eOperator = operatorMask(pDup->op);
- }
- }
-
-#ifndef SQLITE_OMIT_BETWEEN_OPTIMIZATION
- /* If a term is the BETWEEN operator, create two new virtual terms
- ** that define the range that the BETWEEN implements. For example:
- **
- ** a BETWEEN b AND c
- **
- ** is converted into:
- **
- ** (a BETWEEN b AND c) AND (a>=b) AND (a<=c)
- **
- ** The two new terms are added onto the end of the WhereClause object.
- ** The new terms are "dynamic" and are children of the original BETWEEN
- ** term. That means that if the BETWEEN term is coded, the children are
- ** skipped. Or, if the children are satisfied by an index, the original
- ** BETWEEN term is skipped.
- */
- else if( pExpr->op==TK_BETWEEN && pWC->op==TK_AND ){
- ExprList *pList = pExpr->x.pList;
- int i;
- static const u8 ops[] = {TK_GE, TK_LE};
- assert( pList!=0 );
- assert( pList->nExpr==2 );
- for(i=0; i<2; i++){
- Expr *pNewExpr;
- int idxNew;
- pNewExpr = sqlite3PExpr(pParse, ops[i],
- sqlite3ExprDup(db, pExpr->pLeft, 0),
- sqlite3ExprDup(db, pList->a[i].pExpr, 0), 0);
- idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC);
- testcase( idxNew==0 );
- exprAnalyze(pSrc, pWC, idxNew);
- pTerm = &pWC->a[idxTerm];
- pWC->a[idxNew].iParent = idxTerm;
- }
- pTerm->nChild = 2;
- }
-#endif /* SQLITE_OMIT_BETWEEN_OPTIMIZATION */
-
-#if !defined(SQLITE_OMIT_OR_OPTIMIZATION) && !defined(SQLITE_OMIT_SUBQUERY)
- /* Analyze a term that is composed of two or more subterms connected by
- ** an OR operator.
- */
- else if( pExpr->op==TK_OR ){
- assert( pWC->op==TK_AND );
- exprAnalyzeOrTerm(pSrc, pWC, idxTerm);
- pTerm = &pWC->a[idxTerm];
- }
-#endif /* SQLITE_OMIT_OR_OPTIMIZATION */
-
-#ifndef SQLITE_OMIT_LIKE_OPTIMIZATION
- /* Add constraints to reduce the search space on a LIKE or GLOB
- ** operator.
- **
- ** A like pattern of the form "x LIKE 'abc%'" is changed into constraints
- **
- ** x>='abc' AND x<'abd' AND x LIKE 'abc%'
- **
- ** The last character of the prefix "abc" is incremented to form the
- ** termination condition "abd".
- */
- if( isLikeOrGlob(pParse, pExpr, &nPattern, &isComplete, &noCase)
- && pWC->op==TK_AND ){
- Expr *pLeft, *pRight;
- Expr *pStr1, *pStr2;
- Expr *pNewExpr1, *pNewExpr2;
- int idxNew1, idxNew2;
-
- pLeft = pExpr->x.pList->a[1].pExpr;
- pRight = pExpr->x.pList->a[0].pExpr;
- pStr1 = sqlite3Expr(db, TK_STRING, pRight->u.zToken);
- if( pStr1 ) pStr1->u.zToken[nPattern] = 0;
- pStr2 = sqlite3ExprDup(db, pStr1, 0);
- if( !db->mallocFailed ){
- u8 c, *pC; /* Last character before the first wildcard */
- pC = (u8*)&pStr2->u.zToken[nPattern-1];
- c = *pC;
- if( noCase ){
- /* The point is to increment the last character before the first
- ** wildcard. But if we increment '@', that will push it into the
- ** alphabetic range where case conversions will mess up the
- ** inequality. To avoid this, make sure to also run the full
- ** LIKE on all candidate expressions by clearing the isComplete flag
- */
- if( c=='A'-1 ) isComplete = 0;
-
- c = sqlite3UpperToLower[c];
- }
- *pC = c + 1;
- }
- pNewExpr1 = sqlite3PExpr(pParse, TK_GE, sqlite3ExprDup(db,pLeft,0),pStr1,0);
- idxNew1 = whereClauseInsert(pWC, pNewExpr1, TERM_VIRTUAL|TERM_DYNAMIC);
- testcase( idxNew1==0 );
- exprAnalyze(pSrc, pWC, idxNew1);
- pNewExpr2 = sqlite3PExpr(pParse, TK_LT, sqlite3ExprDup(db,pLeft,0),pStr2,0);
- idxNew2 = whereClauseInsert(pWC, pNewExpr2, TERM_VIRTUAL|TERM_DYNAMIC);
- testcase( idxNew2==0 );
- exprAnalyze(pSrc, pWC, idxNew2);
- pTerm = &pWC->a[idxTerm];
- if( isComplete ){
- pWC->a[idxNew1].iParent = idxTerm;
- pWC->a[idxNew2].iParent = idxTerm;
- pTerm->nChild = 2;
- }
- }
-#endif /* SQLITE_OMIT_LIKE_OPTIMIZATION */
-
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- /* Add a WO_MATCH auxiliary term to the constraint set if the
- ** current expression is of the form: column MATCH expr.
- ** This information is used by the xBestIndex methods of
- ** virtual tables. The native query optimizer does not attempt
- ** to do anything with MATCH functions.
- */
- if( isMatchOfColumn(pExpr) ){
- int idxNew;
- Expr *pRight, *pLeft;
- WhereTerm *pNewTerm;
- Bitmask prereqColumn, prereqExpr;
-
- pRight = pExpr->x.pList->a[0].pExpr;
- pLeft = pExpr->x.pList->a[1].pExpr;
- prereqExpr = exprTableUsage(pMaskSet, pRight);
- prereqColumn = exprTableUsage(pMaskSet, pLeft);
- if( (prereqExpr & prereqColumn)==0 ){
- Expr *pNewExpr;
- pNewExpr = sqlite3PExpr(pParse, TK_MATCH,
- 0, sqlite3ExprDup(db, pRight, 0), 0);
- idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC);
- testcase( idxNew==0 );
- pNewTerm = &pWC->a[idxNew];
- pNewTerm->prereqRight = prereqExpr;
- pNewTerm->leftCursor = pLeft->iTable;
- pNewTerm->u.leftColumn = pLeft->iColumn;
- pNewTerm->eOperator = WO_MATCH;
- pNewTerm->iParent = idxTerm;
- pTerm = &pWC->a[idxTerm];
- pTerm->nChild = 1;
- pTerm->wtFlags |= TERM_COPIED;
- pNewTerm->prereqAll = pTerm->prereqAll;
- }
- }
-#endif /* SQLITE_OMIT_VIRTUALTABLE */
-
- /* Prevent ON clause terms of a LEFT JOIN from being used to drive
- ** an index for tables to the left of the join.
- */
- pTerm->prereqRight |= extraRight;
-}
-
-/*
-** Return TRUE if any of the expressions in pList->a[iFirst...] contain
-** a reference to any table other than the iBase table.
-*/
-static int referencesOtherTables(
- ExprList *pList, /* Search expressions in ths list */
- WhereMaskSet *pMaskSet, /* Mapping from tables to bitmaps */
- int iFirst, /* Be searching with the iFirst-th expression */
- int iBase /* Ignore references to this table */
-){
- Bitmask allowed = ~getMask(pMaskSet, iBase);
- while( iFirst<pList->nExpr ){
- if( (exprTableUsage(pMaskSet, pList->a[iFirst++].pExpr)&allowed)!=0 ){
- return 1;
- }
- }
- return 0;
-}
-
-
-/*
-** This routine decides if pIdx can be used to satisfy the ORDER BY
-** clause. If it can, it returns 1. If pIdx cannot satisfy the
-** ORDER BY clause, this routine returns 0.
-**
-** pOrderBy is an ORDER BY clause from a SELECT statement. pTab is the
-** left-most table in the FROM clause of that same SELECT statement and
-** the table has a cursor number of "base". pIdx is an index on pTab.
-**
-** nEqCol is the number of columns of pIdx that are used as equality
-** constraints. Any of these columns may be missing from the ORDER BY
-** clause and the match can still be a success.
-**
-** All terms of the ORDER BY that match against the index must be either
-** ASC or DESC. (Terms of the ORDER BY clause past the end of a UNIQUE
-** index do not need to satisfy this constraint.) The *pbRev value is
-** set to 1 if the ORDER BY clause is all DESC and it is set to 0 if
-** the ORDER BY clause is all ASC.
-*/
-static int isSortingIndex(
- Parse *pParse, /* Parsing context */
- WhereMaskSet *pMaskSet, /* Mapping from table cursor numbers to bitmaps */
- Index *pIdx, /* The index we are testing */
- int base, /* Cursor number for the table to be sorted */
- ExprList *pOrderBy, /* The ORDER BY clause */
- int nEqCol, /* Number of index columns with == constraints */
- int *pbRev /* Set to 1 if ORDER BY is DESC */
-){
- int i, j; /* Loop counters */
- int sortOrder = 0; /* XOR of index and ORDER BY sort direction */
- int nTerm; /* Number of ORDER BY terms */
- struct ExprList_item *pTerm; /* A term of the ORDER BY clause */
- sqlite3 *db = pParse->db;
-
- assert( pOrderBy!=0 );
- nTerm = pOrderBy->nExpr;
- assert( nTerm>0 );
-
- /* Argument pIdx must either point to a 'real' named index structure,
- ** or an index structure allocated on the stack by bestBtreeIndex() to
- ** represent the rowid index that is part of every table. */
- assert( pIdx->zName || (pIdx->nColumn==1 && pIdx->aiColumn[0]==-1) );
-
- /* Match terms of the ORDER BY clause against columns of
- ** the index.
- **
- ** Note that indices have pIdx->nColumn regular columns plus
- ** one additional column containing the rowid. The rowid column
- ** of the index is also allowed to match against the ORDER BY
- ** clause.
- */
- for(i=j=0, pTerm=pOrderBy->a; j<nTerm && i<=pIdx->nColumn; i++){
- Expr *pExpr; /* The expression of the ORDER BY pTerm */
- CollSeq *pColl; /* The collating sequence of pExpr */
- int termSortOrder; /* Sort order for this term */
- int iColumn; /* The i-th column of the index. -1 for rowid */
- int iSortOrder; /* 1 for DESC, 0 for ASC on the i-th index term */
- const char *zColl; /* Name of the collating sequence for i-th index term */
-
- pExpr = pTerm->pExpr;
- if( pExpr->op!=TK_COLUMN || pExpr->iTable!=base ){
- /* Can not use an index sort on anything that is not a column in the
- ** left-most table of the FROM clause */
- break;
- }
- pColl = sqlite3ExprCollSeq(pParse, pExpr);
- if( !pColl ){
- pColl = db->pDfltColl;
- }
- if( pIdx->zName && i<pIdx->nColumn ){
- iColumn = pIdx->aiColumn[i];
- if( iColumn==pIdx->pTable->iPKey ){
- iColumn = -1;
- }
- iSortOrder = pIdx->aSortOrder[i];
- zColl = pIdx->azColl[i];
- }else{
- iColumn = -1;
- iSortOrder = 0;
- zColl = pColl->zName;
- }
- if( pExpr->iColumn!=iColumn || sqlite3StrICmp(pColl->zName, zColl) ){
- /* Term j of the ORDER BY clause does not match column i of the index */
- if( i<nEqCol ){
- /* If an index column that is constrained by == fails to match an
- ** ORDER BY term, that is OK. Just ignore that column of the index
- */
- continue;
- }else if( i==pIdx->nColumn ){
- /* Index column i is the rowid. All other terms match. */
- break;
- }else{
- /* If an index column fails to match and is not constrained by ==
- ** then the index cannot satisfy the ORDER BY constraint.
- */
- return 0;
- }
- }
- assert( pIdx->aSortOrder!=0 || iColumn==-1 );
- assert( pTerm->sortOrder==0 || pTerm->sortOrder==1 );
- assert( iSortOrder==0 || iSortOrder==1 );
- termSortOrder = iSortOrder ^ pTerm->sortOrder;
- if( i>nEqCol ){
- if( termSortOrder!=sortOrder ){
- /* Indices can only be used if all ORDER BY terms past the
- ** equality constraints are all either DESC or ASC. */
- return 0;
- }
- }else{
- sortOrder = termSortOrder;
- }
- j++;
- pTerm++;
- if( iColumn<0 && !referencesOtherTables(pOrderBy, pMaskSet, j, base) ){
- /* If the indexed column is the primary key and everything matches
- ** so far and none of the ORDER BY terms to the right reference other
- ** tables in the join, then we are assured that the index can be used
- ** to sort because the primary key is unique and so none of the other
- ** columns will make any difference
- */
- j = nTerm;
- }
- }
-
- *pbRev = sortOrder!=0;
- if( j>=nTerm ){
- /* All terms of the ORDER BY clause are covered by this index so
- ** this index can be used for sorting. */
- return 1;
- }
- if( pIdx->onError!=OE_None && i==pIdx->nColumn
- && !referencesOtherTables(pOrderBy, pMaskSet, j, base) ){
- /* All terms of this index match some prefix of the ORDER BY clause
- ** and the index is UNIQUE and no terms on the tail of the ORDER BY
- ** clause reference other tables in a join. If this is all true then
- ** the order by clause is superfluous. */
- return 1;
- }
- return 0;
-}
-
-/*
-** Prepare a crude estimate of the logarithm of the input value.
-** The results need not be exact. This is only used for estimating
-** the total cost of performing operations with O(logN) or O(NlogN)
-** complexity. Because N is just a guess, it is no great tragedy if
-** logN is a little off.
-*/
-static double estLog(double N){
- double logN = 1;
- double x = 10;
- while( N>x ){
- logN += 1;
- x *= 10;
- }
- return logN;
-}
-
-/*
-** Two routines for printing the content of an sqlite3_index_info
-** structure. Used for testing and debugging only. If neither
-** SQLITE_TEST or SQLITE_DEBUG are defined, then these routines
-** are no-ops.
-*/
-#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_DEBUG)
-static void TRACE_IDX_INPUTS(sqlite3_index_info *p){
- int i;
- if( !sqlite3WhereTrace ) return;
- for(i=0; i<p->nConstraint; i++){
- sqlite3DebugPrintf(" constraint[%d]: col=%d termid=%d op=%d usabled=%d\n",
- i,
- p->aConstraint[i].iColumn,
- p->aConstraint[i].iTermOffset,
- p->aConstraint[i].op,
- p->aConstraint[i].usable);
- }
- for(i=0; i<p->nOrderBy; i++){
- sqlite3DebugPrintf(" orderby[%d]: col=%d desc=%d\n",
- i,
- p->aOrderBy[i].iColumn,
- p->aOrderBy[i].desc);
- }
-}
-static void TRACE_IDX_OUTPUTS(sqlite3_index_info *p){
- int i;
- if( !sqlite3WhereTrace ) return;
- for(i=0; i<p->nConstraint; i++){
- sqlite3DebugPrintf(" usage[%d]: argvIdx=%d omit=%d\n",
- i,
- p->aConstraintUsage[i].argvIndex,
- p->aConstraintUsage[i].omit);
- }
- sqlite3DebugPrintf(" idxNum=%d\n", p->idxNum);
- sqlite3DebugPrintf(" idxStr=%s\n", p->idxStr);
- sqlite3DebugPrintf(" orderByConsumed=%d\n", p->orderByConsumed);
- sqlite3DebugPrintf(" estimatedCost=%g\n", p->estimatedCost);
-}
-#else
-#define TRACE_IDX_INPUTS(A)
-#define TRACE_IDX_OUTPUTS(A)
-#endif
-
-/*
-** Required because bestIndex() is called by bestOrClauseIndex()
-*/
-static void bestIndex(
- Parse*, WhereClause*, struct SrcList_item*, Bitmask, ExprList*, WhereCost*);
-
-/*
-** This routine attempts to find an scanning strategy that can be used
-** to optimize an 'OR' expression that is part of a WHERE clause.
-**
-** The table associated with FROM clause term pSrc may be either a
-** regular B-Tree table or a virtual table.
-*/
-static void bestOrClauseIndex(
- Parse *pParse, /* The parsing context */
- WhereClause *pWC, /* The WHERE clause */
- struct SrcList_item *pSrc, /* The FROM clause term to search */
- Bitmask notReady, /* Mask of cursors that are not available */
- ExprList *pOrderBy, /* The ORDER BY clause */
- WhereCost *pCost /* Lowest cost query plan */
-){
-#ifndef SQLITE_OMIT_OR_OPTIMIZATION
- const int iCur = pSrc->iCursor; /* The cursor of the table to be accessed */
- const Bitmask maskSrc = getMask(pWC->pMaskSet, iCur); /* Bitmask for pSrc */
- WhereTerm * const pWCEnd = &pWC->a[pWC->nTerm]; /* End of pWC->a[] */
- WhereTerm *pTerm; /* A single term of the WHERE clause */
-
- /* Search the WHERE clause terms for a usable WO_OR term. */
- for(pTerm=pWC->a; pTerm<pWCEnd; pTerm++){
- if( pTerm->eOperator==WO_OR
- && ((pTerm->prereqAll & ~maskSrc) & notReady)==0
- && (pTerm->u.pOrInfo->indexable & maskSrc)!=0
- ){
- WhereClause * const pOrWC = &pTerm->u.pOrInfo->wc;
- WhereTerm * const pOrWCEnd = &pOrWC->a[pOrWC->nTerm];
- WhereTerm *pOrTerm;
- int flags = WHERE_MULTI_OR;
- double rTotal = 0;
- double nRow = 0;
- Bitmask used = 0;
-
- for(pOrTerm=pOrWC->a; pOrTerm<pOrWCEnd; pOrTerm++){
- WhereCost sTermCost;
- WHERETRACE(("... Multi-index OR testing for term %d of %d....\n",
- (pOrTerm - pOrWC->a), (pTerm - pWC->a)
- ));
- if( pOrTerm->eOperator==WO_AND ){
- WhereClause *pAndWC = &pOrTerm->u.pAndInfo->wc;
- bestIndex(pParse, pAndWC, pSrc, notReady, 0, &sTermCost);
- }else if( pOrTerm->leftCursor==iCur ){
- WhereClause tempWC;
- tempWC.pParse = pWC->pParse;
- tempWC.pMaskSet = pWC->pMaskSet;
- tempWC.op = TK_AND;
- tempWC.a = pOrTerm;
- tempWC.nTerm = 1;
- bestIndex(pParse, &tempWC, pSrc, notReady, 0, &sTermCost);
- }else{
- continue;
- }
- rTotal += sTermCost.rCost;
- nRow += sTermCost.nRow;
- used |= sTermCost.used;
- if( rTotal>=pCost->rCost ) break;
- }
-
- /* If there is an ORDER BY clause, increase the scan cost to account
- ** for the cost of the sort. */
- if( pOrderBy!=0 ){
- rTotal += nRow*estLog(nRow);
- WHERETRACE(("... sorting increases OR cost to %.9g\n", rTotal));
- }
-
- /* If the cost of scanning using this OR term for optimization is
- ** less than the current cost stored in pCost, replace the contents
- ** of pCost. */
- WHERETRACE(("... multi-index OR cost=%.9g nrow=%.9g\n", rTotal, nRow));
- if( rTotal<pCost->rCost ){
- pCost->rCost = rTotal;
- pCost->nRow = nRow;
- pCost->used = used;
- pCost->plan.wsFlags = flags;
- pCost->plan.u.pTerm = pTerm;
- }
- }
- }
-#endif /* SQLITE_OMIT_OR_OPTIMIZATION */
-}
-
-#ifndef SQLITE_OMIT_VIRTUALTABLE
-/*
-** Allocate and populate an sqlite3_index_info structure. It is the
-** responsibility of the caller to eventually release the structure
-** by passing the pointer returned by this function to sqlite3_free().
-*/
-static sqlite3_index_info *allocateIndexInfo(
- Parse *pParse,
- WhereClause *pWC,
- struct SrcList_item *pSrc,
- ExprList *pOrderBy
-){
- int i, j;
- int nTerm;
- struct sqlite3_index_constraint *pIdxCons;
- struct sqlite3_index_orderby *pIdxOrderBy;
- struct sqlite3_index_constraint_usage *pUsage;
- WhereTerm *pTerm;
- int nOrderBy;
- sqlite3_index_info *pIdxInfo;
-
- WHERETRACE(("Recomputing index info for %s...\n", pSrc->pTab->zName));
-
- /* Count the number of possible WHERE clause constraints referring
- ** to this virtual table */
- for(i=nTerm=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
- if( pTerm->leftCursor != pSrc->iCursor ) continue;
- assert( (pTerm->eOperator&(pTerm->eOperator-1))==0 );
- testcase( pTerm->eOperator==WO_IN );
- testcase( pTerm->eOperator==WO_ISNULL );
- if( pTerm->eOperator & (WO_IN|WO_ISNULL) ) continue;
- nTerm++;
- }
-
- /* If the ORDER BY clause contains only columns in the current
- ** virtual table then allocate space for the aOrderBy part of
- ** the sqlite3_index_info structure.
- */
- nOrderBy = 0;
- if( pOrderBy ){
- for(i=0; i<pOrderBy->nExpr; i++){
- Expr *pExpr = pOrderBy->a[i].pExpr;
- if( pExpr->op!=TK_COLUMN || pExpr->iTable!=pSrc->iCursor ) break;
- }
- if( i==pOrderBy->nExpr ){
- nOrderBy = pOrderBy->nExpr;
- }
- }
-
- /* Allocate the sqlite3_index_info structure
- */
- pIdxInfo = sqlite3DbMallocZero(pParse->db, sizeof(*pIdxInfo)
- + (sizeof(*pIdxCons) + sizeof(*pUsage))*nTerm
- + sizeof(*pIdxOrderBy)*nOrderBy );
- if( pIdxInfo==0 ){
- sqlite3ErrorMsg(pParse, "out of memory");
- /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */
- return 0;
- }
-
- /* Initialize the structure. The sqlite3_index_info structure contains
- ** many fields that are declared "const" to prevent xBestIndex from
- ** changing them. We have to do some funky casting in order to
- ** initialize those fields.
- */
- pIdxCons = (struct sqlite3_index_constraint*)&pIdxInfo[1];
- pIdxOrderBy = (struct sqlite3_index_orderby*)&pIdxCons[nTerm];
- pUsage = (struct sqlite3_index_constraint_usage*)&pIdxOrderBy[nOrderBy];
- *(int*)&pIdxInfo->nConstraint = nTerm;
- *(int*)&pIdxInfo->nOrderBy = nOrderBy;
- *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint = pIdxCons;
- *(struct sqlite3_index_orderby**)&pIdxInfo->aOrderBy = pIdxOrderBy;
- *(struct sqlite3_index_constraint_usage**)&pIdxInfo->aConstraintUsage =
- pUsage;
-
- for(i=j=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
- if( pTerm->leftCursor != pSrc->iCursor ) continue;
- assert( (pTerm->eOperator&(pTerm->eOperator-1))==0 );
- testcase( pTerm->eOperator==WO_IN );
- testcase( pTerm->eOperator==WO_ISNULL );
- if( pTerm->eOperator & (WO_IN|WO_ISNULL) ) continue;
- pIdxCons[j].iColumn = pTerm->u.leftColumn;
- pIdxCons[j].iTermOffset = i;
- pIdxCons[j].op = (u8)pTerm->eOperator;
- /* The direct assignment in the previous line is possible only because
- ** the WO_ and SQLITE_INDEX_CONSTRAINT_ codes are identical. The
- ** following asserts verify this fact. */
- assert( WO_EQ==SQLITE_INDEX_CONSTRAINT_EQ );
- assert( WO_LT==SQLITE_INDEX_CONSTRAINT_LT );
- assert( WO_LE==SQLITE_INDEX_CONSTRAINT_LE );
- assert( WO_GT==SQLITE_INDEX_CONSTRAINT_GT );
- assert( WO_GE==SQLITE_INDEX_CONSTRAINT_GE );
- assert( WO_MATCH==SQLITE_INDEX_CONSTRAINT_MATCH );
- assert( pTerm->eOperator & (WO_EQ|WO_LT|WO_LE|WO_GT|WO_GE|WO_MATCH) );
- j++;
- }
- for(i=0; i<nOrderBy; i++){
- Expr *pExpr = pOrderBy->a[i].pExpr;
- pIdxOrderBy[i].iColumn = pExpr->iColumn;
- pIdxOrderBy[i].desc = pOrderBy->a[i].sortOrder;
- }
-
- return pIdxInfo;
-}
-
-/*
-** The table object reference passed as the second argument to this function
-** must represent a virtual table. This function invokes the xBestIndex()
-** method of the virtual table with the sqlite3_index_info pointer passed
-** as the argument.
-**
-** If an error occurs, pParse is populated with an error message and a
-** non-zero value is returned. Otherwise, 0 is returned and the output
-** part of the sqlite3_index_info structure is left populated.
-**
-** Whether or not an error is returned, it is the responsibility of the
-** caller to eventually free p->idxStr if p->needToFreeIdxStr indicates
-** that this is required.
-*/
-static int vtabBestIndex(Parse *pParse, Table *pTab, sqlite3_index_info *p){
- sqlite3_vtab *pVtab = sqlite3GetVTable(pParse->db, pTab)->pVtab;
- int i;
- int rc;
-
- (void)sqlite3SafetyOff(pParse->db);
- WHERETRACE(("xBestIndex for %s\n", pTab->zName));
- TRACE_IDX_INPUTS(p);
- rc = pVtab->pModule->xBestIndex(pVtab, p);
- TRACE_IDX_OUTPUTS(p);
- (void)sqlite3SafetyOn(pParse->db);
-
- if( rc!=SQLITE_OK ){
- if( rc==SQLITE_NOMEM ){
- pParse->db->mallocFailed = 1;
- }else if( !pVtab->zErrMsg ){
- sqlite3ErrorMsg(pParse, "%s", sqlite3ErrStr(rc));
- }else{
- sqlite3ErrorMsg(pParse, "%s", pVtab->zErrMsg);
- }
- }
- sqlite3DbFree(pParse->db, pVtab->zErrMsg);
- pVtab->zErrMsg = 0;
-
- for(i=0; i<p->nConstraint; i++){
- if( !p->aConstraint[i].usable && p->aConstraintUsage[i].argvIndex>0 ){
- sqlite3ErrorMsg(pParse,
- "table %s: xBestIndex returned an invalid plan", pTab->zName);
- }
- }
-
- return pParse->nErr;
-}
-
-
-/*
-** Compute the best index for a virtual table.
-**
-** The best index is computed by the xBestIndex method of the virtual
-** table module. This routine is really just a wrapper that sets up
-** the sqlite3_index_info structure that is used to communicate with
-** xBestIndex.
-**
-** In a join, this routine might be called multiple times for the
-** same virtual table. The sqlite3_index_info structure is created
-** and initialized on the first invocation and reused on all subsequent
-** invocations. The sqlite3_index_info structure is also used when
-** code is generated to access the virtual table. The whereInfoDelete()
-** routine takes care of freeing the sqlite3_index_info structure after
-** everybody has finished with it.
-*/
-static void bestVirtualIndex(
- Parse *pParse, /* The parsing context */
- WhereClause *pWC, /* The WHERE clause */
- struct SrcList_item *pSrc, /* The FROM clause term to search */
- Bitmask notReady, /* Mask of cursors that are not available */
- ExprList *pOrderBy, /* The order by clause */
- WhereCost *pCost, /* Lowest cost query plan */
- sqlite3_index_info **ppIdxInfo /* Index information passed to xBestIndex */
-){
- Table *pTab = pSrc->pTab;
- sqlite3_index_info *pIdxInfo;
- struct sqlite3_index_constraint *pIdxCons;
- struct sqlite3_index_constraint_usage *pUsage;
- WhereTerm *pTerm;
- int i, j;
- int nOrderBy;
-
- /* Make sure wsFlags is initialized to some sane value. Otherwise, if the
- ** malloc in allocateIndexInfo() fails and this function returns leaving
- ** wsFlags in an uninitialized state, the caller may behave unpredictably.
- */
- memset(pCost, 0, sizeof(*pCost));
- pCost->plan.wsFlags = WHERE_VIRTUALTABLE;
-
- /* If the sqlite3_index_info structure has not been previously
- ** allocated and initialized, then allocate and initialize it now.
- */
- pIdxInfo = *ppIdxInfo;
- if( pIdxInfo==0 ){
- *ppIdxInfo = pIdxInfo = allocateIndexInfo(pParse, pWC, pSrc, pOrderBy);
- }
- if( pIdxInfo==0 ){
- return;
- }
-
- /* At this point, the sqlite3_index_info structure that pIdxInfo points
- ** to will have been initialized, either during the current invocation or
- ** during some prior invocation. Now we just have to customize the
- ** details of pIdxInfo for the current invocation and pass it to
- ** xBestIndex.
- */
-
- /* The module name must be defined. Also, by this point there must
- ** be a pointer to an sqlite3_vtab structure. Otherwise
- ** sqlite3ViewGetColumnNames() would have picked up the error.
- */
- assert( pTab->azModuleArg && pTab->azModuleArg[0] );
- assert( sqlite3GetVTable(pParse->db, pTab) );
-
- /* Set the aConstraint[].usable fields and initialize all
- ** output variables to zero.
- **
- ** aConstraint[].usable is true for constraints where the right-hand
- ** side contains only references to tables to the left of the current
- ** table. In other words, if the constraint is of the form:
- **
- ** column = expr
- **
- ** and we are evaluating a join, then the constraint on column is
- ** only valid if all tables referenced in expr occur to the left
- ** of the table containing column.
- **
- ** The aConstraints[] array contains entries for all constraints
- ** on the current table. That way we only have to compute it once
- ** even though we might try to pick the best index multiple times.
- ** For each attempt at picking an index, the order of tables in the
- ** join might be different so we have to recompute the usable flag
- ** each time.
- */
- pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint;
- pUsage = pIdxInfo->aConstraintUsage;
- for(i=0; i<pIdxInfo->nConstraint; i++, pIdxCons++){
- j = pIdxCons->iTermOffset;
- pTerm = &pWC->a[j];
- pIdxCons->usable = (pTerm->prereqRight&notReady) ? 0 : 1;
- }
- memset(pUsage, 0, sizeof(pUsage[0])*pIdxInfo->nConstraint);
- if( pIdxInfo->needToFreeIdxStr ){
- sqlite3_free(pIdxInfo->idxStr);
- }
- pIdxInfo->idxStr = 0;
- pIdxInfo->idxNum = 0;
- pIdxInfo->needToFreeIdxStr = 0;
- pIdxInfo->orderByConsumed = 0;
- /* ((double)2) In case of SQLITE_OMIT_FLOATING_POINT... */
- pIdxInfo->estimatedCost = SQLITE_BIG_DBL / ((double)2);
- nOrderBy = pIdxInfo->nOrderBy;
- if( !pOrderBy ){
- pIdxInfo->nOrderBy = 0;
- }
-
- if( vtabBestIndex(pParse, pTab, pIdxInfo) ){
- return;
- }
-
- pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint;
- for(i=0; i<pIdxInfo->nConstraint; i++){
- if( pUsage[i].argvIndex>0 ){
- pCost->used |= pWC->a[pIdxCons[i].iTermOffset].prereqRight;
- }
- }
-
- /* The cost is not allowed to be larger than SQLITE_BIG_DBL (the
- ** inital value of lowestCost in this loop. If it is, then the
- ** (cost<lowestCost) test below will never be true.
- **
- ** Use "(double)2" instead of "2.0" in case OMIT_FLOATING_POINT
- ** is defined.
- */
- if( (SQLITE_BIG_DBL/((double)2))<pIdxInfo->estimatedCost ){
- pCost->rCost = (SQLITE_BIG_DBL/((double)2));
- }else{
- pCost->rCost = pIdxInfo->estimatedCost;
- }
- pCost->plan.u.pVtabIdx = pIdxInfo;
- if( pIdxInfo->orderByConsumed ){
- pCost->plan.wsFlags |= WHERE_ORDERBY;
- }
- pCost->plan.nEq = 0;
- pIdxInfo->nOrderBy = nOrderBy;
-
- /* Try to find a more efficient access pattern by using multiple indexes
- ** to optimize an OR expression within the WHERE clause.
- */
- bestOrClauseIndex(pParse, pWC, pSrc, notReady, pOrderBy, pCost);
-}
-#endif /* SQLITE_OMIT_VIRTUALTABLE */
-
-/*
-** Argument pIdx is a pointer to an index structure that has an array of
-** SQLITE_INDEX_SAMPLES evenly spaced samples of the first indexed column
-** stored in Index.aSample. The domain of values stored in said column
-** may be thought of as divided into (SQLITE_INDEX_SAMPLES+1) regions.
-** Region 0 contains all values smaller than the first sample value. Region
-** 1 contains values larger than or equal to the value of the first sample,
-** but smaller than the value of the second. And so on.
-**
-** If successful, this function determines which of the regions value
-** pVal lies in, sets *piRegion to the region index (a value between 0
-** and SQLITE_INDEX_SAMPLES+1, inclusive) and returns SQLITE_OK.
-** Or, if an OOM occurs while converting text values between encodings,
-** SQLITE_NOMEM is returned and *piRegion is undefined.
-*/
-#ifdef SQLITE_ENABLE_STAT2
-static int whereRangeRegion(
- Parse *pParse, /* Database connection */
- Index *pIdx, /* Index to consider domain of */
- sqlite3_value *pVal, /* Value to consider */
- int *piRegion /* OUT: Region of domain in which value lies */
-){
- if( ALWAYS(pVal) ){
- IndexSample *aSample = pIdx->aSample;
- int i = 0;
- int eType = sqlite3_value_type(pVal);
-
- if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){
- double r = sqlite3_value_double(pVal);
- for(i=0; i<SQLITE_INDEX_SAMPLES; i++){
- if( aSample[i].eType==SQLITE_NULL ) continue;
- if( aSample[i].eType>=SQLITE_TEXT || aSample[i].u.r>r ) break;
- }
- }else{
- sqlite3 *db = pParse->db;
- CollSeq *pColl;
- const u8 *z;
- int n;
-
- /* pVal comes from sqlite3ValueFromExpr() so the type cannot be NULL */
- assert( eType==SQLITE_TEXT || eType==SQLITE_BLOB );
-
- if( eType==SQLITE_BLOB ){
- z = (const u8 *)sqlite3_value_blob(pVal);
- pColl = db->pDfltColl;
- assert( pColl->enc==SQLITE_UTF8 );
- }else{
- pColl = sqlite3GetCollSeq(db, SQLITE_UTF8, 0, *pIdx->azColl);
- if( pColl==0 ){
- sqlite3ErrorMsg(pParse, "no such collation sequence: %s",
- *pIdx->azColl);
- return SQLITE_ERROR;
- }
- z = (const u8 *)sqlite3ValueText(pVal, pColl->enc);
- if( !z ){
- return SQLITE_NOMEM;
- }
- assert( z && pColl && pColl->xCmp );
- }
- n = sqlite3ValueBytes(pVal, pColl->enc);
-
- for(i=0; i<SQLITE_INDEX_SAMPLES; i++){
- int r;
- int eSampletype = aSample[i].eType;
- if( eSampletype==SQLITE_NULL || eSampletype<eType ) continue;
- if( (eSampletype!=eType) ) break;
- if( pColl->enc==SQLITE_UTF8 ){
- r = pColl->xCmp(pColl->pUser, aSample[i].nByte, aSample[i].u.z, n, z);
- }else{
- int nSample;
- char *zSample = sqlite3Utf8to16(
- db, pColl->enc, aSample[i].u.z, aSample[i].nByte, &nSample
- );
- if( !zSample ){
- assert( db->mallocFailed );
- return SQLITE_NOMEM;
- }
- r = pColl->xCmp(pColl->pUser, nSample, zSample, n, z);
- sqlite3DbFree(db, zSample);
- }
- if( r>0 ) break;
- }
- }
-
- assert( i>=0 && i<=SQLITE_INDEX_SAMPLES );
- *piRegion = i;
- }
- return SQLITE_OK;
-}
-#endif /* #ifdef SQLITE_ENABLE_STAT2 */
-
-/*
-** This function is used to estimate the number of rows that will be visited
-** by scanning an index for a range of values. The range may have an upper
-** bound, a lower bound, or both. The WHERE clause terms that set the upper
-** and lower bounds are represented by pLower and pUpper respectively. For
-** example, assuming that index p is on t1(a):
-**
-** ... FROM t1 WHERE a > ? AND a < ? ...
-** |_____| |_____|
-** | |
-** pLower pUpper
-**
-** If either of the upper or lower bound is not present, then NULL is passed in
-** place of the corresponding WhereTerm.
-**
-** The nEq parameter is passed the index of the index column subject to the
-** range constraint. Or, equivalently, the number of equality constraints
-** optimized by the proposed index scan. For example, assuming index p is
-** on t1(a, b), and the SQL query is:
-**
-** ... FROM t1 WHERE a = ? AND b > ? AND b < ? ...
-**
-** then nEq should be passed the value 1 (as the range restricted column,
-** b, is the second left-most column of the index). Or, if the query is:
-**
-** ... FROM t1 WHERE a > ? AND a < ? ...
-**
-** then nEq should be passed 0.
-**
-** The returned value is an integer between 1 and 100, inclusive. A return
-** value of 1 indicates that the proposed range scan is expected to visit
-** approximately 1/100th (1%) of the rows selected by the nEq equality
-** constraints (if any). A return value of 100 indicates that it is expected
-** that the range scan will visit every row (100%) selected by the equality
-** constraints.
-**
-** In the absence of sqlite_stat2 ANALYZE data, each range inequality
-** reduces the search space by 2/3rds. Hence a single constraint (x>?)
-** results in a return of 33 and a range constraint (x>? AND x<?) results
-** in a return of 11.
-*/
-static int whereRangeScanEst(
- Parse *pParse, /* Parsing & code generating context */
- Index *p, /* The index containing the range-compared column; "x" */
- int nEq, /* index into p->aCol[] of the range-compared column */
- WhereTerm *pLower, /* Lower bound on the range. ex: "x>123" Might be NULL */
- WhereTerm *pUpper, /* Upper bound on the range. ex: "x<455" Might be NULL */
- int *piEst /* OUT: Return value */
-){
- int rc = SQLITE_OK;
-
-#ifdef SQLITE_ENABLE_STAT2
- sqlite3 *db = pParse->db;
- sqlite3_value *pLowerVal = 0;
- sqlite3_value *pUpperVal = 0;
-
- if( nEq==0 && p->aSample ){
- int iEst;
- int iLower = 0;
- int iUpper = SQLITE_INDEX_SAMPLES;
- u8 aff = p->pTable->aCol[0].affinity;
-
- if( pLower ){
- Expr *pExpr = pLower->pExpr->pRight;
- rc = sqlite3ValueFromExpr(db, pExpr, SQLITE_UTF8, aff, &pLowerVal);
- }
- if( rc==SQLITE_OK && pUpper ){
- Expr *pExpr = pUpper->pExpr->pRight;
- rc = sqlite3ValueFromExpr(db, pExpr, SQLITE_UTF8, aff, &pUpperVal);
- }
-
- if( rc!=SQLITE_OK || (pLowerVal==0 && pUpperVal==0) ){
- sqlite3ValueFree(pLowerVal);
- sqlite3ValueFree(pUpperVal);
- goto range_est_fallback;
- }else if( pLowerVal==0 ){
- rc = whereRangeRegion(pParse, p, pUpperVal, &iUpper);
- if( pLower ) iLower = iUpper/2;
- }else if( pUpperVal==0 ){
- rc = whereRangeRegion(pParse, p, pLowerVal, &iLower);
- if( pUpper ) iUpper = (iLower + SQLITE_INDEX_SAMPLES + 1)/2;
- }else{
- rc = whereRangeRegion(pParse, p, pUpperVal, &iUpper);
- if( rc==SQLITE_OK ){
- rc = whereRangeRegion(pParse, p, pLowerVal, &iLower);
- }
- }
-
- iEst = iUpper - iLower;
- testcase( iEst==SQLITE_INDEX_SAMPLES );
- assert( iEst<=SQLITE_INDEX_SAMPLES );
- if( iEst<1 ){
- iEst = 1;
- }
-
- sqlite3ValueFree(pLowerVal);
- sqlite3ValueFree(pUpperVal);
- *piEst = (iEst * 100)/SQLITE_INDEX_SAMPLES;
- return rc;
- }
-range_est_fallback:
-#else
- UNUSED_PARAMETER(pParse);
- UNUSED_PARAMETER(p);
- UNUSED_PARAMETER(nEq);
-#endif
- assert( pLower || pUpper );
- if( pLower && pUpper ){
- *piEst = 11;
- }else{
- *piEst = 33;
- }
- return rc;
-}
-
-
-/*
-** Find the query plan for accessing a particular table. Write the
-** best query plan and its cost into the WhereCost object supplied as the
-** last parameter.
-**
-** The lowest cost plan wins. The cost is an estimate of the amount of
-** CPU and disk I/O need to process the request using the selected plan.
-** Factors that influence cost include:
-**
-** * The estimated number of rows that will be retrieved. (The
-** fewer the better.)
-**
-** * Whether or not sorting must occur.
-**
-** * Whether or not there must be separate lookups in the
-** index and in the main table.
-**
-** If there was an INDEXED BY clause (pSrc->pIndex) attached to the table in
-** the SQL statement, then this function only considers plans using the
-** named index. If no such plan is found, then the returned cost is
-** SQLITE_BIG_DBL. If a plan is found that uses the named index,
-** then the cost is calculated in the usual way.
-**
-** If a NOT INDEXED clause (pSrc->notIndexed!=0) was attached to the table
-** in the SELECT statement, then no indexes are considered. However, the
-** selected plan may still take advantage of the tables built-in rowid
-** index.
-*/
-static void bestBtreeIndex(
- Parse *pParse, /* The parsing context */
- WhereClause *pWC, /* The WHERE clause */
- struct SrcList_item *pSrc, /* The FROM clause term to search */
- Bitmask notReady, /* Mask of cursors that are not available */
- ExprList *pOrderBy, /* The ORDER BY clause */
- WhereCost *pCost /* Lowest cost query plan */
-){
- int iCur = pSrc->iCursor; /* The cursor of the table to be accessed */
- Index *pProbe; /* An index we are evaluating */
- Index *pIdx; /* Copy of pProbe, or zero for IPK index */
- int eqTermMask; /* Current mask of valid equality operators */
- int idxEqTermMask; /* Index mask of valid equality operators */
- Index sPk; /* A fake index object for the primary key */
- unsigned int aiRowEstPk[2]; /* The aiRowEst[] value for the sPk index */
- int aiColumnPk = -1; /* The aColumn[] value for the sPk index */
- int wsFlagMask; /* Allowed flags in pCost->plan.wsFlag */
-
- /* Initialize the cost to a worst-case value */
- memset(pCost, 0, sizeof(*pCost));
- pCost->rCost = SQLITE_BIG_DBL;
-
- /* If the pSrc table is the right table of a LEFT JOIN then we may not
- ** use an index to satisfy IS NULL constraints on that table. This is
- ** because columns might end up being NULL if the table does not match -
- ** a circumstance which the index cannot help us discover. Ticket #2177.
- */
- if( pSrc->jointype & JT_LEFT ){
- idxEqTermMask = WO_EQ|WO_IN;
- }else{
- idxEqTermMask = WO_EQ|WO_IN|WO_ISNULL;
- }
-
- if( pSrc->pIndex ){
- /* An INDEXED BY clause specifies a particular index to use */
- pIdx = pProbe = pSrc->pIndex;
- wsFlagMask = ~(WHERE_ROWID_EQ|WHERE_ROWID_RANGE);
- eqTermMask = idxEqTermMask;
- }else{
- /* There is no INDEXED BY clause. Create a fake Index object to
- ** represent the primary key */
- Index *pFirst; /* Any other index on the table */
- memset(&sPk, 0, sizeof(Index));
- sPk.nColumn = 1;
- sPk.aiColumn = &aiColumnPk;
- sPk.aiRowEst = aiRowEstPk;
- aiRowEstPk[1] = 1;
- sPk.onError = OE_Replace;
- sPk.pTable = pSrc->pTab;
- pFirst = pSrc->pTab->pIndex;
- if( pSrc->notIndexed==0 ){
- sPk.pNext = pFirst;
- }
- /* The aiRowEstPk[0] is an estimate of the total number of rows in the
- ** table. Get this information from the ANALYZE information if it is
- ** available. If not available, assume the table 1 million rows in size.
- */
- if( pFirst ){
- assert( pFirst->aiRowEst!=0 ); /* Allocated together with pFirst */
- aiRowEstPk[0] = pFirst->aiRowEst[0];
- }else{
- aiRowEstPk[0] = 1000000;
- }
- pProbe = &sPk;
- wsFlagMask = ~(
- WHERE_COLUMN_IN|WHERE_COLUMN_EQ|WHERE_COLUMN_NULL|WHERE_COLUMN_RANGE
- );
- eqTermMask = WO_EQ|WO_IN;
- pIdx = 0;
- }
-
- /* Loop over all indices looking for the best one to use
- */
- for(; pProbe; pIdx=pProbe=pProbe->pNext){
- const unsigned int * const aiRowEst = pProbe->aiRowEst;
- double cost; /* Cost of using pProbe */
- double nRow; /* Estimated number of rows in result set */
- int rev; /* True to scan in reverse order */
- int wsFlags = 0;
- Bitmask used = 0;
-
- /* The following variables are populated based on the properties of
- ** scan being evaluated. They are then used to determine the expected
- ** cost and number of rows returned.
- **
- ** nEq:
- ** Number of equality terms that can be implemented using the index.
- **
- ** nInMul:
- ** The "in-multiplier". This is an estimate of how many seek operations
- ** SQLite must perform on the index in question. For example, if the
- ** WHERE clause is:
- **
- ** WHERE a IN (1, 2, 3) AND b IN (4, 5, 6)
- **
- ** SQLite must perform 9 lookups on an index on (a, b), so nInMul is
- ** set to 9. Given the same schema and either of the following WHERE
- ** clauses:
- **
- ** WHERE a = 1
- ** WHERE a >= 2
- **
- ** nInMul is set to 1.
- **
- ** If there exists a WHERE term of the form "x IN (SELECT ...)", then
- ** the sub-select is assumed to return 25 rows for the purposes of
- ** determining nInMul.
- **
- ** bInEst:
- ** Set to true if there was at least one "x IN (SELECT ...)" term used
- ** in determining the value of nInMul.
- **
- ** nBound:
- ** An estimate on the amount of the table that must be searched. A
- ** value of 100 means the entire table is searched. Range constraints
- ** might reduce this to a value less than 100 to indicate that only
- ** a fraction of the table needs searching. In the absence of
- ** sqlite_stat2 ANALYZE data, a single inequality reduces the search
- ** space to 1/3rd its original size. So an x>? constraint reduces
- ** nBound to 33. Two constraints (x>? AND x<?) reduce nBound to 11.
- **
- ** bSort:
- ** Boolean. True if there is an ORDER BY clause that will require an
- ** external sort (i.e. scanning the index being evaluated will not
- ** correctly order records).
- **
- ** bLookup:
- ** Boolean. True if for each index entry visited a lookup on the
- ** corresponding table b-tree is required. This is always false
- ** for the rowid index. For other indexes, it is true unless all the
- ** columns of the table used by the SELECT statement are present in
- ** the index (such an index is sometimes described as a covering index).
- ** For example, given the index on (a, b), the second of the following
- ** two queries requires table b-tree lookups, but the first does not.
- **
- ** SELECT a, b FROM tbl WHERE a = 1;
- ** SELECT a, b, c FROM tbl WHERE a = 1;
- */
- int nEq;
- int bInEst = 0;
- int nInMul = 1;
- int nBound = 100;
- int bSort = 0;
- int bLookup = 0;
-
- /* Determine the values of nEq and nInMul */
- for(nEq=0; nEq<pProbe->nColumn; nEq++){
- WhereTerm *pTerm; /* A single term of the WHERE clause */
- int j = pProbe->aiColumn[nEq];
- pTerm = findTerm(pWC, iCur, j, notReady, eqTermMask, pIdx);
- if( pTerm==0 ) break;
- wsFlags |= (WHERE_COLUMN_EQ|WHERE_ROWID_EQ);
- if( pTerm->eOperator & WO_IN ){
- Expr *pExpr = pTerm->pExpr;
- wsFlags |= WHERE_COLUMN_IN;
- if( ExprHasProperty(pExpr, EP_xIsSelect) ){
- nInMul *= 25;
- bInEst = 1;
- }else if( pExpr->x.pList ){
- nInMul *= pExpr->x.pList->nExpr + 1;
- }
- }else if( pTerm->eOperator & WO_ISNULL ){
- wsFlags |= WHERE_COLUMN_NULL;
- }
- used |= pTerm->prereqRight;
- }
-
- /* Determine the value of nBound. */
- if( nEq<pProbe->nColumn ){
- int j = 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);
- whereRangeScanEst(pParse, pProbe, nEq, pBtm, pTop, &nBound);
- if( pTop ){
- wsFlags |= WHERE_TOP_LIMIT;
- used |= pTop->prereqRight;
- }
- if( pBtm ){
- wsFlags |= WHERE_BTM_LIMIT;
- used |= pBtm->prereqRight;
- }
- 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
- ** naturally scan rows in the required order, set the appropriate flags
- ** in wsFlags. Otherwise, if there is an ORDER BY clause but the index
- ** will scan rows in a different order, set the bSort variable. */
- if( pOrderBy ){
- if( (wsFlags & (WHERE_COLUMN_IN|WHERE_COLUMN_NULL))==0
- && isSortingIndex(pParse,pWC->pMaskSet,pProbe,iCur,pOrderBy,nEq,&rev)
- ){
- wsFlags |= WHERE_ROWID_RANGE|WHERE_COLUMN_RANGE|WHERE_ORDERBY;
- wsFlags |= (rev ? WHERE_REVERSE : 0);
- }else{
- bSort = 1;
- }
- }
-
- /* If currently calculating the cost of using an index (not the IPK
- ** index), determine if all required column data may be obtained without
- ** seeking to entries in the main table (i.e. if the index is a covering
- ** index for this query). If it is, set the WHERE_IDX_ONLY flag in
- ** wsFlags. Otherwise, set the bLookup variable to true. */
- if( pIdx && wsFlags ){
- Bitmask m = pSrc->colUsed;
- int j;
- for(j=0; j<pIdx->nColumn; j++){
- int x = pIdx->aiColumn[j];
- if( x<BMS-1 ){
- m &= ~(((Bitmask)1)<<x);
- }
- }
- if( m==0 ){
- wsFlags |= WHERE_IDX_ONLY;
- }else{
- bLookup = 1;
- }
- }
-
- /**** Begin adding up the cost of using this index (Needs improvements)
- **
- ** Estimate the number of rows of output. For an IN operator,
- ** do not let the estimate exceed half the rows in the table.
- */
- nRow = (double)(aiRowEst[nEq] * nInMul);
- if( bInEst && nRow*2>aiRowEst[0] ){
- nRow = aiRowEst[0]/2;
- nInMul = (int)(nRow / aiRowEst[nEq]);
- }
-
- /* Assume constant cost to access a row and logarithmic cost to
- ** do a binary search. Hence, the initial cost is the number of output
- ** rows plus log2(table-size) times the number of binary searches.
- */
- cost = nRow + nInMul*estLog(aiRowEst[0]);
-
- /* Adjust the number of rows and the cost downward to reflect rows
- ** that are excluded by range constraints.
- */
- nRow = (nRow * (double)nBound) / (double)100;
- cost = (cost * (double)nBound) / (double)100;
-
- /* Add in the estimated cost of sorting the result
- */
- if( bSort ){
- cost += cost*estLog(cost);
- }
-
- /* If all information can be taken directly from the index, we avoid
- ** doing table lookups. This reduces the cost by half. (Not really -
- ** this needs to be fixed.)
- */
- if( pIdx && bLookup==0 ){
- cost /= (double)2;
- }
- /**** Cost of using this index has now been computed ****/
-
- WHERETRACE((
- "tbl=%s idx=%s nEq=%d nInMul=%d nBound=%d bSort=%d bLookup=%d"
- " wsFlags=%d (nRow=%.2f cost=%.2f)\n",
- pSrc->pTab->zName, (pIdx ? pIdx->zName : "ipk"),
- nEq, nInMul, nBound, bSort, bLookup, wsFlags, nRow, cost
- ));
-
- /* If this index is the best we have seen so far, then record this
- ** index and its cost in the pCost structure.
- */
- if( (!pIdx || wsFlags) && cost<pCost->rCost ){
- pCost->rCost = cost;
- pCost->nRow = nRow;
- pCost->used = used;
- pCost->plan.wsFlags = (wsFlags&wsFlagMask);
- pCost->plan.nEq = nEq;
- pCost->plan.u.pIdx = pIdx;
- }
-
- /* If there was an INDEXED BY clause, then only that one index is
- ** considered. */
- if( pSrc->pIndex ) break;
-
- /* Reset masks for the next index in the loop */
- wsFlagMask = ~(WHERE_ROWID_EQ|WHERE_ROWID_RANGE);
- eqTermMask = idxEqTermMask;
- }
-
- /* If there is no ORDER BY clause and the SQLITE_ReverseOrder flag
- ** is set, then reverse the order that the index will be scanned
- ** in. This is used for application testing, to help find cases
- ** where application behaviour depends on the (undefined) order that
- ** SQLite outputs rows in in the absence of an ORDER BY clause. */
- if( !pOrderBy && pParse->db->flags & SQLITE_ReverseOrder ){
- pCost->plan.wsFlags |= WHERE_REVERSE;
- }
-
- assert( pOrderBy || (pCost->plan.wsFlags&WHERE_ORDERBY)==0 );
- assert( pCost->plan.u.pIdx==0 || (pCost->plan.wsFlags&WHERE_ROWID_EQ)==0 );
- assert( pSrc->pIndex==0
- || pCost->plan.u.pIdx==0
- || pCost->plan.u.pIdx==pSrc->pIndex
- );
-
- WHERETRACE(("best index is: %s\n",
- (pCost->plan.u.pIdx ? pCost->plan.u.pIdx->zName : "ipk")
- ));
-
- bestOrClauseIndex(pParse, pWC, pSrc, notReady, pOrderBy, pCost);
- pCost->plan.wsFlags |= eqTermMask;
-}
-
-/*
-** Find the query plan for accessing table pSrc->pTab. Write the
-** best query plan and its cost into the WhereCost object supplied
-** as the last parameter. This function may calculate the cost of
-** both real and virtual table scans.
-*/
-static void bestIndex(
- Parse *pParse, /* The parsing context */
- WhereClause *pWC, /* The WHERE clause */
- struct SrcList_item *pSrc, /* The FROM clause term to search */
- Bitmask notReady, /* Mask of cursors that are not available */
- ExprList *pOrderBy, /* The ORDER BY clause */
- WhereCost *pCost /* Lowest cost query plan */
-){
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- if( IsVirtual(pSrc->pTab) ){
- sqlite3_index_info *p = 0;
- bestVirtualIndex(pParse, pWC, pSrc, notReady, pOrderBy, pCost, &p);
- if( p->needToFreeIdxStr ){
- sqlite3_free(p->idxStr);
- }
- sqlite3DbFree(pParse->db, p);
- }else
-#endif
- {
- bestBtreeIndex(pParse, pWC, pSrc, notReady, pOrderBy, pCost);
- }
-}
-
-/*
-** Disable a term in the WHERE clause. Except, do not disable the term
-** if it controls a LEFT OUTER JOIN and it did not originate in the ON
-** or USING clause of that join.
-**
-** Consider the term t2.z='ok' in the following queries:
-**
-** (1) SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.x WHERE t2.z='ok'
-** (2) SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.x AND t2.z='ok'
-** (3) SELECT * FROM t1, t2 WHERE t1.a=t2.x AND t2.z='ok'
-**
-** The t2.z='ok' is disabled in the in (2) because it originates
-** in the ON clause. The term is disabled in (3) because it is not part
-** of a LEFT OUTER JOIN. In (1), the term is not disabled.
-**
-** Disabling a term causes that term to not be tested in the inner loop
-** of the join. Disabling is an optimization. When terms are satisfied
-** by indices, we disable them to prevent redundant tests in the inner
-** loop. We would get the correct results if nothing were ever disabled,
-** but joins might run a little slower. The trick is to disable as much
-** as we can without disabling too much. If we disabled in (1), we'd get
-** the wrong answer. See ticket #813.
-*/
-static void disableTerm(WhereLevel *pLevel, WhereTerm *pTerm){
- if( pTerm
- && ALWAYS((pTerm->wtFlags & TERM_CODED)==0)
- && (pLevel->iLeftJoin==0 || ExprHasProperty(pTerm->pExpr, EP_FromJoin))
- ){
- pTerm->wtFlags |= TERM_CODED;
- if( pTerm->iParent>=0 ){
- WhereTerm *pOther = &pTerm->pWC->a[pTerm->iParent];
- if( (--pOther->nChild)==0 ){
- disableTerm(pLevel, pOther);
- }
- }
- }
-}
-
-/*
-** Code an OP_Affinity opcode to apply the column affinity string zAff
-** to the n registers starting at base.
-**
-** Buffer zAff was allocated using sqlite3DbMalloc(). It is the
-** responsibility of this function to arrange for it to be eventually
-** freed using sqlite3DbFree().
-*/
-static void codeApplyAffinity(Parse *pParse, int base, int n, char *zAff){
- Vdbe *v = pParse->pVdbe;
- assert( v!=0 );
- sqlite3VdbeAddOp2(v, OP_Affinity, base, n);
- sqlite3VdbeChangeP4(v, -1, zAff, P4_DYNAMIC);
- sqlite3ExprCacheAffinityChange(pParse, base, n);
-}
-
-
-/*
-** Generate code for a single equality term of the WHERE clause. An equality
-** term can be either X=expr or X IN (...). pTerm is the term to be
-** coded.
-**
-** The current value for the constraint is left in register iReg.
-**
-** For a constraint of the form X=expr, the expression is evaluated and its
-** result is left on the stack. For constraints of the form X IN (...)
-** this routine sets up a loop that will iterate over all values of X.
-*/
-static int codeEqualityTerm(
- Parse *pParse, /* The parsing context */
- WhereTerm *pTerm, /* The term of the WHERE clause to be coded */
- WhereLevel *pLevel, /* When level of the FROM clause we are working on */
- int iTarget /* Attempt to leave results in this register */
-){
- Expr *pX = pTerm->pExpr;
- Vdbe *v = pParse->pVdbe;
- int iReg; /* Register holding results */
-
- assert( iTarget>0 );
- if( pX->op==TK_EQ ){
- iReg = sqlite3ExprCodeTarget(pParse, pX->pRight, iTarget);
- }else if( pX->op==TK_ISNULL ){
- iReg = iTarget;
- sqlite3VdbeAddOp2(v, OP_Null, 0, iReg);
-#ifndef SQLITE_OMIT_SUBQUERY
- }else{
- int eType;
- int iTab;
- struct InLoop *pIn;
-
- assert( pX->op==TK_IN );
- iReg = iTarget;
- eType = sqlite3FindInIndex(pParse, pX, 0);
- iTab = pX->iTable;
- sqlite3VdbeAddOp2(v, OP_Rewind, iTab, 0);
- assert( pLevel->plan.wsFlags & WHERE_IN_ABLE );
- if( pLevel->u.in.nIn==0 ){
- pLevel->addrNxt = sqlite3VdbeMakeLabel(v);
- }
- pLevel->u.in.nIn++;
- pLevel->u.in.aInLoop =
- sqlite3DbReallocOrFree(pParse->db, pLevel->u.in.aInLoop,
- sizeof(pLevel->u.in.aInLoop[0])*pLevel->u.in.nIn);
- pIn = pLevel->u.in.aInLoop;
- if( pIn ){
- pIn += pLevel->u.in.nIn - 1;
- pIn->iCur = iTab;
- if( eType==IN_INDEX_ROWID ){
- pIn->addrInTop = sqlite3VdbeAddOp2(v, OP_Rowid, iTab, iReg);
- }else{
- pIn->addrInTop = sqlite3VdbeAddOp3(v, OP_Column, iTab, 0, iReg);
- }
- sqlite3VdbeAddOp1(v, OP_IsNull, iReg);
- }else{
- pLevel->u.in.nIn = 0;
- }
-#endif
- }
- disableTerm(pLevel, pTerm);
- return iReg;
-}
-
-/*
-** Generate code that will evaluate all == and IN constraints for an
-** index. The values for all constraints are left on the stack.
-**
-** For example, consider table t1(a,b,c,d,e,f) with index i1(a,b,c).
-** Suppose the WHERE clause is this: a==5 AND b IN (1,2,3) AND c>5 AND c<10
-** The index has as many as three equality constraints, but in this
-** example, the third "c" value is an inequality. So only two
-** constraints are coded. This routine will generate code to evaluate
-** a==5 and b IN (1,2,3). The current values for a and b will be stored
-** in consecutive registers and the index of the first register is returned.
-**
-** In the example above nEq==2. But this subroutine works for any value
-** of nEq including 0. If nEq==0, this routine is nearly a no-op.
-** The only thing it does is allocate the pLevel->iMem memory cell.
-**
-** This routine always allocates at least one memory cell and returns
-** the index of that memory cell. The code that
-** calls this routine will use that memory cell to store the termination
-** key value of the loop. If one or more IN operators appear, then
-** this routine allocates an additional nEq memory cells for internal
-** use.
-**
-** Before returning, *pzAff is set to point to a buffer containing a
-** copy of the column affinity string of the index allocated using
-** sqlite3DbMalloc(). Except, entries in the copy of the string associated
-** with equality constraints that use NONE affinity are set to
-** SQLITE_AFF_NONE. This is to deal with SQL such as the following:
-**
-** CREATE TABLE t1(a TEXT PRIMARY KEY, b);
-** SELECT ... FROM t1 AS t2, t1 WHERE t1.a = t2.b;
-**
-** In the example above, the index on t1(a) has TEXT affinity. But since
-** the right hand side of the equality constraint (t2.b) has NONE affinity,
-** no conversion should be attempted before using a t2.b value as part of
-** a key to search the index. Hence the first byte in the returned affinity
-** string in this example would be set to SQLITE_AFF_NONE.
-*/
-static int codeAllEqualityTerms(
- Parse *pParse, /* Parsing context */
- WhereLevel *pLevel, /* Which nested loop of the FROM we are coding */
- WhereClause *pWC, /* The WHERE clause */
- Bitmask notReady, /* Which parts of FROM have not yet been coded */
- int nExtraReg, /* Number of extra registers to allocate */
- char **pzAff /* OUT: Set to point to affinity string */
-){
- int nEq = pLevel->plan.nEq; /* The number of == or IN constraints to code */
- Vdbe *v = pParse->pVdbe; /* The vm under construction */
- Index *pIdx; /* The index being used for this loop */
- int iCur = pLevel->iTabCur; /* The cursor of the table */
- WhereTerm *pTerm; /* A single constraint term */
- int j; /* Loop counter */
- int regBase; /* Base register */
- int nReg; /* Number of registers to allocate */
- char *zAff; /* Affinity string to return */
-
- /* This module is only called on query plans that use an index. */
- assert( pLevel->plan.wsFlags & WHERE_INDEXED );
- pIdx = pLevel->plan.u.pIdx;
-
- /* Figure out how many memory cells we will need then allocate them.
- */
- regBase = pParse->nMem + 1;
- nReg = pLevel->plan.nEq + nExtraReg;
- pParse->nMem += nReg;
-
- zAff = sqlite3DbStrDup(pParse->db, sqlite3IndexAffinityStr(v, pIdx));
- if( !zAff ){
- pParse->db->mallocFailed = 1;
- }
-
- /* Evaluate the equality constraints
- */
- assert( pIdx->nColumn>=nEq );
- for(j=0; j<nEq; j++){
- int r1;
- int k = pIdx->aiColumn[j];
- pTerm = findTerm(pWC, iCur, k, notReady, pLevel->plan.wsFlags, pIdx);
- if( NEVER(pTerm==0) ) break;
- assert( (pTerm->wtFlags & TERM_CODED)==0 );
- r1 = codeEqualityTerm(pParse, pTerm, pLevel, regBase+j);
- if( r1!=regBase+j ){
- if( nReg==1 ){
- sqlite3ReleaseTempReg(pParse, regBase);
- regBase = r1;
- }else{
- sqlite3VdbeAddOp2(v, OP_SCopy, r1, regBase+j);
- }
- }
- testcase( pTerm->eOperator & WO_ISNULL );
- testcase( pTerm->eOperator & WO_IN );
- if( (pTerm->eOperator & (WO_ISNULL|WO_IN))==0 ){
- sqlite3VdbeAddOp2(v, OP_IsNull, regBase+j, pLevel->addrBrk);
- if( zAff
- && sqlite3CompareAffinity(pTerm->pExpr->pRight, zAff[j])==SQLITE_AFF_NONE
- ){
- zAff[j] = SQLITE_AFF_NONE;
- }
- }
- }
- *pzAff = zAff;
- return regBase;
-}
-
-/*
-** Generate code for the start of the iLevel-th loop in the WHERE clause
-** implementation described by pWInfo.
-*/
-static Bitmask codeOneLoopStart(
- WhereInfo *pWInfo, /* Complete information about the WHERE clause */
- int iLevel, /* Which level of pWInfo->a[] should be coded */
- u16 wctrlFlags, /* One of the WHERE_* flags defined in sqliteInt.h */
- Bitmask notReady /* Which tables are currently available */
-){
- int j, k; /* Loop counters */
- int iCur; /* The VDBE cursor for the table */
- int addrNxt; /* Where to jump to continue with the next IN case */
- int omitTable; /* True if we use the index only */
- int bRev; /* True if we need to scan in reverse order */
- WhereLevel *pLevel; /* The where level to be coded */
- WhereClause *pWC; /* Decomposition of the entire WHERE clause */
- WhereTerm *pTerm; /* A WHERE clause term */
- Parse *pParse; /* Parsing context */
- Vdbe *v; /* The prepared stmt under constructions */
- struct SrcList_item *pTabItem; /* FROM clause term being coded */
- int addrBrk; /* Jump here to break out of the loop */
- int addrCont; /* Jump here to continue with next cycle */
- int iRowidReg = 0; /* Rowid is stored in this register, if not zero */
- int iReleaseReg = 0; /* Temp register to free before returning */
-
- pParse = pWInfo->pParse;
- v = pParse->pVdbe;
- pWC = pWInfo->pWC;
- pLevel = &pWInfo->a[iLevel];
- pTabItem = &pWInfo->pTabList->a[pLevel->iFrom];
- iCur = pTabItem->iCursor;
- bRev = (pLevel->plan.wsFlags & WHERE_REVERSE)!=0;
- omitTable = (pLevel->plan.wsFlags & WHERE_IDX_ONLY)!=0
- && (wctrlFlags & WHERE_FORCE_TABLE)==0;
-
- /* Create labels for the "break" and "continue" instructions
- ** for the current loop. Jump to addrBrk to break out of a loop.
- ** Jump to cont to go immediately to the next iteration of the
- ** loop.
- **
- ** When there is an IN operator, we also have a "addrNxt" label that
- ** means to continue with the next IN value combination. When
- ** there are no IN operators in the constraints, the "addrNxt" label
- ** is the same as "addrBrk".
- */
- addrBrk = pLevel->addrBrk = pLevel->addrNxt = sqlite3VdbeMakeLabel(v);
- addrCont = pLevel->addrCont = sqlite3VdbeMakeLabel(v);
-
- /* If this is the right table of a LEFT OUTER JOIN, allocate and
- ** initialize a memory cell that records if this table matches any
- ** row of the left table of the join.
- */
- if( pLevel->iFrom>0 && (pTabItem[0].jointype & JT_LEFT)!=0 ){
- pLevel->iLeftJoin = ++pParse->nMem;
- sqlite3VdbeAddOp2(v, OP_Integer, 0, pLevel->iLeftJoin);
- VdbeComment((v, "init LEFT JOIN no-match flag"));
- }
-
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- if( (pLevel->plan.wsFlags & WHERE_VIRTUALTABLE)!=0 ){
- /* Case 0: The table is a virtual-table. Use the VFilter and VNext
- ** to access the data.
- */
- int iReg; /* P3 Value for OP_VFilter */
- sqlite3_index_info *pVtabIdx = pLevel->plan.u.pVtabIdx;
- int nConstraint = pVtabIdx->nConstraint;
- struct sqlite3_index_constraint_usage *aUsage =
- pVtabIdx->aConstraintUsage;
- const struct sqlite3_index_constraint *aConstraint =
- pVtabIdx->aConstraint;
-
- iReg = sqlite3GetTempRange(pParse, nConstraint+2);
- for(j=1; j<=nConstraint; j++){
- for(k=0; k<nConstraint; k++){
- if( aUsage[k].argvIndex==j ){
- int iTerm = aConstraint[k].iTermOffset;
- sqlite3ExprCode(pParse, pWC->a[iTerm].pExpr->pRight, iReg+j+1);
- break;
- }
- }
- if( k==nConstraint ) break;
- }
- sqlite3VdbeAddOp2(v, OP_Integer, pVtabIdx->idxNum, iReg);
- sqlite3VdbeAddOp2(v, OP_Integer, j-1, iReg+1);
- sqlite3VdbeAddOp4(v, OP_VFilter, iCur, addrBrk, iReg, pVtabIdx->idxStr,
- pVtabIdx->needToFreeIdxStr ? P4_MPRINTF : P4_STATIC);
- pVtabIdx->needToFreeIdxStr = 0;
- for(j=0; j<nConstraint; j++){
- if( aUsage[j].omit ){
- int iTerm = aConstraint[j].iTermOffset;
- disableTerm(pLevel, &pWC->a[iTerm]);
- }
- }
- pLevel->op = OP_VNext;
- pLevel->p1 = iCur;
- pLevel->p2 = sqlite3VdbeCurrentAddr(v);
- sqlite3ReleaseTempRange(pParse, iReg, nConstraint+2);
- }else
-#endif /* SQLITE_OMIT_VIRTUALTABLE */
-
- if( pLevel->plan.wsFlags & WHERE_ROWID_EQ ){
- /* Case 1: We can directly reference a single row using an
- ** equality comparison against the ROWID field. Or
- ** we reference multiple rows using a "rowid IN (...)"
- ** construct.
- */
- iReleaseReg = sqlite3GetTempReg(pParse);
- pTerm = findTerm(pWC, iCur, -1, notReady, WO_EQ|WO_IN, 0);
- assert( pTerm!=0 );
- assert( pTerm->pExpr!=0 );
- assert( pTerm->leftCursor==iCur );
- assert( omitTable==0 );
- iRowidReg = codeEqualityTerm(pParse, pTerm, pLevel, iReleaseReg);
- addrNxt = pLevel->addrNxt;
- sqlite3VdbeAddOp2(v, OP_MustBeInt, iRowidReg, addrNxt);
- sqlite3VdbeAddOp3(v, OP_NotExists, iCur, addrNxt, iRowidReg);
- sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg);
- VdbeComment((v, "pk"));
- pLevel->op = OP_Noop;
- }else if( pLevel->plan.wsFlags & WHERE_ROWID_RANGE ){
- /* Case 2: We have an inequality comparison against the ROWID field.
- */
- int testOp = OP_Noop;
- int start;
- int memEndValue = 0;
- WhereTerm *pStart, *pEnd;
-
- assert( omitTable==0 );
- pStart = findTerm(pWC, iCur, -1, notReady, WO_GT|WO_GE, 0);
- pEnd = findTerm(pWC, iCur, -1, notReady, WO_LT|WO_LE, 0);
- if( bRev ){
- pTerm = pStart;
- pStart = pEnd;
- pEnd = pTerm;
- }
- if( pStart ){
- Expr *pX; /* The expression that defines the start bound */
- int r1, rTemp; /* Registers for holding the start boundary */
-
- /* The following constant maps TK_xx codes into corresponding
- ** seek opcodes. It depends on a particular ordering of TK_xx
- */
- const u8 aMoveOp[] = {
- /* TK_GT */ OP_SeekGt,
- /* TK_LE */ OP_SeekLe,
- /* TK_LT */ OP_SeekLt,
- /* TK_GE */ OP_SeekGe
- };
- assert( TK_LE==TK_GT+1 ); /* Make sure the ordering.. */
- assert( TK_LT==TK_GT+2 ); /* ... of the TK_xx values... */
- assert( TK_GE==TK_GT+3 ); /* ... is correcct. */
-
- pX = pStart->pExpr;
- assert( pX!=0 );
- assert( pStart->leftCursor==iCur );
- r1 = sqlite3ExprCodeTemp(pParse, pX->pRight, &rTemp);
- sqlite3VdbeAddOp3(v, aMoveOp[pX->op-TK_GT], iCur, addrBrk, r1);
- VdbeComment((v, "pk"));
- sqlite3ExprCacheAffinityChange(pParse, r1, 1);
- sqlite3ReleaseTempReg(pParse, rTemp);
- disableTerm(pLevel, pStart);
- }else{
- sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iCur, addrBrk);
- }
- if( pEnd ){
- Expr *pX;
- pX = pEnd->pExpr;
- assert( pX!=0 );
- assert( pEnd->leftCursor==iCur );
- memEndValue = ++pParse->nMem;
- sqlite3ExprCode(pParse, pX->pRight, memEndValue);
- if( pX->op==TK_LT || pX->op==TK_GT ){
- testOp = bRev ? OP_Le : OP_Ge;
- }else{
- testOp = bRev ? OP_Lt : OP_Gt;
- }
- disableTerm(pLevel, pEnd);
- }
- start = sqlite3VdbeCurrentAddr(v);
- pLevel->op = bRev ? OP_Prev : OP_Next;
- pLevel->p1 = iCur;
- pLevel->p2 = start;
- pLevel->p5 = (pStart==0 && pEnd==0) ?1:0;
- if( testOp!=OP_Noop ){
- iRowidReg = iReleaseReg = sqlite3GetTempReg(pParse);
- sqlite3VdbeAddOp2(v, OP_Rowid, iCur, iRowidReg);
- sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg);
- sqlite3VdbeAddOp3(v, testOp, memEndValue, addrBrk, iRowidReg);
- sqlite3VdbeChangeP5(v, SQLITE_AFF_NUMERIC | SQLITE_JUMPIFNULL);
- }
- }else if( pLevel->plan.wsFlags & (WHERE_COLUMN_RANGE|WHERE_COLUMN_EQ) ){
- /* Case 3: A scan using an index.
- **
- ** The WHERE clause may contain zero or more equality
- ** terms ("==" or "IN" operators) that refer to the N
- ** left-most columns of the index. It may also contain
- ** inequality constraints (>, <, >= or <=) on the indexed
- ** column that immediately follows the N equalities. Only
- ** the right-most column can be an inequality - the rest must
- ** use the "==" and "IN" operators. For example, if the
- ** index is on (x,y,z), then the following clauses are all
- ** optimized:
- **
- ** x=5
- ** x=5 AND y=10
- ** x=5 AND y<10
- ** x=5 AND y>5 AND y<10
- ** x=5 AND y=5 AND z<=10
- **
- ** The z<10 term of the following cannot be used, only
- ** the x=5 term:
- **
- ** x=5 AND z<10
- **
- ** N may be zero if there are inequality constraints.
- ** If there are no inequality constraints, then N is at
- ** least one.
- **
- ** This case is also used when there are no WHERE clause
- ** constraints but an index is selected anyway, in order
- ** to force the output order to conform to an ORDER BY.
- */
- int aStartOp[] = {
- 0,
- 0,
- OP_Rewind, /* 2: (!start_constraints && startEq && !bRev) */
- OP_Last, /* 3: (!start_constraints && startEq && bRev) */
- OP_SeekGt, /* 4: (start_constraints && !startEq && !bRev) */
- OP_SeekLt, /* 5: (start_constraints && !startEq && bRev) */
- OP_SeekGe, /* 6: (start_constraints && startEq && !bRev) */
- OP_SeekLe /* 7: (start_constraints && startEq && bRev) */
- };
- int aEndOp[] = {
- OP_Noop, /* 0: (!end_constraints) */
- OP_IdxGE, /* 1: (end_constraints && !bRev) */
- OP_IdxLT /* 2: (end_constraints && bRev) */
- };
- int nEq = pLevel->plan.nEq;
- int isMinQuery = 0; /* If this is an optimized SELECT min(x).. */
- int regBase; /* Base register holding constraint values */
- int r1; /* Temp register */
- WhereTerm *pRangeStart = 0; /* Inequality constraint at range start */
- WhereTerm *pRangeEnd = 0; /* Inequality constraint at range end */
- int startEq; /* True if range start uses ==, >= or <= */
- int endEq; /* True if range end uses ==, >= or <= */
- int start_constraints; /* Start of range is constrained */
- int nConstraint; /* Number of constraint terms */
- Index *pIdx; /* The index we will be using */
- int iIdxCur; /* The VDBE cursor for the index */
- int nExtraReg = 0; /* Number of extra registers needed */
- int op; /* Instruction opcode */
- char *zAff;
-
- pIdx = pLevel->plan.u.pIdx;
- iIdxCur = pLevel->iIdxCur;
- k = pIdx->aiColumn[nEq]; /* Column for inequality constraints */
-
- /* If this loop satisfies a sort order (pOrderBy) request that
- ** was passed to this function to implement a "SELECT min(x) ..."
- ** query, then the caller will only allow the loop to run for
- ** a single iteration. This means that the first row returned
- ** should not have a NULL value stored in 'x'. If column 'x' is
- ** the first one after the nEq equality constraints in the index,
- ** this requires some special handling.
- */
- if( (wctrlFlags&WHERE_ORDERBY_MIN)!=0
- && (pLevel->plan.wsFlags&WHERE_ORDERBY)
- && (pIdx->nColumn>nEq)
- ){
- /* assert( pOrderBy->nExpr==1 ); */
- /* assert( pOrderBy->a[0].pExpr->iColumn==pIdx->aiColumn[nEq] ); */
- isMinQuery = 1;
- nExtraReg = 1;
- }
-
- /* Find any inequality constraint terms for the start and end
- ** of the range.
- */
- if( pLevel->plan.wsFlags & WHERE_TOP_LIMIT ){
- pRangeEnd = findTerm(pWC, iCur, k, notReady, (WO_LT|WO_LE), pIdx);
- nExtraReg = 1;
- }
- if( pLevel->plan.wsFlags & WHERE_BTM_LIMIT ){
- pRangeStart = findTerm(pWC, iCur, k, notReady, (WO_GT|WO_GE), pIdx);
- nExtraReg = 1;
- }
-
- /* Generate code to evaluate all constraint terms using == or IN
- ** and store the values of those terms in an array of registers
- ** starting at regBase.
- */
- regBase = codeAllEqualityTerms(
- pParse, pLevel, pWC, notReady, nExtraReg, &zAff
- );
- addrNxt = pLevel->addrNxt;
-
- /* If we are doing a reverse order scan on an ascending index, or
- ** a forward order scan on a descending index, interchange the
- ** start and end terms (pRangeStart and pRangeEnd).
- */
- if( bRev==(pIdx->aSortOrder[nEq]==SQLITE_SO_ASC) ){
- SWAP(WhereTerm *, pRangeEnd, pRangeStart);
- }
-
- testcase( pRangeStart && pRangeStart->eOperator & WO_LE );
- testcase( pRangeStart && pRangeStart->eOperator & WO_GE );
- testcase( pRangeEnd && pRangeEnd->eOperator & WO_LE );
- testcase( pRangeEnd && pRangeEnd->eOperator & WO_GE );
- startEq = !pRangeStart || pRangeStart->eOperator & (WO_LE|WO_GE);
- endEq = !pRangeEnd || pRangeEnd->eOperator & (WO_LE|WO_GE);
- start_constraints = pRangeStart || nEq>0;
-
- /* Seek the index cursor to the start of the range. */
- nConstraint = nEq;
- if( pRangeStart ){
- Expr *pRight = pRangeStart->pExpr->pRight;
- sqlite3ExprCode(pParse, pRight, regBase+nEq);
- sqlite3VdbeAddOp2(v, OP_IsNull, regBase+nEq, addrNxt);
- if( zAff
- && sqlite3CompareAffinity(pRight, zAff[nConstraint])==SQLITE_AFF_NONE
- ){
- /* Since the comparison is to be performed with no conversions applied
- ** to the operands, set the affinity to apply to pRight to
- ** SQLITE_AFF_NONE. */
- zAff[nConstraint] = SQLITE_AFF_NONE;
- }
- nConstraint++;
- }else if( isMinQuery ){
- sqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq);
- nConstraint++;
- startEq = 0;
- start_constraints = 1;
- }
- codeApplyAffinity(pParse, regBase, nConstraint, zAff);
- op = aStartOp[(start_constraints<<2) + (startEq<<1) + bRev];
- assert( op!=0 );
- testcase( op==OP_Rewind );
- testcase( op==OP_Last );
- testcase( op==OP_SeekGt );
- testcase( op==OP_SeekGe );
- testcase( op==OP_SeekLe );
- testcase( op==OP_SeekLt );
- sqlite3VdbeAddOp4(v, op, iIdxCur, addrNxt, regBase,
- SQLITE_INT_TO_PTR(nConstraint), P4_INT32);
-
- /* Load the value for the inequality constraint at the end of the
- ** range (if any).
- */
- nConstraint = nEq;
- if( pRangeEnd ){
- Expr *pRight = pRangeEnd->pExpr->pRight;
- sqlite3ExprCacheRemove(pParse, regBase+nEq);
- sqlite3ExprCode(pParse, pRight, regBase+nEq);
- sqlite3VdbeAddOp2(v, OP_IsNull, regBase+nEq, addrNxt);
- zAff = sqlite3DbStrDup(pParse->db, zAff);
- if( zAff
- && sqlite3CompareAffinity(pRight, zAff[nConstraint])==SQLITE_AFF_NONE
- ){
- /* Since the comparison is to be performed with no conversions applied
- ** to the operands, set the affinity to apply to pRight to
- ** SQLITE_AFF_NONE. */
- zAff[nConstraint] = SQLITE_AFF_NONE;
- }
- codeApplyAffinity(pParse, regBase, nEq+1, zAff);
- nConstraint++;
- }
-
- /* Top of the loop body */
- pLevel->p2 = sqlite3VdbeCurrentAddr(v);
-
- /* Check if the index cursor is past the end of the range. */
- op = aEndOp[(pRangeEnd || nEq) * (1 + bRev)];
- testcase( op==OP_Noop );
- testcase( op==OP_IdxGE );
- testcase( op==OP_IdxLT );
- if( op!=OP_Noop ){
- sqlite3VdbeAddOp4(v, op, iIdxCur, addrNxt, regBase,
- SQLITE_INT_TO_PTR(nConstraint), P4_INT32);
- sqlite3VdbeChangeP5(v, endEq!=bRev ?1:0);
- }
-
- /* If there are inequality constraints, check that the value
- ** of the table column that the inequality contrains is not NULL.
- ** If it is, jump to the next iteration of the loop.
- */
- r1 = sqlite3GetTempReg(pParse);
- testcase( pLevel->plan.wsFlags & WHERE_BTM_LIMIT );
- testcase( pLevel->plan.wsFlags & WHERE_TOP_LIMIT );
- if( pLevel->plan.wsFlags & (WHERE_BTM_LIMIT|WHERE_TOP_LIMIT) ){
- sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, nEq, r1);
- sqlite3VdbeAddOp2(v, OP_IsNull, r1, addrCont);
- }
- sqlite3ReleaseTempReg(pParse, r1);
-
- /* Seek the table cursor, if required */
- disableTerm(pLevel, pRangeStart);
- disableTerm(pLevel, pRangeEnd);
- if( !omitTable ){
- iRowidReg = iReleaseReg = sqlite3GetTempReg(pParse);
- sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, iRowidReg);
- sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg);
- sqlite3VdbeAddOp2(v, OP_Seek, iCur, iRowidReg); /* Deferred seek */
- }
-
- /* Record the instruction used to terminate the loop. Disable
- ** WHERE clause terms made redundant by the index range scan.
- */
- pLevel->op = bRev ? OP_Prev : OP_Next;
- pLevel->p1 = iIdxCur;
- }else
-
-#ifndef SQLITE_OMIT_OR_OPTIMIZATION
- if( pLevel->plan.wsFlags & WHERE_MULTI_OR ){
- /* Case 4: Two or more separately indexed terms connected by OR
- **
- ** Example:
- **
- ** CREATE TABLE t1(a,b,c,d);
- ** CREATE INDEX i1 ON t1(a);
- ** CREATE INDEX i2 ON t1(b);
- ** CREATE INDEX i3 ON t1(c);
- **
- ** SELECT * FROM t1 WHERE a=5 OR b=7 OR (c=11 AND d=13)
- **
- ** In the example, there are three indexed terms connected by OR.
- ** The top of the loop looks like this:
- **
- ** Null 1 # Zero the rowset in reg 1
- **
- ** Then, for each indexed term, the following. The arguments to
- ** RowSetTest are such that the rowid of the current row is inserted
- ** into the RowSet. If it is already present, control skips the
- ** Gosub opcode and jumps straight to the code generated by WhereEnd().
- **
- ** sqlite3WhereBegin(<term>)
- ** RowSetTest # Insert rowid into rowset
- ** Gosub 2 A
- ** sqlite3WhereEnd()
- **
- ** Following the above, code to terminate the loop. Label A, the target
- ** of the Gosub above, jumps to the instruction right after the Goto.
- **
- ** Null 1 # Zero the rowset in reg 1
- ** Goto B # The loop is finished.
- **
- ** A: <loop body> # Return data, whatever.
- **
- ** Return 2 # Jump back to the Gosub
- **
- ** B: <after the loop>
- **
- */
- WhereClause *pOrWc; /* The OR-clause broken out into subterms */
- WhereTerm *pFinal; /* Final subterm within the OR-clause. */
- SrcList oneTab; /* Shortened table list */
-
- int regReturn = ++pParse->nMem; /* Register used with OP_Gosub */
- int regRowset = 0; /* Register for RowSet object */
- int regRowid = 0; /* Register holding rowid */
- int iLoopBody = sqlite3VdbeMakeLabel(v); /* Start of loop body */
- int iRetInit; /* Address of regReturn init */
- int ii;
-
- pTerm = pLevel->plan.u.pTerm;
- assert( pTerm!=0 );
- assert( pTerm->eOperator==WO_OR );
- assert( (pTerm->wtFlags & TERM_ORINFO)!=0 );
- pOrWc = &pTerm->u.pOrInfo->wc;
- pFinal = &pOrWc->a[pOrWc->nTerm-1];
-
- /* Set up a SrcList containing just the table being scanned by this loop. */
- oneTab.nSrc = 1;
- oneTab.nAlloc = 1;
- oneTab.a[0] = *pTabItem;
-
- /* Initialize the rowset register to contain NULL. An SQL NULL is
- ** equivalent to an empty rowset.
- **
- ** Also initialize regReturn to contain the address of the instruction
- ** immediately following the OP_Return at the bottom of the loop. This
- ** is required in a few obscure LEFT JOIN cases where control jumps
- ** over the top of the loop into the body of it. In this case the
- ** correct response for the end-of-loop code (the OP_Return) is to
- ** fall through to the next instruction, just as an OP_Next does if
- ** called on an uninitialized cursor.
- */
- if( (wctrlFlags & WHERE_DUPLICATES_OK)==0 ){
- regRowset = ++pParse->nMem;
- regRowid = ++pParse->nMem;
- sqlite3VdbeAddOp2(v, OP_Null, 0, regRowset);
- }
- iRetInit = sqlite3VdbeAddOp2(v, OP_Integer, 0, regReturn);
-
- for(ii=0; ii<pOrWc->nTerm; ii++){
- WhereTerm *pOrTerm = &pOrWc->a[ii];
- if( pOrTerm->leftCursor==iCur || pOrTerm->eOperator==WO_AND ){
- WhereInfo *pSubWInfo; /* Info for single OR-term scan */
- /* Loop through table entries that match term pOrTerm. */
- pSubWInfo = sqlite3WhereBegin(pParse, &oneTab, pOrTerm->pExpr, 0,
- WHERE_OMIT_OPEN | WHERE_OMIT_CLOSE | WHERE_FORCE_TABLE);
- if( pSubWInfo ){
- if( (wctrlFlags & WHERE_DUPLICATES_OK)==0 ){
- int iSet = ((ii==pOrWc->nTerm-1)?-1:ii);
- int r;
- r = sqlite3ExprCodeGetColumn(pParse, pTabItem->pTab, -1, iCur,
- regRowid, 0);
- sqlite3VdbeAddOp4(v, OP_RowSetTest, regRowset,
- sqlite3VdbeCurrentAddr(v)+2,
- r, SQLITE_INT_TO_PTR(iSet), P4_INT32);
- }
- sqlite3VdbeAddOp2(v, OP_Gosub, regReturn, iLoopBody);
-
- /* Finish the loop through table entries that match term pOrTerm. */
- sqlite3WhereEnd(pSubWInfo);
- }
- }
- }
- sqlite3VdbeChangeP1(v, iRetInit, sqlite3VdbeCurrentAddr(v));
- /* sqlite3VdbeAddOp2(v, OP_Null, 0, regRowset); */
- sqlite3VdbeAddOp2(v, OP_Goto, 0, pLevel->addrBrk);
- sqlite3VdbeResolveLabel(v, iLoopBody);
-
- pLevel->op = OP_Return;
- pLevel->p1 = regReturn;
- disableTerm(pLevel, pTerm);
- }else
-#endif /* SQLITE_OMIT_OR_OPTIMIZATION */
-
- {
- /* Case 5: There is no usable index. We must do a complete
- ** scan of the entire table.
- */
- static const u8 aStep[] = { OP_Next, OP_Prev };
- static const u8 aStart[] = { OP_Rewind, OP_Last };
- assert( bRev==0 || bRev==1 );
- assert( omitTable==0 );
- pLevel->op = aStep[bRev];
- pLevel->p1 = iCur;
- pLevel->p2 = 1 + sqlite3VdbeAddOp2(v, aStart[bRev], iCur, addrBrk);
- pLevel->p5 = SQLITE_STMTSTATUS_FULLSCAN_STEP;
- }
- notReady &= ~getMask(pWC->pMaskSet, iCur);
-
- /* Insert code to test every subexpression that can be completely
- ** computed using the current set of tables.
- */
- k = 0;
- for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){
- Expr *pE;
- testcase( pTerm->wtFlags & TERM_VIRTUAL );
- testcase( pTerm->wtFlags & TERM_CODED );
- if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
- if( (pTerm->prereqAll & notReady)!=0 ) continue;
- pE = pTerm->pExpr;
- assert( pE!=0 );
- if( pLevel->iLeftJoin && !ExprHasProperty(pE, EP_FromJoin) ){
- continue;
- }
- sqlite3ExprIfFalse(pParse, pE, addrCont, SQLITE_JUMPIFNULL);
- k = 1;
- pTerm->wtFlags |= TERM_CODED;
- }
-
- /* For a LEFT OUTER JOIN, generate code that will record the fact that
- ** at least one row of the right table has matched the left table.
- */
- if( pLevel->iLeftJoin ){
- pLevel->addrFirst = sqlite3VdbeCurrentAddr(v);
- sqlite3VdbeAddOp2(v, OP_Integer, 1, pLevel->iLeftJoin);
- VdbeComment((v, "record LEFT JOIN hit"));
- sqlite3ExprCacheClear(pParse);
- for(pTerm=pWC->a, j=0; j<pWC->nTerm; j++, pTerm++){
- testcase( pTerm->wtFlags & TERM_VIRTUAL );
- testcase( pTerm->wtFlags & TERM_CODED );
- if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
- if( (pTerm->prereqAll & notReady)!=0 ) continue;
- assert( pTerm->pExpr );
- sqlite3ExprIfFalse(pParse, pTerm->pExpr, addrCont, SQLITE_JUMPIFNULL);
- pTerm->wtFlags |= TERM_CODED;
- }
- }
- sqlite3ReleaseTempReg(pParse, iReleaseReg);
-
- return notReady;
-}
-
-#if defined(SQLITE_TEST)
-/*
-** The following variable holds a text description of query plan generated
-** by the most recent call to sqlite3WhereBegin(). Each call to WhereBegin
-** overwrites the previous. This information is used for testing and
-** analysis only.
-*/
-SQLITE_API char sqlite3_query_plan[BMS*2*40]; /* Text of the join */
-static int nQPlan = 0; /* Next free slow in _query_plan[] */
-
-#endif /* SQLITE_TEST */
-
-
-/*
-** Free a WhereInfo structure
-*/
-static void whereInfoFree(sqlite3 *db, WhereInfo *pWInfo){
- if( pWInfo ){
- int i;
- for(i=0; i<pWInfo->nLevel; i++){
- sqlite3_index_info *pInfo = pWInfo->a[i].pIdxInfo;
- if( pInfo ){
- /* assert( pInfo->needToFreeIdxStr==0 || db->mallocFailed ); */
- if( pInfo->needToFreeIdxStr ){
- sqlite3_free(pInfo->idxStr);
- }
- sqlite3DbFree(db, pInfo);
- }
- }
- whereClauseClear(pWInfo->pWC);
- sqlite3DbFree(db, pWInfo);
- }
-}
-
-
-/*
-** Generate the beginning of the loop used for WHERE clause processing.
-** The return value is a pointer to an opaque structure that contains
-** information needed to terminate the loop. Later, the calling routine
-** should invoke sqlite3WhereEnd() with the return value of this function
-** in order to complete the WHERE clause processing.
-**
-** If an error occurs, this routine returns NULL.
-**
-** The basic idea is to do a nested loop, one loop for each table in
-** the FROM clause of a select. (INSERT and UPDATE statements are the
-** same as a SELECT with only a single table in the FROM clause.) For
-** example, if the SQL is this:
-**
-** SELECT * FROM t1, t2, t3 WHERE ...;
-**
-** Then the code generated is conceptually like the following:
-**
-** foreach row1 in t1 do \ Code generated
-** foreach row2 in t2 do |-- by sqlite3WhereBegin()
-** foreach row3 in t3 do /
-** ...
-** end \ Code generated
-** end |-- by sqlite3WhereEnd()
-** end /
-**
-** Note that the loops might not be nested in the order in which they
-** appear in the FROM clause if a different order is better able to make
-** use of indices. Note also that when the IN operator appears in
-** the WHERE clause, it might result in additional nested loops for
-** scanning through all values on the right-hand side of the IN.
-**
-** There are Btree cursors associated with each table. t1 uses cursor
-** number pTabList->a[0].iCursor. t2 uses the cursor pTabList->a[1].iCursor.
-** And so forth. This routine generates code to open those VDBE cursors
-** and sqlite3WhereEnd() generates the code to close them.
-**
-** The code that sqlite3WhereBegin() generates leaves the cursors named
-** in pTabList pointing at their appropriate entries. The [...] code
-** can use OP_Column and OP_Rowid opcodes on these cursors to extract
-** data from the various tables of the loop.
-**
-** If the WHERE clause is empty, the foreach loops must each scan their
-** entire tables. Thus a three-way join is an O(N^3) operation. But if
-** the tables have indices and there are terms in the WHERE clause that
-** refer to those indices, a complete table scan can be avoided and the
-** code will run much faster. Most of the work of this routine is checking
-** to see if there are indices that can be used to speed up the loop.
-**
-** Terms of the WHERE clause are also used to limit which rows actually
-** make it to the "..." in the middle of the loop. After each "foreach",
-** terms of the WHERE clause that use only terms in that loop and outer
-** loops are evaluated and if false a jump is made around all subsequent
-** inner loops (or around the "..." if the test occurs within the inner-
-** most loop)
-**
-** OUTER JOINS
-**
-** An outer join of tables t1 and t2 is conceptally coded as follows:
-**
-** foreach row1 in t1 do
-** flag = 0
-** foreach row2 in t2 do
-** start:
-** ...
-** flag = 1
-** end
-** if flag==0 then
-** move the row2 cursor to a null row
-** goto start
-** fi
-** end
-**
-** ORDER BY CLAUSE PROCESSING
-**
-** *ppOrderBy is a pointer to the ORDER BY clause of a SELECT statement,
-** if there is one. If there is no ORDER BY clause or if this routine
-** is called from an UPDATE or DELETE statement, then ppOrderBy is NULL.
-**
-** If an index can be used so that the natural output order of the table
-** scan is correct for the ORDER BY clause, then that index is used and
-** *ppOrderBy is set to NULL. This is an optimization that prevents an
-** unnecessary sort of the result set if an index appropriate for the
-** ORDER BY clause already exists.
-**
-** If the where clause loops cannot be arranged to provide the correct
-** output order, then the *ppOrderBy is unchanged.
-*/
-SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
- Parse *pParse, /* The parser context */
- SrcList *pTabList, /* A list of all tables to be scanned */
- Expr *pWhere, /* The WHERE clause */
- ExprList **ppOrderBy, /* An ORDER BY clause, or NULL */
- u16 wctrlFlags /* One of the WHERE_* flags defined in sqliteInt.h */
-){
- int i; /* Loop counter */
- int nByteWInfo; /* Num. bytes allocated for WhereInfo struct */
- WhereInfo *pWInfo; /* Will become the return value of this function */
- Vdbe *v = pParse->pVdbe; /* The virtual database engine */
- Bitmask notReady; /* Cursors that are not yet positioned */
- WhereMaskSet *pMaskSet; /* The expression mask set */
- WhereClause *pWC; /* Decomposition of the WHERE clause */
- struct SrcList_item *pTabItem; /* A single entry from pTabList */
- WhereLevel *pLevel; /* A single level in the pWInfo list */
- int iFrom; /* First unused FROM clause element */
- int andFlags; /* AND-ed combination of all pWC->a[].wtFlags */
- sqlite3 *db; /* Database connection */
-
- /* The number of tables in the FROM clause is limited by the number of
- ** bits in a Bitmask
- */
- if( pTabList->nSrc>BMS ){
- sqlite3ErrorMsg(pParse, "at most %d tables in a join", BMS);
- return 0;
- }
-
- /* Allocate and initialize the WhereInfo structure that will become the
- ** return value. A single allocation is used to store the WhereInfo
- ** struct, the contents of WhereInfo.a[], the WhereClause structure
- ** and the WhereMaskSet structure. Since WhereClause contains an 8-byte
- ** field (type Bitmask) it must be aligned on an 8-byte boundary on
- ** some architectures. Hence the ROUND8() below.
- */
- db = pParse->db;
- nByteWInfo = ROUND8(sizeof(WhereInfo)+(pTabList->nSrc-1)*sizeof(WhereLevel));
- pWInfo = sqlite3DbMallocZero(db,
- nByteWInfo +
- sizeof(WhereClause) +
- sizeof(WhereMaskSet)
- );
- if( db->mallocFailed ){
- goto whereBeginError;
- }
- pWInfo->nLevel = pTabList->nSrc;
- pWInfo->pParse = pParse;
- pWInfo->pTabList = pTabList;
- pWInfo->iBreak = sqlite3VdbeMakeLabel(v);
- pWInfo->pWC = pWC = (WhereClause *)&((u8 *)pWInfo)[nByteWInfo];
- pWInfo->wctrlFlags = wctrlFlags;
- pMaskSet = (WhereMaskSet*)&pWC[1];
-
- /* Split the WHERE clause into separate subexpressions where each
- ** subexpression is separated by an AND operator.
- */
- initMaskSet(pMaskSet);
- whereClauseInit(pWC, pParse, pMaskSet);
- sqlite3ExprCodeConstants(pParse, pWhere);
- whereSplit(pWC, pWhere, TK_AND);
-
- /* Special case: a WHERE clause that is constant. Evaluate the
- ** expression and either jump over all of the code or fall thru.
- */
- if( pWhere && (pTabList->nSrc==0 || sqlite3ExprIsConstantNotJoin(pWhere)) ){
- sqlite3ExprIfFalse(pParse, pWhere, pWInfo->iBreak, SQLITE_JUMPIFNULL);
- pWhere = 0;
- }
-
- /* Assign a bit from the bitmask to every term in the FROM clause.
- **
- ** When assigning bitmask values to FROM clause cursors, it must be
- ** the case that if X is the bitmask for the N-th FROM clause term then
- ** the bitmask for all FROM clause terms to the left of the N-th term
- ** is (X-1). An expression from the ON clause of a LEFT JOIN can use
- ** its Expr.iRightJoinTable value to find the bitmask of the right table
- ** of the join. Subtracting one from the right table bitmask gives a
- ** bitmask for all tables to the left of the join. Knowing the bitmask
- ** for all tables to the left of a left join is important. Ticket #3015.
- **
- ** Configure the WhereClause.vmask variable so that bits that correspond
- ** to virtual table cursors are set. This is used to selectively disable
- ** the OR-to-IN transformation in exprAnalyzeOrTerm(). It is not helpful
- ** with virtual tables.
- */
- assert( pWC->vmask==0 && pMaskSet->n==0 );
- for(i=0; i<pTabList->nSrc; i++){
- createMask(pMaskSet, pTabList->a[i].iCursor);
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- if( ALWAYS(pTabList->a[i].pTab) && IsVirtual(pTabList->a[i].pTab) ){
- pWC->vmask |= ((Bitmask)1 << i);
- }
-#endif
- }
-#ifndef NDEBUG
- {
- Bitmask toTheLeft = 0;
- for(i=0; i<pTabList->nSrc; i++){
- Bitmask m = getMask(pMaskSet, pTabList->a[i].iCursor);
- assert( (m-1)==toTheLeft );
- toTheLeft |= m;
- }
- }
-#endif
-
- /* Analyze all of the subexpressions. Note that exprAnalyze() might
- ** add new virtual terms onto the end of the WHERE clause. We do not
- ** want to analyze these virtual terms, so start analyzing at the end
- ** and work forward so that the added virtual terms are never processed.
- */
- exprAnalyzeAll(pTabList, pWC);
- if( db->mallocFailed ){
- goto whereBeginError;
- }
-
- /* Chose the best index to use for each table in the FROM clause.
- **
- ** This loop fills in the following fields:
- **
- ** pWInfo->a[].pIdx The index to use for this level of the loop.
- ** pWInfo->a[].wsFlags WHERE_xxx flags associated with pIdx
- ** pWInfo->a[].nEq The number of == and IN constraints
- ** pWInfo->a[].iFrom Which term of the FROM clause is being coded
- ** pWInfo->a[].iTabCur The VDBE cursor for the database table
- ** pWInfo->a[].iIdxCur The VDBE cursor for the index
- ** pWInfo->a[].pTerm When wsFlags==WO_OR, the OR-clause term
- **
- ** This loop also figures out the nesting order of tables in the FROM
- ** clause.
- */
- notReady = ~(Bitmask)0;
- pTabItem = pTabList->a;
- pLevel = pWInfo->a;
- andFlags = ~0;
- WHERETRACE(("*** Optimizer Start ***\n"));
- for(i=iFrom=0, pLevel=pWInfo->a; i<pTabList->nSrc; i++, pLevel++){
- WhereCost bestPlan; /* Most efficient plan seen so far */
- Index *pIdx; /* Index for FROM table at pTabItem */
- int j; /* For looping over FROM tables */
- int bestJ = -1; /* The value of j */
- Bitmask m; /* Bitmask value for j or bestJ */
- int isOptimal; /* Iterator for optimal/non-optimal search */
-
- memset(&bestPlan, 0, sizeof(bestPlan));
- bestPlan.rCost = SQLITE_BIG_DBL;
-
- /* Loop through the remaining entries in the FROM clause to find the
- ** next nested loop. The FROM clause entries may be iterated through
- ** either once or twice.
- **
- ** The first iteration, which is always performed, searches for the
- ** FROM clause entry that permits the lowest-cost, "optimal" scan. In
- ** this context an optimal scan is one that uses the same strategy
- ** for the given FROM clause entry as would be selected if the entry
- ** were used as the innermost nested loop. In other words, a table
- ** is chosen such that the cost of running that table cannot be reduced
- ** by waiting for other tables to run first.
- **
- ** The second iteration is only performed if no optimal scan strategies
- ** were found by the first. This iteration is used to search for the
- ** lowest cost scan overall.
- **
- ** Previous versions of SQLite performed only the second iteration -
- ** the next outermost loop was always that with the lowest overall
- ** cost. However, this meant that SQLite could select the wrong plan
- ** for scripts such as the following:
- **
- ** CREATE TABLE t1(a, b);
- ** CREATE TABLE t2(c, d);
- ** SELECT * FROM t2, t1 WHERE t2.rowid = t1.a;
- **
- ** The best strategy is to iterate through table t1 first. However it
- ** is not possible to determine this with a simple greedy algorithm.
- ** However, since the cost of a linear scan through table t2 is the same
- ** as the cost of a linear scan through table t1, a simple greedy
- ** algorithm may choose to use t2 for the outer loop, which is a much
- ** costlier approach.
- */
- for(isOptimal=1; isOptimal>=0 && bestJ<0; isOptimal--){
- Bitmask mask = (isOptimal ? 0 : notReady);
- assert( (pTabList->nSrc-iFrom)>1 || isOptimal );
- for(j=iFrom, pTabItem=&pTabList->a[j]; j<pTabList->nSrc; j++, pTabItem++){
- int doNotReorder; /* True if this table should not be reordered */
- WhereCost sCost; /* Cost information from best[Virtual]Index() */
- ExprList *pOrderBy; /* ORDER BY clause for index to optimize */
-
- doNotReorder = (pTabItem->jointype & (JT_LEFT|JT_CROSS))!=0;
- if( j!=iFrom && doNotReorder ) break;
- m = getMask(pMaskSet, pTabItem->iCursor);
- if( (m & notReady)==0 ){
- if( j==iFrom ) iFrom++;
- continue;
- }
- pOrderBy = ((i==0 && ppOrderBy )?*ppOrderBy:0);
-
- assert( pTabItem->pTab );
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- if( IsVirtual(pTabItem->pTab) ){
- sqlite3_index_info **pp = &pWInfo->a[j].pIdxInfo;
- bestVirtualIndex(pParse, pWC, pTabItem, mask, pOrderBy, &sCost, pp);
- }else
-#endif
- {
- bestBtreeIndex(pParse, pWC, pTabItem, mask, pOrderBy, &sCost);
- }
- assert( isOptimal || (sCost.used&notReady)==0 );
-
- if( (sCost.used&notReady)==0
- && (j==iFrom || sCost.rCost<bestPlan.rCost)
- ){
- bestPlan = sCost;
- bestJ = j;
- }
- if( doNotReorder ) break;
- }
- }
- assert( bestJ>=0 );
- assert( notReady & getMask(pMaskSet, pTabList->a[bestJ].iCursor) );
- WHERETRACE(("*** Optimizer selects table %d for loop %d\n", bestJ,
- pLevel-pWInfo->a));
- if( (bestPlan.plan.wsFlags & WHERE_ORDERBY)!=0 ){
- *ppOrderBy = 0;
- }
- andFlags &= bestPlan.plan.wsFlags;
- pLevel->plan = bestPlan.plan;
- if( bestPlan.plan.wsFlags & WHERE_INDEXED ){
- pLevel->iIdxCur = pParse->nTab++;
- }else{
- pLevel->iIdxCur = -1;
- }
- notReady &= ~getMask(pMaskSet, pTabList->a[bestJ].iCursor);
- pLevel->iFrom = (u8)bestJ;
-
- /* Check that if the table scanned by this loop iteration had an
- ** INDEXED BY clause attached to it, that the named index is being
- ** used for the scan. If not, then query compilation has failed.
- ** Return an error.
- */
- pIdx = pTabList->a[bestJ].pIndex;
- if( pIdx ){
- if( (bestPlan.plan.wsFlags & WHERE_INDEXED)==0 ){
- sqlite3ErrorMsg(pParse, "cannot use index: %s", pIdx->zName);
- goto whereBeginError;
- }else{
- /* If an INDEXED BY clause is used, the bestIndex() function is
- ** guaranteed to find the index specified in the INDEXED BY clause
- ** if it find an index at all. */
- assert( bestPlan.plan.u.pIdx==pIdx );
- }
- }
- }
- WHERETRACE(("*** Optimizer Finished ***\n"));
- if( pParse->nErr || db->mallocFailed ){
- goto whereBeginError;
- }
-
- /* If the total query only selects a single row, then the ORDER BY
- ** clause is irrelevant.
- */
- if( (andFlags & WHERE_UNIQUE)!=0 && ppOrderBy ){
- *ppOrderBy = 0;
- }
-
- /* If the caller is an UPDATE or DELETE statement that is requesting
- ** to use a one-pass algorithm, determine if this is appropriate.
- ** The one-pass algorithm only works if the WHERE clause constraints
- ** the statement to update a single row.
- */
- assert( (wctrlFlags & WHERE_ONEPASS_DESIRED)==0 || pWInfo->nLevel==1 );
- if( (wctrlFlags & WHERE_ONEPASS_DESIRED)!=0 && (andFlags & WHERE_UNIQUE)!=0 ){
- pWInfo->okOnePass = 1;
- pWInfo->a[0].plan.wsFlags &= ~WHERE_IDX_ONLY;
- }
-
- /* Open all tables in the pTabList and any indices selected for
- ** searching those tables.
- */
- sqlite3CodeVerifySchema(pParse, -1); /* Insert the cookie verifier Goto */
- for(i=0, pLevel=pWInfo->a; i<pTabList->nSrc; i++, pLevel++){
- Table *pTab; /* Table to open */
- int iDb; /* Index of database containing table/index */
-
-#ifndef SQLITE_OMIT_EXPLAIN
- if( pParse->explain==2 ){
- char *zMsg;
- struct SrcList_item *pItem = &pTabList->a[pLevel->iFrom];
- zMsg = sqlite3MPrintf(db, "TABLE %s", pItem->zName);
- if( pItem->zAlias ){
- zMsg = sqlite3MAppendf(db, zMsg, "%s AS %s", zMsg, pItem->zAlias);
- }
- if( (pLevel->plan.wsFlags & WHERE_INDEXED)!=0 ){
- zMsg = sqlite3MAppendf(db, zMsg, "%s WITH INDEX %s",
- zMsg, pLevel->plan.u.pIdx->zName);
- }else if( pLevel->plan.wsFlags & WHERE_MULTI_OR ){
- zMsg = sqlite3MAppendf(db, zMsg, "%s VIA MULTI-INDEX UNION", zMsg);
- }else if( pLevel->plan.wsFlags & (WHERE_ROWID_EQ|WHERE_ROWID_RANGE) ){
- zMsg = sqlite3MAppendf(db, zMsg, "%s USING PRIMARY KEY", zMsg);
- }
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- else if( (pLevel->plan.wsFlags & WHERE_VIRTUALTABLE)!=0 ){
- sqlite3_index_info *pVtabIdx = pLevel->plan.u.pVtabIdx;
- zMsg = sqlite3MAppendf(db, zMsg, "%s VIRTUAL TABLE INDEX %d:%s", zMsg,
- pVtabIdx->idxNum, pVtabIdx->idxStr);
- }
-#endif
- if( pLevel->plan.wsFlags & WHERE_ORDERBY ){
- zMsg = sqlite3MAppendf(db, zMsg, "%s ORDER BY", zMsg);
- }
- sqlite3VdbeAddOp4(v, OP_Explain, i, pLevel->iFrom, 0, zMsg, P4_DYNAMIC);
- }
-#endif /* SQLITE_OMIT_EXPLAIN */
- pTabItem = &pTabList->a[pLevel->iFrom];
- pTab = pTabItem->pTab;
- iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
- if( (pTab->tabFlags & TF_Ephemeral)!=0 || pTab->pSelect ) continue;
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- if( (pLevel->plan.wsFlags & WHERE_VIRTUALTABLE)!=0 ){
- const char *pVTab = (const char *)sqlite3GetVTable(db, pTab);
- int iCur = pTabItem->iCursor;
- sqlite3VdbeAddOp4(v, OP_VOpen, iCur, 0, 0, pVTab, P4_VTAB);
- }else
-#endif
- if( (pLevel->plan.wsFlags & WHERE_IDX_ONLY)==0
- && (wctrlFlags & WHERE_OMIT_OPEN)==0 ){
- int op = pWInfo->okOnePass ? OP_OpenWrite : OP_OpenRead;
- sqlite3OpenTable(pParse, pTabItem->iCursor, iDb, pTab, op);
- if( !pWInfo->okOnePass && pTab->nCol<BMS ){
- Bitmask b = pTabItem->colUsed;
- int n = 0;
- for(; b; b=b>>1, n++){}
- sqlite3VdbeChangeP4(v, sqlite3VdbeCurrentAddr(v)-1, SQLITE_INT_TO_PTR(n), P4_INT32);
- assert( n<=pTab->nCol );
- }
- }else{
- sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
- }
- pLevel->iTabCur = pTabItem->iCursor;
- if( (pLevel->plan.wsFlags & WHERE_INDEXED)!=0 ){
- Index *pIx = pLevel->plan.u.pIdx;
- KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIx);
- int iIdxCur = pLevel->iIdxCur;
- assert( pIx->pSchema==pTab->pSchema );
- assert( iIdxCur>=0 );
- sqlite3VdbeAddOp4(v, OP_OpenRead, iIdxCur, pIx->tnum, iDb,
- (char*)pKey, P4_KEYINFO_HANDOFF);
- VdbeComment((v, "%s", pIx->zName));
- }
- sqlite3CodeVerifySchema(pParse, iDb);
- }
- pWInfo->iTop = sqlite3VdbeCurrentAddr(v);
-
- /* Generate the code to do the search. Each iteration of the for
- ** loop below generates code for a single nested loop of the VM
- ** program.
- */
- notReady = ~(Bitmask)0;
- for(i=0; i<pTabList->nSrc; i++){
- notReady = codeOneLoopStart(pWInfo, i, wctrlFlags, notReady);
- pWInfo->iContinue = pWInfo->a[i].addrCont;
- }
-
-#ifdef SQLITE_TEST /* For testing and debugging use only */
- /* Record in the query plan information about the current table
- ** and the index used to access it (if any). If the table itself
- ** is not used, its name is just '{}'. If no index is used
- ** the index is listed as "{}". If the primary key is used the
- ** index name is '*'.
- */
- for(i=0; i<pTabList->nSrc; i++){
- char *z;
- int n;
- pLevel = &pWInfo->a[i];
- pTabItem = &pTabList->a[pLevel->iFrom];
- z = pTabItem->zAlias;
- if( z==0 ) z = pTabItem->pTab->zName;
- n = sqlite3Strlen30(z);
- if( n+nQPlan < sizeof(sqlite3_query_plan)-10 ){
- if( pLevel->plan.wsFlags & WHERE_IDX_ONLY ){
- memcpy(&sqlite3_query_plan[nQPlan], "{}", 2);
- nQPlan += 2;
- }else{
- memcpy(&sqlite3_query_plan[nQPlan], z, n);
- nQPlan += n;
- }
- sqlite3_query_plan[nQPlan++] = ' ';
- }
- testcase( pLevel->plan.wsFlags & WHERE_ROWID_EQ );
- testcase( pLevel->plan.wsFlags & WHERE_ROWID_RANGE );
- if( pLevel->plan.wsFlags & (WHERE_ROWID_EQ|WHERE_ROWID_RANGE) ){
- memcpy(&sqlite3_query_plan[nQPlan], "* ", 2);
- nQPlan += 2;
- }else if( (pLevel->plan.wsFlags & WHERE_INDEXED)!=0 ){
- n = sqlite3Strlen30(pLevel->plan.u.pIdx->zName);
- if( n+nQPlan < sizeof(sqlite3_query_plan)-2 ){
- memcpy(&sqlite3_query_plan[nQPlan], pLevel->plan.u.pIdx->zName, n);
- nQPlan += n;
- sqlite3_query_plan[nQPlan++] = ' ';
- }
- }else{
- memcpy(&sqlite3_query_plan[nQPlan], "{} ", 3);
- nQPlan += 3;
- }
- }
- while( nQPlan>0 && sqlite3_query_plan[nQPlan-1]==' ' ){
- sqlite3_query_plan[--nQPlan] = 0;
- }
- sqlite3_query_plan[nQPlan] = 0;
- nQPlan = 0;
-#endif /* SQLITE_TEST // Testing and debugging use only */
-
- /* Record the continuation address in the WhereInfo structure. Then
- ** clean up and return.
- */
- return pWInfo;
-
- /* Jump here if malloc fails */
-whereBeginError:
- whereInfoFree(db, pWInfo);
- return 0;
-}
-
-/*
-** Generate the end of the WHERE loop. See comments on
-** sqlite3WhereBegin() for additional information.
-*/
-SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
- Parse *pParse = pWInfo->pParse;
- Vdbe *v = pParse->pVdbe;
- int i;
- WhereLevel *pLevel;
- SrcList *pTabList = pWInfo->pTabList;
- sqlite3 *db = pParse->db;
-
- /* Generate loop termination code.
- */
- sqlite3ExprCacheClear(pParse);
- for(i=pTabList->nSrc-1; i>=0; i--){
- pLevel = &pWInfo->a[i];
- sqlite3VdbeResolveLabel(v, pLevel->addrCont);
- if( pLevel->op!=OP_Noop ){
- sqlite3VdbeAddOp2(v, pLevel->op, pLevel->p1, pLevel->p2);
- sqlite3VdbeChangeP5(v, pLevel->p5);
- }
- if( pLevel->plan.wsFlags & WHERE_IN_ABLE && pLevel->u.in.nIn>0 ){
- struct InLoop *pIn;
- int j;
- sqlite3VdbeResolveLabel(v, pLevel->addrNxt);
- for(j=pLevel->u.in.nIn, pIn=&pLevel->u.in.aInLoop[j-1]; j>0; j--, pIn--){
- sqlite3VdbeJumpHere(v, pIn->addrInTop+1);
- sqlite3VdbeAddOp2(v, OP_Next, pIn->iCur, pIn->addrInTop);
- sqlite3VdbeJumpHere(v, pIn->addrInTop-1);
- }
- sqlite3DbFree(db, pLevel->u.in.aInLoop);
- }
- sqlite3VdbeResolveLabel(v, pLevel->addrBrk);
- if( pLevel->iLeftJoin ){
- int addr;
- addr = sqlite3VdbeAddOp1(v, OP_IfPos, pLevel->iLeftJoin);
- sqlite3VdbeAddOp1(v, OP_NullRow, pTabList->a[i].iCursor);
- if( pLevel->iIdxCur>=0 ){
- sqlite3VdbeAddOp1(v, OP_NullRow, pLevel->iIdxCur);
- }
- if( pLevel->op==OP_Return ){
- sqlite3VdbeAddOp2(v, OP_Gosub, pLevel->p1, pLevel->addrFirst);
- }else{
- sqlite3VdbeAddOp2(v, OP_Goto, 0, pLevel->addrFirst);
- }
- sqlite3VdbeJumpHere(v, addr);
- }
- }
-
- /* The "break" point is here, just past the end of the outer loop.
- ** Set it.
- */
- sqlite3VdbeResolveLabel(v, pWInfo->iBreak);
-
- /* Close all of the cursors that were opened by sqlite3WhereBegin.
- */
- for(i=0, pLevel=pWInfo->a; i<pTabList->nSrc; i++, pLevel++){
- struct SrcList_item *pTabItem = &pTabList->a[pLevel->iFrom];
- Table *pTab = pTabItem->pTab;
- assert( pTab!=0 );
- if( (pTab->tabFlags & TF_Ephemeral)!=0 || pTab->pSelect ) continue;
- if( (pWInfo->wctrlFlags & WHERE_OMIT_CLOSE)==0 ){
- if( !pWInfo->okOnePass && (pLevel->plan.wsFlags & WHERE_IDX_ONLY)==0 ){
- sqlite3VdbeAddOp1(v, OP_Close, pTabItem->iCursor);
- }
- if( (pLevel->plan.wsFlags & WHERE_INDEXED)!=0 ){
- sqlite3VdbeAddOp1(v, OP_Close, pLevel->iIdxCur);
- }
- }
-
- /* If this scan uses an index, make code substitutions to read data
- ** from the index in preference to the table. Sometimes, this means
- ** the table need never be read from. This is a performance boost,
- ** as the vdbe level waits until the table is read before actually
- ** seeking the table cursor to the record corresponding to the current
- ** position in the index.
- **
- ** Calls to the code generator in between sqlite3WhereBegin and
- ** sqlite3WhereEnd will have created code that references the table
- ** directly. This loop scans all that code looking for opcodes
- ** that reference the table and converts them into opcodes that
- ** reference the index.
- */
- if( (pLevel->plan.wsFlags & WHERE_INDEXED)!=0 && !db->mallocFailed){
- int k, j, last;
- VdbeOp *pOp;
- Index *pIdx = pLevel->plan.u.pIdx;
- int useIndexOnly = pLevel->plan.wsFlags & WHERE_IDX_ONLY;
-
- assert( pIdx!=0 );
- pOp = sqlite3VdbeGetOp(v, pWInfo->iTop);
- last = sqlite3VdbeCurrentAddr(v);
- for(k=pWInfo->iTop; k<last; k++, pOp++){
- if( pOp->p1!=pLevel->iTabCur ) continue;
- if( pOp->opcode==OP_Column ){
- for(j=0; j<pIdx->nColumn; j++){
- if( pOp->p2==pIdx->aiColumn[j] ){
- pOp->p2 = j;
- pOp->p1 = pLevel->iIdxCur;
- break;
- }
- }
- assert(!useIndexOnly || j<pIdx->nColumn);
- }else if( pOp->opcode==OP_Rowid ){
- pOp->p1 = pLevel->iIdxCur;
- pOp->opcode = OP_IdxRowid;
- }else if( pOp->opcode==OP_NullRow && useIndexOnly ){
- pOp->opcode = OP_Noop;
- }
- }
- }
- }
-
- /* Final cleanup
- */
- whereInfoFree(db, pWInfo);
- return;
-}
-
-/************** End of where.c ***********************************************/
-/************** Begin file parse.c *******************************************/
-/* Driver template for the LEMON parser generator.
-** The author disclaims copyright to this source code.
-**
-** This version of "lempar.c" is modified, slightly, for use by SQLite.
-** The only modifications are the addition of a couple of NEVER()
-** macros to disable tests that are needed in the case of a general
-** LALR(1) grammar but which are always false in the
-** specific grammar used by SQLite.
-*/
-/* First off, code is included that follows the "include" declaration
-** in the input grammar file. */
-
-
-/*
-** Disable all error recovery processing in the parser push-down
-** automaton.
-*/
-#define YYNOERRORRECOVERY 1
-
-/*
-** Make yytestcase() the same as testcase()
-*/
-#define yytestcase(X) testcase(X)
-
-/*
-** An instance of this structure holds information about the
-** LIMIT clause of a SELECT statement.
-*/
-struct LimitVal {
- Expr *pLimit; /* The LIMIT expression. NULL if there is no limit */
- Expr *pOffset; /* The OFFSET expression. NULL if there is none */
-};
-
-/*
-** An instance of this structure is used to store the LIKE,
-** GLOB, NOT LIKE, and NOT GLOB operators.
-*/
-struct LikeOp {
- Token eOperator; /* "like" or "glob" or "regexp" */
- int not; /* True if the NOT keyword is present */
-};
-
-/*
-** An instance of the following structure describes the event of a
-** TRIGGER. "a" is the event type, one of TK_UPDATE, TK_INSERT,
-** TK_DELETE, or TK_INSTEAD. If the event is of the form
-**
-** UPDATE ON (a,b,c)
-**
-** Then the "b" IdList records the list "a,b,c".
-*/
-struct TrigEvent { int a; IdList * b; };
-
-/*
-** An instance of this structure holds the ATTACH key and the key type.
-*/
-struct AttachKey { int type; Token key; };
-
-
- /* This is a utility routine used to set the ExprSpan.zStart and
- ** ExprSpan.zEnd values of pOut so that the span covers the complete
- ** range of text beginning with pStart and going to the end of pEnd.
- */
- static void spanSet(ExprSpan *pOut, Token *pStart, Token *pEnd){
- pOut->zStart = pStart->z;
- pOut->zEnd = &pEnd->z[pEnd->n];
- }
-
- /* Construct a new Expr object from a single identifier. Use the
- ** new Expr to populate pOut. Set the span of pOut to be the identifier
- ** that created the expression.
- */
- static void spanExpr(ExprSpan *pOut, Parse *pParse, int op, Token *pValue){
- pOut->pExpr = sqlite3PExpr(pParse, op, 0, 0, pValue);
- pOut->zStart = pValue->z;
- pOut->zEnd = &pValue->z[pValue->n];
- }
-
- /* This routine constructs a binary expression node out of two ExprSpan
- ** objects and uses the result to populate a new ExprSpan object.
- */
- static void spanBinaryExpr(
- ExprSpan *pOut, /* Write the result here */
- Parse *pParse, /* The parsing context. Errors accumulate here */
- int op, /* The binary operation */
- ExprSpan *pLeft, /* The left operand */
- ExprSpan *pRight /* The right operand */
- ){
- pOut->pExpr = sqlite3PExpr(pParse, op, pLeft->pExpr, pRight->pExpr, 0);
- pOut->zStart = pLeft->zStart;
- pOut->zEnd = pRight->zEnd;
- }
-
- /* Construct an expression node for a unary postfix operator
- */
- static void spanUnaryPostfix(
- ExprSpan *pOut, /* Write the new expression node here */
- Parse *pParse, /* Parsing context to record errors */
- int op, /* The operator */
- ExprSpan *pOperand, /* The operand */
- Token *pPostOp /* The operand token for setting the span */
- ){
- pOut->pExpr = sqlite3PExpr(pParse, op, pOperand->pExpr, 0, 0);
- pOut->zStart = pOperand->zStart;
- pOut->zEnd = &pPostOp->z[pPostOp->n];
- }
-
- /* Construct an expression node for a unary prefix operator
- */
- static void spanUnaryPrefix(
- ExprSpan *pOut, /* Write the new expression node here */
- Parse *pParse, /* Parsing context to record errors */
- int op, /* The operator */
- ExprSpan *pOperand, /* The operand */
- Token *pPreOp /* The operand token for setting the span */
- ){
- pOut->pExpr = sqlite3PExpr(pParse, op, pOperand->pExpr, 0, 0);
- pOut->zStart = pPreOp->z;
- pOut->zEnd = pOperand->zEnd;
- }
-/* Next is all token values, in a form suitable for use by makeheaders.
-** This section will be null unless lemon is run with the -m switch.
-*/
-/*
-** These constants (all generated automatically by the parser generator)
-** specify the various kinds of tokens (terminals) that the parser
-** understands.
-**
-** Each symbol here is a terminal symbol in the grammar.
-*/
-/* Make sure the INTERFACE macro is defined.
-*/
-#ifndef INTERFACE
-# define INTERFACE 1
-#endif
-/* The next thing included is series of defines which control
-** various aspects of the generated parser.
-** YYCODETYPE is the data type used for storing terminal
-** and nonterminal numbers. "unsigned char" is
-** used if there are fewer than 250 terminals
-** and nonterminals. "int" is used otherwise.
-** YYNOCODE is a number of type YYCODETYPE which corresponds
-** to no legal terminal or nonterminal number. This
-** number is used to fill in empty slots of the hash
-** table.
-** YYFALLBACK If defined, this indicates that one or more tokens
-** have fall-back values which should be used if the
-** original value of the token will not parse.
-** YYACTIONTYPE is the data type used for storing terminal
-** and nonterminal numbers. "unsigned char" is
-** used if there are fewer than 250 rules and
-** states combined. "int" is used otherwise.
-** sqlite3ParserTOKENTYPE is the data type used for minor tokens given
-** directly to the parser from the tokenizer.
-** YYMINORTYPE is the data type used for all minor tokens.
-** This is typically a union of many types, one of
-** which is sqlite3ParserTOKENTYPE. The entry in the union
-** for base tokens is called "yy0".
-** YYSTACKDEPTH is the maximum depth of the parser's stack. If
-** zero the stack is dynamically sized using realloc()
-** sqlite3ParserARG_SDECL A static variable declaration for the %extra_argument
-** sqlite3ParserARG_PDECL A parameter declaration for the %extra_argument
-** sqlite3ParserARG_STORE Code to store %extra_argument into yypParser
-** sqlite3ParserARG_FETCH Code to extract %extra_argument from yypParser
-** YYNSTATE the combined number of states.
-** YYNRULE the number of rules in the grammar
-** YYERRORSYMBOL is the code number of the error symbol. If not
-** defined, then do no error processing.
-*/
-#define YYCODETYPE unsigned char
-#define YYNOCODE 254
-#define YYACTIONTYPE unsigned short int
-#define YYWILDCARD 65
-#define sqlite3ParserTOKENTYPE Token
-typedef union {
- int yyinit;
- sqlite3ParserTOKENTYPE yy0;
- Select* yy3;
- ExprList* yy14;
- SrcList* yy65;
- struct LikeOp yy96;
- Expr* yy132;
- u8 yy186;
- int yy328;
- ExprSpan yy346;
- struct TrigEvent yy378;
- IdList* yy408;
- struct {int value; int mask;} yy429;
- TriggerStep* yy473;
- struct LimitVal yy476;
-} YYMINORTYPE;
-#ifndef YYSTACKDEPTH
-#define YYSTACKDEPTH 100
-#endif
-#define sqlite3ParserARG_SDECL Parse *pParse;
-#define sqlite3ParserARG_PDECL ,Parse *pParse
-#define sqlite3ParserARG_FETCH Parse *pParse = yypParser->pParse
-#define sqlite3ParserARG_STORE yypParser->pParse = pParse
-#define YYNSTATE 629
-#define YYNRULE 329
-#define YYFALLBACK 1
-#define YY_NO_ACTION (YYNSTATE+YYNRULE+2)
-#define YY_ACCEPT_ACTION (YYNSTATE+YYNRULE+1)
-#define YY_ERROR_ACTION (YYNSTATE+YYNRULE)
-
-/* The yyzerominor constant is used to initialize instances of
-** YYMINORTYPE objects to zero. */
-static const YYMINORTYPE yyzerominor = { 0 };
-
-/* Define the yytestcase() macro to be a no-op if is not already defined
-** otherwise.
-**
-** Applications can choose to define yytestcase() in the %include section
-** to a macro that can assist in verifying code coverage. For production
-** code the yytestcase() macro should be turned off. But it is useful
-** for testing.
-*/
-#ifndef yytestcase
-# define yytestcase(X)
-#endif
-
-
-/* Next are the tables used to determine what action to take based on the
-** current state and lookahead token. These tables are used to implement
-** functions that take a state number and lookahead value and return an
-** action integer.
-**
-** Suppose the action integer is N. Then the action is determined as
-** follows
-**
-** 0 <= N < YYNSTATE Shift N. That is, push the lookahead
-** token onto the stack and goto state N.
-**
-** YYNSTATE <= N < YYNSTATE+YYNRULE Reduce by rule N-YYNSTATE.
-**
-** N == YYNSTATE+YYNRULE A syntax error has occurred.
-**
-** N == YYNSTATE+YYNRULE+1 The parser accepts its input.
-**
-** N == YYNSTATE+YYNRULE+2 No such action. Denotes unused
-** slots in the yy_action[] table.
-**
-** The action table is constructed as a single large table named yy_action[].
-** Given state S and lookahead X, the action is computed as
-**
-** yy_action[ yy_shift_ofst[S] + X ]
-**
-** If the index value yy_shift_ofst[S]+X is out of range or if the value
-** yy_lookahead[yy_shift_ofst[S]+X] is not equal to X or if yy_shift_ofst[S]
-** is equal to YY_SHIFT_USE_DFLT, it means that the action is not in the table
-** and that yy_default[S] should be used instead.
-**
-** The formula above is for computing the action when the lookahead is
-** a terminal symbol. If the lookahead is a non-terminal (as occurs after
-** a reduce action) then the yy_reduce_ofst[] array is used in place of
-** the yy_shift_ofst[] array and YY_REDUCE_USE_DFLT is used in place of
-** YY_SHIFT_USE_DFLT.
-**
-** The following are the tables generated in this section:
-**
-** yy_action[] A single table containing all actions.
-** yy_lookahead[] A table containing the lookahead for each entry in
-** yy_action. Used to detect hash collisions.
-** yy_shift_ofst[] For each state, the offset into yy_action for
-** shifting terminals.
-** yy_reduce_ofst[] For each state, the offset into yy_action for
-** shifting non-terminals after a reduce.
-** yy_default[] Default action for each state.
-*/
-static const YYACTIONTYPE yy_action[] = {
- /* 0 */ 309, 959, 178, 628, 2, 153, 216, 448, 24, 24,
- /* 10 */ 24, 24, 497, 26, 26, 26, 26, 27, 27, 28,
- /* 20 */ 28, 28, 29, 218, 422, 423, 214, 422, 423, 455,
- /* 30 */ 461, 31, 26, 26, 26, 26, 27, 27, 28, 28,
- /* 40 */ 28, 29, 218, 30, 492, 32, 137, 23, 22, 315,
- /* 50 */ 465, 466, 462, 462, 25, 25, 24, 24, 24, 24,
- /* 60 */ 445, 26, 26, 26, 26, 27, 27, 28, 28, 28,
- /* 70 */ 29, 218, 309, 218, 318, 448, 521, 499, 45, 26,
- /* 80 */ 26, 26, 26, 27, 27, 28, 28, 28, 29, 218,
- /* 90 */ 422, 423, 425, 426, 159, 425, 426, 366, 369, 370,
- /* 100 */ 318, 455, 461, 394, 523, 21, 188, 504, 371, 27,
- /* 110 */ 27, 28, 28, 28, 29, 218, 422, 423, 424, 23,
- /* 120 */ 22, 315, 465, 466, 462, 462, 25, 25, 24, 24,
- /* 130 */ 24, 24, 564, 26, 26, 26, 26, 27, 27, 28,
- /* 140 */ 28, 28, 29, 218, 309, 230, 513, 138, 477, 220,
- /* 150 */ 557, 148, 135, 260, 364, 265, 365, 156, 425, 426,
- /* 160 */ 245, 610, 337, 30, 269, 32, 137, 448, 608, 609,
- /* 170 */ 233, 230, 499, 455, 461, 57, 515, 334, 135, 260,
- /* 180 */ 364, 265, 365, 156, 425, 426, 444, 78, 417, 414,
- /* 190 */ 269, 23, 22, 315, 465, 466, 462, 462, 25, 25,
- /* 200 */ 24, 24, 24, 24, 348, 26, 26, 26, 26, 27,
- /* 210 */ 27, 28, 28, 28, 29, 218, 309, 216, 543, 556,
- /* 220 */ 486, 130, 498, 607, 30, 337, 32, 137, 351, 396,
- /* 230 */ 438, 63, 337, 361, 424, 448, 487, 337, 424, 544,
- /* 240 */ 334, 217, 195, 606, 605, 455, 461, 334, 18, 444,
- /* 250 */ 85, 488, 334, 347, 192, 565, 444, 78, 316, 472,
- /* 260 */ 473, 444, 85, 23, 22, 315, 465, 466, 462, 462,
- /* 270 */ 25, 25, 24, 24, 24, 24, 445, 26, 26, 26,
- /* 280 */ 26, 27, 27, 28, 28, 28, 29, 218, 309, 353,
- /* 290 */ 223, 320, 607, 193, 238, 337, 481, 16, 351, 185,
- /* 300 */ 330, 419, 222, 350, 604, 219, 215, 424, 112, 337,
- /* 310 */ 334, 157, 606, 408, 213, 563, 538, 455, 461, 444,
- /* 320 */ 79, 219, 562, 524, 334, 576, 522, 629, 417, 414,
- /* 330 */ 450, 581, 441, 444, 78, 23, 22, 315, 465, 466,
- /* 340 */ 462, 462, 25, 25, 24, 24, 24, 24, 445, 26,
- /* 350 */ 26, 26, 26, 27, 27, 28, 28, 28, 29, 218,
- /* 360 */ 309, 452, 452, 452, 159, 399, 311, 366, 369, 370,
- /* 370 */ 337, 251, 404, 407, 219, 355, 556, 4, 371, 422,
- /* 380 */ 423, 397, 286, 285, 244, 334, 540, 566, 63, 455,
- /* 390 */ 461, 424, 216, 478, 444, 93, 28, 28, 28, 29,
- /* 400 */ 218, 413, 477, 220, 578, 40, 545, 23, 22, 315,
- /* 410 */ 465, 466, 462, 462, 25, 25, 24, 24, 24, 24,
- /* 420 */ 582, 26, 26, 26, 26, 27, 27, 28, 28, 28,
- /* 430 */ 29, 218, 309, 546, 337, 30, 517, 32, 137, 378,
- /* 440 */ 326, 337, 874, 153, 194, 448, 1, 425, 426, 334,
- /* 450 */ 422, 423, 422, 423, 29, 218, 334, 613, 444, 71,
- /* 460 */ 210, 455, 461, 66, 581, 444, 93, 422, 423, 626,
- /* 470 */ 949, 303, 949, 500, 479, 555, 202, 43, 445, 23,
- /* 480 */ 22, 315, 465, 466, 462, 462, 25, 25, 24, 24,
- /* 490 */ 24, 24, 436, 26, 26, 26, 26, 27, 27, 28,
- /* 500 */ 28, 28, 29, 218, 309, 187, 211, 360, 520, 440,
- /* 510 */ 246, 327, 622, 448, 397, 286, 285, 551, 425, 426,
- /* 520 */ 425, 426, 334, 159, 337, 216, 366, 369, 370, 494,
- /* 530 */ 556, 444, 9, 455, 461, 425, 426, 371, 495, 334,
- /* 540 */ 445, 618, 63, 504, 198, 424, 501, 449, 444, 72,
- /* 550 */ 474, 23, 22, 315, 465, 466, 462, 462, 25, 25,
- /* 560 */ 24, 24, 24, 24, 395, 26, 26, 26, 26, 27,
- /* 570 */ 27, 28, 28, 28, 29, 218, 309, 486, 445, 337,
- /* 580 */ 537, 60, 224, 479, 343, 202, 398, 337, 439, 554,
- /* 590 */ 199, 140, 337, 487, 334, 526, 527, 551, 516, 508,
- /* 600 */ 456, 457, 334, 444, 67, 455, 461, 334, 488, 476,
- /* 610 */ 528, 444, 76, 39, 424, 41, 444, 97, 579, 527,
- /* 620 */ 529, 459, 460, 23, 22, 315, 465, 466, 462, 462,
- /* 630 */ 25, 25, 24, 24, 24, 24, 337, 26, 26, 26,
- /* 640 */ 26, 27, 27, 28, 28, 28, 29, 218, 309, 337,
- /* 650 */ 458, 334, 272, 621, 307, 337, 312, 337, 374, 64,
- /* 660 */ 444, 96, 317, 448, 334, 342, 472, 473, 469, 337,
- /* 670 */ 334, 508, 334, 444, 101, 359, 252, 455, 461, 444,
- /* 680 */ 99, 444, 104, 358, 334, 345, 424, 340, 157, 468,
- /* 690 */ 468, 424, 493, 444, 105, 23, 22, 315, 465, 466,
- /* 700 */ 462, 462, 25, 25, 24, 24, 24, 24, 337, 26,
- /* 710 */ 26, 26, 26, 27, 27, 28, 28, 28, 29, 218,
- /* 720 */ 309, 337, 181, 334, 499, 56, 139, 337, 219, 268,
- /* 730 */ 384, 448, 444, 129, 382, 387, 334, 168, 337, 389,
- /* 740 */ 508, 424, 334, 311, 424, 444, 131, 496, 269, 455,
- /* 750 */ 461, 444, 59, 334, 424, 424, 391, 340, 8, 468,
- /* 760 */ 468, 263, 444, 102, 390, 290, 321, 23, 22, 315,
- /* 770 */ 465, 466, 462, 462, 25, 25, 24, 24, 24, 24,
- /* 780 */ 337, 26, 26, 26, 26, 27, 27, 28, 28, 28,
- /* 790 */ 29, 218, 309, 337, 138, 334, 416, 2, 268, 337,
- /* 800 */ 389, 337, 443, 325, 444, 77, 442, 293, 334, 291,
- /* 810 */ 7, 482, 337, 424, 334, 424, 334, 444, 100, 499,
- /* 820 */ 339, 455, 461, 444, 68, 444, 98, 334, 254, 504,
- /* 830 */ 232, 626, 948, 504, 948, 231, 444, 132, 47, 23,
- /* 840 */ 22, 315, 465, 466, 462, 462, 25, 25, 24, 24,
- /* 850 */ 24, 24, 337, 26, 26, 26, 26, 27, 27, 28,
- /* 860 */ 28, 28, 29, 218, 309, 337, 280, 334, 256, 538,
- /* 870 */ 362, 337, 258, 268, 622, 549, 444, 133, 203, 140,
- /* 880 */ 334, 424, 548, 337, 180, 158, 334, 292, 424, 444,
- /* 890 */ 134, 287, 552, 455, 461, 444, 69, 443, 334, 463,
- /* 900 */ 340, 442, 468, 468, 427, 428, 429, 444, 80, 281,
- /* 910 */ 322, 23, 33, 315, 465, 466, 462, 462, 25, 25,
- /* 920 */ 24, 24, 24, 24, 337, 26, 26, 26, 26, 27,
- /* 930 */ 27, 28, 28, 28, 29, 218, 309, 337, 406, 334,
- /* 940 */ 212, 268, 550, 337, 268, 389, 329, 177, 444, 81,
- /* 950 */ 542, 541, 334, 475, 475, 337, 424, 216, 334, 424,
- /* 960 */ 424, 444, 70, 535, 368, 455, 461, 444, 82, 405,
- /* 970 */ 334, 261, 392, 340, 445, 468, 468, 587, 323, 444,
- /* 980 */ 83, 324, 262, 288, 22, 315, 465, 466, 462, 462,
- /* 990 */ 25, 25, 24, 24, 24, 24, 337, 26, 26, 26,
- /* 1000 */ 26, 27, 27, 28, 28, 28, 29, 218, 309, 337,
- /* 1010 */ 211, 334, 294, 356, 340, 337, 468, 468, 532, 533,
- /* 1020 */ 444, 84, 403, 144, 334, 574, 600, 337, 424, 573,
- /* 1030 */ 334, 337, 420, 444, 86, 253, 234, 455, 461, 444,
- /* 1040 */ 87, 430, 334, 383, 445, 431, 334, 274, 196, 331,
- /* 1050 */ 424, 444, 88, 432, 145, 444, 73, 315, 465, 466,
- /* 1060 */ 462, 462, 25, 25, 24, 24, 24, 24, 395, 26,
- /* 1070 */ 26, 26, 26, 27, 27, 28, 28, 28, 29, 218,
- /* 1080 */ 35, 344, 445, 3, 337, 394, 337, 333, 423, 278,
- /* 1090 */ 388, 276, 280, 207, 147, 35, 344, 341, 3, 334,
- /* 1100 */ 424, 334, 333, 423, 308, 623, 280, 424, 444, 74,
- /* 1110 */ 444, 89, 341, 337, 6, 346, 338, 337, 421, 337,
- /* 1120 */ 470, 424, 65, 332, 280, 481, 446, 445, 334, 247,
- /* 1130 */ 346, 424, 334, 424, 334, 594, 280, 444, 90, 424,
- /* 1140 */ 481, 444, 91, 444, 92, 38, 37, 625, 337, 410,
- /* 1150 */ 47, 424, 237, 280, 36, 335, 336, 354, 248, 450,
- /* 1160 */ 38, 37, 514, 334, 572, 381, 572, 596, 424, 36,
- /* 1170 */ 335, 336, 444, 75, 450, 200, 506, 216, 154, 597,
- /* 1180 */ 239, 240, 241, 146, 243, 249, 547, 593, 158, 433,
- /* 1190 */ 452, 452, 452, 453, 454, 10, 598, 280, 20, 46,
- /* 1200 */ 174, 412, 298, 337, 424, 452, 452, 452, 453, 454,
- /* 1210 */ 10, 299, 424, 35, 344, 352, 3, 250, 334, 434,
- /* 1220 */ 333, 423, 337, 172, 280, 581, 208, 444, 17, 171,
- /* 1230 */ 341, 19, 173, 447, 424, 422, 423, 334, 337, 424,
- /* 1240 */ 235, 280, 204, 205, 206, 42, 444, 94, 346, 435,
- /* 1250 */ 136, 451, 221, 334, 308, 624, 424, 349, 481, 490,
- /* 1260 */ 445, 152, 444, 95, 424, 424, 424, 236, 503, 491,
- /* 1270 */ 507, 179, 424, 481, 424, 402, 295, 285, 38, 37,
- /* 1280 */ 271, 310, 158, 424, 296, 424, 216, 36, 335, 336,
- /* 1290 */ 509, 266, 450, 190, 191, 539, 267, 625, 558, 273,
- /* 1300 */ 275, 48, 277, 522, 279, 424, 424, 450, 255, 409,
- /* 1310 */ 424, 424, 257, 424, 424, 424, 284, 424, 386, 424,
- /* 1320 */ 357, 584, 585, 452, 452, 452, 453, 454, 10, 259,
- /* 1330 */ 393, 424, 289, 424, 592, 603, 424, 424, 452, 452,
- /* 1340 */ 452, 297, 300, 301, 505, 424, 617, 424, 363, 424,
- /* 1350 */ 424, 373, 577, 158, 158, 511, 424, 424, 424, 525,
- /* 1360 */ 588, 424, 154, 589, 601, 54, 54, 620, 512, 306,
- /* 1370 */ 319, 530, 531, 535, 264, 107, 228, 536, 534, 375,
- /* 1380 */ 559, 304, 560, 561, 305, 227, 229, 553, 567, 161,
- /* 1390 */ 162, 379, 377, 163, 51, 209, 569, 282, 164, 570,
- /* 1400 */ 385, 143, 580, 116, 119, 183, 400, 590, 401, 121,
- /* 1410 */ 122, 123, 124, 126, 599, 328, 614, 55, 58, 615,
- /* 1420 */ 616, 619, 62, 418, 103, 226, 111, 176, 242, 182,
- /* 1430 */ 437, 313, 201, 314, 670, 671, 672, 149, 150, 467,
- /* 1440 */ 464, 34, 483, 471, 480, 184, 197, 502, 484, 5,
- /* 1450 */ 485, 151, 489, 44, 141, 11, 106, 160, 225, 518,
- /* 1460 */ 519, 49, 510, 108, 367, 270, 12, 155, 109, 50,
- /* 1470 */ 110, 262, 376, 186, 568, 113, 142, 154, 165, 115,
- /* 1480 */ 15, 283, 583, 166, 167, 380, 586, 117, 13, 120,
- /* 1490 */ 372, 52, 53, 118, 591, 169, 114, 170, 595, 125,
- /* 1500 */ 127, 571, 575, 602, 14, 128, 611, 612, 61, 175,
- /* 1510 */ 189, 415, 302, 627, 960, 960, 960, 960, 411,
-};
-static const YYCODETYPE yy_lookahead[] = {
- /* 0 */ 19, 142, 143, 144, 145, 24, 116, 26, 75, 76,
- /* 10 */ 77, 78, 25, 80, 81, 82, 83, 84, 85, 86,
- /* 20 */ 87, 88, 89, 90, 26, 27, 160, 26, 27, 48,
- /* 30 */ 49, 79, 80, 81, 82, 83, 84, 85, 86, 87,
- /* 40 */ 88, 89, 90, 222, 223, 224, 225, 66, 67, 68,
- /* 50 */ 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
- /* 60 */ 194, 80, 81, 82, 83, 84, 85, 86, 87, 88,
- /* 70 */ 89, 90, 19, 90, 19, 94, 174, 25, 25, 80,
- /* 80 */ 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
- /* 90 */ 26, 27, 94, 95, 96, 94, 95, 99, 100, 101,
- /* 100 */ 19, 48, 49, 150, 174, 52, 119, 166, 110, 84,
- /* 110 */ 85, 86, 87, 88, 89, 90, 26, 27, 165, 66,
- /* 120 */ 67, 68, 69, 70, 71, 72, 73, 74, 75, 76,
- /* 130 */ 77, 78, 186, 80, 81, 82, 83, 84, 85, 86,
- /* 140 */ 87, 88, 89, 90, 19, 90, 205, 95, 84, 85,
- /* 150 */ 186, 96, 97, 98, 99, 100, 101, 102, 94, 95,
- /* 160 */ 195, 97, 150, 222, 109, 224, 225, 26, 104, 105,
- /* 170 */ 217, 90, 120, 48, 49, 50, 86, 165, 97, 98,
- /* 180 */ 99, 100, 101, 102, 94, 95, 174, 175, 1, 2,
- /* 190 */ 109, 66, 67, 68, 69, 70, 71, 72, 73, 74,
- /* 200 */ 75, 76, 77, 78, 191, 80, 81, 82, 83, 84,
- /* 210 */ 85, 86, 87, 88, 89, 90, 19, 116, 35, 150,
- /* 220 */ 12, 24, 208, 150, 222, 150, 224, 225, 216, 128,
- /* 230 */ 161, 162, 150, 221, 165, 94, 28, 150, 165, 56,
- /* 240 */ 165, 197, 160, 170, 171, 48, 49, 165, 204, 174,
- /* 250 */ 175, 43, 165, 45, 185, 186, 174, 175, 169, 170,
- /* 260 */ 171, 174, 175, 66, 67, 68, 69, 70, 71, 72,
- /* 270 */ 73, 74, 75, 76, 77, 78, 194, 80, 81, 82,
- /* 280 */ 83, 84, 85, 86, 87, 88, 89, 90, 19, 214,
- /* 290 */ 215, 108, 150, 25, 148, 150, 64, 22, 216, 24,
- /* 300 */ 146, 147, 215, 221, 231, 232, 152, 165, 154, 150,
- /* 310 */ 165, 49, 170, 171, 160, 181, 182, 48, 49, 174,
- /* 320 */ 175, 232, 188, 165, 165, 21, 94, 0, 1, 2,
- /* 330 */ 98, 55, 174, 174, 175, 66, 67, 68, 69, 70,
- /* 340 */ 71, 72, 73, 74, 75, 76, 77, 78, 194, 80,
- /* 350 */ 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
- /* 360 */ 19, 129, 130, 131, 96, 61, 104, 99, 100, 101,
- /* 370 */ 150, 226, 218, 231, 232, 216, 150, 196, 110, 26,
- /* 380 */ 27, 105, 106, 107, 158, 165, 183, 161, 162, 48,
- /* 390 */ 49, 165, 116, 166, 174, 175, 86, 87, 88, 89,
- /* 400 */ 90, 247, 84, 85, 100, 136, 183, 66, 67, 68,
- /* 410 */ 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
- /* 420 */ 11, 80, 81, 82, 83, 84, 85, 86, 87, 88,
- /* 430 */ 89, 90, 19, 183, 150, 222, 23, 224, 225, 237,
- /* 440 */ 220, 150, 138, 24, 160, 26, 22, 94, 95, 165,
- /* 450 */ 26, 27, 26, 27, 89, 90, 165, 244, 174, 175,
- /* 460 */ 236, 48, 49, 22, 55, 174, 175, 26, 27, 22,
- /* 470 */ 23, 163, 25, 120, 166, 167, 168, 136, 194, 66,
- /* 480 */ 67, 68, 69, 70, 71, 72, 73, 74, 75, 76,
- /* 490 */ 77, 78, 153, 80, 81, 82, 83, 84, 85, 86,
- /* 500 */ 87, 88, 89, 90, 19, 196, 160, 150, 23, 173,
- /* 510 */ 198, 220, 65, 94, 105, 106, 107, 181, 94, 95,
- /* 520 */ 94, 95, 165, 96, 150, 116, 99, 100, 101, 31,
- /* 530 */ 150, 174, 175, 48, 49, 94, 95, 110, 40, 165,
- /* 540 */ 194, 161, 162, 166, 160, 165, 120, 166, 174, 175,
- /* 550 */ 233, 66, 67, 68, 69, 70, 71, 72, 73, 74,
- /* 560 */ 75, 76, 77, 78, 218, 80, 81, 82, 83, 84,
- /* 570 */ 85, 86, 87, 88, 89, 90, 19, 12, 194, 150,
- /* 580 */ 23, 235, 205, 166, 167, 168, 240, 150, 172, 173,
- /* 590 */ 206, 207, 150, 28, 165, 190, 191, 181, 23, 150,
- /* 600 */ 48, 49, 165, 174, 175, 48, 49, 165, 43, 233,
- /* 610 */ 45, 174, 175, 135, 165, 137, 174, 175, 190, 191,
- /* 620 */ 55, 69, 70, 66, 67, 68, 69, 70, 71, 72,
- /* 630 */ 73, 74, 75, 76, 77, 78, 150, 80, 81, 82,
- /* 640 */ 83, 84, 85, 86, 87, 88, 89, 90, 19, 150,
- /* 650 */ 98, 165, 23, 250, 251, 150, 155, 150, 19, 22,
- /* 660 */ 174, 175, 213, 26, 165, 169, 170, 171, 23, 150,
- /* 670 */ 165, 150, 165, 174, 175, 19, 150, 48, 49, 174,
- /* 680 */ 175, 174, 175, 27, 165, 228, 165, 112, 49, 114,
- /* 690 */ 115, 165, 177, 174, 175, 66, 67, 68, 69, 70,
- /* 700 */ 71, 72, 73, 74, 75, 76, 77, 78, 150, 80,
- /* 710 */ 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
- /* 720 */ 19, 150, 23, 165, 25, 24, 150, 150, 232, 150,
- /* 730 */ 229, 94, 174, 175, 213, 234, 165, 25, 150, 150,
- /* 740 */ 150, 165, 165, 104, 165, 174, 175, 177, 109, 48,
- /* 750 */ 49, 174, 175, 165, 165, 165, 19, 112, 22, 114,
- /* 760 */ 115, 177, 174, 175, 27, 16, 187, 66, 67, 68,
- /* 770 */ 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
- /* 780 */ 150, 80, 81, 82, 83, 84, 85, 86, 87, 88,
- /* 790 */ 89, 90, 19, 150, 95, 165, 144, 145, 150, 150,
- /* 800 */ 150, 150, 113, 213, 174, 175, 117, 58, 165, 60,
- /* 810 */ 74, 23, 150, 165, 165, 165, 165, 174, 175, 120,
- /* 820 */ 19, 48, 49, 174, 175, 174, 175, 165, 209, 166,
- /* 830 */ 241, 22, 23, 166, 25, 187, 174, 175, 126, 66,
- /* 840 */ 67, 68, 69, 70, 71, 72, 73, 74, 75, 76,
- /* 850 */ 77, 78, 150, 80, 81, 82, 83, 84, 85, 86,
- /* 860 */ 87, 88, 89, 90, 19, 150, 150, 165, 205, 182,
- /* 870 */ 86, 150, 205, 150, 65, 166, 174, 175, 206, 207,
- /* 880 */ 165, 165, 177, 150, 23, 25, 165, 138, 165, 174,
- /* 890 */ 175, 241, 166, 48, 49, 174, 175, 113, 165, 98,
- /* 900 */ 112, 117, 114, 115, 7, 8, 9, 174, 175, 193,
- /* 910 */ 187, 66, 67, 68, 69, 70, 71, 72, 73, 74,
- /* 920 */ 75, 76, 77, 78, 150, 80, 81, 82, 83, 84,
- /* 930 */ 85, 86, 87, 88, 89, 90, 19, 150, 97, 165,
- /* 940 */ 160, 150, 177, 150, 150, 150, 248, 249, 174, 175,
- /* 950 */ 97, 98, 165, 129, 130, 150, 165, 116, 165, 165,
- /* 960 */ 165, 174, 175, 103, 178, 48, 49, 174, 175, 128,
- /* 970 */ 165, 98, 242, 112, 194, 114, 115, 199, 187, 174,
- /* 980 */ 175, 187, 109, 242, 67, 68, 69, 70, 71, 72,
- /* 990 */ 73, 74, 75, 76, 77, 78, 150, 80, 81, 82,
- /* 1000 */ 83, 84, 85, 86, 87, 88, 89, 90, 19, 150,
- /* 1010 */ 160, 165, 209, 150, 112, 150, 114, 115, 7, 8,
- /* 1020 */ 174, 175, 209, 6, 165, 29, 199, 150, 165, 33,
- /* 1030 */ 165, 150, 149, 174, 175, 150, 241, 48, 49, 174,
- /* 1040 */ 175, 149, 165, 47, 194, 149, 165, 16, 160, 149,
- /* 1050 */ 165, 174, 175, 13, 151, 174, 175, 68, 69, 70,
- /* 1060 */ 71, 72, 73, 74, 75, 76, 77, 78, 218, 80,
- /* 1070 */ 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
- /* 1080 */ 19, 20, 194, 22, 150, 150, 150, 26, 27, 58,
- /* 1090 */ 240, 60, 150, 160, 151, 19, 20, 36, 22, 165,
- /* 1100 */ 165, 165, 26, 27, 22, 23, 150, 165, 174, 175,
- /* 1110 */ 174, 175, 36, 150, 25, 54, 150, 150, 150, 150,
- /* 1120 */ 23, 165, 25, 159, 150, 64, 194, 194, 165, 199,
- /* 1130 */ 54, 165, 165, 165, 165, 193, 150, 174, 175, 165,
- /* 1140 */ 64, 174, 175, 174, 175, 84, 85, 65, 150, 193,
- /* 1150 */ 126, 165, 217, 150, 93, 94, 95, 123, 200, 98,
- /* 1160 */ 84, 85, 86, 165, 105, 106, 107, 193, 165, 93,
- /* 1170 */ 94, 95, 174, 175, 98, 5, 23, 116, 25, 193,
- /* 1180 */ 10, 11, 12, 13, 14, 201, 23, 17, 25, 150,
- /* 1190 */ 129, 130, 131, 132, 133, 134, 193, 150, 125, 124,
- /* 1200 */ 30, 245, 32, 150, 165, 129, 130, 131, 132, 133,
- /* 1210 */ 134, 41, 165, 19, 20, 122, 22, 202, 165, 150,
- /* 1220 */ 26, 27, 150, 53, 150, 55, 160, 174, 175, 59,
- /* 1230 */ 36, 22, 62, 203, 165, 26, 27, 165, 150, 165,
- /* 1240 */ 193, 150, 105, 106, 107, 135, 174, 175, 54, 150,
- /* 1250 */ 150, 150, 227, 165, 22, 23, 165, 150, 64, 150,
- /* 1260 */ 194, 118, 174, 175, 165, 165, 165, 193, 150, 157,
- /* 1270 */ 150, 157, 165, 64, 165, 105, 106, 107, 84, 85,
- /* 1280 */ 23, 111, 25, 165, 193, 165, 116, 93, 94, 95,
- /* 1290 */ 150, 150, 98, 84, 85, 150, 150, 65, 150, 150,
- /* 1300 */ 150, 104, 150, 94, 150, 165, 165, 98, 210, 139,
- /* 1310 */ 165, 165, 210, 165, 165, 165, 150, 165, 150, 165,
- /* 1320 */ 121, 150, 150, 129, 130, 131, 132, 133, 134, 210,
- /* 1330 */ 150, 165, 150, 165, 150, 150, 165, 165, 129, 130,
- /* 1340 */ 131, 150, 150, 150, 211, 165, 150, 165, 104, 165,
- /* 1350 */ 165, 23, 23, 25, 25, 211, 165, 165, 165, 176,
- /* 1360 */ 23, 165, 25, 23, 23, 25, 25, 23, 211, 25,
- /* 1370 */ 46, 176, 184, 103, 176, 22, 90, 176, 178, 18,
- /* 1380 */ 176, 179, 176, 176, 179, 230, 230, 184, 157, 156,
- /* 1390 */ 156, 44, 157, 156, 135, 157, 157, 238, 156, 239,
- /* 1400 */ 157, 66, 189, 189, 22, 219, 157, 199, 18, 192,
- /* 1410 */ 192, 192, 192, 189, 199, 157, 39, 243, 243, 157,
- /* 1420 */ 157, 37, 246, 1, 164, 180, 180, 249, 15, 219,
- /* 1430 */ 23, 252, 22, 252, 118, 118, 118, 118, 118, 113,
- /* 1440 */ 98, 22, 11, 23, 23, 22, 22, 120, 23, 34,
- /* 1450 */ 23, 25, 23, 25, 118, 25, 22, 102, 50, 23,
- /* 1460 */ 23, 22, 27, 22, 50, 23, 34, 34, 22, 22,
- /* 1470 */ 22, 109, 19, 24, 20, 104, 38, 25, 104, 22,
- /* 1480 */ 5, 138, 1, 118, 34, 42, 27, 108, 22, 119,
- /* 1490 */ 50, 74, 74, 127, 1, 16, 51, 121, 20, 119,
- /* 1500 */ 108, 57, 51, 128, 22, 127, 23, 23, 16, 15,
- /* 1510 */ 22, 3, 140, 4, 253, 253, 253, 253, 63,
-};
-#define YY_SHIFT_USE_DFLT (-111)
-#define YY_SHIFT_MAX 415
-static const short yy_shift_ofst[] = {
- /* 0 */ 187, 1061, 1170, 1061, 1194, 1194, -2, 64, 64, -19,
- /* 10 */ 1194, 1194, 1194, 1194, 1194, 276, 1, 125, 1076, 1194,
- /* 20 */ 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194,
- /* 30 */ 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194,
- /* 40 */ 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194,
- /* 50 */ 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, -48,
- /* 60 */ 409, 1, 1, 141, 318, 318, -110, 53, 197, 269,
- /* 70 */ 341, 413, 485, 557, 629, 701, 773, 845, 773, 773,
- /* 80 */ 773, 773, 773, 773, 773, 773, 773, 773, 773, 773,
- /* 90 */ 773, 773, 773, 773, 773, 773, 917, 989, 989, -67,
- /* 100 */ -67, -1, -1, 55, 25, 310, 1, 1, 1, 1,
- /* 110 */ 1, 639, 304, 1, 1, 1, 1, 1, 1, 1,
- /* 120 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 365,
- /* 130 */ 141, -17, -111, -111, -111, 1209, 81, 424, 353, 426,
- /* 140 */ 441, 90, 565, 565, 1, 1, 1, 1, 1, 1,
- /* 150 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- /* 160 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- /* 170 */ 1, 1, 1, 1, 1, 1, 447, 809, 327, 419,
- /* 180 */ 419, 419, 841, 101, -110, -110, -110, -111, -111, -111,
- /* 190 */ 232, 232, 268, 427, 575, 645, 788, 208, 861, 699,
- /* 200 */ 897, 784, 637, 52, 183, 183, 183, 902, 902, 996,
- /* 210 */ 1059, 902, 902, 902, 902, 275, 689, -13, 141, 824,
- /* 220 */ 824, 478, 498, 498, 656, 498, 262, 498, 141, 498,
- /* 230 */ 141, 860, 737, 712, 737, 656, 656, 712, 1017, 1017,
- /* 240 */ 1017, 1017, 1040, 1040, 1089, -110, 1024, 1034, 1075, 1093,
- /* 250 */ 1073, 1110, 1143, 1143, 1197, 1199, 1197, 1199, 1197, 1199,
- /* 260 */ 1244, 1244, 1324, 1244, 1270, 1244, 1353, 1286, 1286, 1324,
- /* 270 */ 1244, 1244, 1244, 1353, 1361, 1143, 1361, 1143, 1361, 1143,
- /* 280 */ 1143, 1347, 1259, 1361, 1143, 1335, 1335, 1382, 1024, 1143,
- /* 290 */ 1390, 1390, 1390, 1390, 1024, 1335, 1382, 1143, 1377, 1377,
- /* 300 */ 1143, 1143, 1384, -111, -111, -111, -111, -111, -111, 552,
- /* 310 */ 749, 1137, 1031, 1082, 1232, 801, 1097, 1153, 873, 1011,
- /* 320 */ 853, 1163, 1257, 1328, 1329, 1337, 1340, 1341, 736, 1344,
- /* 330 */ 1422, 1413, 1407, 1410, 1316, 1317, 1318, 1319, 1320, 1342,
- /* 340 */ 1326, 1419, 1420, 1421, 1423, 1431, 1424, 1425, 1426, 1427,
- /* 350 */ 1429, 1428, 1415, 1430, 1432, 1428, 1327, 1434, 1433, 1435,
- /* 360 */ 1336, 1436, 1437, 1438, 1408, 1439, 1414, 1441, 1442, 1446,
- /* 370 */ 1447, 1440, 1448, 1355, 1362, 1453, 1454, 1449, 1371, 1443,
- /* 380 */ 1444, 1445, 1452, 1451, 1343, 1374, 1457, 1475, 1481, 1365,
- /* 390 */ 1450, 1459, 1379, 1417, 1418, 1366, 1466, 1370, 1493, 1479,
- /* 400 */ 1376, 1478, 1380, 1392, 1378, 1482, 1375, 1483, 1484, 1492,
- /* 410 */ 1455, 1494, 1372, 1488, 1508, 1509,
-};
-#define YY_REDUCE_USE_DFLT (-180)
-#define YY_REDUCE_MAX 308
-static const short yy_reduce_ofst[] = {
- /* 0 */ -141, 82, 154, 284, 12, 75, 69, 73, 142, -59,
- /* 10 */ 145, 87, 159, 220, 291, 346, 226, 213, 357, 374,
- /* 20 */ 429, 437, 442, 486, 499, 505, 507, 519, 558, 571,
- /* 30 */ 577, 588, 630, 643, 649, 651, 662, 702, 715, 721,
- /* 40 */ 733, 774, 787, 793, 805, 846, 859, 865, 877, 881,
- /* 50 */ 934, 936, 963, 967, 969, 998, 1053, 1072, 1088, -179,
- /* 60 */ 850, 956, 380, 308, 89, 496, 384, 2, 2, 2,
- /* 70 */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- /* 80 */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- /* 90 */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- /* 100 */ 2, 2, 2, 416, 2, 2, 449, 579, 648, 723,
- /* 110 */ 791, 134, 501, 716, 521, 794, 589, -47, 650, 590,
- /* 120 */ 795, 942, 974, 986, 1003, 1047, 1074, 935, 1091, 2,
- /* 130 */ 417, 2, 2, 2, 2, 158, 336, 526, 576, 863,
- /* 140 */ 885, 966, 405, 428, 968, 1039, 1069, 1099, 1100, 966,
- /* 150 */ 1101, 1107, 1109, 1118, 1120, 1140, 1141, 1145, 1146, 1148,
- /* 160 */ 1149, 1150, 1152, 1154, 1166, 1168, 1171, 1172, 1180, 1182,
- /* 170 */ 1184, 1185, 1191, 1192, 1193, 1196, 403, 403, 652, 377,
- /* 180 */ 663, 667, -134, 780, 888, 933, 1066, 44, 672, 698,
- /* 190 */ -98, -70, -54, -36, -35, -35, -35, 13, -35, 14,
- /* 200 */ 146, 181, 227, 14, 203, 223, 250, -35, -35, 224,
- /* 210 */ 202, -35, -35, -35, -35, 339, 309, 312, 381, 317,
- /* 220 */ 376, 457, 515, 570, 619, 584, 687, 705, 709, 765,
- /* 230 */ 726, 786, 730, 778, 741, 803, 813, 827, 883, 892,
- /* 240 */ 896, 900, 903, 943, 964, 932, 930, 958, 984, 1015,
- /* 250 */ 1030, 1025, 1112, 1114, 1098, 1133, 1102, 1144, 1119, 1157,
- /* 260 */ 1183, 1195, 1188, 1198, 1200, 1201, 1202, 1155, 1156, 1203,
- /* 270 */ 1204, 1206, 1207, 1205, 1233, 1231, 1234, 1235, 1237, 1238,
- /* 280 */ 1239, 1159, 1160, 1242, 1243, 1213, 1214, 1186, 1208, 1249,
- /* 290 */ 1217, 1218, 1219, 1220, 1215, 1224, 1210, 1258, 1174, 1175,
- /* 300 */ 1262, 1263, 1176, 1260, 1245, 1246, 1178, 1179, 1181,
-};
-static const YYACTIONTYPE yy_default[] = {
- /* 0 */ 634, 869, 958, 958, 869, 958, 958, 898, 898, 757,
- /* 10 */ 867, 958, 958, 958, 958, 958, 958, 932, 958, 958,
- /* 20 */ 958, 958, 958, 958, 958, 958, 958, 958, 958, 958,
- /* 30 */ 958, 958, 958, 958, 958, 958, 958, 958, 958, 958,
- /* 40 */ 958, 958, 958, 958, 958, 958, 958, 958, 958, 958,
- /* 50 */ 958, 958, 958, 958, 958, 958, 958, 958, 958, 841,
- /* 60 */ 958, 958, 958, 673, 898, 898, 761, 792, 958, 958,
- /* 70 */ 958, 958, 958, 958, 958, 958, 793, 958, 871, 866,
- /* 80 */ 862, 864, 863, 870, 794, 783, 790, 797, 772, 911,
- /* 90 */ 799, 800, 806, 807, 933, 931, 829, 828, 847, 831,
- /* 100 */ 853, 830, 840, 665, 832, 833, 958, 958, 958, 958,
- /* 110 */ 958, 726, 660, 958, 958, 958, 958, 958, 958, 958,
- /* 120 */ 958, 958, 958, 958, 958, 958, 958, 958, 958, 834,
- /* 130 */ 958, 835, 848, 849, 850, 958, 958, 958, 958, 958,
- /* 140 */ 958, 958, 958, 958, 640, 958, 958, 958, 958, 958,
- /* 150 */ 958, 958, 958, 958, 958, 958, 958, 958, 958, 958,
- /* 160 */ 958, 958, 958, 958, 958, 958, 958, 958, 958, 958,
- /* 170 */ 958, 882, 958, 936, 938, 958, 958, 958, 634, 757,
- /* 180 */ 757, 757, 958, 958, 958, 958, 958, 751, 761, 950,
- /* 190 */ 958, 958, 717, 958, 958, 958, 958, 958, 958, 958,
- /* 200 */ 642, 749, 675, 759, 958, 958, 958, 662, 738, 904,
- /* 210 */ 958, 923, 921, 740, 802, 958, 749, 758, 958, 958,
- /* 220 */ 958, 865, 786, 786, 774, 786, 696, 786, 958, 786,
- /* 230 */ 958, 699, 916, 796, 916, 774, 774, 796, 639, 639,
- /* 240 */ 639, 639, 650, 650, 716, 958, 796, 787, 789, 779,
- /* 250 */ 791, 958, 765, 765, 773, 778, 773, 778, 773, 778,
- /* 260 */ 728, 728, 713, 728, 699, 728, 875, 879, 879, 713,
- /* 270 */ 728, 728, 728, 875, 657, 765, 657, 765, 657, 765,
- /* 280 */ 765, 908, 910, 657, 765, 730, 730, 808, 796, 765,
- /* 290 */ 737, 737, 737, 737, 796, 730, 808, 765, 935, 935,
- /* 300 */ 765, 765, 943, 683, 701, 701, 950, 955, 955, 958,
- /* 310 */ 958, 958, 958, 958, 958, 958, 958, 958, 958, 958,
- /* 320 */ 958, 958, 958, 958, 958, 958, 958, 958, 884, 958,
- /* 330 */ 958, 648, 958, 667, 815, 820, 816, 958, 817, 958,
- /* 340 */ 743, 958, 958, 958, 958, 958, 958, 958, 958, 958,
- /* 350 */ 958, 868, 958, 780, 958, 788, 958, 958, 958, 958,
- /* 360 */ 958, 958, 958, 958, 958, 958, 958, 958, 958, 958,
- /* 370 */ 958, 958, 958, 958, 958, 958, 958, 958, 958, 958,
- /* 380 */ 958, 906, 907, 958, 958, 958, 958, 958, 958, 914,
- /* 390 */ 958, 958, 958, 958, 958, 958, 958, 958, 958, 958,
- /* 400 */ 958, 958, 958, 958, 958, 958, 958, 958, 958, 958,
- /* 410 */ 942, 958, 958, 945, 635, 958, 630, 632, 633, 637,
- /* 420 */ 638, 641, 667, 668, 670, 671, 672, 643, 644, 645,
- /* 430 */ 646, 647, 649, 653, 651, 652, 654, 661, 663, 682,
- /* 440 */ 684, 686, 747, 748, 812, 741, 742, 746, 669, 823,
- /* 450 */ 814, 818, 819, 821, 822, 836, 837, 839, 845, 852,
- /* 460 */ 855, 838, 843, 844, 846, 851, 854, 744, 745, 858,
- /* 470 */ 676, 677, 680, 681, 894, 896, 895, 897, 679, 678,
- /* 480 */ 824, 827, 860, 861, 924, 925, 926, 927, 928, 856,
- /* 490 */ 766, 859, 842, 781, 784, 785, 782, 750, 760, 768,
- /* 500 */ 769, 770, 771, 755, 756, 762, 777, 810, 811, 775,
- /* 510 */ 776, 763, 764, 752, 753, 754, 857, 813, 825, 826,
- /* 520 */ 687, 688, 820, 689, 690, 691, 729, 732, 733, 734,
- /* 530 */ 692, 711, 714, 715, 693, 700, 694, 695, 702, 703,
- /* 540 */ 704, 707, 708, 709, 710, 705, 706, 876, 877, 880,
- /* 550 */ 878, 697, 698, 712, 685, 674, 666, 718, 721, 722,
- /* 560 */ 723, 724, 725, 727, 719, 720, 664, 655, 658, 767,
- /* 570 */ 900, 909, 905, 901, 902, 903, 659, 872, 873, 731,
- /* 580 */ 804, 805, 899, 912, 915, 917, 918, 919, 809, 920,
- /* 590 */ 922, 913, 947, 656, 735, 736, 739, 881, 929, 795,
- /* 600 */ 798, 801, 803, 883, 885, 887, 889, 890, 891, 892,
- /* 610 */ 893, 886, 888, 930, 934, 937, 939, 940, 941, 944,
- /* 620 */ 946, 951, 952, 953, 956, 957, 954, 636, 631,
-};
-#define YY_SZ_ACTTAB (int)(sizeof(yy_action)/sizeof(yy_action[0]))
-
-/* The next table maps tokens into fallback tokens. If a construct
-** like the following:
-**
-** %fallback ID X Y Z.
-**
-** appears in the grammar, then ID becomes a fallback token for X, Y,
-** and Z. Whenever one of the tokens X, Y, or Z is input to the parser
-** but it does not parse, the type of the token is changed to ID and
-** the parse is retried before an error is thrown.
-*/
-#ifdef YYFALLBACK
-static const YYCODETYPE yyFallback[] = {
- 0, /* $ => nothing */
- 0, /* SEMI => nothing */
- 26, /* EXPLAIN => ID */
- 26, /* QUERY => ID */
- 26, /* PLAN => ID */
- 26, /* BEGIN => ID */
- 0, /* TRANSACTION => nothing */
- 26, /* DEFERRED => ID */
- 26, /* IMMEDIATE => ID */
- 26, /* EXCLUSIVE => ID */
- 0, /* COMMIT => nothing */
- 26, /* END => ID */
- 26, /* ROLLBACK => ID */
- 26, /* SAVEPOINT => ID */
- 26, /* RELEASE => ID */
- 0, /* TO => nothing */
- 0, /* TABLE => nothing */
- 0, /* CREATE => nothing */
- 26, /* IF => ID */
- 0, /* NOT => nothing */
- 0, /* EXISTS => nothing */
- 26, /* TEMP => ID */
- 0, /* LP => nothing */
- 0, /* RP => nothing */
- 0, /* AS => nothing */
- 0, /* COMMA => nothing */
- 0, /* ID => nothing */
- 0, /* INDEXED => nothing */
- 26, /* ABORT => ID */
- 26, /* AFTER => ID */
- 26, /* ANALYZE => ID */
- 26, /* ASC => ID */
- 26, /* ATTACH => ID */
- 26, /* BEFORE => ID */
- 26, /* BY => ID */
- 26, /* CASCADE => ID */
- 26, /* CAST => ID */
- 26, /* COLUMNKW => ID */
- 26, /* CONFLICT => ID */
- 26, /* DATABASE => ID */
- 26, /* DESC => ID */
- 26, /* DETACH => ID */
- 26, /* EACH => ID */
- 26, /* FAIL => ID */
- 26, /* FOR => ID */
- 26, /* IGNORE => ID */
- 26, /* INITIALLY => ID */
- 26, /* INSTEAD => ID */
- 26, /* LIKE_KW => ID */
- 26, /* MATCH => ID */
- 26, /* KEY => ID */
- 26, /* OF => ID */
- 26, /* OFFSET => ID */
- 26, /* PRAGMA => ID */
- 26, /* RAISE => ID */
- 26, /* REPLACE => ID */
- 26, /* RESTRICT => ID */
- 26, /* ROW => ID */
- 26, /* TRIGGER => ID */
- 26, /* VACUUM => ID */
- 26, /* VIEW => ID */
- 26, /* VIRTUAL => ID */
- 26, /* REINDEX => ID */
- 26, /* RENAME => ID */
- 26, /* CTIME_KW => ID */
-};
-#endif /* YYFALLBACK */
-
-/* The following structure represents a single element of the
-** parser's stack. Information stored includes:
-**
-** + The state number for the parser at this level of the stack.
-**
-** + The value of the token stored at this level of the stack.
-** (In other words, the "major" token.)
-**
-** + The semantic value stored at this level of the stack. This is
-** the information used by the action routines in the grammar.
-** It is sometimes called the "minor" token.
-*/
-struct yyStackEntry {
- YYACTIONTYPE stateno; /* The state-number */
- YYCODETYPE major; /* The major token value. This is the code
- ** number for the token at this stack level */
- YYMINORTYPE minor; /* The user-supplied minor token value. This
- ** is the value of the token */
-};
-typedef struct yyStackEntry yyStackEntry;
-
-/* The state of the parser is completely contained in an instance of
-** the following structure */
-struct yyParser {
- int yyidx; /* Index of top element in stack */
-#ifdef YYTRACKMAXSTACKDEPTH
- int yyidxMax; /* Maximum value of yyidx */
-#endif
- int yyerrcnt; /* Shifts left before out of the error */
- sqlite3ParserARG_SDECL /* A place to hold %extra_argument */
-#if YYSTACKDEPTH<=0
- int yystksz; /* Current side of the stack */
- yyStackEntry *yystack; /* The parser's stack */
-#else
- yyStackEntry yystack[YYSTACKDEPTH]; /* The parser's stack */
-#endif
-};
-typedef struct yyParser yyParser;
-
-#ifndef NDEBUG
-static FILE *yyTraceFILE = 0;
-static char *yyTracePrompt = 0;
-#endif /* NDEBUG */
-
-#ifndef NDEBUG
-/*
-** Turn parser tracing on by giving a stream to which to write the trace
-** and a prompt to preface each trace message. Tracing is turned off
-** by making either argument NULL
-**
-** Inputs:
-** <ul>
-** <li> A FILE* to which trace output should be written.
-** If NULL, then tracing is turned off.
-** <li> A prefix string written at the beginning of every
-** line of trace output. If NULL, then tracing is
-** turned off.
-** </ul>
-**
-** Outputs:
-** None.
-*/
-SQLITE_PRIVATE void sqlite3ParserTrace(FILE *TraceFILE, char *zTracePrompt){
- yyTraceFILE = TraceFILE;
- yyTracePrompt = zTracePrompt;
- if( yyTraceFILE==0 ) yyTracePrompt = 0;
- else if( yyTracePrompt==0 ) yyTraceFILE = 0;
-}
-#endif /* NDEBUG */
-
-#ifndef NDEBUG
-/* For tracing shifts, the names of all terminals and nonterminals
-** are required. The following table supplies these names */
-static const char *const yyTokenName[] = {
- "$", "SEMI", "EXPLAIN", "QUERY",
- "PLAN", "BEGIN", "TRANSACTION", "DEFERRED",
- "IMMEDIATE", "EXCLUSIVE", "COMMIT", "END",
- "ROLLBACK", "SAVEPOINT", "RELEASE", "TO",
- "TABLE", "CREATE", "IF", "NOT",
- "EXISTS", "TEMP", "LP", "RP",
- "AS", "COMMA", "ID", "INDEXED",
- "ABORT", "AFTER", "ANALYZE", "ASC",
- "ATTACH", "BEFORE", "BY", "CASCADE",
- "CAST", "COLUMNKW", "CONFLICT", "DATABASE",
- "DESC", "DETACH", "EACH", "FAIL",
- "FOR", "IGNORE", "INITIALLY", "INSTEAD",
- "LIKE_KW", "MATCH", "KEY", "OF",
- "OFFSET", "PRAGMA", "RAISE", "REPLACE",
- "RESTRICT", "ROW", "TRIGGER", "VACUUM",
- "VIEW", "VIRTUAL", "REINDEX", "RENAME",
- "CTIME_KW", "ANY", "OR", "AND",
- "IS", "BETWEEN", "IN", "ISNULL",
- "NOTNULL", "NE", "EQ", "GT",
- "LE", "LT", "GE", "ESCAPE",
- "BITAND", "BITOR", "LSHIFT", "RSHIFT",
- "PLUS", "MINUS", "STAR", "SLASH",
- "REM", "CONCAT", "COLLATE", "UMINUS",
- "UPLUS", "BITNOT", "STRING", "JOIN_KW",
- "CONSTRAINT", "DEFAULT", "NULL", "PRIMARY",
- "UNIQUE", "CHECK", "REFERENCES", "AUTOINCR",
- "ON", "DELETE", "UPDATE", "INSERT",
- "SET", "DEFERRABLE", "FOREIGN", "DROP",
- "UNION", "ALL", "EXCEPT", "INTERSECT",
- "SELECT", "DISTINCT", "DOT", "FROM",
- "JOIN", "USING", "ORDER", "GROUP",
- "HAVING", "LIMIT", "WHERE", "INTO",
- "VALUES", "INTEGER", "FLOAT", "BLOB",
- "REGISTER", "VARIABLE", "CASE", "WHEN",
- "THEN", "ELSE", "INDEX", "ALTER",
- "ADD", "error", "input", "cmdlist",
- "ecmd", "explain", "cmdx", "cmd",
- "transtype", "trans_opt", "nm", "savepoint_opt",
- "create_table", "create_table_args", "createkw", "temp",
- "ifnotexists", "dbnm", "columnlist", "conslist_opt",
- "select", "column", "columnid", "type",
- "carglist", "id", "ids", "typetoken",
- "typename", "signed", "plus_num", "minus_num",
- "carg", "ccons", "term", "expr",
- "onconf", "sortorder", "autoinc", "idxlist_opt",
- "refargs", "defer_subclause", "refarg", "refact",
- "init_deferred_pred_opt", "conslist", "tcons", "idxlist",
- "defer_subclause_opt", "orconf", "resolvetype", "raisetype",
- "ifexists", "fullname", "oneselect", "multiselect_op",
- "distinct", "selcollist", "from", "where_opt",
- "groupby_opt", "having_opt", "orderby_opt", "limit_opt",
- "sclp", "as", "seltablist", "stl_prefix",
- "joinop", "indexed_opt", "on_opt", "using_opt",
- "joinop2", "inscollist", "sortlist", "sortitem",
- "nexprlist", "setlist", "insert_cmd", "inscollist_opt",
- "itemlist", "exprlist", "likeop", "escape",
- "between_op", "in_op", "case_operand", "case_exprlist",
- "case_else", "uniqueflag", "collate", "nmnum",
- "plus_opt", "number", "trigger_decl", "trigger_cmd_list",
- "trigger_time", "trigger_event", "foreach_clause", "when_clause",
- "trigger_cmd", "trnm", "tridxby", "database_kw_opt",
- "key_opt", "add_column_fullname", "kwcolumn_opt", "create_vtab",
- "vtabarglist", "vtabarg", "vtabargtoken", "lp",
- "anylist",
-};
-#endif /* NDEBUG */
-
-#ifndef NDEBUG
-/* For tracing reduce actions, the names of all rules are required.
-*/
-static const char *const yyRuleName[] = {
- /* 0 */ "input ::= cmdlist",
- /* 1 */ "cmdlist ::= cmdlist ecmd",
- /* 2 */ "cmdlist ::= ecmd",
- /* 3 */ "ecmd ::= SEMI",
- /* 4 */ "ecmd ::= explain cmdx SEMI",
- /* 5 */ "explain ::=",
- /* 6 */ "explain ::= EXPLAIN",
- /* 7 */ "explain ::= EXPLAIN QUERY PLAN",
- /* 8 */ "cmdx ::= cmd",
- /* 9 */ "cmd ::= BEGIN transtype trans_opt",
- /* 10 */ "trans_opt ::=",
- /* 11 */ "trans_opt ::= TRANSACTION",
- /* 12 */ "trans_opt ::= TRANSACTION nm",
- /* 13 */ "transtype ::=",
- /* 14 */ "transtype ::= DEFERRED",
- /* 15 */ "transtype ::= IMMEDIATE",
- /* 16 */ "transtype ::= EXCLUSIVE",
- /* 17 */ "cmd ::= COMMIT trans_opt",
- /* 18 */ "cmd ::= END trans_opt",
- /* 19 */ "cmd ::= ROLLBACK trans_opt",
- /* 20 */ "savepoint_opt ::= SAVEPOINT",
- /* 21 */ "savepoint_opt ::=",
- /* 22 */ "cmd ::= SAVEPOINT nm",
- /* 23 */ "cmd ::= RELEASE savepoint_opt nm",
- /* 24 */ "cmd ::= ROLLBACK trans_opt TO savepoint_opt nm",
- /* 25 */ "cmd ::= create_table create_table_args",
- /* 26 */ "create_table ::= createkw temp TABLE ifnotexists nm dbnm",
- /* 27 */ "createkw ::= CREATE",
- /* 28 */ "ifnotexists ::=",
- /* 29 */ "ifnotexists ::= IF NOT EXISTS",
- /* 30 */ "temp ::= TEMP",
- /* 31 */ "temp ::=",
- /* 32 */ "create_table_args ::= LP columnlist conslist_opt RP",
- /* 33 */ "create_table_args ::= AS select",
- /* 34 */ "columnlist ::= columnlist COMMA column",
- /* 35 */ "columnlist ::= column",
- /* 36 */ "column ::= columnid type carglist",
- /* 37 */ "columnid ::= nm",
- /* 38 */ "id ::= ID",
- /* 39 */ "id ::= INDEXED",
- /* 40 */ "ids ::= ID|STRING",
- /* 41 */ "nm ::= id",
- /* 42 */ "nm ::= STRING",
- /* 43 */ "nm ::= JOIN_KW",
- /* 44 */ "type ::=",
- /* 45 */ "type ::= typetoken",
- /* 46 */ "typetoken ::= typename",
- /* 47 */ "typetoken ::= typename LP signed RP",
- /* 48 */ "typetoken ::= typename LP signed COMMA signed RP",
- /* 49 */ "typename ::= ids",
- /* 50 */ "typename ::= typename ids",
- /* 51 */ "signed ::= plus_num",
- /* 52 */ "signed ::= minus_num",
- /* 53 */ "carglist ::= carglist carg",
- /* 54 */ "carglist ::=",
- /* 55 */ "carg ::= CONSTRAINT nm ccons",
- /* 56 */ "carg ::= ccons",
- /* 57 */ "ccons ::= DEFAULT term",
- /* 58 */ "ccons ::= DEFAULT LP expr RP",
- /* 59 */ "ccons ::= DEFAULT PLUS term",
- /* 60 */ "ccons ::= DEFAULT MINUS term",
- /* 61 */ "ccons ::= DEFAULT id",
- /* 62 */ "ccons ::= NULL onconf",
- /* 63 */ "ccons ::= NOT NULL onconf",
- /* 64 */ "ccons ::= PRIMARY KEY sortorder onconf autoinc",
- /* 65 */ "ccons ::= UNIQUE onconf",
- /* 66 */ "ccons ::= CHECK LP expr RP",
- /* 67 */ "ccons ::= REFERENCES nm idxlist_opt refargs",
- /* 68 */ "ccons ::= defer_subclause",
- /* 69 */ "ccons ::= COLLATE ids",
- /* 70 */ "autoinc ::=",
- /* 71 */ "autoinc ::= AUTOINCR",
- /* 72 */ "refargs ::=",
- /* 73 */ "refargs ::= refargs refarg",
- /* 74 */ "refarg ::= MATCH nm",
- /* 75 */ "refarg ::= ON DELETE refact",
- /* 76 */ "refarg ::= ON UPDATE refact",
- /* 77 */ "refarg ::= ON INSERT refact",
- /* 78 */ "refact ::= SET NULL",
- /* 79 */ "refact ::= SET DEFAULT",
- /* 80 */ "refact ::= CASCADE",
- /* 81 */ "refact ::= RESTRICT",
- /* 82 */ "defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt",
- /* 83 */ "defer_subclause ::= DEFERRABLE init_deferred_pred_opt",
- /* 84 */ "init_deferred_pred_opt ::=",
- /* 85 */ "init_deferred_pred_opt ::= INITIALLY DEFERRED",
- /* 86 */ "init_deferred_pred_opt ::= INITIALLY IMMEDIATE",
- /* 87 */ "conslist_opt ::=",
- /* 88 */ "conslist_opt ::= COMMA conslist",
- /* 89 */ "conslist ::= conslist COMMA tcons",
- /* 90 */ "conslist ::= conslist tcons",
- /* 91 */ "conslist ::= tcons",
- /* 92 */ "tcons ::= CONSTRAINT nm",
- /* 93 */ "tcons ::= PRIMARY KEY LP idxlist autoinc RP onconf",
- /* 94 */ "tcons ::= UNIQUE LP idxlist RP onconf",
- /* 95 */ "tcons ::= CHECK LP expr RP onconf",
- /* 96 */ "tcons ::= FOREIGN KEY LP idxlist RP REFERENCES nm idxlist_opt refargs defer_subclause_opt",
- /* 97 */ "defer_subclause_opt ::=",
- /* 98 */ "defer_subclause_opt ::= defer_subclause",
- /* 99 */ "onconf ::=",
- /* 100 */ "onconf ::= ON CONFLICT resolvetype",
- /* 101 */ "orconf ::=",
- /* 102 */ "orconf ::= OR resolvetype",
- /* 103 */ "resolvetype ::= raisetype",
- /* 104 */ "resolvetype ::= IGNORE",
- /* 105 */ "resolvetype ::= REPLACE",
- /* 106 */ "cmd ::= DROP TABLE ifexists fullname",
- /* 107 */ "ifexists ::= IF EXISTS",
- /* 108 */ "ifexists ::=",
- /* 109 */ "cmd ::= createkw temp VIEW ifnotexists nm dbnm AS select",
- /* 110 */ "cmd ::= DROP VIEW ifexists fullname",
- /* 111 */ "cmd ::= select",
- /* 112 */ "select ::= oneselect",
- /* 113 */ "select ::= select multiselect_op oneselect",
- /* 114 */ "multiselect_op ::= UNION",
- /* 115 */ "multiselect_op ::= UNION ALL",
- /* 116 */ "multiselect_op ::= EXCEPT|INTERSECT",
- /* 117 */ "oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt",
- /* 118 */ "distinct ::= DISTINCT",
- /* 119 */ "distinct ::= ALL",
- /* 120 */ "distinct ::=",
- /* 121 */ "sclp ::= selcollist COMMA",
- /* 122 */ "sclp ::=",
- /* 123 */ "selcollist ::= sclp expr as",
- /* 124 */ "selcollist ::= sclp STAR",
- /* 125 */ "selcollist ::= sclp nm DOT STAR",
- /* 126 */ "as ::= AS nm",
- /* 127 */ "as ::= ids",
- /* 128 */ "as ::=",
- /* 129 */ "from ::=",
- /* 130 */ "from ::= FROM seltablist",
- /* 131 */ "stl_prefix ::= seltablist joinop",
- /* 132 */ "stl_prefix ::=",
- /* 133 */ "seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt",
- /* 134 */ "seltablist ::= stl_prefix LP select RP as on_opt using_opt",
- /* 135 */ "seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt",
- /* 136 */ "dbnm ::=",
- /* 137 */ "dbnm ::= DOT nm",
- /* 138 */ "fullname ::= nm dbnm",
- /* 139 */ "joinop ::= COMMA|JOIN",
- /* 140 */ "joinop ::= JOIN_KW JOIN",
- /* 141 */ "joinop ::= JOIN_KW nm JOIN",
- /* 142 */ "joinop ::= JOIN_KW nm nm JOIN",
- /* 143 */ "on_opt ::= ON expr",
- /* 144 */ "on_opt ::=",
- /* 145 */ "indexed_opt ::=",
- /* 146 */ "indexed_opt ::= INDEXED BY nm",
- /* 147 */ "indexed_opt ::= NOT INDEXED",
- /* 148 */ "using_opt ::= USING LP inscollist RP",
- /* 149 */ "using_opt ::=",
- /* 150 */ "orderby_opt ::=",
- /* 151 */ "orderby_opt ::= ORDER BY sortlist",
- /* 152 */ "sortlist ::= sortlist COMMA sortitem sortorder",
- /* 153 */ "sortlist ::= sortitem sortorder",
- /* 154 */ "sortitem ::= expr",
- /* 155 */ "sortorder ::= ASC",
- /* 156 */ "sortorder ::= DESC",
- /* 157 */ "sortorder ::=",
- /* 158 */ "groupby_opt ::=",
- /* 159 */ "groupby_opt ::= GROUP BY nexprlist",
- /* 160 */ "having_opt ::=",
- /* 161 */ "having_opt ::= HAVING expr",
- /* 162 */ "limit_opt ::=",
- /* 163 */ "limit_opt ::= LIMIT expr",
- /* 164 */ "limit_opt ::= LIMIT expr OFFSET expr",
- /* 165 */ "limit_opt ::= LIMIT expr COMMA expr",
- /* 166 */ "cmd ::= DELETE FROM fullname indexed_opt where_opt",
- /* 167 */ "where_opt ::=",
- /* 168 */ "where_opt ::= WHERE expr",
- /* 169 */ "cmd ::= UPDATE orconf fullname indexed_opt SET setlist where_opt",
- /* 170 */ "setlist ::= setlist COMMA nm EQ expr",
- /* 171 */ "setlist ::= nm EQ expr",
- /* 172 */ "cmd ::= insert_cmd INTO fullname inscollist_opt VALUES LP itemlist RP",
- /* 173 */ "cmd ::= insert_cmd INTO fullname inscollist_opt select",
- /* 174 */ "cmd ::= insert_cmd INTO fullname inscollist_opt DEFAULT VALUES",
- /* 175 */ "insert_cmd ::= INSERT orconf",
- /* 176 */ "insert_cmd ::= REPLACE",
- /* 177 */ "itemlist ::= itemlist COMMA expr",
- /* 178 */ "itemlist ::= expr",
- /* 179 */ "inscollist_opt ::=",
- /* 180 */ "inscollist_opt ::= LP inscollist RP",
- /* 181 */ "inscollist ::= inscollist COMMA nm",
- /* 182 */ "inscollist ::= nm",
- /* 183 */ "expr ::= term",
- /* 184 */ "expr ::= LP expr RP",
- /* 185 */ "term ::= NULL",
- /* 186 */ "expr ::= id",
- /* 187 */ "expr ::= JOIN_KW",
- /* 188 */ "expr ::= nm DOT nm",
- /* 189 */ "expr ::= nm DOT nm DOT nm",
- /* 190 */ "term ::= INTEGER|FLOAT|BLOB",
- /* 191 */ "term ::= STRING",
- /* 192 */ "expr ::= REGISTER",
- /* 193 */ "expr ::= VARIABLE",
- /* 194 */ "expr ::= expr COLLATE ids",
- /* 195 */ "expr ::= CAST LP expr AS typetoken RP",
- /* 196 */ "expr ::= ID LP distinct exprlist RP",
- /* 197 */ "expr ::= ID LP STAR RP",
- /* 198 */ "term ::= CTIME_KW",
- /* 199 */ "expr ::= expr AND expr",
- /* 200 */ "expr ::= expr OR expr",
- /* 201 */ "expr ::= expr LT|GT|GE|LE expr",
- /* 202 */ "expr ::= expr EQ|NE expr",
- /* 203 */ "expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr",
- /* 204 */ "expr ::= expr PLUS|MINUS expr",
- /* 205 */ "expr ::= expr STAR|SLASH|REM expr",
- /* 206 */ "expr ::= expr CONCAT expr",
- /* 207 */ "likeop ::= LIKE_KW",
- /* 208 */ "likeop ::= NOT LIKE_KW",
- /* 209 */ "likeop ::= MATCH",
- /* 210 */ "likeop ::= NOT MATCH",
- /* 211 */ "escape ::= ESCAPE expr",
- /* 212 */ "escape ::=",
- /* 213 */ "expr ::= expr likeop expr escape",
- /* 214 */ "expr ::= expr ISNULL|NOTNULL",
- /* 215 */ "expr ::= expr IS NULL",
- /* 216 */ "expr ::= expr NOT NULL",
- /* 217 */ "expr ::= expr IS NOT NULL",
- /* 218 */ "expr ::= NOT expr",
- /* 219 */ "expr ::= BITNOT expr",
- /* 220 */ "expr ::= MINUS expr",
- /* 221 */ "expr ::= PLUS expr",
- /* 222 */ "between_op ::= BETWEEN",
- /* 223 */ "between_op ::= NOT BETWEEN",
- /* 224 */ "expr ::= expr between_op expr AND expr",
- /* 225 */ "in_op ::= IN",
- /* 226 */ "in_op ::= NOT IN",
- /* 227 */ "expr ::= expr in_op LP exprlist RP",
- /* 228 */ "expr ::= LP select RP",
- /* 229 */ "expr ::= expr in_op LP select RP",
- /* 230 */ "expr ::= expr in_op nm dbnm",
- /* 231 */ "expr ::= EXISTS LP select RP",
- /* 232 */ "expr ::= CASE case_operand case_exprlist case_else END",
- /* 233 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr",
- /* 234 */ "case_exprlist ::= WHEN expr THEN expr",
- /* 235 */ "case_else ::= ELSE expr",
- /* 236 */ "case_else ::=",
- /* 237 */ "case_operand ::= expr",
- /* 238 */ "case_operand ::=",
- /* 239 */ "exprlist ::= nexprlist",
- /* 240 */ "exprlist ::=",
- /* 241 */ "nexprlist ::= nexprlist COMMA expr",
- /* 242 */ "nexprlist ::= expr",
- /* 243 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP idxlist RP",
- /* 244 */ "uniqueflag ::= UNIQUE",
- /* 245 */ "uniqueflag ::=",
- /* 246 */ "idxlist_opt ::=",
- /* 247 */ "idxlist_opt ::= LP idxlist RP",
- /* 248 */ "idxlist ::= idxlist COMMA nm collate sortorder",
- /* 249 */ "idxlist ::= nm collate sortorder",
- /* 250 */ "collate ::=",
- /* 251 */ "collate ::= COLLATE ids",
- /* 252 */ "cmd ::= DROP INDEX ifexists fullname",
- /* 253 */ "cmd ::= VACUUM",
- /* 254 */ "cmd ::= VACUUM nm",
- /* 255 */ "cmd ::= PRAGMA nm dbnm",
- /* 256 */ "cmd ::= PRAGMA nm dbnm EQ nmnum",
- /* 257 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP",
- /* 258 */ "cmd ::= PRAGMA nm dbnm EQ minus_num",
- /* 259 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP",
- /* 260 */ "nmnum ::= plus_num",
- /* 261 */ "nmnum ::= nm",
- /* 262 */ "nmnum ::= ON",
- /* 263 */ "nmnum ::= DELETE",
- /* 264 */ "nmnum ::= DEFAULT",
- /* 265 */ "plus_num ::= plus_opt number",
- /* 266 */ "minus_num ::= MINUS number",
- /* 267 */ "number ::= INTEGER|FLOAT",
- /* 268 */ "plus_opt ::= PLUS",
- /* 269 */ "plus_opt ::=",
- /* 270 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END",
- /* 271 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause",
- /* 272 */ "trigger_time ::= BEFORE",
- /* 273 */ "trigger_time ::= AFTER",
- /* 274 */ "trigger_time ::= INSTEAD OF",
- /* 275 */ "trigger_time ::=",
- /* 276 */ "trigger_event ::= DELETE|INSERT",
- /* 277 */ "trigger_event ::= UPDATE",
- /* 278 */ "trigger_event ::= UPDATE OF inscollist",
- /* 279 */ "foreach_clause ::=",
- /* 280 */ "foreach_clause ::= FOR EACH ROW",
- /* 281 */ "when_clause ::=",
- /* 282 */ "when_clause ::= WHEN expr",
- /* 283 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI",
- /* 284 */ "trigger_cmd_list ::= trigger_cmd SEMI",
- /* 285 */ "trnm ::= nm",
- /* 286 */ "trnm ::= nm DOT nm",
- /* 287 */ "tridxby ::=",
- /* 288 */ "tridxby ::= INDEXED BY nm",
- /* 289 */ "tridxby ::= NOT INDEXED",
- /* 290 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt",
- /* 291 */ "trigger_cmd ::= insert_cmd INTO trnm inscollist_opt VALUES LP itemlist RP",
- /* 292 */ "trigger_cmd ::= insert_cmd INTO trnm inscollist_opt select",
- /* 293 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt",
- /* 294 */ "trigger_cmd ::= select",
- /* 295 */ "expr ::= RAISE LP IGNORE RP",
- /* 296 */ "expr ::= RAISE LP raisetype COMMA nm RP",
- /* 297 */ "raisetype ::= ROLLBACK",
- /* 298 */ "raisetype ::= ABORT",
- /* 299 */ "raisetype ::= FAIL",
- /* 300 */ "cmd ::= DROP TRIGGER ifexists fullname",
- /* 301 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt",
- /* 302 */ "cmd ::= DETACH database_kw_opt expr",
- /* 303 */ "key_opt ::=",
- /* 304 */ "key_opt ::= KEY expr",
- /* 305 */ "database_kw_opt ::= DATABASE",
- /* 306 */ "database_kw_opt ::=",
- /* 307 */ "cmd ::= REINDEX",
- /* 308 */ "cmd ::= REINDEX nm dbnm",
- /* 309 */ "cmd ::= ANALYZE",
- /* 310 */ "cmd ::= ANALYZE nm dbnm",
- /* 311 */ "cmd ::= ALTER TABLE fullname RENAME TO nm",
- /* 312 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt column",
- /* 313 */ "add_column_fullname ::= fullname",
- /* 314 */ "kwcolumn_opt ::=",
- /* 315 */ "kwcolumn_opt ::= COLUMNKW",
- /* 316 */ "cmd ::= create_vtab",
- /* 317 */ "cmd ::= create_vtab LP vtabarglist RP",
- /* 318 */ "create_vtab ::= createkw VIRTUAL TABLE nm dbnm USING nm",
- /* 319 */ "vtabarglist ::= vtabarg",
- /* 320 */ "vtabarglist ::= vtabarglist COMMA vtabarg",
- /* 321 */ "vtabarg ::=",
- /* 322 */ "vtabarg ::= vtabarg vtabargtoken",
- /* 323 */ "vtabargtoken ::= ANY",
- /* 324 */ "vtabargtoken ::= lp anylist RP",
- /* 325 */ "lp ::= LP",
- /* 326 */ "anylist ::=",
- /* 327 */ "anylist ::= anylist LP anylist RP",
- /* 328 */ "anylist ::= anylist ANY",
-};
-#endif /* NDEBUG */
-
-
-#if YYSTACKDEPTH<=0
-/*
-** Try to increase the size of the parser stack.
-*/
-static void yyGrowStack(yyParser *p){
- int newSize;
- yyStackEntry *pNew;
-
- newSize = p->yystksz*2 + 100;
- pNew = realloc(p->yystack, newSize*sizeof(pNew[0]));
- if( pNew ){
- p->yystack = pNew;
- p->yystksz = newSize;
-#ifndef NDEBUG
- if( yyTraceFILE ){
- fprintf(yyTraceFILE,"%sStack grows to %d entries!\n",
- yyTracePrompt, p->yystksz);
- }
-#endif
- }
-}
-#endif
-
-/*
-** This function allocates a new parser.
-** The only argument is a pointer to a function which works like
-** malloc.
-**
-** Inputs:
-** A pointer to the function used to allocate memory.
-**
-** Outputs:
-** A pointer to a parser. This pointer is used in subsequent calls
-** to sqlite3Parser and sqlite3ParserFree.
-*/
-SQLITE_PRIVATE void *sqlite3ParserAlloc(void *(*mallocProc)(size_t)){
- yyParser *pParser;
- pParser = (yyParser*)(*mallocProc)( (size_t)sizeof(yyParser) );
- if( pParser ){
- pParser->yyidx = -1;
-#ifdef YYTRACKMAXSTACKDEPTH
- pParser->yyidxMax = 0;
-#endif
-#if YYSTACKDEPTH<=0
- pParser->yystack = NULL;
- pParser->yystksz = 0;
- yyGrowStack(pParser);
-#endif
- }
- return pParser;
-}
-
-/* The following function deletes the value associated with a
-** symbol. The symbol can be either a terminal or nonterminal.
-** "yymajor" is the symbol code, and "yypminor" is a pointer to
-** the value.
-*/
-static void yy_destructor(
- yyParser *yypParser, /* The parser */
- YYCODETYPE yymajor, /* Type code for object to destroy */
- YYMINORTYPE *yypminor /* The object to be destroyed */
-){
- sqlite3ParserARG_FETCH;
- switch( yymajor ){
- /* Here is inserted the actions which take place when a
- ** terminal or non-terminal is destroyed. This can happen
- ** when the symbol is popped from the stack during a
- ** reduce or during error processing or when a parser is
- ** being destroyed before it is finished parsing.
- **
- ** Note: during a reduce, the only symbols destroyed are those
- ** which appear on the RHS of the rule, but which are not used
- ** inside the C code.
- */
- case 160: /* select */
- case 194: /* oneselect */
-{
-sqlite3SelectDelete(pParse->db, (yypminor->yy3));
-}
- break;
- case 174: /* term */
- case 175: /* expr */
- case 223: /* escape */
-{
-sqlite3ExprDelete(pParse->db, (yypminor->yy346).pExpr);
-}
- break;
- case 179: /* idxlist_opt */
- case 187: /* idxlist */
- case 197: /* selcollist */
- case 200: /* groupby_opt */
- case 202: /* orderby_opt */
- case 204: /* sclp */
- case 214: /* sortlist */
- case 216: /* nexprlist */
- case 217: /* setlist */
- case 220: /* itemlist */
- case 221: /* exprlist */
- case 227: /* case_exprlist */
-{
-sqlite3ExprListDelete(pParse->db, (yypminor->yy14));
-}
- break;
- case 193: /* fullname */
- case 198: /* from */
- case 206: /* seltablist */
- case 207: /* stl_prefix */
-{
-sqlite3SrcListDelete(pParse->db, (yypminor->yy65));
-}
- break;
- case 199: /* where_opt */
- case 201: /* having_opt */
- case 210: /* on_opt */
- case 215: /* sortitem */
- case 226: /* case_operand */
- case 228: /* case_else */
- case 239: /* when_clause */
- case 244: /* key_opt */
-{
-sqlite3ExprDelete(pParse->db, (yypminor->yy132));
-}
- break;
- case 211: /* using_opt */
- case 213: /* inscollist */
- case 219: /* inscollist_opt */
-{
-sqlite3IdListDelete(pParse->db, (yypminor->yy408));
-}
- break;
- case 235: /* trigger_cmd_list */
- case 240: /* trigger_cmd */
-{
-sqlite3DeleteTriggerStep(pParse->db, (yypminor->yy473));
-}
- break;
- case 237: /* trigger_event */
-{
-sqlite3IdListDelete(pParse->db, (yypminor->yy378).b);
-}
- break;
- default: break; /* If no destructor action specified: do nothing */
- }
-}
-
-/*
-** Pop the parser's stack once.
-**
-** If there is a destructor routine associated with the token which
-** is popped from the stack, then call it.
-**
-** Return the major token number for the symbol popped.
-*/
-static int yy_pop_parser_stack(yyParser *pParser){
- YYCODETYPE yymajor;
- yyStackEntry *yytos = &pParser->yystack[pParser->yyidx];
-
- /* There is no mechanism by which the parser stack can be popped below
- ** empty in SQLite. */
- if( NEVER(pParser->yyidx<0) ) return 0;
-#ifndef NDEBUG
- if( yyTraceFILE && pParser->yyidx>=0 ){
- fprintf(yyTraceFILE,"%sPopping %s\n",
- yyTracePrompt,
- yyTokenName[yytos->major]);
- }
-#endif
- yymajor = yytos->major;
- yy_destructor(pParser, yymajor, &yytos->minor);
- pParser->yyidx--;
- return yymajor;
-}
-
-/*
-** Deallocate and destroy a parser. Destructors are all called for
-** all stack elements before shutting the parser down.
-**
-** Inputs:
-** <ul>
-** <li> A pointer to the parser. This should be a pointer
-** obtained from sqlite3ParserAlloc.
-** <li> A pointer to a function used to reclaim memory obtained
-** from malloc.
-** </ul>
-*/
-SQLITE_PRIVATE void sqlite3ParserFree(
- void *p, /* The parser to be deleted */
- void (*freeProc)(void*) /* Function used to reclaim memory */
-){
- yyParser *pParser = (yyParser*)p;
- /* In SQLite, we never try to destroy a parser that was not successfully
- ** created in the first place. */
- if( NEVER(pParser==0) ) return;
- while( pParser->yyidx>=0 ) yy_pop_parser_stack(pParser);
-#if YYSTACKDEPTH<=0
- free(pParser->yystack);
-#endif
- (*freeProc)((void*)pParser);
-}
-
-/*
-** Return the peak depth of the stack for a parser.
-*/
-#ifdef YYTRACKMAXSTACKDEPTH
-SQLITE_PRIVATE int sqlite3ParserStackPeak(void *p){
- yyParser *pParser = (yyParser*)p;
- return pParser->yyidxMax;
-}
-#endif
-
-/*
-** Find the appropriate action for a parser given the terminal
-** look-ahead token iLookAhead.
-**
-** If the look-ahead token is YYNOCODE, then check to see if the action is
-** independent of the look-ahead. If it is, return the action, otherwise
-** return YY_NO_ACTION.
-*/
-static int yy_find_shift_action(
- yyParser *pParser, /* The parser */
- YYCODETYPE iLookAhead /* The look-ahead token */
-){
- int i;
- int stateno = pParser->yystack[pParser->yyidx].stateno;
-
- if( stateno>YY_SHIFT_MAX || (i = yy_shift_ofst[stateno])==YY_SHIFT_USE_DFLT ){
- return yy_default[stateno];
- }
- assert( iLookAhead!=YYNOCODE );
- i += iLookAhead;
- if( i<0 || i>=YY_SZ_ACTTAB || yy_lookahead[i]!=iLookAhead ){
- /* The user of ";" instead of "\000" as a statement terminator in SQLite
- ** means that we always have a look-ahead token. */
- if( iLookAhead>0 ){
-#ifdef YYFALLBACK
- YYCODETYPE iFallback; /* Fallback token */
- if( iLookAhead<sizeof(yyFallback)/sizeof(yyFallback[0])
- && (iFallback = yyFallback[iLookAhead])!=0 ){
-#ifndef NDEBUG
- if( yyTraceFILE ){
- fprintf(yyTraceFILE, "%sFALLBACK %s => %s\n",
- yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[iFallback]);
- }
-#endif
- return yy_find_shift_action(pParser, iFallback);
- }
-#endif
-#ifdef YYWILDCARD
- {
- int j = i - iLookAhead + YYWILDCARD;
- if( j>=0 && j<YY_SZ_ACTTAB && yy_lookahead[j]==YYWILDCARD ){
-#ifndef NDEBUG
- if( yyTraceFILE ){
- fprintf(yyTraceFILE, "%sWILDCARD %s => %s\n",
- yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[YYWILDCARD]);
- }
-#endif /* NDEBUG */
- return yy_action[j];
- }
- }
-#endif /* YYWILDCARD */
- }
- return yy_default[stateno];
- }else{
- return yy_action[i];
- }
-}
-
-/*
-** Find the appropriate action for a parser given the non-terminal
-** look-ahead token iLookAhead.
-**
-** If the look-ahead token is YYNOCODE, then check to see if the action is
-** independent of the look-ahead. If it is, return the action, otherwise
-** return YY_NO_ACTION.
-*/
-static int yy_find_reduce_action(
- int stateno, /* Current state number */
- YYCODETYPE iLookAhead /* The look-ahead token */
-){
- int i;
-#ifdef YYERRORSYMBOL
- if( stateno>YY_REDUCE_MAX ){
- return yy_default[stateno];
- }
-#else
- assert( stateno<=YY_REDUCE_MAX );
-#endif
- i = yy_reduce_ofst[stateno];
- assert( i!=YY_REDUCE_USE_DFLT );
- assert( iLookAhead!=YYNOCODE );
- i += iLookAhead;
-#ifdef YYERRORSYMBOL
- if( i<0 || i>=YY_SZ_ACTTAB || yy_lookahead[i]!=iLookAhead ){
- return yy_default[stateno];
- }
-#else
- assert( i>=0 && i<YY_SZ_ACTTAB );
- assert( yy_lookahead[i]==iLookAhead );
-#endif
- return yy_action[i];
-}
-
-/*
-** The following routine is called if the stack overflows.
-*/
-static void yyStackOverflow(yyParser *yypParser, YYMINORTYPE *yypMinor){
- sqlite3ParserARG_FETCH;
- yypParser->yyidx--;
-#ifndef NDEBUG
- if( yyTraceFILE ){
- fprintf(yyTraceFILE,"%sStack Overflow!\n",yyTracePrompt);
- }
-#endif
- while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser);
- /* Here code is inserted which will execute if the parser
- ** stack every overflows */
-
- UNUSED_PARAMETER(yypMinor); /* Silence some compiler warnings */
- sqlite3ErrorMsg(pParse, "parser stack overflow");
- pParse->parseError = 1;
- sqlite3ParserARG_STORE; /* Suppress warning about unused %extra_argument var */
-}
-
-/*
-** Perform a shift action.
-*/
-static void yy_shift(
- yyParser *yypParser, /* The parser to be shifted */
- int yyNewState, /* The new state to shift in */
- int yyMajor, /* The major token to shift in */
- YYMINORTYPE *yypMinor /* Pointer to the minor token to shift in */
-){
- yyStackEntry *yytos;
- yypParser->yyidx++;
-#ifdef YYTRACKMAXSTACKDEPTH
- if( yypParser->yyidx>yypParser->yyidxMax ){
- yypParser->yyidxMax = yypParser->yyidx;
- }
-#endif
-#if YYSTACKDEPTH>0
- if( yypParser->yyidx>=YYSTACKDEPTH ){
- yyStackOverflow(yypParser, yypMinor);
- return;
- }
-#else
- if( yypParser->yyidx>=yypParser->yystksz ){
- yyGrowStack(yypParser);
- if( yypParser->yyidx>=yypParser->yystksz ){
- yyStackOverflow(yypParser, yypMinor);
- return;
- }
- }
-#endif
- yytos = &yypParser->yystack[yypParser->yyidx];
- yytos->stateno = (YYACTIONTYPE)yyNewState;
- yytos->major = (YYCODETYPE)yyMajor;
- yytos->minor = *yypMinor;
-#ifndef NDEBUG
- if( yyTraceFILE && yypParser->yyidx>0 ){
- int i;
- fprintf(yyTraceFILE,"%sShift %d\n",yyTracePrompt,yyNewState);
- fprintf(yyTraceFILE,"%sStack:",yyTracePrompt);
- for(i=1; i<=yypParser->yyidx; i++)
- fprintf(yyTraceFILE," %s",yyTokenName[yypParser->yystack[i].major]);
- fprintf(yyTraceFILE,"\n");
- }
-#endif
-}
-
-/* The following table contains information about every rule that
-** is used during the reduce.
-*/
-static const struct {
- YYCODETYPE lhs; /* Symbol on the left-hand side of the rule */
- unsigned char nrhs; /* Number of right-hand side symbols in the rule */
-} yyRuleInfo[] = {
- { 142, 1 },
- { 143, 2 },
- { 143, 1 },
- { 144, 1 },
- { 144, 3 },
- { 145, 0 },
- { 145, 1 },
- { 145, 3 },
- { 146, 1 },
- { 147, 3 },
- { 149, 0 },
- { 149, 1 },
- { 149, 2 },
- { 148, 0 },
- { 148, 1 },
- { 148, 1 },
- { 148, 1 },
- { 147, 2 },
- { 147, 2 },
- { 147, 2 },
- { 151, 1 },
- { 151, 0 },
- { 147, 2 },
- { 147, 3 },
- { 147, 5 },
- { 147, 2 },
- { 152, 6 },
- { 154, 1 },
- { 156, 0 },
- { 156, 3 },
- { 155, 1 },
- { 155, 0 },
- { 153, 4 },
- { 153, 2 },
- { 158, 3 },
- { 158, 1 },
- { 161, 3 },
- { 162, 1 },
- { 165, 1 },
- { 165, 1 },
- { 166, 1 },
- { 150, 1 },
- { 150, 1 },
- { 150, 1 },
- { 163, 0 },
- { 163, 1 },
- { 167, 1 },
- { 167, 4 },
- { 167, 6 },
- { 168, 1 },
- { 168, 2 },
- { 169, 1 },
- { 169, 1 },
- { 164, 2 },
- { 164, 0 },
- { 172, 3 },
- { 172, 1 },
- { 173, 2 },
- { 173, 4 },
- { 173, 3 },
- { 173, 3 },
- { 173, 2 },
- { 173, 2 },
- { 173, 3 },
- { 173, 5 },
- { 173, 2 },
- { 173, 4 },
- { 173, 4 },
- { 173, 1 },
- { 173, 2 },
- { 178, 0 },
- { 178, 1 },
- { 180, 0 },
- { 180, 2 },
- { 182, 2 },
- { 182, 3 },
- { 182, 3 },
- { 182, 3 },
- { 183, 2 },
- { 183, 2 },
- { 183, 1 },
- { 183, 1 },
- { 181, 3 },
- { 181, 2 },
- { 184, 0 },
- { 184, 2 },
- { 184, 2 },
- { 159, 0 },
- { 159, 2 },
- { 185, 3 },
- { 185, 2 },
- { 185, 1 },
- { 186, 2 },
- { 186, 7 },
- { 186, 5 },
- { 186, 5 },
- { 186, 10 },
- { 188, 0 },
- { 188, 1 },
- { 176, 0 },
- { 176, 3 },
- { 189, 0 },
- { 189, 2 },
- { 190, 1 },
- { 190, 1 },
- { 190, 1 },
- { 147, 4 },
- { 192, 2 },
- { 192, 0 },
- { 147, 8 },
- { 147, 4 },
- { 147, 1 },
- { 160, 1 },
- { 160, 3 },
- { 195, 1 },
- { 195, 2 },
- { 195, 1 },
- { 194, 9 },
- { 196, 1 },
- { 196, 1 },
- { 196, 0 },
- { 204, 2 },
- { 204, 0 },
- { 197, 3 },
- { 197, 2 },
- { 197, 4 },
- { 205, 2 },
- { 205, 1 },
- { 205, 0 },
- { 198, 0 },
- { 198, 2 },
- { 207, 2 },
- { 207, 0 },
- { 206, 7 },
- { 206, 7 },
- { 206, 7 },
- { 157, 0 },
- { 157, 2 },
- { 193, 2 },
- { 208, 1 },
- { 208, 2 },
- { 208, 3 },
- { 208, 4 },
- { 210, 2 },
- { 210, 0 },
- { 209, 0 },
- { 209, 3 },
- { 209, 2 },
- { 211, 4 },
- { 211, 0 },
- { 202, 0 },
- { 202, 3 },
- { 214, 4 },
- { 214, 2 },
- { 215, 1 },
- { 177, 1 },
- { 177, 1 },
- { 177, 0 },
- { 200, 0 },
- { 200, 3 },
- { 201, 0 },
- { 201, 2 },
- { 203, 0 },
- { 203, 2 },
- { 203, 4 },
- { 203, 4 },
- { 147, 5 },
- { 199, 0 },
- { 199, 2 },
- { 147, 7 },
- { 217, 5 },
- { 217, 3 },
- { 147, 8 },
- { 147, 5 },
- { 147, 6 },
- { 218, 2 },
- { 218, 1 },
- { 220, 3 },
- { 220, 1 },
- { 219, 0 },
- { 219, 3 },
- { 213, 3 },
- { 213, 1 },
- { 175, 1 },
- { 175, 3 },
- { 174, 1 },
- { 175, 1 },
- { 175, 1 },
- { 175, 3 },
- { 175, 5 },
- { 174, 1 },
- { 174, 1 },
- { 175, 1 },
- { 175, 1 },
- { 175, 3 },
- { 175, 6 },
- { 175, 5 },
- { 175, 4 },
- { 174, 1 },
- { 175, 3 },
- { 175, 3 },
- { 175, 3 },
- { 175, 3 },
- { 175, 3 },
- { 175, 3 },
- { 175, 3 },
- { 175, 3 },
- { 222, 1 },
- { 222, 2 },
- { 222, 1 },
- { 222, 2 },
- { 223, 2 },
- { 223, 0 },
- { 175, 4 },
- { 175, 2 },
- { 175, 3 },
- { 175, 3 },
- { 175, 4 },
- { 175, 2 },
- { 175, 2 },
- { 175, 2 },
- { 175, 2 },
- { 224, 1 },
- { 224, 2 },
- { 175, 5 },
- { 225, 1 },
- { 225, 2 },
- { 175, 5 },
- { 175, 3 },
- { 175, 5 },
- { 175, 4 },
- { 175, 4 },
- { 175, 5 },
- { 227, 5 },
- { 227, 4 },
- { 228, 2 },
- { 228, 0 },
- { 226, 1 },
- { 226, 0 },
- { 221, 1 },
- { 221, 0 },
- { 216, 3 },
- { 216, 1 },
- { 147, 11 },
- { 229, 1 },
- { 229, 0 },
- { 179, 0 },
- { 179, 3 },
- { 187, 5 },
- { 187, 3 },
- { 230, 0 },
- { 230, 2 },
- { 147, 4 },
- { 147, 1 },
- { 147, 2 },
- { 147, 3 },
- { 147, 5 },
- { 147, 6 },
- { 147, 5 },
- { 147, 6 },
- { 231, 1 },
- { 231, 1 },
- { 231, 1 },
- { 231, 1 },
- { 231, 1 },
- { 170, 2 },
- { 171, 2 },
- { 233, 1 },
- { 232, 1 },
- { 232, 0 },
- { 147, 5 },
- { 234, 11 },
- { 236, 1 },
- { 236, 1 },
- { 236, 2 },
- { 236, 0 },
- { 237, 1 },
- { 237, 1 },
- { 237, 3 },
- { 238, 0 },
- { 238, 3 },
- { 239, 0 },
- { 239, 2 },
- { 235, 3 },
- { 235, 2 },
- { 241, 1 },
- { 241, 3 },
- { 242, 0 },
- { 242, 3 },
- { 242, 2 },
- { 240, 7 },
- { 240, 8 },
- { 240, 5 },
- { 240, 5 },
- { 240, 1 },
- { 175, 4 },
- { 175, 6 },
- { 191, 1 },
- { 191, 1 },
- { 191, 1 },
- { 147, 4 },
- { 147, 6 },
- { 147, 3 },
- { 244, 0 },
- { 244, 2 },
- { 243, 1 },
- { 243, 0 },
- { 147, 1 },
- { 147, 3 },
- { 147, 1 },
- { 147, 3 },
- { 147, 6 },
- { 147, 6 },
- { 245, 1 },
- { 246, 0 },
- { 246, 1 },
- { 147, 1 },
- { 147, 4 },
- { 247, 7 },
- { 248, 1 },
- { 248, 3 },
- { 249, 0 },
- { 249, 2 },
- { 250, 1 },
- { 250, 3 },
- { 251, 1 },
- { 252, 0 },
- { 252, 4 },
- { 252, 2 },
-};
-
-static void yy_accept(yyParser*); /* Forward Declaration */
-
-/*
-** Perform a reduce action and the shift that must immediately
-** follow the reduce.
-*/
-static void yy_reduce(
- yyParser *yypParser, /* The parser */
- int yyruleno /* Number of the rule by which to reduce */
-){
- int yygoto; /* The next state */
- int yyact; /* The next action */
- YYMINORTYPE yygotominor; /* The LHS of the rule reduced */
- yyStackEntry *yymsp; /* The top of the parser's stack */
- int yysize; /* Amount to pop the stack */
- sqlite3ParserARG_FETCH;
- yymsp = &yypParser->yystack[yypParser->yyidx];
-#ifndef NDEBUG
- if( yyTraceFILE && yyruleno>=0
- && yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ){
- fprintf(yyTraceFILE, "%sReduce [%s].\n", yyTracePrompt,
- yyRuleName[yyruleno]);
- }
-#endif /* NDEBUG */
-
- /* Silence complaints from purify about yygotominor being uninitialized
- ** in some cases when it is copied into the stack after the following
- ** switch. yygotominor is uninitialized when a rule reduces that does
- ** not set the value of its left-hand side nonterminal. Leaving the
- ** value of the nonterminal uninitialized is utterly harmless as long
- ** as the value is never used. So really the only thing this code
- ** accomplishes is to quieten purify.
- **
- ** 2007-01-16: The wireshark project (www.wireshark.org) reports that
- ** without this code, their parser segfaults. I'm not sure what there
- ** parser is doing to make this happen. This is the second bug report
- ** from wireshark this week. Clearly they are stressing Lemon in ways
- ** that it has not been previously stressed... (SQLite ticket #2172)
- */
- /*memset(&yygotominor, 0, sizeof(yygotominor));*/
- yygotominor = yyzerominor;
-
-
- switch( yyruleno ){
- /* Beginning here are the reduction cases. A typical example
- ** follows:
- ** case 0:
- ** #line <lineno> <grammarfile>
- ** { ... } // User supplied code
- ** #line <lineno> <thisfile>
- ** break;
- */
- case 5: /* explain ::= */
-{ sqlite3BeginParse(pParse, 0); }
- break;
- case 6: /* explain ::= EXPLAIN */
-{ sqlite3BeginParse(pParse, 1); }
- break;
- case 7: /* explain ::= EXPLAIN QUERY PLAN */
-{ sqlite3BeginParse(pParse, 2); }
- break;
- case 8: /* cmdx ::= cmd */
-{ sqlite3FinishCoding(pParse); }
- break;
- case 9: /* cmd ::= BEGIN transtype trans_opt */
-{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy328);}
- break;
- case 13: /* transtype ::= */
-{yygotominor.yy328 = TK_DEFERRED;}
- break;
- case 14: /* transtype ::= DEFERRED */
- case 15: /* transtype ::= IMMEDIATE */ yytestcase(yyruleno==15);
- case 16: /* transtype ::= EXCLUSIVE */ yytestcase(yyruleno==16);
- case 114: /* multiselect_op ::= UNION */ yytestcase(yyruleno==114);
- case 116: /* multiselect_op ::= EXCEPT|INTERSECT */ yytestcase(yyruleno==116);
-{yygotominor.yy328 = yymsp[0].major;}
- break;
- case 17: /* cmd ::= COMMIT trans_opt */
- case 18: /* cmd ::= END trans_opt */ yytestcase(yyruleno==18);
-{sqlite3CommitTransaction(pParse);}
- break;
- case 19: /* cmd ::= ROLLBACK trans_opt */
-{sqlite3RollbackTransaction(pParse);}
- break;
- case 22: /* cmd ::= SAVEPOINT nm */
-{
- sqlite3Savepoint(pParse, SAVEPOINT_BEGIN, &yymsp[0].minor.yy0);
-}
- break;
- case 23: /* cmd ::= RELEASE savepoint_opt nm */
-{
- sqlite3Savepoint(pParse, SAVEPOINT_RELEASE, &yymsp[0].minor.yy0);
-}
- break;
- case 24: /* cmd ::= ROLLBACK trans_opt TO savepoint_opt nm */
-{
- sqlite3Savepoint(pParse, SAVEPOINT_ROLLBACK, &yymsp[0].minor.yy0);
-}
- break;
- case 26: /* create_table ::= createkw temp TABLE ifnotexists nm dbnm */
-{
- sqlite3StartTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,yymsp[-4].minor.yy328,0,0,yymsp[-2].minor.yy328);
-}
- break;
- case 27: /* createkw ::= CREATE */
-{
- pParse->db->lookaside.bEnabled = 0;
- yygotominor.yy0 = yymsp[0].minor.yy0;
-}
- break;
- case 28: /* ifnotexists ::= */
- case 31: /* temp ::= */ yytestcase(yyruleno==31);
- case 70: /* autoinc ::= */ yytestcase(yyruleno==70);
- case 84: /* init_deferred_pred_opt ::= */ yytestcase(yyruleno==84);
- case 86: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ yytestcase(yyruleno==86);
- case 97: /* defer_subclause_opt ::= */ yytestcase(yyruleno==97);
- case 108: /* ifexists ::= */ yytestcase(yyruleno==108);
- case 119: /* distinct ::= ALL */ yytestcase(yyruleno==119);
- case 120: /* distinct ::= */ yytestcase(yyruleno==120);
- case 222: /* between_op ::= BETWEEN */ yytestcase(yyruleno==222);
- case 225: /* in_op ::= IN */ yytestcase(yyruleno==225);
-{yygotominor.yy328 = 0;}
- break;
- case 29: /* ifnotexists ::= IF NOT EXISTS */
- case 30: /* temp ::= TEMP */ yytestcase(yyruleno==30);
- case 71: /* autoinc ::= AUTOINCR */ yytestcase(yyruleno==71);
- case 85: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */ yytestcase(yyruleno==85);
- case 107: /* ifexists ::= IF EXISTS */ yytestcase(yyruleno==107);
- case 118: /* distinct ::= DISTINCT */ yytestcase(yyruleno==118);
- case 223: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==223);
- case 226: /* in_op ::= NOT IN */ yytestcase(yyruleno==226);
-{yygotominor.yy328 = 1;}
- break;
- case 32: /* create_table_args ::= LP columnlist conslist_opt RP */
-{
- sqlite3EndTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0);
-}
- break;
- case 33: /* create_table_args ::= AS select */
-{
- sqlite3EndTable(pParse,0,0,yymsp[0].minor.yy3);
- sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy3);
-}
- break;
- case 36: /* column ::= columnid type carglist */
-{
- yygotominor.yy0.z = yymsp[-2].minor.yy0.z;
- yygotominor.yy0.n = (int)(pParse->sLastToken.z-yymsp[-2].minor.yy0.z) + pParse->sLastToken.n;
-}
- break;
- case 37: /* columnid ::= nm */
-{
- sqlite3AddColumn(pParse,&yymsp[0].minor.yy0);
- yygotominor.yy0 = yymsp[0].minor.yy0;
-}
- break;
- case 38: /* id ::= ID */
- case 39: /* id ::= INDEXED */ yytestcase(yyruleno==39);
- case 40: /* ids ::= ID|STRING */ yytestcase(yyruleno==40);
- case 41: /* nm ::= id */ yytestcase(yyruleno==41);
- case 42: /* nm ::= STRING */ yytestcase(yyruleno==42);
- case 43: /* nm ::= JOIN_KW */ yytestcase(yyruleno==43);
- case 46: /* typetoken ::= typename */ yytestcase(yyruleno==46);
- case 49: /* typename ::= ids */ yytestcase(yyruleno==49);
- case 126: /* as ::= AS nm */ yytestcase(yyruleno==126);
- case 127: /* as ::= ids */ yytestcase(yyruleno==127);
- case 137: /* dbnm ::= DOT nm */ yytestcase(yyruleno==137);
- case 146: /* indexed_opt ::= INDEXED BY nm */ yytestcase(yyruleno==146);
- case 251: /* collate ::= COLLATE ids */ yytestcase(yyruleno==251);
- case 260: /* nmnum ::= plus_num */ yytestcase(yyruleno==260);
- case 261: /* nmnum ::= nm */ yytestcase(yyruleno==261);
- case 262: /* nmnum ::= ON */ yytestcase(yyruleno==262);
- case 263: /* nmnum ::= DELETE */ yytestcase(yyruleno==263);
- case 264: /* nmnum ::= DEFAULT */ yytestcase(yyruleno==264);
- case 265: /* plus_num ::= plus_opt number */ yytestcase(yyruleno==265);
- case 266: /* minus_num ::= MINUS number */ yytestcase(yyruleno==266);
- case 267: /* number ::= INTEGER|FLOAT */ yytestcase(yyruleno==267);
- case 285: /* trnm ::= nm */ yytestcase(yyruleno==285);
-{yygotominor.yy0 = yymsp[0].minor.yy0;}
- break;
- case 45: /* type ::= typetoken */
-{sqlite3AddColumnType(pParse,&yymsp[0].minor.yy0);}
- break;
- case 47: /* typetoken ::= typename LP signed RP */
-{
- yygotominor.yy0.z = yymsp[-3].minor.yy0.z;
- yygotominor.yy0.n = (int)(&yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] - yymsp[-3].minor.yy0.z);
-}
- break;
- case 48: /* typetoken ::= typename LP signed COMMA signed RP */
-{
- yygotominor.yy0.z = yymsp[-5].minor.yy0.z;
- yygotominor.yy0.n = (int)(&yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] - yymsp[-5].minor.yy0.z);
-}
- break;
- case 50: /* typename ::= typename ids */
-{yygotominor.yy0.z=yymsp[-1].minor.yy0.z; yygotominor.yy0.n=yymsp[0].minor.yy0.n+(int)(yymsp[0].minor.yy0.z-yymsp[-1].minor.yy0.z);}
- break;
- case 57: /* ccons ::= DEFAULT term */
- case 59: /* ccons ::= DEFAULT PLUS term */ yytestcase(yyruleno==59);
-{sqlite3AddDefaultValue(pParse,&yymsp[0].minor.yy346);}
- break;
- case 58: /* ccons ::= DEFAULT LP expr RP */
-{sqlite3AddDefaultValue(pParse,&yymsp[-1].minor.yy346);}
- break;
- case 60: /* ccons ::= DEFAULT MINUS term */
-{
- ExprSpan v;
- v.pExpr = sqlite3PExpr(pParse, TK_UMINUS, yymsp[0].minor.yy346.pExpr, 0, 0);
- v.zStart = yymsp[-1].minor.yy0.z;
- v.zEnd = yymsp[0].minor.yy346.zEnd;
- sqlite3AddDefaultValue(pParse,&v);
-}
- break;
- case 61: /* ccons ::= DEFAULT id */
-{
- ExprSpan v;
- spanExpr(&v, pParse, TK_STRING, &yymsp[0].minor.yy0);
- sqlite3AddDefaultValue(pParse,&v);
-}
- break;
- case 63: /* ccons ::= NOT NULL onconf */
-{sqlite3AddNotNull(pParse, yymsp[0].minor.yy328);}
- break;
- case 64: /* ccons ::= PRIMARY KEY sortorder onconf autoinc */
-{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy328,yymsp[0].minor.yy328,yymsp[-2].minor.yy328);}
- break;
- case 65: /* ccons ::= UNIQUE onconf */
-{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy328,0,0,0,0);}
- break;
- case 66: /* ccons ::= CHECK LP expr RP */
-{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy346.pExpr);}
- break;
- case 67: /* ccons ::= REFERENCES nm idxlist_opt refargs */
-{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy14,yymsp[0].minor.yy328);}
- break;
- case 68: /* ccons ::= defer_subclause */
-{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy328);}
- break;
- case 69: /* ccons ::= COLLATE ids */
-{sqlite3AddCollateType(pParse, &yymsp[0].minor.yy0);}
- break;
- case 72: /* refargs ::= */
-{ yygotominor.yy328 = OE_Restrict * 0x010101; }
- break;
- case 73: /* refargs ::= refargs refarg */
-{ yygotominor.yy328 = (yymsp[-1].minor.yy328 & ~yymsp[0].minor.yy429.mask) | yymsp[0].minor.yy429.value; }
- break;
- case 74: /* refarg ::= MATCH nm */
-{ yygotominor.yy429.value = 0; yygotominor.yy429.mask = 0x000000; }
- break;
- case 75: /* refarg ::= ON DELETE refact */
-{ yygotominor.yy429.value = yymsp[0].minor.yy328; yygotominor.yy429.mask = 0x0000ff; }
- break;
- case 76: /* refarg ::= ON UPDATE refact */
-{ yygotominor.yy429.value = yymsp[0].minor.yy328<<8; yygotominor.yy429.mask = 0x00ff00; }
- break;
- case 77: /* refarg ::= ON INSERT refact */
-{ yygotominor.yy429.value = yymsp[0].minor.yy328<<16; yygotominor.yy429.mask = 0xff0000; }
- break;
- case 78: /* refact ::= SET NULL */
-{ yygotominor.yy328 = OE_SetNull; }
- break;
- case 79: /* refact ::= SET DEFAULT */
-{ yygotominor.yy328 = OE_SetDflt; }
- break;
- case 80: /* refact ::= CASCADE */
-{ yygotominor.yy328 = OE_Cascade; }
- break;
- case 81: /* refact ::= RESTRICT */
-{ yygotominor.yy328 = OE_Restrict; }
- break;
- case 82: /* defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */
- case 83: /* defer_subclause ::= DEFERRABLE init_deferred_pred_opt */ yytestcase(yyruleno==83);
- case 98: /* defer_subclause_opt ::= defer_subclause */ yytestcase(yyruleno==98);
- case 100: /* onconf ::= ON CONFLICT resolvetype */ yytestcase(yyruleno==100);
- case 103: /* resolvetype ::= raisetype */ yytestcase(yyruleno==103);
-{yygotominor.yy328 = yymsp[0].minor.yy328;}
- break;
- case 87: /* conslist_opt ::= */
-{yygotominor.yy0.n = 0; yygotominor.yy0.z = 0;}
- break;
- case 88: /* conslist_opt ::= COMMA conslist */
-{yygotominor.yy0 = yymsp[-1].minor.yy0;}
- break;
- case 93: /* tcons ::= PRIMARY KEY LP idxlist autoinc RP onconf */
-{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy14,yymsp[0].minor.yy328,yymsp[-2].minor.yy328,0);}
- break;
- case 94: /* tcons ::= UNIQUE LP idxlist RP onconf */
-{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy14,yymsp[0].minor.yy328,0,0,0,0);}
- break;
- case 95: /* tcons ::= CHECK LP expr RP onconf */
-{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy346.pExpr);}
- break;
- case 96: /* tcons ::= FOREIGN KEY LP idxlist RP REFERENCES nm idxlist_opt refargs defer_subclause_opt */
-{
- sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy14, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy14, yymsp[-1].minor.yy328);
- sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy328);
-}
- break;
- case 99: /* onconf ::= */
-{yygotominor.yy328 = OE_Default;}
- break;
- case 101: /* orconf ::= */
-{yygotominor.yy186 = OE_Default;}
- break;
- case 102: /* orconf ::= OR resolvetype */
-{yygotominor.yy186 = (u8)yymsp[0].minor.yy328;}
- break;
- case 104: /* resolvetype ::= IGNORE */
-{yygotominor.yy328 = OE_Ignore;}
- break;
- case 105: /* resolvetype ::= REPLACE */
-{yygotominor.yy328 = OE_Replace;}
- break;
- case 106: /* cmd ::= DROP TABLE ifexists fullname */
-{
- sqlite3DropTable(pParse, yymsp[0].minor.yy65, 0, yymsp[-1].minor.yy328);
-}
- break;
- case 109: /* cmd ::= createkw temp VIEW ifnotexists nm dbnm AS select */
-{
- sqlite3CreateView(pParse, &yymsp[-7].minor.yy0, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, yymsp[0].minor.yy3, yymsp[-6].minor.yy328, yymsp[-4].minor.yy328);
-}
- break;
- case 110: /* cmd ::= DROP VIEW ifexists fullname */
-{
- sqlite3DropTable(pParse, yymsp[0].minor.yy65, 1, yymsp[-1].minor.yy328);
-}
- break;
- case 111: /* cmd ::= select */
-{
- SelectDest dest = {SRT_Output, 0, 0, 0, 0};
- sqlite3Select(pParse, yymsp[0].minor.yy3, &dest);
- sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy3);
-}
- break;
- case 112: /* select ::= oneselect */
-{yygotominor.yy3 = yymsp[0].minor.yy3;}
- break;
- case 113: /* select ::= select multiselect_op oneselect */
-{
- if( yymsp[0].minor.yy3 ){
- yymsp[0].minor.yy3->op = (u8)yymsp[-1].minor.yy328;
- yymsp[0].minor.yy3->pPrior = yymsp[-2].minor.yy3;
- }else{
- sqlite3SelectDelete(pParse->db, yymsp[-2].minor.yy3);
- }
- yygotominor.yy3 = yymsp[0].minor.yy3;
-}
- break;
- case 115: /* multiselect_op ::= UNION ALL */
-{yygotominor.yy328 = TK_ALL;}
- break;
- case 117: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */
-{
- yygotominor.yy3 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy14,yymsp[-5].minor.yy65,yymsp[-4].minor.yy132,yymsp[-3].minor.yy14,yymsp[-2].minor.yy132,yymsp[-1].minor.yy14,yymsp[-7].minor.yy328,yymsp[0].minor.yy476.pLimit,yymsp[0].minor.yy476.pOffset);
-}
- break;
- case 121: /* sclp ::= selcollist COMMA */
- case 247: /* idxlist_opt ::= LP idxlist RP */ yytestcase(yyruleno==247);
-{yygotominor.yy14 = yymsp[-1].minor.yy14;}
- break;
- case 122: /* sclp ::= */
- case 150: /* orderby_opt ::= */ yytestcase(yyruleno==150);
- case 158: /* groupby_opt ::= */ yytestcase(yyruleno==158);
- case 240: /* exprlist ::= */ yytestcase(yyruleno==240);
- case 246: /* idxlist_opt ::= */ yytestcase(yyruleno==246);
-{yygotominor.yy14 = 0;}
- break;
- case 123: /* selcollist ::= sclp expr as */
-{
- yygotominor.yy14 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy14, yymsp[-1].minor.yy346.pExpr);
- if( yymsp[0].minor.yy0.n>0 ) sqlite3ExprListSetName(pParse, yygotominor.yy14, &yymsp[0].minor.yy0, 1);
- sqlite3ExprListSetSpan(pParse,yygotominor.yy14,&yymsp[-1].minor.yy346);
-}
- break;
- case 124: /* selcollist ::= sclp STAR */
-{
- Expr *p = sqlite3Expr(pParse->db, TK_ALL, 0);
- yygotominor.yy14 = sqlite3ExprListAppend(pParse, yymsp[-1].minor.yy14, p);
-}
- break;
- case 125: /* selcollist ::= sclp nm DOT STAR */
-{
- Expr *pRight = sqlite3PExpr(pParse, TK_ALL, 0, 0, &yymsp[0].minor.yy0);
- Expr *pLeft = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-2].minor.yy0);
- Expr *pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight, 0);
- yygotominor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy14, pDot);
-}
- break;
- case 128: /* as ::= */
-{yygotominor.yy0.n = 0;}
- break;
- case 129: /* from ::= */
-{yygotominor.yy65 = sqlite3DbMallocZero(pParse->db, sizeof(*yygotominor.yy65));}
- break;
- case 130: /* from ::= FROM seltablist */
-{
- yygotominor.yy65 = yymsp[0].minor.yy65;
- sqlite3SrcListShiftJoinType(yygotominor.yy65);
-}
- break;
- case 131: /* stl_prefix ::= seltablist joinop */
-{
- yygotominor.yy65 = yymsp[-1].minor.yy65;
- if( ALWAYS(yygotominor.yy65 && yygotominor.yy65->nSrc>0) ) yygotominor.yy65->a[yygotominor.yy65->nSrc-1].jointype = (u8)yymsp[0].minor.yy328;
-}
- break;
- case 132: /* stl_prefix ::= */
-{yygotominor.yy65 = 0;}
- break;
- case 133: /* seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */
-{
- yygotominor.yy65 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy65,&yymsp[-5].minor.yy0,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,0,yymsp[-1].minor.yy132,yymsp[0].minor.yy408);
- sqlite3SrcListIndexedBy(pParse, yygotominor.yy65, &yymsp[-2].minor.yy0);
-}
- break;
- case 134: /* seltablist ::= stl_prefix LP select RP as on_opt using_opt */
-{
- yygotominor.yy65 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy65,0,0,&yymsp[-2].minor.yy0,yymsp[-4].minor.yy3,yymsp[-1].minor.yy132,yymsp[0].minor.yy408);
- }
- break;
- case 135: /* seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */
-{
- if( yymsp[-6].minor.yy65==0 && yymsp[-2].minor.yy0.n==0 && yymsp[-1].minor.yy132==0 && yymsp[0].minor.yy408==0 ){
- yygotominor.yy65 = yymsp[-4].minor.yy65;
- }else{
- Select *pSubquery;
- sqlite3SrcListShiftJoinType(yymsp[-4].minor.yy65);
- pSubquery = sqlite3SelectNew(pParse,0,yymsp[-4].minor.yy65,0,0,0,0,0,0,0);
- yygotominor.yy65 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy65,0,0,&yymsp[-2].minor.yy0,pSubquery,yymsp[-1].minor.yy132,yymsp[0].minor.yy408);
- }
- }
- break;
- case 136: /* dbnm ::= */
- case 145: /* indexed_opt ::= */ yytestcase(yyruleno==145);
-{yygotominor.yy0.z=0; yygotominor.yy0.n=0;}
- break;
- case 138: /* fullname ::= nm dbnm */
-{yygotominor.yy65 = sqlite3SrcListAppend(pParse->db,0,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0);}
- break;
- case 139: /* joinop ::= COMMA|JOIN */
-{ yygotominor.yy328 = JT_INNER; }
- break;
- case 140: /* joinop ::= JOIN_KW JOIN */
-{ yygotominor.yy328 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); }
- break;
- case 141: /* joinop ::= JOIN_KW nm JOIN */
-{ yygotominor.yy328 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); }
- break;
- case 142: /* joinop ::= JOIN_KW nm nm JOIN */
-{ yygotominor.yy328 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0); }
- break;
- case 143: /* on_opt ::= ON expr */
- case 154: /* sortitem ::= expr */ yytestcase(yyruleno==154);
- case 161: /* having_opt ::= HAVING expr */ yytestcase(yyruleno==161);
- case 168: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==168);
- case 235: /* case_else ::= ELSE expr */ yytestcase(yyruleno==235);
- case 237: /* case_operand ::= expr */ yytestcase(yyruleno==237);
-{yygotominor.yy132 = yymsp[0].minor.yy346.pExpr;}
- break;
- case 144: /* on_opt ::= */
- case 160: /* having_opt ::= */ yytestcase(yyruleno==160);
- case 167: /* where_opt ::= */ yytestcase(yyruleno==167);
- case 236: /* case_else ::= */ yytestcase(yyruleno==236);
- case 238: /* case_operand ::= */ yytestcase(yyruleno==238);
-{yygotominor.yy132 = 0;}
- break;
- case 147: /* indexed_opt ::= NOT INDEXED */
-{yygotominor.yy0.z=0; yygotominor.yy0.n=1;}
- break;
- case 148: /* using_opt ::= USING LP inscollist RP */
- case 180: /* inscollist_opt ::= LP inscollist RP */ yytestcase(yyruleno==180);
-{yygotominor.yy408 = yymsp[-1].minor.yy408;}
- break;
- case 149: /* using_opt ::= */
- case 179: /* inscollist_opt ::= */ yytestcase(yyruleno==179);
-{yygotominor.yy408 = 0;}
- break;
- case 151: /* orderby_opt ::= ORDER BY sortlist */
- case 159: /* groupby_opt ::= GROUP BY nexprlist */ yytestcase(yyruleno==159);
- case 239: /* exprlist ::= nexprlist */ yytestcase(yyruleno==239);
-{yygotominor.yy14 = yymsp[0].minor.yy14;}
- break;
- case 152: /* sortlist ::= sortlist COMMA sortitem sortorder */
-{
- yygotominor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy14,yymsp[-1].minor.yy132);
- if( yygotominor.yy14 ) yygotominor.yy14->a[yygotominor.yy14->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy328;
-}
- break;
- case 153: /* sortlist ::= sortitem sortorder */
-{
- yygotominor.yy14 = sqlite3ExprListAppend(pParse,0,yymsp[-1].minor.yy132);
- if( yygotominor.yy14 && ALWAYS(yygotominor.yy14->a) ) yygotominor.yy14->a[0].sortOrder = (u8)yymsp[0].minor.yy328;
-}
- break;
- case 155: /* sortorder ::= ASC */
- case 157: /* sortorder ::= */ yytestcase(yyruleno==157);
-{yygotominor.yy328 = SQLITE_SO_ASC;}
- break;
- case 156: /* sortorder ::= DESC */
-{yygotominor.yy328 = SQLITE_SO_DESC;}
- break;
- case 162: /* limit_opt ::= */
-{yygotominor.yy476.pLimit = 0; yygotominor.yy476.pOffset = 0;}
- break;
- case 163: /* limit_opt ::= LIMIT expr */
-{yygotominor.yy476.pLimit = yymsp[0].minor.yy346.pExpr; yygotominor.yy476.pOffset = 0;}
- break;
- case 164: /* limit_opt ::= LIMIT expr OFFSET expr */
-{yygotominor.yy476.pLimit = yymsp[-2].minor.yy346.pExpr; yygotominor.yy476.pOffset = yymsp[0].minor.yy346.pExpr;}
- break;
- case 165: /* limit_opt ::= LIMIT expr COMMA expr */
-{yygotominor.yy476.pOffset = yymsp[-2].minor.yy346.pExpr; yygotominor.yy476.pLimit = yymsp[0].minor.yy346.pExpr;}
- break;
- case 166: /* cmd ::= DELETE FROM fullname indexed_opt where_opt */
-{
- sqlite3SrcListIndexedBy(pParse, yymsp[-2].minor.yy65, &yymsp[-1].minor.yy0);
- sqlite3DeleteFrom(pParse,yymsp[-2].minor.yy65,yymsp[0].minor.yy132);
-}
- break;
- case 169: /* cmd ::= UPDATE orconf fullname indexed_opt SET setlist where_opt */
-{
- sqlite3SrcListIndexedBy(pParse, yymsp[-4].minor.yy65, &yymsp[-3].minor.yy0);
- sqlite3ExprListCheckLength(pParse,yymsp[-1].minor.yy14,"set list");
- sqlite3Update(pParse,yymsp[-4].minor.yy65,yymsp[-1].minor.yy14,yymsp[0].minor.yy132,yymsp[-5].minor.yy186);
-}
- break;
- case 170: /* setlist ::= setlist COMMA nm EQ expr */
-{
- yygotominor.yy14 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy14, yymsp[0].minor.yy346.pExpr);
- sqlite3ExprListSetName(pParse, yygotominor.yy14, &yymsp[-2].minor.yy0, 1);
-}
- break;
- case 171: /* setlist ::= nm EQ expr */
-{
- yygotominor.yy14 = sqlite3ExprListAppend(pParse, 0, yymsp[0].minor.yy346.pExpr);
- sqlite3ExprListSetName(pParse, yygotominor.yy14, &yymsp[-2].minor.yy0, 1);
-}
- break;
- case 172: /* cmd ::= insert_cmd INTO fullname inscollist_opt VALUES LP itemlist RP */
-{sqlite3Insert(pParse, yymsp[-5].minor.yy65, yymsp[-1].minor.yy14, 0, yymsp[-4].minor.yy408, yymsp[-7].minor.yy186);}
- break;
- case 173: /* cmd ::= insert_cmd INTO fullname inscollist_opt select */
-{sqlite3Insert(pParse, yymsp[-2].minor.yy65, 0, yymsp[0].minor.yy3, yymsp[-1].minor.yy408, yymsp[-4].minor.yy186);}
- break;
- case 174: /* cmd ::= insert_cmd INTO fullname inscollist_opt DEFAULT VALUES */
-{sqlite3Insert(pParse, yymsp[-3].minor.yy65, 0, 0, yymsp[-2].minor.yy408, yymsp[-5].minor.yy186);}
- break;
- case 175: /* insert_cmd ::= INSERT orconf */
-{yygotominor.yy186 = yymsp[0].minor.yy186;}
- break;
- case 176: /* insert_cmd ::= REPLACE */
-{yygotominor.yy186 = OE_Replace;}
- break;
- case 177: /* itemlist ::= itemlist COMMA expr */
- case 241: /* nexprlist ::= nexprlist COMMA expr */ yytestcase(yyruleno==241);
-{yygotominor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy14,yymsp[0].minor.yy346.pExpr);}
- break;
- case 178: /* itemlist ::= expr */
- case 242: /* nexprlist ::= expr */ yytestcase(yyruleno==242);
-{yygotominor.yy14 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy346.pExpr);}
- break;
- case 181: /* inscollist ::= inscollist COMMA nm */
-{yygotominor.yy408 = sqlite3IdListAppend(pParse->db,yymsp[-2].minor.yy408,&yymsp[0].minor.yy0);}
- break;
- case 182: /* inscollist ::= nm */
-{yygotominor.yy408 = sqlite3IdListAppend(pParse->db,0,&yymsp[0].minor.yy0);}
- break;
- case 183: /* expr ::= term */
- case 211: /* escape ::= ESCAPE expr */ yytestcase(yyruleno==211);
-{yygotominor.yy346 = yymsp[0].minor.yy346;}
- break;
- case 184: /* expr ::= LP expr RP */
-{yygotominor.yy346.pExpr = yymsp[-1].minor.yy346.pExpr; spanSet(&yygotominor.yy346,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0);}
- break;
- case 185: /* term ::= NULL */
- case 190: /* term ::= INTEGER|FLOAT|BLOB */ yytestcase(yyruleno==190);
- case 191: /* term ::= STRING */ yytestcase(yyruleno==191);
-{spanExpr(&yygotominor.yy346, pParse, yymsp[0].major, &yymsp[0].minor.yy0);}
- break;
- case 186: /* expr ::= id */
- case 187: /* expr ::= JOIN_KW */ yytestcase(yyruleno==187);
-{spanExpr(&yygotominor.yy346, pParse, TK_ID, &yymsp[0].minor.yy0);}
- break;
- case 188: /* expr ::= nm DOT nm */
-{
- Expr *temp1 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-2].minor.yy0);
- Expr *temp2 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[0].minor.yy0);
- yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp2, 0);
- spanSet(&yygotominor.yy346,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0);
-}
- break;
- case 189: /* expr ::= nm DOT nm DOT nm */
-{
- Expr *temp1 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-4].minor.yy0);
- Expr *temp2 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-2].minor.yy0);
- Expr *temp3 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[0].minor.yy0);
- Expr *temp4 = sqlite3PExpr(pParse, TK_DOT, temp2, temp3, 0);
- yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp4, 0);
- spanSet(&yygotominor.yy346,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0);
-}
- break;
- case 192: /* expr ::= REGISTER */
-{
- /* When doing a nested parse, one can include terms in an expression
- ** that look like this: #1 #2 ... These terms refer to registers
- ** in the virtual machine. #N is the N-th register. */
- if( pParse->nested==0 ){
- sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &yymsp[0].minor.yy0);
- yygotominor.yy346.pExpr = 0;
- }else{
- yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_REGISTER, 0, 0, &yymsp[0].minor.yy0);
- if( yygotominor.yy346.pExpr ) sqlite3GetInt32(&yymsp[0].minor.yy0.z[1], &yygotominor.yy346.pExpr->iTable);
- }
- spanSet(&yygotominor.yy346, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0);
-}
- break;
- case 193: /* expr ::= VARIABLE */
-{
- spanExpr(&yygotominor.yy346, pParse, TK_VARIABLE, &yymsp[0].minor.yy0);
- sqlite3ExprAssignVarNumber(pParse, yygotominor.yy346.pExpr);
- spanSet(&yygotominor.yy346, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0);
-}
- break;
- case 194: /* expr ::= expr COLLATE ids */
-{
- yygotominor.yy346.pExpr = sqlite3ExprSetColl(pParse, yymsp[-2].minor.yy346.pExpr, &yymsp[0].minor.yy0);
- yygotominor.yy346.zStart = yymsp[-2].minor.yy346.zStart;
- yygotominor.yy346.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
-}
- break;
- case 195: /* expr ::= CAST LP expr AS typetoken RP */
-{
- yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_CAST, yymsp[-3].minor.yy346.pExpr, 0, &yymsp[-1].minor.yy0);
- spanSet(&yygotominor.yy346,&yymsp[-5].minor.yy0,&yymsp[0].minor.yy0);
-}
- break;
- case 196: /* expr ::= ID LP distinct exprlist RP */
-{
- if( yymsp[-1].minor.yy14 && yymsp[-1].minor.yy14->nExpr>pParse->db->aLimit[SQLITE_LIMIT_FUNCTION_ARG] ){
- sqlite3ErrorMsg(pParse, "too many arguments on function %T", &yymsp[-4].minor.yy0);
- }
- yygotominor.yy346.pExpr = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy14, &yymsp[-4].minor.yy0);
- spanSet(&yygotominor.yy346,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0);
- if( yymsp[-2].minor.yy328 && yygotominor.yy346.pExpr ){
- yygotominor.yy346.pExpr->flags |= EP_Distinct;
- }
-}
- break;
- case 197: /* expr ::= ID LP STAR RP */
-{
- yygotominor.yy346.pExpr = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0);
- spanSet(&yygotominor.yy346,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0);
-}
- break;
- case 198: /* term ::= CTIME_KW */
-{
- /* The CURRENT_TIME, CURRENT_DATE, and CURRENT_TIMESTAMP values are
- ** treated as functions that return constants */
- yygotominor.yy346.pExpr = sqlite3ExprFunction(pParse, 0,&yymsp[0].minor.yy0);
- if( yygotominor.yy346.pExpr ){
- yygotominor.yy346.pExpr->op = TK_CONST_FUNC;
- }
- spanSet(&yygotominor.yy346, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0);
-}
- break;
- case 199: /* expr ::= expr AND expr */
- case 200: /* expr ::= expr OR expr */ yytestcase(yyruleno==200);
- case 201: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==201);
- case 202: /* expr ::= expr EQ|NE expr */ yytestcase(yyruleno==202);
- case 203: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ yytestcase(yyruleno==203);
- case 204: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==204);
- case 205: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==205);
- case 206: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==206);
-{spanBinaryExpr(&yygotominor.yy346,pParse,yymsp[-1].major,&yymsp[-2].minor.yy346,&yymsp[0].minor.yy346);}
- break;
- case 207: /* likeop ::= LIKE_KW */
- case 209: /* likeop ::= MATCH */ yytestcase(yyruleno==209);
-{yygotominor.yy96.eOperator = yymsp[0].minor.yy0; yygotominor.yy96.not = 0;}
- break;
- case 208: /* likeop ::= NOT LIKE_KW */
- case 210: /* likeop ::= NOT MATCH */ yytestcase(yyruleno==210);
-{yygotominor.yy96.eOperator = yymsp[0].minor.yy0; yygotominor.yy96.not = 1;}
- break;
- case 212: /* escape ::= */
-{memset(&yygotominor.yy346,0,sizeof(yygotominor.yy346));}
- break;
- case 213: /* expr ::= expr likeop expr escape */
-{
- ExprList *pList;
- pList = sqlite3ExprListAppend(pParse,0, yymsp[-1].minor.yy346.pExpr);
- pList = sqlite3ExprListAppend(pParse,pList, yymsp[-3].minor.yy346.pExpr);
- if( yymsp[0].minor.yy346.pExpr ){
- pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy346.pExpr);
- }
- yygotominor.yy346.pExpr = sqlite3ExprFunction(pParse, pList, &yymsp[-2].minor.yy96.eOperator);
- if( yymsp[-2].minor.yy96.not ) yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy346.pExpr, 0, 0);
- yygotominor.yy346.zStart = yymsp[-3].minor.yy346.zStart;
- yygotominor.yy346.zEnd = yymsp[-1].minor.yy346.zEnd;
- if( yygotominor.yy346.pExpr ) yygotominor.yy346.pExpr->flags |= EP_InfixFunc;
-}
- break;
- case 214: /* expr ::= expr ISNULL|NOTNULL */
-{spanUnaryPostfix(&yygotominor.yy346,pParse,yymsp[0].major,&yymsp[-1].minor.yy346,&yymsp[0].minor.yy0);}
- break;
- case 215: /* expr ::= expr IS NULL */
-{spanUnaryPostfix(&yygotominor.yy346,pParse,TK_ISNULL,&yymsp[-2].minor.yy346,&yymsp[0].minor.yy0);}
- break;
- case 216: /* expr ::= expr NOT NULL */
-{spanUnaryPostfix(&yygotominor.yy346,pParse,TK_NOTNULL,&yymsp[-2].minor.yy346,&yymsp[0].minor.yy0);}
- break;
- case 217: /* expr ::= expr IS NOT NULL */
-{spanUnaryPostfix(&yygotominor.yy346,pParse,TK_NOTNULL,&yymsp[-3].minor.yy346,&yymsp[0].minor.yy0);}
- break;
- case 218: /* expr ::= NOT expr */
- case 219: /* expr ::= BITNOT expr */ yytestcase(yyruleno==219);
-{spanUnaryPrefix(&yygotominor.yy346,pParse,yymsp[-1].major,&yymsp[0].minor.yy346,&yymsp[-1].minor.yy0);}
- break;
- case 220: /* expr ::= MINUS expr */
-{spanUnaryPrefix(&yygotominor.yy346,pParse,TK_UMINUS,&yymsp[0].minor.yy346,&yymsp[-1].minor.yy0);}
- break;
- case 221: /* expr ::= PLUS expr */
-{spanUnaryPrefix(&yygotominor.yy346,pParse,TK_UPLUS,&yymsp[0].minor.yy346,&yymsp[-1].minor.yy0);}
- break;
- case 224: /* expr ::= expr between_op expr AND expr */
-{
- ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy346.pExpr);
- pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy346.pExpr);
- yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy346.pExpr, 0, 0);
- if( yygotominor.yy346.pExpr ){
- yygotominor.yy346.pExpr->x.pList = pList;
- }else{
- sqlite3ExprListDelete(pParse->db, pList);
- }
- if( yymsp[-3].minor.yy328 ) yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy346.pExpr, 0, 0);
- yygotominor.yy346.zStart = yymsp[-4].minor.yy346.zStart;
- yygotominor.yy346.zEnd = yymsp[0].minor.yy346.zEnd;
-}
- break;
- case 227: /* expr ::= expr in_op LP exprlist RP */
-{
- yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy346.pExpr, 0, 0);
- if( yygotominor.yy346.pExpr ){
- yygotominor.yy346.pExpr->x.pList = yymsp[-1].minor.yy14;
- sqlite3ExprSetHeight(pParse, yygotominor.yy346.pExpr);
- }else{
- sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy14);
- }
- if( yymsp[-3].minor.yy328 ) yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy346.pExpr, 0, 0);
- yygotominor.yy346.zStart = yymsp[-4].minor.yy346.zStart;
- yygotominor.yy346.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
- }
- break;
- case 228: /* expr ::= LP select RP */
-{
- yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_SELECT, 0, 0, 0);
- if( yygotominor.yy346.pExpr ){
- yygotominor.yy346.pExpr->x.pSelect = yymsp[-1].minor.yy3;
- ExprSetProperty(yygotominor.yy346.pExpr, EP_xIsSelect);
- sqlite3ExprSetHeight(pParse, yygotominor.yy346.pExpr);
- }else{
- sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy3);
- }
- yygotominor.yy346.zStart = yymsp[-2].minor.yy0.z;
- yygotominor.yy346.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
- }
- break;
- case 229: /* expr ::= expr in_op LP select RP */
-{
- yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy346.pExpr, 0, 0);
- if( yygotominor.yy346.pExpr ){
- yygotominor.yy346.pExpr->x.pSelect = yymsp[-1].minor.yy3;
- ExprSetProperty(yygotominor.yy346.pExpr, EP_xIsSelect);
- sqlite3ExprSetHeight(pParse, yygotominor.yy346.pExpr);
- }else{
- sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy3);
- }
- if( yymsp[-3].minor.yy328 ) yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy346.pExpr, 0, 0);
- yygotominor.yy346.zStart = yymsp[-4].minor.yy346.zStart;
- yygotominor.yy346.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
- }
- break;
- case 230: /* expr ::= expr in_op nm dbnm */
-{
- SrcList *pSrc = sqlite3SrcListAppend(pParse->db, 0,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0);
- yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-3].minor.yy346.pExpr, 0, 0);
- if( yygotominor.yy346.pExpr ){
- yygotominor.yy346.pExpr->x.pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0,0);
- ExprSetProperty(yygotominor.yy346.pExpr, EP_xIsSelect);
- sqlite3ExprSetHeight(pParse, yygotominor.yy346.pExpr);
- }else{
- sqlite3SrcListDelete(pParse->db, pSrc);
- }
- if( yymsp[-2].minor.yy328 ) yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy346.pExpr, 0, 0);
- yygotominor.yy346.zStart = yymsp[-3].minor.yy346.zStart;
- yygotominor.yy346.zEnd = yymsp[0].minor.yy0.z ? &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] : &yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n];
- }
- break;
- case 231: /* expr ::= EXISTS LP select RP */
-{
- Expr *p = yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_EXISTS, 0, 0, 0);
- if( p ){
- p->x.pSelect = yymsp[-1].minor.yy3;
- ExprSetProperty(p, EP_xIsSelect);
- sqlite3ExprSetHeight(pParse, p);
- }else{
- sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy3);
- }
- yygotominor.yy346.zStart = yymsp[-3].minor.yy0.z;
- yygotominor.yy346.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
- }
- break;
- case 232: /* expr ::= CASE case_operand case_exprlist case_else END */
-{
- yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy132, yymsp[-1].minor.yy132, 0);
- if( yygotominor.yy346.pExpr ){
- yygotominor.yy346.pExpr->x.pList = yymsp[-2].minor.yy14;
- sqlite3ExprSetHeight(pParse, yygotominor.yy346.pExpr);
- }else{
- sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy14);
- }
- yygotominor.yy346.zStart = yymsp[-4].minor.yy0.z;
- yygotominor.yy346.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
-}
- break;
- case 233: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */
-{
- yygotominor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy14, yymsp[-2].minor.yy346.pExpr);
- yygotominor.yy14 = sqlite3ExprListAppend(pParse,yygotominor.yy14, yymsp[0].minor.yy346.pExpr);
-}
- break;
- case 234: /* case_exprlist ::= WHEN expr THEN expr */
-{
- yygotominor.yy14 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy346.pExpr);
- yygotominor.yy14 = sqlite3ExprListAppend(pParse,yygotominor.yy14, yymsp[0].minor.yy346.pExpr);
-}
- break;
- case 243: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP idxlist RP */
-{
- sqlite3CreateIndex(pParse, &yymsp[-6].minor.yy0, &yymsp[-5].minor.yy0,
- sqlite3SrcListAppend(pParse->db,0,&yymsp[-3].minor.yy0,0), yymsp[-1].minor.yy14, yymsp[-9].minor.yy328,
- &yymsp[-10].minor.yy0, &yymsp[0].minor.yy0, SQLITE_SO_ASC, yymsp[-7].minor.yy328);
-}
- break;
- case 244: /* uniqueflag ::= UNIQUE */
- case 298: /* raisetype ::= ABORT */ yytestcase(yyruleno==298);
-{yygotominor.yy328 = OE_Abort;}
- break;
- case 245: /* uniqueflag ::= */
-{yygotominor.yy328 = OE_None;}
- break;
- case 248: /* idxlist ::= idxlist COMMA nm collate sortorder */
-{
- Expr *p = 0;
- if( yymsp[-1].minor.yy0.n>0 ){
- p = sqlite3Expr(pParse->db, TK_COLUMN, 0);
- sqlite3ExprSetColl(pParse, p, &yymsp[-1].minor.yy0);
- }
- yygotominor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy14, p);
- sqlite3ExprListSetName(pParse,yygotominor.yy14,&yymsp[-2].minor.yy0,1);
- sqlite3ExprListCheckLength(pParse, yygotominor.yy14, "index");
- if( yygotominor.yy14 ) yygotominor.yy14->a[yygotominor.yy14->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy328;
-}
- break;
- case 249: /* idxlist ::= nm collate sortorder */
-{
- Expr *p = 0;
- if( yymsp[-1].minor.yy0.n>0 ){
- p = sqlite3PExpr(pParse, TK_COLUMN, 0, 0, 0);
- sqlite3ExprSetColl(pParse, p, &yymsp[-1].minor.yy0);
- }
- yygotominor.yy14 = sqlite3ExprListAppend(pParse,0, p);
- sqlite3ExprListSetName(pParse, yygotominor.yy14, &yymsp[-2].minor.yy0, 1);
- sqlite3ExprListCheckLength(pParse, yygotominor.yy14, "index");
- if( yygotominor.yy14 ) yygotominor.yy14->a[yygotominor.yy14->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy328;
-}
- break;
- case 250: /* collate ::= */
-{yygotominor.yy0.z = 0; yygotominor.yy0.n = 0;}
- break;
- case 252: /* cmd ::= DROP INDEX ifexists fullname */
-{sqlite3DropIndex(pParse, yymsp[0].minor.yy65, yymsp[-1].minor.yy328);}
- break;
- case 253: /* cmd ::= VACUUM */
- case 254: /* cmd ::= VACUUM nm */ yytestcase(yyruleno==254);
-{sqlite3Vacuum(pParse);}
- break;
- case 255: /* cmd ::= PRAGMA nm dbnm */
-{sqlite3Pragma(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0,0);}
- break;
- case 256: /* cmd ::= PRAGMA nm dbnm EQ nmnum */
-{sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,0);}
- break;
- case 257: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */
-{sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,0);}
- break;
- case 258: /* cmd ::= PRAGMA nm dbnm EQ minus_num */
-{sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,1);}
- break;
- case 259: /* cmd ::= PRAGMA nm dbnm LP minus_num RP */
-{sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,1);}
- break;
- case 270: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
-{
- Token all;
- all.z = yymsp[-3].minor.yy0.z;
- all.n = (int)(yymsp[0].minor.yy0.z - yymsp[-3].minor.yy0.z) + yymsp[0].minor.yy0.n;
- sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy473, &all);
-}
- break;
- case 271: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
-{
- sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy328, yymsp[-4].minor.yy378.a, yymsp[-4].minor.yy378.b, yymsp[-2].minor.yy65, yymsp[0].minor.yy132, yymsp[-10].minor.yy328, yymsp[-8].minor.yy328);
- yygotominor.yy0 = (yymsp[-6].minor.yy0.n==0?yymsp[-7].minor.yy0:yymsp[-6].minor.yy0);
-}
- break;
- case 272: /* trigger_time ::= BEFORE */
- case 275: /* trigger_time ::= */ yytestcase(yyruleno==275);
-{ yygotominor.yy328 = TK_BEFORE; }
- break;
- case 273: /* trigger_time ::= AFTER */
-{ yygotominor.yy328 = TK_AFTER; }
- break;
- case 274: /* trigger_time ::= INSTEAD OF */
-{ yygotominor.yy328 = TK_INSTEAD;}
- break;
- case 276: /* trigger_event ::= DELETE|INSERT */
- case 277: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==277);
-{yygotominor.yy378.a = yymsp[0].major; yygotominor.yy378.b = 0;}
- break;
- case 278: /* trigger_event ::= UPDATE OF inscollist */
-{yygotominor.yy378.a = TK_UPDATE; yygotominor.yy378.b = yymsp[0].minor.yy408;}
- break;
- case 281: /* when_clause ::= */
- case 303: /* key_opt ::= */ yytestcase(yyruleno==303);
-{ yygotominor.yy132 = 0; }
- break;
- case 282: /* when_clause ::= WHEN expr */
- case 304: /* key_opt ::= KEY expr */ yytestcase(yyruleno==304);
-{ yygotominor.yy132 = yymsp[0].minor.yy346.pExpr; }
- break;
- case 283: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
-{
- assert( yymsp[-2].minor.yy473!=0 );
- yymsp[-2].minor.yy473->pLast->pNext = yymsp[-1].minor.yy473;
- yymsp[-2].minor.yy473->pLast = yymsp[-1].minor.yy473;
- yygotominor.yy473 = yymsp[-2].minor.yy473;
-}
- break;
- case 284: /* trigger_cmd_list ::= trigger_cmd SEMI */
-{
- assert( yymsp[-1].minor.yy473!=0 );
- yymsp[-1].minor.yy473->pLast = yymsp[-1].minor.yy473;
- yygotominor.yy473 = yymsp[-1].minor.yy473;
-}
- break;
- case 286: /* trnm ::= nm DOT nm */
-{
- yygotominor.yy0 = yymsp[0].minor.yy0;
- sqlite3ErrorMsg(pParse,
- "qualified table names are not allowed on INSERT, UPDATE, and DELETE "
- "statements within triggers");
-}
- break;
- case 288: /* tridxby ::= INDEXED BY nm */
-{
- sqlite3ErrorMsg(pParse,
- "the INDEXED BY clause is not allowed on UPDATE or DELETE statements "
- "within triggers");
-}
- break;
- case 289: /* tridxby ::= NOT INDEXED */
-{
- sqlite3ErrorMsg(pParse,
- "the NOT INDEXED clause is not allowed on UPDATE or DELETE statements "
- "within triggers");
-}
- break;
- case 290: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt */
-{ yygotominor.yy473 = sqlite3TriggerUpdateStep(pParse->db, &yymsp[-4].minor.yy0, yymsp[-1].minor.yy14, yymsp[0].minor.yy132, yymsp[-5].minor.yy186); }
- break;
- case 291: /* trigger_cmd ::= insert_cmd INTO trnm inscollist_opt VALUES LP itemlist RP */
-{yygotominor.yy473 = sqlite3TriggerInsertStep(pParse->db, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy408, yymsp[-1].minor.yy14, 0, yymsp[-7].minor.yy186);}
- break;
- case 292: /* trigger_cmd ::= insert_cmd INTO trnm inscollist_opt select */
-{yygotominor.yy473 = sqlite3TriggerInsertStep(pParse->db, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy408, 0, yymsp[0].minor.yy3, yymsp[-4].minor.yy186);}
- break;
- case 293: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt */
-{yygotominor.yy473 = sqlite3TriggerDeleteStep(pParse->db, &yymsp[-2].minor.yy0, yymsp[0].minor.yy132);}
- break;
- case 294: /* trigger_cmd ::= select */
-{yygotominor.yy473 = sqlite3TriggerSelectStep(pParse->db, yymsp[0].minor.yy3); }
- break;
- case 295: /* expr ::= RAISE LP IGNORE RP */
-{
- yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_RAISE, 0, 0, 0);
- if( yygotominor.yy346.pExpr ){
- yygotominor.yy346.pExpr->affinity = OE_Ignore;
- }
- yygotominor.yy346.zStart = yymsp[-3].minor.yy0.z;
- yygotominor.yy346.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
-}
- break;
- case 296: /* expr ::= RAISE LP raisetype COMMA nm RP */
-{
- yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_RAISE, 0, 0, &yymsp[-1].minor.yy0);
- if( yygotominor.yy346.pExpr ) {
- yygotominor.yy346.pExpr->affinity = (char)yymsp[-3].minor.yy328;
- }
- yygotominor.yy346.zStart = yymsp[-5].minor.yy0.z;
- yygotominor.yy346.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
-}
- break;
- case 297: /* raisetype ::= ROLLBACK */
-{yygotominor.yy328 = OE_Rollback;}
- break;
- case 299: /* raisetype ::= FAIL */
-{yygotominor.yy328 = OE_Fail;}
- break;
- case 300: /* cmd ::= DROP TRIGGER ifexists fullname */
-{
- sqlite3DropTrigger(pParse,yymsp[0].minor.yy65,yymsp[-1].minor.yy328);
-}
- break;
- case 301: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
-{
- sqlite3Attach(pParse, yymsp[-3].minor.yy346.pExpr, yymsp[-1].minor.yy346.pExpr, yymsp[0].minor.yy132);
-}
- break;
- case 302: /* cmd ::= DETACH database_kw_opt expr */
-{
- sqlite3Detach(pParse, yymsp[0].minor.yy346.pExpr);
-}
- break;
- case 307: /* cmd ::= REINDEX */
-{sqlite3Reindex(pParse, 0, 0);}
- break;
- case 308: /* cmd ::= REINDEX nm dbnm */
-{sqlite3Reindex(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);}
- break;
- case 309: /* cmd ::= ANALYZE */
-{sqlite3Analyze(pParse, 0, 0);}
- break;
- case 310: /* cmd ::= ANALYZE nm dbnm */
-{sqlite3Analyze(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);}
- break;
- case 311: /* cmd ::= ALTER TABLE fullname RENAME TO nm */
-{
- sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy65,&yymsp[0].minor.yy0);
-}
- break;
- case 312: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt column */
-{
- sqlite3AlterFinishAddColumn(pParse, &yymsp[0].minor.yy0);
-}
- break;
- case 313: /* add_column_fullname ::= fullname */
-{
- pParse->db->lookaside.bEnabled = 0;
- sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy65);
-}
- break;
- case 316: /* cmd ::= create_vtab */
-{sqlite3VtabFinishParse(pParse,0);}
- break;
- case 317: /* cmd ::= create_vtab LP vtabarglist RP */
-{sqlite3VtabFinishParse(pParse,&yymsp[0].minor.yy0);}
- break;
- case 318: /* create_vtab ::= createkw VIRTUAL TABLE nm dbnm USING nm */
-{
- sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0);
-}
- break;
- case 321: /* vtabarg ::= */
-{sqlite3VtabArgInit(pParse);}
- break;
- case 323: /* vtabargtoken ::= ANY */
- case 324: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==324);
- case 325: /* lp ::= LP */ yytestcase(yyruleno==325);
-{sqlite3VtabArgExtend(pParse,&yymsp[0].minor.yy0);}
- break;
- default:
- /* (0) input ::= cmdlist */ yytestcase(yyruleno==0);
- /* (1) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==1);
- /* (2) cmdlist ::= ecmd */ yytestcase(yyruleno==2);
- /* (3) ecmd ::= SEMI */ yytestcase(yyruleno==3);
- /* (4) ecmd ::= explain cmdx SEMI */ yytestcase(yyruleno==4);
- /* (10) trans_opt ::= */ yytestcase(yyruleno==10);
- /* (11) trans_opt ::= TRANSACTION */ yytestcase(yyruleno==11);
- /* (12) trans_opt ::= TRANSACTION nm */ yytestcase(yyruleno==12);
- /* (20) savepoint_opt ::= SAVEPOINT */ yytestcase(yyruleno==20);
- /* (21) savepoint_opt ::= */ yytestcase(yyruleno==21);
- /* (25) cmd ::= create_table create_table_args */ yytestcase(yyruleno==25);
- /* (34) columnlist ::= columnlist COMMA column */ yytestcase(yyruleno==34);
- /* (35) columnlist ::= column */ yytestcase(yyruleno==35);
- /* (44) type ::= */ yytestcase(yyruleno==44);
- /* (51) signed ::= plus_num */ yytestcase(yyruleno==51);
- /* (52) signed ::= minus_num */ yytestcase(yyruleno==52);
- /* (53) carglist ::= carglist carg */ yytestcase(yyruleno==53);
- /* (54) carglist ::= */ yytestcase(yyruleno==54);
- /* (55) carg ::= CONSTRAINT nm ccons */ yytestcase(yyruleno==55);
- /* (56) carg ::= ccons */ yytestcase(yyruleno==56);
- /* (62) ccons ::= NULL onconf */ yytestcase(yyruleno==62);
- /* (89) conslist ::= conslist COMMA tcons */ yytestcase(yyruleno==89);
- /* (90) conslist ::= conslist tcons */ yytestcase(yyruleno==90);
- /* (91) conslist ::= tcons */ yytestcase(yyruleno==91);
- /* (92) tcons ::= CONSTRAINT nm */ yytestcase(yyruleno==92);
- /* (268) plus_opt ::= PLUS */ yytestcase(yyruleno==268);
- /* (269) plus_opt ::= */ yytestcase(yyruleno==269);
- /* (279) foreach_clause ::= */ yytestcase(yyruleno==279);
- /* (280) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==280);
- /* (287) tridxby ::= */ yytestcase(yyruleno==287);
- /* (305) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==305);
- /* (306) database_kw_opt ::= */ yytestcase(yyruleno==306);
- /* (314) kwcolumn_opt ::= */ yytestcase(yyruleno==314);
- /* (315) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==315);
- /* (319) vtabarglist ::= vtabarg */ yytestcase(yyruleno==319);
- /* (320) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==320);
- /* (322) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==322);
- /* (326) anylist ::= */ yytestcase(yyruleno==326);
- /* (327) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==327);
- /* (328) anylist ::= anylist ANY */ yytestcase(yyruleno==328);
- break;
- };
- yygoto = yyRuleInfo[yyruleno].lhs;
- yysize = yyRuleInfo[yyruleno].nrhs;
- yypParser->yyidx -= yysize;
- yyact = yy_find_reduce_action(yymsp[-yysize].stateno,(YYCODETYPE)yygoto);
- if( yyact < YYNSTATE ){
-#ifdef NDEBUG
- /* If we are not debugging and the reduce action popped at least
- ** one element off the stack, then we can push the new element back
- ** onto the stack here, and skip the stack overflow test in yy_shift().
- ** That gives a significant speed improvement. */
- if( yysize ){
- yypParser->yyidx++;
- yymsp -= yysize-1;
- yymsp->stateno = (YYACTIONTYPE)yyact;
- yymsp->major = (YYCODETYPE)yygoto;
- yymsp->minor = yygotominor;
- }else
-#endif
- {
- yy_shift(yypParser,yyact,yygoto,&yygotominor);
- }
- }else{
- assert( yyact == YYNSTATE + YYNRULE + 1 );
- yy_accept(yypParser);
- }
-}
-
-/*
-** The following code executes when the parse fails
-*/
-#ifndef YYNOERRORRECOVERY
-static void yy_parse_failed(
- yyParser *yypParser /* The parser */
-){
- sqlite3ParserARG_FETCH;
-#ifndef NDEBUG
- if( yyTraceFILE ){
- fprintf(yyTraceFILE,"%sFail!\n",yyTracePrompt);
- }
-#endif
- while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser);
- /* Here code is inserted which will be executed whenever the
- ** parser fails */
- sqlite3ParserARG_STORE; /* Suppress warning about unused %extra_argument variable */
-}
-#endif /* YYNOERRORRECOVERY */
-
-/*
-** The following code executes when a syntax error first occurs.
-*/
-static void yy_syntax_error(
- yyParser *yypParser, /* The parser */
- int yymajor, /* The major type of the error token */
- YYMINORTYPE yyminor /* The minor type of the error token */
-){
- sqlite3ParserARG_FETCH;
-#define TOKEN (yyminor.yy0)
-
- 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;
- sqlite3ParserARG_STORE; /* Suppress warning about unused %extra_argument variable */
-}
-
-/*
-** The following is executed when the parser accepts
-*/
-static void yy_accept(
- yyParser *yypParser /* The parser */
-){
- sqlite3ParserARG_FETCH;
-#ifndef NDEBUG
- if( yyTraceFILE ){
- fprintf(yyTraceFILE,"%sAccept!\n",yyTracePrompt);
- }
-#endif
- while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser);
- /* Here code is inserted which will be executed whenever the
- ** parser accepts */
- sqlite3ParserARG_STORE; /* Suppress warning about unused %extra_argument variable */
-}
-
-/* The main parser program.
-** The first argument is a pointer to a structure obtained from
-** "sqlite3ParserAlloc" which describes the current state of the parser.
-** The second argument is the major token number. The third is
-** the minor token. The fourth optional argument is whatever the
-** user wants (and specified in the grammar) and is available for
-** use by the action routines.
-**
-** Inputs:
-** <ul>
-** <li> A pointer to the parser (an opaque structure.)
-** <li> The major token number.
-** <li> The minor token number.
-** <li> An option argument of a grammar-specified type.
-** </ul>
-**
-** Outputs:
-** None.
-*/
-SQLITE_PRIVATE void sqlite3Parser(
- void *yyp, /* The parser */
- int yymajor, /* The major token code number */
- sqlite3ParserTOKENTYPE yyminor /* The value for the token */
- sqlite3ParserARG_PDECL /* Optional %extra_argument parameter */
-){
- YYMINORTYPE yyminorunion;
- int yyact; /* The parser action. */
- int yyendofinput; /* True if we are at the end of input */
-#ifdef YYERRORSYMBOL
- int yyerrorhit = 0; /* True if yymajor has invoked an error */
-#endif
- yyParser *yypParser; /* The parser */
-
- /* (re)initialize the parser, if necessary */
- yypParser = (yyParser*)yyp;
- if( yypParser->yyidx<0 ){
-#if YYSTACKDEPTH<=0
- if( yypParser->yystksz <=0 ){
- /*memset(&yyminorunion, 0, sizeof(yyminorunion));*/
- yyminorunion = yyzerominor;
- yyStackOverflow(yypParser, &yyminorunion);
- return;
- }
-#endif
- yypParser->yyidx = 0;
- yypParser->yyerrcnt = -1;
- yypParser->yystack[0].stateno = 0;
- yypParser->yystack[0].major = 0;
- }
- yyminorunion.yy0 = yyminor;
- yyendofinput = (yymajor==0);
- sqlite3ParserARG_STORE;
-
-#ifndef NDEBUG
- if( yyTraceFILE ){
- fprintf(yyTraceFILE,"%sInput %s\n",yyTracePrompt,yyTokenName[yymajor]);
- }
-#endif
-
- do{
- yyact = yy_find_shift_action(yypParser,(YYCODETYPE)yymajor);
- if( yyact<YYNSTATE ){
- assert( !yyendofinput ); /* Impossible to shift the $ token */
- yy_shift(yypParser,yyact,yymajor,&yyminorunion);
- yypParser->yyerrcnt--;
- yymajor = YYNOCODE;
- }else if( yyact < YYNSTATE + YYNRULE ){
- yy_reduce(yypParser,yyact-YYNSTATE);
- }else{
- assert( yyact == YY_ERROR_ACTION );
-#ifdef YYERRORSYMBOL
- int yymx;
-#endif
-#ifndef NDEBUG
- if( yyTraceFILE ){
- fprintf(yyTraceFILE,"%sSyntax Error!\n",yyTracePrompt);
- }
-#endif
-#ifdef YYERRORSYMBOL
- /* A syntax error has occurred.
- ** The response to an error depends upon whether or not the
- ** grammar defines an error token "ERROR".
- **
- ** This is what we do if the grammar does define ERROR:
- **
- ** * Call the %syntax_error function.
- **
- ** * Begin popping the stack until we enter a state where
- ** it is legal to shift the error symbol, then shift
- ** the error symbol.
- **
- ** * Set the error count to three.
- **
- ** * Begin accepting and shifting new tokens. No new error
- ** processing will occur until three tokens have been
- ** shifted successfully.
- **
- */
- if( yypParser->yyerrcnt<0 ){
- yy_syntax_error(yypParser,yymajor,yyminorunion);
- }
- yymx = yypParser->yystack[yypParser->yyidx].major;
- if( yymx==YYERRORSYMBOL || yyerrorhit ){
-#ifndef NDEBUG
- if( yyTraceFILE ){
- fprintf(yyTraceFILE,"%sDiscard input token %s\n",
- yyTracePrompt,yyTokenName[yymajor]);
- }
-#endif
- yy_destructor(yypParser, (YYCODETYPE)yymajor,&yyminorunion);
- yymajor = YYNOCODE;
- }else{
- while(
- yypParser->yyidx >= 0 &&
- yymx != YYERRORSYMBOL &&
- (yyact = yy_find_reduce_action(
- yypParser->yystack[yypParser->yyidx].stateno,
- YYERRORSYMBOL)) >= YYNSTATE
- ){
- yy_pop_parser_stack(yypParser);
- }
- if( yypParser->yyidx < 0 || yymajor==0 ){
- yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion);
- yy_parse_failed(yypParser);
- yymajor = YYNOCODE;
- }else if( yymx!=YYERRORSYMBOL ){
- YYMINORTYPE u2;
- u2.YYERRSYMDT = 0;
- yy_shift(yypParser,yyact,YYERRORSYMBOL,&u2);
- }
- }
- yypParser->yyerrcnt = 3;
- yyerrorhit = 1;
-#elif defined(YYNOERRORRECOVERY)
- /* If the YYNOERRORRECOVERY macro is defined, then do not attempt to
- ** do any kind of error recovery. Instead, simply invoke the syntax
- ** error routine and continue going as if nothing had happened.
- **
- ** Applications can set this macro (for example inside %include) if
- ** they intend to abandon the parse upon the first syntax error seen.
- */
- yy_syntax_error(yypParser,yymajor,yyminorunion);
- yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion);
- yymajor = YYNOCODE;
-
-#else /* YYERRORSYMBOL is not defined */
- /* This is what we do if the grammar does not define ERROR:
- **
- ** * Report an error message, and throw away the input token.
- **
- ** * If the input token is $, then fail the parse.
- **
- ** As before, subsequent error messages are suppressed until
- ** three input tokens have been successfully shifted.
- */
- if( yypParser->yyerrcnt<=0 ){
- yy_syntax_error(yypParser,yymajor,yyminorunion);
- }
- yypParser->yyerrcnt = 3;
- yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion);
- if( yyendofinput ){
- yy_parse_failed(yypParser);
- }
- yymajor = YYNOCODE;
-#endif
- }
- }while( yymajor!=YYNOCODE && yypParser->yyidx>=0 );
- return;
-}
-
-/************** End of parse.c ***********************************************/
-/************** Begin file tokenize.c ****************************************/
-/*
-** 2001 September 15
-**
-** 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.
-**
-*************************************************************************
-** An tokenizer for SQL
-**
-** This file contains C code that splits an SQL input string up into
-** individual tokens and sends those tokens one-by-one over to the
-** parser for analysis.
-**
-** $Id: tokenize.c,v 1.163 2009/07/03 22:54:37 drh Exp $
-*/
-
-/*
-** The charMap() macro maps alphabetic characters into their
-** lower-case ASCII equivalent. On ASCII machines, this is just
-** an upper-to-lower case map. On EBCDIC machines we also need
-** to adjust the encoding. Only alphabetic characters and underscores
-** need to be translated.
-*/
-#ifdef SQLITE_ASCII
-# define charMap(X) sqlite3UpperToLower[(unsigned char)X]
-#endif
-#ifdef SQLITE_EBCDIC
-# define charMap(X) ebcdicToAscii[(unsigned char)X]
-const unsigned char ebcdicToAscii[] = {
-/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 1x */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 2x */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 3x */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 4x */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 5x */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 95, 0, 0, /* 6x */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 7x */
- 0, 97, 98, 99,100,101,102,103,104,105, 0, 0, 0, 0, 0, 0, /* 8x */
- 0,106,107,108,109,110,111,112,113,114, 0, 0, 0, 0, 0, 0, /* 9x */
- 0, 0,115,116,117,118,119,120,121,122, 0, 0, 0, 0, 0, 0, /* Ax */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* Bx */
- 0, 97, 98, 99,100,101,102,103,104,105, 0, 0, 0, 0, 0, 0, /* Cx */
- 0,106,107,108,109,110,111,112,113,114, 0, 0, 0, 0, 0, 0, /* Dx */
- 0, 0,115,116,117,118,119,120,121,122, 0, 0, 0, 0, 0, 0, /* Ex */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* Fx */
-};
-#endif
-
-/*
-** The sqlite3KeywordCode function looks up an identifier to determine if
-** it is a keyword. If it is a keyword, the token code of that keyword is
-** returned. If the input is not a keyword, TK_ID is returned.
-**
-** The implementation of this routine was generated by a program,
-** mkkeywordhash.h, located in the tool subdirectory of the distribution.
-** The output of the mkkeywordhash.c program is written into a file
-** named keywordhash.h and then included into this source file by
-** the #include below.
-*/
-/************** Include keywordhash.h in the middle of tokenize.c ************/
-/************** Begin file keywordhash.h *************************************/
-/***** This file contains automatically generated code ******
-**
-** The code in this file has been automatically generated by
-**
-** $Header: /home/drh/sqlite/trans/cvs/sqlite/sqlite/tool/mkkeywordhash.c,v 1.38 2009/06/09 14:27:41 drh Exp $
-**
-** The code in this file implements a function that determines whether
-** or not a given identifier is really an SQL keyword. The same thing
-** might be implemented more directly using a hand-written hash table.
-** But by using this automatically generated code, the size of the code
-** is substantially reduced. This is important for embedded applications
-** on platforms with limited memory.
-*/
-/* Hash score: 171 */
-static int keywordCode(const char *z, int n){
- /* zText[] encodes 801 bytes of keywords in 541 bytes */
- /* REINDEXEDESCAPEACHECKEYBEFOREIGNOREGEXPLAINSTEADDATABASELECT */
- /* ABLEFTHENDEFERRABLELSEXCEPTRANSACTIONATURALTERAISEXCLUSIVE */
- /* XISTSAVEPOINTERSECTRIGGEREFERENCESCONSTRAINTOFFSETEMPORARY */
- /* UNIQUERYATTACHAVINGROUPDATEBEGINNERELEASEBETWEENOTNULLIKE */
- /* CASCADELETECASECOLLATECREATECURRENT_DATEDETACHIMMEDIATEJOIN */
- /* SERTMATCHPLANALYZEPRAGMABORTVALUESVIRTUALIMITWHENWHERENAME */
- /* AFTEREPLACEANDEFAULTAUTOINCREMENTCASTCOLUMNCOMMITCONFLICTCROSS */
- /* CURRENT_TIMESTAMPRIMARYDEFERREDISTINCTDROPFAILFROMFULLGLOBYIF */
- /* ISNULLORDERESTRICTOUTERIGHTROLLBACKROWUNIONUSINGVACUUMVIEW */
- /* INITIALLY */
- static const char zText[540] = {
- 'R','E','I','N','D','E','X','E','D','E','S','C','A','P','E','A','C','H',
- 'E','C','K','E','Y','B','E','F','O','R','E','I','G','N','O','R','E','G',
- 'E','X','P','L','A','I','N','S','T','E','A','D','D','A','T','A','B','A',
- 'S','E','L','E','C','T','A','B','L','E','F','T','H','E','N','D','E','F',
- 'E','R','R','A','B','L','E','L','S','E','X','C','E','P','T','R','A','N',
- 'S','A','C','T','I','O','N','A','T','U','R','A','L','T','E','R','A','I',
- 'S','E','X','C','L','U','S','I','V','E','X','I','S','T','S','A','V','E',
- 'P','O','I','N','T','E','R','S','E','C','T','R','I','G','G','E','R','E',
- 'F','E','R','E','N','C','E','S','C','O','N','S','T','R','A','I','N','T',
- 'O','F','F','S','E','T','E','M','P','O','R','A','R','Y','U','N','I','Q',
- 'U','E','R','Y','A','T','T','A','C','H','A','V','I','N','G','R','O','U',
- 'P','D','A','T','E','B','E','G','I','N','N','E','R','E','L','E','A','S',
- 'E','B','E','T','W','E','E','N','O','T','N','U','L','L','I','K','E','C',
- 'A','S','C','A','D','E','L','E','T','E','C','A','S','E','C','O','L','L',
- 'A','T','E','C','R','E','A','T','E','C','U','R','R','E','N','T','_','D',
- 'A','T','E','D','E','T','A','C','H','I','M','M','E','D','I','A','T','E',
- 'J','O','I','N','S','E','R','T','M','A','T','C','H','P','L','A','N','A',
- 'L','Y','Z','E','P','R','A','G','M','A','B','O','R','T','V','A','L','U',
- 'E','S','V','I','R','T','U','A','L','I','M','I','T','W','H','E','N','W',
- 'H','E','R','E','N','A','M','E','A','F','T','E','R','E','P','L','A','C',
- 'E','A','N','D','E','F','A','U','L','T','A','U','T','O','I','N','C','R',
- 'E','M','E','N','T','C','A','S','T','C','O','L','U','M','N','C','O','M',
- 'M','I','T','C','O','N','F','L','I','C','T','C','R','O','S','S','C','U',
- 'R','R','E','N','T','_','T','I','M','E','S','T','A','M','P','R','I','M',
- 'A','R','Y','D','E','F','E','R','R','E','D','I','S','T','I','N','C','T',
- 'D','R','O','P','F','A','I','L','F','R','O','M','F','U','L','L','G','L',
- 'O','B','Y','I','F','I','S','N','U','L','L','O','R','D','E','R','E','S',
- 'T','R','I','C','T','O','U','T','E','R','I','G','H','T','R','O','L','L',
- 'B','A','C','K','R','O','W','U','N','I','O','N','U','S','I','N','G','V',
- 'A','C','U','U','M','V','I','E','W','I','N','I','T','I','A','L','L','Y',
- };
- static const unsigned char aHash[127] = {
- 70, 99, 112, 68, 0, 43, 0, 0, 76, 0, 71, 0, 0,
- 41, 12, 72, 15, 0, 111, 79, 49, 106, 0, 19, 0, 0,
- 116, 0, 114, 109, 0, 22, 87, 0, 9, 0, 0, 64, 65,
- 0, 63, 6, 0, 47, 84, 96, 0, 113, 95, 0, 0, 44,
- 0, 97, 24, 0, 17, 0, 117, 48, 23, 0, 5, 104, 25,
- 90, 0, 0, 119, 100, 55, 118, 52, 7, 50, 0, 85, 0,
- 94, 26, 0, 93, 0, 0, 0, 89, 86, 91, 82, 103, 14,
- 38, 102, 0, 75, 0, 18, 83, 105, 31, 0, 115, 74, 107,
- 57, 45, 78, 0, 0, 88, 39, 0, 110, 0, 35, 0, 0,
- 28, 0, 80, 53, 58, 0, 20, 56, 0, 51,
- };
- static const unsigned char aNext[119] = {
- 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 2, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 32, 21, 0, 0, 0, 42, 3, 46, 0,
- 0, 0, 0, 29, 0, 0, 37, 0, 0, 0, 1, 60, 0,
- 0, 61, 0, 40, 0, 0, 0, 0, 0, 0, 0, 59, 0,
- 0, 0, 0, 30, 54, 16, 33, 10, 0, 0, 0, 0, 0,
- 0, 0, 11, 66, 73, 0, 8, 0, 98, 92, 0, 101, 0,
- 81, 0, 69, 0, 0, 108, 27, 36, 67, 77, 0, 34, 62,
- 0, 0,
- };
- static const unsigned char aLen[119] = {
- 7, 7, 5, 4, 6, 4, 5, 3, 6, 7, 3, 6, 6,
- 7, 7, 3, 8, 2, 6, 5, 4, 4, 3, 10, 4, 6,
- 11, 2, 7, 5, 5, 9, 6, 9, 9, 7, 10, 10, 4,
- 6, 2, 3, 4, 9, 2, 6, 5, 6, 6, 5, 6, 5,
- 5, 7, 7, 7, 3, 4, 4, 7, 3, 6, 4, 7, 6,
- 12, 6, 9, 4, 6, 5, 4, 7, 6, 5, 6, 7, 5,
- 4, 5, 6, 5, 7, 3, 7, 13, 2, 2, 4, 6, 6,
- 8, 5, 17, 12, 7, 8, 8, 2, 4, 4, 4, 4, 4,
- 2, 2, 6, 5, 8, 5, 5, 8, 3, 5, 5, 6, 4,
- 9, 3,
- };
- static const unsigned short int aOffset[119] = {
- 0, 2, 2, 8, 9, 14, 16, 20, 23, 25, 25, 29, 33,
- 36, 41, 46, 48, 53, 54, 59, 62, 65, 67, 69, 78, 81,
- 86, 95, 96, 101, 105, 109, 117, 122, 128, 136, 142, 152, 159,
- 162, 162, 165, 167, 167, 171, 176, 179, 184, 189, 194, 197, 203,
- 206, 210, 217, 223, 223, 226, 229, 233, 234, 238, 244, 248, 255,
- 261, 273, 279, 288, 290, 296, 301, 303, 310, 315, 320, 326, 332,
- 337, 341, 344, 350, 354, 361, 363, 370, 372, 374, 383, 387, 393,
- 399, 407, 412, 412, 428, 435, 442, 443, 450, 454, 458, 462, 466,
- 469, 471, 473, 479, 483, 491, 495, 500, 508, 511, 516, 521, 527,
- 531, 536,
- };
- static const unsigned char aCode[119] = {
- TK_REINDEX, TK_INDEXED, TK_INDEX, TK_DESC, TK_ESCAPE,
- TK_EACH, TK_CHECK, TK_KEY, TK_BEFORE, TK_FOREIGN,
- TK_FOR, TK_IGNORE, TK_LIKE_KW, TK_EXPLAIN, TK_INSTEAD,
- TK_ADD, TK_DATABASE, TK_AS, TK_SELECT, TK_TABLE,
- TK_JOIN_KW, TK_THEN, TK_END, TK_DEFERRABLE, TK_ELSE,
- TK_EXCEPT, TK_TRANSACTION,TK_ON, TK_JOIN_KW, TK_ALTER,
- TK_RAISE, TK_EXCLUSIVE, TK_EXISTS, TK_SAVEPOINT, TK_INTERSECT,
- TK_TRIGGER, TK_REFERENCES, TK_CONSTRAINT, TK_INTO, TK_OFFSET,
- TK_OF, TK_SET, TK_TEMP, TK_TEMP, TK_OR,
- TK_UNIQUE, TK_QUERY, TK_ATTACH, TK_HAVING, TK_GROUP,
- TK_UPDATE, TK_BEGIN, TK_JOIN_KW, TK_RELEASE, TK_BETWEEN,
- TK_NOTNULL, TK_NOT, TK_NULL, TK_LIKE_KW, TK_CASCADE,
- TK_ASC, TK_DELETE, TK_CASE, TK_COLLATE, TK_CREATE,
- TK_CTIME_KW, TK_DETACH, TK_IMMEDIATE, TK_JOIN, TK_INSERT,
- TK_MATCH, TK_PLAN, TK_ANALYZE, TK_PRAGMA, TK_ABORT,
- TK_VALUES, TK_VIRTUAL, TK_LIMIT, TK_WHEN, TK_WHERE,
- TK_RENAME, TK_AFTER, TK_REPLACE, TK_AND, TK_DEFAULT,
- TK_AUTOINCR, TK_TO, TK_IN, TK_CAST, TK_COLUMNKW,
- TK_COMMIT, TK_CONFLICT, TK_JOIN_KW, TK_CTIME_KW, TK_CTIME_KW,
- TK_PRIMARY, TK_DEFERRED, TK_DISTINCT, TK_IS, TK_DROP,
- TK_FAIL, TK_FROM, TK_JOIN_KW, TK_LIKE_KW, TK_BY,
- TK_IF, TK_ISNULL, TK_ORDER, TK_RESTRICT, TK_JOIN_KW,
- TK_JOIN_KW, TK_ROLLBACK, TK_ROW, TK_UNION, TK_USING,
- TK_VACUUM, TK_VIEW, TK_INITIALLY, TK_ALL,
- };
- int h, i;
- if( n<2 ) return TK_ID;
- h = ((charMap(z[0])*4) ^
- (charMap(z[n-1])*3) ^
- n) % 127;
- for(i=((int)aHash[h])-1; i>=0; i=((int)aNext[i])-1){
- if( aLen[i]==n && sqlite3StrNICmp(&zText[aOffset[i]],z,n)==0 ){
- testcase( i==0 ); /* REINDEX */
- testcase( i==1 ); /* INDEXED */
- testcase( i==2 ); /* INDEX */
- testcase( i==3 ); /* DESC */
- testcase( i==4 ); /* ESCAPE */
- testcase( i==5 ); /* EACH */
- testcase( i==6 ); /* CHECK */
- testcase( i==7 ); /* KEY */
- testcase( i==8 ); /* BEFORE */
- testcase( i==9 ); /* FOREIGN */
- testcase( i==10 ); /* FOR */
- testcase( i==11 ); /* IGNORE */
- testcase( i==12 ); /* REGEXP */
- testcase( i==13 ); /* EXPLAIN */
- testcase( i==14 ); /* INSTEAD */
- testcase( i==15 ); /* ADD */
- testcase( i==16 ); /* DATABASE */
- testcase( i==17 ); /* AS */
- testcase( i==18 ); /* SELECT */
- testcase( i==19 ); /* TABLE */
- testcase( i==20 ); /* LEFT */
- testcase( i==21 ); /* THEN */
- testcase( i==22 ); /* END */
- testcase( i==23 ); /* DEFERRABLE */
- testcase( i==24 ); /* ELSE */
- testcase( i==25 ); /* EXCEPT */
- testcase( i==26 ); /* TRANSACTION */
- testcase( i==27 ); /* ON */
- testcase( i==28 ); /* NATURAL */
- testcase( i==29 ); /* ALTER */
- testcase( i==30 ); /* RAISE */
- testcase( i==31 ); /* EXCLUSIVE */
- testcase( i==32 ); /* EXISTS */
- testcase( i==33 ); /* SAVEPOINT */
- testcase( i==34 ); /* INTERSECT */
- testcase( i==35 ); /* TRIGGER */
- testcase( i==36 ); /* REFERENCES */
- testcase( i==37 ); /* CONSTRAINT */
- testcase( i==38 ); /* INTO */
- testcase( i==39 ); /* OFFSET */
- testcase( i==40 ); /* OF */
- testcase( i==41 ); /* SET */
- testcase( i==42 ); /* TEMP */
- testcase( i==43 ); /* TEMPORARY */
- testcase( i==44 ); /* OR */
- testcase( i==45 ); /* UNIQUE */
- testcase( i==46 ); /* QUERY */
- testcase( i==47 ); /* ATTACH */
- testcase( i==48 ); /* HAVING */
- testcase( i==49 ); /* GROUP */
- testcase( i==50 ); /* UPDATE */
- testcase( i==51 ); /* BEGIN */
- testcase( i==52 ); /* INNER */
- testcase( i==53 ); /* RELEASE */
- testcase( i==54 ); /* BETWEEN */
- testcase( i==55 ); /* NOTNULL */
- testcase( i==56 ); /* NOT */
- testcase( i==57 ); /* NULL */
- testcase( i==58 ); /* LIKE */
- testcase( i==59 ); /* CASCADE */
- testcase( i==60 ); /* ASC */
- testcase( i==61 ); /* DELETE */
- testcase( i==62 ); /* CASE */
- testcase( i==63 ); /* COLLATE */
- testcase( i==64 ); /* CREATE */
- testcase( i==65 ); /* CURRENT_DATE */
- testcase( i==66 ); /* DETACH */
- testcase( i==67 ); /* IMMEDIATE */
- testcase( i==68 ); /* JOIN */
- testcase( i==69 ); /* INSERT */
- testcase( i==70 ); /* MATCH */
- testcase( i==71 ); /* PLAN */
- testcase( i==72 ); /* ANALYZE */
- testcase( i==73 ); /* PRAGMA */
- testcase( i==74 ); /* ABORT */
- testcase( i==75 ); /* VALUES */
- testcase( i==76 ); /* VIRTUAL */
- testcase( i==77 ); /* LIMIT */
- testcase( i==78 ); /* WHEN */
- testcase( i==79 ); /* WHERE */
- testcase( i==80 ); /* RENAME */
- testcase( i==81 ); /* AFTER */
- testcase( i==82 ); /* REPLACE */
- testcase( i==83 ); /* AND */
- testcase( i==84 ); /* DEFAULT */
- testcase( i==85 ); /* AUTOINCREMENT */
- testcase( i==86 ); /* TO */
- testcase( i==87 ); /* IN */
- testcase( i==88 ); /* CAST */
- testcase( i==89 ); /* COLUMN */
- testcase( i==90 ); /* COMMIT */
- testcase( i==91 ); /* CONFLICT */
- testcase( i==92 ); /* CROSS */
- testcase( i==93 ); /* CURRENT_TIMESTAMP */
- testcase( i==94 ); /* CURRENT_TIME */
- testcase( i==95 ); /* PRIMARY */
- testcase( i==96 ); /* DEFERRED */
- testcase( i==97 ); /* DISTINCT */
- testcase( i==98 ); /* IS */
- testcase( i==99 ); /* DROP */
- testcase( i==100 ); /* FAIL */
- testcase( i==101 ); /* FROM */
- testcase( i==102 ); /* FULL */
- testcase( i==103 ); /* GLOB */
- testcase( i==104 ); /* BY */
- testcase( i==105 ); /* IF */
- testcase( i==106 ); /* ISNULL */
- testcase( i==107 ); /* ORDER */
- testcase( i==108 ); /* RESTRICT */
- testcase( i==109 ); /* OUTER */
- testcase( i==110 ); /* RIGHT */
- testcase( i==111 ); /* ROLLBACK */
- testcase( i==112 ); /* ROW */
- testcase( i==113 ); /* UNION */
- testcase( i==114 ); /* USING */
- testcase( i==115 ); /* VACUUM */
- testcase( i==116 ); /* VIEW */
- testcase( i==117 ); /* INITIALLY */
- testcase( i==118 ); /* ALL */
- return aCode[i];
- }
- }
- return TK_ID;
-}
-SQLITE_PRIVATE int sqlite3KeywordCode(const unsigned char *z, int n){
- return keywordCode((char*)z, n);
-}
-
-/************** End of keywordhash.h *****************************************/
-/************** Continuing where we left off in tokenize.c *******************/
-
-
-/*
-** If X is a character that can be used in an identifier then
-** IdChar(X) will be true. Otherwise it is false.
-**
-** For ASCII, any character with the high-order bit set is
-** allowed in an identifier. For 7-bit characters,
-** sqlite3IsIdChar[X] must be 1.
-**
-** For EBCDIC, the rules are more complex but have the same
-** end result.
-**
-** Ticket #1066. the SQL standard does not allow '$' in the
-** middle of identfiers. But many SQL implementations do.
-** SQLite will allow '$' in identifiers for compatibility.
-** But the feature is undocumented.
-*/
-#ifdef SQLITE_ASCII
-SQLITE_PRIVATE const char sqlite3IsAsciiIdChar[] = {
-/* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF */
- 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 2x */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 3x */
- 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 4x */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, /* 5x */
- 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 6x */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* 7x */
-};
-#define IdChar(C) (((c=C)&0x80)!=0 || (c>0x1f && sqlite3IsAsciiIdChar[c-0x20]))
-#endif
-#ifdef SQLITE_EBCDIC
-SQLITE_PRIVATE const char sqlite3IsEbcdicIdChar[] = {
-/* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF */
- 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 4x */
- 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, /* 5x */
- 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, /* 6x */
- 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, /* 7x */
- 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, /* 8x */
- 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, /* 9x */
- 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, /* Ax */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* Bx */
- 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, /* Cx */
- 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, /* Dx */
- 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, /* Ex */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, /* Fx */
-};
-#define IdChar(C) (((c=C)>=0x42 && sqlite3IsEbcdicIdChar[c-0x40]))
-#endif
-
-
-/*
-** Return the length of the token that begins at z[0].
-** Store the token type in *tokenType before returning.
-*/
-SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *z, int *tokenType){
- int i, c;
- switch( *z ){
- case ' ': case '\t': case '\n': case '\f': case '\r': {
- testcase( z[0]==' ' );
- testcase( z[0]=='\t' );
- testcase( z[0]=='\n' );
- testcase( z[0]=='\f' );
- testcase( z[0]=='\r' );
- for(i=1; sqlite3Isspace(z[i]); i++){}
- *tokenType = TK_SPACE;
- return i;
- }
- case '-': {
- if( z[1]=='-' ){
- for(i=2; (c=z[i])!=0 && c!='\n'; i++){}
- *tokenType = TK_SPACE;
- return i;
- }
- *tokenType = TK_MINUS;
- return 1;
- }
- case '(': {
- *tokenType = TK_LP;
- return 1;
- }
- case ')': {
- *tokenType = TK_RP;
- return 1;
- }
- case ';': {
- *tokenType = TK_SEMI;
- return 1;
- }
- case '+': {
- *tokenType = TK_PLUS;
- return 1;
- }
- case '*': {
- *tokenType = TK_STAR;
- return 1;
- }
- case '/': {
- if( z[1]!='*' || z[2]==0 ){
- *tokenType = TK_SLASH;
- return 1;
- }
- for(i=3, c=z[2]; (c!='*' || z[i]!='/') && (c=z[i])!=0; i++){}
- if( c ) i++;
- *tokenType = TK_SPACE;
- return i;
- }
- case '%': {
- *tokenType = TK_REM;
- return 1;
- }
- case '=': {
- *tokenType = TK_EQ;
- return 1 + (z[1]=='=');
- }
- case '<': {
- if( (c=z[1])=='=' ){
- *tokenType = TK_LE;
- return 2;
- }else if( c=='>' ){
- *tokenType = TK_NE;
- return 2;
- }else if( c=='<' ){
- *tokenType = TK_LSHIFT;
- return 2;
- }else{
- *tokenType = TK_LT;
- return 1;
- }
- }
- case '>': {
- if( (c=z[1])=='=' ){
- *tokenType = TK_GE;
- return 2;
- }else if( c=='>' ){
- *tokenType = TK_RSHIFT;
- return 2;
- }else{
- *tokenType = TK_GT;
- return 1;
- }
- }
- case '!': {
- if( z[1]!='=' ){
- *tokenType = TK_ILLEGAL;
- return 2;
- }else{
- *tokenType = TK_NE;
- return 2;
- }
- }
- case '|': {
- if( z[1]!='|' ){
- *tokenType = TK_BITOR;
- return 1;
- }else{
- *tokenType = TK_CONCAT;
- return 2;
- }
- }
- case ',': {
- *tokenType = TK_COMMA;
- return 1;
- }
- case '&': {
- *tokenType = TK_BITAND;
- return 1;
- }
- case '~': {
- *tokenType = TK_BITNOT;
- return 1;
- }
- case '`':
- case '\'':
- case '"': {
- int delim = z[0];
- testcase( delim=='`' );
- testcase( delim=='\'' );
- testcase( delim=='"' );
- for(i=1; (c=z[i])!=0; i++){
- if( c==delim ){
- if( z[i+1]==delim ){
- i++;
- }else{
- break;
- }
- }
- }
- if( c=='\'' ){
- *tokenType = TK_STRING;
- return i+1;
- }else if( c!=0 ){
- *tokenType = TK_ID;
- return i+1;
- }else{
- *tokenType = TK_ILLEGAL;
- return i;
- }
- }
- case '.': {
-#ifndef SQLITE_OMIT_FLOATING_POINT
- if( !sqlite3Isdigit(z[1]) )
-#endif
- {
- *tokenType = TK_DOT;
- return 1;
- }
- /* If the next character is a digit, this is a floating point
- ** number that begins with ".". Fall thru into the next case */
- }
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9': {
- testcase( z[0]=='0' ); testcase( z[0]=='1' ); testcase( z[0]=='2' );
- testcase( z[0]=='3' ); testcase( z[0]=='4' ); testcase( z[0]=='5' );
- testcase( z[0]=='6' ); testcase( z[0]=='7' ); testcase( z[0]=='8' );
- testcase( z[0]=='9' );
- *tokenType = TK_INTEGER;
- for(i=0; sqlite3Isdigit(z[i]); i++){}
-#ifndef SQLITE_OMIT_FLOATING_POINT
- if( z[i]=='.' ){
- i++;
- while( sqlite3Isdigit(z[i]) ){ i++; }
- *tokenType = TK_FLOAT;
- }
- if( (z[i]=='e' || z[i]=='E') &&
- ( sqlite3Isdigit(z[i+1])
- || ((z[i+1]=='+' || z[i+1]=='-') && sqlite3Isdigit(z[i+2]))
- )
- ){
- i += 2;
- while( sqlite3Isdigit(z[i]) ){ i++; }
- *tokenType = TK_FLOAT;
- }
-#endif
- while( IdChar(z[i]) ){
- *tokenType = TK_ILLEGAL;
- i++;
- }
- return i;
- }
- case '[': {
- for(i=1, c=z[0]; c!=']' && (c=z[i])!=0; i++){}
- *tokenType = c==']' ? TK_ID : TK_ILLEGAL;
- return i;
- }
- case '?': {
- *tokenType = TK_VARIABLE;
- for(i=1; sqlite3Isdigit(z[i]); i++){}
- return i;
- }
- case '#': {
- for(i=1; sqlite3Isdigit(z[i]); i++){}
- if( i>1 ){
- /* Parameters of the form #NNN (where NNN is a number) are used
- ** internally by sqlite3NestedParse. */
- *tokenType = TK_REGISTER;
- return i;
- }
- /* Fall through into the next case if the '#' is not followed by
- ** a digit. Try to match #AAAA where AAAA is a parameter name. */
- }
-#ifndef SQLITE_OMIT_TCL_VARIABLE
- case '$':
-#endif
- case '@': /* For compatibility with MS SQL Server */
- case ':': {
- int n = 0;
- testcase( z[0]=='$' ); testcase( z[0]=='@' ); testcase( z[0]==':' );
- *tokenType = TK_VARIABLE;
- for(i=1; (c=z[i])!=0; i++){
- if( IdChar(c) ){
- n++;
-#ifndef SQLITE_OMIT_TCL_VARIABLE
- }else if( c=='(' && n>0 ){
- do{
- i++;
- }while( (c=z[i])!=0 && !sqlite3Isspace(c) && c!=')' );
- if( c==')' ){
- i++;
- }else{
- *tokenType = TK_ILLEGAL;
- }
- break;
- }else if( c==':' && z[i+1]==':' ){
- i++;
-#endif
- }else{
- break;
- }
- }
- if( n==0 ) *tokenType = TK_ILLEGAL;
- return i;
- }
-#ifndef SQLITE_OMIT_BLOB_LITERAL
- case 'x': case 'X': {
- testcase( z[0]=='x' ); testcase( z[0]=='X' );
- if( z[1]=='\'' ){
- *tokenType = TK_BLOB;
- for(i=2; (c=z[i])!=0 && c!='\''; i++){
- if( !sqlite3Isxdigit(c) ){
- *tokenType = TK_ILLEGAL;
- }
- }
- if( i%2 || !c ) *tokenType = TK_ILLEGAL;
- if( c ) i++;
- return i;
- }
- /* Otherwise fall through to the next case */
- }
-#endif
- default: {
- if( !IdChar(*z) ){
- break;
- }
- for(i=1; IdChar(z[i]); i++){}
- *tokenType = keywordCode((char*)z, i);
- return i;
- }
- }
- *tokenType = TK_ILLEGAL;
- return 1;
-}
-
-/*
-** Run the parser on the given SQL string. The parser structure is
-** passed in. An SQLITE_ status code is returned. If an error occurs
-** then an and attempt is made to write an error message into
-** memory obtained from sqlite3_malloc() and to make *pzErrMsg point to that
-** error message.
-*/
-SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){
- int nErr = 0; /* Number of errors encountered */
- int i; /* Loop counter */
- void *pEngine; /* The LEMON-generated LALR(1) parser */
- int tokenType; /* type of the next token */
- int lastTokenParsed = -1; /* type of the previous token */
- u8 enableLookaside; /* Saved value of db->lookaside.bEnabled */
- sqlite3 *db = pParse->db; /* The database connection */
- int mxSqlLen; /* Max length of an SQL string */
-
-
- mxSqlLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH];
- if( db->activeVdbeCnt==0 ){
- db->u1.isInterrupted = 0;
- }
- pParse->rc = SQLITE_OK;
- pParse->zTail = zSql;
- i = 0;
- assert( pzErrMsg!=0 );
- pEngine = sqlite3ParserAlloc((void*(*)(size_t))sqlite3Malloc);
- if( pEngine==0 ){
- db->mallocFailed = 1;
- return SQLITE_NOMEM;
- }
- assert( pParse->pNewTable==0 );
- assert( pParse->pNewTrigger==0 );
- assert( pParse->nVar==0 );
- assert( pParse->nVarExpr==0 );
- assert( pParse->nVarExprAlloc==0 );
- assert( pParse->apVarExpr==0 );
- enableLookaside = db->lookaside.bEnabled;
- if( db->lookaside.pStart ) db->lookaside.bEnabled = 1;
- while( !db->mallocFailed && zSql[i]!=0 ){
- assert( i>=0 );
- pParse->sLastToken.z = &zSql[i];
- pParse->sLastToken.n = sqlite3GetToken((unsigned char*)&zSql[i],&tokenType);
- i += pParse->sLastToken.n;
- if( i>mxSqlLen ){
- pParse->rc = SQLITE_TOOBIG;
- break;
- }
- switch( tokenType ){
- case TK_SPACE: {
- if( db->u1.isInterrupted ){
- sqlite3ErrorMsg(pParse, "interrupt");
- pParse->rc = SQLITE_INTERRUPT;
- goto abort_parse;
- }
- break;
- }
- case TK_ILLEGAL: {
- sqlite3DbFree(db, *pzErrMsg);
- *pzErrMsg = sqlite3MPrintf(db, "unrecognized token: \"%T\"",
- &pParse->sLastToken);
- nErr++;
- goto abort_parse;
- }
- case TK_SEMI: {
- pParse->zTail = &zSql[i];
- /* Fall thru into the default case */
- }
- default: {
- sqlite3Parser(pEngine, tokenType, pParse->sLastToken, pParse);
- lastTokenParsed = tokenType;
- if( pParse->rc!=SQLITE_OK ){
- goto abort_parse;
- }
- break;
- }
- }
- }
-abort_parse:
- if( zSql[i]==0 && nErr==0 && pParse->rc==SQLITE_OK ){
- if( lastTokenParsed!=TK_SEMI ){
- sqlite3Parser(pEngine, TK_SEMI, pParse->sLastToken, pParse);
- pParse->zTail = &zSql[i];
- }
- sqlite3Parser(pEngine, 0, pParse->sLastToken, pParse);
- }
-#ifdef YYTRACKMAXSTACKDEPTH
- sqlite3StatusSet(SQLITE_STATUS_PARSER_STACK,
- sqlite3ParserStackPeak(pEngine)
- );
-#endif /* YYDEBUG */
- sqlite3ParserFree(pEngine, sqlite3_free);
- db->lookaside.bEnabled = enableLookaside;
- if( db->mallocFailed ){
- pParse->rc = SQLITE_NOMEM;
- }
- if( pParse->rc!=SQLITE_OK && pParse->rc!=SQLITE_DONE && pParse->zErrMsg==0 ){
- sqlite3SetString(&pParse->zErrMsg, db, "%s", sqlite3ErrStr(pParse->rc));
- }
- assert( pzErrMsg!=0 );
- if( pParse->zErrMsg ){
- *pzErrMsg = pParse->zErrMsg;
- pParse->zErrMsg = 0;
- nErr++;
- }
- if( pParse->pVdbe && pParse->nErr>0 && pParse->nested==0 ){
- sqlite3VdbeDelete(pParse->pVdbe);
- pParse->pVdbe = 0;
- }
-#ifndef SQLITE_OMIT_SHARED_CACHE
- if( pParse->nested==0 ){
- sqlite3DbFree(db, pParse->aTableLock);
- pParse->aTableLock = 0;
- pParse->nTableLock = 0;
- }
-#endif
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- sqlite3DbFree(db, pParse->apVtabLock);
-#endif
-
- if( !IN_DECLARE_VTAB ){
- /* If the pParse->declareVtab flag is set, do not delete any table
- ** structure built up in pParse->pNewTable. The calling code (see vtab.c)
- ** will take responsibility for freeing the Table structure.
- */
- sqlite3DeleteTable(pParse->pNewTable);
- }
-
- sqlite3DeleteTrigger(db, pParse->pNewTrigger);
- sqlite3DbFree(db, pParse->apVarExpr);
- sqlite3DbFree(db, pParse->aAlias);
- while( pParse->pAinc ){
- AutoincInfo *p = pParse->pAinc;
- pParse->pAinc = p->pNext;
- sqlite3DbFree(db, p);
- }
- while( pParse->pZombieTab ){
- Table *p = pParse->pZombieTab;
- pParse->pZombieTab = p->pNextZombie;
- sqlite3DeleteTable(p);
- }
- if( nErr>0 && pParse->rc==SQLITE_OK ){
- pParse->rc = SQLITE_ERROR;
- }
- return nErr;
-}
-
-/************** End of tokenize.c ********************************************/
-/************** Begin file complete.c ****************************************/
-/*
-** 2001 September 15
-**
-** 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.
-**
-*************************************************************************
-** An tokenizer for SQL
-**
-** This file contains C code that implements the sqlite3_complete() API.
-** This code used to be part of the tokenizer.c source file. But by
-** separating it out, the code will be automatically omitted from
-** static links that do not use it.
-**
-** $Id: complete.c,v 1.8 2009/04/28 04:46:42 drh Exp $
-*/
-#ifndef SQLITE_OMIT_COMPLETE
-
-/*
-** This is defined in tokenize.c. We just have to import the definition.
-*/
-#ifndef SQLITE_AMALGAMATION
-#ifdef SQLITE_ASCII
-SQLITE_PRIVATE const char sqlite3IsAsciiIdChar[];
-#define IdChar(C) (((c=C)&0x80)!=0 || (c>0x1f && sqlite3IsAsciiIdChar[c-0x20]))
-#endif
-#ifdef SQLITE_EBCDIC
-SQLITE_PRIVATE const char sqlite3IsEbcdicIdChar[];
-#define IdChar(C) (((c=C)>=0x42 && sqlite3IsEbcdicIdChar[c-0x40]))
-#endif
-#endif /* SQLITE_AMALGAMATION */
-
-
-/*
-** Token types used by the sqlite3_complete() routine. See the header
-** comments on that procedure for additional information.
-*/
-#define tkSEMI 0
-#define tkWS 1
-#define tkOTHER 2
-#define tkEXPLAIN 3
-#define tkCREATE 4
-#define tkTEMP 5
-#define tkTRIGGER 6
-#define tkEND 7
-
-/*
-** Return TRUE if the given SQL string ends in a semicolon.
-**
-** Special handling is require for CREATE TRIGGER statements.
-** Whenever the CREATE TRIGGER keywords are seen, the statement
-** must end with ";END;".
-**
-** This implementation uses a state machine with 7 states:
-**
-** (0) START At the beginning or end of an SQL statement. This routine
-** returns 1 if it ends in the START state and 0 if it ends
-** in any other state.
-**
-** (1) NORMAL We are in the middle of statement which ends with a single
-** semicolon.
-**
-** (2) EXPLAIN The keyword EXPLAIN has been seen at the beginning of
-** a statement.
-**
-** (3) CREATE The keyword CREATE has been seen at the beginning of a
-** statement, possibly preceeded by EXPLAIN and/or followed by
-** TEMP or TEMPORARY
-**
-** (4) TRIGGER We are in the middle of a trigger definition that must be
-** ended by a semicolon, the keyword END, and another semicolon.
-**
-** (5) SEMI We've seen the first semicolon in the ";END;" that occurs at
-** the end of a trigger definition.
-**
-** (6) END We've seen the ";END" of the ";END;" that occurs at the end
-** of a trigger difinition.
-**
-** Transitions between states above are determined by tokens extracted
-** from the input. The following tokens are significant:
-**
-** (0) tkSEMI A semicolon.
-** (1) tkWS Whitespace
-** (2) tkOTHER Any other SQL token.
-** (3) tkEXPLAIN The "explain" keyword.
-** (4) tkCREATE The "create" keyword.
-** (5) tkTEMP The "temp" or "temporary" keyword.
-** (6) tkTRIGGER The "trigger" keyword.
-** (7) tkEND The "end" keyword.
-**
-** Whitespace never causes a state transition and is always ignored.
-**
-** If we compile with SQLITE_OMIT_TRIGGER, all of the computation needed
-** to recognize the end of a trigger can be omitted. All we have to do
-** is look for a semicolon that is not part of an string or comment.
-*/
-SQLITE_API int sqlite3_complete(const char *zSql){
- u8 state = 0; /* Current state, using numbers defined in header comment */
- u8 token; /* Value of the next token */
-
-#ifndef SQLITE_OMIT_TRIGGER
- /* A complex statement machine used to detect the end of a CREATE TRIGGER
- ** statement. This is the normal case.
- */
- static const u8 trans[7][8] = {
- /* Token: */
- /* State: ** SEMI WS OTHER EXPLAIN CREATE TEMP TRIGGER END */
- /* 0 START: */ { 0, 0, 1, 2, 3, 1, 1, 1, },
- /* 1 NORMAL: */ { 0, 1, 1, 1, 1, 1, 1, 1, },
- /* 2 EXPLAIN: */ { 0, 2, 2, 1, 3, 1, 1, 1, },
- /* 3 CREATE: */ { 0, 3, 1, 1, 1, 3, 4, 1, },
- /* 4 TRIGGER: */ { 5, 4, 4, 4, 4, 4, 4, 4, },
- /* 5 SEMI: */ { 5, 5, 4, 4, 4, 4, 4, 6, },
- /* 6 END: */ { 0, 6, 4, 4, 4, 4, 4, 4, },
- };
-#else
- /* If triggers are not suppored by this compile then the statement machine
- ** used to detect the end of a statement is much simplier
- */
- static const u8 trans[2][3] = {
- /* Token: */
- /* State: ** SEMI WS OTHER */
- /* 0 START: */ { 0, 0, 1, },
- /* 1 NORMAL: */ { 0, 1, 1, },
- };
-#endif /* SQLITE_OMIT_TRIGGER */
-
- while( *zSql ){
- switch( *zSql ){
- case ';': { /* A semicolon */
- token = tkSEMI;
- break;
- }
- case ' ':
- case '\r':
- case '\t':
- case '\n':
- case '\f': { /* White space is ignored */
- token = tkWS;
- break;
- }
- case '/': { /* C-style comments */
- if( zSql[1]!='*' ){
- token = tkOTHER;
- break;
- }
- zSql += 2;
- while( zSql[0] && (zSql[0]!='*' || zSql[1]!='/') ){ zSql++; }
- if( zSql[0]==0 ) return 0;
- zSql++;
- token = tkWS;
- break;
- }
- case '-': { /* SQL-style comments from "--" to end of line */
- if( zSql[1]!='-' ){
- token = tkOTHER;
- break;
- }
- while( *zSql && *zSql!='\n' ){ zSql++; }
- if( *zSql==0 ) return state==0;
- token = tkWS;
- break;
- }
- case '[': { /* Microsoft-style identifiers in [...] */
- zSql++;
- while( *zSql && *zSql!=']' ){ zSql++; }
- if( *zSql==0 ) return 0;
- token = tkOTHER;
- break;
- }
- case '`': /* Grave-accent quoted symbols used by MySQL */
- case '"': /* single- and double-quoted strings */
- case '\'': {
- int c = *zSql;
- zSql++;
- while( *zSql && *zSql!=c ){ zSql++; }
- if( *zSql==0 ) return 0;
- token = tkOTHER;
- break;
- }
- default: {
- int c;
- if( IdChar((u8)*zSql) ){
- /* Keywords and unquoted identifiers */
- int nId;
- for(nId=1; IdChar(zSql[nId]); nId++){}
-#ifdef SQLITE_OMIT_TRIGGER
- token = tkOTHER;
-#else
- switch( *zSql ){
- case 'c': case 'C': {
- if( nId==6 && sqlite3StrNICmp(zSql, "create", 6)==0 ){
- token = tkCREATE;
- }else{
- token = tkOTHER;
- }
- break;
- }
- case 't': case 'T': {
- if( nId==7 && sqlite3StrNICmp(zSql, "trigger", 7)==0 ){
- token = tkTRIGGER;
- }else if( nId==4 && sqlite3StrNICmp(zSql, "temp", 4)==0 ){
- token = tkTEMP;
- }else if( nId==9 && sqlite3StrNICmp(zSql, "temporary", 9)==0 ){
- token = tkTEMP;
- }else{
- token = tkOTHER;
- }
- break;
- }
- case 'e': case 'E': {
- if( nId==3 && sqlite3StrNICmp(zSql, "end", 3)==0 ){
- token = tkEND;
- }else
-#ifndef SQLITE_OMIT_EXPLAIN
- if( nId==7 && sqlite3StrNICmp(zSql, "explain", 7)==0 ){
- token = tkEXPLAIN;
- }else
-#endif
- {
- token = tkOTHER;
- }
- break;
- }
- default: {
- token = tkOTHER;
- break;
- }
- }
-#endif /* SQLITE_OMIT_TRIGGER */
- zSql += nId-1;
- }else{
- /* Operators and special symbols */
- token = tkOTHER;
- }
- break;
- }
- }
- state = trans[state][token];
- zSql++;
- }
- return state==0;
-}
-
-#ifndef SQLITE_OMIT_UTF16
-/*
-** This routine is the same as the sqlite3_complete() routine described
-** above, except that the parameter is required to be UTF-16 encoded, not
-** UTF-8.
-*/
-SQLITE_API int sqlite3_complete16(const void *zSql){
- sqlite3_value *pVal;
- char const *zSql8;
- int rc = SQLITE_NOMEM;
-
-#ifndef SQLITE_OMIT_AUTOINIT
- rc = sqlite3_initialize();
- if( rc ) return rc;
-#endif
- pVal = sqlite3ValueNew(0);
- sqlite3ValueSetStr(pVal, -1, zSql, SQLITE_UTF16NATIVE, SQLITE_STATIC);
- zSql8 = sqlite3ValueText(pVal, SQLITE_UTF8);
- if( zSql8 ){
- rc = sqlite3_complete(zSql8);
- }else{
- rc = SQLITE_NOMEM;
- }
- sqlite3ValueFree(pVal);
- return sqlite3ApiExit(0, rc);
-}
-#endif /* SQLITE_OMIT_UTF16 */
-#endif /* SQLITE_OMIT_COMPLETE */
-
-/************** End of complete.c ********************************************/
-/************** Begin file main.c ********************************************/
-/*
-** 2001 September 15
-**
-** 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.
-**
-*************************************************************************
-** Main file for the SQLite library. The routines in this file
-** implement the programmer interface to the library. Routines in
-** other files are for internal use by SQLite and should not be
-** accessed by users of the library.
-*/
-
-#ifdef SQLITE_ENABLE_FTS3
-/************** Include fts3.h in the middle of main.c ***********************/
-/************** Begin file fts3.h ********************************************/
-/*
-** 2006 Oct 10
-**
-** 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 header file is used by programs that want to link against the
-** FTS3 library. All it does is declare the sqlite3Fts3Init() interface.
-*/
-
-#if 0
-extern "C" {
-#endif /* __cplusplus */
-
-SQLITE_PRIVATE int sqlite3Fts3Init(sqlite3 *db);
-
-#if 0
-} /* extern "C" */
-#endif /* __cplusplus */
-
-/************** End of fts3.h ************************************************/
-/************** Continuing where we left off in main.c ***********************/
-#endif
-#ifdef SQLITE_ENABLE_RTREE
-/************** Include rtree.h in the middle of main.c **********************/
-/************** Begin file rtree.h *******************************************/
-/*
-** 2008 May 26
-**
-** 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 header file is used by programs that want to link against the
-** RTREE library. All it does is declare the sqlite3RtreeInit() interface.
-*/
-
-#if 0
-extern "C" {
-#endif /* __cplusplus */
-
-SQLITE_PRIVATE int sqlite3RtreeInit(sqlite3 *db);
-
-#if 0
-} /* extern "C" */
-#endif /* __cplusplus */
-
-/************** End of rtree.h ***********************************************/
-/************** Continuing where we left off in main.c ***********************/
-#endif
-#ifdef SQLITE_ENABLE_ICU
-/************** Include sqliteicu.h in the middle of main.c ******************/
-/************** Begin file sqliteicu.h ***************************************/
-/*
-** 2008 May 26
-**
-** 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 header file is used by programs that want to link against the
-** ICU extension. All it does is declare the sqlite3IcuInit() interface.
-*/
-
-#if 0
-extern "C" {
-#endif /* __cplusplus */
-
-SQLITE_PRIVATE int sqlite3IcuInit(sqlite3 *db);
-
-#if 0
-} /* extern "C" */
-#endif /* __cplusplus */
-
-
-/************** End of sqliteicu.h *******************************************/
-/************** Continuing where we left off in main.c ***********************/
-#endif
-
-/*
-** The version of the library
-*/
-#ifndef SQLITE_AMALGAMATION
-SQLITE_API const char sqlite3_version[] = SQLITE_VERSION;
-#endif
-SQLITE_API const char *sqlite3_libversion(void){ return sqlite3_version; }
-SQLITE_API const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; }
-SQLITE_API int sqlite3_libversion_number(void){ return SQLITE_VERSION_NUMBER; }
-SQLITE_API int sqlite3_threadsafe(void){ return SQLITE_THREADSAFE; }
-
-#if !defined(SQLITE_OMIT_TRACE) && defined(SQLITE_ENABLE_IOTRACE)
-/*
-** If the following function pointer is not NULL and if
-** SQLITE_ENABLE_IOTRACE is enabled, then messages describing
-** I/O active are written using this function. These messages
-** are intended for debugging activity only.
-*/
-SQLITE_PRIVATE void (*sqlite3IoTrace)(const char*, ...) = 0;
-#endif
-
-/*
-** If the following global variable points to a string which is the
-** name of a directory, then that directory will be used to store
-** temporary files.
-**
-** See also the "PRAGMA temp_store_directory" SQL command.
-*/
-SQLITE_API char *sqlite3_temp_directory = 0;
-
-/*
-** Initialize SQLite.
-**
-** This routine must be called to initialize the memory allocation,
-** VFS, and mutex subsystems prior to doing any serious work with
-** SQLite. But as long as you do not compile with SQLITE_OMIT_AUTOINIT
-** this routine will be called automatically by key routines such as
-** sqlite3_open().
-**
-** This routine is a no-op except on its very first call for the process,
-** or for the first call after a call to sqlite3_shutdown.
-**
-** The first thread to call this routine runs the initialization to
-** completion. If subsequent threads call this routine before the first
-** thread has finished the initialization process, then the subsequent
-** threads must block until the first thread finishes with the initialization.
-**
-** The first thread might call this routine recursively. Recursive
-** calls to this routine should not block, of course. Otherwise the
-** initialization process would never complete.
-**
-** Let X be the first thread to enter this routine. Let Y be some other
-** thread. Then while the initial invocation of this routine by X is
-** incomplete, it is required that:
-**
-** * Calls to this routine from Y must block until the outer-most
-** call by X completes.
-**
-** * Recursive calls to this routine from thread X return immediately
-** without blocking.
-*/
-SQLITE_API int sqlite3_initialize(void){
- sqlite3_mutex *pMaster; /* The main static mutex */
- int rc; /* Result code */
-
-#ifdef SQLITE_OMIT_WSD
- rc = sqlite3_wsd_init(4096, 24);
- if( rc!=SQLITE_OK ){
- return rc;
- }
-#endif
-
- /* If SQLite is already completely initialized, then this call
- ** to sqlite3_initialize() should be a no-op. But the initialization
- ** must be complete. So isInit must not be set until the very end
- ** of this routine.
- */
- if( sqlite3GlobalConfig.isInit ) return SQLITE_OK;
-
- /* Make sure the mutex subsystem is initialized. If unable to
- ** initialize the mutex subsystem, return early with the error.
- ** If the system is so sick that we are unable to allocate a mutex,
- ** there is not much SQLite is going to be able to do.
- **
- ** The mutex subsystem must take care of serializing its own
- ** initialization.
- */
- rc = sqlite3MutexInit();
- if( rc ) return rc;
-
- /* Initialize the malloc() system and the recursive pInitMutex mutex.
- ** This operation is protected by the STATIC_MASTER mutex. Note that
- ** MutexAlloc() is called for a static mutex prior to initializing the
- ** malloc subsystem - this implies that the allocation of a static
- ** mutex must not require support from the malloc subsystem.
- */
- pMaster = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
- sqlite3_mutex_enter(pMaster);
- sqlite3GlobalConfig.isMutexInit = 1;
- if( !sqlite3GlobalConfig.isMallocInit ){
- rc = sqlite3MallocInit();
- }
- if( rc==SQLITE_OK ){
- sqlite3GlobalConfig.isMallocInit = 1;
- if( !sqlite3GlobalConfig.pInitMutex ){
- sqlite3GlobalConfig.pInitMutex =
- sqlite3MutexAlloc(SQLITE_MUTEX_RECURSIVE);
- if( sqlite3GlobalConfig.bCoreMutex && !sqlite3GlobalConfig.pInitMutex ){
- rc = SQLITE_NOMEM;
- }
- }
- }
- if( rc==SQLITE_OK ){
- sqlite3GlobalConfig.nRefInitMutex++;
- }
- sqlite3_mutex_leave(pMaster);
-
- /* If rc is not SQLITE_OK at this point, then either the malloc
- ** subsystem could not be initialized or the system failed to allocate
- ** the pInitMutex mutex. Return an error in either case. */
- if( rc!=SQLITE_OK ){
- return rc;
- }
-
- /* Do the rest of the initialization under the recursive mutex so
- ** that we will be able to handle recursive calls into
- ** sqlite3_initialize(). The recursive calls normally come through
- ** sqlite3_os_init() when it invokes sqlite3_vfs_register(), but other
- ** recursive calls might also be possible.
- */
- sqlite3_mutex_enter(sqlite3GlobalConfig.pInitMutex);
- if( sqlite3GlobalConfig.isInit==0 && sqlite3GlobalConfig.inProgress==0 ){
- FuncDefHash *pHash = &GLOBAL(FuncDefHash, sqlite3GlobalFunctions);
- sqlite3GlobalConfig.inProgress = 1;
- memset(pHash, 0, sizeof(sqlite3GlobalFunctions));
- sqlite3RegisterGlobalFunctions();
- if( sqlite3GlobalConfig.isPCacheInit==0 ){
- rc = sqlite3PcacheInitialize();
- }
- if( rc==SQLITE_OK ){
- sqlite3GlobalConfig.isPCacheInit = 1;
- rc = sqlite3OsInit();
- }
- if( rc==SQLITE_OK ){
- sqlite3PCacheBufferSetup( sqlite3GlobalConfig.pPage,
- sqlite3GlobalConfig.szPage, sqlite3GlobalConfig.nPage);
- sqlite3GlobalConfig.isInit = 1;
- }
- sqlite3GlobalConfig.inProgress = 0;
- }
- sqlite3_mutex_leave(sqlite3GlobalConfig.pInitMutex);
-
- /* Go back under the static mutex and clean up the recursive
- ** mutex to prevent a resource leak.
- */
- sqlite3_mutex_enter(pMaster);
- sqlite3GlobalConfig.nRefInitMutex--;
- if( sqlite3GlobalConfig.nRefInitMutex<=0 ){
- assert( sqlite3GlobalConfig.nRefInitMutex==0 );
- sqlite3_mutex_free(sqlite3GlobalConfig.pInitMutex);
- sqlite3GlobalConfig.pInitMutex = 0;
- }
- sqlite3_mutex_leave(pMaster);
-
- /* The following is just a sanity check to make sure SQLite has
- ** been compiled correctly. It is important to run this code, but
- ** we don't want to run it too often and soak up CPU cycles for no
- ** reason. So we run it once during initialization.
- */
-#ifndef NDEBUG
-#ifndef SQLITE_OMIT_FLOATING_POINT
- /* This section of code's only "output" is via assert() statements. */
- if ( rc==SQLITE_OK ){
- u64 x = (((u64)1)<<63)-1;
- double y;
- assert(sizeof(x)==8);
- assert(sizeof(x)==sizeof(y));
- memcpy(&y, &x, 8);
- assert( sqlite3IsNaN(y) );
- }
-#endif
-#endif
-
- return rc;
-}
-
-/*
-** Undo the effects of sqlite3_initialize(). Must not be called while
-** there are outstanding database connections or memory allocations or
-** while any part of SQLite is otherwise in use in any thread. This
-** routine is not threadsafe. But it is safe to invoke this routine
-** on when SQLite is already shut down. If SQLite is already shut down
-** when this routine is invoked, then this routine is a harmless no-op.
-*/
-SQLITE_API int sqlite3_shutdown(void){
- if( sqlite3GlobalConfig.isInit ){
- sqlite3_os_end();
- sqlite3_reset_auto_extension();
- sqlite3GlobalConfig.isInit = 0;
- }
- if( sqlite3GlobalConfig.isPCacheInit ){
- sqlite3PcacheShutdown();
- sqlite3GlobalConfig.isPCacheInit = 0;
- }
- if( sqlite3GlobalConfig.isMallocInit ){
- sqlite3MallocEnd();
- sqlite3GlobalConfig.isMallocInit = 0;
- }
- if( sqlite3GlobalConfig.isMutexInit ){
- sqlite3MutexEnd();
- sqlite3GlobalConfig.isMutexInit = 0;
- }
-
- return SQLITE_OK;
-}
-
-/*
-** This API allows applications to modify the global configuration of
-** the SQLite library at run-time.
-**
-** This routine should only be called when there are no outstanding
-** database connections or memory allocations. This routine is not
-** threadsafe. Failure to heed these warnings can lead to unpredictable
-** behavior.
-*/
-SQLITE_API int sqlite3_config(int op, ...){
- va_list ap;
- int rc = SQLITE_OK;
-
- /* sqlite3_config() shall return SQLITE_MISUSE if it is invoked while
- ** the SQLite library is in use. */
- if( sqlite3GlobalConfig.isInit ) return SQLITE_MISUSE;
-
- va_start(ap, op);
- switch( op ){
-
- /* Mutex configuration options are only available in a threadsafe
- ** compile.
- */
-#if SQLITE_THREADSAFE
- case SQLITE_CONFIG_SINGLETHREAD: {
- /* Disable all mutexing */
- sqlite3GlobalConfig.bCoreMutex = 0;
- sqlite3GlobalConfig.bFullMutex = 0;
- break;
- }
- case SQLITE_CONFIG_MULTITHREAD: {
- /* Disable mutexing of database connections */
- /* Enable mutexing of core data structures */
- sqlite3GlobalConfig.bCoreMutex = 1;
- sqlite3GlobalConfig.bFullMutex = 0;
- break;
- }
- case SQLITE_CONFIG_SERIALIZED: {
- /* Enable all mutexing */
- sqlite3GlobalConfig.bCoreMutex = 1;
- sqlite3GlobalConfig.bFullMutex = 1;
- break;
- }
- case SQLITE_CONFIG_MUTEX: {
- /* Specify an alternative mutex implementation */
- sqlite3GlobalConfig.mutex = *va_arg(ap, sqlite3_mutex_methods*);
- break;
- }
- case SQLITE_CONFIG_GETMUTEX: {
- /* Retrieve the current mutex implementation */
- *va_arg(ap, sqlite3_mutex_methods*) = sqlite3GlobalConfig.mutex;
- break;
- }
-#endif
-
-
- case SQLITE_CONFIG_MALLOC: {
- /* Specify an alternative malloc implementation */
- sqlite3GlobalConfig.m = *va_arg(ap, sqlite3_mem_methods*);
- break;
- }
- case SQLITE_CONFIG_GETMALLOC: {
- /* Retrieve the current malloc() implementation */
- if( sqlite3GlobalConfig.m.xMalloc==0 ) sqlite3MemSetDefault();
- *va_arg(ap, sqlite3_mem_methods*) = sqlite3GlobalConfig.m;
- break;
- }
- case SQLITE_CONFIG_MEMSTATUS: {
- /* Enable or disable the malloc status collection */
- sqlite3GlobalConfig.bMemstat = va_arg(ap, int);
- break;
- }
- case SQLITE_CONFIG_SCRATCH: {
- /* Designate a buffer for scratch memory space */
- sqlite3GlobalConfig.pScratch = va_arg(ap, void*);
- sqlite3GlobalConfig.szScratch = va_arg(ap, int);
- sqlite3GlobalConfig.nScratch = va_arg(ap, int);
- break;
- }
- case SQLITE_CONFIG_PAGECACHE: {
- /* Designate a buffer for page cache memory space */
- sqlite3GlobalConfig.pPage = va_arg(ap, void*);
- sqlite3GlobalConfig.szPage = va_arg(ap, int);
- sqlite3GlobalConfig.nPage = va_arg(ap, int);
- break;
- }
-
- case SQLITE_CONFIG_PCACHE: {
- /* Specify an alternative page cache implementation */
- sqlite3GlobalConfig.pcache = *va_arg(ap, sqlite3_pcache_methods*);
- break;
- }
-
- case SQLITE_CONFIG_GETPCACHE: {
- if( sqlite3GlobalConfig.pcache.xInit==0 ){
- sqlite3PCacheSetDefault();
- }
- *va_arg(ap, sqlite3_pcache_methods*) = sqlite3GlobalConfig.pcache;
- break;
- }
-
-#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
- case SQLITE_CONFIG_HEAP: {
- /* Designate a buffer for heap memory space */
- sqlite3GlobalConfig.pHeap = va_arg(ap, void*);
- sqlite3GlobalConfig.nHeap = va_arg(ap, int);
- sqlite3GlobalConfig.mnReq = va_arg(ap, int);
-
- if( sqlite3GlobalConfig.pHeap==0 ){
- /* If the heap pointer is NULL, then restore the malloc implementation
- ** back to NULL pointers too. This will cause the malloc to go
- ** back to its default implementation when sqlite3_initialize() is
- ** run.
- */
- memset(&sqlite3GlobalConfig.m, 0, sizeof(sqlite3GlobalConfig.m));
- }else{
- /* The heap pointer is not NULL, then install one of the
- ** mem5.c/mem3.c methods. If neither ENABLE_MEMSYS3 nor
- ** ENABLE_MEMSYS5 is defined, return an error.
- */
-#ifdef SQLITE_ENABLE_MEMSYS3
- sqlite3GlobalConfig.m = *sqlite3MemGetMemsys3();
-#endif
-#ifdef SQLITE_ENABLE_MEMSYS5
- sqlite3GlobalConfig.m = *sqlite3MemGetMemsys5();
-#endif
- }
- break;
- }
-#endif
-
- case SQLITE_CONFIG_LOOKASIDE: {
- sqlite3GlobalConfig.szLookaside = va_arg(ap, int);
- sqlite3GlobalConfig.nLookaside = va_arg(ap, int);
- break;
- }
-
- default: {
- rc = SQLITE_ERROR;
- break;
- }
- }
- va_end(ap);
- return rc;
-}
-
-/*
-** Set up the lookaside buffers for a database connection.
-** Return SQLITE_OK on success.
-** If lookaside is already active, return SQLITE_BUSY.
-**
-** The sz parameter is the number of bytes in each lookaside slot.
-** The cnt parameter is the number of slots. If pStart is NULL the
-** space for the lookaside memory is obtained from sqlite3_malloc().
-** If pStart is not NULL then it is sz*cnt bytes of memory to use for
-** the lookaside memory.
-*/
-static int setupLookaside(sqlite3 *db, void *pBuf, int sz, int cnt){
- void *pStart;
- if( db->lookaside.nOut ){
- return SQLITE_BUSY;
- }
- /* Free any existing lookaside buffer for this handle before
- ** allocating a new one so we don't have to have space for
- ** both at the same time.
- */
- 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.
- */
- 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 = ROUND8(sz);
- sqlite3BeginBenignMalloc();
- pStart = sqlite3Malloc( sz*cnt );
- sqlite3EndBenignMalloc();
- }else{
- sz = ROUNDDOWN8(sz);
- pStart = pBuf;
- }
- db->lookaside.pStart = pStart;
- db->lookaside.pFree = 0;
- db->lookaside.sz = (u16)sz;
- if( pStart ){
- int i;
- LookasideSlot *p;
- assert( sz > (int)sizeof(LookasideSlot*) );
- p = (LookasideSlot*)pStart;
- for(i=cnt-1; i>=0; i--){
- p->pNext = db->lookaside.pFree;
- db->lookaside.pFree = p;
- p = (LookasideSlot*)&((u8*)p)[sz];
- }
- db->lookaside.pEnd = p;
- db->lookaside.bEnabled = 1;
- db->lookaside.bMalloced = pBuf==0 ?1:0;
- }else{
- db->lookaside.pEnd = 0;
- db->lookaside.bEnabled = 0;
- db->lookaside.bMalloced = 0;
- }
- return SQLITE_OK;
-}
-
-/*
-** Return the mutex associated with a database connection.
-*/
-SQLITE_API sqlite3_mutex *sqlite3_db_mutex(sqlite3 *db){
- return db->mutex;
-}
-
-/*
-** Configuration settings for an individual database connection
-*/
-SQLITE_API int sqlite3_db_config(sqlite3 *db, int op, ...){
- va_list ap;
- int rc;
- va_start(ap, op);
- switch( op ){
- case SQLITE_DBCONFIG_LOOKASIDE: {
- void *pBuf = va_arg(ap, void*);
- int sz = va_arg(ap, int);
- int cnt = va_arg(ap, int);
- rc = setupLookaside(db, pBuf, sz, cnt);
- break;
- }
- default: {
- rc = SQLITE_ERROR;
- break;
- }
- }
- va_end(ap);
- return rc;
-}
-
-
-/*
-** Return true if the buffer z[0..n-1] contains all spaces.
-*/
-static int allSpaces(const char *z, int n){
- while( n>0 && z[n-1]==' ' ){ n--; }
- return n==0;
-}
-
-/*
-** This is the default collating function named "BINARY" which is always
-** available.
-**
-** If the padFlag argument is not NULL then space padding at the end
-** of strings is ignored. This implements the RTRIM collation.
-*/
-static int binCollFunc(
- void *padFlag,
- int nKey1, const void *pKey1,
- int nKey2, const void *pKey2
-){
- int rc, n;
- n = nKey1<nKey2 ? nKey1 : nKey2;
- rc = memcmp(pKey1, pKey2, n);
- if( rc==0 ){
- if( padFlag
- && allSpaces(((char*)pKey1)+n, nKey1-n)
- && allSpaces(((char*)pKey2)+n, nKey2-n)
- ){
- /* Leave rc unchanged at 0 */
- }else{
- rc = nKey1 - nKey2;
- }
- }
- return rc;
-}
-
-/*
-** Another built-in collating sequence: NOCASE.
-**
-** This collating sequence is intended to be used for "case independant
-** comparison". SQLite's knowledge of upper and lower case equivalents
-** extends only to the 26 characters used in the English language.
-**
-** At the moment there is only a UTF-8 implementation.
-*/
-static int nocaseCollatingFunc(
- void *NotUsed,
- int nKey1, const void *pKey1,
- int nKey2, const void *pKey2
-){
- int r = sqlite3StrNICmp(
- (const char *)pKey1, (const char *)pKey2, (nKey1<nKey2)?nKey1:nKey2);
- UNUSED_PARAMETER(NotUsed);
- if( 0==r ){
- r = nKey1-nKey2;
- }
- return r;
-}
-
-/*
-** Return the ROWID of the most recent insert
-*/
-SQLITE_API sqlite_int64 sqlite3_last_insert_rowid(sqlite3 *db){
- return db->lastRowid;
-}
-
-/*
-** Return the number of changes in the most recent call to sqlite3_exec().
-*/
-SQLITE_API int sqlite3_changes(sqlite3 *db){
- return db->nChange;
-}
-
-/*
-** Return the number of changes since the database handle was opened.
-*/
-SQLITE_API int sqlite3_total_changes(sqlite3 *db){
- return db->nTotalChange;
-}
-
-/*
-** Close all open savepoints. This function only manipulates fields of the
-** database handle object, it does not close any savepoints that may be open
-** at the b-tree/pager level.
-*/
-SQLITE_PRIVATE void sqlite3CloseSavepoints(sqlite3 *db){
- while( db->pSavepoint ){
- Savepoint *pTmp = db->pSavepoint;
- db->pSavepoint = pTmp->pNext;
- sqlite3DbFree(db, pTmp);
- }
- db->nSavepoint = 0;
- db->nStatement = 0;
- db->isTransactionSavepoint = 0;
-}
-
-/*
-** Close an existing SQLite database
-*/
-SQLITE_API int sqlite3_close(sqlite3 *db){
- HashElem *i;
- int j;
-
- if( !db ){
- return SQLITE_OK;
- }
- if( !sqlite3SafetyCheckSickOrOk(db) ){
- return SQLITE_MISUSE;
- }
- sqlite3_mutex_enter(db->mutex);
-
- sqlite3ResetInternalSchema(db, 0);
-
- /* If a transaction is open, the ResetInternalSchema() call above
- ** will not have called the xDisconnect() method on any virtual
- ** tables in the db->aVTrans[] array. The following sqlite3VtabRollback()
- ** call will do so. We need to do this before the check for active
- ** SQL statements below, as the v-table implementation may be storing
- ** some prepared statements internally.
- */
- sqlite3VtabRollback(db);
-
- /* If there are any outstanding VMs, return SQLITE_BUSY. */
- if( db->pVdbe ){
- sqlite3Error(db, SQLITE_BUSY,
- "unable to close due to unfinalised statements");
- sqlite3_mutex_leave(db->mutex);
- return SQLITE_BUSY;
- }
- assert( sqlite3SafetyCheckSickOrOk(db) );
-
- for(j=0; j<db->nDb; j++){
- Btree *pBt = db->aDb[j].pBt;
- if( pBt && sqlite3BtreeIsInBackup(pBt) ){
- sqlite3Error(db, SQLITE_BUSY,
- "unable to close due to unfinished backup operation");
- sqlite3_mutex_leave(db->mutex);
- return SQLITE_BUSY;
- }
- }
-
- /* Free any outstanding Savepoint structures. */
- sqlite3CloseSavepoints(db);
-
- for(j=0; j<db->nDb; j++){
- struct Db *pDb = &db->aDb[j];
- if( pDb->pBt ){
- sqlite3BtreeClose(pDb->pBt);
- pDb->pBt = 0;
- if( j!=1 ){
- pDb->pSchema = 0;
- }
- }
- }
- sqlite3ResetInternalSchema(db, 0);
-
- /* Tell the code in notify.c that the connection no longer holds any
- ** locks and does not require any further unlock-notify callbacks.
- */
- sqlite3ConnectionClosed(db);
-
- assert( db->nDb<=2 );
- assert( db->aDb==db->aDbStatic );
- for(j=0; j<ArraySize(db->aFunc.a); j++){
- FuncDef *pNext, *pHash, *p;
- for(p=db->aFunc.a[j]; p; p=pHash){
- pHash = p->pHash;
- while( p ){
- pNext = p->pNext;
- sqlite3DbFree(db, p);
- p = pNext;
- }
- }
- }
- for(i=sqliteHashFirst(&db->aCollSeq); i; i=sqliteHashNext(i)){
- CollSeq *pColl = (CollSeq *)sqliteHashData(i);
- /* Invoke any destructors registered for collation sequence user data. */
- for(j=0; j<3; j++){
- if( pColl[j].xDel ){
- pColl[j].xDel(pColl[j].pUser);
- }
- }
- sqlite3DbFree(db, pColl);
- }
- sqlite3HashClear(&db->aCollSeq);
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- for(i=sqliteHashFirst(&db->aModule); i; i=sqliteHashNext(i)){
- Module *pMod = (Module *)sqliteHashData(i);
- if( pMod->xDestroy ){
- pMod->xDestroy(pMod->pAux);
- }
- sqlite3DbFree(db, pMod);
- }
- sqlite3HashClear(&db->aModule);
-#endif
-
- sqlite3Error(db, SQLITE_OK, 0); /* Deallocates any cached error strings. */
- if( db->pErr ){
- sqlite3ValueFree(db->pErr);
- }
- sqlite3CloseExtensions(db);
-
- db->magic = SQLITE_MAGIC_ERROR;
-
- /* The temp-database schema is allocated differently from the other schema
- ** objects (using sqliteMalloc() directly, instead of sqlite3BtreeSchema()).
- ** So it needs to be freed here. Todo: Why not roll the temp schema into
- ** the same sqliteMalloc() as the one that allocates the database
- ** structure?
- */
- sqlite3DbFree(db, db->aDb[1].pSchema);
- sqlite3_mutex_leave(db->mutex);
- db->magic = SQLITE_MAGIC_CLOSED;
- sqlite3_mutex_free(db->mutex);
- assert( db->lookaside.nOut==0 ); /* Fails on a lookaside memory leak */
- if( db->lookaside.bMalloced ){
- sqlite3_free(db->lookaside.pStart);
- }
- sqlite3_free(db);
- return SQLITE_OK;
-}
-
-/*
-** Rollback all database files.
-*/
-SQLITE_PRIVATE void sqlite3RollbackAll(sqlite3 *db){
- int i;
- int inTrans = 0;
- assert( sqlite3_mutex_held(db->mutex) );
- sqlite3BeginBenignMalloc();
- for(i=0; i<db->nDb; i++){
- if( db->aDb[i].pBt ){
- if( sqlite3BtreeIsInTrans(db->aDb[i].pBt) ){
- inTrans = 1;
- }
- sqlite3BtreeRollback(db->aDb[i].pBt);
- db->aDb[i].inTrans = 0;
- }
- }
- sqlite3VtabRollback(db);
- sqlite3EndBenignMalloc();
-
- if( db->flags&SQLITE_InternChanges ){
- sqlite3ExpirePreparedStatements(db);
- sqlite3ResetInternalSchema(db, 0);
- }
-
- /* If one has been configured, invoke the rollback-hook callback */
- if( db->xRollbackCallback && (inTrans || !db->autoCommit) ){
- db->xRollbackCallback(db->pRollbackArg);
- }
-}
-
-/*
-** Return a static string that describes the kind of error specified in the
-** argument.
-*/
-SQLITE_PRIVATE const char *sqlite3ErrStr(int rc){
- static const char* const aMsg[] = {
- /* SQLITE_OK */ "not an error",
- /* SQLITE_ERROR */ "SQL logic error or missing database",
- /* SQLITE_INTERNAL */ 0,
- /* SQLITE_PERM */ "access permission denied",
- /* SQLITE_ABORT */ "callback requested query abort",
- /* SQLITE_BUSY */ "database is locked",
- /* SQLITE_LOCKED */ "database table is locked",
- /* SQLITE_NOMEM */ "out of memory",
- /* SQLITE_READONLY */ "attempt to write a readonly database",
- /* SQLITE_INTERRUPT */ "interrupted",
- /* SQLITE_IOERR */ "disk I/O error",
- /* SQLITE_CORRUPT */ "database disk image is malformed",
- /* SQLITE_NOTFOUND */ 0,
- /* SQLITE_FULL */ "database or disk is full",
- /* SQLITE_CANTOPEN */ "unable to open database file",
- /* SQLITE_PROTOCOL */ 0,
- /* SQLITE_EMPTY */ "table contains no data",
- /* SQLITE_SCHEMA */ "database schema has changed",
- /* SQLITE_TOOBIG */ "string or blob too big",
- /* SQLITE_CONSTRAINT */ "constraint failed",
- /* SQLITE_MISMATCH */ "datatype mismatch",
- /* SQLITE_MISUSE */ "library routine called out of sequence",
- /* SQLITE_NOLFS */ "large file support is disabled",
- /* SQLITE_AUTH */ "authorization denied",
- /* SQLITE_FORMAT */ "auxiliary database format error",
- /* SQLITE_RANGE */ "bind or column index out of range",
- /* SQLITE_NOTADB */ "file is encrypted or is not a database",
- };
- rc &= 0xff;
- if( ALWAYS(rc>=0) && rc<(int)(sizeof(aMsg)/sizeof(aMsg[0])) && aMsg[rc]!=0 ){
- return aMsg[rc];
- }else{
- return "unknown error";
- }
-}
-
-/*
-** This routine implements a busy callback that sleeps and tries
-** again until a timeout value is reached. The timeout value is
-** an integer number of milliseconds passed in as the first
-** argument.
-*/
-static int sqliteDefaultBusyCallback(
- void *ptr, /* Database connection */
- int count /* Number of times table has been busy */
-){
-#if SQLITE_OS_WIN || (defined(HAVE_USLEEP) && HAVE_USLEEP)
- static const u8 delays[] =
- { 1, 2, 5, 10, 15, 20, 25, 25, 25, 50, 50, 100 };
- static const u8 totals[] =
- { 0, 1, 3, 8, 18, 33, 53, 78, 103, 128, 178, 228 };
-# define NDELAY (sizeof(delays)/sizeof(delays[0]))
- sqlite3 *db = (sqlite3 *)ptr;
- int timeout = db->busyTimeout;
- int delay, prior;
-
- assert( count>=0 );
- if( count < NDELAY ){
- delay = delays[count];
- prior = totals[count];
- }else{
- delay = delays[NDELAY-1];
- prior = totals[NDELAY-1] + delay*(count-(NDELAY-1));
- }
- if( prior + delay > timeout ){
- delay = timeout - prior;
- if( delay<=0 ) return 0;
- }
- sqlite3OsSleep(db->pVfs, delay*1000);
- return 1;
-#else
- sqlite3 *db = (sqlite3 *)ptr;
- int timeout = ((sqlite3 *)ptr)->busyTimeout;
- if( (count+1)*1000 > timeout ){
- return 0;
- }
- sqlite3OsSleep(db->pVfs, 1000000);
- return 1;
-#endif
-}
-
-/*
-** Invoke the given busy handler.
-**
-** This routine is called when an operation failed with a lock.
-** If this routine returns non-zero, the lock is retried. If it
-** returns 0, the operation aborts with an SQLITE_BUSY error.
-*/
-SQLITE_PRIVATE int sqlite3InvokeBusyHandler(BusyHandler *p){
- int rc;
- if( NEVER(p==0) || p->xFunc==0 || p->nBusy<0 ) return 0;
- rc = p->xFunc(p->pArg, p->nBusy);
- if( rc==0 ){
- p->nBusy = -1;
- }else{
- p->nBusy++;
- }
- return rc;
-}
-
-/*
-** This routine sets the busy callback for an Sqlite database to the
-** given callback function with the given argument.
-*/
-SQLITE_API int sqlite3_busy_handler(
- sqlite3 *db,
- int (*xBusy)(void*,int),
- void *pArg
-){
- sqlite3_mutex_enter(db->mutex);
- db->busyHandler.xFunc = xBusy;
- db->busyHandler.pArg = pArg;
- db->busyHandler.nBusy = 0;
- sqlite3_mutex_leave(db->mutex);
- return SQLITE_OK;
-}
-
-#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
-/*
-** This routine sets the progress callback for an Sqlite database to the
-** given callback function with the given argument. The progress callback will
-** be invoked every nOps opcodes.
-*/
-SQLITE_API void sqlite3_progress_handler(
- sqlite3 *db,
- int nOps,
- int (*xProgress)(void*),
- void *pArg
-){
- sqlite3_mutex_enter(db->mutex);
- if( nOps>0 ){
- db->xProgress = xProgress;
- db->nProgressOps = nOps;
- db->pProgressArg = pArg;
- }else{
- db->xProgress = 0;
- db->nProgressOps = 0;
- db->pProgressArg = 0;
- }
- sqlite3_mutex_leave(db->mutex);
-}
-#endif
-
-
-/*
-** This routine installs a default busy handler that waits for the
-** specified number of milliseconds before returning 0.
-*/
-SQLITE_API int sqlite3_busy_timeout(sqlite3 *db, int ms){
- if( ms>0 ){
- db->busyTimeout = ms;
- sqlite3_busy_handler(db, sqliteDefaultBusyCallback, (void*)db);
- }else{
- sqlite3_busy_handler(db, 0, 0);
- }
- return SQLITE_OK;
-}
-
-/*
-** Cause any pending operation to stop at its earliest opportunity.
-*/
-SQLITE_API void sqlite3_interrupt(sqlite3 *db){
- db->u1.isInterrupted = 1;
-}
-
-
-/*
-** This function is exactly the same as sqlite3_create_function(), except
-** that it is designed to be called by internal code. The difference is
-** that if a malloc() fails in sqlite3_create_function(), an error code
-** is returned and the mallocFailed flag cleared.
-*/
-SQLITE_PRIVATE int sqlite3CreateFunc(
- sqlite3 *db,
- const char *zFunctionName,
- int nArg,
- int enc,
- void *pUserData,
- void (*xFunc)(sqlite3_context*,int,sqlite3_value **),
- void (*xStep)(sqlite3_context*,int,sqlite3_value **),
- void (*xFinal)(sqlite3_context*)
-){
- FuncDef *p;
- int nName;
-
- assert( sqlite3_mutex_held(db->mutex) );
- if( zFunctionName==0 ||
- (xFunc && (xFinal || xStep)) ||
- (!xFunc && (xFinal && !xStep)) ||
- (!xFunc && (!xFinal && xStep)) ||
- (nArg<-1 || nArg>SQLITE_MAX_FUNCTION_ARG) ||
- (255<(nName = sqlite3Strlen30( zFunctionName))) ){
- return SQLITE_MISUSE;
- }
-
-#ifndef SQLITE_OMIT_UTF16
- /* If SQLITE_UTF16 is specified as the encoding type, transform this
- ** to one of SQLITE_UTF16LE or SQLITE_UTF16BE using the
- ** SQLITE_UTF16NATIVE macro. SQLITE_UTF16 is not used internally.
- **
- ** If SQLITE_ANY is specified, add three versions of the function
- ** to the hash table.
- */
- if( enc==SQLITE_UTF16 ){
- enc = SQLITE_UTF16NATIVE;
- }else if( enc==SQLITE_ANY ){
- int rc;
- rc = sqlite3CreateFunc(db, zFunctionName, nArg, SQLITE_UTF8,
- pUserData, xFunc, xStep, xFinal);
- if( rc==SQLITE_OK ){
- rc = sqlite3CreateFunc(db, zFunctionName, nArg, SQLITE_UTF16LE,
- pUserData, xFunc, xStep, xFinal);
- }
- if( rc!=SQLITE_OK ){
- return rc;
- }
- enc = SQLITE_UTF16BE;
- }
-#else
- enc = SQLITE_UTF8;
-#endif
-
- /* Check if an existing function is being overridden or deleted. If so,
- ** and there are active VMs, then return SQLITE_BUSY. If a function
- ** is being overridden/deleted but there are no active VMs, allow the
- ** operation to continue but invalidate all precompiled statements.
- */
- p = sqlite3FindFunction(db, zFunctionName, nName, nArg, (u8)enc, 0);
- if( p && p->iPrefEnc==enc && p->nArg==nArg ){
- if( db->activeVdbeCnt ){
- sqlite3Error(db, SQLITE_BUSY,
- "unable to delete/modify user-function due to active statements");
- assert( !db->mallocFailed );
- return SQLITE_BUSY;
- }else{
- sqlite3ExpirePreparedStatements(db);
- }
- }
-
- p = sqlite3FindFunction(db, zFunctionName, nName, nArg, (u8)enc, 1);
- assert(p || db->mallocFailed);
- if( !p ){
- return SQLITE_NOMEM;
- }
- p->flags = 0;
- p->xFunc = xFunc;
- p->xStep = xStep;
- p->xFinalize = xFinal;
- p->pUserData = pUserData;
- p->nArg = (u16)nArg;
- return SQLITE_OK;
-}
-
-/*
-** Create new user functions.
-*/
-SQLITE_API int sqlite3_create_function(
- sqlite3 *db,
- const char *zFunctionName,
- int nArg,
- int enc,
- void *p,
- void (*xFunc)(sqlite3_context*,int,sqlite3_value **),
- void (*xStep)(sqlite3_context*,int,sqlite3_value **),
- void (*xFinal)(sqlite3_context*)
-){
- int rc;
- sqlite3_mutex_enter(db->mutex);
- rc = sqlite3CreateFunc(db, zFunctionName, nArg, enc, p, xFunc, xStep, xFinal);
- rc = sqlite3ApiExit(db, rc);
- sqlite3_mutex_leave(db->mutex);
- return rc;
-}
-
-#ifndef SQLITE_OMIT_UTF16
-SQLITE_API int sqlite3_create_function16(
- sqlite3 *db,
- const void *zFunctionName,
- int nArg,
- int eTextRep,
- void *p,
- void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
- void (*xStep)(sqlite3_context*,int,sqlite3_value**),
- void (*xFinal)(sqlite3_context*)
-){
- int rc;
- char *zFunc8;
- sqlite3_mutex_enter(db->mutex);
- assert( !db->mallocFailed );
- zFunc8 = sqlite3Utf16to8(db, zFunctionName, -1);
- rc = sqlite3CreateFunc(db, zFunc8, nArg, eTextRep, p, xFunc, xStep, xFinal);
- sqlite3DbFree(db, zFunc8);
- rc = sqlite3ApiExit(db, rc);
- sqlite3_mutex_leave(db->mutex);
- return rc;
-}
-#endif
-
-
-/*
-** Declare that a function has been overloaded by a virtual table.
-**
-** If the function already exists as a regular global function, then
-** this routine is a no-op. If the function does not exist, then create
-** a new one that always throws a run-time error.
-**
-** When virtual tables intend to provide an overloaded function, they
-** should call this routine to make sure the global function exists.
-** A global function must exist in order for name resolution to work
-** properly.
-*/
-SQLITE_API int sqlite3_overload_function(
- sqlite3 *db,
- const char *zName,
- int nArg
-){
- int nName = sqlite3Strlen30(zName);
- int rc;
- sqlite3_mutex_enter(db->mutex);
- if( sqlite3FindFunction(db, zName, nName, nArg, SQLITE_UTF8, 0)==0 ){
- sqlite3CreateFunc(db, zName, nArg, SQLITE_UTF8,
- 0, sqlite3InvalidFunction, 0, 0);
- }
- rc = sqlite3ApiExit(db, SQLITE_OK);
- sqlite3_mutex_leave(db->mutex);
- return rc;
-}
-
-#ifndef SQLITE_OMIT_TRACE
-/*
-** Register a trace function. The pArg from the previously registered trace
-** is returned.
-**
-** A NULL trace function means that no tracing is executes. A non-NULL
-** trace is a pointer to a function that is invoked at the start of each
-** SQL statement.
-*/
-SQLITE_API void *sqlite3_trace(sqlite3 *db, void (*xTrace)(void*,const char*), void *pArg){
- void *pOld;
- sqlite3_mutex_enter(db->mutex);
- pOld = db->pTraceArg;
- db->xTrace = xTrace;
- db->pTraceArg = pArg;
- sqlite3_mutex_leave(db->mutex);
- return pOld;
-}
-/*
-** Register a profile function. The pArg from the previously registered
-** profile function is returned.
-**
-** A NULL profile function means that no profiling is executes. A non-NULL
-** profile is a pointer to a function that is invoked at the conclusion of
-** each SQL statement that is run.
-*/
-SQLITE_API void *sqlite3_profile(
- sqlite3 *db,
- void (*xProfile)(void*,const char*,sqlite_uint64),
- void *pArg
-){
- void *pOld;
- sqlite3_mutex_enter(db->mutex);
- pOld = db->pProfileArg;
- db->xProfile = xProfile;
- db->pProfileArg = pArg;
- sqlite3_mutex_leave(db->mutex);
- return pOld;
-}
-#endif /* SQLITE_OMIT_TRACE */
-
-/*** EXPERIMENTAL ***
-**
-** Register a function to be invoked when a transaction comments.
-** If the invoked function returns non-zero, then the commit becomes a
-** rollback.
-*/
-SQLITE_API void *sqlite3_commit_hook(
- sqlite3 *db, /* Attach the hook to this database */
- int (*xCallback)(void*), /* Function to invoke on each commit */
- void *pArg /* Argument to the function */
-){
- void *pOld;
- sqlite3_mutex_enter(db->mutex);
- pOld = db->pCommitArg;
- db->xCommitCallback = xCallback;
- db->pCommitArg = pArg;
- sqlite3_mutex_leave(db->mutex);
- return pOld;
-}
-
-/*
-** Register a callback to be invoked each time a row is updated,
-** inserted or deleted using this database connection.
-*/
-SQLITE_API void *sqlite3_update_hook(
- sqlite3 *db, /* Attach the hook to this database */
- void (*xCallback)(void*,int,char const *,char const *,sqlite_int64),
- void *pArg /* Argument to the function */
-){
- void *pRet;
- sqlite3_mutex_enter(db->mutex);
- pRet = db->pUpdateArg;
- db->xUpdateCallback = xCallback;
- db->pUpdateArg = pArg;
- sqlite3_mutex_leave(db->mutex);
- return pRet;
-}
-
-/*
-** Register a callback to be invoked each time a transaction is rolled
-** back by this database connection.
-*/
-SQLITE_API void *sqlite3_rollback_hook(
- sqlite3 *db, /* Attach the hook to this database */
- void (*xCallback)(void*), /* Callback function */
- void *pArg /* Argument to the function */
-){
- void *pRet;
- sqlite3_mutex_enter(db->mutex);
- pRet = db->pRollbackArg;
- db->xRollbackCallback = xCallback;
- db->pRollbackArg = pArg;
- sqlite3_mutex_leave(db->mutex);
- return pRet;
-}
-
-/*
-** This function returns true if main-memory should be used instead of
-** a temporary file for transient pager files and statement journals.
-** The value returned depends on the value of db->temp_store (runtime
-** parameter) and the compile time value of SQLITE_TEMP_STORE. The
-** following table describes the relationship between these two values
-** and this functions return value.
-**
-** SQLITE_TEMP_STORE db->temp_store Location of temporary database
-** ----------------- -------------- ------------------------------
-** 0 any file (return 0)
-** 1 1 file (return 0)
-** 1 2 memory (return 1)
-** 1 0 file (return 0)
-** 2 1 file (return 0)
-** 2 2 memory (return 1)
-** 2 0 memory (return 1)
-** 3 any memory (return 1)
-*/
-SQLITE_PRIVATE int sqlite3TempInMemory(const sqlite3 *db){
-#if SQLITE_TEMP_STORE==1
- return ( db->temp_store==2 );
-#endif
-#if SQLITE_TEMP_STORE==2
- return ( db->temp_store!=1 );
-#endif
-#if SQLITE_TEMP_STORE==3
- return 1;
-#endif
-#if SQLITE_TEMP_STORE<1 || SQLITE_TEMP_STORE>3
- return 0;
-#endif
-}
-
-/*
-** This routine is called to create a connection to a database BTree
-** driver. If zFilename is the name of a file, then that file is
-** opened and used. If zFilename is the magic name ":memory:" then
-** the database is stored in memory (and is thus forgotten as soon as
-** the connection is closed.) If zFilename is NULL then the database
-** is a "virtual" database for transient use only and is deleted as
-** soon as the connection is closed.
-**
-** A virtual database can be either a disk file (that is automatically
-** deleted when the file is closed) or it an be held entirely in memory.
-** The sqlite3TempInMemory() function is used to determine which.
-*/
-SQLITE_PRIVATE int sqlite3BtreeFactory(
- const sqlite3 *db, /* Main database when opening aux otherwise 0 */
- const char *zFilename, /* Name of the file containing the BTree database */
- int omitJournal, /* if TRUE then do not journal this file */
- int nCache, /* How many pages in the page cache */
- int vfsFlags, /* Flags passed through to vfsOpen */
- Btree **ppBtree /* Pointer to new Btree object written here */
-){
- int btFlags = 0;
- int rc;
-
- assert( sqlite3_mutex_held(db->mutex) );
- assert( ppBtree != 0);
- if( omitJournal ){
- btFlags |= BTREE_OMIT_JOURNAL;
- }
- if( db->flags & SQLITE_NoReadlock ){
- btFlags |= BTREE_NO_READLOCK;
- }
-#ifndef SQLITE_OMIT_MEMORYDB
- if( zFilename==0 && sqlite3TempInMemory(db) ){
- zFilename = ":memory:";
- }
-#endif
-
- if( (vfsFlags & SQLITE_OPEN_MAIN_DB)!=0 && (zFilename==0 || *zFilename==0) ){
- vfsFlags = (vfsFlags & ~SQLITE_OPEN_MAIN_DB) | SQLITE_OPEN_TEMP_DB;
- }
- rc = sqlite3BtreeOpen(zFilename, (sqlite3 *)db, ppBtree, btFlags, vfsFlags);
-
- /* If the B-Tree was successfully opened, set the pager-cache size to the
- ** default value. Except, if the call to BtreeOpen() returned a handle
- ** open on an existing shared pager-cache, do not change the pager-cache
- ** size.
- */
- if( rc==SQLITE_OK && 0==sqlite3BtreeSchema(*ppBtree, 0, 0) ){
- sqlite3BtreeSetCacheSize(*ppBtree, nCache);
- }
- return rc;
-}
-
-/*
-** Return UTF-8 encoded English language explanation of the most recent
-** error.
-*/
-SQLITE_API const char *sqlite3_errmsg(sqlite3 *db){
- const char *z;
- if( !db ){
- return sqlite3ErrStr(SQLITE_NOMEM);
- }
- if( !sqlite3SafetyCheckSickOrOk(db) ){
- return sqlite3ErrStr(SQLITE_MISUSE);
- }
- sqlite3_mutex_enter(db->mutex);
- if( db->mallocFailed ){
- z = sqlite3ErrStr(SQLITE_NOMEM);
- }else{
- z = (char*)sqlite3_value_text(db->pErr);
- assert( !db->mallocFailed );
- if( z==0 ){
- z = sqlite3ErrStr(db->errCode);
- }
- }
- sqlite3_mutex_leave(db->mutex);
- return z;
-}
-
-#ifndef SQLITE_OMIT_UTF16
-/*
-** Return UTF-16 encoded English language explanation of the most recent
-** error.
-*/
-SQLITE_API const void *sqlite3_errmsg16(sqlite3 *db){
- static const u16 outOfMem[] = {
- 'o', 'u', 't', ' ', 'o', 'f', ' ', 'm', 'e', 'm', 'o', 'r', 'y', 0
- };
- static const u16 misuse[] = {
- 'l', 'i', 'b', 'r', 'a', 'r', 'y', ' ',
- 'r', 'o', 'u', 't', 'i', 'n', 'e', ' ',
- 'c', 'a', 'l', 'l', 'e', 'd', ' ',
- 'o', 'u', 't', ' ',
- 'o', 'f', ' ',
- 's', 'e', 'q', 'u', 'e', 'n', 'c', 'e', 0
- };
-
- const void *z;
- if( !db ){
- return (void *)outOfMem;
- }
- if( !sqlite3SafetyCheckSickOrOk(db) ){
- return (void *)misuse;
- }
- sqlite3_mutex_enter(db->mutex);
- if( db->mallocFailed ){
- z = (void *)outOfMem;
- }else{
- z = sqlite3_value_text16(db->pErr);
- if( z==0 ){
- sqlite3ValueSetStr(db->pErr, -1, sqlite3ErrStr(db->errCode),
- SQLITE_UTF8, SQLITE_STATIC);
- z = sqlite3_value_text16(db->pErr);
- }
- /* A malloc() may have failed within the call to sqlite3_value_text16()
- ** above. If this is the case, then the db->mallocFailed flag needs to
- ** be cleared before returning. Do this directly, instead of via
- ** sqlite3ApiExit(), to avoid setting the database handle error message.
- */
- db->mallocFailed = 0;
- }
- sqlite3_mutex_leave(db->mutex);
- return z;
-}
-#endif /* SQLITE_OMIT_UTF16 */
-
-/*
-** Return the most recent error code generated by an SQLite routine. If NULL is
-** passed to this function, we assume a malloc() failed during sqlite3_open().
-*/
-SQLITE_API int sqlite3_errcode(sqlite3 *db){
- if( db && !sqlite3SafetyCheckSickOrOk(db) ){
- return SQLITE_MISUSE;
- }
- if( !db || db->mallocFailed ){
- return SQLITE_NOMEM;
- }
- return db->errCode & db->errMask;
-}
-SQLITE_API int sqlite3_extended_errcode(sqlite3 *db){
- if( db && !sqlite3SafetyCheckSickOrOk(db) ){
- return SQLITE_MISUSE;
- }
- if( !db || db->mallocFailed ){
- return SQLITE_NOMEM;
- }
- return db->errCode;
-}
-
-/*
-** Create a new collating function for database "db". The name is zName
-** and the encoding is enc.
-*/
-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*)
-){
- CollSeq *pColl;
- int enc2;
- int nName = sqlite3Strlen30(zName);
-
- assert( sqlite3_mutex_held(db->mutex) );
-
- /* If SQLITE_UTF16 is specified as the encoding type, transform this
- ** to one of SQLITE_UTF16LE or SQLITE_UTF16BE using the
- ** SQLITE_UTF16NATIVE macro. SQLITE_UTF16 is not used internally.
- */
- enc2 = enc;
- testcase( enc2==SQLITE_UTF16 );
- testcase( enc2==SQLITE_UTF16_ALIGNED );
- if( enc2==SQLITE_UTF16 || enc2==SQLITE_UTF16_ALIGNED ){
- enc2 = SQLITE_UTF16NATIVE;
- }
- if( enc2<SQLITE_UTF8 || enc2>SQLITE_UTF16BE ){
- return SQLITE_MISUSE;
- }
-
- /* Check if this call is removing or replacing an existing collation
- ** sequence. If so, and there are active VMs, return busy. If there
- ** are no active VMs, invalidate any pre-compiled statements.
- */
- pColl = sqlite3FindCollSeq(db, (u8)enc2, zName, 0);
- if( pColl && pColl->xCmp ){
- if( db->activeVdbeCnt ){
- sqlite3Error(db, SQLITE_BUSY,
- "unable to delete/modify collation sequence due to active statements");
- return SQLITE_BUSY;
- }
- sqlite3ExpirePreparedStatements(db);
-
- /* If collation sequence pColl was created directly by a call to
- ** sqlite3_create_collation, and not generated by synthCollSeq(),
- ** then any copies made by synthCollSeq() need to be invalidated.
- ** Also, collation destructor - CollSeq.xDel() - function may need
- ** to be called.
- */
- if( (pColl->enc & ~SQLITE_UTF16_ALIGNED)==enc2 ){
- CollSeq *aColl = sqlite3HashFind(&db->aCollSeq, zName, nName);
- int j;
- for(j=0; j<3; j++){
- CollSeq *p = &aColl[j];
- if( p->enc==pColl->enc ){
- if( p->xDel ){
- p->xDel(p->pUser);
- }
- p->xCmp = 0;
- }
- }
- }
- }
-
- pColl = sqlite3FindCollSeq(db, (u8)enc2, zName, 1);
- if( pColl ){
- pColl->xCmp = xCompare;
- 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;
-}
-
-
-/*
-** This array defines hard upper bounds on limit values. The
-** initializer must be kept in sync with the SQLITE_LIMIT_*
-** #defines in sqlite3.h.
-*/
-static const int aHardLimit[] = {
- SQLITE_MAX_LENGTH,
- SQLITE_MAX_SQL_LENGTH,
- SQLITE_MAX_COLUMN,
- SQLITE_MAX_EXPR_DEPTH,
- SQLITE_MAX_COMPOUND_SELECT,
- SQLITE_MAX_VDBE_OP,
- SQLITE_MAX_FUNCTION_ARG,
- SQLITE_MAX_ATTACHED,
- SQLITE_MAX_LIKE_PATTERN_LENGTH,
- SQLITE_MAX_VARIABLE_NUMBER,
- SQLITE_MAX_TRIGGER_DEPTH,
-};
-
-/*
-** Make sure the hard limits are set to reasonable values
-*/
-#if SQLITE_MAX_LENGTH<100
-# error SQLITE_MAX_LENGTH must be at least 100
-#endif
-#if SQLITE_MAX_SQL_LENGTH<100
-# error SQLITE_MAX_SQL_LENGTH must be at least 100
-#endif
-#if SQLITE_MAX_SQL_LENGTH>SQLITE_MAX_LENGTH
-# error SQLITE_MAX_SQL_LENGTH must not be greater than SQLITE_MAX_LENGTH
-#endif
-#if SQLITE_MAX_COMPOUND_SELECT<2
-# error SQLITE_MAX_COMPOUND_SELECT must be at least 2
-#endif
-#if SQLITE_MAX_VDBE_OP<40
-# error SQLITE_MAX_VDBE_OP must be at least 40
-#endif
-#if SQLITE_MAX_FUNCTION_ARG<0 || SQLITE_MAX_FUNCTION_ARG>1000
-# error SQLITE_MAX_FUNCTION_ARG must be between 0 and 1000
-#endif
-#if SQLITE_MAX_ATTACHED<0 || SQLITE_MAX_ATTACHED>30
-# error SQLITE_MAX_ATTACHED must be between 0 and 30
-#endif
-#if SQLITE_MAX_LIKE_PATTERN_LENGTH<1
-# error SQLITE_MAX_LIKE_PATTERN_LENGTH must be at least 1
-#endif
-#if SQLITE_MAX_VARIABLE_NUMBER<1
-# error SQLITE_MAX_VARIABLE_NUMBER must be at least 1
-#endif
-#if SQLITE_MAX_COLUMN>32767
-# error SQLITE_MAX_COLUMN must not exceed 32767
-#endif
-#if SQLITE_MAX_TRIGGER_DEPTH<1
-# error SQLITE_MAX_TRIGGER_DEPTH must be at least 1
-#endif
-
-
-/*
-** Change the value of a limit. Report the old value.
-** If an invalid limit index is supplied, report -1.
-** Make no changes but still report the old value if the
-** new limit is negative.
-**
-** A new lower limit does not shrink existing constructs.
-** It merely prevents new constructs that exceed the limit
-** from forming.
-*/
-SQLITE_API int sqlite3_limit(sqlite3 *db, int limitId, int newLimit){
- int oldLimit;
- if( limitId<0 || limitId>=SQLITE_N_LIMIT ){
- return -1;
- }
- oldLimit = db->aLimit[limitId];
- if( newLimit>=0 ){
- if( newLimit>aHardLimit[limitId] ){
- newLimit = aHardLimit[limitId];
- }
- db->aLimit[limitId] = newLimit;
- }
- return oldLimit;
-}
-
-/*
-** This routine does the work of opening a database on behalf of
-** sqlite3_open() and sqlite3_open16(). The database filename "zFilename"
-** is UTF-8 encoded.
-*/
-static int openDatabase(
- const char *zFilename, /* Database filename UTF-8 encoded */
- sqlite3 **ppDb, /* OUT: Returned database handle */
- unsigned flags, /* Operational flags */
- const char *zVfs /* Name of the VFS to use */
-){
- sqlite3 *db;
- int rc;
- int isThreadsafe;
-
- *ppDb = 0;
-#ifndef SQLITE_OMIT_AUTOINIT
- rc = sqlite3_initialize();
- if( rc ) return rc;
-#endif
-
- if( sqlite3GlobalConfig.bCoreMutex==0 ){
- isThreadsafe = 0;
- }else if( flags & SQLITE_OPEN_NOMUTEX ){
- isThreadsafe = 0;
- }else if( flags & SQLITE_OPEN_FULLMUTEX ){
- isThreadsafe = 1;
- }else{
- isThreadsafe = sqlite3GlobalConfig.bFullMutex;
- }
- if( flags & SQLITE_OPEN_PRIVATECACHE ){
- flags &= ~SQLITE_OPEN_SHAREDCACHE;
- }else if( sqlite3GlobalConfig.sharedCacheEnabled ){
- flags |= SQLITE_OPEN_SHAREDCACHE;
- }
-
- /* Remove harmful bits from the flags parameter
- **
- ** The SQLITE_OPEN_NOMUTEX and SQLITE_OPEN_FULLMUTEX flags were
- ** dealt with in the previous code block. Besides these, the only
- ** valid input flags for sqlite3_open_v2() are SQLITE_OPEN_READONLY,
- ** SQLITE_OPEN_READWRITE, and SQLITE_OPEN_CREATE. Silently mask
- ** off all other flags.
- */
- flags &= ~( SQLITE_OPEN_DELETEONCLOSE |
- SQLITE_OPEN_EXCLUSIVE |
- SQLITE_OPEN_MAIN_DB |
- SQLITE_OPEN_TEMP_DB |
- SQLITE_OPEN_TRANSIENT_DB |
- SQLITE_OPEN_MAIN_JOURNAL |
- SQLITE_OPEN_TEMP_JOURNAL |
- SQLITE_OPEN_SUBJOURNAL |
- SQLITE_OPEN_MASTER_JOURNAL |
- SQLITE_OPEN_NOMUTEX |
- SQLITE_OPEN_FULLMUTEX
- );
-
- /* Allocate the sqlite data structure */
- db = sqlite3MallocZero( sizeof(sqlite3) );
- if( db==0 ) goto opendb_out;
- if( isThreadsafe ){
- db->mutex = sqlite3MutexAlloc(SQLITE_MUTEX_RECURSIVE);
- if( db->mutex==0 ){
- sqlite3_free(db);
- db = 0;
- goto opendb_out;
- }
- }
- sqlite3_mutex_enter(db->mutex);
- db->errMask = 0xff;
- db->nDb = 2;
- db->magic = SQLITE_MAGIC_BUSY;
- db->aDb = db->aDbStatic;
-
- assert( sizeof(db->aLimit)==sizeof(aHardLimit) );
- memcpy(db->aLimit, aHardLimit, sizeof(db->aLimit));
- db->autoCommit = 1;
- db->nextAutovac = -1;
- db->nextPagesize = 0;
- db->flags |= SQLITE_ShortColNames
-#if SQLITE_DEFAULT_FILE_FORMAT<4
- | SQLITE_LegacyFileFmt
-#endif
-#ifdef SQLITE_ENABLE_LOAD_EXTENSION
- | SQLITE_LoadExtension
-#endif
-#if SQLITE_DEFAULT_RECURSIVE_TRIGGERS
- | SQLITE_RecTriggers
-#endif
- ;
- sqlite3HashInit(&db->aCollSeq);
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- sqlite3HashInit(&db->aModule);
-#endif
-
- db->pVfs = sqlite3_vfs_find(zVfs);
- if( !db->pVfs ){
- rc = SQLITE_ERROR;
- sqlite3Error(db, rc, "no such vfs: %s", zVfs);
- goto opendb_out;
- }
-
- /* Add the default collation sequence BINARY. BINARY works for both UTF-8
- ** 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);
- if( db->mallocFailed ){
- goto opendb_out;
- }
- db->pDfltColl = sqlite3FindCollSeq(db, SQLITE_UTF8, "BINARY", 0);
- assert( db->pDfltColl!=0 );
-
- /* Also add a UTF-8 case-insensitive collation sequence. */
- createCollation(db, "NOCASE", SQLITE_UTF8, SQLITE_COLL_NOCASE, 0,
- nocaseCollatingFunc, 0);
-
- /* Open the backend database driver */
- db->openFlags = flags;
- rc = sqlite3BtreeFactory(db, zFilename, 0, SQLITE_DEFAULT_CACHE_SIZE,
- flags | SQLITE_OPEN_MAIN_DB,
- &db->aDb[0].pBt);
- if( rc!=SQLITE_OK ){
- if( rc==SQLITE_IOERR_NOMEM ){
- rc = SQLITE_NOMEM;
- }
- sqlite3Error(db, rc, 0);
- goto opendb_out;
- }
- db->aDb[0].pSchema = sqlite3SchemaGet(db, db->aDb[0].pBt);
- db->aDb[1].pSchema = sqlite3SchemaGet(db, 0);
-
-
- /* The default safety_level for the main database is 'full'; for the temp
- ** database it is 'NONE'. This matches the pager layer defaults.
- */
- db->aDb[0].zName = "main";
- db->aDb[0].safety_level = 3;
- db->aDb[1].zName = "temp";
- db->aDb[1].safety_level = 1;
-
- db->magic = SQLITE_MAGIC_OPEN;
- if( db->mallocFailed ){
- goto opendb_out;
- }
-
- /* Register all built-in functions, but do not attempt to read the
- ** database schema yet. This is delayed until the first time the database
- ** is accessed.
- */
- sqlite3Error(db, SQLITE_OK, 0);
- sqlite3RegisterBuiltinFunctions(db);
-
- /* 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;
- }
-
-#ifdef SQLITE_ENABLE_FTS1
- if( !db->mallocFailed ){
- extern int sqlite3Fts1Init(sqlite3*);
- rc = sqlite3Fts1Init(db);
- }
-#endif
-
-#ifdef SQLITE_ENABLE_FTS2
- if( !db->mallocFailed && rc==SQLITE_OK ){
- extern int sqlite3Fts2Init(sqlite3*);
- rc = sqlite3Fts2Init(db);
- }
-#endif
-
-#ifdef SQLITE_ENABLE_FTS3
- if( !db->mallocFailed && rc==SQLITE_OK ){
- rc = sqlite3Fts3Init(db);
- }
-#endif
-
-#ifdef SQLITE_ENABLE_ICU
- if( !db->mallocFailed && rc==SQLITE_OK ){
- rc = sqlite3IcuInit(db);
- }
-#endif
-
-#ifdef SQLITE_ENABLE_RTREE
- if( !db->mallocFailed && rc==SQLITE_OK){
- rc = sqlite3RtreeInit(db);
- }
-#endif
-
- sqlite3Error(db, rc, 0);
-
- /* -DSQLITE_DEFAULT_LOCKING_MODE=1 makes EXCLUSIVE the default locking
- ** mode. -DSQLITE_DEFAULT_LOCKING_MODE=0 make NORMAL the default locking
- ** mode. Doing nothing at all also makes NORMAL the default.
- */
-#ifdef SQLITE_DEFAULT_LOCKING_MODE
- db->dfltLockMode = SQLITE_DEFAULT_LOCKING_MODE;
- sqlite3PagerLockingMode(sqlite3BtreePager(db->aDb[0].pBt),
- SQLITE_DEFAULT_LOCKING_MODE);
-#endif
-
- /* Enable the lookaside-malloc subsystem */
- setupLookaside(db, 0, sqlite3GlobalConfig.szLookaside,
- sqlite3GlobalConfig.nLookaside);
-
-opendb_out:
- if( db ){
- assert( db->mutex!=0 || isThreadsafe==0 || sqlite3GlobalConfig.bFullMutex==0 );
- sqlite3_mutex_leave(db->mutex);
- }
- rc = sqlite3_errcode(db);
- if( rc==SQLITE_NOMEM ){
- sqlite3_close(db);
- db = 0;
- }else if( rc!=SQLITE_OK ){
- db->magic = SQLITE_MAGIC_SICK;
- }
- *ppDb = db;
- return sqlite3ApiExit(0, rc);
-}
-
-/*
-** Open a new database handle.
-*/
-SQLITE_API int sqlite3_open(
- const char *zFilename,
- sqlite3 **ppDb
-){
- return openDatabase(zFilename, ppDb,
- SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, 0);
-}
-SQLITE_API int sqlite3_open_v2(
- const char *filename, /* Database filename (UTF-8) */
- sqlite3 **ppDb, /* OUT: SQLite db handle */
- int flags, /* Flags */
- const char *zVfs /* Name of VFS module to use */
-){
- return openDatabase(filename, ppDb, flags, zVfs);
-}
-
-#ifndef SQLITE_OMIT_UTF16
-/*
-** Open a new database handle.
-*/
-SQLITE_API int sqlite3_open16(
- const void *zFilename,
- sqlite3 **ppDb
-){
- char const *zFilename8; /* zFilename encoded in UTF-8 instead of UTF-16 */
- sqlite3_value *pVal;
- int rc;
-
- assert( zFilename );
- assert( ppDb );
- *ppDb = 0;
-#ifndef SQLITE_OMIT_AUTOINIT
- rc = sqlite3_initialize();
- if( rc ) return rc;
-#endif
- pVal = sqlite3ValueNew(0);
- sqlite3ValueSetStr(pVal, -1, zFilename, SQLITE_UTF16NATIVE, SQLITE_STATIC);
- zFilename8 = sqlite3ValueText(pVal, SQLITE_UTF8);
- if( zFilename8 ){
- rc = openDatabase(zFilename8, ppDb,
- SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, 0);
- assert( *ppDb || rc==SQLITE_NOMEM );
- if( rc==SQLITE_OK && !DbHasProperty(*ppDb, 0, DB_SchemaLoaded) ){
- ENC(*ppDb) = SQLITE_UTF16NATIVE;
- }
- }else{
- rc = SQLITE_NOMEM;
- }
- sqlite3ValueFree(pVal);
-
- return sqlite3ApiExit(0, rc);
-}
-#endif /* SQLITE_OMIT_UTF16 */
-
-/*
-** Register a new collation sequence with the database handle db.
-*/
-SQLITE_API int sqlite3_create_collation(
- sqlite3* db,
- const char *zName,
- int enc,
- void* pCtx,
- int(*xCompare)(void*,int,const void*,int,const void*)
-){
- int rc;
- sqlite3_mutex_enter(db->mutex);
- assert( !db->mallocFailed );
- rc = createCollation(db, zName, (u8)enc, SQLITE_COLL_USER, pCtx, xCompare, 0);
- rc = sqlite3ApiExit(db, rc);
- sqlite3_mutex_leave(db->mutex);
- return rc;
-}
-
-/*
-** Register a new collation sequence with the database handle db.
-*/
-SQLITE_API int sqlite3_create_collation_v2(
- sqlite3* db,
- const char *zName,
- int enc,
- void* pCtx,
- int(*xCompare)(void*,int,const void*,int,const void*),
- void(*xDel)(void*)
-){
- int rc;
- sqlite3_mutex_enter(db->mutex);
- assert( !db->mallocFailed );
- rc = createCollation(db, zName, (u8)enc, SQLITE_COLL_USER, pCtx, xCompare, xDel);
- rc = sqlite3ApiExit(db, rc);
- sqlite3_mutex_leave(db->mutex);
- return rc;
-}
-
-#ifndef SQLITE_OMIT_UTF16
-/*
-** Register a new collation sequence with the database handle db.
-*/
-SQLITE_API int sqlite3_create_collation16(
- sqlite3* db,
- const void *zName,
- int enc,
- void* pCtx,
- int(*xCompare)(void*,int,const void*,int,const void*)
-){
- int rc = SQLITE_OK;
- char *zName8;
- sqlite3_mutex_enter(db->mutex);
- assert( !db->mallocFailed );
- zName8 = sqlite3Utf16to8(db, zName, -1);
- if( zName8 ){
- rc = createCollation(db, zName8, (u8)enc, SQLITE_COLL_USER, pCtx, xCompare, 0);
- sqlite3DbFree(db, zName8);
- }
- rc = sqlite3ApiExit(db, rc);
- sqlite3_mutex_leave(db->mutex);
- return rc;
-}
-#endif /* SQLITE_OMIT_UTF16 */
-
-/*
-** Register a collation sequence factory callback with the database handle
-** db. Replace any previously installed collation sequence factory.
-*/
-SQLITE_API int sqlite3_collation_needed(
- sqlite3 *db,
- void *pCollNeededArg,
- void(*xCollNeeded)(void*,sqlite3*,int eTextRep,const char*)
-){
- sqlite3_mutex_enter(db->mutex);
- db->xCollNeeded = xCollNeeded;
- db->xCollNeeded16 = 0;
- db->pCollNeededArg = pCollNeededArg;
- sqlite3_mutex_leave(db->mutex);
- return SQLITE_OK;
-}
-
-#ifndef SQLITE_OMIT_UTF16
-/*
-** Register a collation sequence factory callback with the database handle
-** db. Replace any previously installed collation sequence factory.
-*/
-SQLITE_API int sqlite3_collation_needed16(
- sqlite3 *db,
- void *pCollNeededArg,
- void(*xCollNeeded16)(void*,sqlite3*,int eTextRep,const void*)
-){
- sqlite3_mutex_enter(db->mutex);
- db->xCollNeeded = 0;
- db->xCollNeeded16 = xCollNeeded16;
- db->pCollNeededArg = pCollNeededArg;
- sqlite3_mutex_leave(db->mutex);
- return SQLITE_OK;
-}
-#endif /* SQLITE_OMIT_UTF16 */
-
-#ifndef SQLITE_OMIT_GLOBALRECOVER
-#ifndef SQLITE_OMIT_DEPRECATED
-/*
-** This function is now an anachronism. It used to be used to recover from a
-** malloc() failure, but SQLite now does this automatically.
-*/
-SQLITE_API int sqlite3_global_recover(void){
- return SQLITE_OK;
-}
-#endif
-#endif
-
-/*
-** Test to see whether or not the database connection is in autocommit
-** mode. Return TRUE if it is and FALSE if not. Autocommit mode is on
-** by default. Autocommit is disabled by a BEGIN statement and reenabled
-** by the next COMMIT or ROLLBACK.
-**
-******* THIS IS AN EXPERIMENTAL API AND IS SUBJECT TO CHANGE ******
-*/
-SQLITE_API int sqlite3_get_autocommit(sqlite3 *db){
- return db->autoCommit;
-}
-
-#ifdef SQLITE_DEBUG
-/*
-** The following routine is subtituted for constant SQLITE_CORRUPT in
-** debugging builds. This provides a way to set a breakpoint for when
-** corruption is first detected.
-*/
-SQLITE_PRIVATE int sqlite3Corrupt(void){
- return SQLITE_CORRUPT;
-}
-#endif
-
-#ifndef SQLITE_OMIT_DEPRECATED
-/*
-** This is a convenience routine that makes sure that all thread-specific
-** data for this thread has been deallocated.
-**
-** SQLite no longer uses thread-specific data so this routine is now a
-** no-op. It is retained for historical compatibility.
-*/
-SQLITE_API void sqlite3_thread_cleanup(void){
-}
-#endif
-
-/*
-** Return meta information about a specific column of a database table.
-** See comment in sqlite3.h (sqlite.h.in) for details.
-*/
-#ifdef SQLITE_ENABLE_COLUMN_METADATA
-SQLITE_API int sqlite3_table_column_metadata(
- sqlite3 *db, /* Connection handle */
- const char *zDbName, /* Database name or NULL */
- const char *zTableName, /* Table name */
- const char *zColumnName, /* Column name */
- char const **pzDataType, /* OUTPUT: Declared data type */
- char const **pzCollSeq, /* OUTPUT: Collation sequence name */
- int *pNotNull, /* OUTPUT: True if NOT NULL constraint exists */
- int *pPrimaryKey, /* OUTPUT: True if column part of PK */
- int *pAutoinc /* OUTPUT: True if column is auto-increment */
-){
- int rc;
- char *zErrMsg = 0;
- Table *pTab = 0;
- Column *pCol = 0;
- int iCol;
-
- char const *zDataType = 0;
- char const *zCollSeq = 0;
- int notnull = 0;
- int primarykey = 0;
- int autoinc = 0;
-
- /* Ensure the database schema has been loaded */
- sqlite3_mutex_enter(db->mutex);
- (void)sqlite3SafetyOn(db);
- sqlite3BtreeEnterAll(db);
- rc = sqlite3Init(db, &zErrMsg);
- if( SQLITE_OK!=rc ){
- goto error_out;
- }
-
- /* Locate the table in question */
- pTab = sqlite3FindTable(db, zTableName, zDbName);
- if( !pTab || pTab->pSelect ){
- pTab = 0;
- goto error_out;
- }
-
- /* Find the column for which info is requested */
- if( sqlite3IsRowid(zColumnName) ){
- iCol = pTab->iPKey;
- if( iCol>=0 ){
- pCol = &pTab->aCol[iCol];
- }
- }else{
- for(iCol=0; iCol<pTab->nCol; iCol++){
- pCol = &pTab->aCol[iCol];
- if( 0==sqlite3StrICmp(pCol->zName, zColumnName) ){
- break;
- }
- }
- if( iCol==pTab->nCol ){
- pTab = 0;
- goto error_out;
- }
- }
-
- /* The following block stores the meta information that will be returned
- ** to the caller in local variables zDataType, zCollSeq, notnull, primarykey
- ** and autoinc. At this point there are two possibilities:
- **
- ** 1. The specified column name was rowid", "oid" or "_rowid_"
- ** and there is no explicitly declared IPK column.
- **
- ** 2. The table is not a view and the column name identified an
- ** explicitly declared column. Copy meta information from *pCol.
- */
- if( pCol ){
- zDataType = pCol->zType;
- zCollSeq = pCol->zColl;
- notnull = pCol->notNull!=0;
- primarykey = pCol->isPrimKey!=0;
- autoinc = pTab->iPKey==iCol && (pTab->tabFlags & TF_Autoincrement)!=0;
- }else{
- zDataType = "INTEGER";
- primarykey = 1;
- }
- if( !zCollSeq ){
- zCollSeq = "BINARY";
- }
-
-error_out:
- sqlite3BtreeLeaveAll(db);
- (void)sqlite3SafetyOff(db);
-
- /* Whether the function call succeeded or failed, set the output parameters
- ** to whatever their local counterparts contain. If an error did occur,
- ** this has the effect of zeroing all output parameters.
- */
- if( pzDataType ) *pzDataType = zDataType;
- if( pzCollSeq ) *pzCollSeq = zCollSeq;
- if( pNotNull ) *pNotNull = notnull;
- if( pPrimaryKey ) *pPrimaryKey = primarykey;
- if( pAutoinc ) *pAutoinc = autoinc;
-
- if( SQLITE_OK==rc && !pTab ){
- sqlite3DbFree(db, zErrMsg);
- zErrMsg = sqlite3MPrintf(db, "no such table column: %s.%s", zTableName,
- zColumnName);
- rc = SQLITE_ERROR;
- }
- sqlite3Error(db, rc, (zErrMsg?"%s":0), zErrMsg);
- sqlite3DbFree(db, zErrMsg);
- rc = sqlite3ApiExit(db, rc);
- sqlite3_mutex_leave(db->mutex);
- return rc;
-}
-#endif
-
-/*
-** Sleep for a little while. Return the amount of time slept.
-*/
-SQLITE_API int sqlite3_sleep(int ms){
- sqlite3_vfs *pVfs;
- int rc;
- pVfs = sqlite3_vfs_find(0);
- if( pVfs==0 ) return 0;
-
- /* This function works in milliseconds, but the underlying OsSleep()
- ** API uses microseconds. Hence the 1000's.
- */
- rc = (sqlite3OsSleep(pVfs, 1000*ms)/1000);
- return rc;
-}
-
-/*
-** Enable or disable the extended result codes.
-*/
-SQLITE_API int sqlite3_extended_result_codes(sqlite3 *db, int onoff){
- sqlite3_mutex_enter(db->mutex);
- db->errMask = onoff ? 0xffffffff : 0xff;
- sqlite3_mutex_leave(db->mutex);
- return SQLITE_OK;
-}
-
-/*
-** Invoke the xFileControl method on a particular database.
-*/
-SQLITE_API int sqlite3_file_control(sqlite3 *db, const char *zDbName, int op, void *pArg){
- int rc = SQLITE_ERROR;
- int iDb;
- sqlite3_mutex_enter(db->mutex);
- if( zDbName==0 ){
- iDb = 0;
- }else{
- for(iDb=0; iDb<db->nDb; iDb++){
- if( strcmp(db->aDb[iDb].zName, zDbName)==0 ) break;
- }
- }
- if( iDb<db->nDb ){
- Btree *pBtree = db->aDb[iDb].pBt;
- if( pBtree ){
- Pager *pPager;
- sqlite3_file *fd;
- sqlite3BtreeEnter(pBtree);
- pPager = sqlite3BtreePager(pBtree);
- assert( pPager!=0 );
- fd = sqlite3PagerFile(pPager);
- assert( fd!=0 );
- if( fd->pMethods ){
- rc = sqlite3OsFileControl(fd, op, pArg);
- }
- sqlite3BtreeLeave(pBtree);
- }
- }
- sqlite3_mutex_leave(db->mutex);
- return rc;
-}
-
-/*
-** Interface to the testing logic.
-*/
-SQLITE_API int sqlite3_test_control(int op, ...){
- int rc = 0;
-#ifndef SQLITE_OMIT_BUILTIN_TEST
- va_list ap;
- va_start(ap, op);
- switch( op ){
-
- /*
- ** Save the current state of the PRNG.
- */
- case SQLITE_TESTCTRL_PRNG_SAVE: {
- sqlite3PrngSaveState();
- break;
- }
-
- /*
- ** Restore the state of the PRNG to the last state saved using
- ** PRNG_SAVE. If PRNG_SAVE has never before been called, then
- ** this verb acts like PRNG_RESET.
- */
- case SQLITE_TESTCTRL_PRNG_RESTORE: {
- sqlite3PrngRestoreState();
- break;
- }
-
- /*
- ** Reset the PRNG back to its uninitialized state. The next call
- ** to sqlite3_randomness() will reseed the PRNG using a single call
- ** to the xRandomness method of the default VFS.
- */
- case SQLITE_TESTCTRL_PRNG_RESET: {
- sqlite3PrngResetState();
- break;
- }
-
- /*
- ** sqlite3_test_control(BITVEC_TEST, size, program)
- **
- ** Run a test against a Bitvec object of size. The program argument
- ** is an array of integers that defines the test. Return -1 on a
- ** memory allocation error, 0 on success, or non-zero for an error.
- ** See the sqlite3BitvecBuiltinTest() for additional information.
- */
- case SQLITE_TESTCTRL_BITVEC_TEST: {
- int sz = va_arg(ap, int);
- int *aProg = va_arg(ap, int*);
- rc = sqlite3BitvecBuiltinTest(sz, aProg);
- break;
- }
-
- /*
- ** sqlite3_test_control(BENIGN_MALLOC_HOOKS, xBegin, xEnd)
- **
- ** Register hooks to call to indicate which malloc() failures
- ** are benign.
- */
- case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS: {
- typedef void (*void_function)(void);
- void_function xBenignBegin;
- void_function xBenignEnd;
- xBenignBegin = va_arg(ap, void_function);
- xBenignEnd = va_arg(ap, void_function);
- sqlite3BenignMallocHooks(xBenignBegin, xBenignEnd);
- break;
- }
-
- /*
- ** sqlite3_test_control(SQLITE_TESTCTRL_PENDING_BYTE, unsigned int X)
- **
- ** Set the PENDING byte to the value in the argument, if X>0.
- ** Make no changes if X==0. Return the value of the pending byte
- ** as it existing before this routine was called.
- **
- ** IMPORTANT: Changing the PENDING byte from 0x40000000 results in
- ** an incompatible database file format. Changing the PENDING byte
- ** while any database connection is open results in undefined and
- ** dileterious behavior.
- */
- case SQLITE_TESTCTRL_PENDING_BYTE: {
- unsigned int newVal = va_arg(ap, unsigned int);
- rc = sqlite3PendingByte;
- if( newVal ) sqlite3PendingByte = newVal;
- break;
- }
-
- /*
- ** sqlite3_test_control(SQLITE_TESTCTRL_ASSERT, int X)
- **
- ** This action provides a run-time test to see whether or not
- ** assert() was enabled at compile-time. If X is true and assert()
- ** is enabled, then the return value is true. If X is true and
- ** assert() is disabled, then the return value is zero. If X is
- ** false and assert() is enabled, then the assertion fires and the
- ** process aborts. If X is false and assert() is disabled, then the
- ** return value is zero.
- */
- case SQLITE_TESTCTRL_ASSERT: {
- volatile int x = 0;
- assert( (x = va_arg(ap,int))!=0 );
- rc = x;
- break;
- }
-
-
- /*
- ** sqlite3_test_control(SQLITE_TESTCTRL_ALWAYS, int X)
- **
- ** This action provides a run-time test to see how the ALWAYS and
- ** NEVER macros were defined at compile-time.
- **
- ** The return value is ALWAYS(X).
- **
- ** The recommended test is X==2. If the return value is 2, that means
- ** ALWAYS() and NEVER() are both no-op pass-through macros, which is the
- ** default setting. If the return value is 1, then ALWAYS() is either
- ** hard-coded to true or else it asserts if its argument is false.
- ** The first behavior (hard-coded to true) is the case if
- ** SQLITE_TESTCTRL_ASSERT shows that assert() is disabled and the second
- ** behavior (assert if the argument to ALWAYS() is false) is the case if
- ** SQLITE_TESTCTRL_ASSERT shows that assert() is enabled.
- **
- ** The run-time test procedure might look something like this:
- **
- ** if( sqlite3_test_control(SQLITE_TESTCTRL_ALWAYS, 2)==2 ){
- ** // ALWAYS() and NEVER() are no-op pass-through macros
- ** }else if( sqlite3_test_control(SQLITE_TESTCTRL_ASSERT, 1) ){
- ** // ALWAYS(x) asserts that x is true. NEVER(x) asserts x is false.
- ** }else{
- ** // ALWAYS(x) is a constant 1. NEVER(x) is a constant 0.
- ** }
- */
- case SQLITE_TESTCTRL_ALWAYS: {
- int x = va_arg(ap,int);
- rc = ALWAYS(x);
- break;
- }
-
- /* sqlite3_test_control(SQLITE_TESTCTRL_RESERVE, sqlite3 *db, int N)
- **
- ** Set the nReserve size to N for the main database on the database
- ** connection db.
- */
- case SQLITE_TESTCTRL_RESERVE: {
- sqlite3 *db = va_arg(ap, sqlite3*);
- int x = va_arg(ap,int);
- sqlite3_mutex_enter(db->mutex);
- sqlite3BtreeSetPageSize(db->aDb[0].pBt, 0, x, 0);
- sqlite3_mutex_leave(db->mutex);
- break;
- }
-
- }
- va_end(ap);
-#endif /* SQLITE_OMIT_BUILTIN_TEST */
- return rc;
-}
-
-/************** End of main.c ************************************************/
-/************** Begin file notify.c ******************************************/
-/*
-** 2009 March 3
-**
-** 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 implementation of the sqlite3_unlock_notify()
-** API method and its associated functionality.
-**
-** $Id: notify.c,v 1.4 2009/04/07 22:06:57 drh Exp $
-*/
-
-/* Omit this entire file if SQLITE_ENABLE_UNLOCK_NOTIFY is not defined. */
-#ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
-
-/*
-** Public interfaces:
-**
-** sqlite3ConnectionBlocked()
-** sqlite3ConnectionUnlocked()
-** sqlite3ConnectionClosed()
-** sqlite3_unlock_notify()
-*/
-
-#define assertMutexHeld() \
- assert( sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)) )
-
-/*
-** Head of a linked list of all sqlite3 objects created by this process
-** for which either sqlite3.pBlockingConnection or sqlite3.pUnlockConnection
-** is not NULL. This variable may only accessed while the STATIC_MASTER
-** mutex is held.
-*/
-static sqlite3 *SQLITE_WSD sqlite3BlockedList = 0;
-
-#ifndef NDEBUG
-/*
-** This function is a complex assert() that verifies the following
-** properties of the blocked connections list:
-**
-** 1) Each entry in the list has a non-NULL value for either
-** pUnlockConnection or pBlockingConnection, or both.
-**
-** 2) All entries in the list that share a common value for
-** xUnlockNotify are grouped together.
-**
-** 3) If the argument db is not NULL, then none of the entries in the
-** blocked connections list have pUnlockConnection or pBlockingConnection
-** set to db. This is used when closing connection db.
-*/
-static void checkListProperties(sqlite3 *db){
- sqlite3 *p;
- for(p=sqlite3BlockedList; p; p=p->pNextBlocked){
- int seen = 0;
- sqlite3 *p2;
-
- /* Verify property (1) */
- assert( p->pUnlockConnection || p->pBlockingConnection );
-
- /* Verify property (2) */
- for(p2=sqlite3BlockedList; p2!=p; p2=p2->pNextBlocked){
- if( p2->xUnlockNotify==p->xUnlockNotify ) seen = 1;
- assert( p2->xUnlockNotify==p->xUnlockNotify || !seen );
- assert( db==0 || p->pUnlockConnection!=db );
- assert( db==0 || p->pBlockingConnection!=db );
- }
- }
-}
-#else
-# define checkListProperties(x)
-#endif
-
-/*
-** Remove connection db from the blocked connections list. If connection
-** db is not currently a part of the list, this function is a no-op.
-*/
-static void removeFromBlockedList(sqlite3 *db){
- sqlite3 **pp;
- assertMutexHeld();
- for(pp=&sqlite3BlockedList; *pp; pp = &(*pp)->pNextBlocked){
- if( *pp==db ){
- *pp = (*pp)->pNextBlocked;
- break;
- }
- }
-}
-
-/*
-** Add connection db to the blocked connections list. It is assumed
-** that it is not already a part of the list.
-*/
-static void addToBlockedList(sqlite3 *db){
- sqlite3 **pp;
- assertMutexHeld();
- for(
- pp=&sqlite3BlockedList;
- *pp && (*pp)->xUnlockNotify!=db->xUnlockNotify;
- pp=&(*pp)->pNextBlocked
- );
- db->pNextBlocked = *pp;
- *pp = db;
-}
-
-/*
-** Obtain the STATIC_MASTER mutex.
-*/
-static void enterMutex(void){
- sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
- checkListProperties(0);
-}
-
-/*
-** Release the STATIC_MASTER mutex.
-*/
-static void leaveMutex(void){
- assertMutexHeld();
- checkListProperties(0);
- sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
-}
-
-/*
-** Register an unlock-notify callback.
-**
-** This is called after connection "db" has attempted some operation
-** but has received an SQLITE_LOCKED error because another connection
-** (call it pOther) in the same process was busy using the same shared
-** cache. pOther is found by looking at db->pBlockingConnection.
-**
-** If there is no blocking connection, the callback is invoked immediately,
-** before this routine returns.
-**
-** If pOther is already blocked on db, then report SQLITE_LOCKED, to indicate
-** a deadlock.
-**
-** Otherwise, make arrangements to invoke xNotify when pOther drops
-** its locks.
-**
-** Each call to this routine overrides any prior callbacks registered
-** on the same "db". If xNotify==0 then any prior callbacks are immediately
-** cancelled.
-*/
-SQLITE_API int sqlite3_unlock_notify(
- sqlite3 *db,
- void (*xNotify)(void **, int),
- void *pArg
-){
- int rc = SQLITE_OK;
-
- sqlite3_mutex_enter(db->mutex);
- enterMutex();
-
- if( xNotify==0 ){
- removeFromBlockedList(db);
- db->pUnlockConnection = 0;
- db->xUnlockNotify = 0;
- db->pUnlockArg = 0;
- }else if( 0==db->pBlockingConnection ){
- /* The blocking transaction has been concluded. Or there never was a
- ** blocking transaction. In either case, invoke the notify callback
- ** immediately.
- */
- xNotify(&pArg, 1);
- }else{
- sqlite3 *p;
-
- for(p=db->pBlockingConnection; p && p!=db; p=p->pUnlockConnection){}
- if( p ){
- rc = SQLITE_LOCKED; /* Deadlock detected. */
- }else{
- db->pUnlockConnection = db->pBlockingConnection;
- db->xUnlockNotify = xNotify;
- db->pUnlockArg = pArg;
- removeFromBlockedList(db);
- addToBlockedList(db);
- }
- }
-
- leaveMutex();
- assert( !db->mallocFailed );
- sqlite3Error(db, rc, (rc?"database is deadlocked":0));
- sqlite3_mutex_leave(db->mutex);
- return rc;
-}
-
-/*
-** This function is called while stepping or preparing a statement
-** associated with connection db. The operation will return SQLITE_LOCKED
-** to the user because it requires a lock that will not be available
-** until connection pBlocker concludes its current transaction.
-*/
-SQLITE_PRIVATE void sqlite3ConnectionBlocked(sqlite3 *db, sqlite3 *pBlocker){
- enterMutex();
- if( db->pBlockingConnection==0 && db->pUnlockConnection==0 ){
- addToBlockedList(db);
- }
- db->pBlockingConnection = pBlocker;
- leaveMutex();
-}
-
-/*
-** This function is called when
-** the transaction opened by database db has just finished. Locks held
-** by database connection db have been released.
-**
-** This function loops through each entry in the blocked connections
-** list and does the following:
-**
-** 1) If the sqlite3.pBlockingConnection member of a list entry is
-** set to db, then set pBlockingConnection=0.
-**
-** 2) If the sqlite3.pUnlockConnection member of a list entry is
-** set to db, then invoke the configured unlock-notify callback and
-** set pUnlockConnection=0.
-**
-** 3) If the two steps above mean that pBlockingConnection==0 and
-** pUnlockConnection==0, remove the entry from the blocked connections
-** list.
-*/
-SQLITE_PRIVATE void sqlite3ConnectionUnlocked(sqlite3 *db){
- void (*xUnlockNotify)(void **, int) = 0; /* Unlock-notify cb to invoke */
- int nArg = 0; /* Number of entries in aArg[] */
- sqlite3 **pp; /* Iterator variable */
- void **aArg; /* Arguments to the unlock callback */
- void **aDyn = 0; /* Dynamically allocated space for aArg[] */
- void *aStatic[16]; /* Starter space for aArg[]. No malloc required */
-
- aArg = aStatic;
- enterMutex(); /* Enter STATIC_MASTER mutex */
-
- /* This loop runs once for each entry in the blocked-connections list. */
- for(pp=&sqlite3BlockedList; *pp; /* no-op */ ){
- sqlite3 *p = *pp;
-
- /* Step 1. */
- if( p->pBlockingConnection==db ){
- p->pBlockingConnection = 0;
- }
-
- /* Step 2. */
- if( p->pUnlockConnection==db ){
- assert( p->xUnlockNotify );
- if( p->xUnlockNotify!=xUnlockNotify && nArg!=0 ){
- xUnlockNotify(aArg, nArg);
- nArg = 0;
- }
-
- sqlite3BeginBenignMalloc();
- assert( aArg==aDyn || (aDyn==0 && aArg==aStatic) );
- assert( nArg<=(int)ArraySize(aStatic) || aArg==aDyn );
- if( (!aDyn && nArg==(int)ArraySize(aStatic))
- || (aDyn && nArg==(int)(sqlite3DbMallocSize(db, aDyn)/sizeof(void*)))
- ){
- /* The aArg[] array needs to grow. */
- void **pNew = (void **)sqlite3Malloc(nArg*sizeof(void *)*2);
- if( pNew ){
- memcpy(pNew, aArg, nArg*sizeof(void *));
- sqlite3_free(aDyn);
- aDyn = aArg = pNew;
- }else{
- /* This occurs when the array of context pointers that need to
- ** be passed to the unlock-notify callback is larger than the
- ** aStatic[] array allocated on the stack and the attempt to
- ** allocate a larger array from the heap has failed.
- **
- ** This is a difficult situation to handle. Returning an error
- ** code to the caller is insufficient, as even if an error code
- ** is returned the transaction on connection db will still be
- ** closed and the unlock-notify callbacks on blocked connections
- ** will go unissued. This might cause the application to wait
- ** indefinitely for an unlock-notify callback that will never
- ** arrive.
- **
- ** Instead, invoke the unlock-notify callback with the context
- ** array already accumulated. We can then clear the array and
- ** begin accumulating any further context pointers without
- ** requiring any dynamic allocation. This is sub-optimal because
- ** it means that instead of one callback with a large array of
- ** context pointers the application will receive two or more
- ** callbacks with smaller arrays of context pointers, which will
- ** reduce the applications ability to prioritize multiple
- ** connections. But it is the best that can be done under the
- ** circumstances.
- */
- xUnlockNotify(aArg, nArg);
- nArg = 0;
- }
- }
- sqlite3EndBenignMalloc();
-
- aArg[nArg++] = p->pUnlockArg;
- xUnlockNotify = p->xUnlockNotify;
- p->pUnlockConnection = 0;
- p->xUnlockNotify = 0;
- p->pUnlockArg = 0;
- }
-
- /* Step 3. */
- if( p->pBlockingConnection==0 && p->pUnlockConnection==0 ){
- /* Remove connection p from the blocked connections list. */
- *pp = p->pNextBlocked;
- p->pNextBlocked = 0;
- }else{
- pp = &p->pNextBlocked;
- }
- }
-
- if( nArg!=0 ){
- xUnlockNotify(aArg, nArg);
- }
- sqlite3_free(aDyn);
- leaveMutex(); /* Leave STATIC_MASTER mutex */
-}
-
-/*
-** This is called when the database connection passed as an argument is
-** being closed. The connection is removed from the blocked list.
-*/
-SQLITE_PRIVATE void sqlite3ConnectionClosed(sqlite3 *db){
- sqlite3ConnectionUnlocked(db);
- enterMutex();
- removeFromBlockedList(db);
- checkListProperties(db);
- leaveMutex();
-}
-#endif
-
-/************** End of notify.c **********************************************/
-/************** Begin file fts3.c ********************************************/
-/*
-** 2006 Oct 10
-**
-** 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 is an SQLite module implementing full-text search.
-*/
-
-/*
-** The code in this file is only compiled if:
-**
-** * The FTS3 module is being built as an extension
-** (in which case SQLITE_CORE is not defined), or
-**
-** * The FTS3 module is being built into the core of
-** SQLite (in which case SQLITE_ENABLE_FTS3 is defined).
-*/
-
-/* TODO(shess) Consider exporting this comment to an HTML file or the
-** wiki.
-*/
-/* The full-text index is stored in a series of b+tree (-like)
-** structures called segments which map terms to doclists. The
-** structures are like b+trees in layout, but are constructed from the
-** bottom up in optimal fashion and are not updatable. Since trees
-** are built from the bottom up, things will be described from the
-** bottom up.
-**
-**
-**** Varints ****
-** The basic unit of encoding is a variable-length integer called a
-** varint. We encode variable-length integers in little-endian order
-** using seven bits * per byte as follows:
-**
-** KEY:
-** A = 0xxxxxxx 7 bits of data and one flag bit
-** B = 1xxxxxxx 7 bits of data and one flag bit
-**
-** 7 bits - A
-** 14 bits - BA
-** 21 bits - BBA
-** and so on.
-**
-** This is identical to how sqlite encodes varints (see util.c).
-**
-**
-**** Document lists ****
-** A doclist (document list) holds a docid-sorted list of hits for a
-** given term. Doclists hold docids, and can optionally associate
-** token positions and offsets with docids.
-**
-** A DL_POSITIONS_OFFSETS doclist is stored like this:
-**
-** array {
-** varint docid;
-** array { (position list for column 0)
-** varint position; (delta from previous position plus POS_BASE)
-** varint startOffset; (delta from previous startOffset)
-** varint endOffset; (delta from startOffset)
-** }
-** array {
-** varint POS_COLUMN; (marks start of position list for new column)
-** varint column; (index of new column)
-** array {
-** varint position; (delta from previous position plus POS_BASE)
-** varint startOffset;(delta from previous startOffset)
-** varint endOffset; (delta from startOffset)
-** }
-** }
-** varint POS_END; (marks end of positions for this document.
-** }
-**
-** Here, array { X } means zero or more occurrences of X, adjacent in
-** memory. A "position" is an index of a token in the token stream
-** generated by the tokenizer, while an "offset" is a byte offset,
-** both based at 0. Note that POS_END and POS_COLUMN occur in the
-** same logical place as the position element, and act as sentinals
-** ending a position list array.
-**
-** A DL_POSITIONS doclist omits the startOffset and endOffset
-** information. A DL_DOCIDS doclist omits both the position and
-** offset information, becoming an array of varint-encoded docids.
-**
-** On-disk data is stored as type DL_DEFAULT, so we don't serialize
-** the type. Due to how deletion is implemented in the segmentation
-** system, on-disk doclists MUST store at least positions.
-**
-**
-**** Segment leaf nodes ****
-** Segment leaf nodes store terms and doclists, ordered by term. Leaf
-** nodes are written using LeafWriter, and read using LeafReader (to
-** iterate through a single leaf node's data) and LeavesReader (to
-** iterate through a segment's entire leaf layer). Leaf nodes have
-** the format:
-**
-** varint iHeight; (height from leaf level, always 0)
-** varint nTerm; (length of first term)
-** char pTerm[nTerm]; (content of first term)
-** varint nDoclist; (length of term's associated doclist)
-** char pDoclist[nDoclist]; (content of doclist)
-** array {
-** (further terms are delta-encoded)
-** varint nPrefix; (length of prefix shared with previous term)
-** varint nSuffix; (length of unshared suffix)
-** char pTermSuffix[nSuffix];(unshared suffix of next term)
-** varint nDoclist; (length of term's associated doclist)
-** char pDoclist[nDoclist]; (content of doclist)
-** }
-**
-** Here, array { X } means zero or more occurrences of X, adjacent in
-** memory.
-**
-** Leaf nodes are broken into blocks which are stored contiguously in
-** the %_segments table in sorted order. This means that when the end
-** of a node is reached, the next term is in the node with the next
-** greater node id.
-**
-** New data is spilled to a new leaf node when the current node
-** exceeds LEAF_MAX bytes (default 2048). New data which itself is
-** larger than STANDALONE_MIN (default 1024) is placed in a standalone
-** node (a leaf node with a single term and doclist). The goal of
-** these settings is to pack together groups of small doclists while
-** making it efficient to directly access large doclists. The
-** assumption is that large doclists represent terms which are more
-** likely to be query targets.
-**
-** TODO(shess) It may be useful for blocking decisions to be more
-** dynamic. For instance, it may make more sense to have a 2.5k leaf
-** node rather than splitting into 2k and .5k nodes. My intuition is
-** that this might extend through 2x or 4x the pagesize.
-**
-**
-**** Segment interior nodes ****
-** Segment interior nodes store blockids for subtree nodes and terms
-** to describe what data is stored by the each subtree. Interior
-** nodes are written using InteriorWriter, and read using
-** InteriorReader. InteriorWriters are created as needed when
-** SegmentWriter creates new leaf nodes, or when an interior node
-** itself grows too big and must be split. The format of interior
-** nodes:
-**
-** varint iHeight; (height from leaf level, always >0)
-** varint iBlockid; (block id of node's leftmost subtree)
-** optional {
-** varint nTerm; (length of first term)
-** char pTerm[nTerm]; (content of first term)
-** array {
-** (further terms are delta-encoded)
-** varint nPrefix; (length of shared prefix with previous term)
-** varint nSuffix; (length of unshared suffix)
-** char pTermSuffix[nSuffix]; (unshared suffix of next term)
-** }
-** }
-**
-** Here, optional { X } means an optional element, while array { X }
-** means zero or more occurrences of X, adjacent in memory.
-**
-** An interior node encodes n terms separating n+1 subtrees. The
-** subtree blocks are contiguous, so only the first subtree's blockid
-** is encoded. The subtree at iBlockid will contain all terms less
-** than the first term encoded (or all terms if no term is encoded).
-** Otherwise, for terms greater than or equal to pTerm[i] but less
-** than pTerm[i+1], the subtree for that term will be rooted at
-** iBlockid+i. Interior nodes only store enough term data to
-** distinguish adjacent children (if the rightmost term of the left
-** child is "something", and the leftmost term of the right child is
-** "wicked", only "w" is stored).
-**
-** New data is spilled to a new interior node at the same height when
-** the current node exceeds INTERIOR_MAX bytes (default 2048).
-** INTERIOR_MIN_TERMS (default 7) keeps large terms from monopolizing
-** interior nodes and making the tree too skinny. The interior nodes
-** at a given height are naturally tracked by interior nodes at
-** height+1, and so on.
-**
-**
-**** Segment directory ****
-** The segment directory in table %_segdir stores meta-information for
-** merging and deleting segments, and also the root node of the
-** segment's tree.
-**
-** The root node is the top node of the segment's tree after encoding
-** the entire segment, restricted to ROOT_MAX bytes (default 1024).
-** This could be either a leaf node or an interior node. If the top
-** node requires more than ROOT_MAX bytes, it is flushed to %_segments
-** and a new root interior node is generated (which should always fit
-** within ROOT_MAX because it only needs space for 2 varints, the
-** height and the blockid of the previous root).
-**
-** The meta-information in the segment directory is:
-** level - segment level (see below)
-** idx - index within level
-** - (level,idx uniquely identify a segment)
-** start_block - first leaf node
-** leaves_end_block - last leaf node
-** end_block - last block (including interior nodes)
-** root - contents of root node
-**
-** If the root node is a leaf node, then start_block,
-** leaves_end_block, and end_block are all 0.
-**
-**
-**** Segment merging ****
-** To amortize update costs, segments are grouped into levels and
-** merged in batches. Each increase in level represents exponentially
-** more documents.
-**
-** New documents (actually, document updates) are tokenized and
-** written individually (using LeafWriter) to a level 0 segment, with
-** incrementing idx. When idx reaches MERGE_COUNT (default 16), all
-** level 0 segments are merged into a single level 1 segment. Level 1
-** is populated like level 0, and eventually MERGE_COUNT level 1
-** segments are merged to a single level 2 segment (representing
-** MERGE_COUNT^2 updates), and so on.
-**
-** A segment merge traverses all segments at a given level in
-** parallel, performing a straightforward sorted merge. Since segment
-** leaf nodes are written in to the %_segments table in order, this
-** merge traverses the underlying sqlite disk structures efficiently.
-** After the merge, all segment blocks from the merged level are
-** deleted.
-**
-** MERGE_COUNT controls how often we merge segments. 16 seems to be
-** somewhat of a sweet spot for insertion performance. 32 and 64 show
-** very similar performance numbers to 16 on insertion, though they're
-** a tiny bit slower (perhaps due to more overhead in merge-time
-** sorting). 8 is about 20% slower than 16, 4 about 50% slower than
-** 16, 2 about 66% slower than 16.
-**
-** At query time, high MERGE_COUNT increases the number of segments
-** which need to be scanned and merged. For instance, with 100k docs
-** inserted:
-**
-** MERGE_COUNT segments
-** 16 25
-** 8 12
-** 4 10
-** 2 6
-**
-** This appears to have only a moderate impact on queries for very
-** frequent terms (which are somewhat dominated by segment merge
-** costs), and infrequent and non-existent terms still seem to be fast
-** even with many segments.
-**
-** TODO(shess) That said, it would be nice to have a better query-side
-** argument for MERGE_COUNT of 16. Also, it is possible/likely that
-** optimizations to things like doclist merging will swing the sweet
-** spot around.
-**
-**
-**
-**** Handling of deletions and updates ****
-** Since we're using a segmented structure, with no docid-oriented
-** index into the term index, we clearly cannot simply update the term
-** index when a document is deleted or updated. For deletions, we
-** write an empty doclist (varint(docid) varint(POS_END)), for updates
-** we simply write the new doclist. Segment merges overwrite older
-** data for a particular docid with newer data, so deletes or updates
-** will eventually overtake the earlier data and knock it out. The
-** query logic likewise merges doclists so that newer data knocks out
-** older data.
-**
-** TODO(shess) Provide a VACUUM type operation to clear out all
-** deletions and duplications. This would basically be a forced merge
-** into a single segment.
-*/
-
-#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3)
-
-#if defined(SQLITE_ENABLE_FTS3) && !defined(SQLITE_CORE)
-# define SQLITE_CORE 1
-#endif
-
-
-/************** Include fts3_expr.h in the middle of fts3.c ******************/
-/************** Begin file fts3_expr.h ***************************************/
-/*
-** 2008 Nov 28
-**
-** 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.
-**
-******************************************************************************
-**
-*/
-
-/************** Include fts3_tokenizer.h in the middle of fts3_expr.h ********/
-/************** Begin file fts3_tokenizer.h **********************************/
-/*
-** 2006 July 10
-**
-** The author disclaims copyright to this source code.
-**
-*************************************************************************
-** Defines the interface to tokenizers used by fulltext-search. There
-** are three basic components:
-**
-** sqlite3_tokenizer_module is a singleton defining the tokenizer
-** interface functions. This is essentially the class structure for
-** tokenizers.
-**
-** sqlite3_tokenizer is used to define a particular tokenizer, perhaps
-** including customization information defined at creation time.
-**
-** sqlite3_tokenizer_cursor is generated by a tokenizer to generate
-** tokens from a particular input.
-*/
-#ifndef _FTS3_TOKENIZER_H_
-#define _FTS3_TOKENIZER_H_
-
-/* TODO(shess) Only used for SQLITE_OK and SQLITE_DONE at this time.
-** If tokenizers are to be allowed to call sqlite3_*() functions, then
-** we will need a way to register the API consistently.
-*/
-
-/*
-** Structures used by the tokenizer interface. When a new tokenizer
-** implementation is registered, the caller provides a pointer to
-** an sqlite3_tokenizer_module containing pointers to the callback
-** functions that make up an implementation.
-**
-** When an fts3 table is created, it passes any arguments passed to
-** the tokenizer clause of the CREATE VIRTUAL TABLE statement to the
-** sqlite3_tokenizer_module.xCreate() function of the requested tokenizer
-** implementation. The xCreate() function in turn returns an
-** sqlite3_tokenizer structure representing the specific tokenizer to
-** be used for the fts3 table (customized by the tokenizer clause arguments).
-**
-** To tokenize an input buffer, the sqlite3_tokenizer_module.xOpen()
-** method is called. It returns an sqlite3_tokenizer_cursor object
-** that may be used to tokenize a specific input buffer based on
-** the tokenization rules supplied by a specific sqlite3_tokenizer
-** object.
-*/
-typedef struct sqlite3_tokenizer_module sqlite3_tokenizer_module;
-typedef struct sqlite3_tokenizer sqlite3_tokenizer;
-typedef struct sqlite3_tokenizer_cursor sqlite3_tokenizer_cursor;
-
-struct sqlite3_tokenizer_module {
-
- /*
- ** Structure version. Should always be set to 0.
- */
- int iVersion;
-
- /*
- ** Create a new tokenizer. The values in the argv[] array are the
- ** arguments passed to the "tokenizer" clause of the CREATE VIRTUAL
- ** TABLE statement that created the fts3 table. For example, if
- ** the following SQL is executed:
- **
- ** CREATE .. USING fts3( ... , tokenizer <tokenizer-name> arg1 arg2)
- **
- ** then argc is set to 2, and the argv[] array contains pointers
- ** to the strings "arg1" and "arg2".
- **
- ** This method should return either SQLITE_OK (0), or an SQLite error
- ** code. If SQLITE_OK is returned, then *ppTokenizer should be set
- ** to point at the newly created tokenizer structure. The generic
- ** sqlite3_tokenizer.pModule variable should not be initialised by
- ** this callback. The caller will do so.
- */
- int (*xCreate)(
- int argc, /* Size of argv array */
- const char *const*argv, /* Tokenizer argument strings */
- sqlite3_tokenizer **ppTokenizer /* OUT: Created tokenizer */
- );
-
- /*
- ** Destroy an existing tokenizer. The fts3 module calls this method
- ** exactly once for each successful call to xCreate().
- */
- int (*xDestroy)(sqlite3_tokenizer *pTokenizer);
-
- /*
- ** Create a tokenizer cursor to tokenize an input buffer. The caller
- ** is responsible for ensuring that the input buffer remains valid
- ** until the cursor is closed (using the xClose() method).
- */
- int (*xOpen)(
- sqlite3_tokenizer *pTokenizer, /* Tokenizer object */
- const char *pInput, int nBytes, /* Input buffer */
- sqlite3_tokenizer_cursor **ppCursor /* OUT: Created tokenizer cursor */
- );
-
- /*
- ** Destroy an existing tokenizer cursor. The fts3 module calls this
- ** method exactly once for each successful call to xOpen().
- */
- int (*xClose)(sqlite3_tokenizer_cursor *pCursor);
-
- /*
- ** Retrieve the next token from the tokenizer cursor pCursor. This
- ** method should either return SQLITE_OK and set the values of the
- ** "OUT" variables identified below, or SQLITE_DONE to indicate that
- ** the end of the buffer has been reached, or an SQLite error code.
- **
- ** *ppToken should be set to point at a buffer containing the
- ** normalized version of the token (i.e. after any case-folding and/or
- ** stemming has been performed). *pnBytes should be set to the length
- ** of this buffer in bytes. The input text that generated the token is
- ** identified by the byte offsets returned in *piStartOffset and
- ** *piEndOffset. *piStartOffset should be set to the index of the first
- ** byte of the token in the input buffer. *piEndOffset should be set
- ** to the index of the first byte just past the end of the token in
- ** the input buffer.
- **
- ** The buffer *ppToken is set to point at is managed by the tokenizer
- ** implementation. It is only required to be valid until the next call
- ** to xNext() or xClose().
- */
- /* TODO(shess) current implementation requires pInput to be
- ** nul-terminated. This should either be fixed, or pInput/nBytes
- ** should be converted to zInput.
- */
- int (*xNext)(
- sqlite3_tokenizer_cursor *pCursor, /* Tokenizer cursor */
- const char **ppToken, int *pnBytes, /* OUT: Normalized text for token */
- int *piStartOffset, /* OUT: Byte offset of token in input buffer */
- int *piEndOffset, /* OUT: Byte offset of end of token in input buffer */
- int *piPosition /* OUT: Number of tokens returned before this one */
- );
-};
-
-struct sqlite3_tokenizer {
- const sqlite3_tokenizer_module *pModule; /* The module for this tokenizer */
- /* Tokenizer implementations will typically add additional fields */
-};
-
-struct sqlite3_tokenizer_cursor {
- sqlite3_tokenizer *pTokenizer; /* Tokenizer for this cursor. */
- /* Tokenizer implementations will typically add additional fields */
-};
-
-#endif /* _FTS3_TOKENIZER_H_ */
-
-/************** End of fts3_tokenizer.h **************************************/
-/************** Continuing where we left off in fts3_expr.h ******************/
-
-/*
-** The following describes the syntax supported by the fts3 MATCH
-** operator in a similar format to that used by the lemon parser
-** generator. This module does not use actually lemon, it uses a
-** custom parser.
-**
-** query ::= andexpr (OR andexpr)*.
-**
-** andexpr ::= notexpr (AND? notexpr)*.
-**
-** notexpr ::= nearexpr (NOT nearexpr|-TOKEN)*.
-** notexpr ::= LP query RP.
-**
-** nearexpr ::= phrase (NEAR distance_opt nearexpr)*.
-**
-** distance_opt ::= .
-** distance_opt ::= / INTEGER.
-**
-** phrase ::= TOKEN.
-** phrase ::= COLUMN:TOKEN.
-** phrase ::= "TOKEN TOKEN TOKEN...".
-*/
-
-typedef struct Fts3Expr Fts3Expr;
-typedef struct Fts3Phrase Fts3Phrase;
-
-/*
-** A "phrase" is a sequence of one or more tokens that must match in
-** sequence. A single token is the base case and the most common case.
-** For a sequence of tokens contained in "...", nToken will be the number
-** of tokens in the string.
-*/
-struct Fts3Phrase {
- int nToken; /* Number of tokens in the phrase */
- int iColumn; /* Index of column this phrase must match */
- int isNot; /* Phrase prefixed by unary not (-) operator */
- struct PhraseToken {
- char *z; /* Text of the token */
- int n; /* Number of bytes in buffer pointed to by z */
- int isPrefix; /* True if token ends in with a "*" character */
- } aToken[1]; /* One entry for each token in the phrase */
-};
-
-/*
-** A tree of these objects forms the RHS of a MATCH operator.
-*/
-struct Fts3Expr {
- int eType; /* One of the FTSQUERY_XXX values defined below */
- int nNear; /* Valid if eType==FTSQUERY_NEAR */
- Fts3Expr *pParent; /* pParent->pLeft==this or pParent->pRight==this */
- Fts3Expr *pLeft; /* Left operand */
- Fts3Expr *pRight; /* Right operand */
- Fts3Phrase *pPhrase; /* Valid if eType==FTSQUERY_PHRASE */
-};
-
-SQLITE_PRIVATE int sqlite3Fts3ExprParse(sqlite3_tokenizer *, char **, int, int,
- const char *, int, Fts3Expr **);
-SQLITE_PRIVATE void sqlite3Fts3ExprFree(Fts3Expr *);
-
-/*
-** Candidate values for Fts3Query.eType. Note that the order of the first
-** four values is in order of precedence when parsing expressions. For
-** example, the following:
-**
-** "a OR b AND c NOT d NEAR e"
-**
-** is equivalent to:
-**
-** "a OR (b AND (c NOT (d NEAR e)))"
-*/
-#define FTSQUERY_NEAR 1
-#define FTSQUERY_NOT 2
-#define FTSQUERY_AND 3
-#define FTSQUERY_OR 4
-#define FTSQUERY_PHRASE 5
-
-#ifdef SQLITE_TEST
-SQLITE_PRIVATE void sqlite3Fts3ExprInitTestInterface(sqlite3 *db);
-#endif
-
-/************** End of fts3_expr.h *******************************************/
-/************** Continuing where we left off in fts3.c ***********************/
-/************** Include fts3_hash.h in the middle of fts3.c ******************/
-/************** Begin file fts3_hash.h ***************************************/
-/*
-** 2001 September 22
-**
-** 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 is the header file for the generic hash-table implemenation
-** used in SQLite. We've modified it slightly to serve as a standalone
-** hash table implementation for the full-text indexing module.
-**
-*/
-#ifndef _FTS3_HASH_H_
-#define _FTS3_HASH_H_
-
-/* Forward declarations of structures. */
-typedef struct fts3Hash fts3Hash;
-typedef struct fts3HashElem fts3HashElem;
-
-/* A complete hash table is an instance of the following structure.
-** The internals of this structure are intended to be opaque -- client
-** code should not attempt to access or modify the fields of this structure
-** directly. Change this structure only by using the routines below.
-** However, many of the "procedures" and "functions" for modifying and
-** accessing this structure are really macros, so we can't really make
-** this structure opaque.
-*/
-struct fts3Hash {
- char keyClass; /* HASH_INT, _POINTER, _STRING, _BINARY */
- char copyKey; /* True if copy of key made on insert */
- int count; /* Number of entries in this table */
- fts3HashElem *first; /* The first element of the array */
- int htsize; /* Number of buckets in the hash table */
- struct _fts3ht { /* the hash table */
- int count; /* Number of entries with this hash */
- fts3HashElem *chain; /* Pointer to first entry with this hash */
- } *ht;
-};
-
-/* Each element in the hash table is an instance of the following
-** structure. All elements are stored on a single doubly-linked list.
-**
-** Again, this structure is intended to be opaque, but it can't really
-** be opaque because it is used by macros.
-*/
-struct fts3HashElem {
- fts3HashElem *next, *prev; /* Next and previous elements in the table */
- void *data; /* Data associated with this element */
- void *pKey; int nKey; /* Key associated with this element */
-};
-
-/*
-** There are 2 different modes of operation for a hash table:
-**
-** FTS3_HASH_STRING pKey points to a string that is nKey bytes long
-** (including the null-terminator, if any). Case
-** is respected in comparisons.
-**
-** FTS3_HASH_BINARY pKey points to binary data nKey bytes long.
-** memcmp() is used to compare keys.
-**
-** A copy of the key is made if the copyKey parameter to fts3HashInit is 1.
-*/
-#define FTS3_HASH_STRING 1
-#define FTS3_HASH_BINARY 2
-
-/*
-** Access routines. To delete, insert a NULL pointer.
-*/
-SQLITE_PRIVATE void sqlite3Fts3HashInit(fts3Hash*, int keytype, int copyKey);
-SQLITE_PRIVATE void *sqlite3Fts3HashInsert(fts3Hash*, const void *pKey, int nKey, void *pData);
-SQLITE_PRIVATE void *sqlite3Fts3HashFind(const fts3Hash*, const void *pKey, int nKey);
-SQLITE_PRIVATE void sqlite3Fts3HashClear(fts3Hash*);
-
-/*
-** Shorthand for the functions above
-*/
-#define fts3HashInit sqlite3Fts3HashInit
-#define fts3HashInsert sqlite3Fts3HashInsert
-#define fts3HashFind sqlite3Fts3HashFind
-#define fts3HashClear sqlite3Fts3HashClear
-
-/*
-** Macros for looping over all elements of a hash table. The idiom is
-** like this:
-**
-** fts3Hash h;
-** fts3HashElem *p;
-** ...
-** for(p=fts3HashFirst(&h); p; p=fts3HashNext(p)){
-** SomeStructure *pData = fts3HashData(p);
-** // do something with pData
-** }
-*/
-#define fts3HashFirst(H) ((H)->first)
-#define fts3HashNext(E) ((E)->next)
-#define fts3HashData(E) ((E)->data)
-#define fts3HashKey(E) ((E)->pKey)
-#define fts3HashKeysize(E) ((E)->nKey)
-
-/*
-** Number of entries in a hash table
-*/
-#define fts3HashCount(H) ((H)->count)
-
-#endif /* _FTS3_HASH_H_ */
-
-/************** End of fts3_hash.h *******************************************/
-/************** Continuing where we left off in fts3.c ***********************/
-#ifndef SQLITE_CORE
- SQLITE_EXTENSION_INIT1
-#endif
-
-
-/* TODO(shess) MAN, this thing needs some refactoring. At minimum, it
-** would be nice to order the file better, perhaps something along the
-** lines of:
-**
-** - utility functions
-** - table setup functions
-** - table update functions
-** - table query functions
-**
-** Put the query functions last because they're likely to reference
-** typedefs or functions from the table update section.
-*/
-
-#if 0
-# define FTSTRACE(A) printf A; fflush(stdout)
-#else
-# define FTSTRACE(A)
-#endif
-
-/* It is not safe to call isspace(), tolower(), or isalnum() on
-** hi-bit-set characters. This is the same solution used in the
-** tokenizer.
-*/
-/* TODO(shess) The snippet-generation code should be using the
-** tokenizer-generated tokens rather than doing its own local
-** tokenization.
-*/
-/* TODO(shess) Is __isascii() a portable version of (c&0x80)==0? */
-static int safe_isspace(char c){
- return (c&0x80)==0 ? isspace(c) : 0;
-}
-static int safe_tolower(char c){
- return (c&0x80)==0 ? tolower(c) : c;
-}
-static int safe_isalnum(char c){
- return (c&0x80)==0 ? isalnum(c) : 0;
-}
-
-typedef enum DocListType {
- DL_DOCIDS, /* docids only */
- DL_POSITIONS, /* docids + positions */
- DL_POSITIONS_OFFSETS /* docids + positions + offsets */
-} DocListType;
-
-/*
-** By default, only positions and not offsets are stored in the doclists.
-** To change this so that offsets are stored too, compile with
-**
-** -DDL_DEFAULT=DL_POSITIONS_OFFSETS
-**
-** If DL_DEFAULT is set to DL_DOCIDS, your table can only be inserted
-** into (no deletes or updates).
-*/
-#ifndef DL_DEFAULT
-# define DL_DEFAULT DL_POSITIONS
-#endif
-
-enum {
- POS_END = 0, /* end of this position list */
- POS_COLUMN, /* followed by new column number */
- POS_BASE
-};
-
-/* MERGE_COUNT controls how often we merge segments (see comment at
-** top of file).
-*/
-#define MERGE_COUNT 16
-
-/* utility functions */
-
-/* CLEAR() and SCRAMBLE() abstract memset() on a pointer to a single
-** record to prevent errors of the form:
-**
-** my_function(SomeType *b){
-** memset(b, '\0', sizeof(b)); // sizeof(b)!=sizeof(*b)
-** }
-*/
-/* TODO(shess) Obvious candidates for a header file. */
-#define CLEAR(b) memset(b, '\0', sizeof(*(b)))
-
-#ifndef NDEBUG
-# define SCRAMBLE(b) memset(b, 0x55, sizeof(*(b)))
-#else
-# define SCRAMBLE(b)
-#endif
-
-/* We may need up to VARINT_MAX bytes to store an encoded 64-bit integer. */
-#define VARINT_MAX 10
-
-/* Write a 64-bit variable-length integer to memory starting at p[0].
- * The length of data written will be between 1 and VARINT_MAX bytes.
- * The number of bytes written is returned. */
-static int fts3PutVarint(char *p, sqlite_int64 v){
- unsigned char *q = (unsigned char *) p;
- sqlite_uint64 vu = v;
- do{
- *q++ = (unsigned char) ((vu & 0x7f) | 0x80);
- vu >>= 7;
- }while( vu!=0 );
- q[-1] &= 0x7f; /* turn off high bit in final byte */
- assert( q - (unsigned char *)p <= VARINT_MAX );
- return (int) (q - (unsigned char *)p);
-}
-
-/* Read a 64-bit variable-length integer from memory starting at p[0].
- * Return the number of bytes read, or 0 on error.
- * The value is stored in *v. */
-static int fts3GetVarint(const char *p, sqlite_int64 *v){
- const unsigned char *q = (const unsigned char *) p;
- sqlite_uint64 x = 0, y = 1;
- while( (*q & 0x80) == 0x80 ){
- x += y * (*q++ & 0x7f);
- y <<= 7;
- if( q - (unsigned char *)p >= VARINT_MAX ){ /* bad data */
- assert( 0 );
- return 0;
- }
- }
- x += y * (*q++);
- *v = (sqlite_int64) x;
- return (int) (q - (unsigned char *)p);
-}
-
-static int fts3GetVarint32(const char *p, int *pi){
- sqlite_int64 i;
- int ret = fts3GetVarint(p, &i);
- *pi = (int) i;
- assert( *pi==i );
- return ret;
-}
-
-/*******************************************************************/
-/* DataBuffer is used to collect data into a buffer in piecemeal
-** fashion. It implements the usual distinction between amount of
-** data currently stored (nData) and buffer capacity (nCapacity).
-**
-** dataBufferInit - create a buffer with given initial capacity.
-** dataBufferReset - forget buffer's data, retaining capacity.
-** dataBufferDestroy - free buffer's data.
-** dataBufferSwap - swap contents of two buffers.
-** dataBufferExpand - expand capacity without adding data.
-** dataBufferAppend - append data.
-** dataBufferAppend2 - append two pieces of data at once.
-** dataBufferReplace - replace buffer's data.
-*/
-typedef struct DataBuffer {
- char *pData; /* Pointer to malloc'ed buffer. */
- int nCapacity; /* Size of pData buffer. */
- int nData; /* End of data loaded into pData. */
-} DataBuffer;
-
-static void dataBufferInit(DataBuffer *pBuffer, int nCapacity){
- assert( nCapacity>=0 );
- pBuffer->nData = 0;
- pBuffer->nCapacity = nCapacity;
- pBuffer->pData = nCapacity==0 ? NULL : sqlite3_malloc(nCapacity);
-}
-static void dataBufferReset(DataBuffer *pBuffer){
- pBuffer->nData = 0;
-}
-static void dataBufferDestroy(DataBuffer *pBuffer){
- if( pBuffer->pData!=NULL ) sqlite3_free(pBuffer->pData);
- SCRAMBLE(pBuffer);
-}
-static void dataBufferSwap(DataBuffer *pBuffer1, DataBuffer *pBuffer2){
- DataBuffer tmp = *pBuffer1;
- *pBuffer1 = *pBuffer2;
- *pBuffer2 = tmp;
-}
-static void dataBufferExpand(DataBuffer *pBuffer, int nAddCapacity){
- assert( nAddCapacity>0 );
- /* TODO(shess) Consider expanding more aggressively. Note that the
- ** underlying malloc implementation may take care of such things for
- ** us already.
- */
- if( pBuffer->nData+nAddCapacity>pBuffer->nCapacity ){
- pBuffer->nCapacity = pBuffer->nData+nAddCapacity;
- pBuffer->pData = sqlite3_realloc(pBuffer->pData, pBuffer->nCapacity);
- }
-}
-static void dataBufferAppend(DataBuffer *pBuffer,
- const char *pSource, int nSource){
- assert( nSource>0 && pSource!=NULL );
- dataBufferExpand(pBuffer, nSource);
- memcpy(pBuffer->pData+pBuffer->nData, pSource, nSource);
- pBuffer->nData += nSource;
-}
-static void dataBufferAppend2(DataBuffer *pBuffer,
- const char *pSource1, int nSource1,
- const char *pSource2, int nSource2){
- assert( nSource1>0 && pSource1!=NULL );
- assert( nSource2>0 && pSource2!=NULL );
- dataBufferExpand(pBuffer, nSource1+nSource2);
- memcpy(pBuffer->pData+pBuffer->nData, pSource1, nSource1);
- memcpy(pBuffer->pData+pBuffer->nData+nSource1, pSource2, nSource2);
- pBuffer->nData += nSource1+nSource2;
-}
-static void dataBufferReplace(DataBuffer *pBuffer,
- const char *pSource, int nSource){
- dataBufferReset(pBuffer);
- dataBufferAppend(pBuffer, pSource, nSource);
-}
-
-/* StringBuffer is a null-terminated version of DataBuffer. */
-typedef struct StringBuffer {
- DataBuffer b; /* Includes null terminator. */
-} StringBuffer;
-
-static void initStringBuffer(StringBuffer *sb){
- dataBufferInit(&sb->b, 100);
- dataBufferReplace(&sb->b, "", 1);
-}
-static int stringBufferLength(StringBuffer *sb){
- return sb->b.nData-1;
-}
-static char *stringBufferData(StringBuffer *sb){
- return sb->b.pData;
-}
-static void stringBufferDestroy(StringBuffer *sb){
- dataBufferDestroy(&sb->b);
-}
-
-static void nappend(StringBuffer *sb, const char *zFrom, int nFrom){
- assert( sb->b.nData>0 );
- if( nFrom>0 ){
- sb->b.nData--;
- dataBufferAppend2(&sb->b, zFrom, nFrom, "", 1);
- }
-}
-static void append(StringBuffer *sb, const char *zFrom){
- nappend(sb, zFrom, strlen(zFrom));
-}
-
-/* Append a list of strings separated by commas. */
-static void appendList(StringBuffer *sb, int nString, char **azString){
- int i;
- for(i=0; i<nString; ++i){
- if( i>0 ) append(sb, ", ");
- append(sb, azString[i]);
- }
-}
-
-static int endsInWhiteSpace(StringBuffer *p){
- return stringBufferLength(p)>0 &&
- safe_isspace(stringBufferData(p)[stringBufferLength(p)-1]);
-}
-
-/* If the StringBuffer ends in something other than white space, add a
-** single space character to the end.
-*/
-static void appendWhiteSpace(StringBuffer *p){
- if( stringBufferLength(p)==0 ) return;
- if( !endsInWhiteSpace(p) ) append(p, " ");
-}
-
-/* Remove white space from the end of the StringBuffer */
-static void trimWhiteSpace(StringBuffer *p){
- while( endsInWhiteSpace(p) ){
- p->b.pData[--p->b.nData-1] = '\0';
- }
-}
-
-/*******************************************************************/
-/* DLReader is used to read document elements from a doclist. The
-** current docid is cached, so dlrDocid() is fast. DLReader does not
-** own the doclist buffer.
-**
-** dlrAtEnd - true if there's no more data to read.
-** dlrDocid - docid of current document.
-** dlrDocData - doclist data for current document (including docid).
-** dlrDocDataBytes - length of same.
-** dlrAllDataBytes - length of all remaining data.
-** dlrPosData - position data for current document.
-** dlrPosDataLen - length of pos data for current document (incl POS_END).
-** dlrStep - step to current document.
-** dlrInit - initial for doclist of given type against given data.
-** dlrDestroy - clean up.
-**
-** Expected usage is something like:
-**
-** DLReader reader;
-** dlrInit(&reader, pData, nData);
-** while( !dlrAtEnd(&reader) ){
-** // calls to dlrDocid() and kin.
-** dlrStep(&reader);
-** }
-** dlrDestroy(&reader);
-*/
-typedef struct DLReader {
- DocListType iType;
- const char *pData;
- int nData;
-
- sqlite_int64 iDocid;
- int nElement;
-} DLReader;
-
-static int dlrAtEnd(DLReader *pReader){
- assert( pReader->nData>=0 );
- return pReader->nData==0;
-}
-static sqlite_int64 dlrDocid(DLReader *pReader){
- assert( !dlrAtEnd(pReader) );
- return pReader->iDocid;
-}
-static const char *dlrDocData(DLReader *pReader){
- assert( !dlrAtEnd(pReader) );
- return pReader->pData;
-}
-static int dlrDocDataBytes(DLReader *pReader){
- assert( !dlrAtEnd(pReader) );
- return pReader->nElement;
-}
-static int dlrAllDataBytes(DLReader *pReader){
- assert( !dlrAtEnd(pReader) );
- return pReader->nData;
-}
-/* TODO(shess) Consider adding a field to track iDocid varint length
-** to make these two functions faster. This might matter (a tiny bit)
-** for queries.
-*/
-static const char *dlrPosData(DLReader *pReader){
- sqlite_int64 iDummy;
- int n = fts3GetVarint(pReader->pData, &iDummy);
- assert( !dlrAtEnd(pReader) );
- return pReader->pData+n;
-}
-static int dlrPosDataLen(DLReader *pReader){
- sqlite_int64 iDummy;
- int n = fts3GetVarint(pReader->pData, &iDummy);
- assert( !dlrAtEnd(pReader) );
- return pReader->nElement-n;
-}
-static void dlrStep(DLReader *pReader){
- assert( !dlrAtEnd(pReader) );
-
- /* Skip past current doclist element. */
- assert( pReader->nElement<=pReader->nData );
- pReader->pData += pReader->nElement;
- pReader->nData -= pReader->nElement;
-
- /* If there is more data, read the next doclist element. */
- if( pReader->nData!=0 ){
- sqlite_int64 iDocidDelta;
- int iDummy, n = fts3GetVarint(pReader->pData, &iDocidDelta);
- pReader->iDocid += iDocidDelta;
- if( pReader->iType>=DL_POSITIONS ){
- assert( n<pReader->nData );
- while( 1 ){
- n += fts3GetVarint32(pReader->pData+n, &iDummy);
- assert( n<=pReader->nData );
- if( iDummy==POS_END ) break;
- if( iDummy==POS_COLUMN ){
- n += fts3GetVarint32(pReader->pData+n, &iDummy);
- assert( n<pReader->nData );
- }else if( pReader->iType==DL_POSITIONS_OFFSETS ){
- n += fts3GetVarint32(pReader->pData+n, &iDummy);
- n += fts3GetVarint32(pReader->pData+n, &iDummy);
- assert( n<pReader->nData );
- }
- }
- }
- pReader->nElement = n;
- assert( pReader->nElement<=pReader->nData );
- }
-}
-static void dlrInit(DLReader *pReader, DocListType iType,
- const char *pData, int nData){
- assert( pData!=NULL && nData!=0 );
- pReader->iType = iType;
- pReader->pData = pData;
- pReader->nData = nData;
- pReader->nElement = 0;
- pReader->iDocid = 0;
-
- /* Load the first element's data. There must be a first element. */
- dlrStep(pReader);
-}
-static void dlrDestroy(DLReader *pReader){
- SCRAMBLE(pReader);
-}
-
-#ifndef NDEBUG
-/* Verify that the doclist can be validly decoded. Also returns the
-** last docid found because it is convenient in other assertions for
-** DLWriter.
-*/
-static void docListValidate(DocListType iType, const char *pData, int nData,
- sqlite_int64 *pLastDocid){
- sqlite_int64 iPrevDocid = 0;
- assert( nData>0 );
- assert( pData!=0 );
- assert( pData+nData>pData );
- while( nData!=0 ){
- sqlite_int64 iDocidDelta;
- int n = fts3GetVarint(pData, &iDocidDelta);
- iPrevDocid += iDocidDelta;
- if( iType>DL_DOCIDS ){
- int iDummy;
- while( 1 ){
- n += fts3GetVarint32(pData+n, &iDummy);
- if( iDummy==POS_END ) break;
- if( iDummy==POS_COLUMN ){
- n += fts3GetVarint32(pData+n, &iDummy);
- }else if( iType>DL_POSITIONS ){
- n += fts3GetVarint32(pData+n, &iDummy);
- n += fts3GetVarint32(pData+n, &iDummy);
- }
- assert( n<=nData );
- }
- }
- assert( n<=nData );
- pData += n;
- nData -= n;
- }
- if( pLastDocid ) *pLastDocid = iPrevDocid;
-}
-#define ASSERT_VALID_DOCLIST(i, p, n, o) docListValidate(i, p, n, o)
-#else
-#define ASSERT_VALID_DOCLIST(i, p, n, o) assert( 1 )
-#endif
-
-/*******************************************************************/
-/* DLWriter is used to write doclist data to a DataBuffer. DLWriter
-** always appends to the buffer and does not own it.
-**
-** dlwInit - initialize to write a given type doclistto a buffer.
-** dlwDestroy - clear the writer's memory. Does not free buffer.
-** dlwAppend - append raw doclist data to buffer.
-** dlwCopy - copy next doclist from reader to writer.
-** dlwAdd - construct doclist element and append to buffer.
-** Only apply dlwAdd() to DL_DOCIDS doclists (else use PLWriter).
-*/
-typedef struct DLWriter {
- DocListType iType;
- DataBuffer *b;
- sqlite_int64 iPrevDocid;
-#ifndef NDEBUG
- int has_iPrevDocid;
-#endif
-} DLWriter;
-
-static void dlwInit(DLWriter *pWriter, DocListType iType, DataBuffer *b){
- pWriter->b = b;
- pWriter->iType = iType;
- pWriter->iPrevDocid = 0;
-#ifndef NDEBUG
- pWriter->has_iPrevDocid = 0;
-#endif
-}
-static void dlwDestroy(DLWriter *pWriter){
- SCRAMBLE(pWriter);
-}
-/* iFirstDocid is the first docid in the doclist in pData. It is
-** needed because pData may point within a larger doclist, in which
-** case the first item would be delta-encoded.
-**
-** iLastDocid is the final docid in the doclist in pData. It is
-** needed to create the new iPrevDocid for future delta-encoding. The
-** code could decode the passed doclist to recreate iLastDocid, but
-** the only current user (docListMerge) already has decoded this
-** information.
-*/
-/* TODO(shess) This has become just a helper for docListMerge.
-** Consider a refactor to make this cleaner.
-*/
-static void dlwAppend(DLWriter *pWriter,
- const char *pData, int nData,
- sqlite_int64 iFirstDocid, sqlite_int64 iLastDocid){
- sqlite_int64 iDocid = 0;
- char c[VARINT_MAX];
- int nFirstOld, nFirstNew; /* Old and new varint len of first docid. */
-#ifndef NDEBUG
- sqlite_int64 iLastDocidDelta;
-#endif
-
- /* Recode the initial docid as delta from iPrevDocid. */
- nFirstOld = fts3GetVarint(pData, &iDocid);
- assert( nFirstOld<nData || (nFirstOld==nData && pWriter->iType==DL_DOCIDS) );
- nFirstNew = fts3PutVarint(c, iFirstDocid-pWriter->iPrevDocid);
-
- /* Verify that the incoming doclist is valid AND that it ends with
- ** the expected docid. This is essential because we'll trust this
- ** docid in future delta-encoding.
- */
- ASSERT_VALID_DOCLIST(pWriter->iType, pData, nData, &iLastDocidDelta);
- assert( iLastDocid==iFirstDocid-iDocid+iLastDocidDelta );
-
- /* Append recoded initial docid and everything else. Rest of docids
- ** should have been delta-encoded from previous initial docid.
- */
- if( nFirstOld<nData ){
- dataBufferAppend2(pWriter->b, c, nFirstNew,
- pData+nFirstOld, nData-nFirstOld);
- }else{
- dataBufferAppend(pWriter->b, c, nFirstNew);
- }
- pWriter->iPrevDocid = iLastDocid;
-}
-static void dlwCopy(DLWriter *pWriter, DLReader *pReader){
- dlwAppend(pWriter, dlrDocData(pReader), dlrDocDataBytes(pReader),
- dlrDocid(pReader), dlrDocid(pReader));
-}
-static void dlwAdd(DLWriter *pWriter, sqlite_int64 iDocid){
- char c[VARINT_MAX];
- int n = fts3PutVarint(c, iDocid-pWriter->iPrevDocid);
-
- /* Docids must ascend. */
- assert( !pWriter->has_iPrevDocid || iDocid>pWriter->iPrevDocid );
- assert( pWriter->iType==DL_DOCIDS );
-
- dataBufferAppend(pWriter->b, c, n);
- pWriter->iPrevDocid = iDocid;
-#ifndef NDEBUG
- pWriter->has_iPrevDocid = 1;
-#endif
-}
-
-/*******************************************************************/
-/* PLReader is used to read data from a document's position list. As
-** the caller steps through the list, data is cached so that varints
-** only need to be decoded once.
-**
-** plrInit, plrDestroy - create/destroy a reader.
-** plrColumn, plrPosition, plrStartOffset, plrEndOffset - accessors
-** plrAtEnd - at end of stream, only call plrDestroy once true.
-** plrStep - step to the next element.
-*/
-typedef struct PLReader {
- /* These refer to the next position's data. nData will reach 0 when
- ** reading the last position, so plrStep() signals EOF by setting
- ** pData to NULL.
- */
- const char *pData;
- int nData;
-
- DocListType iType;
- int iColumn; /* the last column read */
- int iPosition; /* the last position read */
- int iStartOffset; /* the last start offset read */
- int iEndOffset; /* the last end offset read */
-} PLReader;
-
-static int plrAtEnd(PLReader *pReader){
- return pReader->pData==NULL;
-}
-static int plrColumn(PLReader *pReader){
- assert( !plrAtEnd(pReader) );
- return pReader->iColumn;
-}
-static int plrPosition(PLReader *pReader){
- assert( !plrAtEnd(pReader) );
- return pReader->iPosition;
-}
-static int plrStartOffset(PLReader *pReader){
- assert( !plrAtEnd(pReader) );
- return pReader->iStartOffset;
-}
-static int plrEndOffset(PLReader *pReader){
- assert( !plrAtEnd(pReader) );
- return pReader->iEndOffset;
-}
-static void plrStep(PLReader *pReader){
- int i, n;
-
- assert( !plrAtEnd(pReader) );
-
- if( pReader->nData==0 ){
- pReader->pData = NULL;
- return;
- }
-
- n = fts3GetVarint32(pReader->pData, &i);
- if( i==POS_COLUMN ){
- n += fts3GetVarint32(pReader->pData+n, &pReader->iColumn);
- pReader->iPosition = 0;
- pReader->iStartOffset = 0;
- n += fts3GetVarint32(pReader->pData+n, &i);
- }
- /* Should never see adjacent column changes. */
- assert( i!=POS_COLUMN );
-
- if( i==POS_END ){
- pReader->nData = 0;
- pReader->pData = NULL;
- return;
- }
-
- pReader->iPosition += i-POS_BASE;
- if( pReader->iType==DL_POSITIONS_OFFSETS ){
- n += fts3GetVarint32(pReader->pData+n, &i);
- pReader->iStartOffset += i;
- n += fts3GetVarint32(pReader->pData+n, &i);
- pReader->iEndOffset = pReader->iStartOffset+i;
- }
- assert( n<=pReader->nData );
- pReader->pData += n;
- pReader->nData -= n;
-}
-
-static void plrInit(PLReader *pReader, DLReader *pDLReader){
- pReader->pData = dlrPosData(pDLReader);
- pReader->nData = dlrPosDataLen(pDLReader);
- pReader->iType = pDLReader->iType;
- pReader->iColumn = 0;
- pReader->iPosition = 0;
- pReader->iStartOffset = 0;
- pReader->iEndOffset = 0;
- plrStep(pReader);
-}
-static void plrDestroy(PLReader *pReader){
- SCRAMBLE(pReader);
-}
-
-/*******************************************************************/
-/* PLWriter is used in constructing a document's position list. As a
-** convenience, if iType is DL_DOCIDS, PLWriter becomes a no-op.
-** PLWriter writes to the associated DLWriter's buffer.
-**
-** plwInit - init for writing a document's poslist.
-** plwDestroy - clear a writer.
-** plwAdd - append position and offset information.
-** plwCopy - copy next position's data from reader to writer.
-** plwTerminate - add any necessary doclist terminator.
-**
-** Calling plwAdd() after plwTerminate() may result in a corrupt
-** doclist.
-*/
-/* TODO(shess) Until we've written the second item, we can cache the
-** first item's information. Then we'd have three states:
-**
-** - initialized with docid, no positions.
-** - docid and one position.
-** - docid and multiple positions.
-**
-** Only the last state needs to actually write to dlw->b, which would
-** be an improvement in the DLCollector case.
-*/
-typedef struct PLWriter {
- DLWriter *dlw;
-
- int iColumn; /* the last column written */
- int iPos; /* the last position written */
- int iOffset; /* the last start offset written */
-} PLWriter;
-
-/* TODO(shess) In the case where the parent is reading these values
-** from a PLReader, we could optimize to a copy if that PLReader has
-** the same type as pWriter.
-*/
-static void plwAdd(PLWriter *pWriter, int iColumn, int iPos,
- int iStartOffset, int iEndOffset){
- /* Worst-case space for POS_COLUMN, iColumn, iPosDelta,
- ** iStartOffsetDelta, and iEndOffsetDelta.
- */
- char c[5*VARINT_MAX];
- int n = 0;
-
- /* Ban plwAdd() after plwTerminate(). */
- assert( pWriter->iPos!=-1 );
-
- if( pWriter->dlw->iType==DL_DOCIDS ) return;
-
- if( iColumn!=pWriter->iColumn ){
- n += fts3PutVarint(c+n, POS_COLUMN);
- n += fts3PutVarint(c+n, iColumn);
- pWriter->iColumn = iColumn;
- pWriter->iPos = 0;
- pWriter->iOffset = 0;
- }
- assert( iPos>=pWriter->iPos );
- n += fts3PutVarint(c+n, POS_BASE+(iPos-pWriter->iPos));
- pWriter->iPos = iPos;
- if( pWriter->dlw->iType==DL_POSITIONS_OFFSETS ){
- assert( iStartOffset>=pWriter->iOffset );
- n += fts3PutVarint(c+n, iStartOffset-pWriter->iOffset);
- pWriter->iOffset = iStartOffset;
- assert( iEndOffset>=iStartOffset );
- n += fts3PutVarint(c+n, iEndOffset-iStartOffset);
- }
- dataBufferAppend(pWriter->dlw->b, c, n);
-}
-static void plwCopy(PLWriter *pWriter, PLReader *pReader){
- plwAdd(pWriter, plrColumn(pReader), plrPosition(pReader),
- plrStartOffset(pReader), plrEndOffset(pReader));
-}
-static void plwInit(PLWriter *pWriter, DLWriter *dlw, sqlite_int64 iDocid){
- char c[VARINT_MAX];
- int n;
-
- pWriter->dlw = dlw;
-
- /* Docids must ascend. */
- assert( !pWriter->dlw->has_iPrevDocid || iDocid>pWriter->dlw->iPrevDocid );
- n = fts3PutVarint(c, iDocid-pWriter->dlw->iPrevDocid);
- dataBufferAppend(pWriter->dlw->b, c, n);
- pWriter->dlw->iPrevDocid = iDocid;
-#ifndef NDEBUG
- pWriter->dlw->has_iPrevDocid = 1;
-#endif
-
- pWriter->iColumn = 0;
- pWriter->iPos = 0;
- pWriter->iOffset = 0;
-}
-/* TODO(shess) Should plwDestroy() also terminate the doclist? But
-** then plwDestroy() would no longer be just a destructor, it would
-** also be doing work, which isn't consistent with the overall idiom.
-** Another option would be for plwAdd() to always append any necessary
-** terminator, so that the output is always correct. But that would
-** add incremental work to the common case with the only benefit being
-** API elegance. Punt for now.
-*/
-static void plwTerminate(PLWriter *pWriter){
- if( pWriter->dlw->iType>DL_DOCIDS ){
- char c[VARINT_MAX];
- int n = fts3PutVarint(c, POS_END);
- dataBufferAppend(pWriter->dlw->b, c, n);
- }
-#ifndef NDEBUG
- /* Mark as terminated for assert in plwAdd(). */
- pWriter->iPos = -1;
-#endif
-}
-static void plwDestroy(PLWriter *pWriter){
- SCRAMBLE(pWriter);
-}
-
-/*******************************************************************/
-/* DLCollector wraps PLWriter and DLWriter to provide a
-** dynamically-allocated doclist area to use during tokenization.
-**
-** dlcNew - malloc up and initialize a collector.
-** dlcDelete - destroy a collector and all contained items.
-** dlcAddPos - append position and offset information.
-** dlcAddDoclist - add the collected doclist to the given buffer.
-** dlcNext - terminate the current document and open another.
-*/
-typedef struct DLCollector {
- DataBuffer b;
- DLWriter dlw;
- PLWriter plw;
-} DLCollector;
-
-/* TODO(shess) This could also be done by calling plwTerminate() and
-** dataBufferAppend(). I tried that, expecting nominal performance
-** differences, but it seemed to pretty reliably be worth 1% to code
-** it this way. I suspect it is the incremental malloc overhead (some
-** percentage of the plwTerminate() calls will cause a realloc), so
-** this might be worth revisiting if the DataBuffer implementation
-** changes.
-*/
-static void dlcAddDoclist(DLCollector *pCollector, DataBuffer *b){
- if( pCollector->dlw.iType>DL_DOCIDS ){
- char c[VARINT_MAX];
- int n = fts3PutVarint(c, POS_END);
- dataBufferAppend2(b, pCollector->b.pData, pCollector->b.nData, c, n);
- }else{
- dataBufferAppend(b, pCollector->b.pData, pCollector->b.nData);
- }
-}
-static void dlcNext(DLCollector *pCollector, sqlite_int64 iDocid){
- plwTerminate(&pCollector->plw);
- plwDestroy(&pCollector->plw);
- plwInit(&pCollector->plw, &pCollector->dlw, iDocid);
-}
-static void dlcAddPos(DLCollector *pCollector, int iColumn, int iPos,
- int iStartOffset, int iEndOffset){
- plwAdd(&pCollector->plw, iColumn, iPos, iStartOffset, iEndOffset);
-}
-
-static DLCollector *dlcNew(sqlite_int64 iDocid, DocListType iType){
- DLCollector *pCollector = sqlite3_malloc(sizeof(DLCollector));
- dataBufferInit(&pCollector->b, 0);
- dlwInit(&pCollector->dlw, iType, &pCollector->b);
- plwInit(&pCollector->plw, &pCollector->dlw, iDocid);
- return pCollector;
-}
-static void dlcDelete(DLCollector *pCollector){
- plwDestroy(&pCollector->plw);
- dlwDestroy(&pCollector->dlw);
- dataBufferDestroy(&pCollector->b);
- SCRAMBLE(pCollector);
- sqlite3_free(pCollector);
-}
-
-
-/* Copy the doclist data of iType in pData/nData into *out, trimming
-** unnecessary data as we go. Only columns matching iColumn are
-** copied, all columns copied if iColumn is -1. Elements with no
-** matching columns are dropped. The output is an iOutType doclist.
-*/
-/* NOTE(shess) This code is only valid after all doclists are merged.
-** If this is run before merges, then doclist items which represent
-** deletion will be trimmed, and will thus not effect a deletion
-** during the merge.
-*/
-static void docListTrim(DocListType iType, const char *pData, int nData,
- int iColumn, DocListType iOutType, DataBuffer *out){
- DLReader dlReader;
- DLWriter dlWriter;
-
- assert( iOutType<=iType );
-
- dlrInit(&dlReader, iType, pData, nData);
- dlwInit(&dlWriter, iOutType, out);
-
- while( !dlrAtEnd(&dlReader) ){
- PLReader plReader;
- PLWriter plWriter;
- int match = 0;
-
- plrInit(&plReader, &dlReader);
-
- while( !plrAtEnd(&plReader) ){
- if( iColumn==-1 || plrColumn(&plReader)==iColumn ){
- if( !match ){
- plwInit(&plWriter, &dlWriter, dlrDocid(&dlReader));
- match = 1;
- }
- plwAdd(&plWriter, plrColumn(&plReader), plrPosition(&plReader),
- plrStartOffset(&plReader), plrEndOffset(&plReader));
- }
- plrStep(&plReader);
- }
- if( match ){
- plwTerminate(&plWriter);
- plwDestroy(&plWriter);
- }
-
- plrDestroy(&plReader);
- dlrStep(&dlReader);
- }
- dlwDestroy(&dlWriter);
- dlrDestroy(&dlReader);
-}
-
-/* Used by docListMerge() to keep doclists in the ascending order by
-** docid, then ascending order by age (so the newest comes first).
-*/
-typedef struct OrderedDLReader {
- DLReader *pReader;
-
- /* TODO(shess) If we assume that docListMerge pReaders is ordered by
- ** age (which we do), then we could use pReader comparisons to break
- ** ties.
- */
- int idx;
-} OrderedDLReader;
-
-/* Order eof to end, then by docid asc, idx desc. */
-static int orderedDLReaderCmp(OrderedDLReader *r1, OrderedDLReader *r2){
- if( dlrAtEnd(r1->pReader) ){
- if( dlrAtEnd(r2->pReader) ) return 0; /* Both atEnd(). */
- return 1; /* Only r1 atEnd(). */
- }
- if( dlrAtEnd(r2->pReader) ) return -1; /* Only r2 atEnd(). */
-
- if( dlrDocid(r1->pReader)<dlrDocid(r2->pReader) ) return -1;
- if( dlrDocid(r1->pReader)>dlrDocid(r2->pReader) ) return 1;
-
- /* Descending on idx. */
- return r2->idx-r1->idx;
-}
-
-/* Bubble p[0] to appropriate place in p[1..n-1]. Assumes that
-** p[1..n-1] is already sorted.
-*/
-/* TODO(shess) Is this frequent enough to warrant a binary search?
-** Before implementing that, instrument the code to check. In most
-** current usage, I expect that p[0] will be less than p[1] a very
-** high proportion of the time.
-*/
-static void orderedDLReaderReorder(OrderedDLReader *p, int n){
- while( n>1 && orderedDLReaderCmp(p, p+1)>0 ){
- OrderedDLReader tmp = p[0];
- p[0] = p[1];
- p[1] = tmp;
- n--;
- p++;
- }
-}
-
-/* Given an array of doclist readers, merge their doclist elements
-** into out in sorted order (by docid), dropping elements from older
-** readers when there is a duplicate docid. pReaders is assumed to be
-** ordered by age, oldest first.
-*/
-/* TODO(shess) nReaders must be <= MERGE_COUNT. This should probably
-** be fixed.
-*/
-static void docListMerge(DataBuffer *out,
- DLReader *pReaders, int nReaders){
- OrderedDLReader readers[MERGE_COUNT];
- DLWriter writer;
- int i, n;
- const char *pStart = 0;
- int nStart = 0;
- sqlite_int64 iFirstDocid = 0, iLastDocid = 0;
-
- assert( nReaders>0 );
- if( nReaders==1 ){
- dataBufferAppend(out, dlrDocData(pReaders), dlrAllDataBytes(pReaders));
- return;
- }
-
- assert( nReaders<=MERGE_COUNT );
- n = 0;
- for(i=0; i<nReaders; i++){
- assert( pReaders[i].iType==pReaders[0].iType );
- readers[i].pReader = pReaders+i;
- readers[i].idx = i;
- n += dlrAllDataBytes(&pReaders[i]);
- }
- /* Conservatively size output to sum of inputs. Output should end
- ** up strictly smaller than input.
- */
- dataBufferExpand(out, n);
-
- /* Get the readers into sorted order. */
- while( i-->0 ){
- orderedDLReaderReorder(readers+i, nReaders-i);
- }
-
- dlwInit(&writer, pReaders[0].iType, out);
- while( !dlrAtEnd(readers[0].pReader) ){
- sqlite_int64 iDocid = dlrDocid(readers[0].pReader);
-
- /* If this is a continuation of the current buffer to copy, extend
- ** that buffer. memcpy() seems to be more efficient if it has a
- ** lots of data to copy.
- */
- if( dlrDocData(readers[0].pReader)==pStart+nStart ){
- nStart += dlrDocDataBytes(readers[0].pReader);
- }else{
- if( pStart!=0 ){
- dlwAppend(&writer, pStart, nStart, iFirstDocid, iLastDocid);
- }
- pStart = dlrDocData(readers[0].pReader);
- nStart = dlrDocDataBytes(readers[0].pReader);
- iFirstDocid = iDocid;
- }
- iLastDocid = iDocid;
- dlrStep(readers[0].pReader);
-
- /* Drop all of the older elements with the same docid. */
- for(i=1; i<nReaders &&
- !dlrAtEnd(readers[i].pReader) &&
- dlrDocid(readers[i].pReader)==iDocid; i++){
- dlrStep(readers[i].pReader);
- }
-
- /* Get the readers back into order. */
- while( i-->0 ){
- orderedDLReaderReorder(readers+i, nReaders-i);
- }
- }
-
- /* Copy over any remaining elements. */
- if( nStart>0 ) dlwAppend(&writer, pStart, nStart, iFirstDocid, iLastDocid);
- dlwDestroy(&writer);
-}
-
-/* Helper function for posListUnion(). Compares the current position
-** between left and right, returning as standard C idiom of <0 if
-** left<right, >0 if left>right, and 0 if left==right. "End" always
-** compares greater.
-*/
-static int posListCmp(PLReader *pLeft, PLReader *pRight){
- assert( pLeft->iType==pRight->iType );
- if( pLeft->iType==DL_DOCIDS ) return 0;
-
- if( plrAtEnd(pLeft) ) return plrAtEnd(pRight) ? 0 : 1;
- if( plrAtEnd(pRight) ) return -1;
-
- if( plrColumn(pLeft)<plrColumn(pRight) ) return -1;
- if( plrColumn(pLeft)>plrColumn(pRight) ) return 1;
-
- if( plrPosition(pLeft)<plrPosition(pRight) ) return -1;
- if( plrPosition(pLeft)>plrPosition(pRight) ) return 1;
- if( pLeft->iType==DL_POSITIONS ) return 0;
-
- if( plrStartOffset(pLeft)<plrStartOffset(pRight) ) return -1;
- if( plrStartOffset(pLeft)>plrStartOffset(pRight) ) return 1;
-
- if( plrEndOffset(pLeft)<plrEndOffset(pRight) ) return -1;
- if( plrEndOffset(pLeft)>plrEndOffset(pRight) ) return 1;
-
- return 0;
-}
-
-/* Write the union of position lists in pLeft and pRight to pOut.
-** "Union" in this case meaning "All unique position tuples". Should
-** work with any doclist type, though both inputs and the output
-** should be the same type.
-*/
-static void posListUnion(DLReader *pLeft, DLReader *pRight, DLWriter *pOut){
- PLReader left, right;
- PLWriter writer;
-
- assert( dlrDocid(pLeft)==dlrDocid(pRight) );
- assert( pLeft->iType==pRight->iType );
- assert( pLeft->iType==pOut->iType );
-
- plrInit(&left, pLeft);
- plrInit(&right, pRight);
- plwInit(&writer, pOut, dlrDocid(pLeft));
-
- while( !plrAtEnd(&left) || !plrAtEnd(&right) ){
- int c = posListCmp(&left, &right);
- if( c<0 ){
- plwCopy(&writer, &left);
- plrStep(&left);
- }else if( c>0 ){
- plwCopy(&writer, &right);
- plrStep(&right);
- }else{
- plwCopy(&writer, &left);
- plrStep(&left);
- plrStep(&right);
- }
- }
-
- plwTerminate(&writer);
- plwDestroy(&writer);
- plrDestroy(&left);
- plrDestroy(&right);
-}
-
-/* Write the union of doclists in pLeft and pRight to pOut. For
-** docids in common between the inputs, the union of the position
-** lists is written. Inputs and outputs are always type DL_DEFAULT.
-*/
-static void docListUnion(
- const char *pLeft, int nLeft,
- const char *pRight, int nRight,
- DataBuffer *pOut /* Write the combined doclist here */
-){
- DLReader left, right;
- DLWriter writer;
-
- if( nLeft==0 ){
- if( nRight!=0) dataBufferAppend(pOut, pRight, nRight);
- return;
- }
- if( nRight==0 ){
- dataBufferAppend(pOut, pLeft, nLeft);
- return;
- }
-
- dlrInit(&left, DL_DEFAULT, pLeft, nLeft);
- dlrInit(&right, DL_DEFAULT, pRight, nRight);
- dlwInit(&writer, DL_DEFAULT, pOut);
-
- while( !dlrAtEnd(&left) || !dlrAtEnd(&right) ){
- if( dlrAtEnd(&right) ){
- dlwCopy(&writer, &left);
- dlrStep(&left);
- }else if( dlrAtEnd(&left) ){
- dlwCopy(&writer, &right);
- dlrStep(&right);
- }else if( dlrDocid(&left)<dlrDocid(&right) ){
- dlwCopy(&writer, &left);
- dlrStep(&left);
- }else if( dlrDocid(&left)>dlrDocid(&right) ){
- dlwCopy(&writer, &right);
- dlrStep(&right);
- }else{
- posListUnion(&left, &right, &writer);
- dlrStep(&left);
- dlrStep(&right);
- }
- }
-
- dlrDestroy(&left);
- dlrDestroy(&right);
- dlwDestroy(&writer);
-}
-
-/*
-** This function is used as part of the implementation of phrase and
-** NEAR matching.
-**
-** pLeft and pRight are DLReaders positioned to the same docid in
-** lists of type DL_POSITION. This function writes an entry to the
-** DLWriter pOut for each position in pRight that is less than
-** (nNear+1) greater (but not equal to or smaller) than a position
-** in pLeft. For example, if nNear is 0, and the positions contained
-** by pLeft and pRight are:
-**
-** pLeft: 5 10 15 20
-** pRight: 6 9 17 21
-**
-** then the docid is added to pOut. If pOut is of type DL_POSITIONS,
-** then a positionids "6" and "21" are also added to pOut.
-**
-** If boolean argument isSaveLeft is true, then positionids are copied
-** from pLeft instead of pRight. In the example above, the positions "5"
-** and "20" would be added instead of "6" and "21".
-*/
-static void posListPhraseMerge(
- DLReader *pLeft,
- DLReader *pRight,
- int nNear,
- int isSaveLeft,
- DLWriter *pOut
-){
- PLReader left, right;
- PLWriter writer;
- int match = 0;
-
- assert( dlrDocid(pLeft)==dlrDocid(pRight) );
- assert( pOut->iType!=DL_POSITIONS_OFFSETS );
-
- plrInit(&left, pLeft);
- plrInit(&right, pRight);
-
- while( !plrAtEnd(&left) && !plrAtEnd(&right) ){
- if( plrColumn(&left)<plrColumn(&right) ){
- plrStep(&left);
- }else if( plrColumn(&left)>plrColumn(&right) ){
- plrStep(&right);
- }else if( plrPosition(&left)>=plrPosition(&right) ){
- plrStep(&right);
- }else{
- if( (plrPosition(&right)-plrPosition(&left))<=(nNear+1) ){
- if( !match ){
- plwInit(&writer, pOut, dlrDocid(pLeft));
- match = 1;
- }
- if( !isSaveLeft ){
- plwAdd(&writer, plrColumn(&right), plrPosition(&right), 0, 0);
- }else{
- plwAdd(&writer, plrColumn(&left), plrPosition(&left), 0, 0);
- }
- plrStep(&right);
- }else{
- plrStep(&left);
- }
- }
- }
-
- if( match ){
- plwTerminate(&writer);
- plwDestroy(&writer);
- }
-
- plrDestroy(&left);
- plrDestroy(&right);
-}
-
-/*
-** Compare the values pointed to by the PLReaders passed as arguments.
-** Return -1 if the value pointed to by pLeft is considered less than
-** the value pointed to by pRight, +1 if it is considered greater
-** than it, or 0 if it is equal. i.e.
-**
-** (*pLeft - *pRight)
-**
-** A PLReader that is in the EOF condition is considered greater than
-** any other. If neither argument is in EOF state, the return value of
-** plrColumn() is used. If the plrColumn() values are equal, the
-** comparison is on the basis of plrPosition().
-*/
-static int plrCompare(PLReader *pLeft, PLReader *pRight){
- assert(!plrAtEnd(pLeft) || !plrAtEnd(pRight));
-
- if( plrAtEnd(pRight) || plrAtEnd(pLeft) ){
- return (plrAtEnd(pRight) ? -1 : 1);
- }
- if( plrColumn(pLeft)!=plrColumn(pRight) ){
- return ((plrColumn(pLeft)<plrColumn(pRight)) ? -1 : 1);
- }
- if( plrPosition(pLeft)!=plrPosition(pRight) ){
- return ((plrPosition(pLeft)<plrPosition(pRight)) ? -1 : 1);
- }
- return 0;
-}
-
-/* We have two doclists with positions: pLeft and pRight. Depending
-** on the value of the nNear parameter, perform either a phrase
-** intersection (if nNear==0) or a NEAR intersection (if nNear>0)
-** and write the results into pOut.
-**
-** A phrase intersection means that two documents only match
-** if pLeft.iPos+1==pRight.iPos.
-**
-** A NEAR intersection means that two documents only match if
-** (abs(pLeft.iPos-pRight.iPos)<nNear).
-**
-** If a NEAR intersection is requested, then the nPhrase argument should
-** be passed the number of tokens in the two operands to the NEAR operator
-** combined. For example:
-**
-** Query syntax nPhrase
-** ------------------------------------
-** "A B C" NEAR "D E" 5
-** A NEAR B 2
-**
-** iType controls the type of data written to pOut. If iType is
-** DL_POSITIONS, the positions are those from pRight.
-*/
-static void docListPhraseMerge(
- const char *pLeft, int nLeft,
- const char *pRight, int nRight,
- int nNear, /* 0 for a phrase merge, non-zero for a NEAR merge */
- int nPhrase, /* Number of tokens in left+right operands to NEAR */
- DocListType iType, /* Type of doclist to write to pOut */
- DataBuffer *pOut /* Write the combined doclist here */
-){
- DLReader left, right;
- DLWriter writer;
-
- if( nLeft==0 || nRight==0 ) return;
-
- assert( iType!=DL_POSITIONS_OFFSETS );
-
- dlrInit(&left, DL_POSITIONS, pLeft, nLeft);
- dlrInit(&right, DL_POSITIONS, pRight, nRight);
- dlwInit(&writer, iType, pOut);
-
- while( !dlrAtEnd(&left) && !dlrAtEnd(&right) ){
- if( dlrDocid(&left)<dlrDocid(&right) ){
- dlrStep(&left);
- }else if( dlrDocid(&right)<dlrDocid(&left) ){
- dlrStep(&right);
- }else{
- if( nNear==0 ){
- posListPhraseMerge(&left, &right, 0, 0, &writer);
- }else{
- /* This case occurs when two terms (simple terms or phrases) are
- * connected by a NEAR operator, span (nNear+1). i.e.
- *
- * '"terrible company" NEAR widget'
- */
- DataBuffer one = {0, 0, 0};
- DataBuffer two = {0, 0, 0};
-
- DLWriter dlwriter2;
- DLReader dr1 = {0, 0, 0, 0, 0};
- DLReader dr2 = {0, 0, 0, 0, 0};
-
- dlwInit(&dlwriter2, iType, &one);
- posListPhraseMerge(&right, &left, nNear-3+nPhrase, 1, &dlwriter2);
- dlwInit(&dlwriter2, iType, &two);
- posListPhraseMerge(&left, &right, nNear-1, 0, &dlwriter2);
-
- if( one.nData) dlrInit(&dr1, iType, one.pData, one.nData);
- if( two.nData) dlrInit(&dr2, iType, two.pData, two.nData);
-
- if( !dlrAtEnd(&dr1) || !dlrAtEnd(&dr2) ){
- PLReader pr1 = {0};
- PLReader pr2 = {0};
-
- PLWriter plwriter;
- plwInit(&plwriter, &writer, dlrDocid(dlrAtEnd(&dr1)?&dr2:&dr1));
-
- if( one.nData ) plrInit(&pr1, &dr1);
- if( two.nData ) plrInit(&pr2, &dr2);
- while( !plrAtEnd(&pr1) || !plrAtEnd(&pr2) ){
- int iCompare = plrCompare(&pr1, &pr2);
- switch( iCompare ){
- case -1:
- plwCopy(&plwriter, &pr1);
- plrStep(&pr1);
- break;
- case 1:
- plwCopy(&plwriter, &pr2);
- plrStep(&pr2);
- break;
- case 0:
- plwCopy(&plwriter, &pr1);
- plrStep(&pr1);
- plrStep(&pr2);
- break;
- }
- }
- plwTerminate(&plwriter);
- }
- dataBufferDestroy(&one);
- dataBufferDestroy(&two);
- }
- dlrStep(&left);
- dlrStep(&right);
- }
- }
-
- dlrDestroy(&left);
- dlrDestroy(&right);
- dlwDestroy(&writer);
-}
-
-/* We have two DL_DOCIDS doclists: pLeft and pRight.
-** Write the intersection of these two doclists into pOut as a
-** DL_DOCIDS doclist.
-*/
-static void docListAndMerge(
- const char *pLeft, int nLeft,
- const char *pRight, int nRight,
- DataBuffer *pOut /* Write the combined doclist here */
-){
- DLReader left, right;
- DLWriter writer;
-
- if( nLeft==0 || nRight==0 ) return;
-
- dlrInit(&left, DL_DOCIDS, pLeft, nLeft);
- dlrInit(&right, DL_DOCIDS, pRight, nRight);
- dlwInit(&writer, DL_DOCIDS, pOut);
-
- while( !dlrAtEnd(&left) && !dlrAtEnd(&right) ){
- if( dlrDocid(&left)<dlrDocid(&right) ){
- dlrStep(&left);
- }else if( dlrDocid(&right)<dlrDocid(&left) ){
- dlrStep(&right);
- }else{
- dlwAdd(&writer, dlrDocid(&left));
- dlrStep(&left);
- dlrStep(&right);
- }
- }
-
- dlrDestroy(&left);
- dlrDestroy(&right);
- dlwDestroy(&writer);
-}
-
-/* We have two DL_DOCIDS doclists: pLeft and pRight.
-** Write the union of these two doclists into pOut as a
-** DL_DOCIDS doclist.
-*/
-static void docListOrMerge(
- const char *pLeft, int nLeft,
- const char *pRight, int nRight,
- DataBuffer *pOut /* Write the combined doclist here */
-){
- DLReader left, right;
- DLWriter writer;
-
- if( nLeft==0 ){
- if( nRight!=0 ) dataBufferAppend(pOut, pRight, nRight);
- return;
- }
- if( nRight==0 ){
- dataBufferAppend(pOut, pLeft, nLeft);
- return;
- }
-
- dlrInit(&left, DL_DOCIDS, pLeft, nLeft);
- dlrInit(&right, DL_DOCIDS, pRight, nRight);
- dlwInit(&writer, DL_DOCIDS, pOut);
-
- while( !dlrAtEnd(&left) || !dlrAtEnd(&right) ){
- if( dlrAtEnd(&right) ){
- dlwAdd(&writer, dlrDocid(&left));
- dlrStep(&left);
- }else if( dlrAtEnd(&left) ){
- dlwAdd(&writer, dlrDocid(&right));
- dlrStep(&right);
- }else if( dlrDocid(&left)<dlrDocid(&right) ){
- dlwAdd(&writer, dlrDocid(&left));
- dlrStep(&left);
- }else if( dlrDocid(&right)<dlrDocid(&left) ){
- dlwAdd(&writer, dlrDocid(&right));
- dlrStep(&right);
- }else{
- dlwAdd(&writer, dlrDocid(&left));
- dlrStep(&left);
- dlrStep(&right);
- }
- }
-
- dlrDestroy(&left);
- dlrDestroy(&right);
- dlwDestroy(&writer);
-}
-
-/* We have two DL_DOCIDS doclists: pLeft and pRight.
-** Write into pOut as DL_DOCIDS doclist containing all documents that
-** occur in pLeft but not in pRight.
-*/
-static void docListExceptMerge(
- const char *pLeft, int nLeft,
- const char *pRight, int nRight,
- DataBuffer *pOut /* Write the combined doclist here */
-){
- DLReader left, right;
- DLWriter writer;
-
- if( nLeft==0 ) return;
- if( nRight==0 ){
- dataBufferAppend(pOut, pLeft, nLeft);
- return;
- }
-
- dlrInit(&left, DL_DOCIDS, pLeft, nLeft);
- dlrInit(&right, DL_DOCIDS, pRight, nRight);
- dlwInit(&writer, DL_DOCIDS, pOut);
-
- while( !dlrAtEnd(&left) ){
- while( !dlrAtEnd(&right) && dlrDocid(&right)<dlrDocid(&left) ){
- dlrStep(&right);
- }
- if( dlrAtEnd(&right) || dlrDocid(&left)<dlrDocid(&right) ){
- dlwAdd(&writer, dlrDocid(&left));
- }
- dlrStep(&left);
- }
-
- dlrDestroy(&left);
- dlrDestroy(&right);
- dlwDestroy(&writer);
-}
-
-static char *string_dup_n(const char *s, int n){
- char *str = sqlite3_malloc(n + 1);
- memcpy(str, s, n);
- str[n] = '\0';
- return str;
-}
-
-/* Duplicate a string; the caller must free() the returned string.
- * (We don't use strdup() since it is not part of the standard C library and
- * may not be available everywhere.) */
-static char *string_dup(const char *s){
- return string_dup_n(s, strlen(s));
-}
-
-/* Format a string, replacing each occurrence of the % character with
- * zDb.zName. This may be more convenient than sqlite_mprintf()
- * when one string is used repeatedly in a format string.
- * The caller must free() the returned string. */
-static char *string_format(const char *zFormat,
- const char *zDb, const char *zName){
- const char *p;
- size_t len = 0;
- size_t nDb = strlen(zDb);
- size_t nName = strlen(zName);
- size_t nFullTableName = nDb+1+nName;
- char *result;
- char *r;
-
- /* first compute length needed */
- for(p = zFormat ; *p ; ++p){
- len += (*p=='%' ? nFullTableName : 1);
- }
- len += 1; /* for null terminator */
-
- r = result = sqlite3_malloc(len);
- for(p = zFormat; *p; ++p){
- if( *p=='%' ){
- memcpy(r, zDb, nDb);
- r += nDb;
- *r++ = '.';
- memcpy(r, zName, nName);
- r += nName;
- } else {
- *r++ = *p;
- }
- }
- *r++ = '\0';
- assert( r == result + len );
- return result;
-}
-
-static int sql_exec(sqlite3 *db, const char *zDb, const char *zName,
- const char *zFormat){
- char *zCommand = string_format(zFormat, zDb, zName);
- int rc;
- FTSTRACE(("FTS3 sql: %s\n", zCommand));
- rc = sqlite3_exec(db, zCommand, NULL, 0, NULL);
- sqlite3_free(zCommand);
- return rc;
-}
-
-static int sql_prepare(sqlite3 *db, const char *zDb, const char *zName,
- sqlite3_stmt **ppStmt, const char *zFormat){
- char *zCommand = string_format(zFormat, zDb, zName);
- int rc;
- FTSTRACE(("FTS3 prepare: %s\n", zCommand));
- rc = sqlite3_prepare_v2(db, zCommand, -1, ppStmt, NULL);
- sqlite3_free(zCommand);
- return rc;
-}
-
-/* end utility functions */
-
-/* Forward reference */
-typedef struct fulltext_vtab fulltext_vtab;
-
-/*
-** An instance of the following structure keeps track of generated
-** matching-word offset information and snippets.
-*/
-typedef struct Snippet {
- int nMatch; /* Total number of matches */
- int nAlloc; /* Space allocated for aMatch[] */
- struct snippetMatch { /* One entry for each matching term */
- char snStatus; /* Status flag for use while constructing snippets */
- short int iCol; /* The column that contains the match */
- short int iTerm; /* The index in Query.pTerms[] of the matching term */
- int iToken; /* The index of the matching document token */
- short int nByte; /* Number of bytes in the term */
- int iStart; /* The offset to the first character of the term */
- } *aMatch; /* Points to space obtained from malloc */
- char *zOffset; /* Text rendering of aMatch[] */
- int nOffset; /* strlen(zOffset) */
- char *zSnippet; /* Snippet text */
- int nSnippet; /* strlen(zSnippet) */
-} Snippet;
-
-
-typedef enum QueryType {
- QUERY_GENERIC, /* table scan */
- QUERY_DOCID, /* lookup by docid */
- QUERY_FULLTEXT /* QUERY_FULLTEXT + [i] is a full-text search for column i*/
-} QueryType;
-
-typedef enum fulltext_statement {
- CONTENT_INSERT_STMT,
- CONTENT_SELECT_STMT,
- CONTENT_UPDATE_STMT,
- CONTENT_DELETE_STMT,
- CONTENT_EXISTS_STMT,
-
- BLOCK_INSERT_STMT,
- BLOCK_SELECT_STMT,
- BLOCK_DELETE_STMT,
- BLOCK_DELETE_ALL_STMT,
-
- SEGDIR_MAX_INDEX_STMT,
- SEGDIR_SET_STMT,
- SEGDIR_SELECT_LEVEL_STMT,
- SEGDIR_SPAN_STMT,
- SEGDIR_DELETE_STMT,
- SEGDIR_SELECT_SEGMENT_STMT,
- SEGDIR_SELECT_ALL_STMT,
- SEGDIR_DELETE_ALL_STMT,
- SEGDIR_COUNT_STMT,
-
- MAX_STMT /* Always at end! */
-} fulltext_statement;
-
-/* These must exactly match the enum above. */
-/* TODO(shess): Is there some risk that a statement will be used in two
-** cursors at once, e.g. if a query joins a virtual table to itself?
-** If so perhaps we should move some of these to the cursor object.
-*/
-static const char *const fulltext_zStatement[MAX_STMT] = {
- /* CONTENT_INSERT */ NULL, /* generated in contentInsertStatement() */
- /* CONTENT_SELECT */ NULL, /* generated in contentSelectStatement() */
- /* CONTENT_UPDATE */ NULL, /* generated in contentUpdateStatement() */
- /* CONTENT_DELETE */ "delete from %_content where docid = ?",
- /* CONTENT_EXISTS */ "select docid from %_content limit 1",
-
- /* BLOCK_INSERT */
- "insert into %_segments (blockid, block) values (null, ?)",
- /* BLOCK_SELECT */ "select block from %_segments where blockid = ?",
- /* BLOCK_DELETE */ "delete from %_segments where blockid between ? and ?",
- /* BLOCK_DELETE_ALL */ "delete from %_segments",
-
- /* SEGDIR_MAX_INDEX */ "select max(idx) from %_segdir where level = ?",
- /* SEGDIR_SET */ "insert into %_segdir values (?, ?, ?, ?, ?, ?)",
- /* SEGDIR_SELECT_LEVEL */
- "select start_block, leaves_end_block, root from %_segdir "
- " where level = ? order by idx",
- /* SEGDIR_SPAN */
- "select min(start_block), max(end_block) from %_segdir "
- " where level = ? and start_block <> 0",
- /* SEGDIR_DELETE */ "delete from %_segdir where level = ?",
-
- /* NOTE(shess): The first three results of the following two
- ** statements must match.
- */
- /* SEGDIR_SELECT_SEGMENT */
- "select start_block, leaves_end_block, root from %_segdir "
- " where level = ? and idx = ?",
- /* SEGDIR_SELECT_ALL */
- "select start_block, leaves_end_block, root from %_segdir "
- " order by level desc, idx asc",
- /* SEGDIR_DELETE_ALL */ "delete from %_segdir",
- /* SEGDIR_COUNT */ "select count(*), ifnull(max(level),0) from %_segdir",
-};
-
-/*
-** A connection to a fulltext index is an instance of the following
-** structure. The xCreate and xConnect methods create an instance
-** of this structure and xDestroy and xDisconnect free that instance.
-** All other methods receive a pointer to the structure as one of their
-** arguments.
-*/
-struct fulltext_vtab {
- sqlite3_vtab base; /* Base class used by SQLite core */
- sqlite3 *db; /* The database connection */
- const char *zDb; /* logical database name */
- const char *zName; /* virtual table name */
- int nColumn; /* number of columns in virtual table */
- char **azColumn; /* column names. malloced */
- char **azContentColumn; /* column names in content table; malloced */
- sqlite3_tokenizer *pTokenizer; /* tokenizer for inserts and queries */
-
- /* Precompiled statements which we keep as long as the table is
- ** open.
- */
- sqlite3_stmt *pFulltextStatements[MAX_STMT];
-
- /* Precompiled statements used for segment merges. We run a
- ** separate select across the leaf level of each tree being merged.
- */
- sqlite3_stmt *pLeafSelectStmts[MERGE_COUNT];
- /* The statement used to prepare pLeafSelectStmts. */
-#define LEAF_SELECT \
- "select block from %_segments where blockid between ? and ? order by blockid"
-
- /* These buffer pending index updates during transactions.
- ** nPendingData estimates the memory size of the pending data. It
- ** doesn't include the hash-bucket overhead, nor any malloc
- ** overhead. When nPendingData exceeds kPendingThreshold, the
- ** buffer is flushed even before the transaction closes.
- ** pendingTerms stores the data, and is only valid when nPendingData
- ** is >=0 (nPendingData<0 means pendingTerms has not been
- ** initialized). iPrevDocid is the last docid written, used to make
- ** certain we're inserting in sorted order.
- */
- int nPendingData;
-#define kPendingThreshold (1*1024*1024)
- sqlite_int64 iPrevDocid;
- fts3Hash pendingTerms;
-};
-
-/*
-** When the core wants to do a query, it create a cursor using a
-** call to xOpen. This structure is an instance of a cursor. It
-** is destroyed by xClose.
-*/
-typedef struct fulltext_cursor {
- sqlite3_vtab_cursor base; /* Base class used by SQLite core */
- QueryType iCursorType; /* Copy of sqlite3_index_info.idxNum */
- sqlite3_stmt *pStmt; /* Prepared statement in use by the cursor */
- int eof; /* True if at End Of Results */
- Fts3Expr *pExpr; /* Parsed MATCH query string */
- Snippet snippet; /* Cached snippet for the current row */
- int iColumn; /* Column being searched */
- DataBuffer result; /* Doclist results from fulltextQuery */
- DLReader reader; /* Result reader if result not empty */
-} fulltext_cursor;
-
-static fulltext_vtab *cursor_vtab(fulltext_cursor *c){
- return (fulltext_vtab *) c->base.pVtab;
-}
-
-static const sqlite3_module fts3Module; /* forward declaration */
-
-/* Return a dynamically generated statement of the form
- * insert into %_content (docid, ...) values (?, ...)
- */
-static const char *contentInsertStatement(fulltext_vtab *v){
- StringBuffer sb;
- int i;
-
- initStringBuffer(&sb);
- append(&sb, "insert into %_content (docid, ");
- appendList(&sb, v->nColumn, v->azContentColumn);
- append(&sb, ") values (?");
- for(i=0; i<v->nColumn; ++i)
- append(&sb, ", ?");
- append(&sb, ")");
- return stringBufferData(&sb);
-}
-
-/* Return a dynamically generated statement of the form
- * select <content columns> from %_content where docid = ?
- */
-static const char *contentSelectStatement(fulltext_vtab *v){
- StringBuffer sb;
- initStringBuffer(&sb);
- append(&sb, "SELECT ");
- appendList(&sb, v->nColumn, v->azContentColumn);
- append(&sb, " FROM %_content WHERE docid = ?");
- return stringBufferData(&sb);
-}
-
-/* Return a dynamically generated statement of the form
- * update %_content set [col_0] = ?, [col_1] = ?, ...
- * where docid = ?
- */
-static const char *contentUpdateStatement(fulltext_vtab *v){
- StringBuffer sb;
- int i;
-
- initStringBuffer(&sb);
- append(&sb, "update %_content set ");
- for(i=0; i<v->nColumn; ++i) {
- if( i>0 ){
- append(&sb, ", ");
- }
- append(&sb, v->azContentColumn[i]);
- append(&sb, " = ?");
- }
- append(&sb, " where docid = ?");
- return stringBufferData(&sb);
-}
-
-/* Puts a freshly-prepared statement determined by iStmt in *ppStmt.
-** If the indicated statement has never been prepared, it is prepared
-** and cached, otherwise the cached version is reset.
-*/
-static int sql_get_statement(fulltext_vtab *v, fulltext_statement iStmt,
- sqlite3_stmt **ppStmt){
- assert( iStmt<MAX_STMT );
- if( v->pFulltextStatements[iStmt]==NULL ){
- const char *zStmt;
- int rc;
- switch( iStmt ){
- case CONTENT_INSERT_STMT:
- zStmt = contentInsertStatement(v); break;
- case CONTENT_SELECT_STMT:
- zStmt = contentSelectStatement(v); break;
- case CONTENT_UPDATE_STMT:
- zStmt = contentUpdateStatement(v); break;
- default:
- zStmt = fulltext_zStatement[iStmt];
- }
- rc = sql_prepare(v->db, v->zDb, v->zName, &v->pFulltextStatements[iStmt],
- zStmt);
- if( zStmt != fulltext_zStatement[iStmt]) sqlite3_free((void *) zStmt);
- if( rc!=SQLITE_OK ) return rc;
- } else {
- int rc = sqlite3_reset(v->pFulltextStatements[iStmt]);
- if( rc!=SQLITE_OK ) return rc;
- }
-
- *ppStmt = v->pFulltextStatements[iStmt];
- return SQLITE_OK;
-}
-
-/* Like sqlite3_step(), but convert SQLITE_DONE to SQLITE_OK and
-** SQLITE_ROW to SQLITE_ERROR. Useful for statements like UPDATE,
-** where we expect no results.
-*/
-static int sql_single_step(sqlite3_stmt *s){
- int rc = sqlite3_step(s);
- return (rc==SQLITE_DONE) ? SQLITE_OK : rc;
-}
-
-/* Like sql_get_statement(), but for special replicated LEAF_SELECT
-** statements. idx -1 is a special case for an uncached version of
-** the statement (used in the optimize implementation).
-*/
-/* TODO(shess) Write version for generic statements and then share
-** that between the cached-statement functions.
-*/
-static int sql_get_leaf_statement(fulltext_vtab *v, int idx,
- sqlite3_stmt **ppStmt){
- assert( idx>=-1 && idx<MERGE_COUNT );
- if( idx==-1 ){
- return sql_prepare(v->db, v->zDb, v->zName, ppStmt, LEAF_SELECT);
- }else if( v->pLeafSelectStmts[idx]==NULL ){
- int rc = sql_prepare(v->db, v->zDb, v->zName, &v->pLeafSelectStmts[idx],
- LEAF_SELECT);
- if( rc!=SQLITE_OK ) return rc;
- }else{
- int rc = sqlite3_reset(v->pLeafSelectStmts[idx]);
- if( rc!=SQLITE_OK ) return rc;
- }
-
- *ppStmt = v->pLeafSelectStmts[idx];
- return SQLITE_OK;
-}
-
-/* insert into %_content (docid, ...) values ([docid], [pValues])
-** If the docid contains SQL NULL, then a unique docid will be
-** generated.
-*/
-static int content_insert(fulltext_vtab *v, sqlite3_value *docid,
- sqlite3_value **pValues){
- sqlite3_stmt *s;
- int i;
- int rc = sql_get_statement(v, CONTENT_INSERT_STMT, &s);
- if( rc!=SQLITE_OK ) return rc;
-
- rc = sqlite3_bind_value(s, 1, docid);
- if( rc!=SQLITE_OK ) return rc;
-
- for(i=0; i<v->nColumn; ++i){
- rc = sqlite3_bind_value(s, 2+i, pValues[i]);
- if( rc!=SQLITE_OK ) return rc;
- }
-
- return sql_single_step(s);
-}
-
-/* update %_content set col0 = pValues[0], col1 = pValues[1], ...
- * where docid = [iDocid] */
-static int content_update(fulltext_vtab *v, sqlite3_value **pValues,
- sqlite_int64 iDocid){
- sqlite3_stmt *s;
- int i;
- int rc = sql_get_statement(v, CONTENT_UPDATE_STMT, &s);
- if( rc!=SQLITE_OK ) return rc;
-
- for(i=0; i<v->nColumn; ++i){
- rc = sqlite3_bind_value(s, 1+i, pValues[i]);
- if( rc!=SQLITE_OK ) return rc;
- }
-
- rc = sqlite3_bind_int64(s, 1+v->nColumn, iDocid);
- if( rc!=SQLITE_OK ) return rc;
-
- return sql_single_step(s);
-}
-
-static void freeStringArray(int nString, const char **pString){
- int i;
-
- for (i=0 ; i < nString ; ++i) {
- if( pString[i]!=NULL ) sqlite3_free((void *) pString[i]);
- }
- sqlite3_free((void *) pString);
-}
-
-/* select * from %_content where docid = [iDocid]
- * The caller must delete the returned array and all strings in it.
- * null fields will be NULL in the returned array.
- *
- * TODO: Perhaps we should return pointer/length strings here for consistency
- * with other code which uses pointer/length. */
-static int content_select(fulltext_vtab *v, sqlite_int64 iDocid,
- const char ***pValues){
- sqlite3_stmt *s;
- const char **values;
- int i;
- int rc;
-
- *pValues = NULL;
-
- rc = sql_get_statement(v, CONTENT_SELECT_STMT, &s);
- if( rc!=SQLITE_OK ) return rc;
-
- rc = sqlite3_bind_int64(s, 1, iDocid);
- if( rc!=SQLITE_OK ) return rc;
-
- rc = sqlite3_step(s);
- if( rc!=SQLITE_ROW ) return rc;
-
- values = (const char **) sqlite3_malloc(v->nColumn * sizeof(const char *));
- for(i=0; i<v->nColumn; ++i){
- if( sqlite3_column_type(s, i)==SQLITE_NULL ){
- values[i] = NULL;
- }else{
- values[i] = string_dup((char*)sqlite3_column_text(s, i));
- }
- }
-
- /* We expect only one row. We must execute another sqlite3_step()
- * to complete the iteration; otherwise the table will remain locked. */
- rc = sqlite3_step(s);
- if( rc==SQLITE_DONE ){
- *pValues = values;
- return SQLITE_OK;
- }
-
- freeStringArray(v->nColumn, values);
- return rc;
-}
-
-/* delete from %_content where docid = [iDocid ] */
-static int content_delete(fulltext_vtab *v, sqlite_int64 iDocid){
- sqlite3_stmt *s;
- int rc = sql_get_statement(v, CONTENT_DELETE_STMT, &s);
- if( rc!=SQLITE_OK ) return rc;
-
- rc = sqlite3_bind_int64(s, 1, iDocid);
- if( rc!=SQLITE_OK ) return rc;
-
- return sql_single_step(s);
-}
-
-/* Returns SQLITE_ROW if any rows exist in %_content, SQLITE_DONE if
-** no rows exist, and any error in case of failure.
-*/
-static int content_exists(fulltext_vtab *v){
- sqlite3_stmt *s;
- int rc = sql_get_statement(v, CONTENT_EXISTS_STMT, &s);
- if( rc!=SQLITE_OK ) return rc;
-
- rc = sqlite3_step(s);
- if( rc!=SQLITE_ROW ) return rc;
-
- /* We expect only one row. We must execute another sqlite3_step()
- * to complete the iteration; otherwise the table will remain locked. */
- rc = sqlite3_step(s);
- if( rc==SQLITE_DONE ) return SQLITE_ROW;
- if( rc==SQLITE_ROW ) return SQLITE_ERROR;
- return rc;
-}
-
-/* insert into %_segments values ([pData])
-** returns assigned blockid in *piBlockid
-*/
-static int block_insert(fulltext_vtab *v, const char *pData, int nData,
- sqlite_int64 *piBlockid){
- sqlite3_stmt *s;
- int rc = sql_get_statement(v, BLOCK_INSERT_STMT, &s);
- if( rc!=SQLITE_OK ) return rc;
-
- rc = sqlite3_bind_blob(s, 1, pData, nData, SQLITE_STATIC);
- if( rc!=SQLITE_OK ) return rc;
-
- rc = sqlite3_step(s);
- if( rc==SQLITE_ROW ) return SQLITE_ERROR;
- if( rc!=SQLITE_DONE ) return rc;
-
- /* blockid column is an alias for rowid. */
- *piBlockid = sqlite3_last_insert_rowid(v->db);
- return SQLITE_OK;
-}
-
-/* delete from %_segments
-** where blockid between [iStartBlockid] and [iEndBlockid]
-**
-** Deletes the range of blocks, inclusive, used to delete the blocks
-** which form a segment.
-*/
-static int block_delete(fulltext_vtab *v,
- sqlite_int64 iStartBlockid, sqlite_int64 iEndBlockid){
- sqlite3_stmt *s;
- int rc = sql_get_statement(v, BLOCK_DELETE_STMT, &s);
- if( rc!=SQLITE_OK ) return rc;
-
- rc = sqlite3_bind_int64(s, 1, iStartBlockid);
- if( rc!=SQLITE_OK ) return rc;
-
- rc = sqlite3_bind_int64(s, 2, iEndBlockid);
- if( rc!=SQLITE_OK ) return rc;
-
- return sql_single_step(s);
-}
-
-/* Returns SQLITE_ROW with *pidx set to the maximum segment idx found
-** at iLevel. Returns SQLITE_DONE if there are no segments at
-** iLevel. Otherwise returns an error.
-*/
-static int segdir_max_index(fulltext_vtab *v, int iLevel, int *pidx){
- sqlite3_stmt *s;
- int rc = sql_get_statement(v, SEGDIR_MAX_INDEX_STMT, &s);
- if( rc!=SQLITE_OK ) return rc;
-
- rc = sqlite3_bind_int(s, 1, iLevel);
- if( rc!=SQLITE_OK ) return rc;
-
- rc = sqlite3_step(s);
- /* Should always get at least one row due to how max() works. */
- if( rc==SQLITE_DONE ) return SQLITE_DONE;
- if( rc!=SQLITE_ROW ) return rc;
-
- /* NULL means that there were no inputs to max(). */
- if( SQLITE_NULL==sqlite3_column_type(s, 0) ){
- rc = sqlite3_step(s);
- if( rc==SQLITE_ROW ) return SQLITE_ERROR;
- return rc;
- }
-
- *pidx = sqlite3_column_int(s, 0);
-
- /* We expect only one row. We must execute another sqlite3_step()
- * to complete the iteration; otherwise the table will remain locked. */
- rc = sqlite3_step(s);
- if( rc==SQLITE_ROW ) return SQLITE_ERROR;
- if( rc!=SQLITE_DONE ) return rc;
- return SQLITE_ROW;
-}
-
-/* insert into %_segdir values (
-** [iLevel], [idx],
-** [iStartBlockid], [iLeavesEndBlockid], [iEndBlockid],
-** [pRootData]
-** )
-*/
-static int segdir_set(fulltext_vtab *v, int iLevel, int idx,
- sqlite_int64 iStartBlockid,
- sqlite_int64 iLeavesEndBlockid,
- sqlite_int64 iEndBlockid,
- const char *pRootData, int nRootData){
- sqlite3_stmt *s;
- int rc = sql_get_statement(v, SEGDIR_SET_STMT, &s);
- if( rc!=SQLITE_OK ) return rc;
-
- rc = sqlite3_bind_int(s, 1, iLevel);
- if( rc!=SQLITE_OK ) return rc;
-
- rc = sqlite3_bind_int(s, 2, idx);
- if( rc!=SQLITE_OK ) return rc;
-
- rc = sqlite3_bind_int64(s, 3, iStartBlockid);
- if( rc!=SQLITE_OK ) return rc;
-
- rc = sqlite3_bind_int64(s, 4, iLeavesEndBlockid);
- if( rc!=SQLITE_OK ) return rc;
-
- rc = sqlite3_bind_int64(s, 5, iEndBlockid);
- if( rc!=SQLITE_OK ) return rc;
-
- rc = sqlite3_bind_blob(s, 6, pRootData, nRootData, SQLITE_STATIC);
- if( rc!=SQLITE_OK ) return rc;
-
- return sql_single_step(s);
-}
-
-/* Queries %_segdir for the block span of the segments in level
-** iLevel. Returns SQLITE_DONE if there are no blocks for iLevel,
-** SQLITE_ROW if there are blocks, else an error.
-*/
-static int segdir_span(fulltext_vtab *v, int iLevel,
- sqlite_int64 *piStartBlockid,
- sqlite_int64 *piEndBlockid){
- sqlite3_stmt *s;
- int rc = sql_get_statement(v, SEGDIR_SPAN_STMT, &s);
- if( rc!=SQLITE_OK ) return rc;
-
- rc = sqlite3_bind_int(s, 1, iLevel);
- if( rc!=SQLITE_OK ) return rc;
-
- rc = sqlite3_step(s);
- if( rc==SQLITE_DONE ) return SQLITE_DONE; /* Should never happen */
- if( rc!=SQLITE_ROW ) return rc;
-
- /* This happens if all segments at this level are entirely inline. */
- if( SQLITE_NULL==sqlite3_column_type(s, 0) ){
- /* We expect only one row. We must execute another sqlite3_step()
- * to complete the iteration; otherwise the table will remain locked. */
- int rc2 = sqlite3_step(s);
- if( rc2==SQLITE_ROW ) return SQLITE_ERROR;
- return rc2;
- }
-
- *piStartBlockid = sqlite3_column_int64(s, 0);
- *piEndBlockid = sqlite3_column_int64(s, 1);
-
- /* We expect only one row. We must execute another sqlite3_step()
- * to complete the iteration; otherwise the table will remain locked. */
- rc = sqlite3_step(s);
- if( rc==SQLITE_ROW ) return SQLITE_ERROR;
- if( rc!=SQLITE_DONE ) return rc;
- return SQLITE_ROW;
-}
-
-/* Delete the segment blocks and segment directory records for all
-** segments at iLevel.
-*/
-static int segdir_delete(fulltext_vtab *v, int iLevel){
- sqlite3_stmt *s;
- sqlite_int64 iStartBlockid, iEndBlockid;
- int rc = segdir_span(v, iLevel, &iStartBlockid, &iEndBlockid);
- if( rc!=SQLITE_ROW && rc!=SQLITE_DONE ) return rc;
-
- if( rc==SQLITE_ROW ){
- rc = block_delete(v, iStartBlockid, iEndBlockid);
- if( rc!=SQLITE_OK ) return rc;
- }
-
- /* Delete the segment directory itself. */
- rc = sql_get_statement(v, SEGDIR_DELETE_STMT, &s);
- if( rc!=SQLITE_OK ) return rc;
-
- rc = sqlite3_bind_int64(s, 1, iLevel);
- if( rc!=SQLITE_OK ) return rc;
-
- return sql_single_step(s);
-}
-
-/* Delete entire fts index, SQLITE_OK on success, relevant error on
-** failure.
-*/
-static int segdir_delete_all(fulltext_vtab *v){
- sqlite3_stmt *s;
- int rc = sql_get_statement(v, SEGDIR_DELETE_ALL_STMT, &s);
- if( rc!=SQLITE_OK ) return rc;
-
- rc = sql_single_step(s);
- if( rc!=SQLITE_OK ) return rc;
-
- rc = sql_get_statement(v, BLOCK_DELETE_ALL_STMT, &s);
- if( rc!=SQLITE_OK ) return rc;
-
- return sql_single_step(s);
-}
-
-/* Returns SQLITE_OK with *pnSegments set to the number of entries in
-** %_segdir and *piMaxLevel set to the highest level which has a
-** segment. Otherwise returns the SQLite error which caused failure.
-*/
-static int segdir_count(fulltext_vtab *v, int *pnSegments, int *piMaxLevel){
- sqlite3_stmt *s;
- int rc = sql_get_statement(v, SEGDIR_COUNT_STMT, &s);
- if( rc!=SQLITE_OK ) return rc;
-
- rc = sqlite3_step(s);
- /* TODO(shess): This case should not be possible? Should stronger
- ** measures be taken if it happens?
- */
- if( rc==SQLITE_DONE ){
- *pnSegments = 0;
- *piMaxLevel = 0;
- return SQLITE_OK;
- }
- if( rc!=SQLITE_ROW ) return rc;
-
- *pnSegments = sqlite3_column_int(s, 0);
- *piMaxLevel = sqlite3_column_int(s, 1);
-
- /* We expect only one row. We must execute another sqlite3_step()
- * to complete the iteration; otherwise the table will remain locked. */
- rc = sqlite3_step(s);
- if( rc==SQLITE_DONE ) return SQLITE_OK;
- if( rc==SQLITE_ROW ) return SQLITE_ERROR;
- return rc;
-}
-
-/* TODO(shess) clearPendingTerms() is far down the file because
-** writeZeroSegment() is far down the file because LeafWriter is far
-** down the file. Consider refactoring the code to move the non-vtab
-** code above the vtab code so that we don't need this forward
-** reference.
-*/
-static int clearPendingTerms(fulltext_vtab *v);
-
-/*
-** Free the memory used to contain a fulltext_vtab structure.
-*/
-static void fulltext_vtab_destroy(fulltext_vtab *v){
- int iStmt, i;
-
- FTSTRACE(("FTS3 Destroy %p\n", v));
- for( iStmt=0; iStmt<MAX_STMT; iStmt++ ){
- if( v->pFulltextStatements[iStmt]!=NULL ){
- sqlite3_finalize(v->pFulltextStatements[iStmt]);
- v->pFulltextStatements[iStmt] = NULL;
- }
- }
-
- for( i=0; i<MERGE_COUNT; i++ ){
- if( v->pLeafSelectStmts[i]!=NULL ){
- sqlite3_finalize(v->pLeafSelectStmts[i]);
- v->pLeafSelectStmts[i] = NULL;
- }
- }
-
- if( v->pTokenizer!=NULL ){
- v->pTokenizer->pModule->xDestroy(v->pTokenizer);
- v->pTokenizer = NULL;
- }
-
- clearPendingTerms(v);
-
- sqlite3_free(v->azColumn);
- for(i = 0; i < v->nColumn; ++i) {
- sqlite3_free(v->azContentColumn[i]);
- }
- sqlite3_free(v->azContentColumn);
- sqlite3_free(v);
-}
-
-/*
-** Token types for parsing the arguments to xConnect or xCreate.
-*/
-#define TOKEN_EOF 0 /* End of file */
-#define TOKEN_SPACE 1 /* Any kind of whitespace */
-#define TOKEN_ID 2 /* An identifier */
-#define TOKEN_STRING 3 /* A string literal */
-#define TOKEN_PUNCT 4 /* A single punctuation character */
-
-/*
-** If X is a character that can be used in an identifier then
-** ftsIdChar(X) will be true. Otherwise it is false.
-**
-** For ASCII, any character with the high-order bit set is
-** allowed in an identifier. For 7-bit characters,
-** isFtsIdChar[X] must be 1.
-**
-** Ticket #1066. the SQL standard does not allow '$' in the
-** middle of identfiers. But many SQL implementations do.
-** SQLite will allow '$' in identifiers for compatibility.
-** But the feature is undocumented.
-*/
-static const char isFtsIdChar[] = {
-/* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF */
- 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 2x */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 3x */
- 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 4x */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, /* 5x */
- 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 6x */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* 7x */
-};
-#define ftsIdChar(C) (((c=C)&0x80)!=0 || (c>0x1f && isFtsIdChar[c-0x20]))
-
-
-/*
-** Return the length of the token that begins at z[0].
-** Store the token type in *tokenType before returning.
-*/
-static int ftsGetToken(const char *z, int *tokenType){
- int i, c;
- switch( *z ){
- case 0: {
- *tokenType = TOKEN_EOF;
- return 0;
- }
- case ' ': case '\t': case '\n': case '\f': case '\r': {
- for(i=1; safe_isspace(z[i]); i++){}
- *tokenType = TOKEN_SPACE;
- return i;
- }
- case '`':
- case '\'':
- case '"': {
- int delim = z[0];
- for(i=1; (c=z[i])!=0; i++){
- if( c==delim ){
- if( z[i+1]==delim ){
- i++;
- }else{
- break;
- }
- }
- }
- *tokenType = TOKEN_STRING;
- return i + (c!=0);
- }
- case '[': {
- for(i=1, c=z[0]; c!=']' && (c=z[i])!=0; i++){}
- *tokenType = TOKEN_ID;
- return i;
- }
- default: {
- if( !ftsIdChar(*z) ){
- break;
- }
- for(i=1; ftsIdChar(z[i]); i++){}
- *tokenType = TOKEN_ID;
- return i;
- }
- }
- *tokenType = TOKEN_PUNCT;
- return 1;
-}
-
-/*
-** A token extracted from a string is an instance of the following
-** structure.
-*/
-typedef struct FtsToken {
- const char *z; /* Pointer to token text. Not '\000' terminated */
- short int n; /* Length of the token text in bytes. */
-} FtsToken;
-
-/*
-** Given a input string (which is really one of the argv[] parameters
-** passed into xConnect or xCreate) split the string up into tokens.
-** Return an array of pointers to '\000' terminated strings, one string
-** for each non-whitespace token.
-**
-** The returned array is terminated by a single NULL pointer.
-**
-** Space to hold the returned array is obtained from a single
-** malloc and should be freed by passing the return value to free().
-** The individual strings within the token list are all a part of
-** the single memory allocation and will all be freed at once.
-*/
-static char **tokenizeString(const char *z, int *pnToken){
- int nToken = 0;
- FtsToken *aToken = sqlite3_malloc( strlen(z) * sizeof(aToken[0]) );
- int n = 1;
- int e, i;
- int totalSize = 0;
- char **azToken;
- char *zCopy;
- while( n>0 ){
- n = ftsGetToken(z, &e);
- if( e!=TOKEN_SPACE ){
- aToken[nToken].z = z;
- aToken[nToken].n = n;
- nToken++;
- totalSize += n+1;
- }
- z += n;
- }
- azToken = (char**)sqlite3_malloc( nToken*sizeof(char*) + totalSize );
- zCopy = (char*)&azToken[nToken];
- nToken--;
- for(i=0; i<nToken; i++){
- azToken[i] = zCopy;
- n = aToken[i].n;
- memcpy(zCopy, aToken[i].z, n);
- zCopy[n] = 0;
- zCopy += n+1;
- }
- azToken[nToken] = 0;
- sqlite3_free(aToken);
- *pnToken = nToken;
- return azToken;
-}
-
-/*
-** Convert an SQL-style quoted string into a normal string by removing
-** the quote characters. The conversion is done in-place. If the
-** input does not begin with a quote character, then this routine
-** is a no-op.
-**
-** Examples:
-**
-** "abc" becomes abc
-** 'xyz' becomes xyz
-** [pqr] becomes pqr
-** `mno` becomes mno
-*/
-static void dequoteString(char *z){
- int quote;
- int i, j;
- if( z==0 ) return;
- quote = z[0];
- switch( quote ){
- case '\'': break;
- case '"': break;
- case '`': break; /* For MySQL compatibility */
- case '[': quote = ']'; break; /* For MS SqlServer compatibility */
- default: return;
- }
- for(i=1, j=0; z[i]; i++){
- if( z[i]==quote ){
- if( z[i+1]==quote ){
- z[j++] = quote;
- i++;
- }else{
- z[j++] = 0;
- break;
- }
- }else{
- z[j++] = z[i];
- }
- }
-}
-
-/*
-** The input azIn is a NULL-terminated list of tokens. Remove the first
-** token and all punctuation tokens. Remove the quotes from
-** around string literal tokens.
-**
-** Example:
-**
-** input: tokenize chinese ( 'simplifed' , 'mixed' )
-** output: chinese simplifed mixed
-**
-** Another example:
-**
-** input: delimiters ( '[' , ']' , '...' )
-** output: [ ] ...
-*/
-static void tokenListToIdList(char **azIn){
- int i, j;
- if( azIn ){
- for(i=0, j=-1; azIn[i]; i++){
- if( safe_isalnum(azIn[i][0]) || azIn[i][1] ){
- dequoteString(azIn[i]);
- if( j>=0 ){
- azIn[j] = azIn[i];
- }
- j++;
- }
- }
- azIn[j] = 0;
- }
-}
-
-
-/*
-** Find the first alphanumeric token in the string zIn. Null-terminate
-** this token. Remove any quotation marks. And return a pointer to
-** the result.
-*/
-static char *firstToken(char *zIn, char **pzTail){
- int n, ttype;
- while(1){
- n = ftsGetToken(zIn, &ttype);
- if( ttype==TOKEN_SPACE ){
- zIn += n;
- }else if( ttype==TOKEN_EOF ){
- *pzTail = zIn;
- return 0;
- }else{
- zIn[n] = 0;
- *pzTail = &zIn[1];
- dequoteString(zIn);
- return zIn;
- }
- }
- /*NOTREACHED*/
-}
-
-/* Return true if...
-**
-** * s begins with the string t, ignoring case
-** * s is longer than t
-** * The first character of s beyond t is not a alphanumeric
-**
-** Ignore leading space in *s.
-**
-** To put it another way, return true if the first token of
-** s[] is t[].
-*/
-static int startsWith(const char *s, const char *t){
- while( safe_isspace(*s) ){ s++; }
- while( *t ){
- if( safe_tolower(*s++)!=safe_tolower(*t++) ) return 0;
- }
- return *s!='_' && !safe_isalnum(*s);
-}
-
-/*
-** An instance of this structure defines the "spec" of a
-** full text index. This structure is populated by parseSpec
-** and use by fulltextConnect and fulltextCreate.
-*/
-typedef struct TableSpec {
- const char *zDb; /* Logical database name */
- const char *zName; /* Name of the full-text index */
- int nColumn; /* Number of columns to be indexed */
- char **azColumn; /* Original names of columns to be indexed */
- char **azContentColumn; /* Column names for %_content */
- char **azTokenizer; /* Name of tokenizer and its arguments */
-} TableSpec;
-
-/*
-** Reclaim all of the memory used by a TableSpec
-*/
-static void clearTableSpec(TableSpec *p) {
- sqlite3_free(p->azColumn);
- sqlite3_free(p->azContentColumn);
- sqlite3_free(p->azTokenizer);
-}
-
-/* Parse a CREATE VIRTUAL TABLE statement, which looks like this:
- *
- * CREATE VIRTUAL TABLE email
- * USING fts3(subject, body, tokenize mytokenizer(myarg))
- *
- * We return parsed information in a TableSpec structure.
- *
- */
-static int parseSpec(TableSpec *pSpec, int argc, const char *const*argv,
- char**pzErr){
- int i, n;
- char *z, *zDummy;
- char **azArg;
- const char *zTokenizer = 0; /* argv[] entry describing the tokenizer */
-
- assert( argc>=3 );
- /* Current interface:
- ** argv[0] - module name
- ** argv[1] - database name
- ** argv[2] - table name
- ** argv[3..] - columns, optionally followed by tokenizer specification
- ** and snippet delimiters specification.
- */
-
- /* Make a copy of the complete argv[][] array in a single allocation.
- ** The argv[][] array is read-only and transient. We can write to the
- ** copy in order to modify things and the copy is persistent.
- */
- CLEAR(pSpec);
- for(i=n=0; i<argc; i++){
- n += strlen(argv[i]) + 1;
- }
- azArg = sqlite3_malloc( sizeof(char*)*argc + n );
- if( azArg==0 ){
- return SQLITE_NOMEM;
- }
- z = (char*)&azArg[argc];
- for(i=0; i<argc; i++){
- azArg[i] = z;
- strcpy(z, argv[i]);
- z += strlen(z)+1;
- }
-
- /* Identify the column names and the tokenizer and delimiter arguments
- ** in the argv[][] array.
- */
- pSpec->zDb = azArg[1];
- pSpec->zName = azArg[2];
- pSpec->nColumn = 0;
- pSpec->azColumn = azArg;
- zTokenizer = "tokenize simple";
- for(i=3; i<argc; ++i){
- if( startsWith(azArg[i],"tokenize") ){
- zTokenizer = azArg[i];
- }else{
- z = azArg[pSpec->nColumn] = firstToken(azArg[i], &zDummy);
- pSpec->nColumn++;
- }
- }
- if( pSpec->nColumn==0 ){
- azArg[0] = "content";
- pSpec->nColumn = 1;
- }
-
- /*
- ** Construct the list of content column names.
- **
- ** Each content column name will be of the form cNNAAAA
- ** where NN is the column number and AAAA is the sanitized
- ** column name. "sanitized" means that special characters are
- ** converted to "_". The cNN prefix guarantees that all column
- ** names are unique.
- **
- ** The AAAA suffix is not strictly necessary. It is included
- ** for the convenience of people who might examine the generated
- ** %_content table and wonder what the columns are used for.
- */
- pSpec->azContentColumn = sqlite3_malloc( pSpec->nColumn * sizeof(char *) );
- if( pSpec->azContentColumn==0 ){
- clearTableSpec(pSpec);
- return SQLITE_NOMEM;
- }
- for(i=0; i<pSpec->nColumn; i++){
- char *p;
- pSpec->azContentColumn[i] = sqlite3_mprintf("c%d%s", i, azArg[i]);
- for (p = pSpec->azContentColumn[i]; *p ; ++p) {
- if( !safe_isalnum(*p) ) *p = '_';
- }
- }
-
- /*
- ** Parse the tokenizer specification string.
- */
- pSpec->azTokenizer = tokenizeString(zTokenizer, &n);
- tokenListToIdList(pSpec->azTokenizer);
-
- return SQLITE_OK;
-}
-
-/*
-** Generate a CREATE TABLE statement that describes the schema of
-** the virtual table. Return a pointer to this schema string.
-**
-** Space is obtained from sqlite3_mprintf() and should be freed
-** using sqlite3_free().
-*/
-static char *fulltextSchema(
- int nColumn, /* Number of columns */
- const char *const* azColumn, /* List of columns */
- const char *zTableName /* Name of the table */
-){
- int i;
- char *zSchema, *zNext;
- const char *zSep = "(";
- zSchema = sqlite3_mprintf("CREATE TABLE x");
- for(i=0; i<nColumn; i++){
- zNext = sqlite3_mprintf("%s%s%Q", zSchema, zSep, azColumn[i]);
- sqlite3_free(zSchema);
- zSchema = zNext;
- zSep = ",";
- }
- zNext = sqlite3_mprintf("%s,%Q HIDDEN", zSchema, zTableName);
- sqlite3_free(zSchema);
- zSchema = zNext;
- zNext = sqlite3_mprintf("%s,docid HIDDEN)", zSchema);
- sqlite3_free(zSchema);
- return zNext;
-}
-
-/*
-** Build a new sqlite3_vtab structure that will describe the
-** fulltext index defined by spec.
-*/
-static int constructVtab(
- sqlite3 *db, /* The SQLite database connection */
- fts3Hash *pHash, /* Hash table containing tokenizers */
- TableSpec *spec, /* Parsed spec information from parseSpec() */
- sqlite3_vtab **ppVTab, /* Write the resulting vtab structure here */
- char **pzErr /* Write any error message here */
-){
- int rc;
- int n;
- fulltext_vtab *v = 0;
- const sqlite3_tokenizer_module *m = NULL;
- char *schema;
-
- char const *zTok; /* Name of tokenizer to use for this fts table */
- int nTok; /* Length of zTok, including nul terminator */
-
- v = (fulltext_vtab *) sqlite3_malloc(sizeof(fulltext_vtab));
- if( v==0 ) return SQLITE_NOMEM;
- CLEAR(v);
- /* sqlite will initialize v->base */
- v->db = db;
- v->zDb = spec->zDb; /* Freed when azColumn is freed */
- v->zName = spec->zName; /* Freed when azColumn is freed */
- v->nColumn = spec->nColumn;
- v->azContentColumn = spec->azContentColumn;
- spec->azContentColumn = 0;
- v->azColumn = spec->azColumn;
- spec->azColumn = 0;
-
- if( spec->azTokenizer==0 ){
- return SQLITE_NOMEM;
- }
-
- zTok = spec->azTokenizer[0];
- if( !zTok ){
- zTok = "simple";
- }
- nTok = strlen(zTok)+1;
-
- m = (sqlite3_tokenizer_module *)sqlite3Fts3HashFind(pHash, zTok, nTok);
- if( !m ){
- *pzErr = sqlite3_mprintf("unknown tokenizer: %s", spec->azTokenizer[0]);
- rc = SQLITE_ERROR;
- goto err;
- }
-
- for(n=0; spec->azTokenizer[n]; n++){}
- if( n ){
- rc = m->xCreate(n-1, (const char*const*)&spec->azTokenizer[1],
- &v->pTokenizer);
- }else{
- rc = m->xCreate(0, 0, &v->pTokenizer);
- }
- if( rc!=SQLITE_OK ) goto err;
- v->pTokenizer->pModule = m;
-
- /* TODO: verify the existence of backing tables foo_content, foo_term */
-
- schema = fulltextSchema(v->nColumn, (const char*const*)v->azColumn,
- spec->zName);
- rc = sqlite3_declare_vtab(db, schema);
- sqlite3_free(schema);
- if( rc!=SQLITE_OK ) goto err;
-
- memset(v->pFulltextStatements, 0, sizeof(v->pFulltextStatements));
-
- /* Indicate that the buffer is not live. */
- v->nPendingData = -1;
-
- *ppVTab = &v->base;
- FTSTRACE(("FTS3 Connect %p\n", v));
-
- return rc;
-
-err:
- fulltext_vtab_destroy(v);
- return rc;
-}
-
-static int fulltextConnect(
- sqlite3 *db,
- void *pAux,
- int argc, const char *const*argv,
- sqlite3_vtab **ppVTab,
- char **pzErr
-){
- TableSpec spec;
- int rc = parseSpec(&spec, argc, argv, pzErr);
- if( rc!=SQLITE_OK ) return rc;
-
- rc = constructVtab(db, (fts3Hash *)pAux, &spec, ppVTab, pzErr);
- clearTableSpec(&spec);
- return rc;
-}
-
-/* The %_content table holds the text of each document, with
-** the docid column exposed as the SQLite rowid for the table.
-*/
-/* TODO(shess) This comment needs elaboration to match the updated
-** code. Work it into the top-of-file comment at that time.
-*/
-static int fulltextCreate(sqlite3 *db, void *pAux,
- int argc, const char * const *argv,
- sqlite3_vtab **ppVTab, char **pzErr){
- int rc;
- TableSpec spec;
- StringBuffer schema;
- FTSTRACE(("FTS3 Create\n"));
-
- rc = parseSpec(&spec, argc, argv, pzErr);
- if( rc!=SQLITE_OK ) return rc;
-
- initStringBuffer(&schema);
- append(&schema, "CREATE TABLE %_content(");
- append(&schema, " docid INTEGER PRIMARY KEY,");
- appendList(&schema, spec.nColumn, spec.azContentColumn);
- append(&schema, ")");
- rc = sql_exec(db, spec.zDb, spec.zName, stringBufferData(&schema));
- stringBufferDestroy(&schema);
- if( rc!=SQLITE_OK ) goto out;
-
- rc = sql_exec(db, spec.zDb, spec.zName,
- "create table %_segments("
- " blockid INTEGER PRIMARY KEY,"
- " block blob"
- ");"
- );
- if( rc!=SQLITE_OK ) goto out;
-
- rc = sql_exec(db, spec.zDb, spec.zName,
- "create table %_segdir("
- " level integer,"
- " idx integer,"
- " start_block integer,"
- " leaves_end_block integer,"
- " end_block integer,"
- " root blob,"
- " primary key(level, idx)"
- ");");
- if( rc!=SQLITE_OK ) goto out;
-
- rc = constructVtab(db, (fts3Hash *)pAux, &spec, ppVTab, pzErr);
-
-out:
- clearTableSpec(&spec);
- return rc;
-}
-
-/* Decide how to handle an SQL query. */
-static int fulltextBestIndex(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){
- fulltext_vtab *v = (fulltext_vtab *)pVTab;
- int i;
- FTSTRACE(("FTS3 BestIndex\n"));
-
- for(i=0; i<pInfo->nConstraint; ++i){
- const struct sqlite3_index_constraint *pConstraint;
- pConstraint = &pInfo->aConstraint[i];
- if( pConstraint->usable ) {
- if( (pConstraint->iColumn==-1 || pConstraint->iColumn==v->nColumn+1) &&
- pConstraint->op==SQLITE_INDEX_CONSTRAINT_EQ ){
- pInfo->idxNum = QUERY_DOCID; /* lookup by docid */
- FTSTRACE(("FTS3 QUERY_DOCID\n"));
- } else if( pConstraint->iColumn>=0 && pConstraint->iColumn<=v->nColumn &&
- pConstraint->op==SQLITE_INDEX_CONSTRAINT_MATCH ){
- /* full-text search */
- pInfo->idxNum = QUERY_FULLTEXT + pConstraint->iColumn;
- FTSTRACE(("FTS3 QUERY_FULLTEXT %d\n", pConstraint->iColumn));
- } else continue;
-
- pInfo->aConstraintUsage[i].argvIndex = 1;
- pInfo->aConstraintUsage[i].omit = 1;
-
- /* An arbitrary value for now.
- * TODO: Perhaps docid matches should be considered cheaper than
- * full-text searches. */
- pInfo->estimatedCost = 1.0;
-
- return SQLITE_OK;
- }
- }
- pInfo->idxNum = QUERY_GENERIC;
- return SQLITE_OK;
-}
-
-static int fulltextDisconnect(sqlite3_vtab *pVTab){
- FTSTRACE(("FTS3 Disconnect %p\n", pVTab));
- fulltext_vtab_destroy((fulltext_vtab *)pVTab);
- return SQLITE_OK;
-}
-
-static int fulltextDestroy(sqlite3_vtab *pVTab){
- fulltext_vtab *v = (fulltext_vtab *)pVTab;
- int rc;
-
- FTSTRACE(("FTS3 Destroy %p\n", pVTab));
- rc = sql_exec(v->db, v->zDb, v->zName,
- "drop table if exists %_content;"
- "drop table if exists %_segments;"
- "drop table if exists %_segdir;"
- );
- if( rc!=SQLITE_OK ) return rc;
-
- fulltext_vtab_destroy((fulltext_vtab *)pVTab);
- return SQLITE_OK;
-}
-
-static int fulltextOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
- fulltext_cursor *c;
-
- c = (fulltext_cursor *) sqlite3_malloc(sizeof(fulltext_cursor));
- if( c ){
- memset(c, 0, sizeof(fulltext_cursor));
- /* sqlite will initialize c->base */
- *ppCursor = &c->base;
- FTSTRACE(("FTS3 Open %p: %p\n", pVTab, c));
- return SQLITE_OK;
- }else{
- return SQLITE_NOMEM;
- }
-}
-
-/* Free all of the dynamically allocated memory held by the
-** Snippet
-*/
-static void snippetClear(Snippet *p){
- sqlite3_free(p->aMatch);
- sqlite3_free(p->zOffset);
- sqlite3_free(p->zSnippet);
- CLEAR(p);
-}
-
-/*
-** Append a single entry to the p->aMatch[] log.
-*/
-static void snippetAppendMatch(
- Snippet *p, /* Append the entry to this snippet */
- int iCol, int iTerm, /* The column and query term */
- int iToken, /* Matching token in document */
- int iStart, int nByte /* Offset and size of the match */
-){
- int i;
- struct snippetMatch *pMatch;
- if( p->nMatch+1>=p->nAlloc ){
- p->nAlloc = p->nAlloc*2 + 10;
- p->aMatch = sqlite3_realloc(p->aMatch, p->nAlloc*sizeof(p->aMatch[0]) );
- if( p->aMatch==0 ){
- p->nMatch = 0;
- p->nAlloc = 0;
- return;
- }
- }
- i = p->nMatch++;
- pMatch = &p->aMatch[i];
- pMatch->iCol = iCol;
- pMatch->iTerm = iTerm;
- pMatch->iToken = iToken;
- pMatch->iStart = iStart;
- pMatch->nByte = nByte;
-}
-
-/*
-** Sizing information for the circular buffer used in snippetOffsetsOfColumn()
-*/
-#define FTS3_ROTOR_SZ (32)
-#define FTS3_ROTOR_MASK (FTS3_ROTOR_SZ-1)
-
-/*
-** Function to iterate through the tokens of a compiled expression.
-**
-** Except, skip all tokens on the right-hand side of a NOT operator.
-** This function is used to find tokens as part of snippet and offset
-** generation and we do nt want snippets and offsets to report matches
-** for tokens on the RHS of a NOT.
-*/
-static int fts3NextExprToken(Fts3Expr **ppExpr, int *piToken){
- Fts3Expr *p = *ppExpr;
- int iToken = *piToken;
- if( iToken<0 ){
- /* In this case the expression p is the root of an expression tree.
- ** Move to the first token in the expression tree.
- */
- while( p->pLeft ){
- p = p->pLeft;
- }
- iToken = 0;
- }else{
- assert(p && p->eType==FTSQUERY_PHRASE );
- if( iToken<(p->pPhrase->nToken-1) ){
- iToken++;
- }else{
- iToken = 0;
- while( p->pParent && p->pParent->pLeft!=p ){
- assert( p->pParent->pRight==p );
- p = p->pParent;
- }
- p = p->pParent;
- if( p ){
- assert( p->pRight!=0 );
- p = p->pRight;
- while( p->pLeft ){
- p = p->pLeft;
- }
- }
- }
- }
-
- *ppExpr = p;
- *piToken = iToken;
- return p?1:0;
-}
-
-/*
-** Return TRUE if the expression node pExpr is located beneath the
-** RHS of a NOT operator.
-*/
-static int fts3ExprBeneathNot(Fts3Expr *p){
- Fts3Expr *pParent;
- while( p ){
- pParent = p->pParent;
- if( pParent && pParent->eType==FTSQUERY_NOT && pParent->pRight==p ){
- return 1;
- }
- p = pParent;
- }
- return 0;
-}
-
-/*
-** Add entries to pSnippet->aMatch[] for every match that occurs against
-** document zDoc[0..nDoc-1] which is stored in column iColumn.
-*/
-static void snippetOffsetsOfColumn(
- fulltext_cursor *pCur, /* The fulltest search cursor */
- Snippet *pSnippet, /* The Snippet object to be filled in */
- int iColumn, /* Index of fulltext table column */
- const char *zDoc, /* Text of the fulltext table column */
- int nDoc /* Length of zDoc in bytes */
-){
- const sqlite3_tokenizer_module *pTModule; /* The tokenizer module */
- sqlite3_tokenizer *pTokenizer; /* The specific tokenizer */
- sqlite3_tokenizer_cursor *pTCursor; /* Tokenizer cursor */
- fulltext_vtab *pVtab; /* The full text index */
- int nColumn; /* Number of columns in the index */
- int i, j; /* Loop counters */
- int rc; /* Return code */
- unsigned int match, prevMatch; /* Phrase search bitmasks */
- const char *zToken; /* Next token from the tokenizer */
- int nToken; /* Size of zToken */
- int iBegin, iEnd, iPos; /* Offsets of beginning and end */
-
- /* The following variables keep a circular buffer of the last
- ** few tokens */
- unsigned int iRotor = 0; /* Index of current token */
- int iRotorBegin[FTS3_ROTOR_SZ]; /* Beginning offset of token */
- int iRotorLen[FTS3_ROTOR_SZ]; /* Length of token */
-
- pVtab = cursor_vtab(pCur);
- nColumn = pVtab->nColumn;
- pTokenizer = pVtab->pTokenizer;
- pTModule = pTokenizer->pModule;
- rc = pTModule->xOpen(pTokenizer, zDoc, nDoc, &pTCursor);
- if( rc ) return;
- pTCursor->pTokenizer = pTokenizer;
-
- prevMatch = 0;
- while( !pTModule->xNext(pTCursor, &zToken, &nToken, &iBegin, &iEnd, &iPos) ){
- Fts3Expr *pIter = pCur->pExpr;
- int iIter = -1;
- iRotorBegin[iRotor&FTS3_ROTOR_MASK] = iBegin;
- iRotorLen[iRotor&FTS3_ROTOR_MASK] = iEnd-iBegin;
- match = 0;
- for(i=0; i<(FTS3_ROTOR_SZ-1) && fts3NextExprToken(&pIter, &iIter); i++){
- int nPhrase; /* Number of tokens in current phrase */
- struct PhraseToken *pToken; /* Current token */
- int iCol; /* Column index */
-
- if( fts3ExprBeneathNot(pIter) ) continue;
- nPhrase = pIter->pPhrase->nToken;
- pToken = &pIter->pPhrase->aToken[iIter];
- iCol = pIter->pPhrase->iColumn;
- if( iCol>=0 && iCol<nColumn && iCol!=iColumn ) continue;
- if( pToken->n>nToken ) continue;
- if( !pToken->isPrefix && pToken->n<nToken ) continue;
- assert( pToken->n<=nToken );
- if( memcmp(pToken->z, zToken, pToken->n) ) continue;
- if( iIter>0 && (prevMatch & (1<<i))==0 ) continue;
- match |= 1<<i;
- if( i==(FTS3_ROTOR_SZ-2) || nPhrase==iIter+1 ){
- for(j=nPhrase-1; j>=0; j--){
- int k = (iRotor-j) & FTS3_ROTOR_MASK;
- snippetAppendMatch(pSnippet, iColumn, i-j, iPos-j,
- iRotorBegin[k], iRotorLen[k]);
- }
- }
- }
- prevMatch = match<<1;
- iRotor++;
- }
- pTModule->xClose(pTCursor);
-}
-
-/*
-** Remove entries from the pSnippet structure to account for the NEAR
-** operator. When this is called, pSnippet contains the list of token
-** offsets produced by treating all NEAR operators as AND operators.
-** This function removes any entries that should not be present after
-** accounting for the NEAR restriction. For example, if the queried
-** document is:
-**
-** "A B C D E A"
-**
-** and the query is:
-**
-** A NEAR/0 E
-**
-** then when this function is called the Snippet contains token offsets
-** 0, 4 and 5. This function removes the "0" entry (because the first A
-** is not near enough to an E).
-**
-** When this function is called, the value pointed to by parameter piLeft is
-** the integer id of the left-most token in the expression tree headed by
-** pExpr. This function increments *piLeft by the total number of tokens
-** in the expression tree headed by pExpr.
-**
-** Return 1 if any trimming occurs. Return 0 if no trimming is required.
-*/
-static int trimSnippetOffsets(
- Fts3Expr *pExpr, /* The search expression */
- Snippet *pSnippet, /* The set of snippet offsets to be trimmed */
- int *piLeft /* Index of left-most token in pExpr */
-){
- if( pExpr ){
- if( trimSnippetOffsets(pExpr->pLeft, pSnippet, piLeft) ){
- return 1;
- }
-
- switch( pExpr->eType ){
- case FTSQUERY_PHRASE:
- *piLeft += pExpr->pPhrase->nToken;
- break;
- case FTSQUERY_NEAR: {
- /* The right-hand-side of a NEAR operator is always a phrase. The
- ** left-hand-side is either a phrase or an expression tree that is
- ** itself headed by a NEAR operator. The following initializations
- ** set local variable iLeft to the token number of the left-most
- ** token in the right-hand phrase, and iRight to the right most
- ** token in the same phrase. For example, if we had:
- **
- ** <col> MATCH '"abc def" NEAR/2 "ghi jkl"'
- **
- ** then iLeft will be set to 2 (token number of ghi) and nToken will
- ** be set to 4.
- */
- Fts3Expr *pLeft = pExpr->pLeft;
- Fts3Expr *pRight = pExpr->pRight;
- int iLeft = *piLeft;
- int nNear = pExpr->nNear;
- int nToken = pRight->pPhrase->nToken;
- int jj, ii;
- if( pLeft->eType==FTSQUERY_NEAR ){
- pLeft = pLeft->pRight;
- }
- assert( pRight->eType==FTSQUERY_PHRASE );
- assert( pLeft->eType==FTSQUERY_PHRASE );
- nToken += pLeft->pPhrase->nToken;
-
- for(ii=0; ii<pSnippet->nMatch; ii++){
- struct snippetMatch *p = &pSnippet->aMatch[ii];
- if( p->iTerm==iLeft ){
- int isOk = 0;
- /* Snippet ii is an occurence of query term iLeft in the document.
- ** It occurs at position (p->iToken) of the document. We now
- ** search for an instance of token (iLeft-1) somewhere in the
- ** range (p->iToken - nNear)...(p->iToken + nNear + nToken) within
- ** the set of snippetMatch structures. If one is found, proceed.
- ** If one cannot be found, then remove snippets ii..(ii+N-1)
- ** from the matching snippets, where N is the number of tokens
- ** in phrase pRight->pPhrase.
- */
- for(jj=0; isOk==0 && jj<pSnippet->nMatch; jj++){
- struct snippetMatch *p2 = &pSnippet->aMatch[jj];
- if( p2->iTerm==(iLeft-1) ){
- if( p2->iToken>=(p->iToken-nNear-1)
- && p2->iToken<(p->iToken+nNear+nToken)
- ){
- isOk = 1;
- }
- }
- }
- if( !isOk ){
- int kk;
- for(kk=0; kk<pRight->pPhrase->nToken; kk++){
- pSnippet->aMatch[kk+ii].iTerm = -2;
- }
- return 1;
- }
- }
- if( p->iTerm==(iLeft-1) ){
- int isOk = 0;
- for(jj=0; isOk==0 && jj<pSnippet->nMatch; jj++){
- struct snippetMatch *p2 = &pSnippet->aMatch[jj];
- if( p2->iTerm==iLeft ){
- if( p2->iToken<=(p->iToken+nNear+1)
- && p2->iToken>(p->iToken-nNear-nToken)
- ){
- isOk = 1;
- }
- }
- }
- if( !isOk ){
- int kk;
- for(kk=0; kk<pLeft->pPhrase->nToken; kk++){
- pSnippet->aMatch[ii-kk].iTerm = -2;
- }
- return 1;
- }
- }
- }
- break;
- }
- }
-
- if( trimSnippetOffsets(pExpr->pRight, pSnippet, piLeft) ){
- return 1;
- }
- }
- return 0;
-}
-
-/*
-** Compute all offsets for the current row of the query.
-** If the offsets have already been computed, this routine is a no-op.
-*/
-static void snippetAllOffsets(fulltext_cursor *p){
- int nColumn;
- int iColumn, i;
- int iFirst, iLast;
- int iTerm = 0;
- fulltext_vtab *pFts = cursor_vtab(p);
-
- if( p->snippet.nMatch || p->pExpr==0 ){
- return;
- }
- nColumn = pFts->nColumn;
- iColumn = (p->iCursorType - QUERY_FULLTEXT);
- if( iColumn<0 || iColumn>=nColumn ){
- /* Look for matches over all columns of the full-text index */
- iFirst = 0;
- iLast = nColumn-1;
- }else{
- /* Look for matches in the iColumn-th column of the index only */
- iFirst = iColumn;
- iLast = iColumn;
- }
- for(i=iFirst; i<=iLast; i++){
- const char *zDoc;
- int nDoc;
- zDoc = (const char*)sqlite3_column_text(p->pStmt, i+1);
- nDoc = sqlite3_column_bytes(p->pStmt, i+1);
- snippetOffsetsOfColumn(p, &p->snippet, i, zDoc, nDoc);
- }
-
- while( trimSnippetOffsets(p->pExpr, &p->snippet, &iTerm) ){
- iTerm = 0;
- }
-}
-
-/*
-** Convert the information in the aMatch[] array of the snippet
-** into the string zOffset[0..nOffset-1]. This string is used as
-** the return of the SQL offsets() function.
-*/
-static void snippetOffsetText(Snippet *p){
- int i;
- int cnt = 0;
- StringBuffer sb;
- char zBuf[200];
- if( p->zOffset ) return;
- initStringBuffer(&sb);
- for(i=0; i<p->nMatch; i++){
- struct snippetMatch *pMatch = &p->aMatch[i];
- if( pMatch->iTerm>=0 ){
- /* If snippetMatch.iTerm is less than 0, then the match was
- ** discarded as part of processing the NEAR operator (see the
- ** trimSnippetOffsetsForNear() function for details). Ignore
- ** it in this case
- */
- zBuf[0] = ' ';
- sqlite3_snprintf(sizeof(zBuf)-1, &zBuf[cnt>0], "%d %d %d %d",
- pMatch->iCol, pMatch->iTerm, pMatch->iStart, pMatch->nByte);
- append(&sb, zBuf);
- cnt++;
- }
- }
- p->zOffset = stringBufferData(&sb);
- p->nOffset = stringBufferLength(&sb);
-}
-
-/*
-** zDoc[0..nDoc-1] is phrase of text. aMatch[0..nMatch-1] are a set
-** of matching words some of which might be in zDoc. zDoc is column
-** number iCol.
-**
-** iBreak is suggested spot in zDoc where we could begin or end an
-** excerpt. Return a value similar to iBreak but possibly adjusted
-** to be a little left or right so that the break point is better.
-*/
-static int wordBoundary(
- int iBreak, /* The suggested break point */
- const char *zDoc, /* Document text */
- int nDoc, /* Number of bytes in zDoc[] */
- struct snippetMatch *aMatch, /* Matching words */
- int nMatch, /* Number of entries in aMatch[] */
- int iCol /* The column number for zDoc[] */
-){
- int i;
- if( iBreak<=10 ){
- return 0;
- }
- if( iBreak>=nDoc-10 ){
- return nDoc;
- }
- for(i=0; i<nMatch && aMatch[i].iCol<iCol; i++){}
- while( i<nMatch && aMatch[i].iStart+aMatch[i].nByte<iBreak ){ i++; }
- if( i<nMatch ){
- if( aMatch[i].iStart<iBreak+10 ){
- return aMatch[i].iStart;
- }
- if( i>0 && aMatch[i-1].iStart+aMatch[i-1].nByte>=iBreak ){
- return aMatch[i-1].iStart;
- }
- }
- for(i=1; i<=10; i++){
- if( safe_isspace(zDoc[iBreak-i]) ){
- return iBreak - i + 1;
- }
- if( safe_isspace(zDoc[iBreak+i]) ){
- return iBreak + i + 1;
- }
- }
- return iBreak;
-}
-
-
-
-/*
-** Allowed values for Snippet.aMatch[].snStatus
-*/
-#define SNIPPET_IGNORE 0 /* It is ok to omit this match from the snippet */
-#define SNIPPET_DESIRED 1 /* We want to include this match in the snippet */
-
-/*
-** Generate the text of a snippet.
-*/
-static void snippetText(
- fulltext_cursor *pCursor, /* The cursor we need the snippet for */
- const char *zStartMark, /* Markup to appear before each match */
- const char *zEndMark, /* Markup to appear after each match */
- const char *zEllipsis /* Ellipsis mark */
-){
- int i, j;
- struct snippetMatch *aMatch;
- int nMatch;
- int nDesired;
- StringBuffer sb;
- int tailCol;
- int tailOffset;
- int iCol;
- int nDoc;
- const char *zDoc;
- int iStart, iEnd;
- int tailEllipsis = 0;
- int iMatch;
-
-
- sqlite3_free(pCursor->snippet.zSnippet);
- pCursor->snippet.zSnippet = 0;
- aMatch = pCursor->snippet.aMatch;
- nMatch = pCursor->snippet.nMatch;
- initStringBuffer(&sb);
-
- for(i=0; i<nMatch; i++){
- aMatch[i].snStatus = SNIPPET_IGNORE;
- }
- nDesired = 0;
- for(i=0; i<FTS3_ROTOR_SZ; i++){
- for(j=0; j<nMatch; j++){
- if( aMatch[j].iTerm==i ){
- aMatch[j].snStatus = SNIPPET_DESIRED;
- nDesired++;
- break;
- }
- }
- }
-
- iMatch = 0;
- tailCol = -1;
- tailOffset = 0;
- for(i=0; i<nMatch && nDesired>0; i++){
- if( aMatch[i].snStatus!=SNIPPET_DESIRED ) continue;
- nDesired--;
- iCol = aMatch[i].iCol;
- zDoc = (const char*)sqlite3_column_text(pCursor->pStmt, iCol+1);
- nDoc = sqlite3_column_bytes(pCursor->pStmt, iCol+1);
- iStart = aMatch[i].iStart - 40;
- iStart = wordBoundary(iStart, zDoc, nDoc, aMatch, nMatch, iCol);
- if( iStart<=10 ){
- iStart = 0;
- }
- if( iCol==tailCol && iStart<=tailOffset+20 ){
- iStart = tailOffset;
- }
- if( (iCol!=tailCol && tailCol>=0) || iStart!=tailOffset ){
- trimWhiteSpace(&sb);
- appendWhiteSpace(&sb);
- append(&sb, zEllipsis);
- appendWhiteSpace(&sb);
- }
- iEnd = aMatch[i].iStart + aMatch[i].nByte + 40;
- iEnd = wordBoundary(iEnd, zDoc, nDoc, aMatch, nMatch, iCol);
- if( iEnd>=nDoc-10 ){
- iEnd = nDoc;
- tailEllipsis = 0;
- }else{
- tailEllipsis = 1;
- }
- while( iMatch<nMatch && aMatch[iMatch].iCol<iCol ){ iMatch++; }
- while( iStart<iEnd ){
- while( iMatch<nMatch && aMatch[iMatch].iStart<iStart
- && aMatch[iMatch].iCol<=iCol ){
- iMatch++;
- }
- if( iMatch<nMatch && aMatch[iMatch].iStart<iEnd
- && aMatch[iMatch].iCol==iCol ){
- nappend(&sb, &zDoc[iStart], aMatch[iMatch].iStart - iStart);
- iStart = aMatch[iMatch].iStart;
- append(&sb, zStartMark);
- nappend(&sb, &zDoc[iStart], aMatch[iMatch].nByte);
- append(&sb, zEndMark);
- iStart += aMatch[iMatch].nByte;
- for(j=iMatch+1; j<nMatch; j++){
- if( aMatch[j].iTerm==aMatch[iMatch].iTerm
- && aMatch[j].snStatus==SNIPPET_DESIRED ){
- nDesired--;
- aMatch[j].snStatus = SNIPPET_IGNORE;
- }
- }
- }else{
- nappend(&sb, &zDoc[iStart], iEnd - iStart);
- iStart = iEnd;
- }
- }
- tailCol = iCol;
- tailOffset = iEnd;
- }
- trimWhiteSpace(&sb);
- if( tailEllipsis ){
- appendWhiteSpace(&sb);
- append(&sb, zEllipsis);
- }
- pCursor->snippet.zSnippet = stringBufferData(&sb);
- pCursor->snippet.nSnippet = stringBufferLength(&sb);
-}
-
-
-/*
-** Close the cursor. For additional information see the documentation
-** on the xClose method of the virtual table interface.
-*/
-static int fulltextClose(sqlite3_vtab_cursor *pCursor){
- fulltext_cursor *c = (fulltext_cursor *) pCursor;
- FTSTRACE(("FTS3 Close %p\n", c));
- sqlite3_finalize(c->pStmt);
- sqlite3Fts3ExprFree(c->pExpr);
- snippetClear(&c->snippet);
- if( c->result.nData!=0 ){
- dlrDestroy(&c->reader);
- }
- dataBufferDestroy(&c->result);
- sqlite3_free(c);
- return SQLITE_OK;
-}
-
-static int fulltextNext(sqlite3_vtab_cursor *pCursor){
- fulltext_cursor *c = (fulltext_cursor *) pCursor;
- int rc;
-
- FTSTRACE(("FTS3 Next %p\n", pCursor));
- snippetClear(&c->snippet);
- if( c->iCursorType < QUERY_FULLTEXT ){
- /* TODO(shess) Handle SQLITE_SCHEMA AND SQLITE_BUSY. */
- rc = sqlite3_step(c->pStmt);
- switch( rc ){
- case SQLITE_ROW:
- c->eof = 0;
- return SQLITE_OK;
- case SQLITE_DONE:
- c->eof = 1;
- return SQLITE_OK;
- default:
- c->eof = 1;
- return rc;
- }
- } else { /* full-text query */
- rc = sqlite3_reset(c->pStmt);
- if( rc!=SQLITE_OK ) return rc;
-
- if( c->result.nData==0 || dlrAtEnd(&c->reader) ){
- c->eof = 1;
- return SQLITE_OK;
- }
- rc = sqlite3_bind_int64(c->pStmt, 1, dlrDocid(&c->reader));
- dlrStep(&c->reader);
- if( rc!=SQLITE_OK ) return rc;
- /* TODO(shess) Handle SQLITE_SCHEMA AND SQLITE_BUSY. */
- rc = sqlite3_step(c->pStmt);
- if( rc==SQLITE_ROW ){ /* the case we expect */
- c->eof = 0;
- return SQLITE_OK;
- }
- /* an error occurred; abort */
- return rc==SQLITE_DONE ? SQLITE_ERROR : rc;
- }
-}
-
-
-/* TODO(shess) If we pushed LeafReader to the top of the file, or to
-** another file, term_select() could be pushed above
-** docListOfTerm().
-*/
-static int termSelect(fulltext_vtab *v, int iColumn,
- const char *pTerm, int nTerm, int isPrefix,
- DocListType iType, DataBuffer *out);
-
-/*
-** Return a DocList corresponding to the phrase *pPhrase.
-**
-** The resulting DL_DOCIDS doclist is stored in pResult, which is
-** overwritten.
-*/
-static int docListOfPhrase(
- fulltext_vtab *pTab, /* The full text index */
- Fts3Phrase *pPhrase, /* Phrase to return a doclist corresponding to */
- DocListType eListType, /* Either DL_DOCIDS or DL_POSITIONS */
- DataBuffer *pResult /* Write the result here */
-){
- int ii;
- int rc = SQLITE_OK;
- int iCol = pPhrase->iColumn;
- DocListType eType = eListType;
- assert( eType==DL_POSITIONS || eType==DL_DOCIDS );
- if( pPhrase->nToken>1 ){
- eType = DL_POSITIONS;
- }
-
- /* This code should never be called with buffered updates. */
- assert( pTab->nPendingData<0 );
-
- for(ii=0; rc==SQLITE_OK && ii<pPhrase->nToken; ii++){
- DataBuffer tmp;
- struct PhraseToken *p = &pPhrase->aToken[ii];
- rc = termSelect(pTab, iCol, p->z, p->n, p->isPrefix, eType, &tmp);
- if( rc==SQLITE_OK ){
- if( ii==0 ){
- *pResult = tmp;
- }else{
- DataBuffer res = *pResult;
- dataBufferInit(pResult, 0);
- if( ii==(pPhrase->nToken-1) ){
- eType = eListType;
- }
- docListPhraseMerge(
- res.pData, res.nData, tmp.pData, tmp.nData, 0, 0, eType, pResult
- );
- dataBufferDestroy(&res);
- dataBufferDestroy(&tmp);
- }
- }
- }
-
- return rc;
-}
-
-/*
-** Evaluate the full-text expression pExpr against fts3 table pTab. Write
-** the results into pRes.
-*/
-static int evalFts3Expr(
- fulltext_vtab *pTab, /* Fts3 Virtual table object */
- Fts3Expr *pExpr, /* Parsed fts3 expression */
- DataBuffer *pRes /* OUT: Write results of the expression here */
-){
- int rc = SQLITE_OK;
-
- /* Initialize the output buffer. If this is an empty query (pExpr==0),
- ** this is all that needs to be done. Empty queries produce empty
- ** result sets.
- */
- dataBufferInit(pRes, 0);
-
- if( pExpr ){
- if( pExpr->eType==FTSQUERY_PHRASE ){
- DocListType eType = DL_DOCIDS;
- if( pExpr->pParent && pExpr->pParent->eType==FTSQUERY_NEAR ){
- eType = DL_POSITIONS;
- }
- rc = docListOfPhrase(pTab, pExpr->pPhrase, eType, pRes);
- }else{
- DataBuffer lhs;
- DataBuffer rhs;
-
- dataBufferInit(&rhs, 0);
- if( SQLITE_OK==(rc = evalFts3Expr(pTab, pExpr->pLeft, &lhs))
- && SQLITE_OK==(rc = evalFts3Expr(pTab, pExpr->pRight, &rhs))
- ){
- switch( pExpr->eType ){
- case FTSQUERY_NEAR: {
- int nToken;
- Fts3Expr *pLeft;
- DocListType eType = DL_DOCIDS;
- if( pExpr->pParent && pExpr->pParent->eType==FTSQUERY_NEAR ){
- eType = DL_POSITIONS;
- }
- pLeft = pExpr->pLeft;
- while( pLeft->eType==FTSQUERY_NEAR ){
- pLeft=pLeft->pRight;
- }
- assert( pExpr->pRight->eType==FTSQUERY_PHRASE );
- assert( pLeft->eType==FTSQUERY_PHRASE );
- nToken = pLeft->pPhrase->nToken + pExpr->pRight->pPhrase->nToken;
- docListPhraseMerge(lhs.pData, lhs.nData, rhs.pData, rhs.nData,
- pExpr->nNear+1, nToken, eType, pRes
- );
- break;
- }
- case FTSQUERY_NOT: {
- docListExceptMerge(lhs.pData, lhs.nData, rhs.pData, rhs.nData,pRes);
- break;
- }
- case FTSQUERY_AND: {
- docListAndMerge(lhs.pData, lhs.nData, rhs.pData, rhs.nData, pRes);
- break;
- }
- case FTSQUERY_OR: {
- docListOrMerge(lhs.pData, lhs.nData, rhs.pData, rhs.nData, pRes);
- break;
- }
- }
- }
- dataBufferDestroy(&lhs);
- dataBufferDestroy(&rhs);
- }
- }
-
- return rc;
-}
-
-/* TODO(shess) Refactor the code to remove this forward decl. */
-static int flushPendingTerms(fulltext_vtab *v);
-
-/* Perform a full-text query using the search expression in
-** zInput[0..nInput-1]. Return a list of matching documents
-** in pResult.
-**
-** Queries must match column iColumn. Or if iColumn>=nColumn
-** they are allowed to match against any column.
-*/
-static int fulltextQuery(
- fulltext_vtab *v, /* The full text index */
- int iColumn, /* Match against this column by default */
- const char *zInput, /* The query string */
- int nInput, /* Number of bytes in zInput[] */
- DataBuffer *pResult, /* Write the result doclist here */
- Fts3Expr **ppExpr /* Put parsed query string here */
-){
- int rc;
-
- /* TODO(shess) Instead of flushing pendingTerms, we could query for
- ** the relevant term and merge the doclist into what we receive from
- ** the database. Wait and see if this is a common issue, first.
- **
- ** A good reason not to flush is to not generate update-related
- ** error codes from here.
- */
-
- /* Flush any buffered updates before executing the query. */
- rc = flushPendingTerms(v);
- if( rc!=SQLITE_OK ){
- return rc;
- }
-
- /* Parse the query passed to the MATCH operator. */
- rc = sqlite3Fts3ExprParse(v->pTokenizer,
- v->azColumn, v->nColumn, iColumn, zInput, nInput, ppExpr
- );
- if( rc!=SQLITE_OK ){
- assert( 0==(*ppExpr) );
- return rc;
- }
-
- return evalFts3Expr(v, *ppExpr, pResult);
-}
-
-/*
-** This is the xFilter interface for the virtual table. See
-** the virtual table xFilter method documentation for additional
-** information.
-**
-** If idxNum==QUERY_GENERIC then do a full table scan against
-** the %_content table.
-**
-** If idxNum==QUERY_DOCID then do a docid lookup for a single entry
-** in the %_content table.
-**
-** If idxNum>=QUERY_FULLTEXT then use the full text index. The
-** column on the left-hand side of the MATCH operator is column
-** number idxNum-QUERY_FULLTEXT, 0 indexed. argv[0] is the right-hand
-** side of the MATCH operator.
-*/
-/* TODO(shess) Upgrade the cursor initialization and destruction to
-** account for fulltextFilter() being called multiple times on the
-** same cursor. The current solution is very fragile. Apply fix to
-** fts3 as appropriate.
-*/
-static int fulltextFilter(
- sqlite3_vtab_cursor *pCursor, /* The cursor used for this query */
- int idxNum, const char *idxStr, /* Which indexing scheme to use */
- int argc, sqlite3_value **argv /* Arguments for the indexing scheme */
-){
- fulltext_cursor *c = (fulltext_cursor *) pCursor;
- fulltext_vtab *v = cursor_vtab(c);
- int rc;
-
- FTSTRACE(("FTS3 Filter %p\n",pCursor));
-
- /* If the cursor has a statement that was not prepared according to
- ** idxNum, clear it. I believe all calls to fulltextFilter with a
- ** given cursor will have the same idxNum , but in this case it's
- ** easy to be safe.
- */
- if( c->pStmt && c->iCursorType!=idxNum ){
- sqlite3_finalize(c->pStmt);
- c->pStmt = NULL;
- }
-
- /* Get a fresh statement appropriate to idxNum. */
- /* TODO(shess): Add a prepared-statement cache in the vt structure.
- ** The cache must handle multiple open cursors. Easier to cache the
- ** statement variants at the vt to reduce malloc/realloc/free here.
- ** Or we could have a StringBuffer variant which allowed stack
- ** construction for small values.
- */
- if( !c->pStmt ){
- StringBuffer sb;
- initStringBuffer(&sb);
- append(&sb, "SELECT docid, ");
- appendList(&sb, v->nColumn, v->azContentColumn);
- append(&sb, " FROM %_content");
- if( idxNum!=QUERY_GENERIC ) append(&sb, " WHERE docid = ?");
- rc = sql_prepare(v->db, v->zDb, v->zName, &c->pStmt,
- stringBufferData(&sb));
- stringBufferDestroy(&sb);
- if( rc!=SQLITE_OK ) return rc;
- c->iCursorType = idxNum;
- }else{
- sqlite3_reset(c->pStmt);
- assert( c->iCursorType==idxNum );
- }
-
- switch( idxNum ){
- case QUERY_GENERIC:
- break;
-
- case QUERY_DOCID:
- rc = sqlite3_bind_int64(c->pStmt, 1, sqlite3_value_int64(argv[0]));
- if( rc!=SQLITE_OK ) return rc;
- break;
-
- default: /* full-text search */
- {
- int iCol = idxNum-QUERY_FULLTEXT;
- const char *zQuery = (const char *)sqlite3_value_text(argv[0]);
- assert( idxNum<=QUERY_FULLTEXT+v->nColumn);
- assert( argc==1 );
- if( c->result.nData!=0 ){
- /* This case happens if the same cursor is used repeatedly. */
- dlrDestroy(&c->reader);
- dataBufferReset(&c->result);
- }else{
- dataBufferInit(&c->result, 0);
- }
- rc = fulltextQuery(v, iCol, zQuery, -1, &c->result, &c->pExpr);
- if( rc!=SQLITE_OK ) return rc;
- if( c->result.nData!=0 ){
- dlrInit(&c->reader, DL_DOCIDS, c->result.pData, c->result.nData);
- }
- break;
- }
- }
-
- return fulltextNext(pCursor);
-}
-
-/* This is the xEof method of the virtual table. The SQLite core
-** calls this routine to find out if it has reached the end of
-** a query's results set.
-*/
-static int fulltextEof(sqlite3_vtab_cursor *pCursor){
- fulltext_cursor *c = (fulltext_cursor *) pCursor;
- return c->eof;
-}
-
-/* This is the xColumn method of the virtual table. The SQLite
-** core calls this method during a query when it needs the value
-** of a column from the virtual table. This method needs to use
-** one of the sqlite3_result_*() routines to store the requested
-** value back in the pContext.
-*/
-static int fulltextColumn(sqlite3_vtab_cursor *pCursor,
- sqlite3_context *pContext, int idxCol){
- fulltext_cursor *c = (fulltext_cursor *) pCursor;
- fulltext_vtab *v = cursor_vtab(c);
-
- if( idxCol<v->nColumn ){
- sqlite3_value *pVal = sqlite3_column_value(c->pStmt, idxCol+1);
- sqlite3_result_value(pContext, pVal);
- }else if( idxCol==v->nColumn ){
- /* The extra column whose name is the same as the table.
- ** Return a blob which is a pointer to the cursor
- */
- sqlite3_result_blob(pContext, &c, sizeof(c), SQLITE_TRANSIENT);
- }else if( idxCol==v->nColumn+1 ){
- /* The docid column, which is an alias for rowid. */
- sqlite3_value *pVal = sqlite3_column_value(c->pStmt, 0);
- sqlite3_result_value(pContext, pVal);
- }
- return SQLITE_OK;
-}
-
-/* This is the xRowid method. The SQLite core calls this routine to
-** retrieve the rowid for the current row of the result set. fts3
-** exposes %_content.docid as the rowid for the virtual table. The
-** rowid should be written to *pRowid.
-*/
-static int fulltextRowid(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){
- fulltext_cursor *c = (fulltext_cursor *) pCursor;
-
- *pRowid = sqlite3_column_int64(c->pStmt, 0);
- return SQLITE_OK;
-}
-
-/* Add all terms in [zText] to pendingTerms table. If [iColumn] > 0,
-** we also store positions and offsets in the hash table using that
-** column number.
-*/
-static int buildTerms(fulltext_vtab *v, sqlite_int64 iDocid,
- const char *zText, int iColumn){
- sqlite3_tokenizer *pTokenizer = v->pTokenizer;
- sqlite3_tokenizer_cursor *pCursor;
- const char *pToken;
- int nTokenBytes;
- int iStartOffset, iEndOffset, iPosition;
- int rc;
-
- rc = pTokenizer->pModule->xOpen(pTokenizer, zText, -1, &pCursor);
- if( rc!=SQLITE_OK ) return rc;
-
- pCursor->pTokenizer = pTokenizer;
- while( SQLITE_OK==(rc=pTokenizer->pModule->xNext(pCursor,
- &pToken, &nTokenBytes,
- &iStartOffset, &iEndOffset,
- &iPosition)) ){
- DLCollector *p;
- int nData; /* Size of doclist before our update. */
-
- /* Positions can't be negative; we use -1 as a terminator
- * internally. Token can't be NULL or empty. */
- if( iPosition<0 || pToken == NULL || nTokenBytes == 0 ){
- rc = SQLITE_ERROR;
- break;
- }
-
- p = fts3HashFind(&v->pendingTerms, pToken, nTokenBytes);
- if( p==NULL ){
- nData = 0;
- p = dlcNew(iDocid, DL_DEFAULT);
- fts3HashInsert(&v->pendingTerms, pToken, nTokenBytes, p);
-
- /* Overhead for our hash table entry, the key, and the value. */
- v->nPendingData += sizeof(struct fts3HashElem)+sizeof(*p)+nTokenBytes;
- }else{
- nData = p->b.nData;
- if( p->dlw.iPrevDocid!=iDocid ) dlcNext(p, iDocid);
- }
- if( iColumn>=0 ){
- dlcAddPos(p, iColumn, iPosition, iStartOffset, iEndOffset);
- }
-
- /* Accumulate data added by dlcNew or dlcNext, and dlcAddPos. */
- v->nPendingData += p->b.nData-nData;
- }
-
- /* TODO(shess) Check return? Should this be able to cause errors at
- ** this point? Actually, same question about sqlite3_finalize(),
- ** though one could argue that failure there means that the data is
- ** not durable. *ponder*
- */
- pTokenizer->pModule->xClose(pCursor);
- if( SQLITE_DONE == rc ) return SQLITE_OK;
- return rc;
-}
-
-/* Add doclists for all terms in [pValues] to pendingTerms table. */
-static int insertTerms(fulltext_vtab *v, sqlite_int64 iDocid,
- sqlite3_value **pValues){
- int i;
- for(i = 0; i < v->nColumn ; ++i){
- char *zText = (char*)sqlite3_value_text(pValues[i]);
- int rc = buildTerms(v, iDocid, zText, i);
- if( rc!=SQLITE_OK ) return rc;
- }
- return SQLITE_OK;
-}
-
-/* Add empty doclists for all terms in the given row's content to
-** pendingTerms.
-*/
-static int deleteTerms(fulltext_vtab *v, sqlite_int64 iDocid){
- const char **pValues;
- int i, rc;
-
- /* TODO(shess) Should we allow such tables at all? */
- if( DL_DEFAULT==DL_DOCIDS ) return SQLITE_ERROR;
-
- rc = content_select(v, iDocid, &pValues);
- if( rc!=SQLITE_OK ) return rc;
-
- for(i = 0 ; i < v->nColumn; ++i) {
- rc = buildTerms(v, iDocid, pValues[i], -1);
- if( rc!=SQLITE_OK ) break;
- }
-
- freeStringArray(v->nColumn, pValues);
- return SQLITE_OK;
-}
-
-/* TODO(shess) Refactor the code to remove this forward decl. */
-static int initPendingTerms(fulltext_vtab *v, sqlite_int64 iDocid);
-
-/* Insert a row into the %_content table; set *piDocid to be the ID of the
-** new row. Add doclists for terms to pendingTerms.
-*/
-static int index_insert(fulltext_vtab *v, sqlite3_value *pRequestDocid,
- sqlite3_value **pValues, sqlite_int64 *piDocid){
- int rc;
-
- rc = content_insert(v, pRequestDocid, pValues); /* execute an SQL INSERT */
- if( rc!=SQLITE_OK ) return rc;
-
- /* docid column is an alias for rowid. */
- *piDocid = sqlite3_last_insert_rowid(v->db);
- rc = initPendingTerms(v, *piDocid);
- if( rc!=SQLITE_OK ) return rc;
-
- return insertTerms(v, *piDocid, pValues);
-}
-
-/* Delete a row from the %_content table; add empty doclists for terms
-** to pendingTerms.
-*/
-static int index_delete(fulltext_vtab *v, sqlite_int64 iRow){
- int rc = initPendingTerms(v, iRow);
- if( rc!=SQLITE_OK ) return rc;
-
- rc = deleteTerms(v, iRow);
- if( rc!=SQLITE_OK ) return rc;
-
- return content_delete(v, iRow); /* execute an SQL DELETE */
-}
-
-/* Update a row in the %_content table; add delete doclists to
-** pendingTerms for old terms not in the new data, add insert doclists
-** to pendingTerms for terms in the new data.
-*/
-static int index_update(fulltext_vtab *v, sqlite_int64 iRow,
- sqlite3_value **pValues){
- int rc = initPendingTerms(v, iRow);
- if( rc!=SQLITE_OK ) return rc;
-
- /* Generate an empty doclist for each term that previously appeared in this
- * row. */
- rc = deleteTerms(v, iRow);
- if( rc!=SQLITE_OK ) return rc;
-
- rc = content_update(v, pValues, iRow); /* execute an SQL UPDATE */
- if( rc!=SQLITE_OK ) return rc;
-
- /* Now add positions for terms which appear in the updated row. */
- return insertTerms(v, iRow, pValues);
-}
-
-/*******************************************************************/
-/* InteriorWriter is used to collect terms and block references into
-** interior nodes in %_segments. See commentary at top of file for
-** format.
-*/
-
-/* How large interior nodes can grow. */
-#define INTERIOR_MAX 2048
-
-/* Minimum number of terms per interior node (except the root). This
-** prevents large terms from making the tree too skinny - must be >0
-** so that the tree always makes progress. Note that the min tree
-** fanout will be INTERIOR_MIN_TERMS+1.
-*/
-#define INTERIOR_MIN_TERMS 7
-#if INTERIOR_MIN_TERMS<1
-# error INTERIOR_MIN_TERMS must be greater than 0.
-#endif
-
-/* ROOT_MAX controls how much data is stored inline in the segment
-** directory.
-*/
-/* TODO(shess) Push ROOT_MAX down to whoever is writing things. It's
-** only here so that interiorWriterRootInfo() and leafWriterRootInfo()
-** can both see it, but if the caller passed it in, we wouldn't even
-** need a define.
-*/
-#define ROOT_MAX 1024
-#if ROOT_MAX<VARINT_MAX*2
-# error ROOT_MAX must have enough space for a header.
-#endif
-
-/* InteriorBlock stores a linked-list of interior blocks while a lower
-** layer is being constructed.
-*/
-typedef struct InteriorBlock {
- DataBuffer term; /* Leftmost term in block's subtree. */
- DataBuffer data; /* Accumulated data for the block. */
- struct InteriorBlock *next;
-} InteriorBlock;
-
-static InteriorBlock *interiorBlockNew(int iHeight, sqlite_int64 iChildBlock,
- const char *pTerm, int nTerm){
- InteriorBlock *block = sqlite3_malloc(sizeof(InteriorBlock));
- char c[VARINT_MAX+VARINT_MAX];
- int n;
-
- if( block ){
- memset(block, 0, sizeof(*block));
- dataBufferInit(&block->term, 0);
- dataBufferReplace(&block->term, pTerm, nTerm);
-
- n = fts3PutVarint(c, iHeight);
- n += fts3PutVarint(c+n, iChildBlock);
- dataBufferInit(&block->data, INTERIOR_MAX);
- dataBufferReplace(&block->data, c, n);
- }
- return block;
-}
-
-#ifndef NDEBUG
-/* Verify that the data is readable as an interior node. */
-static void interiorBlockValidate(InteriorBlock *pBlock){
- const char *pData = pBlock->data.pData;
- int nData = pBlock->data.nData;
- int n, iDummy;
- sqlite_int64 iBlockid;
-
- assert( nData>0 );
- assert( pData!=0 );
- assert( pData+nData>pData );
-
- /* Must lead with height of node as a varint(n), n>0 */
- n = fts3GetVarint32(pData, &iDummy);
- assert( n>0 );
- assert( iDummy>0 );
- assert( n<nData );
- pData += n;
- nData -= n;
-
- /* Must contain iBlockid. */
- n = fts3GetVarint(pData, &iBlockid);
- assert( n>0 );
- assert( n<=nData );
- pData += n;
- nData -= n;
-
- /* Zero or more terms of positive length */
- if( nData!=0 ){
- /* First term is not delta-encoded. */
- n = fts3GetVarint32(pData, &iDummy);
- assert( n>0 );
- assert( iDummy>0 );
- assert( n+iDummy>0);
- assert( n+iDummy<=nData );
- pData += n+iDummy;
- nData -= n+iDummy;
-
- /* Following terms delta-encoded. */
- while( nData!=0 ){
- /* Length of shared prefix. */
- n = fts3GetVarint32(pData, &iDummy);
- assert( n>0 );
- assert( iDummy>=0 );
- assert( n<nData );
- pData += n;
- nData -= n;
-
- /* Length and data of distinct suffix. */
- n = fts3GetVarint32(pData, &iDummy);
- assert( n>0 );
- assert( iDummy>0 );
- assert( n+iDummy>0);
- assert( n+iDummy<=nData );
- pData += n+iDummy;
- nData -= n+iDummy;
- }
- }
-}
-#define ASSERT_VALID_INTERIOR_BLOCK(x) interiorBlockValidate(x)
-#else
-#define ASSERT_VALID_INTERIOR_BLOCK(x) assert( 1 )
-#endif
-
-typedef struct InteriorWriter {
- int iHeight; /* from 0 at leaves. */
- InteriorBlock *first, *last;
- struct InteriorWriter *parentWriter;
-
- DataBuffer term; /* Last term written to block "last". */
- sqlite_int64 iOpeningChildBlock; /* First child block in block "last". */
-#ifndef NDEBUG
- sqlite_int64 iLastChildBlock; /* for consistency checks. */
-#endif
-} InteriorWriter;
-
-/* Initialize an interior node where pTerm[nTerm] marks the leftmost
-** term in the tree. iChildBlock is the leftmost child block at the
-** next level down the tree.
-*/
-static void interiorWriterInit(int iHeight, const char *pTerm, int nTerm,
- sqlite_int64 iChildBlock,
- InteriorWriter *pWriter){
- InteriorBlock *block;
- assert( iHeight>0 );
- CLEAR(pWriter);
-
- pWriter->iHeight = iHeight;
- pWriter->iOpeningChildBlock = iChildBlock;
-#ifndef NDEBUG
- pWriter->iLastChildBlock = iChildBlock;
-#endif
- block = interiorBlockNew(iHeight, iChildBlock, pTerm, nTerm);
- pWriter->last = pWriter->first = block;
- ASSERT_VALID_INTERIOR_BLOCK(pWriter->last);
- dataBufferInit(&pWriter->term, 0);
-}
-
-/* Append the child node rooted at iChildBlock to the interior node,
-** with pTerm[nTerm] as the leftmost term in iChildBlock's subtree.
-*/
-static void interiorWriterAppend(InteriorWriter *pWriter,
- const char *pTerm, int nTerm,
- sqlite_int64 iChildBlock){
- char c[VARINT_MAX+VARINT_MAX];
- int n, nPrefix = 0;
-
- ASSERT_VALID_INTERIOR_BLOCK(pWriter->last);
-
- /* The first term written into an interior node is actually
- ** associated with the second child added (the first child was added
- ** in interiorWriterInit, or in the if clause at the bottom of this
- ** function). That term gets encoded straight up, with nPrefix left
- ** at 0.
- */
- if( pWriter->term.nData==0 ){
- n = fts3PutVarint(c, nTerm);
- }else{
- while( nPrefix<pWriter->term.nData &&
- pTerm[nPrefix]==pWriter->term.pData[nPrefix] ){
- nPrefix++;
- }
-
- n = fts3PutVarint(c, nPrefix);
- n += fts3PutVarint(c+n, nTerm-nPrefix);
- }
-
-#ifndef NDEBUG
- pWriter->iLastChildBlock++;
-#endif
- assert( pWriter->iLastChildBlock==iChildBlock );
-
- /* Overflow to a new block if the new term makes the current block
- ** too big, and the current block already has enough terms.
- */
- if( pWriter->last->data.nData+n+nTerm-nPrefix>INTERIOR_MAX &&
- iChildBlock-pWriter->iOpeningChildBlock>INTERIOR_MIN_TERMS ){
- pWriter->last->next = interiorBlockNew(pWriter->iHeight, iChildBlock,
- pTerm, nTerm);
- pWriter->last = pWriter->last->next;
- pWriter->iOpeningChildBlock = iChildBlock;
- dataBufferReset(&pWriter->term);
- }else{
- dataBufferAppend2(&pWriter->last->data, c, n,
- pTerm+nPrefix, nTerm-nPrefix);
- dataBufferReplace(&pWriter->term, pTerm, nTerm);
- }
- ASSERT_VALID_INTERIOR_BLOCK(pWriter->last);
-}
-
-/* Free the space used by pWriter, including the linked-list of
-** InteriorBlocks, and parentWriter, if present.
-*/
-static int interiorWriterDestroy(InteriorWriter *pWriter){
- InteriorBlock *block = pWriter->first;
-
- while( block!=NULL ){
- InteriorBlock *b = block;
- block = block->next;
- dataBufferDestroy(&b->term);
- dataBufferDestroy(&b->data);
- sqlite3_free(b);
- }
- if( pWriter->parentWriter!=NULL ){
- interiorWriterDestroy(pWriter->parentWriter);
- sqlite3_free(pWriter->parentWriter);
- }
- dataBufferDestroy(&pWriter->term);
- SCRAMBLE(pWriter);
- return SQLITE_OK;
-}
-
-/* If pWriter can fit entirely in ROOT_MAX, return it as the root info
-** directly, leaving *piEndBlockid unchanged. Otherwise, flush
-** pWriter to %_segments, building a new layer of interior nodes, and
-** recursively ask for their root into.
-*/
-static int interiorWriterRootInfo(fulltext_vtab *v, InteriorWriter *pWriter,
- char **ppRootInfo, int *pnRootInfo,
- sqlite_int64 *piEndBlockid){
- InteriorBlock *block = pWriter->first;
- sqlite_int64 iBlockid = 0;
- int rc;
-
- /* If we can fit the segment inline */
- if( block==pWriter->last && block->data.nData<ROOT_MAX ){
- *ppRootInfo = block->data.pData;
- *pnRootInfo = block->data.nData;
- return SQLITE_OK;
- }
-
- /* Flush the first block to %_segments, and create a new level of
- ** interior node.
- */
- ASSERT_VALID_INTERIOR_BLOCK(block);
- rc = block_insert(v, block->data.pData, block->data.nData, &iBlockid);
- if( rc!=SQLITE_OK ) return rc;
- *piEndBlockid = iBlockid;
-
- pWriter->parentWriter = sqlite3_malloc(sizeof(*pWriter->parentWriter));
- interiorWriterInit(pWriter->iHeight+1,
- block->term.pData, block->term.nData,
- iBlockid, pWriter->parentWriter);
-
- /* Flush additional blocks and append to the higher interior
- ** node.
- */
- for(block=block->next; block!=NULL; block=block->next){
- ASSERT_VALID_INTERIOR_BLOCK(block);
- rc = block_insert(v, block->data.pData, block->data.nData, &iBlockid);
- if( rc!=SQLITE_OK ) return rc;
- *piEndBlockid = iBlockid;
-
- interiorWriterAppend(pWriter->parentWriter,
- block->term.pData, block->term.nData, iBlockid);
- }
-
- /* Parent node gets the chance to be the root. */
- return interiorWriterRootInfo(v, pWriter->parentWriter,
- ppRootInfo, pnRootInfo, piEndBlockid);
-}
-
-/****************************************************************/
-/* InteriorReader is used to read off the data from an interior node
-** (see comment at top of file for the format).
-*/
-typedef struct InteriorReader {
- const char *pData;
- int nData;
-
- DataBuffer term; /* previous term, for decoding term delta. */
-
- sqlite_int64 iBlockid;
-} InteriorReader;
-
-static void interiorReaderDestroy(InteriorReader *pReader){
- dataBufferDestroy(&pReader->term);
- SCRAMBLE(pReader);
-}
-
-/* TODO(shess) The assertions are great, but what if we're in NDEBUG
-** and the blob is empty or otherwise contains suspect data?
-*/
-static void interiorReaderInit(const char *pData, int nData,
- InteriorReader *pReader){
- int n, nTerm;
-
- /* Require at least the leading flag byte */
- assert( nData>0 );
- assert( pData[0]!='\0' );
-
- CLEAR(pReader);
-
- /* Decode the base blockid, and set the cursor to the first term. */
- n = fts3GetVarint(pData+1, &pReader->iBlockid);
- assert( 1+n<=nData );
- pReader->pData = pData+1+n;
- pReader->nData = nData-(1+n);
-
- /* A single-child interior node (such as when a leaf node was too
- ** large for the segment directory) won't have any terms.
- ** Otherwise, decode the first term.
- */
- if( pReader->nData==0 ){
- dataBufferInit(&pReader->term, 0);
- }else{
- n = fts3GetVarint32(pReader->pData, &nTerm);
- dataBufferInit(&pReader->term, nTerm);
- dataBufferReplace(&pReader->term, pReader->pData+n, nTerm);
- assert( n+nTerm<=pReader->nData );
- pReader->pData += n+nTerm;
- pReader->nData -= n+nTerm;
- }
-}
-
-static int interiorReaderAtEnd(InteriorReader *pReader){
- return pReader->term.nData==0;
-}
-
-static sqlite_int64 interiorReaderCurrentBlockid(InteriorReader *pReader){
- return pReader->iBlockid;
-}
-
-static int interiorReaderTermBytes(InteriorReader *pReader){
- assert( !interiorReaderAtEnd(pReader) );
- return pReader->term.nData;
-}
-static const char *interiorReaderTerm(InteriorReader *pReader){
- assert( !interiorReaderAtEnd(pReader) );
- return pReader->term.pData;
-}
-
-/* Step forward to the next term in the node. */
-static void interiorReaderStep(InteriorReader *pReader){
- assert( !interiorReaderAtEnd(pReader) );
-
- /* If the last term has been read, signal eof, else construct the
- ** next term.
- */
- if( pReader->nData==0 ){
- dataBufferReset(&pReader->term);
- }else{
- int n, nPrefix, nSuffix;
-
- n = fts3GetVarint32(pReader->pData, &nPrefix);
- n += fts3GetVarint32(pReader->pData+n, &nSuffix);
-
- /* Truncate the current term and append suffix data. */
- pReader->term.nData = nPrefix;
- dataBufferAppend(&pReader->term, pReader->pData+n, nSuffix);
-
- assert( n+nSuffix<=pReader->nData );
- pReader->pData += n+nSuffix;
- pReader->nData -= n+nSuffix;
- }
- pReader->iBlockid++;
-}
-
-/* Compare the current term to pTerm[nTerm], returning strcmp-style
-** results. If isPrefix, equality means equal through nTerm bytes.
-*/
-static int interiorReaderTermCmp(InteriorReader *pReader,
- const char *pTerm, int nTerm, int isPrefix){
- const char *pReaderTerm = interiorReaderTerm(pReader);
- int nReaderTerm = interiorReaderTermBytes(pReader);
- int c, n = nReaderTerm<nTerm ? nReaderTerm : nTerm;
-
- if( n==0 ){
- if( nReaderTerm>0 ) return -1;
- if( nTerm>0 ) return 1;
- return 0;
- }
-
- c = memcmp(pReaderTerm, pTerm, n);
- if( c!=0 ) return c;
- if( isPrefix && n==nTerm ) return 0;
- return nReaderTerm - nTerm;
-}
-
-/****************************************************************/
-/* LeafWriter is used to collect terms and associated doclist data
-** into leaf blocks in %_segments (see top of file for format info).
-** Expected usage is:
-**
-** LeafWriter writer;
-** leafWriterInit(0, 0, &writer);
-** while( sorted_terms_left_to_process ){
-** // data is doclist data for that term.
-** rc = leafWriterStep(v, &writer, pTerm, nTerm, pData, nData);
-** if( rc!=SQLITE_OK ) goto err;
-** }
-** rc = leafWriterFinalize(v, &writer);
-**err:
-** leafWriterDestroy(&writer);
-** return rc;
-**
-** leafWriterStep() may write a collected leaf out to %_segments.
-** leafWriterFinalize() finishes writing any buffered data and stores
-** a root node in %_segdir. leafWriterDestroy() frees all buffers and
-** InteriorWriters allocated as part of writing this segment.
-**
-** TODO(shess) Document leafWriterStepMerge().
-*/
-
-/* Put terms with data this big in their own block. */
-#define STANDALONE_MIN 1024
-
-/* Keep leaf blocks below this size. */
-#define LEAF_MAX 2048
-
-typedef struct LeafWriter {
- int iLevel;
- int idx;
- sqlite_int64 iStartBlockid; /* needed to create the root info */
- sqlite_int64 iEndBlockid; /* when we're done writing. */
-
- DataBuffer term; /* previous encoded term */
- DataBuffer data; /* encoding buffer */
-
- /* bytes of first term in the current node which distinguishes that
- ** term from the last term of the previous node.
- */
- int nTermDistinct;
-
- InteriorWriter parentWriter; /* if we overflow */
- int has_parent;
-} LeafWriter;
-
-static void leafWriterInit(int iLevel, int idx, LeafWriter *pWriter){
- CLEAR(pWriter);
- pWriter->iLevel = iLevel;
- pWriter->idx = idx;
-
- dataBufferInit(&pWriter->term, 32);
-
- /* Start out with a reasonably sized block, though it can grow. */
- dataBufferInit(&pWriter->data, LEAF_MAX);
-}
-
-#ifndef NDEBUG
-/* Verify that the data is readable as a leaf node. */
-static void leafNodeValidate(const char *pData, int nData){
- int n, iDummy;
-
- if( nData==0 ) return;
- assert( nData>0 );
- assert( pData!=0 );
- assert( pData+nData>pData );
-
- /* Must lead with a varint(0) */
- n = fts3GetVarint32(pData, &iDummy);
- assert( iDummy==0 );
- assert( n>0 );
- assert( n<nData );
- pData += n;
- nData -= n;
-
- /* Leading term length and data must fit in buffer. */
- n = fts3GetVarint32(pData, &iDummy);
- assert( n>0 );
- assert( iDummy>0 );
- assert( n+iDummy>0 );
- assert( n+iDummy<nData );
- pData += n+iDummy;
- nData -= n+iDummy;
-
- /* Leading term's doclist length and data must fit. */
- n = fts3GetVarint32(pData, &iDummy);
- assert( n>0 );
- assert( iDummy>0 );
- assert( n+iDummy>0 );
- assert( n+iDummy<=nData );
- ASSERT_VALID_DOCLIST(DL_DEFAULT, pData+n, iDummy, NULL);
- pData += n+iDummy;
- nData -= n+iDummy;
-
- /* Verify that trailing terms and doclists also are readable. */
- while( nData!=0 ){
- n = fts3GetVarint32(pData, &iDummy);
- assert( n>0 );
- assert( iDummy>=0 );
- assert( n<nData );
- pData += n;
- nData -= n;
- n = fts3GetVarint32(pData, &iDummy);
- assert( n>0 );
- assert( iDummy>0 );
- assert( n+iDummy>0 );
- assert( n+iDummy<nData );
- pData += n+iDummy;
- nData -= n+iDummy;
-
- n = fts3GetVarint32(pData, &iDummy);
- assert( n>0 );
- assert( iDummy>0 );
- assert( n+iDummy>0 );
- assert( n+iDummy<=nData );
- ASSERT_VALID_DOCLIST(DL_DEFAULT, pData+n, iDummy, NULL);
- pData += n+iDummy;
- nData -= n+iDummy;
- }
-}
-#define ASSERT_VALID_LEAF_NODE(p, n) leafNodeValidate(p, n)
-#else
-#define ASSERT_VALID_LEAF_NODE(p, n) assert( 1 )
-#endif
-
-/* Flush the current leaf node to %_segments, and adding the resulting
-** blockid and the starting term to the interior node which will
-** contain it.
-*/
-static int leafWriterInternalFlush(fulltext_vtab *v, LeafWriter *pWriter,
- int iData, int nData){
- sqlite_int64 iBlockid = 0;
- const char *pStartingTerm;
- int nStartingTerm, rc, n;
-
- /* Must have the leading varint(0) flag, plus at least some
- ** valid-looking data.
- */
- assert( nData>2 );
- assert( iData>=0 );
- assert( iData+nData<=pWriter->data.nData );
- ASSERT_VALID_LEAF_NODE(pWriter->data.pData+iData, nData);
-
- rc = block_insert(v, pWriter->data.pData+iData, nData, &iBlockid);
- if( rc!=SQLITE_OK ) return rc;
- assert( iBlockid!=0 );
-
- /* Reconstruct the first term in the leaf for purposes of building
- ** the interior node.
- */
- n = fts3GetVarint32(pWriter->data.pData+iData+1, &nStartingTerm);
- pStartingTerm = pWriter->data.pData+iData+1+n;
- assert( pWriter->data.nData>iData+1+n+nStartingTerm );
- assert( pWriter->nTermDistinct>0 );
- assert( pWriter->nTermDistinct<=nStartingTerm );
- nStartingTerm = pWriter->nTermDistinct;
-
- if( pWriter->has_parent ){
- interiorWriterAppend(&pWriter->parentWriter,
- pStartingTerm, nStartingTerm, iBlockid);
- }else{
- interiorWriterInit(1, pStartingTerm, nStartingTerm, iBlockid,
- &pWriter->parentWriter);
- pWriter->has_parent = 1;
- }
-
- /* Track the span of this segment's leaf nodes. */
- if( pWriter->iEndBlockid==0 ){
- pWriter->iEndBlockid = pWriter->iStartBlockid = iBlockid;
- }else{
- pWriter->iEndBlockid++;
- assert( iBlockid==pWriter->iEndBlockid );
- }
-
- return SQLITE_OK;
-}
-static int leafWriterFlush(fulltext_vtab *v, LeafWriter *pWriter){
- int rc = leafWriterInternalFlush(v, pWriter, 0, pWriter->data.nData);
- if( rc!=SQLITE_OK ) return rc;
-
- /* Re-initialize the output buffer. */
- dataBufferReset(&pWriter->data);
-
- return SQLITE_OK;
-}
-
-/* Fetch the root info for the segment. If the entire leaf fits
-** within ROOT_MAX, then it will be returned directly, otherwise it
-** will be flushed and the root info will be returned from the
-** interior node. *piEndBlockid is set to the blockid of the last
-** interior or leaf node written to disk (0 if none are written at
-** all).
-*/
-static int leafWriterRootInfo(fulltext_vtab *v, LeafWriter *pWriter,
- char **ppRootInfo, int *pnRootInfo,
- sqlite_int64 *piEndBlockid){
- /* we can fit the segment entirely inline */
- if( !pWriter->has_parent && pWriter->data.nData<ROOT_MAX ){
- *ppRootInfo = pWriter->data.pData;
- *pnRootInfo = pWriter->data.nData;
- *piEndBlockid = 0;
- return SQLITE_OK;
- }
-
- /* Flush remaining leaf data. */
- if( pWriter->data.nData>0 ){
- int rc = leafWriterFlush(v, pWriter);
- if( rc!=SQLITE_OK ) return rc;
- }
-
- /* We must have flushed a leaf at some point. */
- assert( pWriter->has_parent );
-
- /* Tenatively set the end leaf blockid as the end blockid. If the
- ** interior node can be returned inline, this will be the final
- ** blockid, otherwise it will be overwritten by
- ** interiorWriterRootInfo().
- */
- *piEndBlockid = pWriter->iEndBlockid;
-
- return interiorWriterRootInfo(v, &pWriter->parentWriter,
- ppRootInfo, pnRootInfo, piEndBlockid);
-}
-
-/* Collect the rootInfo data and store it into the segment directory.
-** This has the effect of flushing the segment's leaf data to
-** %_segments, and also flushing any interior nodes to %_segments.
-*/
-static int leafWriterFinalize(fulltext_vtab *v, LeafWriter *pWriter){
- sqlite_int64 iEndBlockid;
- char *pRootInfo;
- int rc, nRootInfo;
-
- rc = leafWriterRootInfo(v, pWriter, &pRootInfo, &nRootInfo, &iEndBlockid);
- if( rc!=SQLITE_OK ) return rc;
-
- /* Don't bother storing an entirely empty segment. */
- if( iEndBlockid==0 && nRootInfo==0 ) return SQLITE_OK;
-
- return segdir_set(v, pWriter->iLevel, pWriter->idx,
- pWriter->iStartBlockid, pWriter->iEndBlockid,
- iEndBlockid, pRootInfo, nRootInfo);
-}
-
-static void leafWriterDestroy(LeafWriter *pWriter){
- if( pWriter->has_parent ) interiorWriterDestroy(&pWriter->parentWriter);
- dataBufferDestroy(&pWriter->term);
- dataBufferDestroy(&pWriter->data);
-}
-
-/* Encode a term into the leafWriter, delta-encoding as appropriate.
-** Returns the length of the new term which distinguishes it from the
-** previous term, which can be used to set nTermDistinct when a node
-** boundary is crossed.
-*/
-static int leafWriterEncodeTerm(LeafWriter *pWriter,
- const char *pTerm, int nTerm){
- char c[VARINT_MAX+VARINT_MAX];
- int n, nPrefix = 0;
-
- assert( nTerm>0 );
- while( nPrefix<pWriter->term.nData &&
- pTerm[nPrefix]==pWriter->term.pData[nPrefix] ){
- nPrefix++;
- /* Failing this implies that the terms weren't in order. */
- assert( nPrefix<nTerm );
- }
-
- if( pWriter->data.nData==0 ){
- /* Encode the node header and leading term as:
- ** varint(0)
- ** varint(nTerm)
- ** char pTerm[nTerm]
- */
- n = fts3PutVarint(c, '\0');
- n += fts3PutVarint(c+n, nTerm);
- dataBufferAppend2(&pWriter->data, c, n, pTerm, nTerm);
- }else{
- /* Delta-encode the term as:
- ** varint(nPrefix)
- ** varint(nSuffix)
- ** char pTermSuffix[nSuffix]
- */
- n = fts3PutVarint(c, nPrefix);
- n += fts3PutVarint(c+n, nTerm-nPrefix);
- dataBufferAppend2(&pWriter->data, c, n, pTerm+nPrefix, nTerm-nPrefix);
- }
- dataBufferReplace(&pWriter->term, pTerm, nTerm);
-
- return nPrefix+1;
-}
-
-/* Used to avoid a memmove when a large amount of doclist data is in
-** the buffer. This constructs a node and term header before
-** iDoclistData and flushes the resulting complete node using
-** leafWriterInternalFlush().
-*/
-static int leafWriterInlineFlush(fulltext_vtab *v, LeafWriter *pWriter,
- const char *pTerm, int nTerm,
- int iDoclistData){
- char c[VARINT_MAX+VARINT_MAX];
- int iData, n = fts3PutVarint(c, 0);
- n += fts3PutVarint(c+n, nTerm);
-
- /* There should always be room for the header. Even if pTerm shared
- ** a substantial prefix with the previous term, the entire prefix
- ** could be constructed from earlier data in the doclist, so there
- ** should be room.
- */
- assert( iDoclistData>=n+nTerm );
-
- iData = iDoclistData-(n+nTerm);
- memcpy(pWriter->data.pData+iData, c, n);
- memcpy(pWriter->data.pData+iData+n, pTerm, nTerm);
-
- return leafWriterInternalFlush(v, pWriter, iData, pWriter->data.nData-iData);
-}
-
-/* Push pTerm[nTerm] along with the doclist data to the leaf layer of
-** %_segments.
-*/
-static int leafWriterStepMerge(fulltext_vtab *v, LeafWriter *pWriter,
- const char *pTerm, int nTerm,
- DLReader *pReaders, int nReaders){
- char c[VARINT_MAX+VARINT_MAX];
- int iTermData = pWriter->data.nData, iDoclistData;
- int i, nData, n, nActualData, nActual, rc, nTermDistinct;
-
- ASSERT_VALID_LEAF_NODE(pWriter->data.pData, pWriter->data.nData);
- nTermDistinct = leafWriterEncodeTerm(pWriter, pTerm, nTerm);
-
- /* Remember nTermDistinct if opening a new node. */
- if( iTermData==0 ) pWriter->nTermDistinct = nTermDistinct;
-
- iDoclistData = pWriter->data.nData;
-
- /* Estimate the length of the merged doclist so we can leave space
- ** to encode it.
- */
- for(i=0, nData=0; i<nReaders; i++){
- nData += dlrAllDataBytes(&pReaders[i]);
- }
- n = fts3PutVarint(c, nData);
- dataBufferAppend(&pWriter->data, c, n);
-
- docListMerge(&pWriter->data, pReaders, nReaders);
- ASSERT_VALID_DOCLIST(DL_DEFAULT,
- pWriter->data.pData+iDoclistData+n,
- pWriter->data.nData-iDoclistData-n, NULL);
-
- /* The actual amount of doclist data at this point could be smaller
- ** than the length we encoded. Additionally, the space required to
- ** encode this length could be smaller. For small doclists, this is
- ** not a big deal, we can just use memmove() to adjust things.
- */
- nActualData = pWriter->data.nData-(iDoclistData+n);
- nActual = fts3PutVarint(c, nActualData);
- assert( nActualData<=nData );
- assert( nActual<=n );
-
- /* If the new doclist is big enough for force a standalone leaf
- ** node, we can immediately flush it inline without doing the
- ** memmove().
- */
- /* TODO(shess) This test matches leafWriterStep(), which does this
- ** test before it knows the cost to varint-encode the term and
- ** doclist lengths. At some point, change to
- ** pWriter->data.nData-iTermData>STANDALONE_MIN.
- */
- if( nTerm+nActualData>STANDALONE_MIN ){
- /* Push leaf node from before this term. */
- if( iTermData>0 ){
- rc = leafWriterInternalFlush(v, pWriter, 0, iTermData);
- if( rc!=SQLITE_OK ) return rc;
-
- pWriter->nTermDistinct = nTermDistinct;
- }
-
- /* Fix the encoded doclist length. */
- iDoclistData += n - nActual;
- memcpy(pWriter->data.pData+iDoclistData, c, nActual);
-
- /* Push the standalone leaf node. */
- rc = leafWriterInlineFlush(v, pWriter, pTerm, nTerm, iDoclistData);
- if( rc!=SQLITE_OK ) return rc;
-
- /* Leave the node empty. */
- dataBufferReset(&pWriter->data);
-
- return rc;
- }
-
- /* At this point, we know that the doclist was small, so do the
- ** memmove if indicated.
- */
- if( nActual<n ){
- memmove(pWriter->data.pData+iDoclistData+nActual,
- pWriter->data.pData+iDoclistData+n,
- pWriter->data.nData-(iDoclistData+n));
- pWriter->data.nData -= n-nActual;
- }
-
- /* Replace written length with actual length. */
- memcpy(pWriter->data.pData+iDoclistData, c, nActual);
-
- /* If the node is too large, break things up. */
- /* TODO(shess) This test matches leafWriterStep(), which does this
- ** test before it knows the cost to varint-encode the term and
- ** doclist lengths. At some point, change to
- ** pWriter->data.nData>LEAF_MAX.
- */
- if( iTermData+nTerm+nActualData>LEAF_MAX ){
- /* Flush out the leading data as a node */
- rc = leafWriterInternalFlush(v, pWriter, 0, iTermData);
- if( rc!=SQLITE_OK ) return rc;
-
- pWriter->nTermDistinct = nTermDistinct;
-
- /* Rebuild header using the current term */
- n = fts3PutVarint(pWriter->data.pData, 0);
- n += fts3PutVarint(pWriter->data.pData+n, nTerm);
- memcpy(pWriter->data.pData+n, pTerm, nTerm);
- n += nTerm;
-
- /* There should always be room, because the previous encoding
- ** included all data necessary to construct the term.
- */
- assert( n<iDoclistData );
- /* So long as STANDALONE_MIN is half or less of LEAF_MAX, the
- ** following memcpy() is safe (as opposed to needing a memmove).
- */
- assert( 2*STANDALONE_MIN<=LEAF_MAX );
- assert( n+pWriter->data.nData-iDoclistData<iDoclistData );
- memcpy(pWriter->data.pData+n,
- pWriter->data.pData+iDoclistData,
- pWriter->data.nData-iDoclistData);
- pWriter->data.nData -= iDoclistData-n;
- }
- ASSERT_VALID_LEAF_NODE(pWriter->data.pData, pWriter->data.nData);
-
- return SQLITE_OK;
-}
-
-/* Push pTerm[nTerm] along with the doclist data to the leaf layer of
-** %_segments.
-*/
-/* TODO(shess) Revise writeZeroSegment() so that doclists are
-** constructed directly in pWriter->data.
-*/
-static int leafWriterStep(fulltext_vtab *v, LeafWriter *pWriter,
- const char *pTerm, int nTerm,
- const char *pData, int nData){
- int rc;
- DLReader reader;
-
- dlrInit(&reader, DL_DEFAULT, pData, nData);
- rc = leafWriterStepMerge(v, pWriter, pTerm, nTerm, &reader, 1);
- dlrDestroy(&reader);
-
- return rc;
-}
-
-
-/****************************************************************/
-/* LeafReader is used to iterate over an individual leaf node. */
-typedef struct LeafReader {
- DataBuffer term; /* copy of current term. */
-
- const char *pData; /* data for current term. */
- int nData;
-} LeafReader;
-
-static void leafReaderDestroy(LeafReader *pReader){
- dataBufferDestroy(&pReader->term);
- SCRAMBLE(pReader);
-}
-
-static int leafReaderAtEnd(LeafReader *pReader){
- return pReader->nData<=0;
-}
-
-/* Access the current term. */
-static int leafReaderTermBytes(LeafReader *pReader){
- return pReader->term.nData;
-}
-static const char *leafReaderTerm(LeafReader *pReader){
- assert( pReader->term.nData>0 );
- return pReader->term.pData;
-}
-
-/* Access the doclist data for the current term. */
-static int leafReaderDataBytes(LeafReader *pReader){
- int nData;
- assert( pReader->term.nData>0 );
- fts3GetVarint32(pReader->pData, &nData);
- return nData;
-}
-static const char *leafReaderData(LeafReader *pReader){
- int n, nData;
- assert( pReader->term.nData>0 );
- n = fts3GetVarint32(pReader->pData, &nData);
- return pReader->pData+n;
-}
-
-static void leafReaderInit(const char *pData, int nData,
- LeafReader *pReader){
- int nTerm, n;
-
- assert( nData>0 );
- assert( pData[0]=='\0' );
-
- CLEAR(pReader);
-
- /* Read the first term, skipping the header byte. */
- n = fts3GetVarint32(pData+1, &nTerm);
- dataBufferInit(&pReader->term, nTerm);
- dataBufferReplace(&pReader->term, pData+1+n, nTerm);
-
- /* Position after the first term. */
- assert( 1+n+nTerm<nData );
- pReader->pData = pData+1+n+nTerm;
- pReader->nData = nData-1-n-nTerm;
-}
-
-/* Step the reader forward to the next term. */
-static void leafReaderStep(LeafReader *pReader){
- int n, nData, nPrefix, nSuffix;
- assert( !leafReaderAtEnd(pReader) );
-
- /* Skip previous entry's data block. */
- n = fts3GetVarint32(pReader->pData, &nData);
- assert( n+nData<=pReader->nData );
- pReader->pData += n+nData;
- pReader->nData -= n+nData;
-
- if( !leafReaderAtEnd(pReader) ){
- /* Construct the new term using a prefix from the old term plus a
- ** suffix from the leaf data.
- */
- n = fts3GetVarint32(pReader->pData, &nPrefix);
- n += fts3GetVarint32(pReader->pData+n, &nSuffix);
- assert( n+nSuffix<pReader->nData );
- pReader->term.nData = nPrefix;
- dataBufferAppend(&pReader->term, pReader->pData+n, nSuffix);
-
- pReader->pData += n+nSuffix;
- pReader->nData -= n+nSuffix;
- }
-}
-
-/* strcmp-style comparison of pReader's current term against pTerm.
-** If isPrefix, equality means equal through nTerm bytes.
-*/
-static int leafReaderTermCmp(LeafReader *pReader,
- const char *pTerm, int nTerm, int isPrefix){
- int c, n = pReader->term.nData<nTerm ? pReader->term.nData : nTerm;
- if( n==0 ){
- if( pReader->term.nData>0 ) return -1;
- if(nTerm>0 ) return 1;
- return 0;
- }
-
- c = memcmp(pReader->term.pData, pTerm, n);
- if( c!=0 ) return c;
- if( isPrefix && n==nTerm ) return 0;
- return pReader->term.nData - nTerm;
-}
-
-
-/****************************************************************/
-/* LeavesReader wraps LeafReader to allow iterating over the entire
-** leaf layer of the tree.
-*/
-typedef struct LeavesReader {
- int idx; /* Index within the segment. */
-
- sqlite3_stmt *pStmt; /* Statement we're streaming leaves from. */
- int eof; /* we've seen SQLITE_DONE from pStmt. */
-
- LeafReader leafReader; /* reader for the current leaf. */
- DataBuffer rootData; /* root data for inline. */
-} LeavesReader;
-
-/* Access the current term. */
-static int leavesReaderTermBytes(LeavesReader *pReader){
- assert( !pReader->eof );
- return leafReaderTermBytes(&pReader->leafReader);
-}
-static const char *leavesReaderTerm(LeavesReader *pReader){
- assert( !pReader->eof );
- return leafReaderTerm(&pReader->leafReader);
-}
-
-/* Access the doclist data for the current term. */
-static int leavesReaderDataBytes(LeavesReader *pReader){
- assert( !pReader->eof );
- return leafReaderDataBytes(&pReader->leafReader);
-}
-static const char *leavesReaderData(LeavesReader *pReader){
- assert( !pReader->eof );
- return leafReaderData(&pReader->leafReader);
-}
-
-static int leavesReaderAtEnd(LeavesReader *pReader){
- return pReader->eof;
-}
-
-/* loadSegmentLeaves() may not read all the way to SQLITE_DONE, thus
-** leaving the statement handle open, which locks the table.
-*/
-/* TODO(shess) This "solution" is not satisfactory. Really, there
-** should be check-in function for all statement handles which
-** arranges to call sqlite3_reset(). This most likely will require
-** modification to control flow all over the place, though, so for now
-** just punt.
-**
-** Note the the current system assumes that segment merges will run to
-** completion, which is why this particular probably hasn't arisen in
-** this case. Probably a brittle assumption.
-*/
-static int leavesReaderReset(LeavesReader *pReader){
- return sqlite3_reset(pReader->pStmt);
-}
-
-static void leavesReaderDestroy(LeavesReader *pReader){
- /* If idx is -1, that means we're using a non-cached statement
- ** handle in the optimize() case, so we need to release it.
- */
- if( pReader->pStmt!=NULL && pReader->idx==-1 ){
- sqlite3_finalize(pReader->pStmt);
- }
- leafReaderDestroy(&pReader->leafReader);
- dataBufferDestroy(&pReader->rootData);
- SCRAMBLE(pReader);
-}
-
-/* Initialize pReader with the given root data (if iStartBlockid==0
-** the leaf data was entirely contained in the root), or from the
-** stream of blocks between iStartBlockid and iEndBlockid, inclusive.
-*/
-static int leavesReaderInit(fulltext_vtab *v,
- int idx,
- sqlite_int64 iStartBlockid,
- sqlite_int64 iEndBlockid,
- const char *pRootData, int nRootData,
- LeavesReader *pReader){
- CLEAR(pReader);
- pReader->idx = idx;
-
- dataBufferInit(&pReader->rootData, 0);
- if( iStartBlockid==0 ){
- /* Entire leaf level fit in root data. */
- dataBufferReplace(&pReader->rootData, pRootData, nRootData);
- leafReaderInit(pReader->rootData.pData, pReader->rootData.nData,
- &pReader->leafReader);
- }else{
- sqlite3_stmt *s;
- int rc = sql_get_leaf_statement(v, idx, &s);
- if( rc!=SQLITE_OK ) return rc;
-
- rc = sqlite3_bind_int64(s, 1, iStartBlockid);
- if( rc!=SQLITE_OK ) return rc;
-
- rc = sqlite3_bind_int64(s, 2, iEndBlockid);
- if( rc!=SQLITE_OK ) return rc;
-
- rc = sqlite3_step(s);
- if( rc==SQLITE_DONE ){
- pReader->eof = 1;
- return SQLITE_OK;
- }
- if( rc!=SQLITE_ROW ) return rc;
-
- pReader->pStmt = s;
- leafReaderInit(sqlite3_column_blob(pReader->pStmt, 0),
- sqlite3_column_bytes(pReader->pStmt, 0),
- &pReader->leafReader);
- }
- return SQLITE_OK;
-}
-
-/* Step the current leaf forward to the next term. If we reach the
-** end of the current leaf, step forward to the next leaf block.
-*/
-static int leavesReaderStep(fulltext_vtab *v, LeavesReader *pReader){
- assert( !leavesReaderAtEnd(pReader) );
- leafReaderStep(&pReader->leafReader);
-
- if( leafReaderAtEnd(&pReader->leafReader) ){
- int rc;
- if( pReader->rootData.pData ){
- pReader->eof = 1;
- return SQLITE_OK;
- }
- rc = sqlite3_step(pReader->pStmt);
- if( rc!=SQLITE_ROW ){
- pReader->eof = 1;
- return rc==SQLITE_DONE ? SQLITE_OK : rc;
- }
- leafReaderDestroy(&pReader->leafReader);
- leafReaderInit(sqlite3_column_blob(pReader->pStmt, 0),
- sqlite3_column_bytes(pReader->pStmt, 0),
- &pReader->leafReader);
- }
- return SQLITE_OK;
-}
-
-/* Order LeavesReaders by their term, ignoring idx. Readers at eof
-** always sort to the end.
-*/
-static int leavesReaderTermCmp(LeavesReader *lr1, LeavesReader *lr2){
- if( leavesReaderAtEnd(lr1) ){
- if( leavesReaderAtEnd(lr2) ) return 0;
- return 1;
- }
- if( leavesReaderAtEnd(lr2) ) return -1;
-
- return leafReaderTermCmp(&lr1->leafReader,
- leavesReaderTerm(lr2), leavesReaderTermBytes(lr2),
- 0);
-}
-
-/* Similar to leavesReaderTermCmp(), with additional ordering by idx
-** so that older segments sort before newer segments.
-*/
-static int leavesReaderCmp(LeavesReader *lr1, LeavesReader *lr2){
- int c = leavesReaderTermCmp(lr1, lr2);
- if( c!=0 ) return c;
- return lr1->idx-lr2->idx;
-}
-
-/* Assume that pLr[1]..pLr[nLr] are sorted. Bubble pLr[0] into its
-** sorted position.
-*/
-static void leavesReaderReorder(LeavesReader *pLr, int nLr){
- while( nLr>1 && leavesReaderCmp(pLr, pLr+1)>0 ){
- LeavesReader tmp = pLr[0];
- pLr[0] = pLr[1];
- pLr[1] = tmp;
- nLr--;
- pLr++;
- }
-}
-
-/* Initializes pReaders with the segments from level iLevel, returning
-** the number of segments in *piReaders. Leaves pReaders in sorted
-** order.
-*/
-static int leavesReadersInit(fulltext_vtab *v, int iLevel,
- LeavesReader *pReaders, int *piReaders){
- sqlite3_stmt *s;
- int i, rc = sql_get_statement(v, SEGDIR_SELECT_LEVEL_STMT, &s);
- if( rc!=SQLITE_OK ) return rc;
-
- rc = sqlite3_bind_int(s, 1, iLevel);
- if( rc!=SQLITE_OK ) return rc;
-
- i = 0;
- while( (rc = sqlite3_step(s))==SQLITE_ROW ){
- sqlite_int64 iStart = sqlite3_column_int64(s, 0);
- sqlite_int64 iEnd = sqlite3_column_int64(s, 1);
- const char *pRootData = sqlite3_column_blob(s, 2);
- int nRootData = sqlite3_column_bytes(s, 2);
-
- assert( i<MERGE_COUNT );
- rc = leavesReaderInit(v, i, iStart, iEnd, pRootData, nRootData,
- &pReaders[i]);
- if( rc!=SQLITE_OK ) break;
-
- i++;
- }
- if( rc!=SQLITE_DONE ){
- while( i-->0 ){
- leavesReaderDestroy(&pReaders[i]);
- }
- return rc;
- }
-
- *piReaders = i;
-
- /* Leave our results sorted by term, then age. */
- while( i-- ){
- leavesReaderReorder(pReaders+i, *piReaders-i);
- }
- return SQLITE_OK;
-}
-
-/* Merge doclists from pReaders[nReaders] into a single doclist, which
-** is written to pWriter. Assumes pReaders is ordered oldest to
-** newest.
-*/
-/* TODO(shess) Consider putting this inline in segmentMerge(). */
-static int leavesReadersMerge(fulltext_vtab *v,
- LeavesReader *pReaders, int nReaders,
- LeafWriter *pWriter){
- DLReader dlReaders[MERGE_COUNT];
- const char *pTerm = leavesReaderTerm(pReaders);
- int i, nTerm = leavesReaderTermBytes(pReaders);
-
- assert( nReaders<=MERGE_COUNT );
-
- for(i=0; i<nReaders; i++){
- dlrInit(&dlReaders[i], DL_DEFAULT,
- leavesReaderData(pReaders+i),
- leavesReaderDataBytes(pReaders+i));
- }
-
- return leafWriterStepMerge(v, pWriter, pTerm, nTerm, dlReaders, nReaders);
-}
-
-/* Forward ref due to mutual recursion with segdirNextIndex(). */
-static int segmentMerge(fulltext_vtab *v, int iLevel);
-
-/* Put the next available index at iLevel into *pidx. If iLevel
-** already has MERGE_COUNT segments, they are merged to a higher
-** level to make room.
-*/
-static int segdirNextIndex(fulltext_vtab *v, int iLevel, int *pidx){
- int rc = segdir_max_index(v, iLevel, pidx);
- if( rc==SQLITE_DONE ){ /* No segments at iLevel. */
- *pidx = 0;
- }else if( rc==SQLITE_ROW ){
- if( *pidx==(MERGE_COUNT-1) ){
- rc = segmentMerge(v, iLevel);
- if( rc!=SQLITE_OK ) return rc;
- *pidx = 0;
- }else{
- (*pidx)++;
- }
- }else{
- return rc;
- }
- return SQLITE_OK;
-}
-
-/* Merge MERGE_COUNT segments at iLevel into a new segment at
-** iLevel+1. If iLevel+1 is already full of segments, those will be
-** merged to make room.
-*/
-static int segmentMerge(fulltext_vtab *v, int iLevel){
- LeafWriter writer;
- LeavesReader lrs[MERGE_COUNT];
- int i, rc, idx = 0;
-
- /* Determine the next available segment index at the next level,
- ** merging as necessary.
- */
- rc = segdirNextIndex(v, iLevel+1, &idx);
- if( rc!=SQLITE_OK ) return rc;
-
- /* TODO(shess) This assumes that we'll always see exactly
- ** MERGE_COUNT segments to merge at a given level. That will be
- ** broken if we allow the developer to request preemptive or
- ** deferred merging.
- */
- memset(&lrs, '\0', sizeof(lrs));
- rc = leavesReadersInit(v, iLevel, lrs, &i);
- if( rc!=SQLITE_OK ) return rc;
- assert( i==MERGE_COUNT );
-
- leafWriterInit(iLevel+1, idx, &writer);
-
- /* Since leavesReaderReorder() pushes readers at eof to the end,
- ** when the first reader is empty, all will be empty.
- */
- while( !leavesReaderAtEnd(lrs) ){
- /* Figure out how many readers share their next term. */
- for(i=1; i<MERGE_COUNT && !leavesReaderAtEnd(lrs+i); i++){
- if( 0!=leavesReaderTermCmp(lrs, lrs+i) ) break;
- }
-
- rc = leavesReadersMerge(v, lrs, i, &writer);
- if( rc!=SQLITE_OK ) goto err;
-
- /* Step forward those that were merged. */
- while( i-->0 ){
- rc = leavesReaderStep(v, lrs+i);
- if( rc!=SQLITE_OK ) goto err;
-
- /* Reorder by term, then by age. */
- leavesReaderReorder(lrs+i, MERGE_COUNT-i);
- }
- }
-
- for(i=0; i<MERGE_COUNT; i++){
- leavesReaderDestroy(&lrs[i]);
- }
-
- rc = leafWriterFinalize(v, &writer);
- leafWriterDestroy(&writer);
- if( rc!=SQLITE_OK ) return rc;
-
- /* Delete the merged segment data. */
- return segdir_delete(v, iLevel);
-
- err:
- for(i=0; i<MERGE_COUNT; i++){
- leavesReaderDestroy(&lrs[i]);
- }
- leafWriterDestroy(&writer);
- return rc;
-}
-
-/* Accumulate the union of *acc and *pData into *acc. */
-static void docListAccumulateUnion(DataBuffer *acc,
- const char *pData, int nData) {
- DataBuffer tmp = *acc;
- dataBufferInit(acc, tmp.nData+nData);
- docListUnion(tmp.pData, tmp.nData, pData, nData, acc);
- dataBufferDestroy(&tmp);
-}
-
-/* TODO(shess) It might be interesting to explore different merge
-** strategies, here. For instance, since this is a sorted merge, we
-** could easily merge many doclists in parallel. With some
-** comprehension of the storage format, we could merge all of the
-** doclists within a leaf node directly from the leaf node's storage.
-** It may be worthwhile to merge smaller doclists before larger
-** doclists, since they can be traversed more quickly - but the
-** results may have less overlap, making them more expensive in a
-** different way.
-*/
-
-/* Scan pReader for pTerm/nTerm, and merge the term's doclist over
-** *out (any doclists with duplicate docids overwrite those in *out).
-** Internal function for loadSegmentLeaf().
-*/
-static int loadSegmentLeavesInt(fulltext_vtab *v, LeavesReader *pReader,
- const char *pTerm, int nTerm, int isPrefix,
- DataBuffer *out){
- /* doclist data is accumulated into pBuffers similar to how one does
- ** increment in binary arithmetic. If index 0 is empty, the data is
- ** stored there. If there is data there, it is merged and the
- ** results carried into position 1, with further merge-and-carry
- ** until an empty position is found.
- */
- DataBuffer *pBuffers = NULL;
- int nBuffers = 0, nMaxBuffers = 0, rc;
-
- assert( nTerm>0 );
-
- for(rc=SQLITE_OK; rc==SQLITE_OK && !leavesReaderAtEnd(pReader);
- rc=leavesReaderStep(v, pReader)){
- /* TODO(shess) Really want leavesReaderTermCmp(), but that name is
- ** already taken to compare the terms of two LeavesReaders. Think
- ** on a better name. [Meanwhile, break encapsulation rather than
- ** use a confusing name.]
- */
- int c = leafReaderTermCmp(&pReader->leafReader, pTerm, nTerm, isPrefix);
- if( c>0 ) break; /* Past any possible matches. */
- if( c==0 ){
- const char *pData = leavesReaderData(pReader);
- int iBuffer, nData = leavesReaderDataBytes(pReader);
-
- /* Find the first empty buffer. */
- for(iBuffer=0; iBuffer<nBuffers; ++iBuffer){
- if( 0==pBuffers[iBuffer].nData ) break;
- }
-
- /* Out of buffers, add an empty one. */
- if( iBuffer==nBuffers ){
- if( nBuffers==nMaxBuffers ){
- DataBuffer *p;
- nMaxBuffers += 20;
-
- /* Manual realloc so we can handle NULL appropriately. */
- p = sqlite3_malloc(nMaxBuffers*sizeof(*pBuffers));
- if( p==NULL ){
- rc = SQLITE_NOMEM;
- break;
- }
-
- if( nBuffers>0 ){
- assert(pBuffers!=NULL);
- memcpy(p, pBuffers, nBuffers*sizeof(*pBuffers));
- sqlite3_free(pBuffers);
- }
- pBuffers = p;
- }
- dataBufferInit(&(pBuffers[nBuffers]), 0);
- nBuffers++;
- }
-
- /* At this point, must have an empty at iBuffer. */
- assert(iBuffer<nBuffers && pBuffers[iBuffer].nData==0);
-
- /* If empty was first buffer, no need for merge logic. */
- if( iBuffer==0 ){
- dataBufferReplace(&(pBuffers[0]), pData, nData);
- }else{
- /* pAcc is the empty buffer the merged data will end up in. */
- DataBuffer *pAcc = &(pBuffers[iBuffer]);
- DataBuffer *p = &(pBuffers[0]);
-
- /* Handle position 0 specially to avoid need to prime pAcc
- ** with pData/nData.
- */
- dataBufferSwap(p, pAcc);
- docListAccumulateUnion(pAcc, pData, nData);
-
- /* Accumulate remaining doclists into pAcc. */
- for(++p; p<pAcc; ++p){
- docListAccumulateUnion(pAcc, p->pData, p->nData);
-
- /* dataBufferReset() could allow a large doclist to blow up
- ** our memory requirements.
- */
- if( p->nCapacity<1024 ){
- dataBufferReset(p);
- }else{
- dataBufferDestroy(p);
- dataBufferInit(p, 0);
- }
- }
- }
- }
- }
-
- /* Union all the doclists together into *out. */
- /* TODO(shess) What if *out is big? Sigh. */
- if( rc==SQLITE_OK && nBuffers>0 ){
- int iBuffer;
- for(iBuffer=0; iBuffer<nBuffers; ++iBuffer){
- if( pBuffers[iBuffer].nData>0 ){
- if( out->nData==0 ){
- dataBufferSwap(out, &(pBuffers[iBuffer]));
- }else{
- docListAccumulateUnion(out, pBuffers[iBuffer].pData,
- pBuffers[iBuffer].nData);
- }
- }
- }
- }
-
- while( nBuffers-- ){
- dataBufferDestroy(&(pBuffers[nBuffers]));
- }
- if( pBuffers!=NULL ) sqlite3_free(pBuffers);
-
- return rc;
-}
-
-/* Call loadSegmentLeavesInt() with pData/nData as input. */
-static int loadSegmentLeaf(fulltext_vtab *v, const char *pData, int nData,
- const char *pTerm, int nTerm, int isPrefix,
- DataBuffer *out){
- LeavesReader reader;
- int rc;
-
- assert( nData>1 );
- assert( *pData=='\0' );
- rc = leavesReaderInit(v, 0, 0, 0, pData, nData, &reader);
- if( rc!=SQLITE_OK ) return rc;
-
- rc = loadSegmentLeavesInt(v, &reader, pTerm, nTerm, isPrefix, out);
- leavesReaderReset(&reader);
- leavesReaderDestroy(&reader);
- return rc;
-}
-
-/* Call loadSegmentLeavesInt() with the leaf nodes from iStartLeaf to
-** iEndLeaf (inclusive) as input, and merge the resulting doclist into
-** out.
-*/
-static int loadSegmentLeaves(fulltext_vtab *v,
- sqlite_int64 iStartLeaf, sqlite_int64 iEndLeaf,
- const char *pTerm, int nTerm, int isPrefix,
- DataBuffer *out){
- int rc;
- LeavesReader reader;
-
- assert( iStartLeaf<=iEndLeaf );
- rc = leavesReaderInit(v, 0, iStartLeaf, iEndLeaf, NULL, 0, &reader);
- if( rc!=SQLITE_OK ) return rc;
-
- rc = loadSegmentLeavesInt(v, &reader, pTerm, nTerm, isPrefix, out);
- leavesReaderReset(&reader);
- leavesReaderDestroy(&reader);
- return rc;
-}
-
-/* Taking pData/nData as an interior node, find the sequence of child
-** nodes which could include pTerm/nTerm/isPrefix. Note that the
-** interior node terms logically come between the blocks, so there is
-** one more blockid than there are terms (that block contains terms >=
-** the last interior-node term).
-*/
-/* TODO(shess) The calling code may already know that the end child is
-** not worth calculating, because the end may be in a later sibling
-** node. Consider whether breaking symmetry is worthwhile. I suspect
-** it is not worthwhile.
-*/
-static void getChildrenContaining(const char *pData, int nData,
- const char *pTerm, int nTerm, int isPrefix,
- sqlite_int64 *piStartChild,
- sqlite_int64 *piEndChild){
- InteriorReader reader;
-
- assert( nData>1 );
- assert( *pData!='\0' );
- interiorReaderInit(pData, nData, &reader);
-
- /* Scan for the first child which could contain pTerm/nTerm. */
- while( !interiorReaderAtEnd(&reader) ){
- if( interiorReaderTermCmp(&reader, pTerm, nTerm, 0)>0 ) break;
- interiorReaderStep(&reader);
- }
- *piStartChild = interiorReaderCurrentBlockid(&reader);
-
- /* Keep scanning to find a term greater than our term, using prefix
- ** comparison if indicated. If isPrefix is false, this will be the
- ** same blockid as the starting block.
- */
- while( !interiorReaderAtEnd(&reader) ){
- if( interiorReaderTermCmp(&reader, pTerm, nTerm, isPrefix)>0 ) break;
- interiorReaderStep(&reader);
- }
- *piEndChild = interiorReaderCurrentBlockid(&reader);
-
- interiorReaderDestroy(&reader);
-
- /* Children must ascend, and if !prefix, both must be the same. */
- assert( *piEndChild>=*piStartChild );
- assert( isPrefix || *piStartChild==*piEndChild );
-}
-
-/* Read block at iBlockid and pass it with other params to
-** getChildrenContaining().
-*/
-static int loadAndGetChildrenContaining(
- fulltext_vtab *v,
- sqlite_int64 iBlockid,
- const char *pTerm, int nTerm, int isPrefix,
- sqlite_int64 *piStartChild, sqlite_int64 *piEndChild
-){
- sqlite3_stmt *s = NULL;
- int rc;
-
- assert( iBlockid!=0 );
- assert( pTerm!=NULL );
- assert( nTerm!=0 ); /* TODO(shess) Why not allow this? */
- assert( piStartChild!=NULL );
- assert( piEndChild!=NULL );
-
- rc = sql_get_statement(v, BLOCK_SELECT_STMT, &s);
- if( rc!=SQLITE_OK ) return rc;
-
- rc = sqlite3_bind_int64(s, 1, iBlockid);
- if( rc!=SQLITE_OK ) return rc;
-
- rc = sqlite3_step(s);
- if( rc==SQLITE_DONE ) return SQLITE_ERROR;
- if( rc!=SQLITE_ROW ) return rc;
-
- getChildrenContaining(sqlite3_column_blob(s, 0), sqlite3_column_bytes(s, 0),
- pTerm, nTerm, isPrefix, piStartChild, piEndChild);
-
- /* We expect only one row. We must execute another sqlite3_step()
- * to complete the iteration; otherwise the table will remain
- * locked. */
- rc = sqlite3_step(s);
- if( rc==SQLITE_ROW ) return SQLITE_ERROR;
- if( rc!=SQLITE_DONE ) return rc;
-
- return SQLITE_OK;
-}
-
-/* Traverse the tree represented by pData[nData] looking for
-** pTerm[nTerm], placing its doclist into *out. This is internal to
-** loadSegment() to make error-handling cleaner.
-*/
-static int loadSegmentInt(fulltext_vtab *v, const char *pData, int nData,
- sqlite_int64 iLeavesEnd,
- const char *pTerm, int nTerm, int isPrefix,
- DataBuffer *out){
- /* Special case where root is a leaf. */
- if( *pData=='\0' ){
- return loadSegmentLeaf(v, pData, nData, pTerm, nTerm, isPrefix, out);
- }else{
- int rc;
- sqlite_int64 iStartChild, iEndChild;
-
- /* Process pData as an interior node, then loop down the tree
- ** until we find the set of leaf nodes to scan for the term.
- */
- getChildrenContaining(pData, nData, pTerm, nTerm, isPrefix,
- &iStartChild, &iEndChild);
- while( iStartChild>iLeavesEnd ){
- sqlite_int64 iNextStart, iNextEnd;
- rc = loadAndGetChildrenContaining(v, iStartChild, pTerm, nTerm, isPrefix,
- &iNextStart, &iNextEnd);
- if( rc!=SQLITE_OK ) return rc;
-
- /* If we've branched, follow the end branch, too. */
- if( iStartChild!=iEndChild ){
- sqlite_int64 iDummy;
- rc = loadAndGetChildrenContaining(v, iEndChild, pTerm, nTerm, isPrefix,
- &iDummy, &iNextEnd);
- if( rc!=SQLITE_OK ) return rc;
- }
-
- assert( iNextStart<=iNextEnd );
- iStartChild = iNextStart;
- iEndChild = iNextEnd;
- }
- assert( iStartChild<=iLeavesEnd );
- assert( iEndChild<=iLeavesEnd );
-
- /* Scan through the leaf segments for doclists. */
- return loadSegmentLeaves(v, iStartChild, iEndChild,
- pTerm, nTerm, isPrefix, out);
- }
-}
-
-/* Call loadSegmentInt() to collect the doclist for pTerm/nTerm, then
-** merge its doclist over *out (any duplicate doclists read from the
-** segment rooted at pData will overwrite those in *out).
-*/
-/* TODO(shess) Consider changing this to determine the depth of the
-** leaves using either the first characters of interior nodes (when
-** ==1, we're one level above the leaves), or the first character of
-** the root (which will describe the height of the tree directly).
-** Either feels somewhat tricky to me.
-*/
-/* TODO(shess) The current merge is likely to be slow for large
-** doclists (though it should process from newest/smallest to
-** oldest/largest, so it may not be that bad). It might be useful to
-** modify things to allow for N-way merging. This could either be
-** within a segment, with pairwise merges across segments, or across
-** all segments at once.
-*/
-static int loadSegment(fulltext_vtab *v, const char *pData, int nData,
- sqlite_int64 iLeavesEnd,
- const char *pTerm, int nTerm, int isPrefix,
- DataBuffer *out){
- DataBuffer result;
- int rc;
-
- assert( nData>1 );
-
- /* This code should never be called with buffered updates. */
- assert( v->nPendingData<0 );
-
- dataBufferInit(&result, 0);
- rc = loadSegmentInt(v, pData, nData, iLeavesEnd,
- pTerm, nTerm, isPrefix, &result);
- if( rc==SQLITE_OK && result.nData>0 ){
- if( out->nData==0 ){
- DataBuffer tmp = *out;
- *out = result;
- result = tmp;
- }else{
- DataBuffer merged;
- DLReader readers[2];
-
- dlrInit(&readers[0], DL_DEFAULT, out->pData, out->nData);
- dlrInit(&readers[1], DL_DEFAULT, result.pData, result.nData);
- dataBufferInit(&merged, out->nData+result.nData);
- docListMerge(&merged, readers, 2);
- dataBufferDestroy(out);
- *out = merged;
- dlrDestroy(&readers[0]);
- dlrDestroy(&readers[1]);
- }
- }
- dataBufferDestroy(&result);
- return rc;
-}
-
-/* Scan the database and merge together the posting lists for the term
-** into *out.
-*/
-static int termSelect(
- fulltext_vtab *v,
- int iColumn,
- const char *pTerm, int nTerm, /* Term to query for */
- int isPrefix, /* True for a prefix search */
- DocListType iType,
- DataBuffer *out /* Write results here */
-){
- DataBuffer doclist;
- sqlite3_stmt *s;
- int rc = sql_get_statement(v, SEGDIR_SELECT_ALL_STMT, &s);
- if( rc!=SQLITE_OK ) return rc;
-
- /* This code should never be called with buffered updates. */
- assert( v->nPendingData<0 );
-
- dataBufferInit(&doclist, 0);
- dataBufferInit(out, 0);
-
- /* Traverse the segments from oldest to newest so that newer doclist
- ** elements for given docids overwrite older elements.
- */
- while( (rc = sqlite3_step(s))==SQLITE_ROW ){
- const char *pData = sqlite3_column_blob(s, 2);
- const int nData = sqlite3_column_bytes(s, 2);
- const sqlite_int64 iLeavesEnd = sqlite3_column_int64(s, 1);
- rc = loadSegment(v, pData, nData, iLeavesEnd, pTerm, nTerm, isPrefix,
- &doclist);
- if( rc!=SQLITE_OK ) goto err;
- }
- if( rc==SQLITE_DONE ){
- if( doclist.nData!=0 ){
- /* TODO(shess) The old term_select_all() code applied the column
- ** restrict as we merged segments, leading to smaller buffers.
- ** This is probably worthwhile to bring back, once the new storage
- ** system is checked in.
- */
- if( iColumn==v->nColumn) iColumn = -1;
- docListTrim(DL_DEFAULT, doclist.pData, doclist.nData,
- iColumn, iType, out);
- }
- rc = SQLITE_OK;
- }
-
- err:
- dataBufferDestroy(&doclist);
- return rc;
-}
-
-/****************************************************************/
-/* Used to hold hashtable data for sorting. */
-typedef struct TermData {
- const char *pTerm;
- int nTerm;
- DLCollector *pCollector;
-} TermData;
-
-/* Orders TermData elements in strcmp fashion ( <0 for less-than, 0
-** for equal, >0 for greater-than).
-*/
-static int termDataCmp(const void *av, const void *bv){
- const TermData *a = (const TermData *)av;
- const TermData *b = (const TermData *)bv;
- int n = a->nTerm<b->nTerm ? a->nTerm : b->nTerm;
- int c = memcmp(a->pTerm, b->pTerm, n);
- if( c!=0 ) return c;
- return a->nTerm-b->nTerm;
-}
-
-/* Order pTerms data by term, then write a new level 0 segment using
-** LeafWriter.
-*/
-static int writeZeroSegment(fulltext_vtab *v, fts3Hash *pTerms){
- fts3HashElem *e;
- int idx, rc, i, n;
- TermData *pData;
- LeafWriter writer;
- DataBuffer dl;
-
- /* Determine the next index at level 0, merging as necessary. */
- rc = segdirNextIndex(v, 0, &idx);
- if( rc!=SQLITE_OK ) return rc;
-
- n = fts3HashCount(pTerms);
- pData = sqlite3_malloc(n*sizeof(TermData));
-
- for(i = 0, e = fts3HashFirst(pTerms); e; i++, e = fts3HashNext(e)){
- assert( i<n );
- pData[i].pTerm = fts3HashKey(e);
- pData[i].nTerm = fts3HashKeysize(e);
- pData[i].pCollector = fts3HashData(e);
- }
- assert( i==n );
-
- /* TODO(shess) Should we allow user-defined collation sequences,
- ** here? I think we only need that once we support prefix searches.
- */
- if( n>1 ) qsort(pData, n, sizeof(*pData), termDataCmp);
-
- /* TODO(shess) Refactor so that we can write directly to the segment
- ** DataBuffer, as happens for segment merges.
- */
- leafWriterInit(0, idx, &writer);
- dataBufferInit(&dl, 0);
- for(i=0; i<n; i++){
- dataBufferReset(&dl);
- dlcAddDoclist(pData[i].pCollector, &dl);
- rc = leafWriterStep(v, &writer,
- pData[i].pTerm, pData[i].nTerm, dl.pData, dl.nData);
- if( rc!=SQLITE_OK ) goto err;
- }
- rc = leafWriterFinalize(v, &writer);
-
- err:
- dataBufferDestroy(&dl);
- sqlite3_free(pData);
- leafWriterDestroy(&writer);
- return rc;
-}
-
-/* If pendingTerms has data, free it. */
-static int clearPendingTerms(fulltext_vtab *v){
- if( v->nPendingData>=0 ){
- fts3HashElem *e;
- for(e=fts3HashFirst(&v->pendingTerms); e; e=fts3HashNext(e)){
- dlcDelete(fts3HashData(e));
- }
- fts3HashClear(&v->pendingTerms);
- v->nPendingData = -1;
- }
- return SQLITE_OK;
-}
-
-/* If pendingTerms has data, flush it to a level-zero segment, and
-** free it.
-*/
-static int flushPendingTerms(fulltext_vtab *v){
- if( v->nPendingData>=0 ){
- int rc = writeZeroSegment(v, &v->pendingTerms);
- if( rc==SQLITE_OK ) clearPendingTerms(v);
- return rc;
- }
- return SQLITE_OK;
-}
-
-/* If pendingTerms is "too big", or docid is out of order, flush it.
-** Regardless, be certain that pendingTerms is initialized for use.
-*/
-static int initPendingTerms(fulltext_vtab *v, sqlite_int64 iDocid){
- /* TODO(shess) Explore whether partially flushing the buffer on
- ** forced-flush would provide better performance. I suspect that if
- ** we ordered the doclists by size and flushed the largest until the
- ** buffer was half empty, that would let the less frequent terms
- ** generate longer doclists.
- */
- if( iDocid<=v->iPrevDocid || v->nPendingData>kPendingThreshold ){
- int rc = flushPendingTerms(v);
- if( rc!=SQLITE_OK ) return rc;
- }
- if( v->nPendingData<0 ){
- fts3HashInit(&v->pendingTerms, FTS3_HASH_STRING, 1);
- v->nPendingData = 0;
- }
- v->iPrevDocid = iDocid;
- return SQLITE_OK;
-}
-
-/* This function implements the xUpdate callback; it is the top-level entry
- * point for inserting, deleting or updating a row in a full-text table. */
-static int fulltextUpdate(sqlite3_vtab *pVtab, int nArg, sqlite3_value **ppArg,
- sqlite_int64 *pRowid){
- fulltext_vtab *v = (fulltext_vtab *) pVtab;
- int rc;
-
- FTSTRACE(("FTS3 Update %p\n", pVtab));
-
- if( nArg<2 ){
- rc = index_delete(v, sqlite3_value_int64(ppArg[0]));
- if( rc==SQLITE_OK ){
- /* If we just deleted the last row in the table, clear out the
- ** index data.
- */
- rc = content_exists(v);
- if( rc==SQLITE_ROW ){
- rc = SQLITE_OK;
- }else if( rc==SQLITE_DONE ){
- /* Clear the pending terms so we don't flush a useless level-0
- ** segment when the transaction closes.
- */
- rc = clearPendingTerms(v);
- if( rc==SQLITE_OK ){
- rc = segdir_delete_all(v);
- }
- }
- }
- } else if( sqlite3_value_type(ppArg[0]) != SQLITE_NULL ){
- /* An update:
- * ppArg[0] = old rowid
- * ppArg[1] = new rowid
- * ppArg[2..2+v->nColumn-1] = values
- * ppArg[2+v->nColumn] = value for magic column (we ignore this)
- * ppArg[2+v->nColumn+1] = value for docid
- */
- sqlite_int64 rowid = sqlite3_value_int64(ppArg[0]);
- if( sqlite3_value_type(ppArg[1]) != SQLITE_INTEGER ||
- sqlite3_value_int64(ppArg[1]) != rowid ){
- rc = SQLITE_ERROR; /* we don't allow changing the rowid */
- }else if( sqlite3_value_type(ppArg[2+v->nColumn+1]) != SQLITE_INTEGER ||
- sqlite3_value_int64(ppArg[2+v->nColumn+1]) != rowid ){
- rc = SQLITE_ERROR; /* we don't allow changing the docid */
- }else{
- assert( nArg==2+v->nColumn+2);
- rc = index_update(v, rowid, &ppArg[2]);
- }
- } else {
- /* An insert:
- * ppArg[1] = requested rowid
- * ppArg[2..2+v->nColumn-1] = values
- * ppArg[2+v->nColumn] = value for magic column (we ignore this)
- * ppArg[2+v->nColumn+1] = value for docid
- */
- sqlite3_value *pRequestDocid = ppArg[2+v->nColumn+1];
- assert( nArg==2+v->nColumn+2);
- if( SQLITE_NULL != sqlite3_value_type(pRequestDocid) &&
- SQLITE_NULL != sqlite3_value_type(ppArg[1]) ){
- /* TODO(shess) Consider allowing this to work if the values are
- ** identical. I'm inclined to discourage that usage, though,
- ** given that both rowid and docid are special columns. Better
- ** would be to define one or the other as the default winner,
- ** but should it be fts3-centric (docid) or SQLite-centric
- ** (rowid)?
- */
- rc = SQLITE_ERROR;
- }else{
- if( SQLITE_NULL == sqlite3_value_type(pRequestDocid) ){
- pRequestDocid = ppArg[1];
- }
- rc = index_insert(v, pRequestDocid, &ppArg[2], pRowid);
- }
- }
-
- return rc;
-}
-
-static int fulltextSync(sqlite3_vtab *pVtab){
- FTSTRACE(("FTS3 xSync()\n"));
- return flushPendingTerms((fulltext_vtab *)pVtab);
-}
-
-static int fulltextBegin(sqlite3_vtab *pVtab){
- fulltext_vtab *v = (fulltext_vtab *) pVtab;
- FTSTRACE(("FTS3 xBegin()\n"));
-
- /* Any buffered updates should have been cleared by the previous
- ** transaction.
- */
- assert( v->nPendingData<0 );
- return clearPendingTerms(v);
-}
-
-static int fulltextCommit(sqlite3_vtab *pVtab){
- fulltext_vtab *v = (fulltext_vtab *) pVtab;
- FTSTRACE(("FTS3 xCommit()\n"));
-
- /* Buffered updates should have been cleared by fulltextSync(). */
- assert( v->nPendingData<0 );
- return clearPendingTerms(v);
-}
-
-static int fulltextRollback(sqlite3_vtab *pVtab){
- FTSTRACE(("FTS3 xRollback()\n"));
- return clearPendingTerms((fulltext_vtab *)pVtab);
-}
-
-/*
-** Implementation of the snippet() function for FTS3
-*/
-static void snippetFunc(
- sqlite3_context *pContext,
- int argc,
- sqlite3_value **argv
-){
- fulltext_cursor *pCursor;
- if( argc<1 ) return;
- if( sqlite3_value_type(argv[0])!=SQLITE_BLOB ||
- sqlite3_value_bytes(argv[0])!=sizeof(pCursor) ){
- sqlite3_result_error(pContext, "illegal first argument to html_snippet",-1);
- }else{
- const char *zStart = "<b>";
- const char *zEnd = "</b>";
- const char *zEllipsis = "<b>...</b>";
- memcpy(&pCursor, sqlite3_value_blob(argv[0]), sizeof(pCursor));
- if( argc>=2 ){
- zStart = (const char*)sqlite3_value_text(argv[1]);
- if( argc>=3 ){
- zEnd = (const char*)sqlite3_value_text(argv[2]);
- if( argc>=4 ){
- zEllipsis = (const char*)sqlite3_value_text(argv[3]);
- }
- }
- }
- snippetAllOffsets(pCursor);
- snippetText(pCursor, zStart, zEnd, zEllipsis);
- sqlite3_result_text(pContext, pCursor->snippet.zSnippet,
- pCursor->snippet.nSnippet, SQLITE_STATIC);
- }
-}
-
-/*
-** Implementation of the offsets() function for FTS3
-*/
-static void snippetOffsetsFunc(
- sqlite3_context *pContext,
- int argc,
- sqlite3_value **argv
-){
- fulltext_cursor *pCursor;
- if( argc<1 ) return;
- if( sqlite3_value_type(argv[0])!=SQLITE_BLOB ||
- sqlite3_value_bytes(argv[0])!=sizeof(pCursor) ){
- sqlite3_result_error(pContext, "illegal first argument to offsets",-1);
- }else{
- memcpy(&pCursor, sqlite3_value_blob(argv[0]), sizeof(pCursor));
- snippetAllOffsets(pCursor);
- snippetOffsetText(&pCursor->snippet);
- sqlite3_result_text(pContext,
- pCursor->snippet.zOffset, pCursor->snippet.nOffset,
- SQLITE_STATIC);
- }
-}
-
-/* OptLeavesReader is nearly identical to LeavesReader, except that
-** where LeavesReader is geared towards the merging of complete
-** segment levels (with exactly MERGE_COUNT segments), OptLeavesReader
-** is geared towards implementation of the optimize() function, and
-** can merge all segments simultaneously. This version may be
-** somewhat less efficient than LeavesReader because it merges into an
-** accumulator rather than doing an N-way merge, but since segment
-** size grows exponentially (so segment count logrithmically) this is
-** probably not an immediate problem.
-*/
-/* TODO(shess): Prove that assertion, or extend the merge code to
-** merge tree fashion (like the prefix-searching code does).
-*/
-/* TODO(shess): OptLeavesReader and LeavesReader could probably be
-** merged with little or no loss of performance for LeavesReader. The
-** merged code would need to handle >MERGE_COUNT segments, and would
-** also need to be able to optionally optimize away deletes.
-*/
-typedef struct OptLeavesReader {
- /* Segment number, to order readers by age. */
- int segment;
- LeavesReader reader;
-} OptLeavesReader;
-
-static int optLeavesReaderAtEnd(OptLeavesReader *pReader){
- return leavesReaderAtEnd(&pReader->reader);
-}
-static int optLeavesReaderTermBytes(OptLeavesReader *pReader){
- return leavesReaderTermBytes(&pReader->reader);
-}
-static const char *optLeavesReaderData(OptLeavesReader *pReader){
- return leavesReaderData(&pReader->reader);
-}
-static int optLeavesReaderDataBytes(OptLeavesReader *pReader){
- return leavesReaderDataBytes(&pReader->reader);
-}
-static const char *optLeavesReaderTerm(OptLeavesReader *pReader){
- return leavesReaderTerm(&pReader->reader);
-}
-static int optLeavesReaderStep(fulltext_vtab *v, OptLeavesReader *pReader){
- return leavesReaderStep(v, &pReader->reader);
-}
-static int optLeavesReaderTermCmp(OptLeavesReader *lr1, OptLeavesReader *lr2){
- return leavesReaderTermCmp(&lr1->reader, &lr2->reader);
-}
-/* Order by term ascending, segment ascending (oldest to newest), with
-** exhausted readers to the end.
-*/
-static int optLeavesReaderCmp(OptLeavesReader *lr1, OptLeavesReader *lr2){
- int c = optLeavesReaderTermCmp(lr1, lr2);
- if( c!=0 ) return c;
- return lr1->segment-lr2->segment;
-}
-/* Bubble pLr[0] to appropriate place in pLr[1..nLr-1]. Assumes that
-** pLr[1..nLr-1] is already sorted.
-*/
-static void optLeavesReaderReorder(OptLeavesReader *pLr, int nLr){
- while( nLr>1 && optLeavesReaderCmp(pLr, pLr+1)>0 ){
- OptLeavesReader tmp = pLr[0];
- pLr[0] = pLr[1];
- pLr[1] = tmp;
- nLr--;
- pLr++;
- }
-}
-
-/* optimize() helper function. Put the readers in order and iterate
-** through them, merging doclists for matching terms into pWriter.
-** Returns SQLITE_OK on success, or the SQLite error code which
-** prevented success.
-*/
-static int optimizeInternal(fulltext_vtab *v,
- OptLeavesReader *readers, int nReaders,
- LeafWriter *pWriter){
- int i, rc = SQLITE_OK;
- DataBuffer doclist, merged, tmp;
-
- /* Order the readers. */
- i = nReaders;
- while( i-- > 0 ){
- optLeavesReaderReorder(&readers[i], nReaders-i);
- }
-
- dataBufferInit(&doclist, LEAF_MAX);
- dataBufferInit(&merged, LEAF_MAX);
-
- /* Exhausted readers bubble to the end, so when the first reader is
- ** at eof, all are at eof.
- */
- while( !optLeavesReaderAtEnd(&readers[0]) ){
-
- /* Figure out how many readers share the next term. */
- for(i=1; i<nReaders && !optLeavesReaderAtEnd(&readers[i]); i++){
- if( 0!=optLeavesReaderTermCmp(&readers[0], &readers[i]) ) break;
- }
-
- /* Special-case for no merge. */
- if( i==1 ){
- /* Trim deletions from the doclist. */
- dataBufferReset(&merged);
- docListTrim(DL_DEFAULT,
- optLeavesReaderData(&readers[0]),
- optLeavesReaderDataBytes(&readers[0]),
- -1, DL_DEFAULT, &merged);
- }else{
- DLReader dlReaders[MERGE_COUNT];
- int iReader, nReaders;
-
- /* Prime the pipeline with the first reader's doclist. After
- ** one pass index 0 will reference the accumulated doclist.
- */
- dlrInit(&dlReaders[0], DL_DEFAULT,
- optLeavesReaderData(&readers[0]),
- optLeavesReaderDataBytes(&readers[0]));
- iReader = 1;
-
- assert( iReader<i ); /* Must execute the loop at least once. */
- while( iReader<i ){
- /* Merge 16 inputs per pass. */
- for( nReaders=1; iReader<i && nReaders<MERGE_COUNT;
- iReader++, nReaders++ ){
- dlrInit(&dlReaders[nReaders], DL_DEFAULT,
- optLeavesReaderData(&readers[iReader]),
- optLeavesReaderDataBytes(&readers[iReader]));
- }
-
- /* Merge doclists and swap result into accumulator. */
- dataBufferReset(&merged);
- docListMerge(&merged, dlReaders, nReaders);
- tmp = merged;
- merged = doclist;
- doclist = tmp;
-
- while( nReaders-- > 0 ){
- dlrDestroy(&dlReaders[nReaders]);
- }
-
- /* Accumulated doclist to reader 0 for next pass. */
- dlrInit(&dlReaders[0], DL_DEFAULT, doclist.pData, doclist.nData);
- }
-
- /* Destroy reader that was left in the pipeline. */
- dlrDestroy(&dlReaders[0]);
-
- /* Trim deletions from the doclist. */
- dataBufferReset(&merged);
- docListTrim(DL_DEFAULT, doclist.pData, doclist.nData,
- -1, DL_DEFAULT, &merged);
- }
-
- /* Only pass doclists with hits (skip if all hits deleted). */
- if( merged.nData>0 ){
- rc = leafWriterStep(v, pWriter,
- optLeavesReaderTerm(&readers[0]),
- optLeavesReaderTermBytes(&readers[0]),
- merged.pData, merged.nData);
- if( rc!=SQLITE_OK ) goto err;
- }
-
- /* Step merged readers to next term and reorder. */
- while( i-- > 0 ){
- rc = optLeavesReaderStep(v, &readers[i]);
- if( rc!=SQLITE_OK ) goto err;
-
- optLeavesReaderReorder(&readers[i], nReaders-i);
- }
- }
-
- err:
- dataBufferDestroy(&doclist);
- dataBufferDestroy(&merged);
- return rc;
-}
-
-/* Implement optimize() function for FTS3. optimize(t) merges all
-** segments in the fts index into a single segment. 't' is the magic
-** table-named column.
-*/
-static void optimizeFunc(sqlite3_context *pContext,
- int argc, sqlite3_value **argv){
- fulltext_cursor *pCursor;
- if( argc>1 ){
- sqlite3_result_error(pContext, "excess arguments to optimize()",-1);
- }else if( sqlite3_value_type(argv[0])!=SQLITE_BLOB ||
- sqlite3_value_bytes(argv[0])!=sizeof(pCursor) ){
- sqlite3_result_error(pContext, "illegal first argument to optimize",-1);
- }else{
- fulltext_vtab *v;
- int i, rc, iMaxLevel;
- OptLeavesReader *readers;
- int nReaders;
- LeafWriter writer;
- sqlite3_stmt *s;
-
- memcpy(&pCursor, sqlite3_value_blob(argv[0]), sizeof(pCursor));
- v = cursor_vtab(pCursor);
-
- /* Flush any buffered updates before optimizing. */
- rc = flushPendingTerms(v);
- if( rc!=SQLITE_OK ) goto err;
-
- rc = segdir_count(v, &nReaders, &iMaxLevel);
- if( rc!=SQLITE_OK ) goto err;
- if( nReaders==0 || nReaders==1 ){
- sqlite3_result_text(pContext, "Index already optimal", -1,
- SQLITE_STATIC);
- return;
- }
-
- rc = sql_get_statement(v, SEGDIR_SELECT_ALL_STMT, &s);
- if( rc!=SQLITE_OK ) goto err;
-
- readers = sqlite3_malloc(nReaders*sizeof(readers[0]));
- if( readers==NULL ) goto err;
-
- /* Note that there will already be a segment at this position
- ** until we call segdir_delete() on iMaxLevel.
- */
- leafWriterInit(iMaxLevel, 0, &writer);
-
- i = 0;
- while( (rc = sqlite3_step(s))==SQLITE_ROW ){
- sqlite_int64 iStart = sqlite3_column_int64(s, 0);
- sqlite_int64 iEnd = sqlite3_column_int64(s, 1);
- const char *pRootData = sqlite3_column_blob(s, 2);
- int nRootData = sqlite3_column_bytes(s, 2);
-
- assert( i<nReaders );
- rc = leavesReaderInit(v, -1, iStart, iEnd, pRootData, nRootData,
- &readers[i].reader);
- if( rc!=SQLITE_OK ) break;
-
- readers[i].segment = i;
- i++;
- }
-
- /* If we managed to successfully read them all, optimize them. */
- if( rc==SQLITE_DONE ){
- assert( i==nReaders );
- rc = optimizeInternal(v, readers, nReaders, &writer);
- }
-
- while( i-- > 0 ){
- leavesReaderDestroy(&readers[i].reader);
- }
- sqlite3_free(readers);
-
- /* If we've successfully gotten to here, delete the old segments
- ** and flush the interior structure of the new segment.
- */
- if( rc==SQLITE_OK ){
- for( i=0; i<=iMaxLevel; i++ ){
- rc = segdir_delete(v, i);
- if( rc!=SQLITE_OK ) break;
- }
-
- if( rc==SQLITE_OK ) rc = leafWriterFinalize(v, &writer);
- }
-
- leafWriterDestroy(&writer);
-
- if( rc!=SQLITE_OK ) goto err;
-
- sqlite3_result_text(pContext, "Index optimized", -1, SQLITE_STATIC);
- return;
-
- /* TODO(shess): Error-handling needs to be improved along the
- ** lines of the dump_ functions.
- */
- err:
- {
- char buf[512];
- sqlite3_snprintf(sizeof(buf), buf, "Error in optimize: %s",
- sqlite3_errmsg(sqlite3_context_db_handle(pContext)));
- sqlite3_result_error(pContext, buf, -1);
- }
- }
-}
-
-#ifdef SQLITE_TEST
-/* Generate an error of the form "<prefix>: <msg>". If msg is NULL,
-** pull the error from the context's db handle.
-*/
-static void generateError(sqlite3_context *pContext,
- const char *prefix, const char *msg){
- char buf[512];
- if( msg==NULL ) msg = sqlite3_errmsg(sqlite3_context_db_handle(pContext));
- sqlite3_snprintf(sizeof(buf), buf, "%s: %s", prefix, msg);
- sqlite3_result_error(pContext, buf, -1);
-}
-
-/* Helper function to collect the set of terms in the segment into
-** pTerms. The segment is defined by the leaf nodes between
-** iStartBlockid and iEndBlockid, inclusive, or by the contents of
-** pRootData if iStartBlockid is 0 (in which case the entire segment
-** fit in a leaf).
-*/
-static int collectSegmentTerms(fulltext_vtab *v, sqlite3_stmt *s,
- fts3Hash *pTerms){
- const sqlite_int64 iStartBlockid = sqlite3_column_int64(s, 0);
- const sqlite_int64 iEndBlockid = sqlite3_column_int64(s, 1);
- const char *pRootData = sqlite3_column_blob(s, 2);
- const int nRootData = sqlite3_column_bytes(s, 2);
- LeavesReader reader;
- int rc = leavesReaderInit(v, 0, iStartBlockid, iEndBlockid,
- pRootData, nRootData, &reader);
- if( rc!=SQLITE_OK ) return rc;
-
- while( rc==SQLITE_OK && !leavesReaderAtEnd(&reader) ){
- const char *pTerm = leavesReaderTerm(&reader);
- const int nTerm = leavesReaderTermBytes(&reader);
- void *oldValue = sqlite3Fts3HashFind(pTerms, pTerm, nTerm);
- void *newValue = (void *)((char *)oldValue+1);
-
- /* From the comment before sqlite3Fts3HashInsert in fts3_hash.c,
- ** the data value passed is returned in case of malloc failure.
- */
- if( newValue==sqlite3Fts3HashInsert(pTerms, pTerm, nTerm, newValue) ){
- rc = SQLITE_NOMEM;
- }else{
- rc = leavesReaderStep(v, &reader);
- }
- }
-
- leavesReaderDestroy(&reader);
- return rc;
-}
-
-/* Helper function to build the result string for dump_terms(). */
-static int generateTermsResult(sqlite3_context *pContext, fts3Hash *pTerms){
- int iTerm, nTerms, nResultBytes, iByte;
- char *result;
- TermData *pData;
- fts3HashElem *e;
-
- /* Iterate pTerms to generate an array of terms in pData for
- ** sorting.
- */
- nTerms = fts3HashCount(pTerms);
- assert( nTerms>0 );
- pData = sqlite3_malloc(nTerms*sizeof(TermData));
- if( pData==NULL ) return SQLITE_NOMEM;
-
- nResultBytes = 0;
- for(iTerm = 0, e = fts3HashFirst(pTerms); e; iTerm++, e = fts3HashNext(e)){
- nResultBytes += fts3HashKeysize(e)+1; /* Term plus trailing space */
- assert( iTerm<nTerms );
- pData[iTerm].pTerm = fts3HashKey(e);
- pData[iTerm].nTerm = fts3HashKeysize(e);
- pData[iTerm].pCollector = fts3HashData(e); /* unused */
- }
- assert( iTerm==nTerms );
-
- assert( nResultBytes>0 ); /* nTerms>0, nResultsBytes must be, too. */
- result = sqlite3_malloc(nResultBytes);
- if( result==NULL ){
- sqlite3_free(pData);
- return SQLITE_NOMEM;
- }
-
- if( nTerms>1 ) qsort(pData, nTerms, sizeof(*pData), termDataCmp);
-
- /* Read the terms in order to build the result. */
- iByte = 0;
- for(iTerm=0; iTerm<nTerms; ++iTerm){
- memcpy(result+iByte, pData[iTerm].pTerm, pData[iTerm].nTerm);
- iByte += pData[iTerm].nTerm;
- result[iByte++] = ' ';
- }
- assert( iByte==nResultBytes );
- assert( result[nResultBytes-1]==' ' );
- result[nResultBytes-1] = '\0';
-
- /* Passes away ownership of result. */
- sqlite3_result_text(pContext, result, nResultBytes-1, sqlite3_free);
- sqlite3_free(pData);
- return SQLITE_OK;
-}
-
-/* Implements dump_terms() for use in inspecting the fts3 index from
-** tests. TEXT result containing the ordered list of terms joined by
-** spaces. dump_terms(t, level, idx) dumps the terms for the segment
-** specified by level, idx (in %_segdir), while dump_terms(t) dumps
-** all terms in the index. In both cases t is the fts table's magic
-** table-named column.
-*/
-static void dumpTermsFunc(
- sqlite3_context *pContext,
- int argc, sqlite3_value **argv
-){
- fulltext_cursor *pCursor;
- if( argc!=3 && argc!=1 ){
- generateError(pContext, "dump_terms", "incorrect arguments");
- }else if( sqlite3_value_type(argv[0])!=SQLITE_BLOB ||
- sqlite3_value_bytes(argv[0])!=sizeof(pCursor) ){
- generateError(pContext, "dump_terms", "illegal first argument");
- }else{
- fulltext_vtab *v;
- fts3Hash terms;
- sqlite3_stmt *s = NULL;
- int rc;
-
- memcpy(&pCursor, sqlite3_value_blob(argv[0]), sizeof(pCursor));
- v = cursor_vtab(pCursor);
-
- /* If passed only the cursor column, get all segments. Otherwise
- ** get the segment described by the following two arguments.
- */
- if( argc==1 ){
- rc = sql_get_statement(v, SEGDIR_SELECT_ALL_STMT, &s);
- }else{
- rc = sql_get_statement(v, SEGDIR_SELECT_SEGMENT_STMT, &s);
- if( rc==SQLITE_OK ){
- rc = sqlite3_bind_int(s, 1, sqlite3_value_int(argv[1]));
- if( rc==SQLITE_OK ){
- rc = sqlite3_bind_int(s, 2, sqlite3_value_int(argv[2]));
- }
- }
- }
-
- if( rc!=SQLITE_OK ){
- generateError(pContext, "dump_terms", NULL);
- return;
- }
-
- /* Collect the terms for each segment. */
- sqlite3Fts3HashInit(&terms, FTS3_HASH_STRING, 1);
- while( (rc = sqlite3_step(s))==SQLITE_ROW ){
- rc = collectSegmentTerms(v, s, &terms);
- if( rc!=SQLITE_OK ) break;
- }
-
- if( rc!=SQLITE_DONE ){
- sqlite3_reset(s);
- generateError(pContext, "dump_terms", NULL);
- }else{
- const int nTerms = fts3HashCount(&terms);
- if( nTerms>0 ){
- rc = generateTermsResult(pContext, &terms);
- if( rc==SQLITE_NOMEM ){
- generateError(pContext, "dump_terms", "out of memory");
- }else{
- assert( rc==SQLITE_OK );
- }
- }else if( argc==3 ){
- /* The specific segment asked for could not be found. */
- generateError(pContext, "dump_terms", "segment not found");
- }else{
- /* No segments found. */
- /* TODO(shess): It should be impossible to reach this. This
- ** case can only happen for an empty table, in which case
- ** SQLite has no rows to call this function on.
- */
- sqlite3_result_null(pContext);
- }
- }
- sqlite3Fts3HashClear(&terms);
- }
-}
-
-/* Expand the DL_DEFAULT doclist in pData into a text result in
-** pContext.
-*/
-static void createDoclistResult(sqlite3_context *pContext,
- const char *pData, int nData){
- DataBuffer dump;
- DLReader dlReader;
-
- assert( pData!=NULL && nData>0 );
-
- dataBufferInit(&dump, 0);
- dlrInit(&dlReader, DL_DEFAULT, pData, nData);
- for( ; !dlrAtEnd(&dlReader); dlrStep(&dlReader) ){
- char buf[256];
- PLReader plReader;
-
- plrInit(&plReader, &dlReader);
- if( DL_DEFAULT==DL_DOCIDS || plrAtEnd(&plReader) ){
- sqlite3_snprintf(sizeof(buf), buf, "[%lld] ", dlrDocid(&dlReader));
- dataBufferAppend(&dump, buf, strlen(buf));
- }else{
- int iColumn = plrColumn(&plReader);
-
- sqlite3_snprintf(sizeof(buf), buf, "[%lld %d[",
- dlrDocid(&dlReader), iColumn);
- dataBufferAppend(&dump, buf, strlen(buf));
-
- for( ; !plrAtEnd(&plReader); plrStep(&plReader) ){
- if( plrColumn(&plReader)!=iColumn ){
- iColumn = plrColumn(&plReader);
- sqlite3_snprintf(sizeof(buf), buf, "] %d[", iColumn);
- assert( dump.nData>0 );
- dump.nData--; /* Overwrite trailing space. */
- assert( dump.pData[dump.nData]==' ');
- dataBufferAppend(&dump, buf, strlen(buf));
- }
- if( DL_DEFAULT==DL_POSITIONS_OFFSETS ){
- sqlite3_snprintf(sizeof(buf), buf, "%d,%d,%d ",
- plrPosition(&plReader),
- plrStartOffset(&plReader), plrEndOffset(&plReader));
- }else if( DL_DEFAULT==DL_POSITIONS ){
- sqlite3_snprintf(sizeof(buf), buf, "%d ", plrPosition(&plReader));
- }else{
- assert( NULL=="Unhandled DL_DEFAULT value");
- }
- dataBufferAppend(&dump, buf, strlen(buf));
- }
- plrDestroy(&plReader);
-
- assert( dump.nData>0 );
- dump.nData--; /* Overwrite trailing space. */
- assert( dump.pData[dump.nData]==' ');
- dataBufferAppend(&dump, "]] ", 3);
- }
- }
- dlrDestroy(&dlReader);
-
- assert( dump.nData>0 );
- dump.nData--; /* Overwrite trailing space. */
- assert( dump.pData[dump.nData]==' ');
- dump.pData[dump.nData] = '\0';
- assert( dump.nData>0 );
-
- /* Passes ownership of dump's buffer to pContext. */
- sqlite3_result_text(pContext, dump.pData, dump.nData, sqlite3_free);
- dump.pData = NULL;
- dump.nData = dump.nCapacity = 0;
-}
-
-/* Implements dump_doclist() for use in inspecting the fts3 index from
-** tests. TEXT result containing a string representation of the
-** doclist for the indicated term. dump_doclist(t, term, level, idx)
-** dumps the doclist for term from the segment specified by level, idx
-** (in %_segdir), while dump_doclist(t, term) dumps the logical
-** doclist for the term across all segments. The per-segment doclist
-** can contain deletions, while the full-index doclist will not
-** (deletions are omitted).
-**
-** Result formats differ with the setting of DL_DEFAULTS. Examples:
-**
-** DL_DOCIDS: [1] [3] [7]
-** DL_POSITIONS: [1 0[0 4] 1[17]] [3 1[5]]
-** DL_POSITIONS_OFFSETS: [1 0[0,0,3 4,23,26] 1[17,102,105]] [3 1[5,20,23]]
-**
-** In each case the number after the outer '[' is the docid. In the
-** latter two cases, the number before the inner '[' is the column
-** associated with the values within. For DL_POSITIONS the numbers
-** within are the positions, for DL_POSITIONS_OFFSETS they are the
-** position, the start offset, and the end offset.
-*/
-static void dumpDoclistFunc(
- sqlite3_context *pContext,
- int argc, sqlite3_value **argv
-){
- fulltext_cursor *pCursor;
- if( argc!=2 && argc!=4 ){
- generateError(pContext, "dump_doclist", "incorrect arguments");
- }else if( sqlite3_value_type(argv[0])!=SQLITE_BLOB ||
- sqlite3_value_bytes(argv[0])!=sizeof(pCursor) ){
- generateError(pContext, "dump_doclist", "illegal first argument");
- }else if( sqlite3_value_text(argv[1])==NULL ||
- sqlite3_value_text(argv[1])[0]=='\0' ){
- generateError(pContext, "dump_doclist", "empty second argument");
- }else{
- const char *pTerm = (const char *)sqlite3_value_text(argv[1]);
- const int nTerm = strlen(pTerm);
- fulltext_vtab *v;
- int rc;
- DataBuffer doclist;
-
- memcpy(&pCursor, sqlite3_value_blob(argv[0]), sizeof(pCursor));
- v = cursor_vtab(pCursor);
-
- dataBufferInit(&doclist, 0);
-
- /* termSelect() yields the same logical doclist that queries are
- ** run against.
- */
- if( argc==2 ){
- rc = termSelect(v, v->nColumn, pTerm, nTerm, 0, DL_DEFAULT, &doclist);
- }else{
- sqlite3_stmt *s = NULL;
-
- /* Get our specific segment's information. */
- rc = sql_get_statement(v, SEGDIR_SELECT_SEGMENT_STMT, &s);
- if( rc==SQLITE_OK ){
- rc = sqlite3_bind_int(s, 1, sqlite3_value_int(argv[2]));
- if( rc==SQLITE_OK ){
- rc = sqlite3_bind_int(s, 2, sqlite3_value_int(argv[3]));
- }
- }
-
- if( rc==SQLITE_OK ){
- rc = sqlite3_step(s);
-
- if( rc==SQLITE_DONE ){
- dataBufferDestroy(&doclist);
- generateError(pContext, "dump_doclist", "segment not found");
- return;
- }
-
- /* Found a segment, load it into doclist. */
- if( rc==SQLITE_ROW ){
- const sqlite_int64 iLeavesEnd = sqlite3_column_int64(s, 1);
- const char *pData = sqlite3_column_blob(s, 2);
- const int nData = sqlite3_column_bytes(s, 2);
-
- /* loadSegment() is used by termSelect() to load each
- ** segment's data.
- */
- rc = loadSegment(v, pData, nData, iLeavesEnd, pTerm, nTerm, 0,
- &doclist);
- if( rc==SQLITE_OK ){
- rc = sqlite3_step(s);
-
- /* Should not have more than one matching segment. */
- if( rc!=SQLITE_DONE ){
- sqlite3_reset(s);
- dataBufferDestroy(&doclist);
- generateError(pContext, "dump_doclist", "invalid segdir");
- return;
- }
- rc = SQLITE_OK;
- }
- }
- }
-
- sqlite3_reset(s);
- }
-
- if( rc==SQLITE_OK ){
- if( doclist.nData>0 ){
- createDoclistResult(pContext, doclist.pData, doclist.nData);
- }else{
- /* TODO(shess): This can happen if the term is not present, or
- ** if all instances of the term have been deleted and this is
- ** an all-index dump. It may be interesting to distinguish
- ** these cases.
- */
- sqlite3_result_text(pContext, "", 0, SQLITE_STATIC);
- }
- }else if( rc==SQLITE_NOMEM ){
- /* Handle out-of-memory cases specially because if they are
- ** generated in fts3 code they may not be reflected in the db
- ** handle.
- */
- /* TODO(shess): Handle this more comprehensively.
- ** sqlite3ErrStr() has what I need, but is internal.
- */
- generateError(pContext, "dump_doclist", "out of memory");
- }else{
- generateError(pContext, "dump_doclist", NULL);
- }
-
- dataBufferDestroy(&doclist);
- }
-}
-#endif
-
-/*
-** This routine implements the xFindFunction method for the FTS3
-** virtual table.
-*/
-static int fulltextFindFunction(
- sqlite3_vtab *pVtab,
- int nArg,
- const char *zName,
- void (**pxFunc)(sqlite3_context*,int,sqlite3_value**),
- void **ppArg
-){
- if( strcmp(zName,"snippet")==0 ){
- *pxFunc = snippetFunc;
- return 1;
- }else if( strcmp(zName,"offsets")==0 ){
- *pxFunc = snippetOffsetsFunc;
- return 1;
- }else if( strcmp(zName,"optimize")==0 ){
- *pxFunc = optimizeFunc;
- return 1;
-#ifdef SQLITE_TEST
- /* NOTE(shess): These functions are present only for testing
- ** purposes. No particular effort is made to optimize their
- ** execution or how they build their results.
- */
- }else if( strcmp(zName,"dump_terms")==0 ){
- /* fprintf(stderr, "Found dump_terms\n"); */
- *pxFunc = dumpTermsFunc;
- return 1;
- }else if( strcmp(zName,"dump_doclist")==0 ){
- /* fprintf(stderr, "Found dump_doclist\n"); */
- *pxFunc = dumpDoclistFunc;
- return 1;
-#endif
- }
- return 0;
-}
-
-/*
-** Rename an fts3 table.
-*/
-static int fulltextRename(
- sqlite3_vtab *pVtab,
- const char *zName
-){
- fulltext_vtab *p = (fulltext_vtab *)pVtab;
- int rc = SQLITE_NOMEM;
- char *zSql = sqlite3_mprintf(
- "ALTER TABLE %Q.'%q_content' RENAME TO '%q_content';"
- "ALTER TABLE %Q.'%q_segments' RENAME TO '%q_segments';"
- "ALTER TABLE %Q.'%q_segdir' RENAME TO '%q_segdir';"
- , p->zDb, p->zName, zName
- , p->zDb, p->zName, zName
- , p->zDb, p->zName, zName
- );
- if( zSql ){
- rc = sqlite3_exec(p->db, zSql, 0, 0, 0);
- sqlite3_free(zSql);
- }
- return rc;
-}
-
-static const sqlite3_module fts3Module = {
- /* iVersion */ 0,
- /* xCreate */ fulltextCreate,
- /* xConnect */ fulltextConnect,
- /* xBestIndex */ fulltextBestIndex,
- /* xDisconnect */ fulltextDisconnect,
- /* xDestroy */ fulltextDestroy,
- /* xOpen */ fulltextOpen,
- /* xClose */ fulltextClose,
- /* xFilter */ fulltextFilter,
- /* xNext */ fulltextNext,
- /* xEof */ fulltextEof,
- /* xColumn */ fulltextColumn,
- /* xRowid */ fulltextRowid,
- /* xUpdate */ fulltextUpdate,
- /* xBegin */ fulltextBegin,
- /* xSync */ fulltextSync,
- /* xCommit */ fulltextCommit,
- /* xRollback */ fulltextRollback,
- /* xFindFunction */ fulltextFindFunction,
- /* xRename */ fulltextRename,
-};
-
-static void hashDestroy(void *p){
- fts3Hash *pHash = (fts3Hash *)p;
- sqlite3Fts3HashClear(pHash);
- sqlite3_free(pHash);
-}
-
-/*
-** The fts3 built-in tokenizers - "simple" and "porter" - are implemented
-** in files fts3_tokenizer1.c and fts3_porter.c respectively. The following
-** two forward declarations are for functions declared in these files
-** used to retrieve the respective implementations.
-**
-** Calling sqlite3Fts3SimpleTokenizerModule() sets the value pointed
-** to by the argument to point a the "simple" tokenizer implementation.
-** Function ...PorterTokenizerModule() sets *pModule to point to the
-** porter tokenizer/stemmer implementation.
-*/
-SQLITE_PRIVATE void sqlite3Fts3SimpleTokenizerModule(sqlite3_tokenizer_module const**ppModule);
-SQLITE_PRIVATE void sqlite3Fts3PorterTokenizerModule(sqlite3_tokenizer_module const**ppModule);
-SQLITE_PRIVATE void sqlite3Fts3IcuTokenizerModule(sqlite3_tokenizer_module const**ppModule);
-
-SQLITE_PRIVATE int sqlite3Fts3InitHashTable(sqlite3 *, fts3Hash *, const char *);
-
-/*
-** Initialise the fts3 extension. If this extension is built as part
-** of the sqlite library, then this function is called directly by
-** SQLite. If fts3 is built as a dynamically loadable extension, this
-** function is called by the sqlite3_extension_init() entry point.
-*/
-SQLITE_PRIVATE int sqlite3Fts3Init(sqlite3 *db){
- int rc = SQLITE_OK;
- fts3Hash *pHash = 0;
- const sqlite3_tokenizer_module *pSimple = 0;
- const sqlite3_tokenizer_module *pPorter = 0;
- const sqlite3_tokenizer_module *pIcu = 0;
-
- sqlite3Fts3SimpleTokenizerModule(&pSimple);
- sqlite3Fts3PorterTokenizerModule(&pPorter);
-#ifdef SQLITE_ENABLE_ICU
- sqlite3Fts3IcuTokenizerModule(&pIcu);
-#endif
-
- /* Allocate and initialise the hash-table used to store tokenizers. */
- pHash = sqlite3_malloc(sizeof(fts3Hash));
- if( !pHash ){
- rc = SQLITE_NOMEM;
- }else{
- sqlite3Fts3HashInit(pHash, FTS3_HASH_STRING, 1);
- }
-
- /* Load the built-in tokenizers into the hash table */
- if( rc==SQLITE_OK ){
- if( sqlite3Fts3HashInsert(pHash, "simple", 7, (void *)pSimple)
- || sqlite3Fts3HashInsert(pHash, "porter", 7, (void *)pPorter)
- || (pIcu && sqlite3Fts3HashInsert(pHash, "icu", 4, (void *)pIcu))
- ){
- rc = SQLITE_NOMEM;
- }
- }
-
-#ifdef SQLITE_TEST
- sqlite3Fts3ExprInitTestInterface(db);
-#endif
-
- /* Create the virtual table wrapper around the hash-table and overload
- ** the two scalar functions. If this is successful, register the
- ** module with sqlite.
- */
- if( SQLITE_OK==rc
- && SQLITE_OK==(rc = sqlite3Fts3InitHashTable(db, pHash, "fts3_tokenizer"))
- && SQLITE_OK==(rc = sqlite3_overload_function(db, "snippet", -1))
- && SQLITE_OK==(rc = sqlite3_overload_function(db, "offsets", -1))
- && SQLITE_OK==(rc = sqlite3_overload_function(db, "optimize", -1))
-#ifdef SQLITE_TEST
- && SQLITE_OK==(rc = sqlite3_overload_function(db, "dump_terms", -1))
- && SQLITE_OK==(rc = sqlite3_overload_function(db, "dump_doclist", -1))
-#endif
- ){
- return sqlite3_create_module_v2(
- db, "fts3", &fts3Module, (void *)pHash, hashDestroy
- );
- }
-
- /* An error has occurred. Delete the hash table and return the error code. */
- assert( rc!=SQLITE_OK );
- if( pHash ){
- sqlite3Fts3HashClear(pHash);
- sqlite3_free(pHash);
- }
- return rc;
-}
-
-#if !SQLITE_CORE
-SQLITE_API int sqlite3_extension_init(
- sqlite3 *db,
- char **pzErrMsg,
- const sqlite3_api_routines *pApi
-){
- SQLITE_EXTENSION_INIT2(pApi)
- return sqlite3Fts3Init(db);
-}
-#endif
-
-#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */
-
-/************** End of fts3.c ************************************************/
-/************** Begin file fts3_expr.c ***************************************/
-/*
-** 2008 Nov 28
-**
-** 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 module contains code that implements a parser for fts3 query strings
-** (the right-hand argument to the MATCH operator). Because the supported
-** syntax is relatively simple, the whole tokenizer/parser system is
-** hand-coded. The public interface to this module is declared in source
-** code file "fts3_expr.h".
-*/
-#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3)
-
-/*
-** By default, this module parses the legacy syntax that has been
-** traditionally used by fts3. Or, if SQLITE_ENABLE_FTS3_PARENTHESIS
-** is defined, then it uses the new syntax. The differences between
-** the new and the old syntaxes are:
-**
-** a) The new syntax supports parenthesis. The old does not.
-**
-** b) The new syntax supports the AND and NOT operators. The old does not.
-**
-** c) The old syntax supports the "-" token qualifier. This is not
-** supported by the new syntax (it is replaced by the NOT operator).
-**
-** d) When using the old syntax, the OR operator has a greater precedence
-** than an implicit AND. When using the new, both implicity and explicit
-** AND operators have a higher precedence than OR.
-**
-** If compiled with SQLITE_TEST defined, then this module exports the
-** symbol "int sqlite3_fts3_enable_parentheses". Setting this variable
-** to zero causes the module to use the old syntax. If it is set to
-** non-zero the new syntax is activated. This is so both syntaxes can
-** be tested using a single build of testfixture.
-*/
-#ifdef SQLITE_TEST
-SQLITE_API int sqlite3_fts3_enable_parentheses = 0;
-#else
-# ifdef SQLITE_ENABLE_FTS3_PARENTHESIS
-# define sqlite3_fts3_enable_parentheses 1
-# else
-# define sqlite3_fts3_enable_parentheses 0
-# endif
-#endif
-
-/*
-** Default span for NEAR operators.
-*/
-#define SQLITE_FTS3_DEFAULT_NEAR_PARAM 10
-
-
-typedef struct ParseContext ParseContext;
-struct ParseContext {
- sqlite3_tokenizer *pTokenizer; /* Tokenizer module */
- const char **azCol; /* Array of column names for fts3 table */
- int nCol; /* Number of entries in azCol[] */
- int iDefaultCol; /* Default column to query */
- sqlite3_context *pCtx; /* Write error message here */
- int nNest; /* Number of nested brackets */
-};
-
-/*
-** This function is equivalent to the standard isspace() function.
-**
-** The standard isspace() can be awkward to use safely, because although it
-** is defined to accept an argument of type int, its behaviour when passed
-** an integer that falls outside of the range of the unsigned char type
-** is undefined (and sometimes, "undefined" means segfault). This wrapper
-** is defined to accept an argument of type char, and always returns 0 for
-** any values that fall outside of the range of the unsigned char type (i.e.
-** negative values).
-*/
-static int fts3isspace(char c){
- return (c&0x80)==0 ? isspace(c) : 0;
-}
-
-/*
-** Extract the next token from buffer z (length n) using the tokenizer
-** and other information (column names etc.) in pParse. Create an Fts3Expr
-** structure of type FTSQUERY_PHRASE containing a phrase consisting of this
-** single token and set *ppExpr to point to it. If the end of the buffer is
-** reached before a token is found, set *ppExpr to zero. It is the
-** responsibility of the caller to eventually deallocate the allocated
-** Fts3Expr structure (if any) by passing it to sqlite3_free().
-**
-** Return SQLITE_OK if successful, or SQLITE_NOMEM if a memory allocation
-** fails.
-*/
-static int getNextToken(
- ParseContext *pParse, /* fts3 query parse context */
- int iCol, /* Value for Fts3Phrase.iColumn */
- const char *z, int n, /* Input string */
- Fts3Expr **ppExpr, /* OUT: expression */
- int *pnConsumed /* OUT: Number of bytes consumed */
-){
- sqlite3_tokenizer *pTokenizer = pParse->pTokenizer;
- sqlite3_tokenizer_module const *pModule = pTokenizer->pModule;
- int rc;
- sqlite3_tokenizer_cursor *pCursor;
- Fts3Expr *pRet = 0;
- int nConsumed = 0;
-
- rc = pModule->xOpen(pTokenizer, z, n, &pCursor);
- if( rc==SQLITE_OK ){
- const char *zToken;
- int nToken, iStart, iEnd, iPosition;
- int nByte; /* total space to allocate */
-
- pCursor->pTokenizer = pTokenizer;
- rc = pModule->xNext(pCursor, &zToken, &nToken, &iStart, &iEnd, &iPosition);
-
- if( rc==SQLITE_OK ){
- nByte = sizeof(Fts3Expr) + sizeof(Fts3Phrase) + nToken;
- pRet = (Fts3Expr *)sqlite3_malloc(nByte);
- if( !pRet ){
- rc = SQLITE_NOMEM;
- }else{
- memset(pRet, 0, nByte);
- pRet->eType = FTSQUERY_PHRASE;
- pRet->pPhrase = (Fts3Phrase *)&pRet[1];
- pRet->pPhrase->nToken = 1;
- pRet->pPhrase->iColumn = iCol;
- pRet->pPhrase->aToken[0].n = nToken;
- pRet->pPhrase->aToken[0].z = (char *)&pRet->pPhrase[1];
- memcpy(pRet->pPhrase->aToken[0].z, zToken, nToken);
-
- if( iEnd<n && z[iEnd]=='*' ){
- pRet->pPhrase->aToken[0].isPrefix = 1;
- iEnd++;
- }
- if( !sqlite3_fts3_enable_parentheses && iStart>0 && z[iStart-1]=='-' ){
- pRet->pPhrase->isNot = 1;
- }
- }
- nConsumed = iEnd;
- }
-
- pModule->xClose(pCursor);
- }
-
- *pnConsumed = nConsumed;
- *ppExpr = pRet;
- return rc;
-}
-
-
-/*
-** Enlarge a memory allocation. If an out-of-memory allocation occurs,
-** then free the old allocation.
-*/
-void *fts3ReallocOrFree(void *pOrig, int nNew){
- void *pRet = sqlite3_realloc(pOrig, nNew);
- if( !pRet ){
- sqlite3_free(pOrig);
- }
- return pRet;
-}
-
-/*
-** Buffer zInput, length nInput, contains the contents of a quoted string
-** that appeared as part of an fts3 query expression. Neither quote character
-** is included in the buffer. This function attempts to tokenize the entire
-** input buffer and create an Fts3Expr structure of type FTSQUERY_PHRASE
-** containing the results.
-**
-** If successful, SQLITE_OK is returned and *ppExpr set to point at the
-** allocated Fts3Expr structure. Otherwise, either SQLITE_NOMEM (out of memory
-** error) or SQLITE_ERROR (tokenization error) is returned and *ppExpr set
-** to 0.
-*/
-static int getNextString(
- ParseContext *pParse, /* fts3 query parse context */
- const char *zInput, int nInput, /* Input string */
- Fts3Expr **ppExpr /* OUT: expression */
-){
- sqlite3_tokenizer *pTokenizer = pParse->pTokenizer;
- sqlite3_tokenizer_module const *pModule = pTokenizer->pModule;
- int rc;
- Fts3Expr *p = 0;
- sqlite3_tokenizer_cursor *pCursor = 0;
- char *zTemp = 0;
- int nTemp = 0;
-
- rc = pModule->xOpen(pTokenizer, zInput, nInput, &pCursor);
- if( rc==SQLITE_OK ){
- int ii;
- pCursor->pTokenizer = pTokenizer;
- for(ii=0; rc==SQLITE_OK; ii++){
- const char *zToken;
- int nToken, iBegin, iEnd, iPos;
- rc = pModule->xNext(pCursor, &zToken, &nToken, &iBegin, &iEnd, &iPos);
- if( rc==SQLITE_OK ){
- int nByte = sizeof(Fts3Expr) + sizeof(Fts3Phrase);
- p = fts3ReallocOrFree(p, nByte+ii*sizeof(struct PhraseToken));
- zTemp = fts3ReallocOrFree(zTemp, nTemp + nToken);
- if( !p || !zTemp ){
- goto no_mem;
- }
- if( ii==0 ){
- memset(p, 0, nByte);
- p->pPhrase = (Fts3Phrase *)&p[1];
- }
- p->pPhrase = (Fts3Phrase *)&p[1];
- p->pPhrase->nToken = ii+1;
- p->pPhrase->aToken[ii].n = nToken;
- memcpy(&zTemp[nTemp], zToken, nToken);
- nTemp += nToken;
- if( iEnd<nInput && zInput[iEnd]=='*' ){
- p->pPhrase->aToken[ii].isPrefix = 1;
- }else{
- p->pPhrase->aToken[ii].isPrefix = 0;
- }
- }
- }
-
- pModule->xClose(pCursor);
- pCursor = 0;
- }
-
- if( rc==SQLITE_DONE ){
- int jj;
- char *zNew;
- int nNew = 0;
- int nByte = sizeof(Fts3Expr) + sizeof(Fts3Phrase);
- nByte += (p?(p->pPhrase->nToken-1):0) * sizeof(struct PhraseToken);
- p = fts3ReallocOrFree(p, nByte + nTemp);
- if( !p ){
- goto no_mem;
- }
- if( zTemp ){
- zNew = &(((char *)p)[nByte]);
- memcpy(zNew, zTemp, nTemp);
- }else{
- memset(p, 0, nByte+nTemp);
- }
- p->pPhrase = (Fts3Phrase *)&p[1];
- for(jj=0; jj<p->pPhrase->nToken; jj++){
- p->pPhrase->aToken[jj].z = &zNew[nNew];
- nNew += p->pPhrase->aToken[jj].n;
- }
- sqlite3_free(zTemp);
- p->eType = FTSQUERY_PHRASE;
- p->pPhrase->iColumn = pParse->iDefaultCol;
- rc = SQLITE_OK;
- }
-
- *ppExpr = p;
- return rc;
-no_mem:
-
- if( pCursor ){
- pModule->xClose(pCursor);
- }
- sqlite3_free(zTemp);
- sqlite3_free(p);
- *ppExpr = 0;
- return SQLITE_NOMEM;
-}
-
-/*
-** Function getNextNode(), which is called by fts3ExprParse(), may itself
-** call fts3ExprParse(). So this forward declaration is required.
-*/
-static int fts3ExprParse(ParseContext *, const char *, int, Fts3Expr **, int *);
-
-/*
-** The output variable *ppExpr is populated with an allocated Fts3Expr
-** structure, or set to 0 if the end of the input buffer is reached.
-**
-** Returns an SQLite error code. SQLITE_OK if everything works, SQLITE_NOMEM
-** if a malloc failure occurs, or SQLITE_ERROR if a parse error is encountered.
-** If SQLITE_ERROR is returned, pContext is populated with an error message.
-*/
-static int getNextNode(
- ParseContext *pParse, /* fts3 query parse context */
- const char *z, int n, /* Input string */
- Fts3Expr **ppExpr, /* OUT: expression */
- int *pnConsumed /* OUT: Number of bytes consumed */
-){
- static const struct Fts3Keyword {
- char z[4]; /* Keyword text */
- unsigned char n; /* Length of the keyword */
- unsigned char parenOnly; /* Only valid in paren mode */
- unsigned char eType; /* Keyword code */
- } aKeyword[] = {
- { "OR" , 2, 0, FTSQUERY_OR },
- { "AND", 3, 1, FTSQUERY_AND },
- { "NOT", 3, 1, FTSQUERY_NOT },
- { "NEAR", 4, 0, FTSQUERY_NEAR }
- };
- int ii;
- int iCol;
- int iColLen;
- int rc;
- Fts3Expr *pRet = 0;
-
- const char *zInput = z;
- int nInput = n;
-
- /* Skip over any whitespace before checking for a keyword, an open or
- ** close bracket, or a quoted string.
- */
- while( nInput>0 && fts3isspace(*zInput) ){
- nInput--;
- zInput++;
- }
- if( nInput==0 ){
- return SQLITE_DONE;
- }
-
- /* See if we are dealing with a keyword. */
- for(ii=0; ii<(int)(sizeof(aKeyword)/sizeof(struct Fts3Keyword)); ii++){
- const struct Fts3Keyword *pKey = &aKeyword[ii];
-
- if( (pKey->parenOnly & ~sqlite3_fts3_enable_parentheses)!=0 ){
- continue;
- }
-
- if( nInput>=pKey->n && 0==memcmp(zInput, pKey->z, pKey->n) ){
- int nNear = SQLITE_FTS3_DEFAULT_NEAR_PARAM;
- int nKey = pKey->n;
- char cNext;
-
- /* If this is a "NEAR" keyword, check for an explicit nearness. */
- if( pKey->eType==FTSQUERY_NEAR ){
- assert( nKey==4 );
- if( zInput[4]=='/' && zInput[5]>='0' && zInput[5]<='9' ){
- nNear = 0;
- for(nKey=5; zInput[nKey]>='0' && zInput[nKey]<='9'; nKey++){
- nNear = nNear * 10 + (zInput[nKey] - '0');
- }
- }
- }
-
- /* At this point this is probably a keyword. But for that to be true,
- ** the next byte must contain either whitespace, an open or close
- ** parenthesis, a quote character, or EOF.
- */
- cNext = zInput[nKey];
- if( fts3isspace(cNext)
- || cNext=='"' || cNext=='(' || cNext==')' || cNext==0
- ){
- pRet = (Fts3Expr *)sqlite3_malloc(sizeof(Fts3Expr));
- memset(pRet, 0, sizeof(Fts3Expr));
- pRet->eType = pKey->eType;
- pRet->nNear = nNear;
- *ppExpr = pRet;
- *pnConsumed = (zInput - z) + nKey;
- return SQLITE_OK;
- }
-
- /* Turns out that wasn't a keyword after all. This happens if the
- ** user has supplied a token such as "ORacle". Continue.
- */
- }
- }
-
- /* Check for an open bracket. */
- if( sqlite3_fts3_enable_parentheses ){
- if( *zInput=='(' ){
- int nConsumed;
- int rc;
- pParse->nNest++;
- rc = fts3ExprParse(pParse, &zInput[1], nInput-1, ppExpr, &nConsumed);
- if( rc==SQLITE_OK && !*ppExpr ){
- rc = SQLITE_DONE;
- }
- *pnConsumed = (zInput - z) + 1 + nConsumed;
- return rc;
- }
-
- /* Check for a close bracket. */
- if( *zInput==')' ){
- pParse->nNest--;
- *pnConsumed = (zInput - z) + 1;
- return SQLITE_DONE;
- }
- }
-
- /* See if we are dealing with a quoted phrase. If this is the case, then
- ** search for the closing quote and pass the whole string to getNextString()
- ** for processing. This is easy to do, as fts3 has no syntax for escaping
- ** a quote character embedded in a string.
- */
- if( *zInput=='"' ){
- for(ii=1; ii<nInput && zInput[ii]!='"'; ii++);
- *pnConsumed = (zInput - z) + ii + 1;
- if( ii==nInput ){
- return SQLITE_ERROR;
- }
- return getNextString(pParse, &zInput[1], ii-1, ppExpr);
- }
-
-
- /* If control flows to this point, this must be a regular token, or
- ** the end of the input. Read a regular token using the sqlite3_tokenizer
- ** interface. Before doing so, figure out if there is an explicit
- ** column specifier for the token.
- **
- ** TODO: Strangely, it is not possible to associate a column specifier
- ** with a quoted phrase, only with a single token. Not sure if this was
- ** an implementation artifact or an intentional decision when fts3 was
- ** first implemented. Whichever it was, this module duplicates the
- ** limitation.
- */
- iCol = pParse->iDefaultCol;
- iColLen = 0;
- for(ii=0; ii<pParse->nCol; ii++){
- const char *zStr = pParse->azCol[ii];
- int nStr = strlen(zStr);
- if( nInput>nStr && zInput[nStr]==':'
- && sqlite3_strnicmp(zStr, zInput, nStr)==0
- ){
- iCol = ii;
- iColLen = ((zInput - z) + nStr + 1);
- break;
- }
- }
- rc = getNextToken(pParse, iCol, &z[iColLen], n-iColLen, ppExpr, pnConsumed);
- *pnConsumed += iColLen;
- return rc;
-}
-
-/*
-** The argument is an Fts3Expr structure for a binary operator (any type
-** except an FTSQUERY_PHRASE). Return an integer value representing the
-** precedence of the operator. Lower values have a higher precedence (i.e.
-** group more tightly). For example, in the C language, the == operator
-** groups more tightly than ||, and would therefore have a higher precedence.
-**
-** When using the new fts3 query syntax (when SQLITE_ENABLE_FTS3_PARENTHESIS
-** is defined), the order of the operators in precedence from highest to
-** lowest is:
-**
-** NEAR
-** NOT
-** AND (including implicit ANDs)
-** OR
-**
-** Note that when using the old query syntax, the OR operator has a higher
-** precedence than the AND operator.
-*/
-static int opPrecedence(Fts3Expr *p){
- assert( p->eType!=FTSQUERY_PHRASE );
- if( sqlite3_fts3_enable_parentheses ){
- return p->eType;
- }else if( p->eType==FTSQUERY_NEAR ){
- return 1;
- }else if( p->eType==FTSQUERY_OR ){
- return 2;
- }
- assert( p->eType==FTSQUERY_AND );
- return 3;
-}
-
-/*
-** Argument ppHead contains a pointer to the current head of a query
-** expression tree being parsed. pPrev is the expression node most recently
-** inserted into the tree. This function adds pNew, which is always a binary
-** operator node, into the expression tree based on the relative precedence
-** of pNew and the existing nodes of the tree. This may result in the head
-** of the tree changing, in which case *ppHead is set to the new root node.
-*/
-static void insertBinaryOperator(
- Fts3Expr **ppHead, /* Pointer to the root node of a tree */
- Fts3Expr *pPrev, /* Node most recently inserted into the tree */
- Fts3Expr *pNew /* New binary node to insert into expression tree */
-){
- Fts3Expr *pSplit = pPrev;
- while( pSplit->pParent && opPrecedence(pSplit->pParent)<=opPrecedence(pNew) ){
- pSplit = pSplit->pParent;
- }
-
- if( pSplit->pParent ){
- assert( pSplit->pParent->pRight==pSplit );
- pSplit->pParent->pRight = pNew;
- pNew->pParent = pSplit->pParent;
- }else{
- *ppHead = pNew;
- }
- pNew->pLeft = pSplit;
- pSplit->pParent = pNew;
-}
-
-/*
-** Parse the fts3 query expression found in buffer z, length n. This function
-** returns either when the end of the buffer is reached or an unmatched
-** closing bracket - ')' - is encountered.
-**
-** If successful, SQLITE_OK is returned, *ppExpr is set to point to the
-** parsed form of the expression and *pnConsumed is set to the number of
-** bytes read from buffer z. Otherwise, *ppExpr is set to 0 and SQLITE_NOMEM
-** (out of memory error) or SQLITE_ERROR (parse error) is returned.
-*/
-static int fts3ExprParse(
- ParseContext *pParse, /* fts3 query parse context */
- const char *z, int n, /* Text of MATCH query */
- Fts3Expr **ppExpr, /* OUT: Parsed query structure */
- int *pnConsumed /* OUT: Number of bytes consumed */
-){
- Fts3Expr *pRet = 0;
- Fts3Expr *pPrev = 0;
- Fts3Expr *pNotBranch = 0; /* Only used in legacy parse mode */
- int nIn = n;
- const char *zIn = z;
- int rc = SQLITE_OK;
- int isRequirePhrase = 1;
-
- while( rc==SQLITE_OK ){
- Fts3Expr *p = 0;
- int nByte = 0;
- rc = getNextNode(pParse, zIn, nIn, &p, &nByte);
- if( rc==SQLITE_OK ){
- int isPhrase;
-
- if( !sqlite3_fts3_enable_parentheses
- && p->eType==FTSQUERY_PHRASE && p->pPhrase->isNot
- ){
- /* Create an implicit NOT operator. */
- Fts3Expr *pNot = sqlite3_malloc(sizeof(Fts3Expr));
- if( !pNot ){
- sqlite3Fts3ExprFree(p);
- rc = SQLITE_NOMEM;
- goto exprparse_out;
- }
- memset(pNot, 0, sizeof(Fts3Expr));
- pNot->eType = FTSQUERY_NOT;
- pNot->pRight = p;
- if( pNotBranch ){
- pNot->pLeft = pNotBranch;
- }
- pNotBranch = pNot;
- p = pPrev;
- }else{
- int eType = p->eType;
- assert( eType!=FTSQUERY_PHRASE || !p->pPhrase->isNot );
- isPhrase = (eType==FTSQUERY_PHRASE || p->pLeft);
-
- /* The isRequirePhrase variable is set to true if a phrase or
- ** an expression contained in parenthesis is required. If a
- ** binary operator (AND, OR, NOT or NEAR) is encounted when
- ** isRequirePhrase is set, this is a syntax error.
- */
- if( !isPhrase && isRequirePhrase ){
- sqlite3Fts3ExprFree(p);
- rc = SQLITE_ERROR;
- goto exprparse_out;
- }
-
- if( isPhrase && !isRequirePhrase ){
- /* Insert an implicit AND operator. */
- Fts3Expr *pAnd;
- assert( pRet && pPrev );
- pAnd = sqlite3_malloc(sizeof(Fts3Expr));
- if( !pAnd ){
- sqlite3Fts3ExprFree(p);
- rc = SQLITE_NOMEM;
- goto exprparse_out;
- }
- memset(pAnd, 0, sizeof(Fts3Expr));
- pAnd->eType = FTSQUERY_AND;
- insertBinaryOperator(&pRet, pPrev, pAnd);
- pPrev = pAnd;
- }
-
- /* This test catches attempts to make either operand of a NEAR
- ** operator something other than a phrase. For example, either of
- ** the following:
- **
- ** (bracketed expression) NEAR phrase
- ** phrase NEAR (bracketed expression)
- **
- ** Return an error in either case.
- */
- if( pPrev && (
- (eType==FTSQUERY_NEAR && !isPhrase && pPrev->eType!=FTSQUERY_PHRASE)
- || (eType!=FTSQUERY_PHRASE && isPhrase && pPrev->eType==FTSQUERY_NEAR)
- )){
- sqlite3Fts3ExprFree(p);
- rc = SQLITE_ERROR;
- goto exprparse_out;
- }
-
- if( isPhrase ){
- if( pRet ){
- assert( pPrev && pPrev->pLeft && pPrev->pRight==0 );
- pPrev->pRight = p;
- p->pParent = pPrev;
- }else{
- pRet = p;
- }
- }else{
- insertBinaryOperator(&pRet, pPrev, p);
- }
- isRequirePhrase = !isPhrase;
- }
- assert( nByte>0 );
- }
- assert( rc!=SQLITE_OK || (nByte>0 && nByte<=nIn) );
- nIn -= nByte;
- zIn += nByte;
- pPrev = p;
- }
-
- if( rc==SQLITE_DONE && pRet && isRequirePhrase ){
- rc = SQLITE_ERROR;
- }
-
- if( rc==SQLITE_DONE ){
- rc = SQLITE_OK;
- if( !sqlite3_fts3_enable_parentheses && pNotBranch ){
- if( !pRet ){
- rc = SQLITE_ERROR;
- }else{
- Fts3Expr *pIter = pNotBranch;
- while( pIter->pLeft ){
- pIter = pIter->pLeft;
- }
- pIter->pLeft = pRet;
- pRet = pNotBranch;
- }
- }
- }
- *pnConsumed = n - nIn;
-
-exprparse_out:
- if( rc!=SQLITE_OK ){
- sqlite3Fts3ExprFree(pRet);
- sqlite3Fts3ExprFree(pNotBranch);
- pRet = 0;
- }
- *ppExpr = pRet;
- return rc;
-}
-
-/*
-** Parameters z and n contain a pointer to and length of a buffer containing
-** an fts3 query expression, respectively. This function attempts to parse the
-** query expression and create a tree of Fts3Expr structures representing the
-** parsed expression. If successful, *ppExpr is set to point to the head
-** of the parsed expression tree and SQLITE_OK is returned. If an error
-** occurs, either SQLITE_NOMEM (out-of-memory error) or SQLITE_ERROR (parse
-** error) is returned and *ppExpr is set to 0.
-**
-** If parameter n is a negative number, then z is assumed to point to a
-** nul-terminated string and the length is determined using strlen().
-**
-** The first parameter, pTokenizer, is passed the fts3 tokenizer module to
-** use to normalize query tokens while parsing the expression. The azCol[]
-** array, which is assumed to contain nCol entries, should contain the names
-** of each column in the target fts3 table, in order from left to right.
-** Column names must be nul-terminated strings.
-**
-** The iDefaultCol parameter should be passed the index of the table column
-** that appears on the left-hand-side of the MATCH operator (the default
-** column to match against for tokens for which a column name is not explicitly
-** specified as part of the query string), or -1 if tokens may by default
-** match any table column.
-*/
-SQLITE_PRIVATE int sqlite3Fts3ExprParse(
- sqlite3_tokenizer *pTokenizer, /* Tokenizer module */
- char **azCol, /* Array of column names for fts3 table */
- int nCol, /* Number of entries in azCol[] */
- int iDefaultCol, /* Default column to query */
- const char *z, int n, /* Text of MATCH query */
- Fts3Expr **ppExpr /* OUT: Parsed query structure */
-){
- int nParsed;
- int rc;
- ParseContext sParse;
- sParse.pTokenizer = pTokenizer;
- sParse.azCol = (const char **)azCol;
- sParse.nCol = nCol;
- sParse.iDefaultCol = iDefaultCol;
- sParse.nNest = 0;
- if( z==0 ){
- *ppExpr = 0;
- return SQLITE_OK;
- }
- if( n<0 ){
- n = strlen(z);
- }
- rc = fts3ExprParse(&sParse, z, n, ppExpr, &nParsed);
-
- /* Check for mismatched parenthesis */
- if( rc==SQLITE_OK && sParse.nNest ){
- rc = SQLITE_ERROR;
- sqlite3Fts3ExprFree(*ppExpr);
- *ppExpr = 0;
- }
-
- return rc;
-}
-
-/*
-** Free a parsed fts3 query expression allocated by sqlite3Fts3ExprParse().
-*/
-SQLITE_PRIVATE void sqlite3Fts3ExprFree(Fts3Expr *p){
- if( p ){
- sqlite3Fts3ExprFree(p->pLeft);
- sqlite3Fts3ExprFree(p->pRight);
- sqlite3_free(p);
- }
-}
-
-/****************************************************************************
-*****************************************************************************
-** Everything after this point is just test code.
-*/
-
-#ifdef SQLITE_TEST
-
-
-/*
-** Function to query the hash-table of tokenizers (see README.tokenizers).
-*/
-static int queryTestTokenizer(
- sqlite3 *db,
- const char *zName,
- const sqlite3_tokenizer_module **pp
-){
- int rc;
- sqlite3_stmt *pStmt;
- const char zSql[] = "SELECT fts3_tokenizer(?)";
-
- *pp = 0;
- rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
- if( rc!=SQLITE_OK ){
- return rc;
- }
-
- sqlite3_bind_text(pStmt, 1, zName, -1, SQLITE_STATIC);
- if( SQLITE_ROW==sqlite3_step(pStmt) ){
- if( sqlite3_column_type(pStmt, 0)==SQLITE_BLOB ){
- memcpy(pp, sqlite3_column_blob(pStmt, 0), sizeof(*pp));
- }
- }
-
- return sqlite3_finalize(pStmt);
-}
-
-/*
-** This function is part of the test interface for the query parser. It
-** writes a text representation of the query expression pExpr into the
-** buffer pointed to by argument zBuf. It is assumed that zBuf is large
-** enough to store the required text representation.
-*/
-static void exprToString(Fts3Expr *pExpr, char *zBuf){
- switch( pExpr->eType ){
- case FTSQUERY_PHRASE: {
- Fts3Phrase *pPhrase = pExpr->pPhrase;
- int i;
- zBuf += sprintf(zBuf, "PHRASE %d %d", pPhrase->iColumn, pPhrase->isNot);
- for(i=0; i<pPhrase->nToken; i++){
- zBuf += sprintf(zBuf," %.*s",pPhrase->aToken[i].n,pPhrase->aToken[i].z);
- zBuf += sprintf(zBuf,"%s", (pPhrase->aToken[i].isPrefix?"+":""));
- }
- return;
- }
-
- case FTSQUERY_NEAR:
- zBuf += sprintf(zBuf, "NEAR/%d ", pExpr->nNear);
- break;
- case FTSQUERY_NOT:
- zBuf += sprintf(zBuf, "NOT ");
- break;
- case FTSQUERY_AND:
- zBuf += sprintf(zBuf, "AND ");
- break;
- case FTSQUERY_OR:
- zBuf += sprintf(zBuf, "OR ");
- break;
- }
-
- zBuf += sprintf(zBuf, "{");
- exprToString(pExpr->pLeft, zBuf);
- zBuf += strlen(zBuf);
- zBuf += sprintf(zBuf, "} ");
-
- zBuf += sprintf(zBuf, "{");
- exprToString(pExpr->pRight, zBuf);
- zBuf += strlen(zBuf);
- zBuf += sprintf(zBuf, "}");
-}
-
-/*
-** This is the implementation of a scalar SQL function used to test the
-** expression parser. It should be called as follows:
-**
-** fts3_exprtest(<tokenizer>, <expr>, <column 1>, ...);
-**
-** The first argument, <tokenizer>, is the name of the fts3 tokenizer used
-** to parse the query expression (see README.tokenizers). The second argument
-** is the query expression to parse. Each subsequent argument is the name
-** of a column of the fts3 table that the query expression may refer to.
-** For example:
-**
-** SELECT fts3_exprtest('simple', 'Bill col2:Bloggs', 'col1', 'col2');
-*/
-static void fts3ExprTest(
- sqlite3_context *context,
- int argc,
- sqlite3_value **argv
-){
- sqlite3_tokenizer_module const *pModule = 0;
- sqlite3_tokenizer *pTokenizer = 0;
- int rc;
- char **azCol = 0;
- const char *zExpr;
- int nExpr;
- int nCol;
- int ii;
- Fts3Expr *pExpr;
- sqlite3 *db = sqlite3_context_db_handle(context);
-
- if( argc<3 ){
- sqlite3_result_error(context,
- "Usage: fts3_exprtest(tokenizer, expr, col1, ...", -1
- );
- return;
- }
-
- rc = queryTestTokenizer(db,
- (const char *)sqlite3_value_text(argv[0]), &pModule);
- if( rc==SQLITE_NOMEM ){
- sqlite3_result_error_nomem(context);
- goto exprtest_out;
- }else if( !pModule ){
- sqlite3_result_error(context, "No such tokenizer module", -1);
- goto exprtest_out;
- }
-
- rc = pModule->xCreate(0, 0, &pTokenizer);
- assert( rc==SQLITE_NOMEM || rc==SQLITE_OK );
- if( rc==SQLITE_NOMEM ){
- sqlite3_result_error_nomem(context);
- goto exprtest_out;
- }
- pTokenizer->pModule = pModule;
-
- zExpr = (const char *)sqlite3_value_text(argv[1]);
- nExpr = sqlite3_value_bytes(argv[1]);
- nCol = argc-2;
- azCol = (char **)sqlite3_malloc(nCol*sizeof(char *));
- if( !azCol ){
- sqlite3_result_error_nomem(context);
- goto exprtest_out;
- }
- for(ii=0; ii<nCol; ii++){
- azCol[ii] = (char *)sqlite3_value_text(argv[ii+2]);
- }
-
- rc = sqlite3Fts3ExprParse(
- pTokenizer, azCol, nCol, nCol, zExpr, nExpr, &pExpr
- );
- if( rc==SQLITE_NOMEM ){
- sqlite3_result_error_nomem(context);
- goto exprtest_out;
- }else if( rc==SQLITE_OK ){
- char zBuf[4096];
- exprToString(pExpr, zBuf);
- sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
- sqlite3Fts3ExprFree(pExpr);
- }else{
- sqlite3_result_error(context, "Error parsing expression", -1);
- }
-
-exprtest_out:
- if( pModule && pTokenizer ){
- rc = pModule->xDestroy(pTokenizer);
- }
- sqlite3_free(azCol);
-}
-
-/*
-** Register the query expression parser test function fts3_exprtest()
-** with database connection db.
-*/
-SQLITE_PRIVATE void sqlite3Fts3ExprInitTestInterface(sqlite3* db){
- sqlite3_create_function(
- db, "fts3_exprtest", -1, SQLITE_UTF8, 0, fts3ExprTest, 0, 0
- );
-}
-
-#endif
-#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */
-
-/************** End of fts3_expr.c *******************************************/
-/************** Begin file fts3_hash.c ***************************************/
-/*
-** 2001 September 22
-**
-** 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 is the implementation of generic hash-tables used in SQLite.
-** We've modified it slightly to serve as a standalone hash table
-** implementation for the full-text indexing module.
-*/
-
-/*
-** The code in this file is only compiled if:
-**
-** * The FTS3 module is being built as an extension
-** (in which case SQLITE_CORE is not defined), or
-**
-** * The FTS3 module is being built into the core of
-** SQLite (in which case SQLITE_ENABLE_FTS3 is defined).
-*/
-#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3)
-
-
-
-/*
-** Malloc and Free functions
-*/
-static void *fts3HashMalloc(int n){
- void *p = sqlite3_malloc(n);
- if( p ){
- memset(p, 0, n);
- }
- return p;
-}
-static void fts3HashFree(void *p){
- sqlite3_free(p);
-}
-
-/* Turn bulk memory into a hash table object by initializing the
-** fields of the Hash structure.
-**
-** "pNew" is a pointer to the hash table that is to be initialized.
-** keyClass is one of the constants
-** FTS3_HASH_BINARY or FTS3_HASH_STRING. The value of keyClass
-** determines what kind of key the hash table will use. "copyKey" is
-** true if the hash table should make its own private copy of keys and
-** false if it should just use the supplied pointer.
-*/
-SQLITE_PRIVATE void sqlite3Fts3HashInit(fts3Hash *pNew, int keyClass, int copyKey){
- assert( pNew!=0 );
- assert( keyClass>=FTS3_HASH_STRING && keyClass<=FTS3_HASH_BINARY );
- pNew->keyClass = keyClass;
- pNew->copyKey = copyKey;
- pNew->first = 0;
- pNew->count = 0;
- pNew->htsize = 0;
- pNew->ht = 0;
-}
-
-/* Remove all entries from a hash table. Reclaim all memory.
-** Call this routine to delete a hash table or to reset a hash table
-** to the empty state.
-*/
-SQLITE_PRIVATE void sqlite3Fts3HashClear(fts3Hash *pH){
- fts3HashElem *elem; /* For looping over all elements of the table */
-
- assert( pH!=0 );
- elem = pH->first;
- pH->first = 0;
- fts3HashFree(pH->ht);
- pH->ht = 0;
- pH->htsize = 0;
- while( elem ){
- fts3HashElem *next_elem = elem->next;
- if( pH->copyKey && elem->pKey ){
- fts3HashFree(elem->pKey);
- }
- fts3HashFree(elem);
- elem = next_elem;
- }
- pH->count = 0;
-}
-
-/*
-** Hash and comparison functions when the mode is FTS3_HASH_STRING
-*/
-static int fts3StrHash(const void *pKey, int nKey){
- const char *z = (const char *)pKey;
- int h = 0;
- if( nKey<=0 ) nKey = (int) strlen(z);
- while( nKey > 0 ){
- h = (h<<3) ^ h ^ *z++;
- nKey--;
- }
- return h & 0x7fffffff;
-}
-static int fts3StrCompare(const void *pKey1, int n1, const void *pKey2, int n2){
- if( n1!=n2 ) return 1;
- return strncmp((const char*)pKey1,(const char*)pKey2,n1);
-}
-
-/*
-** Hash and comparison functions when the mode is FTS3_HASH_BINARY
-*/
-static int fts3BinHash(const void *pKey, int nKey){
- int h = 0;
- const char *z = (const char *)pKey;
- while( nKey-- > 0 ){
- h = (h<<3) ^ h ^ *(z++);
- }
- return h & 0x7fffffff;
-}
-static int fts3BinCompare(const void *pKey1, int n1, const void *pKey2, int n2){
- if( n1!=n2 ) return 1;
- return memcmp(pKey1,pKey2,n1);
-}
-
-/*
-** Return a pointer to the appropriate hash function given the key class.
-**
-** The C syntax in this function definition may be unfamilar to some
-** programmers, so we provide the following additional explanation:
-**
-** The name of the function is "ftsHashFunction". The function takes a
-** single parameter "keyClass". The return value of ftsHashFunction()
-** is a pointer to another function. Specifically, the return value
-** of ftsHashFunction() is a pointer to a function that takes two parameters
-** with types "const void*" and "int" and returns an "int".
-*/
-static int (*ftsHashFunction(int keyClass))(const void*,int){
- if( keyClass==FTS3_HASH_STRING ){
- return &fts3StrHash;
- }else{
- assert( keyClass==FTS3_HASH_BINARY );
- return &fts3BinHash;
- }
-}
-
-/*
-** Return a pointer to the appropriate hash function given the key class.
-**
-** For help in interpreted the obscure C code in the function definition,
-** see the header comment on the previous function.
-*/
-static int (*ftsCompareFunction(int keyClass))(const void*,int,const void*,int){
- if( keyClass==FTS3_HASH_STRING ){
- return &fts3StrCompare;
- }else{
- assert( keyClass==FTS3_HASH_BINARY );
- return &fts3BinCompare;
- }
-}
-
-/* Link an element into the hash table
-*/
-static void fts3HashInsertElement(
- fts3Hash *pH, /* The complete hash table */
- struct _fts3ht *pEntry, /* The entry into which pNew is inserted */
- fts3HashElem *pNew /* The element to be inserted */
-){
- fts3HashElem *pHead; /* First element already in pEntry */
- pHead = pEntry->chain;
- if( pHead ){
- pNew->next = pHead;
- pNew->prev = pHead->prev;
- if( pHead->prev ){ pHead->prev->next = pNew; }
- else { pH->first = pNew; }
- pHead->prev = pNew;
- }else{
- pNew->next = pH->first;
- if( pH->first ){ pH->first->prev = pNew; }
- pNew->prev = 0;
- pH->first = pNew;
- }
- pEntry->count++;
- pEntry->chain = pNew;
-}
-
-
-/* Resize the hash table so that it cantains "new_size" buckets.
-** "new_size" must be a power of 2. The hash table might fail
-** to resize if sqliteMalloc() fails.
-*/
-static void fts3Rehash(fts3Hash *pH, int new_size){
- struct _fts3ht *new_ht; /* The new hash table */
- fts3HashElem *elem, *next_elem; /* For looping over existing elements */
- int (*xHash)(const void*,int); /* The hash function */
-
- assert( (new_size & (new_size-1))==0 );
- new_ht = (struct _fts3ht *)fts3HashMalloc( new_size*sizeof(struct _fts3ht) );
- if( new_ht==0 ) return;
- fts3HashFree(pH->ht);
- pH->ht = new_ht;
- pH->htsize = new_size;
- xHash = ftsHashFunction(pH->keyClass);
- for(elem=pH->first, pH->first=0; elem; elem = next_elem){
- int h = (*xHash)(elem->pKey, elem->nKey) & (new_size-1);
- next_elem = elem->next;
- fts3HashInsertElement(pH, &new_ht[h], elem);
- }
-}
-
-/* This function (for internal use only) locates an element in an
-** hash table that matches the given key. The hash for this key has
-** already been computed and is passed as the 4th parameter.
-*/
-static fts3HashElem *fts3FindElementByHash(
- const fts3Hash *pH, /* The pH to be searched */
- const void *pKey, /* The key we are searching for */
- int nKey,
- int h /* The hash for this key. */
-){
- fts3HashElem *elem; /* Used to loop thru the element list */
- int count; /* Number of elements left to test */
- int (*xCompare)(const void*,int,const void*,int); /* comparison function */
-
- if( pH->ht ){
- struct _fts3ht *pEntry = &pH->ht[h];
- elem = pEntry->chain;
- count = pEntry->count;
- xCompare = ftsCompareFunction(pH->keyClass);
- while( count-- && elem ){
- if( (*xCompare)(elem->pKey,elem->nKey,pKey,nKey)==0 ){
- return elem;
- }
- elem = elem->next;
- }
- }
- return 0;
-}
-
-/* Remove a single entry from the hash table given a pointer to that
-** element and a hash on the element's key.
-*/
-static void fts3RemoveElementByHash(
- fts3Hash *pH, /* The pH containing "elem" */
- fts3HashElem* elem, /* The element to be removed from the pH */
- int h /* Hash value for the element */
-){
- struct _fts3ht *pEntry;
- if( elem->prev ){
- elem->prev->next = elem->next;
- }else{
- pH->first = elem->next;
- }
- if( elem->next ){
- elem->next->prev = elem->prev;
- }
- pEntry = &pH->ht[h];
- if( pEntry->chain==elem ){
- pEntry->chain = elem->next;
- }
- pEntry->count--;
- if( pEntry->count<=0 ){
- pEntry->chain = 0;
- }
- if( pH->copyKey && elem->pKey ){
- fts3HashFree(elem->pKey);
- }
- fts3HashFree( elem );
- pH->count--;
- if( pH->count<=0 ){
- assert( pH->first==0 );
- assert( pH->count==0 );
- fts3HashClear(pH);
- }
-}
-
-/* Attempt to locate an element of the hash table pH with a key
-** that matches pKey,nKey. Return the data for this element if it is
-** found, or NULL if there is no match.
-*/
-SQLITE_PRIVATE void *sqlite3Fts3HashFind(const fts3Hash *pH, const void *pKey, int nKey){
- int h; /* A hash on key */
- fts3HashElem *elem; /* The element that matches key */
- int (*xHash)(const void*,int); /* The hash function */
-
- if( pH==0 || pH->ht==0 ) return 0;
- xHash = ftsHashFunction(pH->keyClass);
- assert( xHash!=0 );
- h = (*xHash)(pKey,nKey);
- assert( (pH->htsize & (pH->htsize-1))==0 );
- elem = fts3FindElementByHash(pH,pKey,nKey, h & (pH->htsize-1));
- return elem ? elem->data : 0;
-}
-
-/* Insert an element into the hash table pH. The key is pKey,nKey
-** and the data is "data".
-**
-** If no element exists with a matching key, then a new
-** element is created. A copy of the key is made if the copyKey
-** flag is set. NULL is returned.
-**
-** If another element already exists with the same key, then the
-** new data replaces the old data and the old data is returned.
-** The key is not copied in this instance. If a malloc fails, then
-** the new data is returned and the hash table is unchanged.
-**
-** If the "data" parameter to this function is NULL, then the
-** element corresponding to "key" is removed from the hash table.
-*/
-SQLITE_PRIVATE void *sqlite3Fts3HashInsert(
- fts3Hash *pH, /* The hash table to insert into */
- const void *pKey, /* The key */
- int nKey, /* Number of bytes in the key */
- void *data /* The data */
-){
- int hraw; /* Raw hash value of the key */
- int h; /* the hash of the key modulo hash table size */
- fts3HashElem *elem; /* Used to loop thru the element list */
- fts3HashElem *new_elem; /* New element added to the pH */
- int (*xHash)(const void*,int); /* The hash function */
-
- assert( pH!=0 );
- xHash = ftsHashFunction(pH->keyClass);
- assert( xHash!=0 );
- hraw = (*xHash)(pKey, nKey);
- assert( (pH->htsize & (pH->htsize-1))==0 );
- h = hraw & (pH->htsize-1);
- elem = fts3FindElementByHash(pH,pKey,nKey,h);
- if( elem ){
- void *old_data = elem->data;
- if( data==0 ){
- fts3RemoveElementByHash(pH,elem,h);
- }else{
- elem->data = data;
- }
- return old_data;
- }
- if( data==0 ) return 0;
- if( pH->htsize==0 ){
- fts3Rehash(pH,8);
- if( pH->htsize==0 ){
- pH->count = 0;
- return data;
- }
- }
- new_elem = (fts3HashElem*)fts3HashMalloc( sizeof(fts3HashElem) );
- if( new_elem==0 ) return data;
- if( pH->copyKey && pKey!=0 ){
- new_elem->pKey = fts3HashMalloc( nKey );
- if( new_elem->pKey==0 ){
- fts3HashFree(new_elem);
- return data;
- }
- memcpy((void*)new_elem->pKey, pKey, nKey);
- }else{
- new_elem->pKey = (void*)pKey;
- }
- new_elem->nKey = nKey;
- pH->count++;
- if( pH->count > pH->htsize ){
- fts3Rehash(pH,pH->htsize*2);
- }
- assert( pH->htsize>0 );
- assert( (pH->htsize & (pH->htsize-1))==0 );
- h = hraw & (pH->htsize-1);
- fts3HashInsertElement(pH, &pH->ht[h], new_elem);
- new_elem->data = data;
- return 0;
-}
-
-#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */
-
-/************** End of fts3_hash.c *******************************************/
-/************** Begin file fts3_porter.c *************************************/
-/*
-** 2006 September 30
-**
-** 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.
-**
-*************************************************************************
-** Implementation of the full-text-search tokenizer that implements
-** a Porter stemmer.
-*/
-
-/*
-** The code in this file is only compiled if:
-**
-** * The FTS3 module is being built as an extension
-** (in which case SQLITE_CORE is not defined), or
-**
-** * The FTS3 module is being built into the core of
-** SQLite (in which case SQLITE_ENABLE_FTS3 is defined).
-*/
-#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3)
-
-
-
-
-/*
-** Class derived from sqlite3_tokenizer
-*/
-typedef struct porter_tokenizer {
- sqlite3_tokenizer base; /* Base class */
-} porter_tokenizer;
-
-/*
-** Class derived from sqlit3_tokenizer_cursor
-*/
-typedef struct porter_tokenizer_cursor {
- sqlite3_tokenizer_cursor base;
- const char *zInput; /* input we are tokenizing */
- int nInput; /* size of the input */
- int iOffset; /* current position in zInput */
- int iToken; /* index of next token to be returned */
- char *zToken; /* storage for current token */
- int nAllocated; /* space allocated to zToken buffer */
-} porter_tokenizer_cursor;
-
-
-/* Forward declaration */
-static const sqlite3_tokenizer_module porterTokenizerModule;
-
-
-/*
-** Create a new tokenizer instance.
-*/
-static int porterCreate(
- int argc, const char * const *argv,
- sqlite3_tokenizer **ppTokenizer
-){
- porter_tokenizer *t;
- t = (porter_tokenizer *) sqlite3_malloc(sizeof(*t));
- if( t==NULL ) return SQLITE_NOMEM;
- memset(t, 0, sizeof(*t));
- *ppTokenizer = &t->base;
- return SQLITE_OK;
-}
-
-/*
-** Destroy a tokenizer
-*/
-static int porterDestroy(sqlite3_tokenizer *pTokenizer){
- sqlite3_free(pTokenizer);
- return SQLITE_OK;
-}
-
-/*
-** Prepare to begin tokenizing a particular string. The input
-** string to be tokenized is zInput[0..nInput-1]. A cursor
-** used to incrementally tokenize this string is returned in
-** *ppCursor.
-*/
-static int porterOpen(
- sqlite3_tokenizer *pTokenizer, /* The tokenizer */
- const char *zInput, int nInput, /* String to be tokenized */
- sqlite3_tokenizer_cursor **ppCursor /* OUT: Tokenization cursor */
-){
- porter_tokenizer_cursor *c;
-
- c = (porter_tokenizer_cursor *) sqlite3_malloc(sizeof(*c));
- if( c==NULL ) return SQLITE_NOMEM;
-
- c->zInput = zInput;
- if( zInput==0 ){
- c->nInput = 0;
- }else if( nInput<0 ){
- c->nInput = (int)strlen(zInput);
- }else{
- c->nInput = nInput;
- }
- c->iOffset = 0; /* start tokenizing at the beginning */
- c->iToken = 0;
- c->zToken = NULL; /* no space allocated, yet. */
- c->nAllocated = 0;
-
- *ppCursor = &c->base;
- return SQLITE_OK;
-}
-
-/*
-** Close a tokenization cursor previously opened by a call to
-** porterOpen() above.
-*/
-static int porterClose(sqlite3_tokenizer_cursor *pCursor){
- porter_tokenizer_cursor *c = (porter_tokenizer_cursor *) pCursor;
- sqlite3_free(c->zToken);
- sqlite3_free(c);
- return SQLITE_OK;
-}
-/*
-** Vowel or consonant
-*/
-static const char cType[] = {
- 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0,
- 1, 1, 1, 2, 1
-};
-
-/*
-** isConsonant() and isVowel() determine if their first character in
-** the string they point to is a consonant or a vowel, according
-** to Porter ruls.
-**
-** A consonate is any letter other than 'a', 'e', 'i', 'o', or 'u'.
-** 'Y' is a consonant unless it follows another consonant,
-** in which case it is a vowel.
-**
-** In these routine, the letters are in reverse order. So the 'y' rule
-** is that 'y' is a consonant unless it is followed by another
-** consonent.
-*/
-static int isVowel(const char*);
-static int isConsonant(const char *z){
- int j;
- char x = *z;
- if( x==0 ) return 0;
- assert( x>='a' && x<='z' );
- j = cType[x-'a'];
- if( j<2 ) return j;
- return z[1]==0 || isVowel(z + 1);
-}
-static int isVowel(const char *z){
- int j;
- char x = *z;
- if( x==0 ) return 0;
- assert( x>='a' && x<='z' );
- j = cType[x-'a'];
- if( j<2 ) return 1-j;
- return isConsonant(z + 1);
-}
-
-/*
-** Let any sequence of one or more vowels be represented by V and let
-** C be sequence of one or more consonants. Then every word can be
-** represented as:
-**
-** [C] (VC){m} [V]
-**
-** In prose: A word is an optional consonant followed by zero or
-** vowel-consonant pairs followed by an optional vowel. "m" is the
-** number of vowel consonant pairs. This routine computes the value
-** of m for the first i bytes of a word.
-**
-** Return true if the m-value for z is 1 or more. In other words,
-** return true if z contains at least one vowel that is followed
-** by a consonant.
-**
-** In this routine z[] is in reverse order. So we are really looking
-** for an instance of of a consonant followed by a vowel.
-*/
-static int m_gt_0(const char *z){
- while( isVowel(z) ){ z++; }
- if( *z==0 ) return 0;
- while( isConsonant(z) ){ z++; }
- return *z!=0;
-}
-
-/* Like mgt0 above except we are looking for a value of m which is
-** exactly 1
-*/
-static int m_eq_1(const char *z){
- while( isVowel(z) ){ z++; }
- if( *z==0 ) return 0;
- while( isConsonant(z) ){ z++; }
- if( *z==0 ) return 0;
- while( isVowel(z) ){ z++; }
- if( *z==0 ) return 1;
- while( isConsonant(z) ){ z++; }
- return *z==0;
-}
-
-/* Like mgt0 above except we are looking for a value of m>1 instead
-** or m>0
-*/
-static int m_gt_1(const char *z){
- while( isVowel(z) ){ z++; }
- if( *z==0 ) return 0;
- while( isConsonant(z) ){ z++; }
- if( *z==0 ) return 0;
- while( isVowel(z) ){ z++; }
- if( *z==0 ) return 0;
- while( isConsonant(z) ){ z++; }
- return *z!=0;
-}
-
-/*
-** Return TRUE if there is a vowel anywhere within z[0..n-1]
-*/
-static int hasVowel(const char *z){
- while( isConsonant(z) ){ z++; }
- return *z!=0;
-}
-
-/*
-** Return TRUE if the word ends in a double consonant.
-**
-** The text is reversed here. So we are really looking at
-** the first two characters of z[].
-*/
-static int doubleConsonant(const char *z){
- return isConsonant(z) && z[0]==z[1] && isConsonant(z+1);
-}
-
-/*
-** Return TRUE if the word ends with three letters which
-** are consonant-vowel-consonent and where the final consonant
-** is not 'w', 'x', or 'y'.
-**
-** The word is reversed here. So we are really checking the
-** first three letters and the first one cannot be in [wxy].
-*/
-static int star_oh(const char *z){
- return
- z[0]!=0 && isConsonant(z) &&
- z[0]!='w' && z[0]!='x' && z[0]!='y' &&
- z[1]!=0 && isVowel(z+1) &&
- z[2]!=0 && isConsonant(z+2);
-}
-
-/*
-** If the word ends with zFrom and xCond() is true for the stem
-** of the word that preceeds the zFrom ending, then change the
-** ending to zTo.
-**
-** The input word *pz and zFrom are both in reverse order. zTo
-** is in normal order.
-**
-** Return TRUE if zFrom matches. Return FALSE if zFrom does not
-** match. Not that TRUE is returned even if xCond() fails and
-** no substitution occurs.
-*/
-static int stem(
- char **pz, /* The word being stemmed (Reversed) */
- const char *zFrom, /* If the ending matches this... (Reversed) */
- const char *zTo, /* ... change the ending to this (not reversed) */
- int (*xCond)(const char*) /* Condition that must be true */
-){
- char *z = *pz;
- while( *zFrom && *zFrom==*z ){ z++; zFrom++; }
- if( *zFrom!=0 ) return 0;
- if( xCond && !xCond(z) ) return 1;
- while( *zTo ){
- *(--z) = *(zTo++);
- }
- *pz = z;
- return 1;
-}
-
-/*
-** This is the fallback stemmer used when the porter stemmer is
-** inappropriate. The input word is copied into the output with
-** US-ASCII case folding. If the input word is too long (more
-** than 20 bytes if it contains no digits or more than 6 bytes if
-** it contains digits) then word is truncated to 20 or 6 bytes
-** by taking 10 or 3 bytes from the beginning and end.
-*/
-static void copy_stemmer(const char *zIn, int nIn, char *zOut, int *pnOut){
- int i, mx, j;
- int hasDigit = 0;
- for(i=0; i<nIn; i++){
- int c = zIn[i];
- if( c>='A' && c<='Z' ){
- zOut[i] = c - 'A' + 'a';
- }else{
- if( c>='0' && c<='9' ) hasDigit = 1;
- zOut[i] = c;
- }
- }
- mx = hasDigit ? 3 : 10;
- if( nIn>mx*2 ){
- for(j=mx, i=nIn-mx; i<nIn; i++, j++){
- zOut[j] = zOut[i];
- }
- i = j;
- }
- zOut[i] = 0;
- *pnOut = i;
-}
-
-
-/*
-** Stem the input word zIn[0..nIn-1]. Store the output in zOut.
-** zOut is at least big enough to hold nIn bytes. Write the actual
-** size of the output word (exclusive of the '\0' terminator) into *pnOut.
-**
-** Any upper-case characters in the US-ASCII character set ([A-Z])
-** are converted to lower case. Upper-case UTF characters are
-** unchanged.
-**
-** Words that are longer than about 20 bytes are stemmed by retaining
-** a few bytes from the beginning and the end of the word. If the
-** word contains digits, 3 bytes are taken from the beginning and
-** 3 bytes from the end. For long words without digits, 10 bytes
-** are taken from each end. US-ASCII case folding still applies.
-**
-** If the input word contains not digits but does characters not
-** in [a-zA-Z] then no stemming is attempted and this routine just
-** copies the input into the input into the output with US-ASCII
-** case folding.
-**
-** Stemming never increases the length of the word. So there is
-** no chance of overflowing the zOut buffer.
-*/
-static void porter_stemmer(const char *zIn, int nIn, char *zOut, int *pnOut){
- int i, j, c;
- char zReverse[28];
- char *z, *z2;
- if( nIn<3 || nIn>=sizeof(zReverse)-7 ){
- /* The word is too big or too small for the porter stemmer.
- ** Fallback to the copy stemmer */
- copy_stemmer(zIn, nIn, zOut, pnOut);
- return;
- }
- for(i=0, j=sizeof(zReverse)-6; i<nIn; i++, j--){
- c = zIn[i];
- if( c>='A' && c<='Z' ){
- zReverse[j] = c + 'a' - 'A';
- }else if( c>='a' && c<='z' ){
- zReverse[j] = c;
- }else{
- /* The use of a character not in [a-zA-Z] means that we fallback
- ** to the copy stemmer */
- copy_stemmer(zIn, nIn, zOut, pnOut);
- return;
- }
- }
- memset(&zReverse[sizeof(zReverse)-5], 0, 5);
- z = &zReverse[j+1];
-
-
- /* Step 1a */
- if( z[0]=='s' ){
- if(
- !stem(&z, "sess", "ss", 0) &&
- !stem(&z, "sei", "i", 0) &&
- !stem(&z, "ss", "ss", 0)
- ){
- z++;
- }
- }
-
- /* Step 1b */
- z2 = z;
- if( stem(&z, "dee", "ee", m_gt_0) ){
- /* Do nothing. The work was all in the test */
- }else if(
- (stem(&z, "gni", "", hasVowel) || stem(&z, "de", "", hasVowel))
- && z!=z2
- ){
- if( stem(&z, "ta", "ate", 0) ||
- stem(&z, "lb", "ble", 0) ||
- stem(&z, "zi", "ize", 0) ){
- /* Do nothing. The work was all in the test */
- }else if( doubleConsonant(z) && (*z!='l' && *z!='s' && *z!='z') ){
- z++;
- }else if( m_eq_1(z) && star_oh(z) ){
- *(--z) = 'e';
- }
- }
-
- /* Step 1c */
- if( z[0]=='y' && hasVowel(z+1) ){
- z[0] = 'i';
- }
-
- /* Step 2 */
- switch( z[1] ){
- case 'a':
- stem(&z, "lanoita", "ate", m_gt_0) ||
- stem(&z, "lanoit", "tion", m_gt_0);
- break;
- case 'c':
- stem(&z, "icne", "ence", m_gt_0) ||
- stem(&z, "icna", "ance", m_gt_0);
- break;
- case 'e':
- stem(&z, "rezi", "ize", m_gt_0);
- break;
- case 'g':
- stem(&z, "igol", "log", m_gt_0);
- break;
- case 'l':
- stem(&z, "ilb", "ble", m_gt_0) ||
- stem(&z, "illa", "al", m_gt_0) ||
- stem(&z, "iltne", "ent", m_gt_0) ||
- stem(&z, "ile", "e", m_gt_0) ||
- stem(&z, "ilsuo", "ous", m_gt_0);
- break;
- case 'o':
- stem(&z, "noitazi", "ize", m_gt_0) ||
- stem(&z, "noita", "ate", m_gt_0) ||
- stem(&z, "rota", "ate", m_gt_0);
- break;
- case 's':
- stem(&z, "msila", "al", m_gt_0) ||
- stem(&z, "ssenevi", "ive", m_gt_0) ||
- stem(&z, "ssenluf", "ful", m_gt_0) ||
- stem(&z, "ssensuo", "ous", m_gt_0);
- break;
- case 't':
- stem(&z, "itila", "al", m_gt_0) ||
- stem(&z, "itivi", "ive", m_gt_0) ||
- stem(&z, "itilib", "ble", m_gt_0);
- break;
- }
-
- /* Step 3 */
- switch( z[0] ){
- case 'e':
- stem(&z, "etaci", "ic", m_gt_0) ||
- stem(&z, "evita", "", m_gt_0) ||
- stem(&z, "ezila", "al", m_gt_0);
- break;
- case 'i':
- stem(&z, "itici", "ic", m_gt_0);
- break;
- case 'l':
- stem(&z, "laci", "ic", m_gt_0) ||
- stem(&z, "luf", "", m_gt_0);
- break;
- case 's':
- stem(&z, "ssen", "", m_gt_0);
- break;
- }
-
- /* Step 4 */
- switch( z[1] ){
- case 'a':
- if( z[0]=='l' && m_gt_1(z+2) ){
- z += 2;
- }
- break;
- case 'c':
- if( z[0]=='e' && z[2]=='n' && (z[3]=='a' || z[3]=='e') && m_gt_1(z+4) ){
- z += 4;
- }
- break;
- case 'e':
- if( z[0]=='r' && m_gt_1(z+2) ){
- z += 2;
- }
- break;
- case 'i':
- if( z[0]=='c' && m_gt_1(z+2) ){
- z += 2;
- }
- break;
- case 'l':
- if( z[0]=='e' && z[2]=='b' && (z[3]=='a' || z[3]=='i') && m_gt_1(z+4) ){
- z += 4;
- }
- break;
- case 'n':
- if( z[0]=='t' ){
- if( z[2]=='a' ){
- if( m_gt_1(z+3) ){
- z += 3;
- }
- }else if( z[2]=='e' ){
- stem(&z, "tneme", "", m_gt_1) ||
- stem(&z, "tnem", "", m_gt_1) ||
- stem(&z, "tne", "", m_gt_1);
- }
- }
- break;
- case 'o':
- if( z[0]=='u' ){
- if( m_gt_1(z+2) ){
- z += 2;
- }
- }else if( z[3]=='s' || z[3]=='t' ){
- stem(&z, "noi", "", m_gt_1);
- }
- break;
- case 's':
- if( z[0]=='m' && z[2]=='i' && m_gt_1(z+3) ){
- z += 3;
- }
- break;
- case 't':
- stem(&z, "eta", "", m_gt_1) ||
- stem(&z, "iti", "", m_gt_1);
- break;
- case 'u':
- if( z[0]=='s' && z[2]=='o' && m_gt_1(z+3) ){
- z += 3;
- }
- break;
- case 'v':
- case 'z':
- if( z[0]=='e' && z[2]=='i' && m_gt_1(z+3) ){
- z += 3;
- }
- break;
- }
-
- /* Step 5a */
- if( z[0]=='e' ){
- if( m_gt_1(z+1) ){
- z++;
- }else if( m_eq_1(z+1) && !star_oh(z+1) ){
- z++;
- }
- }
-
- /* Step 5b */
- if( m_gt_1(z) && z[0]=='l' && z[1]=='l' ){
- z++;
- }
-
- /* z[] is now the stemmed word in reverse order. Flip it back
- ** around into forward order and return.
- */
- *pnOut = i = strlen(z);
- zOut[i] = 0;
- while( *z ){
- zOut[--i] = *(z++);
- }
-}
-
-/*
-** Characters that can be part of a token. We assume any character
-** whose value is greater than 0x80 (any UTF character) can be
-** part of a token. In other words, delimiters all must have
-** values of 0x7f or lower.
-*/
-static const char porterIdChar[] = {
-/* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 3x */
- 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 4x */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, /* 5x */
- 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 6x */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* 7x */
-};
-#define isDelim(C) (((ch=C)&0x80)==0 && (ch<0x30 || !porterIdChar[ch-0x30]))
-
-/*
-** Extract the next token from a tokenization cursor. The cursor must
-** have been opened by a prior call to porterOpen().
-*/
-static int porterNext(
- sqlite3_tokenizer_cursor *pCursor, /* Cursor returned by porterOpen */
- const char **pzToken, /* OUT: *pzToken is the token text */
- int *pnBytes, /* OUT: Number of bytes in token */
- int *piStartOffset, /* OUT: Starting offset of token */
- int *piEndOffset, /* OUT: Ending offset of token */
- int *piPosition /* OUT: Position integer of token */
-){
- porter_tokenizer_cursor *c = (porter_tokenizer_cursor *) pCursor;
- const char *z = c->zInput;
-
- while( c->iOffset<c->nInput ){
- int iStartOffset, ch;
-
- /* Scan past delimiter characters */
- while( c->iOffset<c->nInput && isDelim(z[c->iOffset]) ){
- c->iOffset++;
- }
-
- /* Count non-delimiter characters. */
- iStartOffset = c->iOffset;
- while( c->iOffset<c->nInput && !isDelim(z[c->iOffset]) ){
- c->iOffset++;
- }
-
- if( c->iOffset>iStartOffset ){
- int n = c->iOffset-iStartOffset;
- if( n>c->nAllocated ){
- c->nAllocated = n+20;
- c->zToken = sqlite3_realloc(c->zToken, c->nAllocated);
- if( c->zToken==NULL ) return SQLITE_NOMEM;
- }
- porter_stemmer(&z[iStartOffset], n, c->zToken, pnBytes);
- *pzToken = c->zToken;
- *piStartOffset = iStartOffset;
- *piEndOffset = c->iOffset;
- *piPosition = c->iToken++;
- return SQLITE_OK;
- }
- }
- return SQLITE_DONE;
-}
-
-/*
-** The set of routines that implement the porter-stemmer tokenizer
-*/
-static const sqlite3_tokenizer_module porterTokenizerModule = {
- 0,
- porterCreate,
- porterDestroy,
- porterOpen,
- porterClose,
- porterNext,
-};
-
-/*
-** Allocate a new porter tokenizer. Return a pointer to the new
-** tokenizer in *ppModule
-*/
-SQLITE_PRIVATE void sqlite3Fts3PorterTokenizerModule(
- sqlite3_tokenizer_module const**ppModule
-){
- *ppModule = &porterTokenizerModule;
-}
-
-#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */
-
-/************** End of fts3_porter.c *****************************************/
-/************** Begin file fts3_tokenizer.c **********************************/
-/*
-** 2007 June 22
-**
-** 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 is part of an SQLite module implementing full-text search.
-** This particular file implements the generic tokenizer interface.
-*/
-
-/*
-** The code in this file is only compiled if:
-**
-** * The FTS3 module is being built as an extension
-** (in which case SQLITE_CORE is not defined), or
-**
-** * The FTS3 module is being built into the core of
-** SQLite (in which case SQLITE_ENABLE_FTS3 is defined).
-*/
-#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3)
-
-#ifndef SQLITE_CORE
- SQLITE_EXTENSION_INIT1
-#endif
-
-
-/*
-** Implementation of the SQL scalar function for accessing the underlying
-** hash table. This function may be called as follows:
-**
-** SELECT <function-name>(<key-name>);
-** SELECT <function-name>(<key-name>, <pointer>);
-**
-** where <function-name> is the name passed as the second argument
-** to the sqlite3Fts3InitHashTable() function (e.g. 'fts3_tokenizer').
-**
-** If the <pointer> argument is specified, it must be a blob value
-** containing a pointer to be stored as the hash data corresponding
-** to the string <key-name>. If <pointer> is not specified, then
-** the string <key-name> must already exist in the has table. Otherwise,
-** an error is returned.
-**
-** Whether or not the <pointer> argument is specified, the value returned
-** is a blob containing the pointer stored as the hash data corresponding
-** to string <key-name> (after the hash-table is updated, if applicable).
-*/
-static void scalarFunc(
- sqlite3_context *context,
- int argc,
- sqlite3_value **argv
-){
- fts3Hash *pHash;
- void *pPtr = 0;
- const unsigned char *zName;
- int nName;
-
- assert( argc==1 || argc==2 );
-
- pHash = (fts3Hash *)sqlite3_user_data(context);
-
- zName = sqlite3_value_text(argv[0]);
- nName = sqlite3_value_bytes(argv[0])+1;
-
- if( argc==2 ){
- void *pOld;
- int n = sqlite3_value_bytes(argv[1]);
- if( n!=sizeof(pPtr) ){
- sqlite3_result_error(context, "argument type mismatch", -1);
- return;
- }
- pPtr = *(void **)sqlite3_value_blob(argv[1]);
- pOld = sqlite3Fts3HashInsert(pHash, (void *)zName, nName, pPtr);
- if( pOld==pPtr ){
- sqlite3_result_error(context, "out of memory", -1);
- return;
- }
- }else{
- pPtr = sqlite3Fts3HashFind(pHash, zName, nName);
- if( !pPtr ){
- char *zErr = sqlite3_mprintf("unknown tokenizer: %s", zName);
- sqlite3_result_error(context, zErr, -1);
- sqlite3_free(zErr);
- return;
- }
- }
-
- sqlite3_result_blob(context, (void *)&pPtr, sizeof(pPtr), SQLITE_TRANSIENT);
-}
-
-#ifdef SQLITE_TEST
-
-
-/*
-** Implementation of a special SQL scalar function for testing tokenizers
-** designed to be used in concert with the Tcl testing framework. This
-** function must be called with two arguments:
-**
-** SELECT <function-name>(<key-name>, <input-string>);
-** SELECT <function-name>(<key-name>, <pointer>);
-**
-** where <function-name> is the name passed as the second argument
-** to the sqlite3Fts3InitHashTable() function (e.g. 'fts3_tokenizer')
-** concatenated with the string '_test' (e.g. 'fts3_tokenizer_test').
-**
-** The return value is a string that may be interpreted as a Tcl
-** list. For each token in the <input-string>, three elements are
-** added to the returned list. The first is the token position, the
-** second is the token text (folded, stemmed, etc.) and the third is the
-** substring of <input-string> associated with the token. For example,
-** using the built-in "simple" tokenizer:
-**
-** SELECT fts_tokenizer_test('simple', 'I don't see how');
-**
-** will return the string:
-**
-** "{0 i I 1 dont don't 2 see see 3 how how}"
-**
-*/
-static void testFunc(
- sqlite3_context *context,
- int argc,
- sqlite3_value **argv
-){
- fts3Hash *pHash;
- sqlite3_tokenizer_module *p;
- sqlite3_tokenizer *pTokenizer = 0;
- sqlite3_tokenizer_cursor *pCsr = 0;
-
- const char *zErr = 0;
-
- const char *zName;
- int nName;
- const char *zInput;
- int nInput;
-
- const char *zArg = 0;
-
- const char *zToken;
- int nToken;
- int iStart;
- int iEnd;
- int iPos;
-
- Tcl_Obj *pRet;
-
- assert( argc==2 || argc==3 );
-
- nName = sqlite3_value_bytes(argv[0]);
- zName = (const char *)sqlite3_value_text(argv[0]);
- nInput = sqlite3_value_bytes(argv[argc-1]);
- zInput = (const char *)sqlite3_value_text(argv[argc-1]);
-
- if( argc==3 ){
- zArg = (const char *)sqlite3_value_text(argv[1]);
- }
-
- pHash = (fts3Hash *)sqlite3_user_data(context);
- p = (sqlite3_tokenizer_module *)sqlite3Fts3HashFind(pHash, zName, nName+1);
-
- if( !p ){
- char *zErr = sqlite3_mprintf("unknown tokenizer: %s", zName);
- sqlite3_result_error(context, zErr, -1);
- sqlite3_free(zErr);
- return;
- }
-
- pRet = Tcl_NewObj();
- Tcl_IncrRefCount(pRet);
-
- if( SQLITE_OK!=p->xCreate(zArg ? 1 : 0, &zArg, &pTokenizer) ){
- zErr = "error in xCreate()";
- goto finish;
- }
- pTokenizer->pModule = p;
- if( SQLITE_OK!=p->xOpen(pTokenizer, zInput, nInput, &pCsr) ){
- zErr = "error in xOpen()";
- goto finish;
- }
- pCsr->pTokenizer = pTokenizer;
-
- while( SQLITE_OK==p->xNext(pCsr, &zToken, &nToken, &iStart, &iEnd, &iPos) ){
- Tcl_ListObjAppendElement(0, pRet, Tcl_NewIntObj(iPos));
- Tcl_ListObjAppendElement(0, pRet, Tcl_NewStringObj(zToken, nToken));
- zToken = &zInput[iStart];
- nToken = iEnd-iStart;
- Tcl_ListObjAppendElement(0, pRet, Tcl_NewStringObj(zToken, nToken));
- }
-
- if( SQLITE_OK!=p->xClose(pCsr) ){
- zErr = "error in xClose()";
- goto finish;
- }
- if( SQLITE_OK!=p->xDestroy(pTokenizer) ){
- zErr = "error in xDestroy()";
- goto finish;
- }
-
-finish:
- if( zErr ){
- sqlite3_result_error(context, zErr, -1);
- }else{
- sqlite3_result_text(context, Tcl_GetString(pRet), -1, SQLITE_TRANSIENT);
- }
- Tcl_DecrRefCount(pRet);
-}
-
-static
-int registerTokenizer(
- sqlite3 *db,
- char *zName,
- const sqlite3_tokenizer_module *p
-){
- int rc;
- sqlite3_stmt *pStmt;
- const char zSql[] = "SELECT fts3_tokenizer(?, ?)";
-
- rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
- if( rc!=SQLITE_OK ){
- return rc;
- }
-
- sqlite3_bind_text(pStmt, 1, zName, -1, SQLITE_STATIC);
- sqlite3_bind_blob(pStmt, 2, &p, sizeof(p), SQLITE_STATIC);
- sqlite3_step(pStmt);
-
- return sqlite3_finalize(pStmt);
-}
-
-static
-int queryTokenizer(
- sqlite3 *db,
- char *zName,
- const sqlite3_tokenizer_module **pp
-){
- int rc;
- sqlite3_stmt *pStmt;
- const char zSql[] = "SELECT fts3_tokenizer(?)";
-
- *pp = 0;
- rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
- if( rc!=SQLITE_OK ){
- return rc;
- }
-
- sqlite3_bind_text(pStmt, 1, zName, -1, SQLITE_STATIC);
- if( SQLITE_ROW==sqlite3_step(pStmt) ){
- if( sqlite3_column_type(pStmt, 0)==SQLITE_BLOB ){
- memcpy(pp, sqlite3_column_blob(pStmt, 0), sizeof(*pp));
- }
- }
-
- return sqlite3_finalize(pStmt);
-}
-
-SQLITE_PRIVATE void sqlite3Fts3SimpleTokenizerModule(sqlite3_tokenizer_module const**ppModule);
-
-/*
-** Implementation of the scalar function fts3_tokenizer_internal_test().
-** This function is used for testing only, it is not included in the
-** build unless SQLITE_TEST is defined.
-**
-** The purpose of this is to test that the fts3_tokenizer() function
-** can be used as designed by the C-code in the queryTokenizer and
-** registerTokenizer() functions above. These two functions are repeated
-** in the README.tokenizer file as an example, so it is important to
-** test them.
-**
-** To run the tests, evaluate the fts3_tokenizer_internal_test() scalar
-** function with no arguments. An assert() will fail if a problem is
-** detected. i.e.:
-**
-** SELECT fts3_tokenizer_internal_test();
-**
-*/
-static void intTestFunc(
- sqlite3_context *context,
- int argc,
- sqlite3_value **argv
-){
- int rc;
- const sqlite3_tokenizer_module *p1;
- const sqlite3_tokenizer_module *p2;
- sqlite3 *db = (sqlite3 *)sqlite3_user_data(context);
-
- /* Test the query function */
- sqlite3Fts3SimpleTokenizerModule(&p1);
- rc = queryTokenizer(db, "simple", &p2);
- assert( rc==SQLITE_OK );
- assert( p1==p2 );
- rc = queryTokenizer(db, "nosuchtokenizer", &p2);
- assert( rc==SQLITE_ERROR );
- assert( p2==0 );
- assert( 0==strcmp(sqlite3_errmsg(db), "unknown tokenizer: nosuchtokenizer") );
-
- /* Test the storage function */
- rc = registerTokenizer(db, "nosuchtokenizer", p1);
- assert( rc==SQLITE_OK );
- rc = queryTokenizer(db, "nosuchtokenizer", &p2);
- assert( rc==SQLITE_OK );
- assert( p2==p1 );
-
- sqlite3_result_text(context, "ok", -1, SQLITE_STATIC);
-}
-
-#endif
-
-/*
-** Set up SQL objects in database db used to access the contents of
-** the hash table pointed to by argument pHash. The hash table must
-** been initialised to use string keys, and to take a private copy
-** of the key when a value is inserted. i.e. by a call similar to:
-**
-** sqlite3Fts3HashInit(pHash, FTS3_HASH_STRING, 1);
-**
-** This function adds a scalar function (see header comment above
-** scalarFunc() in this file for details) and, if ENABLE_TABLE is
-** defined at compilation time, a temporary virtual table (see header
-** comment above struct HashTableVtab) to the database schema. Both
-** provide read/write access to the contents of *pHash.
-**
-** The third argument to this function, zName, is used as the name
-** of both the scalar and, if created, the virtual table.
-*/
-SQLITE_PRIVATE int sqlite3Fts3InitHashTable(
- sqlite3 *db,
- fts3Hash *pHash,
- const char *zName
-){
- int rc = SQLITE_OK;
- void *p = (void *)pHash;
- const int any = SQLITE_ANY;
- char *zTest = 0;
- char *zTest2 = 0;
-
-#ifdef SQLITE_TEST
- void *pdb = (void *)db;
- zTest = sqlite3_mprintf("%s_test", zName);
- zTest2 = sqlite3_mprintf("%s_internal_test", zName);
- if( !zTest || !zTest2 ){
- rc = SQLITE_NOMEM;
- }
-#endif
-
- if( rc!=SQLITE_OK
- || (rc = sqlite3_create_function(db, zName, 1, any, p, scalarFunc, 0, 0))
- || (rc = sqlite3_create_function(db, zName, 2, any, p, scalarFunc, 0, 0))
-#ifdef SQLITE_TEST
- || (rc = sqlite3_create_function(db, zTest, 2, any, p, testFunc, 0, 0))
- || (rc = sqlite3_create_function(db, zTest, 3, any, p, testFunc, 0, 0))
- || (rc = sqlite3_create_function(db, zTest2, 0, any, pdb, intTestFunc, 0, 0))
-#endif
- );
-
- sqlite3_free(zTest);
- sqlite3_free(zTest2);
- return rc;
-}
-
-#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */
-
-/************** End of fts3_tokenizer.c **************************************/
-/************** Begin file fts3_tokenizer1.c *********************************/
-/*
-** 2006 Oct 10
-**
-** 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.
-**
-******************************************************************************
-**
-** Implementation of the "simple" full-text-search tokenizer.
-*/
-
-/*
-** The code in this file is only compiled if:
-**
-** * The FTS3 module is being built as an extension
-** (in which case SQLITE_CORE is not defined), or
-**
-** * The FTS3 module is being built into the core of
-** SQLite (in which case SQLITE_ENABLE_FTS3 is defined).
-*/
-#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3)
-
-
-
-
-typedef struct simple_tokenizer {
- sqlite3_tokenizer base;
- char delim[128]; /* flag ASCII delimiters */
-} simple_tokenizer;
-
-typedef struct simple_tokenizer_cursor {
- sqlite3_tokenizer_cursor base;
- const char *pInput; /* input we are tokenizing */
- int nBytes; /* size of the input */
- int iOffset; /* current position in pInput */
- int iToken; /* index of next token to be returned */
- char *pToken; /* storage for current token */
- int nTokenAllocated; /* space allocated to zToken buffer */
-} simple_tokenizer_cursor;
-
-
-/* Forward declaration */
-static const sqlite3_tokenizer_module simpleTokenizerModule;
-
-static int simpleDelim(simple_tokenizer *t, unsigned char c){
- return c<0x80 && t->delim[c];
-}
-
-/*
-** Create a new tokenizer instance.
-*/
-static int simpleCreate(
- int argc, const char * const *argv,
- sqlite3_tokenizer **ppTokenizer
-){
- simple_tokenizer *t;
-
- t = (simple_tokenizer *) sqlite3_malloc(sizeof(*t));
- if( t==NULL ) return SQLITE_NOMEM;
- memset(t, 0, sizeof(*t));
-
- /* TODO(shess) Delimiters need to remain the same from run to run,
- ** else we need to reindex. One solution would be a meta-table to
- ** track such information in the database, then we'd only want this
- ** information on the initial create.
- */
- if( argc>1 ){
- int i, n = strlen(argv[1]);
- for(i=0; i<n; i++){
- unsigned char ch = argv[1][i];
- /* We explicitly don't support UTF-8 delimiters for now. */
- if( ch>=0x80 ){
- sqlite3_free(t);
- return SQLITE_ERROR;
- }
- t->delim[ch] = 1;
- }
- } else {
- /* Mark non-alphanumeric ASCII characters as delimiters */
- int i;
- for(i=1; i<0x80; i++){
- t->delim[i] = !isalnum(i);
- }
- }
-
- *ppTokenizer = &t->base;
- return SQLITE_OK;
-}
-
-/*
-** Destroy a tokenizer
-*/
-static int simpleDestroy(sqlite3_tokenizer *pTokenizer){
- sqlite3_free(pTokenizer);
- return SQLITE_OK;
-}
-
-/*
-** Prepare to begin tokenizing a particular string. The input
-** string to be tokenized is pInput[0..nBytes-1]. A cursor
-** used to incrementally tokenize this string is returned in
-** *ppCursor.
-*/
-static int simpleOpen(
- sqlite3_tokenizer *pTokenizer, /* The tokenizer */
- const char *pInput, int nBytes, /* String to be tokenized */
- sqlite3_tokenizer_cursor **ppCursor /* OUT: Tokenization cursor */
-){
- simple_tokenizer_cursor *c;
-
- c = (simple_tokenizer_cursor *) sqlite3_malloc(sizeof(*c));
- if( c==NULL ) return SQLITE_NOMEM;
-
- c->pInput = pInput;
- if( pInput==0 ){
- c->nBytes = 0;
- }else if( nBytes<0 ){
- c->nBytes = (int)strlen(pInput);
- }else{
- c->nBytes = nBytes;
- }
- c->iOffset = 0; /* start tokenizing at the beginning */
- c->iToken = 0;
- c->pToken = NULL; /* no space allocated, yet. */
- c->nTokenAllocated = 0;
-
- *ppCursor = &c->base;
- return SQLITE_OK;
-}
-
-/*
-** Close a tokenization cursor previously opened by a call to
-** simpleOpen() above.
-*/
-static int simpleClose(sqlite3_tokenizer_cursor *pCursor){
- simple_tokenizer_cursor *c = (simple_tokenizer_cursor *) pCursor;
- sqlite3_free(c->pToken);
- sqlite3_free(c);
- return SQLITE_OK;
-}
-
-/*
-** Extract the next token from a tokenization cursor. The cursor must
-** have been opened by a prior call to simpleOpen().
-*/
-static int simpleNext(
- sqlite3_tokenizer_cursor *pCursor, /* Cursor returned by simpleOpen */
- const char **ppToken, /* OUT: *ppToken is the token text */
- int *pnBytes, /* OUT: Number of bytes in token */
- int *piStartOffset, /* OUT: Starting offset of token */
- int *piEndOffset, /* OUT: Ending offset of token */
- int *piPosition /* OUT: Position integer of token */
-){
- simple_tokenizer_cursor *c = (simple_tokenizer_cursor *) pCursor;
- simple_tokenizer *t = (simple_tokenizer *) pCursor->pTokenizer;
- unsigned char *p = (unsigned char *)c->pInput;
-
- while( c->iOffset<c->nBytes ){
- int iStartOffset;
-
- /* Scan past delimiter characters */
- while( c->iOffset<c->nBytes && simpleDelim(t, p[c->iOffset]) ){
- c->iOffset++;
- }
-
- /* Count non-delimiter characters. */
- iStartOffset = c->iOffset;
- while( c->iOffset<c->nBytes && !simpleDelim(t, p[c->iOffset]) ){
- c->iOffset++;
- }
-
- if( c->iOffset>iStartOffset ){
- int i, n = c->iOffset-iStartOffset;
- if( n>c->nTokenAllocated ){
- c->nTokenAllocated = n+20;
- c->pToken = sqlite3_realloc(c->pToken, c->nTokenAllocated);
- if( c->pToken==NULL ) return SQLITE_NOMEM;
- }
- for(i=0; i<n; i++){
- /* TODO(shess) This needs expansion to handle UTF-8
- ** case-insensitivity.
- */
- unsigned char ch = p[iStartOffset+i];
- c->pToken[i] = ch<0x80 ? tolower(ch) : ch;
- }
- *ppToken = c->pToken;
- *pnBytes = n;
- *piStartOffset = iStartOffset;
- *piEndOffset = c->iOffset;
- *piPosition = c->iToken++;
-
- return SQLITE_OK;
- }
- }
- return SQLITE_DONE;
-}
-
-/*
-** The set of routines that implement the simple tokenizer
-*/
-static const sqlite3_tokenizer_module simpleTokenizerModule = {
- 0,
- simpleCreate,
- simpleDestroy,
- simpleOpen,
- simpleClose,
- simpleNext,
-};
-
-/*
-** Allocate a new simple tokenizer. Return a pointer to the new
-** tokenizer in *ppModule
-*/
-SQLITE_PRIVATE void sqlite3Fts3SimpleTokenizerModule(
- sqlite3_tokenizer_module const**ppModule
-){
- *ppModule = &simpleTokenizerModule;
-}
-
-#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */
-
-/************** End of fts3_tokenizer1.c *************************************/
-/************** Begin file rtree.c *******************************************/
-/*
-** 2001 September 15
-**
-** 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 code for implementations of the r-tree and r*-tree
-** algorithms packaged as an SQLite virtual table module.
-**
-** $Id: rtree.c,v 1.14 2009/08/06 18:36:47 danielk1977 Exp $
-*/
-
-#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_RTREE)
-
-/*
-** This file contains an implementation of a couple of different variants
-** of the r-tree algorithm. See the README file for further details. The
-** same data-structure is used for all, but the algorithms for insert and
-** delete operations vary. The variants used are selected at compile time
-** by defining the following symbols:
-*/
-
-/* Either, both or none of the following may be set to activate
-** r*tree variant algorithms.
-*/
-#define VARIANT_RSTARTREE_CHOOSESUBTREE 0
-#define VARIANT_RSTARTREE_REINSERT 1
-
-/*
-** Exactly one of the following must be set to 1.
-*/
-#define VARIANT_GUTTMAN_QUADRATIC_SPLIT 0
-#define VARIANT_GUTTMAN_LINEAR_SPLIT 0
-#define VARIANT_RSTARTREE_SPLIT 1
-
-#define VARIANT_GUTTMAN_SPLIT \
- (VARIANT_GUTTMAN_LINEAR_SPLIT||VARIANT_GUTTMAN_QUADRATIC_SPLIT)
-
-#if VARIANT_GUTTMAN_QUADRATIC_SPLIT
- #define PickNext QuadraticPickNext
- #define PickSeeds QuadraticPickSeeds
- #define AssignCells splitNodeGuttman
-#endif
-#if VARIANT_GUTTMAN_LINEAR_SPLIT
- #define PickNext LinearPickNext
- #define PickSeeds LinearPickSeeds
- #define AssignCells splitNodeGuttman
-#endif
-#if VARIANT_RSTARTREE_SPLIT
- #define AssignCells splitNodeStartree
-#endif
-
-
-#ifndef SQLITE_CORE
- SQLITE_EXTENSION_INIT1
-#else
-#endif
-
-
-#ifndef SQLITE_AMALGAMATION
-typedef sqlite3_int64 i64;
-typedef unsigned char u8;
-typedef unsigned int u32;
-#endif
-
-typedef struct Rtree Rtree;
-typedef struct RtreeCursor RtreeCursor;
-typedef struct RtreeNode RtreeNode;
-typedef struct RtreeCell RtreeCell;
-typedef struct RtreeConstraint RtreeConstraint;
-typedef union RtreeCoord RtreeCoord;
-
-/* The rtree may have between 1 and RTREE_MAX_DIMENSIONS dimensions. */
-#define RTREE_MAX_DIMENSIONS 5
-
-/* Size of hash table Rtree.aHash. This hash table is not expected to
-** ever contain very many entries, so a fixed number of buckets is
-** used.
-*/
-#define HASHSIZE 128
-
-/*
-** An rtree virtual-table object.
-*/
-struct Rtree {
- sqlite3_vtab base;
- sqlite3 *db; /* Host database connection */
- int iNodeSize; /* Size in bytes of each node in the node table */
- int nDim; /* Number of dimensions */
- int nBytesPerCell; /* Bytes consumed per cell */
- int iDepth; /* Current depth of the r-tree structure */
- char *zDb; /* Name of database containing r-tree table */
- char *zName; /* Name of r-tree table */
- RtreeNode *aHash[HASHSIZE]; /* Hash table of in-memory nodes. */
- int nBusy; /* Current number of users of this structure */
-
- /* List of nodes removed during a CondenseTree operation. List is
- ** linked together via the pointer normally used for hash chains -
- ** RtreeNode.pNext. RtreeNode.iNode stores the depth of the sub-tree
- ** headed by the node (leaf nodes have RtreeNode.iNode==0).
- */
- RtreeNode *pDeleted;
- int iReinsertHeight; /* Height of sub-trees Reinsert() has run on */
-
- /* Statements to read/write/delete a record from xxx_node */
- sqlite3_stmt *pReadNode;
- sqlite3_stmt *pWriteNode;
- sqlite3_stmt *pDeleteNode;
-
- /* Statements to read/write/delete a record from xxx_rowid */
- sqlite3_stmt *pReadRowid;
- sqlite3_stmt *pWriteRowid;
- sqlite3_stmt *pDeleteRowid;
-
- /* Statements to read/write/delete a record from xxx_parent */
- sqlite3_stmt *pReadParent;
- sqlite3_stmt *pWriteParent;
- sqlite3_stmt *pDeleteParent;
-
- int eCoordType;
-};
-
-/* Possible values for eCoordType: */
-#define RTREE_COORD_REAL32 0
-#define RTREE_COORD_INT32 1
-
-/*
-** The minimum number of cells allowed for a node is a third of the
-** maximum. In Gutman's notation:
-**
-** m = M/3
-**
-** If an R*-tree "Reinsert" operation is required, the same number of
-** cells are removed from the overfull node and reinserted into the tree.
-*/
-#define RTREE_MINCELLS(p) ((((p)->iNodeSize-4)/(p)->nBytesPerCell)/3)
-#define RTREE_REINSERT(p) RTREE_MINCELLS(p)
-#define RTREE_MAXCELLS 51
-
-/*
-** An rtree cursor object.
-*/
-struct RtreeCursor {
- sqlite3_vtab_cursor base;
- RtreeNode *pNode; /* Node cursor is currently pointing at */
- int iCell; /* Index of current cell in pNode */
- int iStrategy; /* Copy of idxNum search parameter */
- int nConstraint; /* Number of entries in aConstraint */
- RtreeConstraint *aConstraint; /* Search constraints. */
-};
-
-union RtreeCoord {
- float f;
- int i;
-};
-
-/*
-** The argument is an RtreeCoord. Return the value stored within the RtreeCoord
-** formatted as a double. This macro assumes that local variable pRtree points
-** to the Rtree structure associated with the RtreeCoord.
-*/
-#define DCOORD(coord) ( \
- (pRtree->eCoordType==RTREE_COORD_REAL32) ? \
- ((double)coord.f) : \
- ((double)coord.i) \
-)
-
-/*
-** A search constraint.
-*/
-struct RtreeConstraint {
- int iCoord; /* Index of constrained coordinate */
- int op; /* Constraining operation */
- double rValue; /* Constraint value. */
-};
-
-/* Possible values for RtreeConstraint.op */
-#define RTREE_EQ 0x41
-#define RTREE_LE 0x42
-#define RTREE_LT 0x43
-#define RTREE_GE 0x44
-#define RTREE_GT 0x45
-
-/*
-** An rtree structure node.
-**
-** Data format (RtreeNode.zData):
-**
-** 1. If the node is the root node (node 1), then the first 2 bytes
-** of the node contain the tree depth as a big-endian integer.
-** For non-root nodes, the first 2 bytes are left unused.
-**
-** 2. The next 2 bytes contain the number of entries currently
-** stored in the node.
-**
-** 3. The remainder of the node contains the node entries. Each entry
-** consists of a single 8-byte integer followed by an even number
-** of 4-byte coordinates. For leaf nodes the integer is the rowid
-** of a record. For internal nodes it is the node number of a
-** child page.
-*/
-struct RtreeNode {
- RtreeNode *pParent; /* Parent node */
- i64 iNode;
- int nRef;
- int isDirty;
- u8 *zData;
- RtreeNode *pNext; /* Next node in this hash chain */
-};
-#define NCELL(pNode) readInt16(&(pNode)->zData[2])
-
-/*
-** Structure to store a deserialized rtree record.
-*/
-struct RtreeCell {
- i64 iRowid;
- RtreeCoord aCoord[RTREE_MAX_DIMENSIONS*2];
-};
-
-#ifndef MAX
-# define MAX(x,y) ((x) < (y) ? (y) : (x))
-#endif
-#ifndef MIN
-# define MIN(x,y) ((x) > (y) ? (y) : (x))
-#endif
-
-/*
-** Functions to deserialize a 16 bit integer, 32 bit real number and
-** 64 bit integer. The deserialized value is returned.
-*/
-static int readInt16(u8 *p){
- return (p[0]<<8) + p[1];
-}
-static void readCoord(u8 *p, RtreeCoord *pCoord){
- u32 i = (
- (((u32)p[0]) << 24) +
- (((u32)p[1]) << 16) +
- (((u32)p[2]) << 8) +
- (((u32)p[3]) << 0)
- );
- *(u32 *)pCoord = i;
-}
-static i64 readInt64(u8 *p){
- return (
- (((i64)p[0]) << 56) +
- (((i64)p[1]) << 48) +
- (((i64)p[2]) << 40) +
- (((i64)p[3]) << 32) +
- (((i64)p[4]) << 24) +
- (((i64)p[5]) << 16) +
- (((i64)p[6]) << 8) +
- (((i64)p[7]) << 0)
- );
-}
-
-/*
-** Functions to serialize a 16 bit integer, 32 bit real number and
-** 64 bit integer. The value returned is the number of bytes written
-** to the argument buffer (always 2, 4 and 8 respectively).
-*/
-static int writeInt16(u8 *p, int i){
- p[0] = (i>> 8)&0xFF;
- p[1] = (i>> 0)&0xFF;
- return 2;
-}
-static int writeCoord(u8 *p, RtreeCoord *pCoord){
- u32 i;
- assert( sizeof(RtreeCoord)==4 );
- assert( sizeof(u32)==4 );
- i = *(u32 *)pCoord;
- p[0] = (i>>24)&0xFF;
- p[1] = (i>>16)&0xFF;
- p[2] = (i>> 8)&0xFF;
- p[3] = (i>> 0)&0xFF;
- return 4;
-}
-static int writeInt64(u8 *p, i64 i){
- p[0] = (i>>56)&0xFF;
- p[1] = (i>>48)&0xFF;
- p[2] = (i>>40)&0xFF;
- p[3] = (i>>32)&0xFF;
- p[4] = (i>>24)&0xFF;
- p[5] = (i>>16)&0xFF;
- p[6] = (i>> 8)&0xFF;
- p[7] = (i>> 0)&0xFF;
- return 8;
-}
-
-/*
-** Increment the reference count of node p.
-*/
-static void nodeReference(RtreeNode *p){
- if( p ){
- p->nRef++;
- }
-}
-
-/*
-** Clear the content of node p (set all bytes to 0x00).
-*/
-static void nodeZero(Rtree *pRtree, RtreeNode *p){
- if( p ){
- memset(&p->zData[2], 0, pRtree->iNodeSize-2);
- p->isDirty = 1;
- }
-}
-
-/*
-** Given a node number iNode, return the corresponding key to use
-** in the Rtree.aHash table.
-*/
-static int nodeHash(i64 iNode){
- return (
- (iNode>>56) ^ (iNode>>48) ^ (iNode>>40) ^ (iNode>>32) ^
- (iNode>>24) ^ (iNode>>16) ^ (iNode>> 8) ^ (iNode>> 0)
- ) % HASHSIZE;
-}
-
-/*
-** Search the node hash table for node iNode. If found, return a pointer
-** to it. Otherwise, return 0.
-*/
-static RtreeNode *nodeHashLookup(Rtree *pRtree, i64 iNode){
- RtreeNode *p;
- assert( iNode!=0 );
- for(p=pRtree->aHash[nodeHash(iNode)]; p && p->iNode!=iNode; p=p->pNext);
- return p;
-}
-
-/*
-** Add node pNode to the node hash table.
-*/
-static void nodeHashInsert(Rtree *pRtree, RtreeNode *pNode){
- if( pNode ){
- int iHash;
- assert( pNode->pNext==0 );
- iHash = nodeHash(pNode->iNode);
- pNode->pNext = pRtree->aHash[iHash];
- pRtree->aHash[iHash] = pNode;
- }
-}
-
-/*
-** Remove node pNode from the node hash table.
-*/
-static void nodeHashDelete(Rtree *pRtree, RtreeNode *pNode){
- RtreeNode **pp;
- if( pNode->iNode!=0 ){
- pp = &pRtree->aHash[nodeHash(pNode->iNode)];
- for( ; (*pp)!=pNode; pp = &(*pp)->pNext){ assert(*pp); }
- *pp = pNode->pNext;
- pNode->pNext = 0;
- }
-}
-
-/*
-** Allocate and return new r-tree node. Initially, (RtreeNode.iNode==0),
-** indicating that node has not yet been assigned a node number. It is
-** assigned a node number when nodeWrite() is called to write the
-** node contents out to the database.
-*/
-static RtreeNode *nodeNew(Rtree *pRtree, RtreeNode *pParent, int zero){
- RtreeNode *pNode;
- pNode = (RtreeNode *)sqlite3_malloc(sizeof(RtreeNode) + pRtree->iNodeSize);
- if( pNode ){
- memset(pNode, 0, sizeof(RtreeNode) + (zero?pRtree->iNodeSize:0));
- pNode->zData = (u8 *)&pNode[1];
- pNode->nRef = 1;
- pNode->pParent = pParent;
- pNode->isDirty = 1;
- nodeReference(pParent);
- }
- return pNode;
-}
-
-/*
-** Obtain a reference to an r-tree node.
-*/
-static int
-nodeAcquire(
- Rtree *pRtree, /* R-tree structure */
- i64 iNode, /* Node number to load */
- RtreeNode *pParent, /* Either the parent node or NULL */
- RtreeNode **ppNode /* OUT: Acquired node */
-){
- int rc;
- RtreeNode *pNode;
-
- /* Check if the requested node is already in the hash table. If so,
- ** increase its reference count and return it.
- */
- if( (pNode = nodeHashLookup(pRtree, iNode)) ){
- assert( !pParent || !pNode->pParent || pNode->pParent==pParent );
- if( pParent && !pNode->pParent ){
- nodeReference(pParent);
- pNode->pParent = pParent;
- }
- pNode->nRef++;
- *ppNode = pNode;
- return SQLITE_OK;
- }
-
- pNode = (RtreeNode *)sqlite3_malloc(sizeof(RtreeNode) + pRtree->iNodeSize);
- if( !pNode ){
- *ppNode = 0;
- return SQLITE_NOMEM;
- }
- pNode->pParent = pParent;
- pNode->zData = (u8 *)&pNode[1];
- pNode->nRef = 1;
- pNode->iNode = iNode;
- pNode->isDirty = 0;
- pNode->pNext = 0;
-
- sqlite3_bind_int64(pRtree->pReadNode, 1, iNode);
- rc = sqlite3_step(pRtree->pReadNode);
- if( rc==SQLITE_ROW ){
- const u8 *zBlob = sqlite3_column_blob(pRtree->pReadNode, 0);
- memcpy(pNode->zData, zBlob, pRtree->iNodeSize);
- nodeReference(pParent);
- }else{
- sqlite3_free(pNode);
- pNode = 0;
- }
-
- *ppNode = pNode;
- rc = sqlite3_reset(pRtree->pReadNode);
-
- if( rc==SQLITE_OK && iNode==1 ){
- pRtree->iDepth = readInt16(pNode->zData);
- }
-
- assert( (rc==SQLITE_OK && pNode) || (pNode==0 && rc!=SQLITE_OK) );
- nodeHashInsert(pRtree, pNode);
-
- return rc;
-}
-
-/*
-** Overwrite cell iCell of node pNode with the contents of pCell.
-*/
-static void nodeOverwriteCell(
- Rtree *pRtree,
- RtreeNode *pNode,
- RtreeCell *pCell,
- int iCell
-){
- int ii;
- u8 *p = &pNode->zData[4 + pRtree->nBytesPerCell*iCell];
- p += writeInt64(p, pCell->iRowid);
- for(ii=0; ii<(pRtree->nDim*2); ii++){
- p += writeCoord(p, &pCell->aCoord[ii]);
- }
- pNode->isDirty = 1;
-}
-
-/*
-** Remove cell the cell with index iCell from node pNode.
-*/
-static void nodeDeleteCell(Rtree *pRtree, RtreeNode *pNode, int iCell){
- u8 *pDst = &pNode->zData[4 + pRtree->nBytesPerCell*iCell];
- u8 *pSrc = &pDst[pRtree->nBytesPerCell];
- int nByte = (NCELL(pNode) - iCell - 1) * pRtree->nBytesPerCell;
- memmove(pDst, pSrc, nByte);
- writeInt16(&pNode->zData[2], NCELL(pNode)-1);
- pNode->isDirty = 1;
-}
-
-/*
-** Insert the contents of cell pCell into node pNode. If the insert
-** is successful, return SQLITE_OK.
-**
-** If there is not enough free space in pNode, return SQLITE_FULL.
-*/
-static int
-nodeInsertCell(
- Rtree *pRtree,
- RtreeNode *pNode,
- RtreeCell *pCell
-){
- int nCell; /* Current number of cells in pNode */
- int nMaxCell; /* Maximum number of cells for pNode */
-
- nMaxCell = (pRtree->iNodeSize-4)/pRtree->nBytesPerCell;
- nCell = NCELL(pNode);
-
- assert(nCell<=nMaxCell);
-
- if( nCell<nMaxCell ){
- nodeOverwriteCell(pRtree, pNode, pCell, nCell);
- writeInt16(&pNode->zData[2], nCell+1);
- pNode->isDirty = 1;
- }
-
- return (nCell==nMaxCell);
-}
-
-/*
-** If the node is dirty, write it out to the database.
-*/
-static int
-nodeWrite(Rtree *pRtree, RtreeNode *pNode){
- int rc = SQLITE_OK;
- if( pNode->isDirty ){
- sqlite3_stmt *p = pRtree->pWriteNode;
- if( pNode->iNode ){
- sqlite3_bind_int64(p, 1, pNode->iNode);
- }else{
- sqlite3_bind_null(p, 1);
- }
- sqlite3_bind_blob(p, 2, pNode->zData, pRtree->iNodeSize, SQLITE_STATIC);
- sqlite3_step(p);
- pNode->isDirty = 0;
- rc = sqlite3_reset(p);
- if( pNode->iNode==0 && rc==SQLITE_OK ){
- pNode->iNode = sqlite3_last_insert_rowid(pRtree->db);
- nodeHashInsert(pRtree, pNode);
- }
- }
- return rc;
-}
-
-/*
-** Release a reference to a node. If the node is dirty and the reference
-** count drops to zero, the node data is written to the database.
-*/
-static int
-nodeRelease(Rtree *pRtree, RtreeNode *pNode){
- int rc = SQLITE_OK;
- if( pNode ){
- assert( pNode->nRef>0 );
- pNode->nRef--;
- if( pNode->nRef==0 ){
- if( pNode->iNode==1 ){
- pRtree->iDepth = -1;
- }
- if( pNode->pParent ){
- rc = nodeRelease(pRtree, pNode->pParent);
- }
- if( rc==SQLITE_OK ){
- rc = nodeWrite(pRtree, pNode);
- }
- nodeHashDelete(pRtree, pNode);
- sqlite3_free(pNode);
- }
- }
- return rc;
-}
-
-/*
-** Return the 64-bit integer value associated with cell iCell of
-** node pNode. If pNode is a leaf node, this is a rowid. If it is
-** an internal node, then the 64-bit integer is a child page number.
-*/
-static i64 nodeGetRowid(
- Rtree *pRtree,
- RtreeNode *pNode,
- int iCell
-){
- assert( iCell<NCELL(pNode) );
- return readInt64(&pNode->zData[4 + pRtree->nBytesPerCell*iCell]);
-}
-
-/*
-** Return coordinate iCoord from cell iCell in node pNode.
-*/
-static void nodeGetCoord(
- Rtree *pRtree,
- RtreeNode *pNode,
- int iCell,
- int iCoord,
- RtreeCoord *pCoord /* Space to write result to */
-){
- readCoord(&pNode->zData[12 + pRtree->nBytesPerCell*iCell + 4*iCoord], pCoord);
-}
-
-/*
-** Deserialize cell iCell of node pNode. Populate the structure pointed
-** to by pCell with the results.
-*/
-static void nodeGetCell(
- Rtree *pRtree,
- RtreeNode *pNode,
- int iCell,
- RtreeCell *pCell
-){
- int ii;
- pCell->iRowid = nodeGetRowid(pRtree, pNode, iCell);
- for(ii=0; ii<pRtree->nDim*2; ii++){
- nodeGetCoord(pRtree, pNode, iCell, ii, &pCell->aCoord[ii]);
- }
-}
-
-
-/* Forward declaration for the function that does the work of
-** the virtual table module xCreate() and xConnect() methods.
-*/
-static int rtreeInit(
- sqlite3 *, void *, int, const char *const*, sqlite3_vtab **, char **, int
-);
-
-/*
-** Rtree virtual table module xCreate method.
-*/
-static int rtreeCreate(
- sqlite3 *db,
- void *pAux,
- int argc, const char *const*argv,
- sqlite3_vtab **ppVtab,
- char **pzErr
-){
- return rtreeInit(db, pAux, argc, argv, ppVtab, pzErr, 1);
-}
-
-/*
-** Rtree virtual table module xConnect method.
-*/
-static int rtreeConnect(
- sqlite3 *db,
- void *pAux,
- int argc, const char *const*argv,
- sqlite3_vtab **ppVtab,
- char **pzErr
-){
- return rtreeInit(db, pAux, argc, argv, ppVtab, pzErr, 0);
-}
-
-/*
-** Increment the r-tree reference count.
-*/
-static void rtreeReference(Rtree *pRtree){
- pRtree->nBusy++;
-}
-
-/*
-** Decrement the r-tree reference count. When the reference count reaches
-** zero the structure is deleted.
-*/
-static void rtreeRelease(Rtree *pRtree){
- pRtree->nBusy--;
- if( pRtree->nBusy==0 ){
- sqlite3_finalize(pRtree->pReadNode);
- sqlite3_finalize(pRtree->pWriteNode);
- sqlite3_finalize(pRtree->pDeleteNode);
- sqlite3_finalize(pRtree->pReadRowid);
- sqlite3_finalize(pRtree->pWriteRowid);
- sqlite3_finalize(pRtree->pDeleteRowid);
- sqlite3_finalize(pRtree->pReadParent);
- sqlite3_finalize(pRtree->pWriteParent);
- sqlite3_finalize(pRtree->pDeleteParent);
- sqlite3_free(pRtree);
- }
-}
-
-/*
-** Rtree virtual table module xDisconnect method.
-*/
-static int rtreeDisconnect(sqlite3_vtab *pVtab){
- rtreeRelease((Rtree *)pVtab);
- return SQLITE_OK;
-}
-
-/*
-** Rtree virtual table module xDestroy method.
-*/
-static int rtreeDestroy(sqlite3_vtab *pVtab){
- Rtree *pRtree = (Rtree *)pVtab;
- int rc;
- char *zCreate = sqlite3_mprintf(
- "DROP TABLE '%q'.'%q_node';"
- "DROP TABLE '%q'.'%q_rowid';"
- "DROP TABLE '%q'.'%q_parent';",
- pRtree->zDb, pRtree->zName,
- pRtree->zDb, pRtree->zName,
- pRtree->zDb, pRtree->zName
- );
- if( !zCreate ){
- rc = SQLITE_NOMEM;
- }else{
- rc = sqlite3_exec(pRtree->db, zCreate, 0, 0, 0);
- sqlite3_free(zCreate);
- }
- if( rc==SQLITE_OK ){
- rtreeRelease(pRtree);
- }
-
- return rc;
-}
-
-/*
-** Rtree virtual table module xOpen method.
-*/
-static int rtreeOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
- int rc = SQLITE_NOMEM;
- RtreeCursor *pCsr;
-
- pCsr = (RtreeCursor *)sqlite3_malloc(sizeof(RtreeCursor));
- if( pCsr ){
- memset(pCsr, 0, sizeof(RtreeCursor));
- pCsr->base.pVtab = pVTab;
- rc = SQLITE_OK;
- }
- *ppCursor = (sqlite3_vtab_cursor *)pCsr;
-
- return rc;
-}
-
-/*
-** Rtree virtual table module xClose method.
-*/
-static int rtreeClose(sqlite3_vtab_cursor *cur){
- Rtree *pRtree = (Rtree *)(cur->pVtab);
- int rc;
- RtreeCursor *pCsr = (RtreeCursor *)cur;
- sqlite3_free(pCsr->aConstraint);
- rc = nodeRelease(pRtree, pCsr->pNode);
- sqlite3_free(pCsr);
- return rc;
-}
-
-/*
-** Rtree virtual table module xEof method.
-**
-** Return non-zero if the cursor does not currently point to a valid
-** record (i.e if the scan has finished), or zero otherwise.
-*/
-static int rtreeEof(sqlite3_vtab_cursor *cur){
- RtreeCursor *pCsr = (RtreeCursor *)cur;
- return (pCsr->pNode==0);
-}
-
-/*
-** Cursor pCursor currently points to a cell in a non-leaf page.
-** Return true if the sub-tree headed by the cell is filtered
-** (excluded) by the constraints in the pCursor->aConstraint[]
-** array, or false otherwise.
-*/
-static int testRtreeCell(Rtree *pRtree, RtreeCursor *pCursor){
- RtreeCell cell;
- int ii;
- int bRes = 0;
-
- nodeGetCell(pRtree, pCursor->pNode, pCursor->iCell, &cell);
- for(ii=0; bRes==0 && ii<pCursor->nConstraint; ii++){
- RtreeConstraint *p = &pCursor->aConstraint[ii];
- double cell_min = DCOORD(cell.aCoord[(p->iCoord>>1)*2]);
- double cell_max = DCOORD(cell.aCoord[(p->iCoord>>1)*2+1]);
-
- assert(p->op==RTREE_LE || p->op==RTREE_LT || p->op==RTREE_GE
- || p->op==RTREE_GT || p->op==RTREE_EQ
- );
-
- switch( p->op ){
- case RTREE_LE: case RTREE_LT: bRes = p->rValue<cell_min; break;
- case RTREE_GE: case RTREE_GT: bRes = p->rValue>cell_max; break;
- case RTREE_EQ:
- bRes = (p->rValue>cell_max || p->rValue<cell_min);
- break;
- }
- }
-
- return bRes;
-}
-
-/*
-** Return true if the cell that cursor pCursor currently points to
-** would be filtered (excluded) by the constraints in the
-** pCursor->aConstraint[] array, or false otherwise.
-**
-** This function assumes that the cell is part of a leaf node.
-*/
-static int testRtreeEntry(Rtree *pRtree, RtreeCursor *pCursor){
- RtreeCell cell;
- int ii;
-
- nodeGetCell(pRtree, pCursor->pNode, pCursor->iCell, &cell);
- for(ii=0; ii<pCursor->nConstraint; ii++){
- RtreeConstraint *p = &pCursor->aConstraint[ii];
- double coord = DCOORD(cell.aCoord[p->iCoord]);
- int res;
- assert(p->op==RTREE_LE || p->op==RTREE_LT || p->op==RTREE_GE
- || p->op==RTREE_GT || p->op==RTREE_EQ
- );
- switch( p->op ){
- case RTREE_LE: res = (coord<=p->rValue); break;
- case RTREE_LT: res = (coord<p->rValue); break;
- case RTREE_GE: res = (coord>=p->rValue); break;
- case RTREE_GT: res = (coord>p->rValue); break;
- case RTREE_EQ: res = (coord==p->rValue); break;
- }
-
- if( !res ) return 1;
- }
-
- return 0;
-}
-
-/*
-** Cursor pCursor currently points at a node that heads a sub-tree of
-** height iHeight (if iHeight==0, then the node is a leaf). Descend
-** to point to the left-most cell of the sub-tree that matches the
-** configured constraints.
-*/
-static int descendToCell(
- Rtree *pRtree,
- RtreeCursor *pCursor,
- int iHeight,
- int *pEof /* OUT: Set to true if cannot descend */
-){
- int isEof;
- int rc;
- int ii;
- RtreeNode *pChild;
- sqlite3_int64 iRowid;
-
- RtreeNode *pSavedNode = pCursor->pNode;
- int iSavedCell = pCursor->iCell;
-
- assert( iHeight>=0 );
-
- if( iHeight==0 ){
- isEof = testRtreeEntry(pRtree, pCursor);
- }else{
- isEof = testRtreeCell(pRtree, pCursor);
- }
- if( isEof || iHeight==0 ){
- *pEof = isEof;
- return SQLITE_OK;
- }
-
- iRowid = nodeGetRowid(pRtree, pCursor->pNode, pCursor->iCell);
- rc = nodeAcquire(pRtree, iRowid, pCursor->pNode, &pChild);
- if( rc!=SQLITE_OK ){
- return rc;
- }
-
- nodeRelease(pRtree, pCursor->pNode);
- pCursor->pNode = pChild;
- isEof = 1;
- for(ii=0; isEof && ii<NCELL(pChild); ii++){
- pCursor->iCell = ii;
- rc = descendToCell(pRtree, pCursor, iHeight-1, &isEof);
- if( rc!=SQLITE_OK ){
- return rc;
- }
- }
-
- if( isEof ){
- assert( pCursor->pNode==pChild );
- nodeReference(pSavedNode);
- nodeRelease(pRtree, pChild);
- pCursor->pNode = pSavedNode;
- pCursor->iCell = iSavedCell;
- }
-
- *pEof = isEof;
- return SQLITE_OK;
-}
-
-/*
-** One of the cells in node pNode is guaranteed to have a 64-bit
-** integer value equal to iRowid. Return the index of this cell.
-*/
-static int nodeRowidIndex(Rtree *pRtree, RtreeNode *pNode, i64 iRowid){
- int ii;
- for(ii=0; nodeGetRowid(pRtree, pNode, ii)!=iRowid; ii++){
- assert( ii<(NCELL(pNode)-1) );
- }
- return ii;
-}
-
-/*
-** Return the index of the cell containing a pointer to node pNode
-** in its parent. If pNode is the root node, return -1.
-*/
-static int nodeParentIndex(Rtree *pRtree, RtreeNode *pNode){
- RtreeNode *pParent = pNode->pParent;
- if( pParent ){
- return nodeRowidIndex(pRtree, pParent, pNode->iNode);
- }
- return -1;
-}
-
-/*
-** Rtree virtual table module xNext method.
-*/
-static int rtreeNext(sqlite3_vtab_cursor *pVtabCursor){
- Rtree *pRtree = (Rtree *)(pVtabCursor->pVtab);
- RtreeCursor *pCsr = (RtreeCursor *)pVtabCursor;
- int rc = SQLITE_OK;
-
- if( pCsr->iStrategy==1 ){
- /* This "scan" is a direct lookup by rowid. There is no next entry. */
- nodeRelease(pRtree, pCsr->pNode);
- pCsr->pNode = 0;
- }
-
- else if( pCsr->pNode ){
- /* Move to the next entry that matches the configured constraints. */
- int iHeight = 0;
- while( pCsr->pNode ){
- RtreeNode *pNode = pCsr->pNode;
- int nCell = NCELL(pNode);
- for(pCsr->iCell++; pCsr->iCell<nCell; pCsr->iCell++){
- int isEof;
- rc = descendToCell(pRtree, pCsr, iHeight, &isEof);
- if( rc!=SQLITE_OK || !isEof ){
- return rc;
- }
- }
- pCsr->pNode = pNode->pParent;
- pCsr->iCell = nodeParentIndex(pRtree, pNode);
- nodeReference(pCsr->pNode);
- nodeRelease(pRtree, pNode);
- iHeight++;
- }
- }
-
- return rc;
-}
-
-/*
-** Rtree virtual table module xRowid method.
-*/
-static int rtreeRowid(sqlite3_vtab_cursor *pVtabCursor, sqlite_int64 *pRowid){
- Rtree *pRtree = (Rtree *)pVtabCursor->pVtab;
- RtreeCursor *pCsr = (RtreeCursor *)pVtabCursor;
-
- assert(pCsr->pNode);
- *pRowid = nodeGetRowid(pRtree, pCsr->pNode, pCsr->iCell);
-
- return SQLITE_OK;
-}
-
-/*
-** Rtree virtual table module xColumn method.
-*/
-static int rtreeColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){
- Rtree *pRtree = (Rtree *)cur->pVtab;
- RtreeCursor *pCsr = (RtreeCursor *)cur;
-
- if( i==0 ){
- i64 iRowid = nodeGetRowid(pRtree, pCsr->pNode, pCsr->iCell);
- sqlite3_result_int64(ctx, iRowid);
- }else{
- RtreeCoord c;
- nodeGetCoord(pRtree, pCsr->pNode, pCsr->iCell, i-1, &c);
- if( pRtree->eCoordType==RTREE_COORD_REAL32 ){
- sqlite3_result_double(ctx, c.f);
- }else{
- assert( pRtree->eCoordType==RTREE_COORD_INT32 );
- sqlite3_result_int(ctx, c.i);
- }
- }
-
- return SQLITE_OK;
-}
-
-/*
-** Use nodeAcquire() to obtain the leaf node containing the record with
-** rowid iRowid. If successful, set *ppLeaf to point to the node and
-** return SQLITE_OK. If there is no such record in the table, set
-** *ppLeaf to 0 and return SQLITE_OK. If an error occurs, set *ppLeaf
-** to zero and return an SQLite error code.
-*/
-static int findLeafNode(Rtree *pRtree, i64 iRowid, RtreeNode **ppLeaf){
- int rc;
- *ppLeaf = 0;
- sqlite3_bind_int64(pRtree->pReadRowid, 1, iRowid);
- if( sqlite3_step(pRtree->pReadRowid)==SQLITE_ROW ){
- i64 iNode = sqlite3_column_int64(pRtree->pReadRowid, 0);
- rc = nodeAcquire(pRtree, iNode, 0, ppLeaf);
- sqlite3_reset(pRtree->pReadRowid);
- }else{
- rc = sqlite3_reset(pRtree->pReadRowid);
- }
- return rc;
-}
-
-
-/*
-** Rtree virtual table module xFilter method.
-*/
-static int rtreeFilter(
- sqlite3_vtab_cursor *pVtabCursor,
- int idxNum, const char *idxStr,
- int argc, sqlite3_value **argv
-){
- Rtree *pRtree = (Rtree *)pVtabCursor->pVtab;
- RtreeCursor *pCsr = (RtreeCursor *)pVtabCursor;
-
- RtreeNode *pRoot = 0;
- int ii;
- int rc = SQLITE_OK;
-
- rtreeReference(pRtree);
-
- sqlite3_free(pCsr->aConstraint);
- pCsr->aConstraint = 0;
- pCsr->iStrategy = idxNum;
-
- if( idxNum==1 ){
- /* Special case - lookup by rowid. */
- RtreeNode *pLeaf; /* Leaf on which the required cell resides */
- i64 iRowid = sqlite3_value_int64(argv[0]);
- rc = findLeafNode(pRtree, iRowid, &pLeaf);
- pCsr->pNode = pLeaf;
- if( pLeaf && rc==SQLITE_OK ){
- pCsr->iCell = nodeRowidIndex(pRtree, pLeaf, iRowid);
- }
- }else{
- /* Normal case - r-tree scan. Set up the RtreeCursor.aConstraint array
- ** with the configured constraints.
- */
- if( argc>0 ){
- pCsr->aConstraint = sqlite3_malloc(sizeof(RtreeConstraint)*argc);
- pCsr->nConstraint = argc;
- if( !pCsr->aConstraint ){
- rc = SQLITE_NOMEM;
- }else{
- assert( (idxStr==0 && argc==0) || strlen(idxStr)==argc*2 );
- for(ii=0; ii<argc; ii++){
- RtreeConstraint *p = &pCsr->aConstraint[ii];
- p->op = idxStr[ii*2];
- p->iCoord = idxStr[ii*2+1]-'a';
- p->rValue = sqlite3_value_double(argv[ii]);
- }
- }
- }
-
- if( rc==SQLITE_OK ){
- pCsr->pNode = 0;
- rc = nodeAcquire(pRtree, 1, 0, &pRoot);
- }
- if( rc==SQLITE_OK ){
- int isEof = 1;
- int nCell = NCELL(pRoot);
- pCsr->pNode = pRoot;
- for(pCsr->iCell=0; rc==SQLITE_OK && pCsr->iCell<nCell; pCsr->iCell++){
- assert( pCsr->pNode==pRoot );
- rc = descendToCell(pRtree, pCsr, pRtree->iDepth, &isEof);
- if( !isEof ){
- break;
- }
- }
- if( rc==SQLITE_OK && isEof ){
- assert( pCsr->pNode==pRoot );
- nodeRelease(pRtree, pRoot);
- pCsr->pNode = 0;
- }
- assert( rc!=SQLITE_OK || !pCsr->pNode || pCsr->iCell<NCELL(pCsr->pNode) );
- }
- }
-
- rtreeRelease(pRtree);
- return rc;
-}
-
-/*
-** Rtree virtual table module xBestIndex method. There are three
-** table scan strategies to choose from (in order from most to
-** least desirable):
-**
-** idxNum idxStr Strategy
-** ------------------------------------------------
-** 1 Unused Direct lookup by rowid.
-** 2 See below R-tree query.
-** 3 Unused Full table scan.
-** ------------------------------------------------
-**
-** If strategy 1 or 3 is used, then idxStr is not meaningful. If strategy
-** 2 is used, idxStr is formatted to contain 2 bytes for each
-** constraint used. The first two bytes of idxStr correspond to
-** the constraint in sqlite3_index_info.aConstraintUsage[] with
-** (argvIndex==1) etc.
-**
-** The first of each pair of bytes in idxStr identifies the constraint
-** operator as follows:
-**
-** Operator Byte Value
-** ----------------------
-** = 0x41 ('A')
-** <= 0x42 ('B')
-** < 0x43 ('C')
-** >= 0x44 ('D')
-** > 0x45 ('E')
-** ----------------------
-**
-** The second of each pair of bytes identifies the coordinate column
-** to which the constraint applies. The leftmost coordinate column
-** is 'a', the second from the left 'b' etc.
-*/
-static int rtreeBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
- int rc = SQLITE_OK;
- int ii, cCol;
-
- int iIdx = 0;
- char zIdxStr[RTREE_MAX_DIMENSIONS*8+1];
- memset(zIdxStr, 0, sizeof(zIdxStr));
-
- assert( pIdxInfo->idxStr==0 );
- for(ii=0; ii<pIdxInfo->nConstraint; ii++){
- struct sqlite3_index_constraint *p = &pIdxInfo->aConstraint[ii];
-
- if( p->usable && p->iColumn==0 && p->op==SQLITE_INDEX_CONSTRAINT_EQ ){
- /* We have an equality constraint on the rowid. Use strategy 1. */
- int jj;
- for(jj=0; jj<ii; jj++){
- pIdxInfo->aConstraintUsage[jj].argvIndex = 0;
- pIdxInfo->aConstraintUsage[jj].omit = 0;
- }
- pIdxInfo->idxNum = 1;
- pIdxInfo->aConstraintUsage[ii].argvIndex = 1;
- pIdxInfo->aConstraintUsage[jj].omit = 1;
-
- /* This strategy involves a two rowid lookups on an B-Tree structures
- ** and then a linear search of an R-Tree node. This should be
- ** considered almost as quick as a direct rowid lookup (for which
- ** sqlite uses an internal cost of 0.0).
- */
- pIdxInfo->estimatedCost = 10.0;
- return SQLITE_OK;
- }
-
- if( p->usable && p->iColumn>0 ){
- u8 op = 0;
- switch( p->op ){
- case SQLITE_INDEX_CONSTRAINT_EQ: op = RTREE_EQ; break;
- case SQLITE_INDEX_CONSTRAINT_GT: op = RTREE_GT; break;
- case SQLITE_INDEX_CONSTRAINT_LE: op = RTREE_LE; break;
- case SQLITE_INDEX_CONSTRAINT_LT: op = RTREE_LT; break;
- case SQLITE_INDEX_CONSTRAINT_GE: op = RTREE_GE; break;
- }
- if( op ){
- /* Make sure this particular constraint has not been used before.
- ** If it has been used before, ignore it.
- **
- ** A <= or < can be used if there is a prior >= or >.
- ** A >= or > can be used if there is a prior < or <=.
- ** A <= or < is disqualified if there is a prior <=, <, or ==.
- ** A >= or > is disqualified if there is a prior >=, >, or ==.
- ** A == is disqualifed if there is any prior constraint.
- */
- int j, opmsk;
- static const unsigned char compatible[] = { 0, 0, 1, 1, 2, 2 };
- assert( compatible[RTREE_EQ & 7]==0 );
- assert( compatible[RTREE_LT & 7]==1 );
- assert( compatible[RTREE_LE & 7]==1 );
- assert( compatible[RTREE_GT & 7]==2 );
- assert( compatible[RTREE_GE & 7]==2 );
- cCol = p->iColumn - 1 + 'a';
- opmsk = compatible[op & 7];
- for(j=0; j<iIdx; j+=2){
- if( zIdxStr[j+1]==cCol && (compatible[zIdxStr[j] & 7] & opmsk)!=0 ){
- op = 0;
- break;
- }
- }
- }
- if( op ){
- assert( iIdx<sizeof(zIdxStr)-1 );
- zIdxStr[iIdx++] = op;
- zIdxStr[iIdx++] = cCol;
- pIdxInfo->aConstraintUsage[ii].argvIndex = (iIdx/2);
- pIdxInfo->aConstraintUsage[ii].omit = 1;
- }
- }
- }
-
- pIdxInfo->idxNum = 2;
- pIdxInfo->needToFreeIdxStr = 1;
- if( iIdx>0 && 0==(pIdxInfo->idxStr = sqlite3_mprintf("%s", zIdxStr)) ){
- return SQLITE_NOMEM;
- }
- assert( iIdx>=0 );
- pIdxInfo->estimatedCost = (2000000.0 / (double)(iIdx + 1));
- return rc;
-}
-
-/*
-** Return the N-dimensional volumn of the cell stored in *p.
-*/
-static float cellArea(Rtree *pRtree, RtreeCell *p){
- float area = 1.0;
- int ii;
- for(ii=0; ii<(pRtree->nDim*2); ii+=2){
- area = area * (DCOORD(p->aCoord[ii+1]) - DCOORD(p->aCoord[ii]));
- }
- return area;
-}
-
-/*
-** Return the margin length of cell p. The margin length is the sum
-** of the objects size in each dimension.
-*/
-static float cellMargin(Rtree *pRtree, RtreeCell *p){
- float margin = 0.0;
- int ii;
- for(ii=0; ii<(pRtree->nDim*2); ii+=2){
- margin += (DCOORD(p->aCoord[ii+1]) - DCOORD(p->aCoord[ii]));
- }
- return margin;
-}
-
-/*
-** Store the union of cells p1 and p2 in p1.
-*/
-static void cellUnion(Rtree *pRtree, RtreeCell *p1, RtreeCell *p2){
- int ii;
- if( pRtree->eCoordType==RTREE_COORD_REAL32 ){
- for(ii=0; ii<(pRtree->nDim*2); ii+=2){
- p1->aCoord[ii].f = MIN(p1->aCoord[ii].f, p2->aCoord[ii].f);
- p1->aCoord[ii+1].f = MAX(p1->aCoord[ii+1].f, p2->aCoord[ii+1].f);
- }
- }else{
- for(ii=0; ii<(pRtree->nDim*2); ii+=2){
- p1->aCoord[ii].i = MIN(p1->aCoord[ii].i, p2->aCoord[ii].i);
- p1->aCoord[ii+1].i = MAX(p1->aCoord[ii+1].i, p2->aCoord[ii+1].i);
- }
- }
-}
-
-/*
-** Return true if the area covered by p2 is a subset of the area covered
-** by p1. False otherwise.
-*/
-static int cellContains(Rtree *pRtree, RtreeCell *p1, RtreeCell *p2){
- int ii;
- int isInt = (pRtree->eCoordType==RTREE_COORD_INT32);
- for(ii=0; ii<(pRtree->nDim*2); ii+=2){
- RtreeCoord *a1 = &p1->aCoord[ii];
- RtreeCoord *a2 = &p2->aCoord[ii];
- if( (!isInt && (a2[0].f<a1[0].f || a2[1].f>a1[1].f))
- || ( isInt && (a2[0].i<a1[0].i || a2[1].i>a1[1].i))
- ){
- return 0;
- }
- }
- return 1;
-}
-
-/*
-** Return the amount cell p would grow by if it were unioned with pCell.
-*/
-static float cellGrowth(Rtree *pRtree, RtreeCell *p, RtreeCell *pCell){
- float area;
- RtreeCell cell;
- memcpy(&cell, p, sizeof(RtreeCell));
- area = cellArea(pRtree, &cell);
- cellUnion(pRtree, &cell, pCell);
- return (cellArea(pRtree, &cell)-area);
-}
-
-#if VARIANT_RSTARTREE_CHOOSESUBTREE || VARIANT_RSTARTREE_SPLIT
-static float cellOverlap(
- Rtree *pRtree,
- RtreeCell *p,
- RtreeCell *aCell,
- int nCell,
- int iExclude
-){
- int ii;
- float overlap = 0.0;
- for(ii=0; ii<nCell; ii++){
- if( ii!=iExclude ){
- int jj;
- float o = 1.0;
- for(jj=0; jj<(pRtree->nDim*2); jj+=2){
- double x1;
- double x2;
-
- x1 = MAX(DCOORD(p->aCoord[jj]), DCOORD(aCell[ii].aCoord[jj]));
- x2 = MIN(DCOORD(p->aCoord[jj+1]), DCOORD(aCell[ii].aCoord[jj+1]));
-
- if( x2<x1 ){
- o = 0.0;
- break;
- }else{
- o = o * (x2-x1);
- }
- }
- overlap += o;
- }
- }
- return overlap;
-}
-#endif
-
-#if VARIANT_RSTARTREE_CHOOSESUBTREE
-static float cellOverlapEnlargement(
- Rtree *pRtree,
- RtreeCell *p,
- RtreeCell *pInsert,
- RtreeCell *aCell,
- int nCell,
- int iExclude
-){
- float before;
- float after;
- before = cellOverlap(pRtree, p, aCell, nCell, iExclude);
- cellUnion(pRtree, p, pInsert);
- after = cellOverlap(pRtree, p, aCell, nCell, iExclude);
- return after-before;
-}
-#endif
-
-
-/*
-** This function implements the ChooseLeaf algorithm from Gutman[84].
-** ChooseSubTree in r*tree terminology.
-*/
-static int ChooseLeaf(
- Rtree *pRtree, /* Rtree table */
- RtreeCell *pCell, /* Cell to insert into rtree */
- int iHeight, /* Height of sub-tree rooted at pCell */
- RtreeNode **ppLeaf /* OUT: Selected leaf page */
-){
- int rc;
- int ii;
- RtreeNode *pNode;
- rc = nodeAcquire(pRtree, 1, 0, &pNode);
-
- for(ii=0; rc==SQLITE_OK && ii<(pRtree->iDepth-iHeight); ii++){
- int iCell;
- sqlite3_int64 iBest;
-
- float fMinGrowth;
- float fMinArea;
- float fMinOverlap;
-
- int nCell = NCELL(pNode);
- RtreeCell cell;
- RtreeNode *pChild;
-
- RtreeCell *aCell = 0;
-
-#if VARIANT_RSTARTREE_CHOOSESUBTREE
- if( ii==(pRtree->iDepth-1) ){
- int jj;
- aCell = sqlite3_malloc(sizeof(RtreeCell)*nCell);
- if( !aCell ){
- rc = SQLITE_NOMEM;
- nodeRelease(pRtree, pNode);
- pNode = 0;
- continue;
- }
- for(jj=0; jj<nCell; jj++){
- nodeGetCell(pRtree, pNode, jj, &aCell[jj]);
- }
- }
-#endif
-
- /* Select the child node which will be enlarged the least if pCell
- ** is inserted into it. Resolve ties by choosing the entry with
- ** the smallest area.
- */
- for(iCell=0; iCell<nCell; iCell++){
- float growth;
- float area;
- float overlap = 0.0;
- nodeGetCell(pRtree, pNode, iCell, &cell);
- growth = cellGrowth(pRtree, &cell, pCell);
- area = cellArea(pRtree, &cell);
-#if VARIANT_RSTARTREE_CHOOSESUBTREE
- if( ii==(pRtree->iDepth-1) ){
- overlap = cellOverlapEnlargement(pRtree,&cell,pCell,aCell,nCell,iCell);
- }
-#endif
- if( (iCell==0)
- || (overlap<fMinOverlap)
- || (overlap==fMinOverlap && growth<fMinGrowth)
- || (overlap==fMinOverlap && growth==fMinGrowth && area<fMinArea)
- ){
- fMinOverlap = overlap;
- fMinGrowth = growth;
- fMinArea = area;
- iBest = cell.iRowid;
- }
- }
-
- sqlite3_free(aCell);
- rc = nodeAcquire(pRtree, iBest, pNode, &pChild);
- nodeRelease(pRtree, pNode);
- pNode = pChild;
- }
-
- *ppLeaf = pNode;
- return rc;
-}
-
-/*
-** A cell with the same content as pCell has just been inserted into
-** the node pNode. This function updates the bounding box cells in
-** all ancestor elements.
-*/
-static void AdjustTree(
- Rtree *pRtree, /* Rtree table */
- RtreeNode *pNode, /* Adjust ancestry of this node. */
- RtreeCell *pCell /* This cell was just inserted */
-){
- RtreeNode *p = pNode;
- while( p->pParent ){
- RtreeCell cell;
- RtreeNode *pParent = p->pParent;
- int iCell = nodeParentIndex(pRtree, p);
-
- nodeGetCell(pRtree, pParent, iCell, &cell);
- if( !cellContains(pRtree, &cell, pCell) ){
- cellUnion(pRtree, &cell, pCell);
- nodeOverwriteCell(pRtree, pParent, &cell, iCell);
- }
-
- p = pParent;
- }
-}
-
-/*
-** Write mapping (iRowid->iNode) to the <rtree>_rowid table.
-*/
-static int rowidWrite(Rtree *pRtree, sqlite3_int64 iRowid, sqlite3_int64 iNode){
- sqlite3_bind_int64(pRtree->pWriteRowid, 1, iRowid);
- sqlite3_bind_int64(pRtree->pWriteRowid, 2, iNode);
- sqlite3_step(pRtree->pWriteRowid);
- return sqlite3_reset(pRtree->pWriteRowid);
-}
-
-/*
-** Write mapping (iNode->iPar) to the <rtree>_parent table.
-*/
-static int parentWrite(Rtree *pRtree, sqlite3_int64 iNode, sqlite3_int64 iPar){
- sqlite3_bind_int64(pRtree->pWriteParent, 1, iNode);
- sqlite3_bind_int64(pRtree->pWriteParent, 2, iPar);
- sqlite3_step(pRtree->pWriteParent);
- return sqlite3_reset(pRtree->pWriteParent);
-}
-
-static int rtreeInsertCell(Rtree *, RtreeNode *, RtreeCell *, int);
-
-#if VARIANT_GUTTMAN_LINEAR_SPLIT
-/*
-** Implementation of the linear variant of the PickNext() function from
-** Guttman[84].
-*/
-static RtreeCell *LinearPickNext(
- Rtree *pRtree,
- RtreeCell *aCell,
- int nCell,
- RtreeCell *pLeftBox,
- RtreeCell *pRightBox,
- int *aiUsed
-){
- int ii;
- for(ii=0; aiUsed[ii]; ii++);
- aiUsed[ii] = 1;
- return &aCell[ii];
-}
-
-/*
-** Implementation of the linear variant of the PickSeeds() function from
-** Guttman[84].
-*/
-static void LinearPickSeeds(
- Rtree *pRtree,
- RtreeCell *aCell,
- int nCell,
- int *piLeftSeed,
- int *piRightSeed
-){
- int i;
- int iLeftSeed = 0;
- int iRightSeed = 1;
- float maxNormalInnerWidth = 0.0;
-
- /* Pick two "seed" cells from the array of cells. The algorithm used
- ** here is the LinearPickSeeds algorithm from Gutman[1984]. The
- ** indices of the two seed cells in the array are stored in local
- ** variables iLeftSeek and iRightSeed.
- */
- for(i=0; i<pRtree->nDim; i++){
- float x1 = aCell[0].aCoord[i*2];
- float x2 = aCell[0].aCoord[i*2+1];
- float x3 = x1;
- float x4 = x2;
- int jj;
-
- int iCellLeft = 0;
- int iCellRight = 0;
-
- for(jj=1; jj<nCell; jj++){
- float left = aCell[jj].aCoord[i*2];
- float right = aCell[jj].aCoord[i*2+1];
-
- if( left<x1 ) x1 = left;
- if( right>x4 ) x4 = right;
- if( left>x3 ){
- x3 = left;
- iCellRight = jj;
- }
- if( right<x2 ){
- x2 = right;
- iCellLeft = jj;
- }
- }
-
- if( x4!=x1 ){
- float normalwidth = (x3 - x2) / (x4 - x1);
- if( normalwidth>maxNormalInnerWidth ){
- iLeftSeed = iCellLeft;
- iRightSeed = iCellRight;
- }
- }
- }
-
- *piLeftSeed = iLeftSeed;
- *piRightSeed = iRightSeed;
-}
-#endif /* VARIANT_GUTTMAN_LINEAR_SPLIT */
-
-#if VARIANT_GUTTMAN_QUADRATIC_SPLIT
-/*
-** Implementation of the quadratic variant of the PickNext() function from
-** Guttman[84].
-*/
-static RtreeCell *QuadraticPickNext(
- Rtree *pRtree,
- RtreeCell *aCell,
- int nCell,
- RtreeCell *pLeftBox,
- RtreeCell *pRightBox,
- int *aiUsed
-){
- #define FABS(a) ((a)<0.0?-1.0*(a):(a))
-
- int iSelect = -1;
- float fDiff;
- int ii;
- for(ii=0; ii<nCell; ii++){
- if( aiUsed[ii]==0 ){
- float left = cellGrowth(pRtree, pLeftBox, &aCell[ii]);
- float right = cellGrowth(pRtree, pLeftBox, &aCell[ii]);
- float diff = FABS(right-left);
- if( iSelect<0 || diff>fDiff ){
- fDiff = diff;
- iSelect = ii;
- }
- }
- }
- aiUsed[iSelect] = 1;
- return &aCell[iSelect];
-}
-
-/*
-** Implementation of the quadratic variant of the PickSeeds() function from
-** Guttman[84].
-*/
-static void QuadraticPickSeeds(
- Rtree *pRtree,
- RtreeCell *aCell,
- int nCell,
- int *piLeftSeed,
- int *piRightSeed
-){
- int ii;
- int jj;
-
- int iLeftSeed = 0;
- int iRightSeed = 1;
- float fWaste = 0.0;
-
- for(ii=0; ii<nCell; ii++){
- for(jj=ii+1; jj<nCell; jj++){
- float right = cellArea(pRtree, &aCell[jj]);
- float growth = cellGrowth(pRtree, &aCell[ii], &aCell[jj]);
- float waste = growth - right;
-
- if( waste>fWaste ){
- iLeftSeed = ii;
- iRightSeed = jj;
- fWaste = waste;
- }
- }
- }
-
- *piLeftSeed = iLeftSeed;
- *piRightSeed = iRightSeed;
-}
-#endif /* VARIANT_GUTTMAN_QUADRATIC_SPLIT */
-
-/*
-** Arguments aIdx, aDistance and aSpare all point to arrays of size
-** nIdx. The aIdx array contains the set of integers from 0 to
-** (nIdx-1) in no particular order. This function sorts the values
-** in aIdx according to the indexed values in aDistance. For
-** example, assuming the inputs:
-**
-** aIdx = { 0, 1, 2, 3 }
-** aDistance = { 5.0, 2.0, 7.0, 6.0 }
-**
-** this function sets the aIdx array to contain:
-**
-** aIdx = { 0, 1, 2, 3 }
-**
-** The aSpare array is used as temporary working space by the
-** sorting algorithm.
-*/
-static void SortByDistance(
- int *aIdx,
- int nIdx,
- float *aDistance,
- int *aSpare
-){
- if( nIdx>1 ){
- int iLeft = 0;
- int iRight = 0;
-
- int nLeft = nIdx/2;
- int nRight = nIdx-nLeft;
- int *aLeft = aIdx;
- int *aRight = &aIdx[nLeft];
-
- SortByDistance(aLeft, nLeft, aDistance, aSpare);
- SortByDistance(aRight, nRight, aDistance, aSpare);
-
- memcpy(aSpare, aLeft, sizeof(int)*nLeft);
- aLeft = aSpare;
-
- while( iLeft<nLeft || iRight<nRight ){
- if( iLeft==nLeft ){
- aIdx[iLeft+iRight] = aRight[iRight];
- iRight++;
- }else if( iRight==nRight ){
- aIdx[iLeft+iRight] = aLeft[iLeft];
- iLeft++;
- }else{
- float fLeft = aDistance[aLeft[iLeft]];
- float fRight = aDistance[aRight[iRight]];
- if( fLeft<fRight ){
- aIdx[iLeft+iRight] = aLeft[iLeft];
- iLeft++;
- }else{
- aIdx[iLeft+iRight] = aRight[iRight];
- iRight++;
- }
- }
- }
-
-#if 0
- /* Check that the sort worked */
- {
- int jj;
- for(jj=1; jj<nIdx; jj++){
- float left = aDistance[aIdx[jj-1]];
- float right = aDistance[aIdx[jj]];
- assert( left<=right );
- }
- }
-#endif
- }
-}
-
-/*
-** Arguments aIdx, aCell and aSpare all point to arrays of size
-** nIdx. The aIdx array contains the set of integers from 0 to
-** (nIdx-1) in no particular order. This function sorts the values
-** in aIdx according to dimension iDim of the cells in aCell. The
-** minimum value of dimension iDim is considered first, the
-** maximum used to break ties.
-**
-** The aSpare array is used as temporary working space by the
-** sorting algorithm.
-*/
-static void SortByDimension(
- Rtree *pRtree,
- int *aIdx,
- int nIdx,
- int iDim,
- RtreeCell *aCell,
- int *aSpare
-){
- if( nIdx>1 ){
-
- int iLeft = 0;
- int iRight = 0;
-
- int nLeft = nIdx/2;
- int nRight = nIdx-nLeft;
- int *aLeft = aIdx;
- int *aRight = &aIdx[nLeft];
-
- SortByDimension(pRtree, aLeft, nLeft, iDim, aCell, aSpare);
- SortByDimension(pRtree, aRight, nRight, iDim, aCell, aSpare);
-
- memcpy(aSpare, aLeft, sizeof(int)*nLeft);
- aLeft = aSpare;
- while( iLeft<nLeft || iRight<nRight ){
- double xleft1 = DCOORD(aCell[aLeft[iLeft]].aCoord[iDim*2]);
- double xleft2 = DCOORD(aCell[aLeft[iLeft]].aCoord[iDim*2+1]);
- double xright1 = DCOORD(aCell[aRight[iRight]].aCoord[iDim*2]);
- double xright2 = DCOORD(aCell[aRight[iRight]].aCoord[iDim*2+1]);
- if( (iLeft!=nLeft) && ((iRight==nRight)
- || (xleft1<xright1)
- || (xleft1==xright1 && xleft2<xright2)
- )){
- aIdx[iLeft+iRight] = aLeft[iLeft];
- iLeft++;
- }else{
- aIdx[iLeft+iRight] = aRight[iRight];
- iRight++;
- }
- }
-
-#if 0
- /* Check that the sort worked */
- {
- int jj;
- for(jj=1; jj<nIdx; jj++){
- float xleft1 = aCell[aIdx[jj-1]].aCoord[iDim*2];
- float xleft2 = aCell[aIdx[jj-1]].aCoord[iDim*2+1];
- float xright1 = aCell[aIdx[jj]].aCoord[iDim*2];
- float xright2 = aCell[aIdx[jj]].aCoord[iDim*2+1];
- assert( xleft1<=xright1 && (xleft1<xright1 || xleft2<=xright2) );
- }
- }
-#endif
- }
-}
-
-#if VARIANT_RSTARTREE_SPLIT
-/*
-** Implementation of the R*-tree variant of SplitNode from Beckman[1990].
-*/
-static int splitNodeStartree(
- Rtree *pRtree,
- RtreeCell *aCell,
- int nCell,
- RtreeNode *pLeft,
- RtreeNode *pRight,
- RtreeCell *pBboxLeft,
- RtreeCell *pBboxRight
-){
- int **aaSorted;
- int *aSpare;
- int ii;
-
- int iBestDim;
- int iBestSplit;
- float fBestMargin;
-
- int nByte = (pRtree->nDim+1)*(sizeof(int*)+nCell*sizeof(int));
-
- aaSorted = (int **)sqlite3_malloc(nByte);
- if( !aaSorted ){
- return SQLITE_NOMEM;
- }
-
- aSpare = &((int *)&aaSorted[pRtree->nDim])[pRtree->nDim*nCell];
- memset(aaSorted, 0, nByte);
- for(ii=0; ii<pRtree->nDim; ii++){
- int jj;
- aaSorted[ii] = &((int *)&aaSorted[pRtree->nDim])[ii*nCell];
- for(jj=0; jj<nCell; jj++){
- aaSorted[ii][jj] = jj;
- }
- SortByDimension(pRtree, aaSorted[ii], nCell, ii, aCell, aSpare);
- }
-
- for(ii=0; ii<pRtree->nDim; ii++){
- float margin = 0.0;
- float fBestOverlap;
- float fBestArea;
- int iBestLeft;
- int nLeft;
-
- for(
- nLeft=RTREE_MINCELLS(pRtree);
- nLeft<=(nCell-RTREE_MINCELLS(pRtree));
- nLeft++
- ){
- RtreeCell left;
- RtreeCell right;
- int kk;
- float overlap;
- float area;
-
- memcpy(&left, &aCell[aaSorted[ii][0]], sizeof(RtreeCell));
- memcpy(&right, &aCell[aaSorted[ii][nCell-1]], sizeof(RtreeCell));
- for(kk=1; kk<(nCell-1); kk++){
- if( kk<nLeft ){
- cellUnion(pRtree, &left, &aCell[aaSorted[ii][kk]]);
- }else{
- cellUnion(pRtree, &right, &aCell[aaSorted[ii][kk]]);
- }
- }
- margin += cellMargin(pRtree, &left);
- margin += cellMargin(pRtree, &right);
- overlap = cellOverlap(pRtree, &left, &right, 1, -1);
- area = cellArea(pRtree, &left) + cellArea(pRtree, &right);
- if( (nLeft==RTREE_MINCELLS(pRtree))
- || (overlap<fBestOverlap)
- || (overlap==fBestOverlap && area<fBestArea)
- ){
- iBestLeft = nLeft;
- fBestOverlap = overlap;
- fBestArea = area;
- }
- }
-
- if( ii==0 || margin<fBestMargin ){
- iBestDim = ii;
- fBestMargin = margin;
- iBestSplit = iBestLeft;
- }
- }
-
- memcpy(pBboxLeft, &aCell[aaSorted[iBestDim][0]], sizeof(RtreeCell));
- memcpy(pBboxRight, &aCell[aaSorted[iBestDim][iBestSplit]], sizeof(RtreeCell));
- for(ii=0; ii<nCell; ii++){
- RtreeNode *pTarget = (ii<iBestSplit)?pLeft:pRight;
- RtreeCell *pBbox = (ii<iBestSplit)?pBboxLeft:pBboxRight;
- RtreeCell *pCell = &aCell[aaSorted[iBestDim][ii]];
- nodeInsertCell(pRtree, pTarget, pCell);
- cellUnion(pRtree, pBbox, pCell);
- }
-
- sqlite3_free(aaSorted);
- return SQLITE_OK;
-}
-#endif
-
-#if VARIANT_GUTTMAN_SPLIT
-/*
-** Implementation of the regular R-tree SplitNode from Guttman[1984].
-*/
-static int splitNodeGuttman(
- Rtree *pRtree,
- RtreeCell *aCell,
- int nCell,
- RtreeNode *pLeft,
- RtreeNode *pRight,
- RtreeCell *pBboxLeft,
- RtreeCell *pBboxRight
-){
- int iLeftSeed = 0;
- int iRightSeed = 1;
- int *aiUsed;
- int i;
-
- aiUsed = sqlite3_malloc(sizeof(int)*nCell);
- memset(aiUsed, 0, sizeof(int)*nCell);
-
- PickSeeds(pRtree, aCell, nCell, &iLeftSeed, &iRightSeed);
-
- memcpy(pBboxLeft, &aCell[iLeftSeed], sizeof(RtreeCell));
- memcpy(pBboxRight, &aCell[iRightSeed], sizeof(RtreeCell));
- nodeInsertCell(pRtree, pLeft, &aCell[iLeftSeed]);
- nodeInsertCell(pRtree, pRight, &aCell[iRightSeed]);
- aiUsed[iLeftSeed] = 1;
- aiUsed[iRightSeed] = 1;
-
- for(i=nCell-2; i>0; i--){
- RtreeCell *pNext;
- pNext = PickNext(pRtree, aCell, nCell, pBboxLeft, pBboxRight, aiUsed);
- float diff =
- cellGrowth(pRtree, pBboxLeft, pNext) -
- cellGrowth(pRtree, pBboxRight, pNext)
- ;
- if( (RTREE_MINCELLS(pRtree)-NCELL(pRight)==i)
- || (diff>0.0 && (RTREE_MINCELLS(pRtree)-NCELL(pLeft)!=i))
- ){
- nodeInsertCell(pRtree, pRight, pNext);
- cellUnion(pRtree, pBboxRight, pNext);
- }else{
- nodeInsertCell(pRtree, pLeft, pNext);
- cellUnion(pRtree, pBboxLeft, pNext);
- }
- }
-
- sqlite3_free(aiUsed);
- return SQLITE_OK;
-}
-#endif
-
-static int updateMapping(
- Rtree *pRtree,
- i64 iRowid,
- RtreeNode *pNode,
- int iHeight
-){
- int (*xSetMapping)(Rtree *, sqlite3_int64, sqlite3_int64);
- xSetMapping = ((iHeight==0)?rowidWrite:parentWrite);
- if( iHeight>0 ){
- RtreeNode *pChild = nodeHashLookup(pRtree, iRowid);
- if( pChild ){
- nodeRelease(pRtree, pChild->pParent);
- nodeReference(pNode);
- pChild->pParent = pNode;
- }
- }
- return xSetMapping(pRtree, iRowid, pNode->iNode);
-}
-
-static int SplitNode(
- Rtree *pRtree,
- RtreeNode *pNode,
- RtreeCell *pCell,
- int iHeight
-){
- int i;
- int newCellIsRight = 0;
-
- int rc = SQLITE_OK;
- int nCell = NCELL(pNode);
- RtreeCell *aCell;
- int *aiUsed;
-
- RtreeNode *pLeft = 0;
- RtreeNode *pRight = 0;
-
- RtreeCell leftbbox;
- RtreeCell rightbbox;
-
- /* Allocate an array and populate it with a copy of pCell and
- ** all cells from node pLeft. Then zero the original node.
- */
- aCell = sqlite3_malloc((sizeof(RtreeCell)+sizeof(int))*(nCell+1));
- if( !aCell ){
- rc = SQLITE_NOMEM;
- goto splitnode_out;
- }
- aiUsed = (int *)&aCell[nCell+1];
- memset(aiUsed, 0, sizeof(int)*(nCell+1));
- for(i=0; i<nCell; i++){
- nodeGetCell(pRtree, pNode, i, &aCell[i]);
- }
- nodeZero(pRtree, pNode);
- memcpy(&aCell[nCell], pCell, sizeof(RtreeCell));
- nCell++;
-
- if( pNode->iNode==1 ){
- pRight = nodeNew(pRtree, pNode, 1);
- pLeft = nodeNew(pRtree, pNode, 1);
- pRtree->iDepth++;
- pNode->isDirty = 1;
- writeInt16(pNode->zData, pRtree->iDepth);
- }else{
- pLeft = pNode;
- pRight = nodeNew(pRtree, pLeft->pParent, 1);
- nodeReference(pLeft);
- }
-
- if( !pLeft || !pRight ){
- rc = SQLITE_NOMEM;
- goto splitnode_out;
- }
-
- memset(pLeft->zData, 0, pRtree->iNodeSize);
- memset(pRight->zData, 0, pRtree->iNodeSize);
-
- rc = AssignCells(pRtree, aCell, nCell, pLeft, pRight, &leftbbox, &rightbbox);
- if( rc!=SQLITE_OK ){
- goto splitnode_out;
- }
-
- /* Ensure both child nodes have node numbers assigned to them. */
- if( (0==pRight->iNode && SQLITE_OK!=(rc = nodeWrite(pRtree, pRight)))
- || (0==pLeft->iNode && SQLITE_OK!=(rc = nodeWrite(pRtree, pLeft)))
- ){
- goto splitnode_out;
- }
-
- rightbbox.iRowid = pRight->iNode;
- leftbbox.iRowid = pLeft->iNode;
-
- if( pNode->iNode==1 ){
- rc = rtreeInsertCell(pRtree, pLeft->pParent, &leftbbox, iHeight+1);
- if( rc!=SQLITE_OK ){
- goto splitnode_out;
- }
- }else{
- RtreeNode *pParent = pLeft->pParent;
- int iCell = nodeParentIndex(pRtree, pLeft);
- nodeOverwriteCell(pRtree, pParent, &leftbbox, iCell);
- AdjustTree(pRtree, pParent, &leftbbox);
- }
- if( (rc = rtreeInsertCell(pRtree, pRight->pParent, &rightbbox, iHeight+1)) ){
- goto splitnode_out;
- }
-
- for(i=0; i<NCELL(pRight); i++){
- i64 iRowid = nodeGetRowid(pRtree, pRight, i);
- rc = updateMapping(pRtree, iRowid, pRight, iHeight);
- if( iRowid==pCell->iRowid ){
- newCellIsRight = 1;
- }
- if( rc!=SQLITE_OK ){
- goto splitnode_out;
- }
- }
- if( pNode->iNode==1 ){
- for(i=0; i<NCELL(pLeft); i++){
- i64 iRowid = nodeGetRowid(pRtree, pLeft, i);
- rc = updateMapping(pRtree, iRowid, pLeft, iHeight);
- if( rc!=SQLITE_OK ){
- goto splitnode_out;
- }
- }
- }else if( newCellIsRight==0 ){
- rc = updateMapping(pRtree, pCell->iRowid, pLeft, iHeight);
- }
-
- if( rc==SQLITE_OK ){
- rc = nodeRelease(pRtree, pRight);
- pRight = 0;
- }
- if( rc==SQLITE_OK ){
- rc = nodeRelease(pRtree, pLeft);
- pLeft = 0;
- }
-
-splitnode_out:
- nodeRelease(pRtree, pRight);
- nodeRelease(pRtree, pLeft);
- sqlite3_free(aCell);
- return rc;
-}
-
-static int fixLeafParent(Rtree *pRtree, RtreeNode *pLeaf){
- int rc = SQLITE_OK;
- if( pLeaf->iNode!=1 && pLeaf->pParent==0 ){
- sqlite3_bind_int64(pRtree->pReadParent, 1, pLeaf->iNode);
- if( sqlite3_step(pRtree->pReadParent)==SQLITE_ROW ){
- i64 iNode = sqlite3_column_int64(pRtree->pReadParent, 0);
- rc = nodeAcquire(pRtree, iNode, 0, &pLeaf->pParent);
- }else{
- rc = SQLITE_ERROR;
- }
- sqlite3_reset(pRtree->pReadParent);
- if( rc==SQLITE_OK ){
- rc = fixLeafParent(pRtree, pLeaf->pParent);
- }
- }
- return rc;
-}
-
-static int deleteCell(Rtree *, RtreeNode *, int, int);
-
-static int removeNode(Rtree *pRtree, RtreeNode *pNode, int iHeight){
- int rc;
- RtreeNode *pParent;
- int iCell;
-
- assert( pNode->nRef==1 );
-
- /* Remove the entry in the parent cell. */
- iCell = nodeParentIndex(pRtree, pNode);
- pParent = pNode->pParent;
- pNode->pParent = 0;
- if( SQLITE_OK!=(rc = deleteCell(pRtree, pParent, iCell, iHeight+1))
- || SQLITE_OK!=(rc = nodeRelease(pRtree, pParent))
- ){
- return rc;
- }
-
- /* Remove the xxx_node entry. */
- sqlite3_bind_int64(pRtree->pDeleteNode, 1, pNode->iNode);
- sqlite3_step(pRtree->pDeleteNode);
- if( SQLITE_OK!=(rc = sqlite3_reset(pRtree->pDeleteNode)) ){
- return rc;
- }
-
- /* Remove the xxx_parent entry. */
- sqlite3_bind_int64(pRtree->pDeleteParent, 1, pNode->iNode);
- sqlite3_step(pRtree->pDeleteParent);
- if( SQLITE_OK!=(rc = sqlite3_reset(pRtree->pDeleteParent)) ){
- return rc;
- }
-
- /* Remove the node from the in-memory hash table and link it into
- ** the Rtree.pDeleted list. Its contents will be re-inserted later on.
- */
- nodeHashDelete(pRtree, pNode);
- pNode->iNode = iHeight;
- pNode->pNext = pRtree->pDeleted;
- pNode->nRef++;
- pRtree->pDeleted = pNode;
-
- return SQLITE_OK;
-}
-
-static void fixBoundingBox(Rtree *pRtree, RtreeNode *pNode){
- RtreeNode *pParent = pNode->pParent;
- if( pParent ){
- int ii;
- int nCell = NCELL(pNode);
- RtreeCell box; /* Bounding box for pNode */
- nodeGetCell(pRtree, pNode, 0, &box);
- for(ii=1; ii<nCell; ii++){
- RtreeCell cell;
- nodeGetCell(pRtree, pNode, ii, &cell);
- cellUnion(pRtree, &box, &cell);
- }
- box.iRowid = pNode->iNode;
- ii = nodeParentIndex(pRtree, pNode);
- nodeOverwriteCell(pRtree, pParent, &box, ii);
- fixBoundingBox(pRtree, pParent);
- }
-}
-
-/*
-** Delete the cell at index iCell of node pNode. After removing the
-** cell, adjust the r-tree data structure if required.
-*/
-static int deleteCell(Rtree *pRtree, RtreeNode *pNode, int iCell, int iHeight){
- int rc;
-
- if( SQLITE_OK!=(rc = fixLeafParent(pRtree, pNode)) ){
- return rc;
- }
-
- /* Remove the cell from the node. This call just moves bytes around
- ** the in-memory node image, so it cannot fail.
- */
- nodeDeleteCell(pRtree, pNode, iCell);
-
- /* If the node is not the tree root and now has less than the minimum
- ** number of cells, remove it from the tree. Otherwise, update the
- ** cell in the parent node so that it tightly contains the updated
- ** node.
- */
- if( pNode->iNode!=1 ){
- RtreeNode *pParent = pNode->pParent;
- if( (pParent->iNode!=1 || NCELL(pParent)!=1)
- && (NCELL(pNode)<RTREE_MINCELLS(pRtree))
- ){
- rc = removeNode(pRtree, pNode, iHeight);
- }else{
- fixBoundingBox(pRtree, pNode);
- }
- }
-
- return rc;
-}
-
-static int Reinsert(
- Rtree *pRtree,
- RtreeNode *pNode,
- RtreeCell *pCell,
- int iHeight
-){
- int *aOrder;
- int *aSpare;
- RtreeCell *aCell;
- float *aDistance;
- int nCell;
- float aCenterCoord[RTREE_MAX_DIMENSIONS];
- int iDim;
- int ii;
- int rc = SQLITE_OK;
-
- memset(aCenterCoord, 0, sizeof(float)*RTREE_MAX_DIMENSIONS);
-
- nCell = NCELL(pNode)+1;
-
- /* Allocate the buffers used by this operation. The allocation is
- ** relinquished before this function returns.
- */
- aCell = (RtreeCell *)sqlite3_malloc(nCell * (
- sizeof(RtreeCell) + /* aCell array */
- sizeof(int) + /* aOrder array */
- sizeof(int) + /* aSpare array */
- sizeof(float) /* aDistance array */
- ));
- if( !aCell ){
- return SQLITE_NOMEM;
- }
- aOrder = (int *)&aCell[nCell];
- aSpare = (int *)&aOrder[nCell];
- aDistance = (float *)&aSpare[nCell];
-
- for(ii=0; ii<nCell; ii++){
- if( ii==(nCell-1) ){
- memcpy(&aCell[ii], pCell, sizeof(RtreeCell));
- }else{
- nodeGetCell(pRtree, pNode, ii, &aCell[ii]);
- }
- aOrder[ii] = ii;
- for(iDim=0; iDim<pRtree->nDim; iDim++){
- aCenterCoord[iDim] += DCOORD(aCell[ii].aCoord[iDim*2]);
- aCenterCoord[iDim] += DCOORD(aCell[ii].aCoord[iDim*2+1]);
- }
- }
- for(iDim=0; iDim<pRtree->nDim; iDim++){
- aCenterCoord[iDim] = aCenterCoord[iDim]/((float)nCell*2.0);
- }
-
- for(ii=0; ii<nCell; ii++){
- aDistance[ii] = 0.0;
- for(iDim=0; iDim<pRtree->nDim; iDim++){
- float coord = DCOORD(aCell[ii].aCoord[iDim*2+1]) -
- DCOORD(aCell[ii].aCoord[iDim*2]);
- aDistance[ii] += (coord-aCenterCoord[iDim])*(coord-aCenterCoord[iDim]);
- }
- }
-
- SortByDistance(aOrder, nCell, aDistance, aSpare);
- nodeZero(pRtree, pNode);
-
- for(ii=0; rc==SQLITE_OK && ii<(nCell-(RTREE_MINCELLS(pRtree)+1)); ii++){
- RtreeCell *p = &aCell[aOrder[ii]];
- nodeInsertCell(pRtree, pNode, p);
- if( p->iRowid==pCell->iRowid ){
- if( iHeight==0 ){
- rc = rowidWrite(pRtree, p->iRowid, pNode->iNode);
- }else{
- rc = parentWrite(pRtree, p->iRowid, pNode->iNode);
- }
- }
- }
- if( rc==SQLITE_OK ){
- fixBoundingBox(pRtree, pNode);
- }
- for(; rc==SQLITE_OK && ii<nCell; ii++){
- /* Find a node to store this cell in. pNode->iNode currently contains
- ** the height of the sub-tree headed by the cell.
- */
- RtreeNode *pInsert;
- RtreeCell *p = &aCell[aOrder[ii]];
- rc = ChooseLeaf(pRtree, p, iHeight, &pInsert);
- if( rc==SQLITE_OK ){
- int rc2;
- rc = rtreeInsertCell(pRtree, pInsert, p, iHeight);
- rc2 = nodeRelease(pRtree, pInsert);
- if( rc==SQLITE_OK ){
- rc = rc2;
- }
- }
- }
-
- sqlite3_free(aCell);
- return rc;
-}
-
-/*
-** Insert cell pCell into node pNode. Node pNode is the head of a
-** subtree iHeight high (leaf nodes have iHeight==0).
-*/
-static int rtreeInsertCell(
- Rtree *pRtree,
- RtreeNode *pNode,
- RtreeCell *pCell,
- int iHeight
-){
- int rc = SQLITE_OK;
- if( iHeight>0 ){
- RtreeNode *pChild = nodeHashLookup(pRtree, pCell->iRowid);
- if( pChild ){
- nodeRelease(pRtree, pChild->pParent);
- nodeReference(pNode);
- pChild->pParent = pNode;
- }
- }
- if( nodeInsertCell(pRtree, pNode, pCell) ){
-#if VARIANT_RSTARTREE_REINSERT
- if( iHeight<=pRtree->iReinsertHeight || pNode->iNode==1){
- rc = SplitNode(pRtree, pNode, pCell, iHeight);
- }else{
- pRtree->iReinsertHeight = iHeight;
- rc = Reinsert(pRtree, pNode, pCell, iHeight);
- }
-#else
- rc = SplitNode(pRtree, pNode, pCell, iHeight);
-#endif
- }else{
- AdjustTree(pRtree, pNode, pCell);
- if( iHeight==0 ){
- rc = rowidWrite(pRtree, pCell->iRowid, pNode->iNode);
- }else{
- rc = parentWrite(pRtree, pCell->iRowid, pNode->iNode);
- }
- }
- return rc;
-}
-
-static int reinsertNodeContent(Rtree *pRtree, RtreeNode *pNode){
- int ii;
- int rc = SQLITE_OK;
- int nCell = NCELL(pNode);
-
- for(ii=0; rc==SQLITE_OK && ii<nCell; ii++){
- RtreeNode *pInsert;
- RtreeCell cell;
- nodeGetCell(pRtree, pNode, ii, &cell);
-
- /* Find a node to store this cell in. pNode->iNode currently contains
- ** the height of the sub-tree headed by the cell.
- */
- rc = ChooseLeaf(pRtree, &cell, pNode->iNode, &pInsert);
- if( rc==SQLITE_OK ){
- int rc2;
- rc = rtreeInsertCell(pRtree, pInsert, &cell, pNode->iNode);
- rc2 = nodeRelease(pRtree, pInsert);
- if( rc==SQLITE_OK ){
- rc = rc2;
- }
- }
- }
- return rc;
-}
-
-/*
-** Select a currently unused rowid for a new r-tree record.
-*/
-static int newRowid(Rtree *pRtree, i64 *piRowid){
- int rc;
- sqlite3_bind_null(pRtree->pWriteRowid, 1);
- sqlite3_bind_null(pRtree->pWriteRowid, 2);
- sqlite3_step(pRtree->pWriteRowid);
- rc = sqlite3_reset(pRtree->pWriteRowid);
- *piRowid = sqlite3_last_insert_rowid(pRtree->db);
- return rc;
-}
-
-#ifndef NDEBUG
-static int hashIsEmpty(Rtree *pRtree){
- int ii;
- for(ii=0; ii<HASHSIZE; ii++){
- assert( !pRtree->aHash[ii] );
- }
- return 1;
-}
-#endif
-
-/*
-** The xUpdate method for rtree module virtual tables.
-*/
-static int rtreeUpdate(
- sqlite3_vtab *pVtab,
- int nData,
- sqlite3_value **azData,
- sqlite_int64 *pRowid
-){
- Rtree *pRtree = (Rtree *)pVtab;
- int rc = SQLITE_OK;
-
- rtreeReference(pRtree);
-
- assert(nData>=1);
- assert(hashIsEmpty(pRtree));
-
- /* If azData[0] is not an SQL NULL value, it is the rowid of a
- ** record to delete from the r-tree table. The following block does
- ** just that.
- */
- if( sqlite3_value_type(azData[0])!=SQLITE_NULL ){
- i64 iDelete; /* The rowid to delete */
- RtreeNode *pLeaf; /* Leaf node containing record iDelete */
- int iCell; /* Index of iDelete cell in pLeaf */
- RtreeNode *pRoot;
-
- /* Obtain a reference to the root node to initialise Rtree.iDepth */
- rc = nodeAcquire(pRtree, 1, 0, &pRoot);
-
- /* Obtain a reference to the leaf node that contains the entry
- ** about to be deleted.
- */
- if( rc==SQLITE_OK ){
- iDelete = sqlite3_value_int64(azData[0]);
- rc = findLeafNode(pRtree, iDelete, &pLeaf);
- }
-
- /* Delete the cell in question from the leaf node. */
- if( rc==SQLITE_OK ){
- int rc2;
- iCell = nodeRowidIndex(pRtree, pLeaf, iDelete);
- rc = deleteCell(pRtree, pLeaf, iCell, 0);
- rc2 = nodeRelease(pRtree, pLeaf);
- if( rc==SQLITE_OK ){
- rc = rc2;
- }
- }
-
- /* Delete the corresponding entry in the <rtree>_rowid table. */
- if( rc==SQLITE_OK ){
- sqlite3_bind_int64(pRtree->pDeleteRowid, 1, iDelete);
- sqlite3_step(pRtree->pDeleteRowid);
- rc = sqlite3_reset(pRtree->pDeleteRowid);
- }
-
- /* Check if the root node now has exactly one child. If so, remove
- ** it, schedule the contents of the child for reinsertion and
- ** reduce the tree height by one.
- **
- ** This is equivalent to copying the contents of the child into
- ** the root node (the operation that Gutman's paper says to perform
- ** in this scenario).
- */
- if( rc==SQLITE_OK && pRtree->iDepth>0 ){
- if( rc==SQLITE_OK && NCELL(pRoot)==1 ){
- RtreeNode *pChild;
- i64 iChild = nodeGetRowid(pRtree, pRoot, 0);
- rc = nodeAcquire(pRtree, iChild, pRoot, &pChild);
- if( rc==SQLITE_OK ){
- rc = removeNode(pRtree, pChild, pRtree->iDepth-1);
- }
- if( rc==SQLITE_OK ){
- pRtree->iDepth--;
- writeInt16(pRoot->zData, pRtree->iDepth);
- pRoot->isDirty = 1;
- }
- }
- }
-
- /* Re-insert the contents of any underfull nodes removed from the tree. */
- for(pLeaf=pRtree->pDeleted; pLeaf; pLeaf=pRtree->pDeleted){
- if( rc==SQLITE_OK ){
- rc = reinsertNodeContent(pRtree, pLeaf);
- }
- pRtree->pDeleted = pLeaf->pNext;
- sqlite3_free(pLeaf);
- }
-
- /* Release the reference to the root node. */
- if( rc==SQLITE_OK ){
- rc = nodeRelease(pRtree, pRoot);
- }else{
- nodeRelease(pRtree, pRoot);
- }
- }
-
- /* If the azData[] array contains more than one element, elements
- ** (azData[2]..azData[argc-1]) contain a new record to insert into
- ** the r-tree structure.
- */
- if( rc==SQLITE_OK && nData>1 ){
- /* Insert a new record into the r-tree */
- RtreeCell cell;
- int ii;
- RtreeNode *pLeaf;
-
- /* Populate the cell.aCoord[] array. The first coordinate is azData[3]. */
- assert( nData==(pRtree->nDim*2 + 3) );
- if( pRtree->eCoordType==RTREE_COORD_REAL32 ){
- for(ii=0; ii<(pRtree->nDim*2); ii+=2){
- cell.aCoord[ii].f = (float)sqlite3_value_double(azData[ii+3]);
- cell.aCoord[ii+1].f = (float)sqlite3_value_double(azData[ii+4]);
- if( cell.aCoord[ii].f>cell.aCoord[ii+1].f ){
- rc = SQLITE_CONSTRAINT;
- goto constraint;
- }
- }
- }else{
- for(ii=0; ii<(pRtree->nDim*2); ii+=2){
- cell.aCoord[ii].i = sqlite3_value_int(azData[ii+3]);
- cell.aCoord[ii+1].i = sqlite3_value_int(azData[ii+4]);
- if( cell.aCoord[ii].i>cell.aCoord[ii+1].i ){
- rc = SQLITE_CONSTRAINT;
- goto constraint;
- }
- }
- }
-
- /* Figure out the rowid of the new row. */
- if( sqlite3_value_type(azData[2])==SQLITE_NULL ){
- rc = newRowid(pRtree, &cell.iRowid);
- }else{
- cell.iRowid = sqlite3_value_int64(azData[2]);
- sqlite3_bind_int64(pRtree->pReadRowid, 1, cell.iRowid);
- if( SQLITE_ROW==sqlite3_step(pRtree->pReadRowid) ){
- sqlite3_reset(pRtree->pReadRowid);
- rc = SQLITE_CONSTRAINT;
- goto constraint;
- }
- rc = sqlite3_reset(pRtree->pReadRowid);
- }
-
- if( rc==SQLITE_OK ){
- rc = ChooseLeaf(pRtree, &cell, 0, &pLeaf);
- }
- if( rc==SQLITE_OK ){
- int rc2;
- pRtree->iReinsertHeight = -1;
- rc = rtreeInsertCell(pRtree, pLeaf, &cell, 0);
- rc2 = nodeRelease(pRtree, pLeaf);
- if( rc==SQLITE_OK ){
- rc = rc2;
- }
- }
- }
-
-constraint:
- rtreeRelease(pRtree);
- return rc;
-}
-
-/*
-** The xRename method for rtree module virtual tables.
-*/
-static int rtreeRename(sqlite3_vtab *pVtab, const char *zNewName){
- Rtree *pRtree = (Rtree *)pVtab;
- int rc = SQLITE_NOMEM;
- char *zSql = sqlite3_mprintf(
- "ALTER TABLE %Q.'%q_node' RENAME TO \"%w_node\";"
- "ALTER TABLE %Q.'%q_parent' RENAME TO \"%w_parent\";"
- "ALTER TABLE %Q.'%q_rowid' RENAME TO \"%w_rowid\";"
- , pRtree->zDb, pRtree->zName, zNewName
- , pRtree->zDb, pRtree->zName, zNewName
- , pRtree->zDb, pRtree->zName, zNewName
- );
- if( zSql ){
- rc = sqlite3_exec(pRtree->db, zSql, 0, 0, 0);
- sqlite3_free(zSql);
- }
- return rc;
-}
-
-static sqlite3_module rtreeModule = {
- 0, /* iVersion */
- rtreeCreate, /* xCreate - create a table */
- rtreeConnect, /* xConnect - connect to an existing table */
- rtreeBestIndex, /* xBestIndex - Determine search strategy */
- rtreeDisconnect, /* xDisconnect - Disconnect from a table */
- rtreeDestroy, /* xDestroy - Drop a table */
- rtreeOpen, /* xOpen - open a cursor */
- rtreeClose, /* xClose - close a cursor */
- rtreeFilter, /* xFilter - configure scan constraints */
- rtreeNext, /* xNext - advance a cursor */
- rtreeEof, /* xEof */
- rtreeColumn, /* xColumn - read data */
- rtreeRowid, /* xRowid - read data */
- rtreeUpdate, /* xUpdate - write data */
- 0, /* xBegin - begin transaction */
- 0, /* xSync - sync transaction */
- 0, /* xCommit - commit transaction */
- 0, /* xRollback - rollback transaction */
- 0, /* xFindFunction - function overloading */
- rtreeRename /* xRename - rename the table */
-};
-
-static int rtreeSqlInit(
- Rtree *pRtree,
- sqlite3 *db,
- const char *zDb,
- const char *zPrefix,
- int isCreate
-){
- int rc = SQLITE_OK;
-
- #define N_STATEMENT 9
- static const char *azSql[N_STATEMENT] = {
- /* Read and write the xxx_node table */
- "SELECT data FROM '%q'.'%q_node' WHERE nodeno = :1",
- "INSERT OR REPLACE INTO '%q'.'%q_node' VALUES(:1, :2)",
- "DELETE FROM '%q'.'%q_node' WHERE nodeno = :1",
-
- /* Read and write the xxx_rowid table */
- "SELECT nodeno FROM '%q'.'%q_rowid' WHERE rowid = :1",
- "INSERT OR REPLACE INTO '%q'.'%q_rowid' VALUES(:1, :2)",
- "DELETE FROM '%q'.'%q_rowid' WHERE rowid = :1",
-
- /* Read and write the xxx_parent table */
- "SELECT parentnode FROM '%q'.'%q_parent' WHERE nodeno = :1",
- "INSERT OR REPLACE INTO '%q'.'%q_parent' VALUES(:1, :2)",
- "DELETE FROM '%q'.'%q_parent' WHERE nodeno = :1"
- };
- sqlite3_stmt **appStmt[N_STATEMENT];
- int i;
-
- pRtree->db = db;
-
- if( isCreate ){
- char *zCreate = sqlite3_mprintf(
-"CREATE TABLE \"%w\".\"%w_node\"(nodeno INTEGER PRIMARY KEY, data BLOB);"
-"CREATE TABLE \"%w\".\"%w_rowid\"(rowid INTEGER PRIMARY KEY, nodeno INTEGER);"
-"CREATE TABLE \"%w\".\"%w_parent\"(nodeno INTEGER PRIMARY KEY, parentnode INTEGER);"
-"INSERT INTO '%q'.'%q_node' VALUES(1, zeroblob(%d))",
- zDb, zPrefix, zDb, zPrefix, zDb, zPrefix, zDb, zPrefix, pRtree->iNodeSize
- );
- if( !zCreate ){
- return SQLITE_NOMEM;
- }
- rc = sqlite3_exec(db, zCreate, 0, 0, 0);
- sqlite3_free(zCreate);
- if( rc!=SQLITE_OK ){
- return rc;
- }
- }
-
- appStmt[0] = &pRtree->pReadNode;
- appStmt[1] = &pRtree->pWriteNode;
- appStmt[2] = &pRtree->pDeleteNode;
- appStmt[3] = &pRtree->pReadRowid;
- appStmt[4] = &pRtree->pWriteRowid;
- appStmt[5] = &pRtree->pDeleteRowid;
- appStmt[6] = &pRtree->pReadParent;
- appStmt[7] = &pRtree->pWriteParent;
- appStmt[8] = &pRtree->pDeleteParent;
-
- for(i=0; i<N_STATEMENT && rc==SQLITE_OK; i++){
- char *zSql = sqlite3_mprintf(azSql[i], zDb, zPrefix);
- if( zSql ){
- rc = sqlite3_prepare_v2(db, zSql, -1, appStmt[i], 0);
- }else{
- rc = SQLITE_NOMEM;
- }
- sqlite3_free(zSql);
- }
-
- return rc;
-}
-
-/*
-** This routine queries database handle db for the page-size used by
-** database zDb. If successful, the page-size in bytes is written to
-** *piPageSize and SQLITE_OK returned. Otherwise, and an SQLite error
-** code is returned.
-*/
-static int getPageSize(sqlite3 *db, const char *zDb, int *piPageSize){
- int rc = SQLITE_NOMEM;
- char *zSql;
- sqlite3_stmt *pStmt = 0;
-
- zSql = sqlite3_mprintf("PRAGMA %Q.page_size", zDb);
- if( !zSql ){
- return SQLITE_NOMEM;
- }
-
- rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
- sqlite3_free(zSql);
- if( rc!=SQLITE_OK ){
- return rc;
- }
-
- if( SQLITE_ROW==sqlite3_step(pStmt) ){
- *piPageSize = sqlite3_column_int(pStmt, 0);
- }
- return sqlite3_finalize(pStmt);
-}
-
-/*
-** This function is the implementation of both the xConnect and xCreate
-** methods of the r-tree virtual table.
-**
-** argv[0] -> module name
-** argv[1] -> database name
-** argv[2] -> table name
-** argv[...] -> column names...
-*/
-static int rtreeInit(
- sqlite3 *db, /* Database connection */
- void *pAux, /* One of the RTREE_COORD_* constants */
- int argc, const char *const*argv, /* Parameters to CREATE TABLE statement */
- sqlite3_vtab **ppVtab, /* OUT: New virtual table */
- char **pzErr, /* OUT: Error message, if any */
- int isCreate /* True for xCreate, false for xConnect */
-){
- int rc = SQLITE_OK;
- int iPageSize = 0;
- Rtree *pRtree;
- int nDb; /* Length of string argv[1] */
- int nName; /* Length of string argv[2] */
- int eCoordType = (int)pAux;
-
- const char *aErrMsg[] = {
- 0, /* 0 */
- "Wrong number of columns for an rtree table", /* 1 */
- "Too few columns for an rtree table", /* 2 */
- "Too many columns for an rtree table" /* 3 */
- };
-
- int iErr = (argc<6) ? 2 : argc>(RTREE_MAX_DIMENSIONS*2+4) ? 3 : argc%2;
- if( aErrMsg[iErr] ){
- *pzErr = sqlite3_mprintf("%s", aErrMsg[iErr]);
- return SQLITE_ERROR;
- }
-
- rc = getPageSize(db, argv[1], &iPageSize);
- if( rc!=SQLITE_OK ){
- return rc;
- }
-
- /* Allocate the sqlite3_vtab structure */
- nDb = strlen(argv[1]);
- nName = strlen(argv[2]);
- pRtree = (Rtree *)sqlite3_malloc(sizeof(Rtree)+nDb+nName+2);
- if( !pRtree ){
- return SQLITE_NOMEM;
- }
- memset(pRtree, 0, sizeof(Rtree)+nDb+nName+2);
- pRtree->nBusy = 1;
- pRtree->base.pModule = &rtreeModule;
- pRtree->zDb = (char *)&pRtree[1];
- pRtree->zName = &pRtree->zDb[nDb+1];
- pRtree->nDim = (argc-4)/2;
- pRtree->nBytesPerCell = 8 + pRtree->nDim*4*2;
- pRtree->eCoordType = eCoordType;
- memcpy(pRtree->zDb, argv[1], nDb);
- memcpy(pRtree->zName, argv[2], nName);
-
- /* Figure out the node size to use. By default, use 64 bytes less than
- ** the database page-size. This ensures that each node is stored on
- ** a single database page.
- **
- ** If the databasd page-size is so large that more than RTREE_MAXCELLS
- ** entries would fit in a single node, use a smaller node-size.
- */
- pRtree->iNodeSize = iPageSize-64;
- if( (4+pRtree->nBytesPerCell*RTREE_MAXCELLS)<pRtree->iNodeSize ){
- pRtree->iNodeSize = 4+pRtree->nBytesPerCell*RTREE_MAXCELLS;
- }
-
- /* Create/Connect to the underlying relational database schema. If
- ** that is successful, call sqlite3_declare_vtab() to configure
- ** the r-tree table schema.
- */
- if( (rc = rtreeSqlInit(pRtree, db, argv[1], argv[2], isCreate)) ){
- *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db));
- }else{
- char *zSql = sqlite3_mprintf("CREATE TABLE x(%s", argv[3]);
- char *zTmp;
- int ii;
- for(ii=4; zSql && ii<argc; ii++){
- zTmp = zSql;
- zSql = sqlite3_mprintf("%s, %s", zTmp, argv[ii]);
- sqlite3_free(zTmp);
- }
- if( zSql ){
- zTmp = zSql;
- zSql = sqlite3_mprintf("%s);", zTmp);
- sqlite3_free(zTmp);
- }
- if( !zSql ){
- rc = SQLITE_NOMEM;
- }else if( SQLITE_OK!=(rc = sqlite3_declare_vtab(db, zSql)) ){
- *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db));
- }
- sqlite3_free(zSql);
- }
-
- if( rc==SQLITE_OK ){
- *ppVtab = (sqlite3_vtab *)pRtree;
- }else{
- rtreeRelease(pRtree);
- }
- return rc;
-}
-
-
-/*
-** Implementation of a scalar function that decodes r-tree nodes to
-** human readable strings. This can be used for debugging and analysis.
-**
-** The scalar function takes two arguments, a blob of data containing
-** an r-tree node, and the number of dimensions the r-tree indexes.
-** For a two-dimensional r-tree structure called "rt", to deserialize
-** all nodes, a statement like:
-**
-** SELECT rtreenode(2, data) FROM rt_node;
-**
-** The human readable string takes the form of a Tcl list with one
-** entry for each cell in the r-tree node. Each entry is itself a
-** list, containing the 8-byte rowid/pageno followed by the
-** <num-dimension>*2 coordinates.
-*/
-static void rtreenode(sqlite3_context *ctx, int nArg, sqlite3_value **apArg){
- char *zText = 0;
- RtreeNode node;
- Rtree tree;
- int ii;
-
- memset(&node, 0, sizeof(RtreeNode));
- memset(&tree, 0, sizeof(Rtree));
- tree.nDim = sqlite3_value_int(apArg[0]);
- tree.nBytesPerCell = 8 + 8 * tree.nDim;
- node.zData = (u8 *)sqlite3_value_blob(apArg[1]);
-
- for(ii=0; ii<NCELL(&node); ii++){
- char zCell[512];
- int nCell = 0;
- RtreeCell cell;
- int jj;
-
- nodeGetCell(&tree, &node, ii, &cell);
- sqlite3_snprintf(512-nCell,&zCell[nCell],"%d", cell.iRowid);
- nCell = strlen(zCell);
- for(jj=0; jj<tree.nDim*2; jj++){
- sqlite3_snprintf(512-nCell,&zCell[nCell]," %f",(double)cell.aCoord[jj].f);
- nCell = strlen(zCell);
- }
-
- if( zText ){
- char *zTextNew = sqlite3_mprintf("%s {%s}", zText, zCell);
- sqlite3_free(zText);
- zText = zTextNew;
- }else{
- zText = sqlite3_mprintf("{%s}", zCell);
- }
- }
-
- sqlite3_result_text(ctx, zText, -1, sqlite3_free);
-}
-
-static void rtreedepth(sqlite3_context *ctx, int nArg, sqlite3_value **apArg){
- if( sqlite3_value_type(apArg[0])!=SQLITE_BLOB
- || sqlite3_value_bytes(apArg[0])<2
- ){
- sqlite3_result_error(ctx, "Invalid argument to rtreedepth()", -1);
- }else{
- u8 *zBlob = (u8 *)sqlite3_value_blob(apArg[0]);
- sqlite3_result_int(ctx, readInt16(zBlob));
- }
-}
-
-/*
-** Register the r-tree module with database handle db. This creates the
-** virtual table module "rtree" and the debugging/analysis scalar
-** function "rtreenode".
-*/
-SQLITE_PRIVATE int sqlite3RtreeInit(sqlite3 *db){
- int rc = SQLITE_OK;
-
- if( rc==SQLITE_OK ){
- int utf8 = SQLITE_UTF8;
- rc = sqlite3_create_function(db, "rtreenode", 2, utf8, 0, rtreenode, 0, 0);
- }
- if( rc==SQLITE_OK ){
- int utf8 = SQLITE_UTF8;
- rc = sqlite3_create_function(db, "rtreedepth", 1, utf8, 0,rtreedepth, 0, 0);
- }
- if( rc==SQLITE_OK ){
- void *c = (void *)RTREE_COORD_REAL32;
- rc = sqlite3_create_module_v2(db, "rtree", &rtreeModule, c, 0);
- }
- if( rc==SQLITE_OK ){
- void *c = (void *)RTREE_COORD_INT32;
- rc = sqlite3_create_module_v2(db, "rtree_i32", &rtreeModule, c, 0);
- }
-
- return rc;
-}
-
-#if !SQLITE_CORE
-SQLITE_API int sqlite3_extension_init(
- sqlite3 *db,
- char **pzErrMsg,
- const sqlite3_api_routines *pApi
-){
- SQLITE_EXTENSION_INIT2(pApi)
- return sqlite3RtreeInit(db);
-}
-#endif
-
-#endif
-
-/************** End of rtree.c ***********************************************/
-/************** Begin file icu.c *********************************************/
-/*
-** 2007 May 6
-**
-** 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.
-**
-*************************************************************************
-** $Id: icu.c,v 1.7 2007/12/13 21:54:11 drh Exp $
-**
-** This file implements an integration between the ICU library
-** ("International Components for Unicode", an open-source library
-** for handling unicode data) and SQLite. The integration uses
-** ICU to provide the following to SQLite:
-**
-** * An implementation of the SQL regexp() function (and hence REGEXP
-** operator) using the ICU uregex_XX() APIs.
-**
-** * Implementations of the SQL scalar upper() and lower() functions
-** for case mapping.
-**
-** * Integration of ICU and SQLite collation seqences.
-**
-** * An implementation of the LIKE operator that uses ICU to
-** provide case-independent matching.
-*/
-
-#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_ICU)
-
-/* Include ICU headers */
-#include <unicode/utypes.h>
-#include <unicode/uregex.h>
-#include <unicode/ustring.h>
-#include <unicode/ucol.h>
-
-
-#ifndef SQLITE_CORE
- SQLITE_EXTENSION_INIT1
-#else
-#endif
-
-/*
-** Maximum length (in bytes) of the pattern in a LIKE or GLOB
-** operator.
-*/
-#ifndef SQLITE_MAX_LIKE_PATTERN_LENGTH
-# define SQLITE_MAX_LIKE_PATTERN_LENGTH 50000
-#endif
-
-/*
-** Version of sqlite3_free() that is always a function, never a macro.
-*/
-static void xFree(void *p){
- sqlite3_free(p);
-}
-
-/*
-** Compare two UTF-8 strings for equality where the first string is
-** a "LIKE" expression. Return true (1) if they are the same and
-** false (0) if they are different.
-*/
-static int icuLikeCompare(
- const uint8_t *zPattern, /* LIKE pattern */
- const uint8_t *zString, /* The UTF-8 string to compare against */
- const UChar32 uEsc /* The escape character */
-){
- static const int MATCH_ONE = (UChar32)'_';
- static const int MATCH_ALL = (UChar32)'%';
-
- int iPattern = 0; /* Current byte index in zPattern */
- int iString = 0; /* Current byte index in zString */
-
- int prevEscape = 0; /* True if the previous character was uEsc */
-
- while( zPattern[iPattern]!=0 ){
-
- /* Read (and consume) the next character from the input pattern. */
- UChar32 uPattern;
- U8_NEXT_UNSAFE(zPattern, iPattern, uPattern);
- assert(uPattern!=0);
-
- /* There are now 4 possibilities:
- **
- ** 1. uPattern is an unescaped match-all character "%",
- ** 2. uPattern is an unescaped match-one character "_",
- ** 3. uPattern is an unescaped escape character, or
- ** 4. uPattern is to be handled as an ordinary character
- */
- if( !prevEscape && uPattern==MATCH_ALL ){
- /* Case 1. */
- uint8_t c;
-
- /* Skip any MATCH_ALL or MATCH_ONE characters that follow a
- ** MATCH_ALL. For each MATCH_ONE, skip one character in the
- ** test string.
- */
- while( (c=zPattern[iPattern]) == MATCH_ALL || c == MATCH_ONE ){
- if( c==MATCH_ONE ){
- if( zString[iString]==0 ) return 0;
- U8_FWD_1_UNSAFE(zString, iString);
- }
- iPattern++;
- }
-
- if( zPattern[iPattern]==0 ) return 1;
-
- while( zString[iString] ){
- if( icuLikeCompare(&zPattern[iPattern], &zString[iString], uEsc) ){
- return 1;
- }
- U8_FWD_1_UNSAFE(zString, iString);
- }
- return 0;
-
- }else if( !prevEscape && uPattern==MATCH_ONE ){
- /* Case 2. */
- if( zString[iString]==0 ) return 0;
- U8_FWD_1_UNSAFE(zString, iString);
-
- }else if( !prevEscape && uPattern==uEsc){
- /* Case 3. */
- prevEscape = 1;
-
- }else{
- /* Case 4. */
- UChar32 uString;
- U8_NEXT_UNSAFE(zString, iString, uString);
- uString = u_foldCase(uString, U_FOLD_CASE_DEFAULT);
- uPattern = u_foldCase(uPattern, U_FOLD_CASE_DEFAULT);
- if( uString!=uPattern ){
- return 0;
- }
- prevEscape = 0;
- }
- }
-
- return zString[iString]==0;
-}
-
-/*
-** Implementation of the like() SQL function. This function implements
-** the build-in LIKE operator. The first argument to the function is the
-** pattern and the second argument is the string. So, the SQL statements:
-**
-** A LIKE B
-**
-** is implemented as like(B, A). If there is an escape character E,
-**
-** A LIKE B ESCAPE E
-**
-** is mapped to like(B, A, E).
-*/
-static void icuLikeFunc(
- sqlite3_context *context,
- int argc,
- sqlite3_value **argv
-){
- const unsigned char *zA = sqlite3_value_text(argv[0]);
- const unsigned char *zB = sqlite3_value_text(argv[1]);
- UChar32 uEsc = 0;
-
- /* Limit the length of the LIKE or GLOB pattern to avoid problems
- ** of deep recursion and N*N behavior in patternCompare().
- */
- if( sqlite3_value_bytes(argv[0])>SQLITE_MAX_LIKE_PATTERN_LENGTH ){
- sqlite3_result_error(context, "LIKE or GLOB pattern too complex", -1);
- return;
- }
-
-
- if( argc==3 ){
- /* The escape character string must consist of a single UTF-8 character.
- ** Otherwise, return an error.
- */
- int nE= sqlite3_value_bytes(argv[2]);
- const unsigned char *zE = sqlite3_value_text(argv[2]);
- int i = 0;
- if( zE==0 ) return;
- U8_NEXT(zE, i, nE, uEsc);
- if( i!=nE){
- sqlite3_result_error(context,
- "ESCAPE expression must be a single character", -1);
- return;
- }
- }
-
- if( zA && zB ){
- sqlite3_result_int(context, icuLikeCompare(zA, zB, uEsc));
- }
-}
-
-/*
-** This function is called when an ICU function called from within
-** the implementation of an SQL scalar function returns an error.
-**
-** The scalar function context passed as the first argument is
-** loaded with an error message based on the following two args.
-*/
-static void icuFunctionError(
- sqlite3_context *pCtx, /* SQLite scalar function context */
- const char *zName, /* Name of ICU function that failed */
- UErrorCode e /* Error code returned by ICU function */
-){
- char zBuf[128];
- sqlite3_snprintf(128, zBuf, "ICU error: %s(): %s", zName, u_errorName(e));
- zBuf[127] = '\0';
- sqlite3_result_error(pCtx, zBuf, -1);
-}
-
-/*
-** Function to delete compiled regexp objects. Registered as
-** a destructor function with sqlite3_set_auxdata().
-*/
-static void icuRegexpDelete(void *p){
- URegularExpression *pExpr = (URegularExpression *)p;
- uregex_close(pExpr);
-}
-
-/*
-** Implementation of SQLite REGEXP operator. This scalar function takes
-** two arguments. The first is a regular expression pattern to compile
-** the second is a string to match against that pattern. If either
-** argument is an SQL NULL, then NULL Is returned. Otherwise, the result
-** is 1 if the string matches the pattern, or 0 otherwise.
-**
-** SQLite maps the regexp() function to the regexp() operator such
-** that the following two are equivalent:
-**
-** zString REGEXP zPattern
-** regexp(zPattern, zString)
-**
-** Uses the following ICU regexp APIs:
-**
-** uregex_open()
-** uregex_matches()
-** uregex_close()
-*/
-static void icuRegexpFunc(sqlite3_context *p, int nArg, sqlite3_value **apArg){
- UErrorCode status = U_ZERO_ERROR;
- URegularExpression *pExpr;
- UBool res;
- const UChar *zString = sqlite3_value_text16(apArg[1]);
-
- /* If the left hand side of the regexp operator is NULL,
- ** then the result is also NULL.
- */
- if( !zString ){
- return;
- }
-
- pExpr = sqlite3_get_auxdata(p, 0);
- if( !pExpr ){
- const UChar *zPattern = sqlite3_value_text16(apArg[0]);
- if( !zPattern ){
- return;
- }
- pExpr = uregex_open(zPattern, -1, 0, 0, &status);
-
- if( U_SUCCESS(status) ){
- sqlite3_set_auxdata(p, 0, pExpr, icuRegexpDelete);
- }else{
- assert(!pExpr);
- icuFunctionError(p, "uregex_open", status);
- return;
- }
- }
-
- /* Configure the text that the regular expression operates on. */
- uregex_setText(pExpr, zString, -1, &status);
- if( !U_SUCCESS(status) ){
- icuFunctionError(p, "uregex_setText", status);
- return;
- }
-
- /* Attempt the match */
- res = uregex_matches(pExpr, 0, &status);
- if( !U_SUCCESS(status) ){
- icuFunctionError(p, "uregex_matches", status);
- return;
- }
-
- /* Set the text that the regular expression operates on to a NULL
- ** pointer. This is not really necessary, but it is tidier than
- ** leaving the regular expression object configured with an invalid
- ** pointer after this function returns.
- */
- uregex_setText(pExpr, 0, 0, &status);
-
- /* Return 1 or 0. */
- sqlite3_result_int(p, res ? 1 : 0);
-}
-
-/*
-** Implementations of scalar functions for case mapping - upper() and
-** lower(). Function upper() converts its input to upper-case (ABC).
-** Function lower() converts to lower-case (abc).
-**
-** ICU provides two types of case mapping, "general" case mapping and
-** "language specific". Refer to ICU documentation for the differences
-** between the two.
-**
-** To utilise "general" case mapping, the upper() or lower() scalar
-** functions are invoked with one argument:
-**
-** upper('ABC') -> 'abc'
-** lower('abc') -> 'ABC'
-**
-** To access ICU "language specific" case mapping, upper() or lower()
-** should be invoked with two arguments. The second argument is the name
-** of the locale to use. Passing an empty string ("") or SQL NULL value
-** as the second argument is the same as invoking the 1 argument version
-** of upper() or lower().
-**
-** lower('I', 'en_us') -> 'i'
-** lower('I', 'tr_tr') -> 'ı' (small dotless i)
-**
-** http://www.icu-project.org/userguide/posix.html#case_mappings
-*/
-static void icuCaseFunc16(sqlite3_context *p, int nArg, sqlite3_value **apArg){
- const UChar *zInput;
- UChar *zOutput;
- int nInput;
- int nOutput;
-
- UErrorCode status = U_ZERO_ERROR;
- const char *zLocale = 0;
-
- assert(nArg==1 || nArg==2);
- if( nArg==2 ){
- zLocale = (const char *)sqlite3_value_text(apArg[1]);
- }
-
- zInput = sqlite3_value_text16(apArg[0]);
- if( !zInput ){
- return;
- }
- nInput = sqlite3_value_bytes16(apArg[0]);
-
- nOutput = nInput * 2 + 2;
- zOutput = sqlite3_malloc(nOutput);
- if( !zOutput ){
- return;
- }
-
- if( sqlite3_user_data(p) ){
- u_strToUpper(zOutput, nOutput/2, zInput, nInput/2, zLocale, &status);
- }else{
- u_strToLower(zOutput, nOutput/2, zInput, nInput/2, zLocale, &status);
- }
-
- if( !U_SUCCESS(status) ){
- icuFunctionError(p, "u_strToLower()/u_strToUpper", status);
- return;
- }
-
- sqlite3_result_text16(p, zOutput, -1, xFree);
-}
-
-/*
-** Collation sequence destructor function. The pCtx argument points to
-** a UCollator structure previously allocated using ucol_open().
-*/
-static void icuCollationDel(void *pCtx){
- UCollator *p = (UCollator *)pCtx;
- ucol_close(p);
-}
-
-/*
-** Collation sequence comparison function. The pCtx argument points to
-** a UCollator structure previously allocated using ucol_open().
-*/
-static int icuCollationColl(
- void *pCtx,
- int nLeft,
- const void *zLeft,
- int nRight,
- const void *zRight
-){
- UCollationResult res;
- UCollator *p = (UCollator *)pCtx;
- res = ucol_strcoll(p, (UChar *)zLeft, nLeft/2, (UChar *)zRight, nRight/2);
- switch( res ){
- case UCOL_LESS: return -1;
- case UCOL_GREATER: return +1;
- case UCOL_EQUAL: return 0;
- }
- assert(!"Unexpected return value from ucol_strcoll()");
- return 0;
-}
-
-/*
-** Implementation of the scalar function icu_load_collation().
-**
-** This scalar function is used to add ICU collation based collation
-** types to an SQLite database connection. It is intended to be called
-** as follows:
-**
-** SELECT icu_load_collation(<locale>, <collation-name>);
-**
-** Where <locale> is a string containing an ICU locale identifier (i.e.
-** "en_AU", "tr_TR" etc.) and <collation-name> is the name of the
-** collation sequence to create.
-*/
-static void icuLoadCollation(
- sqlite3_context *p,
- int nArg,
- sqlite3_value **apArg
-){
- sqlite3 *db = (sqlite3 *)sqlite3_user_data(p);
- UErrorCode status = U_ZERO_ERROR;
- const char *zLocale; /* Locale identifier - (eg. "jp_JP") */
- const char *zName; /* SQL Collation sequence name (eg. "japanese") */
- UCollator *pUCollator; /* ICU library collation object */
- int rc; /* Return code from sqlite3_create_collation_x() */
-
- assert(nArg==2);
- zLocale = (const char *)sqlite3_value_text(apArg[0]);
- zName = (const char *)sqlite3_value_text(apArg[1]);
-
- if( !zLocale || !zName ){
- return;
- }
-
- pUCollator = ucol_open(zLocale, &status);
- if( !U_SUCCESS(status) ){
- icuFunctionError(p, "ucol_open", status);
- return;
- }
- assert(p);
-
- rc = sqlite3_create_collation_v2(db, zName, SQLITE_UTF16, (void *)pUCollator,
- icuCollationColl, icuCollationDel
- );
- if( rc!=SQLITE_OK ){
- ucol_close(pUCollator);
- sqlite3_result_error(p, "Error registering collation function", -1);
- }
-}
-
-/*
-** Register the ICU extension functions with database db.
-*/
-SQLITE_PRIVATE int sqlite3IcuInit(sqlite3 *db){
- struct IcuScalar {
- const char *zName; /* Function name */
- int nArg; /* Number of arguments */
- int enc; /* Optimal text encoding */
- void *pContext; /* sqlite3_user_data() context */
- void (*xFunc)(sqlite3_context*,int,sqlite3_value**);
- } scalars[] = {
- {"regexp",-1, SQLITE_ANY, 0, icuRegexpFunc},
-
- {"lower", 1, SQLITE_UTF16, 0, icuCaseFunc16},
- {"lower", 2, SQLITE_UTF16, 0, icuCaseFunc16},
- {"upper", 1, SQLITE_UTF16, (void*)1, icuCaseFunc16},
- {"upper", 2, SQLITE_UTF16, (void*)1, icuCaseFunc16},
-
- {"lower", 1, SQLITE_UTF8, 0, icuCaseFunc16},
- {"lower", 2, SQLITE_UTF8, 0, icuCaseFunc16},
- {"upper", 1, SQLITE_UTF8, (void*)1, icuCaseFunc16},
- {"upper", 2, SQLITE_UTF8, (void*)1, icuCaseFunc16},
-
- {"like", 2, SQLITE_UTF8, 0, icuLikeFunc},
- {"like", 3, SQLITE_UTF8, 0, icuLikeFunc},
-
- {"icu_load_collation", 2, SQLITE_UTF8, (void*)db, icuLoadCollation},
- };
-
- int rc = SQLITE_OK;
- int i;
-
- for(i=0; rc==SQLITE_OK && i<(sizeof(scalars)/sizeof(struct IcuScalar)); i++){
- struct IcuScalar *p = &scalars[i];
- rc = sqlite3_create_function(
- db, p->zName, p->nArg, p->enc, p->pContext, p->xFunc, 0, 0
- );
- }
-
- return rc;
-}
-
-#if !SQLITE_CORE
-SQLITE_API int sqlite3_extension_init(
- sqlite3 *db,
- char **pzErrMsg,
- const sqlite3_api_routines *pApi
-){
- SQLITE_EXTENSION_INIT2(pApi)
- return sqlite3IcuInit(db);
-}
-#endif
-
-#endif
-
-/************** End of icu.c *************************************************/
-/************** Begin file fts3_icu.c ****************************************/
-/*
-** 2007 June 22
-**
-** 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 a tokenizer for fts3 based on the ICU library.
-**
-** $Id: fts3_icu.c,v 1.3 2008/09/01 18:34:20 danielk1977 Exp $
-*/
-
-#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3)
-#ifdef SQLITE_ENABLE_ICU
-
-
-#include <unicode/ubrk.h>
-#include <unicode/utf16.h>
-
-typedef struct IcuTokenizer IcuTokenizer;
-typedef struct IcuCursor IcuCursor;
-
-struct IcuTokenizer {
- sqlite3_tokenizer base;
- char *zLocale;
-};
-
-struct IcuCursor {
- sqlite3_tokenizer_cursor base;
-
- UBreakIterator *pIter; /* ICU break-iterator object */
- int nChar; /* Number of UChar elements in pInput */
- UChar *aChar; /* Copy of input using utf-16 encoding */
- int *aOffset; /* Offsets of each character in utf-8 input */
-
- int nBuffer;
- char *zBuffer;
-
- int iToken;
-};
-
-/*
-** Create a new tokenizer instance.
-*/
-static int icuCreate(
- int argc, /* Number of entries in argv[] */
- const char * const *argv, /* Tokenizer creation arguments */
- sqlite3_tokenizer **ppTokenizer /* OUT: Created tokenizer */
-){
- IcuTokenizer *p;
- int n = 0;
-
- if( argc>0 ){
- n = strlen(argv[0])+1;
- }
- p = (IcuTokenizer *)sqlite3_malloc(sizeof(IcuTokenizer)+n);
- if( !p ){
- return SQLITE_NOMEM;
- }
- memset(p, 0, sizeof(IcuTokenizer));
-
- if( n ){
- p->zLocale = (char *)&p[1];
- memcpy(p->zLocale, argv[0], n);
- }
-
- *ppTokenizer = (sqlite3_tokenizer *)p;
-
- return SQLITE_OK;
-}
-
-/*
-** Destroy a tokenizer
-*/
-static int icuDestroy(sqlite3_tokenizer *pTokenizer){
- IcuTokenizer *p = (IcuTokenizer *)pTokenizer;
- sqlite3_free(p);
- return SQLITE_OK;
-}
-
-/*
-** Prepare to begin tokenizing a particular string. The input
-** string to be tokenized is pInput[0..nBytes-1]. A cursor
-** used to incrementally tokenize this string is returned in
-** *ppCursor.
-*/
-static int icuOpen(
- sqlite3_tokenizer *pTokenizer, /* The tokenizer */
- const char *zInput, /* Input string */
- int nInput, /* Length of zInput in bytes */
- sqlite3_tokenizer_cursor **ppCursor /* OUT: Tokenization cursor */
-){
- IcuTokenizer *p = (IcuTokenizer *)pTokenizer;
- IcuCursor *pCsr;
-
- const int32_t opt = U_FOLD_CASE_DEFAULT;
- UErrorCode status = U_ZERO_ERROR;
- int nChar;
-
- UChar32 c;
- int iInput = 0;
- int iOut = 0;
-
- *ppCursor = 0;
-
- if( nInput<0 ){
- nInput = strlen(zInput);
- }
- nChar = nInput+1;
- pCsr = (IcuCursor *)sqlite3_malloc(
- sizeof(IcuCursor) + /* IcuCursor */
- nChar * sizeof(UChar) + /* IcuCursor.aChar[] */
- (nChar+1) * sizeof(int) /* IcuCursor.aOffset[] */
- );
- if( !pCsr ){
- return SQLITE_NOMEM;
- }
- memset(pCsr, 0, sizeof(IcuCursor));
- pCsr->aChar = (UChar *)&pCsr[1];
- pCsr->aOffset = (int *)&pCsr->aChar[nChar];
-
- pCsr->aOffset[iOut] = iInput;
- U8_NEXT(zInput, iInput, nInput, c);
- while( c>0 ){
- int isError = 0;
- c = u_foldCase(c, opt);
- U16_APPEND(pCsr->aChar, iOut, nChar, c, isError);
- if( isError ){
- sqlite3_free(pCsr);
- return SQLITE_ERROR;
- }
- pCsr->aOffset[iOut] = iInput;
-
- if( iInput<nInput ){
- U8_NEXT(zInput, iInput, nInput, c);
- }else{
- c = 0;
- }
- }
-
- pCsr->pIter = ubrk_open(UBRK_WORD, p->zLocale, pCsr->aChar, iOut, &status);
- if( !U_SUCCESS(status) ){
- sqlite3_free(pCsr);
- return SQLITE_ERROR;
- }
- pCsr->nChar = iOut;
-
- ubrk_first(pCsr->pIter);
- *ppCursor = (sqlite3_tokenizer_cursor *)pCsr;
- return SQLITE_OK;
-}
-
-/*
-** Close a tokenization cursor previously opened by a call to icuOpen().
-*/
-static int icuClose(sqlite3_tokenizer_cursor *pCursor){
- IcuCursor *pCsr = (IcuCursor *)pCursor;
- ubrk_close(pCsr->pIter);
- sqlite3_free(pCsr->zBuffer);
- sqlite3_free(pCsr);
- return SQLITE_OK;
-}
-
-/*
-** Extract the next token from a tokenization cursor.
-*/
-static int icuNext(
- sqlite3_tokenizer_cursor *pCursor, /* Cursor returned by simpleOpen */
- const char **ppToken, /* OUT: *ppToken is the token text */
- int *pnBytes, /* OUT: Number of bytes in token */
- int *piStartOffset, /* OUT: Starting offset of token */
- int *piEndOffset, /* OUT: Ending offset of token */
- int *piPosition /* OUT: Position integer of token */
-){
- IcuCursor *pCsr = (IcuCursor *)pCursor;
-
- int iStart = 0;
- int iEnd = 0;
- int nByte = 0;
-
- while( iStart==iEnd ){
- UChar32 c;
-
- iStart = ubrk_current(pCsr->pIter);
- iEnd = ubrk_next(pCsr->pIter);
- if( iEnd==UBRK_DONE ){
- return SQLITE_DONE;
- }
-
- while( iStart<iEnd ){
- int iWhite = iStart;
- U8_NEXT(pCsr->aChar, iWhite, pCsr->nChar, c);
- if( u_isspace(c) ){
- iStart = iWhite;
- }else{
- break;
- }
- }
- assert(iStart<=iEnd);
- }
-
- do {
- UErrorCode status = U_ZERO_ERROR;
- if( nByte ){
- char *zNew = sqlite3_realloc(pCsr->zBuffer, nByte);
- if( !zNew ){
- return SQLITE_NOMEM;
- }
- pCsr->zBuffer = zNew;
- pCsr->nBuffer = nByte;
- }
-
- u_strToUTF8(
- pCsr->zBuffer, pCsr->nBuffer, &nByte, /* Output vars */
- &pCsr->aChar[iStart], iEnd-iStart, /* Input vars */
- &status /* Output success/failure */
- );
- } while( nByte>pCsr->nBuffer );
-
- *ppToken = pCsr->zBuffer;
- *pnBytes = nByte;
- *piStartOffset = pCsr->aOffset[iStart];
- *piEndOffset = pCsr->aOffset[iEnd];
- *piPosition = pCsr->iToken++;
-
- return SQLITE_OK;
-}
-
-/*
-** The set of routines that implement the simple tokenizer
-*/
-static const sqlite3_tokenizer_module icuTokenizerModule = {
- 0, /* iVersion */
- icuCreate, /* xCreate */
- icuDestroy, /* xCreate */
- icuOpen, /* xOpen */
- icuClose, /* xClose */
- icuNext, /* xNext */
-};
-
-/*
-** Set *ppModule to point at the implementation of the ICU tokenizer.
-*/
-SQLITE_PRIVATE void sqlite3Fts3IcuTokenizerModule(
- sqlite3_tokenizer_module const**ppModule
-){
- *ppModule = &icuTokenizerModule;
-}
-
-#endif /* defined(SQLITE_ENABLE_ICU) */
-#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */
-
-/************** End of fts3_icu.c ********************************************/
diff --git a/crawl-ref/source/util/sqlite/sqlite3.h b/crawl-ref/source/util/sqlite/sqlite3.h
deleted file mode 100644
index b33728a859..0000000000
--- a/crawl-ref/source/util/sqlite/sqlite3.h
+++ /dev/null
@@ -1,5759 +0,0 @@
-/*
-** 2001 September 15
-**
-** 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 header file defines the interface that the SQLite library
-** presents to client programs. If a C-function, structure, datatype,
-** or constant definition does not appear in this file, then it is
-** not a published API of SQLite, is subject to change without
-** notice, and should not be referenced by programs that use SQLite.
-**
-** Some of the definitions that are in this file are marked as
-** "experimental". Experimental interfaces are normally new
-** features recently added to SQLite. We do not anticipate changes
-** to experimental interfaces but reserve the right to make minor changes
-** if experience from use "in the wild" suggest such changes are prudent.
-**
-** The official C-language API documentation for SQLite is derived
-** from comments in this file. This file is the authoritative source
-** on how SQLite interfaces are suppose to operate.
-**
-** The name of this file under configuration management is "sqlite.h.in".
-** The makefile makes some minor changes to this file (such as inserting
-** the version number) and changes its name to "sqlite3.h" as
-** part of the build process.
-*/
-#ifndef _SQLITE3_H_
-#define _SQLITE3_H_
-#include <stdarg.h> /* Needed for the definition of va_list */
-
-/*
-** Make sure we can call this stuff from C++.
-*/
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-/*
-** Add the ability to override 'extern'
-*/
-#ifndef SQLITE_EXTERN
-# define SQLITE_EXTERN extern
-#endif
-
-#ifndef SQLITE_API
-# define SQLITE_API
-#endif
-
-
-/*
-** These no-op macros are used in front of interfaces to mark those
-** interfaces as either deprecated or experimental. New applications
-** should not use deprecated interfaces - they are support for backwards
-** compatibility only. Application writers should be aware that
-** experimental interfaces are subject to change in point releases.
-**
-** These macros used to resolve to various kinds of compiler magic that
-** would generate warning messages when they were used. But that
-** compiler magic ended up generating such a flurry of bug reports
-** that we have taken it all out and gone back to using simple
-** noop macros.
-*/
-#define SQLITE_DEPRECATED
-#define SQLITE_EXPERIMENTAL
-
-/*
-** Ensure these symbols were not defined by some previous header file.
-*/
-#ifdef SQLITE_VERSION
-# undef SQLITE_VERSION
-#endif
-#ifdef SQLITE_VERSION_NUMBER
-# undef SQLITE_VERSION_NUMBER
-#endif
-
-/*
-** CAPI3REF: Compile-Time Library Version Numbers {H10010} <S60100>
-**
-** The SQLITE_VERSION and SQLITE_VERSION_NUMBER #defines in
-** the sqlite3.h file specify the version of SQLite with which
-** that header file is associated.
-**
-** The "version" of SQLite is a string of the form "W.X.Y" or "W.X.Y.Z".
-** The W value is major version number and is always 3 in SQLite3.
-** The W value only changes when backwards compatibility is
-** broken and we intend to never break backwards compatibility.
-** The X value is the minor version number and only changes when
-** there are major feature enhancements that are forwards compatible
-** but not backwards compatible.
-** The Y value is the release number and is incremented with
-** each release but resets back to 0 whenever X is incremented.
-** The Z value only appears on branch releases.
-**
-** The SQLITE_VERSION_NUMBER is an integer that is computed as
-** follows:
-**
-** <blockquote><pre>
-** SQLITE_VERSION_NUMBER = W*1000000 + X*1000 + Y
-** </pre></blockquote>
-**
-** Since version 3.6.18, SQLite source code has been stored in the
-** <a href="http://www.fossil-scm.org/">fossil configuration management
-** system</a>. The SQLITE_SOURCE_ID
-** macro is a string which identifies a particular check-in of SQLite
-** within its configuration management system. The string contains the
-** date and time of the check-in (UTC) and an SHA1 hash of the entire
-** source tree.
-**
-** See also: [sqlite3_libversion()],
-** [sqlite3_libversion_number()], [sqlite3_sourceid()],
-** [sqlite_version()] and [sqlite_source_id()].
-**
-** Requirements: [H10011] [H10014]
-*/
-#define SQLITE_VERSION "3.6.18"
-#define SQLITE_VERSION_NUMBER 3006018
-#define SQLITE_SOURCE_ID "2009-09-11 14:05:07 b084828a771ec40be85f07c590ca99de4f6c24ee"
-
-/*
-** CAPI3REF: Run-Time Library Version Numbers {H10020} <S60100>
-** KEYWORDS: sqlite3_version
-**
-** These interfaces provide the same information as the [SQLITE_VERSION],
-** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] #defines in the header,
-** but are associated with the library instead of the header file. Cautious
-** programmers might include assert() statements in their application to
-** verify that values returned by these interfaces match the macros in
-** the header, and thus insure that the application is
-** compiled with matching library and header files.
-**
-** <blockquote><pre>
-** assert( sqlite3_libversion_number()==SQLITE_VERSION_NUMBER );
-** assert( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)==0 );
-** assert( strcmp(sqlite3_libversion,SQLITE_VERSION)==0 );
-** </pre></blockquote>
-**
-** The sqlite3_libversion() function returns the same information as is
-** in the sqlite3_version[] string constant. The function is provided
-** for use in DLLs since DLL users usually do not have direct access to string
-** constants within the DLL. Similarly, the sqlite3_sourceid() function
-** returns the same information as is in the [SQLITE_SOURCE_ID] #define of
-** the header file.
-**
-** See also: [sqlite_version()] and [sqlite_source_id()].
-**
-** Requirements: [H10021] [H10022] [H10023]
-*/
-SQLITE_API SQLITE_EXTERN const char sqlite3_version[];
-SQLITE_API const char *sqlite3_libversion(void);
-SQLITE_API const char *sqlite3_sourceid(void);
-SQLITE_API int sqlite3_libversion_number(void);
-
-/*
-** CAPI3REF: Test To See If The Library Is Threadsafe {H10100} <S60100>
-**
-** SQLite can be compiled with or without mutexes. When
-** the [SQLITE_THREADSAFE] C preprocessor macro is 1 or 2, mutexes
-** are enabled and SQLite is threadsafe. When the
-** [SQLITE_THREADSAFE] macro is 0,
-** the mutexes are omitted. Without the mutexes, it is not safe
-** to use SQLite concurrently from more than one thread.
-**
-** Enabling mutexes incurs a measurable performance penalty.
-** So if speed is of utmost importance, it makes sense to disable
-** the mutexes. But for maximum safety, mutexes should be enabled.
-** The default behavior is for mutexes to be enabled.
-**
-** This interface can be used by an application to make sure that the
-** version of SQLite that it is linking against was compiled with
-** the desired setting of the [SQLITE_THREADSAFE] macro.
-**
-** This interface only reports on the compile-time mutex setting
-** of the [SQLITE_THREADSAFE] flag. If SQLite is compiled with
-** SQLITE_THREADSAFE=1 then mutexes are enabled by default but
-** can be fully or partially disabled using a call to [sqlite3_config()]
-** with the verbs [SQLITE_CONFIG_SINGLETHREAD], [SQLITE_CONFIG_MULTITHREAD],
-** or [SQLITE_CONFIG_MUTEX]. The return value of this function shows
-** only the default compile-time setting, not any run-time changes
-** to that setting.
-**
-** See the [threading mode] documentation for additional information.
-**
-** Requirements: [H10101] [H10102]
-*/
-SQLITE_API int sqlite3_threadsafe(void);
-
-/*
-** CAPI3REF: Database Connection Handle {H12000} <S40200>
-** KEYWORDS: {database connection} {database connections}
-**
-** Each open SQLite database is represented by a pointer to an instance of
-** the opaque structure named "sqlite3". It is useful to think of an sqlite3
-** pointer as an object. The [sqlite3_open()], [sqlite3_open16()], and
-** [sqlite3_open_v2()] interfaces are its constructors, and [sqlite3_close()]
-** is its destructor. There are many other interfaces (such as
-** [sqlite3_prepare_v2()], [sqlite3_create_function()], and
-** [sqlite3_busy_timeout()] to name but three) that are methods on an
-** sqlite3 object.
-*/
-typedef struct sqlite3 sqlite3;
-
-/*
-** CAPI3REF: 64-Bit Integer Types {H10200} <S10110>
-** KEYWORDS: sqlite_int64 sqlite_uint64
-**
-** Because there is no cross-platform way to specify 64-bit integer types
-** SQLite includes typedefs for 64-bit signed and unsigned integers.
-**
-** The sqlite3_int64 and sqlite3_uint64 are the preferred type definitions.
-** The sqlite_int64 and sqlite_uint64 types are supported for backwards
-** compatibility only.
-**
-** Requirements: [H10201] [H10202]
-*/
-#ifdef SQLITE_INT64_TYPE
- typedef SQLITE_INT64_TYPE sqlite_int64;
- typedef unsigned SQLITE_INT64_TYPE sqlite_uint64;
-#elif defined(_MSC_VER) || defined(__BORLANDC__)
- typedef __int64 sqlite_int64;
- typedef unsigned __int64 sqlite_uint64;
-#else
- typedef long long int sqlite_int64;
- typedef unsigned long long int sqlite_uint64;
-#endif
-typedef sqlite_int64 sqlite3_int64;
-typedef sqlite_uint64 sqlite3_uint64;
-
-/*
-** If compiling for a processor that lacks floating point support,
-** substitute integer for floating-point.
-*/
-#ifdef SQLITE_OMIT_FLOATING_POINT
-# define double sqlite3_int64
-#endif
-
-/*
-** CAPI3REF: Closing A Database Connection {H12010} <S30100><S40200>
-**
-** This routine is the destructor for the [sqlite3] object.
-**
-** Applications should [sqlite3_finalize | finalize] all [prepared statements]
-** and [sqlite3_blob_close | close] all [BLOB handles] associated with
-** the [sqlite3] object prior to attempting to close the object.
-** The [sqlite3_next_stmt()] interface can be used to locate all
-** [prepared statements] associated with a [database connection] if desired.
-** Typical code might look like this:
-**
-** <blockquote><pre>
-** sqlite3_stmt *pStmt;
-** while( (pStmt = sqlite3_next_stmt(db, 0))!=0 ){
-** &nbsp; sqlite3_finalize(pStmt);
-** }
-** </pre></blockquote>
-**
-** If [sqlite3_close()] is invoked while a transaction is open,
-** the transaction is automatically rolled back.
-**
-** The C parameter to [sqlite3_close(C)] must be either a NULL
-** pointer or an [sqlite3] object pointer obtained
-** from [sqlite3_open()], [sqlite3_open16()], or
-** [sqlite3_open_v2()], and not previously closed.
-**
-** Requirements:
-** [H12011] [H12012] [H12013] [H12014] [H12015] [H12019]
-*/
-SQLITE_API int sqlite3_close(sqlite3 *);
-
-/*
-** The type for a callback function.
-** This is legacy and deprecated. It is included for historical
-** compatibility and is not documented.
-*/
-typedef int (*sqlite3_callback)(void*,int,char**, char**);
-
-/*
-** CAPI3REF: One-Step Query Execution Interface {H12100} <S10000>
-**
-** The sqlite3_exec() interface is a convenient way of running one or more
-** SQL statements without having to write a lot of C code. The UTF-8 encoded
-** SQL statements are passed in as the second parameter to sqlite3_exec().
-** The statements are evaluated one by one until either an error or
-** an interrupt is encountered, or until they are all done. The 3rd parameter
-** is an optional callback that is invoked once for each row of any query
-** results produced by the SQL statements. The 5th parameter tells where
-** to write any error messages.
-**
-** The error message passed back through the 5th parameter is held
-** in memory obtained from [sqlite3_malloc()]. To avoid a memory leak,
-** the calling application should call [sqlite3_free()] on any error
-** message returned through the 5th parameter when it has finished using
-** the error message.
-**
-** If the SQL statement in the 2nd parameter is NULL or an empty string
-** or a string containing only whitespace and comments, then no SQL
-** statements are evaluated and the database is not changed.
-**
-** The sqlite3_exec() interface is implemented in terms of
-** [sqlite3_prepare_v2()], [sqlite3_step()], and [sqlite3_finalize()].
-** The sqlite3_exec() routine does nothing to the database that cannot be done
-** by [sqlite3_prepare_v2()], [sqlite3_step()], and [sqlite3_finalize()].
-**
-** The first parameter to [sqlite3_exec()] must be an valid and open
-** [database connection].
-**
-** The database connection must not be closed while
-** [sqlite3_exec()] is running.
-**
-** The calling function should use [sqlite3_free()] to free
-** the memory that *errmsg is left pointing at once the error
-** message is no longer needed.
-**
-** The SQL statement text in the 2nd parameter to [sqlite3_exec()]
-** must remain unchanged while [sqlite3_exec()] is running.
-**
-** Requirements:
-** [H12101] [H12102] [H12104] [H12105] [H12107] [H12110] [H12113] [H12116]
-** [H12119] [H12122] [H12125] [H12131] [H12134] [H12137] [H12138]
-*/
-SQLITE_API int sqlite3_exec(
- sqlite3*, /* An open database */
- const char *sql, /* SQL to be evaluated */
- int (*callback)(void*,int,char**,char**), /* Callback function */
- void *, /* 1st argument to callback */
- char **errmsg /* Error msg written here */
-);
-
-/*
-** CAPI3REF: Result Codes {H10210} <S10700>
-** KEYWORDS: SQLITE_OK {error code} {error codes}
-** 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.
-**
-** New error codes may be added in future versions of SQLite.
-**
-** See also: [SQLITE_IOERR_READ | extended result codes]
-*/
-#define SQLITE_OK 0 /* Successful result */
-/* beginning-of-error-codes */
-#define SQLITE_ERROR 1 /* SQL error or missing database */
-#define SQLITE_INTERNAL 2 /* Internal logic error in SQLite */
-#define SQLITE_PERM 3 /* Access permission denied */
-#define SQLITE_ABORT 4 /* Callback routine requested an abort */
-#define SQLITE_BUSY 5 /* The database file is locked */
-#define SQLITE_LOCKED 6 /* A table in the database is locked */
-#define SQLITE_NOMEM 7 /* A malloc() failed */
-#define SQLITE_READONLY 8 /* Attempt to write a readonly database */
-#define SQLITE_INTERRUPT 9 /* Operation terminated by sqlite3_interrupt()*/
-#define SQLITE_IOERR 10 /* Some kind of disk I/O error occurred */
-#define SQLITE_CORRUPT 11 /* The database disk image is malformed */
-#define SQLITE_NOTFOUND 12 /* NOT USED. Table or record not found */
-#define SQLITE_FULL 13 /* Insertion failed because database is full */
-#define SQLITE_CANTOPEN 14 /* Unable to open the database file */
-#define SQLITE_PROTOCOL 15 /* NOT USED. Database lock protocol error */
-#define SQLITE_EMPTY 16 /* Database is empty */
-#define SQLITE_SCHEMA 17 /* The database schema changed */
-#define SQLITE_TOOBIG 18 /* String or BLOB exceeds size limit */
-#define SQLITE_CONSTRAINT 19 /* Abort due to constraint violation */
-#define SQLITE_MISMATCH 20 /* Data type mismatch */
-#define SQLITE_MISUSE 21 /* Library used incorrectly */
-#define SQLITE_NOLFS 22 /* Uses OS features not supported on host */
-#define SQLITE_AUTH 23 /* Authorization denied */
-#define SQLITE_FORMAT 24 /* Auxiliary database format error */
-#define SQLITE_RANGE 25 /* 2nd parameter to sqlite3_bind out of range */
-#define SQLITE_NOTADB 26 /* File opened that is not a database file */
-#define SQLITE_ROW 100 /* sqlite3_step() has another row ready */
-#define SQLITE_DONE 101 /* sqlite3_step() has finished executing */
-/* end-of-error-codes */
-
-/*
-** CAPI3REF: Extended Result Codes {H10220} <S10700>
-** KEYWORDS: {extended error code} {extended error codes}
-** KEYWORDS: {extended result code} {extended result codes}
-**
-** In its default configuration, SQLite API routines return one of 26 integer
-** [SQLITE_OK | result codes]. However, experience has shown that many of
-** these result codes are too coarse-grained. They do not provide as
-** much information about problems as programmers might like. In an effort to
-** address this, newer versions of SQLite (version 3.3.8 and later) include
-** support for additional result codes that provide more detailed information
-** about errors. The extended result codes are enabled or disabled
-** on a per database connection basis using the
-** [sqlite3_extended_result_codes()] API.
-**
-** Some of the available extended result codes are listed here.
-** One may expect the number of extended result codes will be expand
-** over time. Software that uses extended result codes should expect
-** to see new result codes in future releases of SQLite.
-**
-** The SQLITE_OK result code will never be extended. It will always
-** be exactly zero.
-*/
-#define SQLITE_IOERR_READ (SQLITE_IOERR | (1<<8))
-#define SQLITE_IOERR_SHORT_READ (SQLITE_IOERR | (2<<8))
-#define SQLITE_IOERR_WRITE (SQLITE_IOERR | (3<<8))
-#define SQLITE_IOERR_FSYNC (SQLITE_IOERR | (4<<8))
-#define SQLITE_IOERR_DIR_FSYNC (SQLITE_IOERR | (5<<8))
-#define SQLITE_IOERR_TRUNCATE (SQLITE_IOERR | (6<<8))
-#define SQLITE_IOERR_FSTAT (SQLITE_IOERR | (7<<8))
-#define SQLITE_IOERR_UNLOCK (SQLITE_IOERR | (8<<8))
-#define SQLITE_IOERR_RDLOCK (SQLITE_IOERR | (9<<8))
-#define SQLITE_IOERR_DELETE (SQLITE_IOERR | (10<<8))
-#define SQLITE_IOERR_BLOCKED (SQLITE_IOERR | (11<<8))
-#define SQLITE_IOERR_NOMEM (SQLITE_IOERR | (12<<8))
-#define SQLITE_IOERR_ACCESS (SQLITE_IOERR | (13<<8))
-#define SQLITE_IOERR_CHECKRESERVEDLOCK (SQLITE_IOERR | (14<<8))
-#define SQLITE_IOERR_LOCK (SQLITE_IOERR | (15<<8))
-#define SQLITE_IOERR_CLOSE (SQLITE_IOERR | (16<<8))
-#define SQLITE_IOERR_DIR_CLOSE (SQLITE_IOERR | (17<<8))
-#define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8) )
-
-/*
-** CAPI3REF: Flags For File Open Operations {H10230} <H11120> <H12700>
-**
-** These bit values are intended for use in the
-** 3rd parameter to the [sqlite3_open_v2()] interface and
-** in the 4th parameter to the xOpen method of the
-** [sqlite3_vfs] object.
-*/
-#define SQLITE_OPEN_READONLY 0x00000001 /* Ok for sqlite3_open_v2() */
-#define SQLITE_OPEN_READWRITE 0x00000002 /* Ok for sqlite3_open_v2() */
-#define SQLITE_OPEN_CREATE 0x00000004 /* Ok for sqlite3_open_v2() */
-#define SQLITE_OPEN_DELETEONCLOSE 0x00000008 /* VFS only */
-#define SQLITE_OPEN_EXCLUSIVE 0x00000010 /* VFS only */
-#define SQLITE_OPEN_MAIN_DB 0x00000100 /* VFS only */
-#define SQLITE_OPEN_TEMP_DB 0x00000200 /* VFS only */
-#define SQLITE_OPEN_TRANSIENT_DB 0x00000400 /* VFS only */
-#define SQLITE_OPEN_MAIN_JOURNAL 0x00000800 /* VFS only */
-#define SQLITE_OPEN_TEMP_JOURNAL 0x00001000 /* VFS only */
-#define SQLITE_OPEN_SUBJOURNAL 0x00002000 /* VFS only */
-#define SQLITE_OPEN_MASTER_JOURNAL 0x00004000 /* VFS only */
-#define SQLITE_OPEN_NOMUTEX 0x00008000 /* Ok for sqlite3_open_v2() */
-#define SQLITE_OPEN_FULLMUTEX 0x00010000 /* Ok for sqlite3_open_v2() */
-#define SQLITE_OPEN_SHAREDCACHE 0x00020000 /* Ok for sqlite3_open_v2() */
-#define SQLITE_OPEN_PRIVATECACHE 0x00040000 /* Ok for sqlite3_open_v2() */
-
-/*
-** CAPI3REF: Device Characteristics {H10240} <H11120>
-**
-** The xDeviceCapabilities method of the [sqlite3_io_methods]
-** object returns an integer which is a vector of the these
-** bit values expressing I/O characteristics of the mass storage
-** device that holds the file that the [sqlite3_io_methods]
-** refers to.
-**
-** The SQLITE_IOCAP_ATOMIC property means that all writes of
-** any size are atomic. The SQLITE_IOCAP_ATOMICnnn values
-** mean that writes of blocks that are nnn bytes in size and
-** are aligned to an address which is an integer multiple of
-** nnn are atomic. The SQLITE_IOCAP_SAFE_APPEND value means
-** that when data is appended to a file, the data is appended
-** 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().
-*/
-#define SQLITE_IOCAP_ATOMIC 0x00000001
-#define SQLITE_IOCAP_ATOMIC512 0x00000002
-#define SQLITE_IOCAP_ATOMIC1K 0x00000004
-#define SQLITE_IOCAP_ATOMIC2K 0x00000008
-#define SQLITE_IOCAP_ATOMIC4K 0x00000010
-#define SQLITE_IOCAP_ATOMIC8K 0x00000020
-#define SQLITE_IOCAP_ATOMIC16K 0x00000040
-#define SQLITE_IOCAP_ATOMIC32K 0x00000080
-#define SQLITE_IOCAP_ATOMIC64K 0x00000100
-#define SQLITE_IOCAP_SAFE_APPEND 0x00000200
-#define SQLITE_IOCAP_SEQUENTIAL 0x00000400
-
-/*
-** CAPI3REF: File Locking Levels {H10250} <H11120> <H11310>
-**
-** SQLite uses one of these integer values as the second
-** argument to calls it makes to the xLock() and xUnlock() methods
-** of an [sqlite3_io_methods] object.
-*/
-#define SQLITE_LOCK_NONE 0
-#define SQLITE_LOCK_SHARED 1
-#define SQLITE_LOCK_RESERVED 2
-#define SQLITE_LOCK_PENDING 3
-#define SQLITE_LOCK_EXCLUSIVE 4
-
-/*
-** CAPI3REF: Synchronization Type Flags {H10260} <H11120>
-**
-** When SQLite invokes the xSync() method of an
-** [sqlite3_io_methods] object it uses a combination of
-** these integer values as the second argument.
-**
-** When the SQLITE_SYNC_DATAONLY flag is used, it means that the
-** sync operation only needs to flush data to mass storage. Inode
-** information need not be flushed. If the lower four bits of the flag
-** equal SQLITE_SYNC_NORMAL, that means to use normal fsync() semantics.
-** If the lower four bits equal SQLITE_SYNC_FULL, that means
-** to use Mac OS X style fullsync instead of fsync().
-*/
-#define SQLITE_SYNC_NORMAL 0x00002
-#define SQLITE_SYNC_FULL 0x00003
-#define SQLITE_SYNC_DATAONLY 0x00010
-
-/*
-** CAPI3REF: OS Interface Open File Handle {H11110} <S20110>
-**
-** An [sqlite3_file] object represents an open file in the
-** [sqlite3_vfs | OS interface layer]. Individual OS interface
-** implementations will
-** want to subclass this object by appending additional fields
-** for their own use. The pMethods entry is a pointer to an
-** [sqlite3_io_methods] object that defines methods for performing
-** I/O operations on the open file.
-*/
-typedef struct sqlite3_file sqlite3_file;
-struct sqlite3_file {
- const struct sqlite3_io_methods *pMethods; /* Methods for an open file */
-};
-
-/*
-** CAPI3REF: OS Interface File Virtual Methods Object {H11120} <S20110>
-**
-** Every file opened by the [sqlite3_vfs] xOpen method populates an
-** [sqlite3_file] object (or, more commonly, a subclass of the
-** [sqlite3_file] object) with a pointer to an instance of this object.
-** This object defines the methods used to perform various operations
-** against the open file represented by the [sqlite3_file] object.
-**
-** If the xOpen method sets the sqlite3_file.pMethods element
-** to a non-NULL pointer, then the sqlite3_io_methods.xClose method
-** may be invoked even if the xOpen reported that it failed. The
-** only way to prevent a call to xClose following a failed xOpen
-** is for the xOpen to set the sqlite3_file.pMethods element to NULL.
-**
-** The flags argument to xSync may be one of [SQLITE_SYNC_NORMAL] or
-** [SQLITE_SYNC_FULL]. The first choice is the normal fsync().
-** The second choice is a Mac OS X style fullsync. The [SQLITE_SYNC_DATAONLY]
-** flag may be ORed in to indicate that only the data of the file
-** and not its inode needs to be synced.
-**
-** The integer values to xLock() and xUnlock() are one of
-** <ul>
-** <li> [SQLITE_LOCK_NONE],
-** <li> [SQLITE_LOCK_SHARED],
-** <li> [SQLITE_LOCK_RESERVED],
-** <li> [SQLITE_LOCK_PENDING], or
-** <li> [SQLITE_LOCK_EXCLUSIVE].
-** </ul>
-** xLock() increases the lock. xUnlock() decreases the lock.
-** The xCheckReservedLock() method checks whether any database connection,
-** either in this process or in some other process, is holding a RESERVED,
-** PENDING, or EXCLUSIVE lock on the file. It returns true
-** if such a lock exists and false otherwise.
-**
-** The xFileControl() method is a generic interface that allows custom
-** VFS implementations to directly control an open file using the
-** [sqlite3_file_control()] interface. The second "op" argument is an
-** integer opcode. The third argument is a generic pointer intended to
-** point to a structure that may contain arguments or space in which to
-** write return values. Potential uses for xFileControl() might be
-** functions to enable blocking locks with timeouts, to change the
-** locking strategy (for example to use dot-file locks), to inquire
-** about the status of a lock, or to break stale locks. The SQLite
-** core reserves all opcodes less than 100 for its own use.
-** A [SQLITE_FCNTL_LOCKSTATE | list of opcodes] less than 100 is available.
-** Applications that define a custom xFileControl method should use opcodes
-** greater than 100 to avoid conflicts.
-**
-** The xSectorSize() method returns the sector size of the
-** device that underlies the file. The sector size is the
-** minimum write that can be performed without disturbing
-** other bytes in the file. The xDeviceCharacteristics()
-** method returns a bit vector describing behaviors of the
-** underlying device:
-**
-** <ul>
-** <li> [SQLITE_IOCAP_ATOMIC]
-** <li> [SQLITE_IOCAP_ATOMIC512]
-** <li> [SQLITE_IOCAP_ATOMIC1K]
-** <li> [SQLITE_IOCAP_ATOMIC2K]
-** <li> [SQLITE_IOCAP_ATOMIC4K]
-** <li> [SQLITE_IOCAP_ATOMIC8K]
-** <li> [SQLITE_IOCAP_ATOMIC16K]
-** <li> [SQLITE_IOCAP_ATOMIC32K]
-** <li> [SQLITE_IOCAP_ATOMIC64K]
-** <li> [SQLITE_IOCAP_SAFE_APPEND]
-** <li> [SQLITE_IOCAP_SEQUENTIAL]
-** </ul>
-**
-** The SQLITE_IOCAP_ATOMIC property means that all writes of
-** any size are atomic. The SQLITE_IOCAP_ATOMICnnn values
-** mean that writes of blocks that are nnn bytes in size and
-** are aligned to an address which is an integer multiple of
-** nnn are atomic. The SQLITE_IOCAP_SAFE_APPEND value means
-** that when data is appended to a file, the data is appended
-** 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().
-**
-** If xRead() returns SQLITE_IOERR_SHORT_READ it must also fill
-** in the unread portions of the buffer with zeros. A VFS that
-** fails to zero-fill short reads might seem to work. However,
-** failure to zero-fill short reads will eventually lead to
-** database corruption.
-*/
-typedef struct sqlite3_io_methods sqlite3_io_methods;
-struct sqlite3_io_methods {
- int iVersion;
- int (*xClose)(sqlite3_file*);
- int (*xRead)(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst);
- int (*xWrite)(sqlite3_file*, const void*, int iAmt, sqlite3_int64 iOfst);
- int (*xTruncate)(sqlite3_file*, sqlite3_int64 size);
- int (*xSync)(sqlite3_file*, int flags);
- int (*xFileSize)(sqlite3_file*, sqlite3_int64 *pSize);
- int (*xLock)(sqlite3_file*, int);
- int (*xUnlock)(sqlite3_file*, int);
- int (*xCheckReservedLock)(sqlite3_file*, int *pResOut);
- int (*xFileControl)(sqlite3_file*, int op, void *pArg);
- int (*xSectorSize)(sqlite3_file*);
- int (*xDeviceCharacteristics)(sqlite3_file*);
- /* Additional methods may be added in future releases */
-};
-
-/*
-** CAPI3REF: Standard File Control Opcodes {H11310} <S30800>
-**
-** These integer constants are opcodes for the xFileControl method
-** of the [sqlite3_io_methods] object and for the [sqlite3_file_control()]
-** interface.
-**
-** The [SQLITE_FCNTL_LOCKSTATE] opcode is used for debugging. This
-** opcode causes the xFileControl method to write the current state of
-** the lock (one of [SQLITE_LOCK_NONE], [SQLITE_LOCK_SHARED],
-** [SQLITE_LOCK_RESERVED], [SQLITE_LOCK_PENDING], or [SQLITE_LOCK_EXCLUSIVE])
-** into an integer that the pArg argument points to. This capability
-** is used during testing and only needs to be supported when SQLITE_TEST
-** is defined.
-*/
-#define SQLITE_FCNTL_LOCKSTATE 1
-#define SQLITE_GET_LOCKPROXYFILE 2
-#define SQLITE_SET_LOCKPROXYFILE 3
-#define SQLITE_LAST_ERRNO 4
-
-/*
-** CAPI3REF: Mutex Handle {H17110} <S20130>
-**
-** The mutex module within SQLite defines [sqlite3_mutex] to be an
-** abstract type for a mutex object. The SQLite core never looks
-** at the internal representation of an [sqlite3_mutex]. It only
-** deals with pointers to the [sqlite3_mutex] object.
-**
-** Mutexes are created using [sqlite3_mutex_alloc()].
-*/
-typedef struct sqlite3_mutex sqlite3_mutex;
-
-/*
-** CAPI3REF: OS Interface Object {H11140} <S20100>
-**
-** An instance of the sqlite3_vfs object defines the interface between
-** the SQLite core and the underlying operating system. The "vfs"
-** in the name of the object stands for "virtual file system".
-**
-** The value of the iVersion field is initially 1 but may be larger in
-** future versions of SQLite. Additional fields may be appended to this
-** object when the iVersion value is increased. Note that the structure
-** of the sqlite3_vfs object changes in the transaction between
-** SQLite version 3.5.9 and 3.6.0 and yet the iVersion field was not
-** modified.
-**
-** The szOsFile field is the size of the subclassed [sqlite3_file]
-** structure used by this VFS. mxPathname is the maximum length of
-** a pathname in this VFS.
-**
-** Registered sqlite3_vfs objects are kept on a linked list formed by
-** the pNext pointer. The [sqlite3_vfs_register()]
-** and [sqlite3_vfs_unregister()] interfaces manage this list
-** in a thread-safe way. The [sqlite3_vfs_find()] interface
-** searches the list. Neither the application code nor the VFS
-** implementation should use the pNext pointer.
-**
-** The pNext field is the only field in the sqlite3_vfs
-** structure that SQLite will ever modify. SQLite will only access
-** or modify this field while holding a particular static mutex.
-** The application should never modify anything within the sqlite3_vfs
-** object once the object has been registered.
-**
-** The zName field holds the name of the VFS module. The name must
-** be unique across all VFS modules.
-**
-** SQLite will guarantee that the zFilename parameter to xOpen
-** is either a NULL pointer or string obtained
-** from xFullPathname(). SQLite further guarantees that
-** the string will be valid and unchanged until xClose() is
-** called. Because of the previous sentence,
-** the [sqlite3_file] can safely store a pointer to the
-** filename if it needs to remember the filename for some reason.
-** If the zFilename parameter is xOpen is a NULL pointer then xOpen
-** must invent its own temporary name for the file. Whenever the
-** xFilename parameter is NULL it will also be the case that the
-** flags parameter will include [SQLITE_OPEN_DELETEONCLOSE].
-**
-** The flags argument to xOpen() includes all bits set in
-** the flags argument to [sqlite3_open_v2()]. Or if [sqlite3_open()]
-** or [sqlite3_open16()] is used, then flags includes at least
-** [SQLITE_OPEN_READWRITE] | [SQLITE_OPEN_CREATE].
-** If xOpen() opens a file read-only then it sets *pOutFlags to
-** include [SQLITE_OPEN_READONLY]. Other bits in *pOutFlags may be set.
-**
-** SQLite will also add one of the following flags to the xOpen()
-** call, depending on the object being opened:
-**
-** <ul>
-** <li> [SQLITE_OPEN_MAIN_DB]
-** <li> [SQLITE_OPEN_MAIN_JOURNAL]
-** <li> [SQLITE_OPEN_TEMP_DB]
-** <li> [SQLITE_OPEN_TEMP_JOURNAL]
-** <li> [SQLITE_OPEN_TRANSIENT_DB]
-** <li> [SQLITE_OPEN_SUBJOURNAL]
-** <li> [SQLITE_OPEN_MASTER_JOURNAL]
-** </ul>
-**
-** The file I/O implementation can use the object type flags to
-** change the way it deals with files. For example, an application
-** that does not care about crash recovery or rollback might make
-** the open of a journal file a no-op. Writes to this journal would
-** also be no-ops, and any attempt to read the journal would return
-** SQLITE_IOERR. Or the implementation might recognize that a database
-** file will be doing page-aligned sector reads and writes in a random
-** order and set up its I/O subsystem accordingly.
-**
-** SQLite might also add one of the following flags to the xOpen method:
-**
-** <ul>
-** <li> [SQLITE_OPEN_DELETEONCLOSE]
-** <li> [SQLITE_OPEN_EXCLUSIVE]
-** </ul>
-**
-** The [SQLITE_OPEN_DELETEONCLOSE] flag means the file should be
-** deleted when it is closed. The [SQLITE_OPEN_DELETEONCLOSE]
-** will be set for TEMP databases, journals and for subjournals.
-**
-** The [SQLITE_OPEN_EXCLUSIVE] flag is always used in conjunction
-** with the [SQLITE_OPEN_CREATE] flag, which are both directly
-** analogous to the O_EXCL and O_CREAT flags of the POSIX open()
-** API. The SQLITE_OPEN_EXCLUSIVE flag, when paired with the
-** SQLITE_OPEN_CREATE, is used to indicate that file should always
-** be created, and that it is an error if it already exists.
-** It is <i>not</i> used to indicate the file should be opened
-** for exclusive access.
-**
-** At least szOsFile bytes of memory are allocated by SQLite
-** to hold the [sqlite3_file] structure passed as the third
-** argument to xOpen. The xOpen method does not have to
-** allocate the structure; it should just fill it in. Note that
-** the xOpen method must set the sqlite3_file.pMethods to either
-** a valid [sqlite3_io_methods] object or to NULL. xOpen must do
-** this even if the open fails. SQLite expects that the sqlite3_file.pMethods
-** element will be valid after xOpen returns regardless of the success
-** or failure of the xOpen call.
-**
-** The flags argument to xAccess() may be [SQLITE_ACCESS_EXISTS]
-** to test for the existence of a file, or [SQLITE_ACCESS_READWRITE] to
-** test whether a file is readable and writable, or [SQLITE_ACCESS_READ]
-** to test whether a file is at least readable. The file can be a
-** directory.
-**
-** SQLite will always allocate at least mxPathname+1 bytes for the
-** output buffer xFullPathname. The exact size of the output buffer
-** is also passed as a parameter to both methods. If the output buffer
-** is not large enough, [SQLITE_CANTOPEN] should be returned. Since this is
-** handled as a fatal error by SQLite, vfs implementations should endeavor
-** to prevent this by setting mxPathname to a sufficiently large value.
-**
-** The xRandomness(), xSleep(), and xCurrentTime() interfaces
-** are not strictly a part of the filesystem, but they are
-** included in the VFS structure for completeness.
-** The xRandomness() function attempts to return nBytes bytes
-** of good-quality randomness into zOut. The return value is
-** the actual number of bytes of randomness obtained.
-** The xSleep() method causes the calling thread to sleep for at
-** least the number of microseconds given. The xCurrentTime()
-** method returns a Julian Day Number for the current date and time.
-**
-*/
-typedef struct sqlite3_vfs sqlite3_vfs;
-struct sqlite3_vfs {
- int iVersion; /* Structure version number */
- int szOsFile; /* Size of subclassed sqlite3_file */
- int mxPathname; /* Maximum file pathname length */
- sqlite3_vfs *pNext; /* Next registered VFS */
- const char *zName; /* Name of this virtual file system */
- void *pAppData; /* Pointer to application-specific data */
- int (*xOpen)(sqlite3_vfs*, const char *zName, sqlite3_file*,
- int flags, int *pOutFlags);
- int (*xDelete)(sqlite3_vfs*, const char *zName, int syncDir);
- int (*xAccess)(sqlite3_vfs*, const char *zName, int flags, int *pResOut);
- int (*xFullPathname)(sqlite3_vfs*, const char *zName, int nOut, char *zOut);
- void *(*xDlOpen)(sqlite3_vfs*, const char *zFilename);
- void (*xDlError)(sqlite3_vfs*, int nByte, char *zErrMsg);
- void (*(*xDlSym)(sqlite3_vfs*,void*, const char *zSymbol))(void);
- void (*xDlClose)(sqlite3_vfs*, void*);
- int (*xRandomness)(sqlite3_vfs*, int nByte, char *zOut);
- int (*xSleep)(sqlite3_vfs*, int microseconds);
- int (*xCurrentTime)(sqlite3_vfs*, double*);
- int (*xGetLastError)(sqlite3_vfs*, int, char *);
- /* New fields may be appended in figure versions. The iVersion
- ** value will increment whenever this happens. */
-};
-
-/*
-** CAPI3REF: Flags for the xAccess VFS method {H11190} <H11140>
-**
-** These integer constants can be used as the third parameter to
-** the xAccess method of an [sqlite3_vfs] object. {END} They determine
-** what kind of permissions the xAccess method is looking for.
-** With SQLITE_ACCESS_EXISTS, the xAccess method
-** simply checks whether the file exists.
-** With SQLITE_ACCESS_READWRITE, the xAccess method
-** checks whether the file is both readable and writable.
-** With SQLITE_ACCESS_READ, the xAccess method
-** checks whether the file is readable.
-*/
-#define SQLITE_ACCESS_EXISTS 0
-#define SQLITE_ACCESS_READWRITE 1
-#define SQLITE_ACCESS_READ 2
-
-/*
-** CAPI3REF: Initialize The SQLite Library {H10130} <S20000><S30100>
-**
-** The sqlite3_initialize() routine initializes the
-** SQLite library. The sqlite3_shutdown() routine
-** deallocates any resources that were allocated by sqlite3_initialize().
-**
-** A call to sqlite3_initialize() is an "effective" call if it is
-** the first time sqlite3_initialize() is invoked during the lifetime of
-** the process, or if it is the first time sqlite3_initialize() is invoked
-** following a call to sqlite3_shutdown(). Only an effective call
-** of sqlite3_initialize() does any initialization. All other calls
-** are harmless no-ops.
-**
-** A call to sqlite3_shutdown() is an "effective" call if it is the first
-** call to sqlite3_shutdown() since the last sqlite3_initialize(). Only
-** an effective call to sqlite3_shutdown() does any deinitialization.
-** All other calls to sqlite3_shutdown() are harmless no-ops.
-**
-** Among other things, sqlite3_initialize() shall invoke
-** sqlite3_os_init(). Similarly, sqlite3_shutdown()
-** shall invoke sqlite3_os_end().
-**
-** The sqlite3_initialize() routine returns [SQLITE_OK] on success.
-** If for some reason, sqlite3_initialize() is unable to initialize
-** the library (perhaps it is unable to allocate a needed resource such
-** as a mutex) it returns an [error code] other than [SQLITE_OK].
-**
-** The sqlite3_initialize() routine is called internally by many other
-** SQLite interfaces so that an application usually does not need to
-** invoke sqlite3_initialize() directly. For example, [sqlite3_open()]
-** calls sqlite3_initialize() so the SQLite library will be automatically
-** initialized when [sqlite3_open()] is called if it has not be initialized
-** already. However, if SQLite is compiled with the [SQLITE_OMIT_AUTOINIT]
-** compile-time option, then the automatic calls to sqlite3_initialize()
-** are omitted and the application must call sqlite3_initialize() directly
-** prior to using any other SQLite interface. For maximum portability,
-** it is recommended that applications always invoke sqlite3_initialize()
-** directly prior to using any other SQLite interface. Future releases
-** of SQLite may require this. In other words, the behavior exhibited
-** when SQLite is compiled with [SQLITE_OMIT_AUTOINIT] might become the
-** default behavior in some future release of SQLite.
-**
-** The sqlite3_os_init() routine does operating-system specific
-** initialization of the SQLite library. The sqlite3_os_end()
-** routine undoes the effect of sqlite3_os_init(). Typical tasks
-** performed by these routines include allocation or deallocation
-** of static resources, initialization of global variables,
-** setting up a default [sqlite3_vfs] module, or setting up
-** a default configuration using [sqlite3_config()].
-**
-** The application should never invoke either sqlite3_os_init()
-** or sqlite3_os_end() directly. The application should only invoke
-** sqlite3_initialize() and sqlite3_shutdown(). The sqlite3_os_init()
-** interface is called automatically by sqlite3_initialize() and
-** sqlite3_os_end() is called by sqlite3_shutdown(). Appropriate
-** implementations for sqlite3_os_init() and sqlite3_os_end()
-** are built into SQLite when it is compiled for Unix, Windows, or OS/2.
-** When [custom builds | built for other platforms]
-** (using the [SQLITE_OS_OTHER=1] compile-time
-** option) the application must supply a suitable implementation for
-** sqlite3_os_init() and sqlite3_os_end(). An application-supplied
-** implementation of sqlite3_os_init() or sqlite3_os_end()
-** must return [SQLITE_OK] on success and some other [error code] upon
-** failure.
-*/
-SQLITE_API int sqlite3_initialize(void);
-SQLITE_API int sqlite3_shutdown(void);
-SQLITE_API int sqlite3_os_init(void);
-SQLITE_API int sqlite3_os_end(void);
-
-/*
-** CAPI3REF: Configuring The SQLite Library {H14100} <S20000><S30200>
-** EXPERIMENTAL
-**
-** The sqlite3_config() interface is used to make global configuration
-** changes to SQLite in order to tune SQLite to the specific needs of
-** the application. The default configuration is recommended for most
-** applications and so this routine is usually not necessary. It is
-** provided to support rare applications with unusual needs.
-**
-** The sqlite3_config() interface is not threadsafe. The application
-** must insure that no other SQLite interfaces are invoked by other
-** threads while sqlite3_config() is running. Furthermore, sqlite3_config()
-** may only be invoked prior to library initialization using
-** [sqlite3_initialize()] or after shutdown by [sqlite3_shutdown()].
-** Note, however, that sqlite3_config() can be called as part of the
-** implementation of an application-defined [sqlite3_os_init()].
-**
-** The first argument to sqlite3_config() is an integer
-** [SQLITE_CONFIG_SINGLETHREAD | configuration option] that determines
-** what property of SQLite is to be configured. Subsequent arguments
-** vary depending on the [SQLITE_CONFIG_SINGLETHREAD | configuration option]
-** in the first argument.
-**
-** When a configuration option is set, sqlite3_config() returns [SQLITE_OK].
-** If the option is unknown or SQLite is unable to set the option
-** then this routine returns a non-zero [error code].
-**
-** Requirements:
-** [H14103] [H14106] [H14120] [H14123] [H14126] [H14129] [H14132] [H14135]
-** [H14138] [H14141] [H14144] [H14147] [H14150] [H14153] [H14156] [H14159]
-** [H14162] [H14165] [H14168]
-*/
-SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_config(int, ...);
-
-/*
-** CAPI3REF: Configure database connections {H14200} <S20000>
-** EXPERIMENTAL
-**
-** The sqlite3_db_config() interface is used to make configuration
-** changes to a [database connection]. The interface is similar to
-** [sqlite3_config()] except that the changes apply to a single
-** [database connection] (specified in the first argument). The
-** sqlite3_db_config() interface can only be used immediately after
-** the database connection is created using [sqlite3_open()],
-** [sqlite3_open16()], or [sqlite3_open_v2()].
-**
-** The second argument to sqlite3_db_config(D,V,...) is the
-** configuration verb - an integer code that indicates what
-** aspect of the [database connection] is being configured.
-** The only choice for this value is [SQLITE_DBCONFIG_LOOKASIDE].
-** New verbs are likely to be added in future releases of SQLite.
-** Additional arguments depend on the verb.
-**
-** Requirements:
-** [H14203] [H14206] [H14209] [H14212] [H14215]
-*/
-SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_db_config(sqlite3*, int op, ...);
-
-/*
-** CAPI3REF: Memory Allocation Routines {H10155} <S20120>
-** EXPERIMENTAL
-**
-** An instance of this object defines the interface between SQLite
-** and low-level memory allocation routines.
-**
-** This object is used in only one place in the SQLite interface.
-** A pointer to an instance of this object is the argument to
-** [sqlite3_config()] when the configuration option is
-** [SQLITE_CONFIG_MALLOC] or [SQLITE_CONFIG_GETMALLOC].
-** By creating an instance of this object
-** and passing it to [sqlite3_config]([SQLITE_CONFIG_MALLOC])
-** during configuration, an application can specify an alternative
-** memory allocation subsystem for SQLite to use for all of its
-** dynamic memory needs.
-**
-** Note that SQLite comes with several [built-in memory allocators]
-** that are perfectly adequate for the overwhelming majority of applications
-** and that this object is only useful to a tiny minority of applications
-** with specialized memory allocation requirements. This object is
-** also used during testing of SQLite in order to specify an alternative
-** memory allocator that simulates memory out-of-memory conditions in
-** order to verify that SQLite recovers gracefully from such
-** conditions.
-**
-** The xMalloc and xFree methods must work like the
-** malloc() and free() functions from the standard C library.
-** The xRealloc method must work like realloc() from the standard C library
-** with the exception that if the second argument to xRealloc is zero,
-** xRealloc must be a no-op - it must not perform any allocation or
-** deallocation. SQLite guaranteeds that the second argument to
-** xRealloc is always a value returned by a prior call to xRoundup.
-** And so in cases where xRoundup always returns a positive number,
-** xRealloc can perform exactly as the standard library realloc() and
-** still be in compliance with this specification.
-**
-** xSize should return the allocated size of a memory allocation
-** previously obtained from xMalloc or xRealloc. The allocated size
-** is always at least as big as the requested size but may be larger.
-**
-** The xRoundup method returns what would be the allocated size of
-** a memory allocation given a particular requested size. Most memory
-** allocators round up memory allocations at least to the next multiple
-** of 8. Some allocators round up to a larger multiple or to a power of 2.
-** Every memory allocation request coming in through [sqlite3_malloc()]
-** or [sqlite3_realloc()] first calls xRoundup. If xRoundup returns 0,
-** that causes the corresponding memory allocation to fail.
-**
-** The xInit method initializes the memory allocator. (For example,
-** it might allocate any require mutexes or initialize internal data
-** structures. The xShutdown method is invoked (indirectly) by
-** [sqlite3_shutdown()] and should deallocate any resources acquired
-** by xInit. The pAppData pointer is used as the only parameter to
-** xInit and xShutdown.
-**
-** SQLite holds the [SQLITE_MUTEX_STATIC_MASTER] mutex when it invokes
-** the xInit method, so the xInit method need not be threadsafe. The
-** xShutdown method is only called from [sqlite3_shutdown()] so it does
-** not need to be threadsafe either. For all other methods, SQLite
-** holds the [SQLITE_MUTEX_STATIC_MEM] mutex as long as the
-** [SQLITE_CONFIG_MEMSTATUS] configuration option is turned on (which
-** it is by default) and so the methods are automatically serialized.
-** However, if [SQLITE_CONFIG_MEMSTATUS] is disabled, then the other
-** methods must be threadsafe or else make their own arrangements for
-** serialization.
-**
-** SQLite will never invoke xInit() more than once without an intervening
-** call to xShutdown().
-*/
-typedef struct sqlite3_mem_methods sqlite3_mem_methods;
-struct sqlite3_mem_methods {
- void *(*xMalloc)(int); /* Memory allocation function */
- void (*xFree)(void*); /* Free a prior allocation */
- void *(*xRealloc)(void*,int); /* Resize an allocation */
- int (*xSize)(void*); /* Return the size of an allocation */
- int (*xRoundup)(int); /* Round up request size to allocation size */
- int (*xInit)(void*); /* Initialize the memory allocator */
- void (*xShutdown)(void*); /* Deinitialize the memory allocator */
- void *pAppData; /* Argument to xInit() and xShutdown() */
-};
-
-/*
-** CAPI3REF: Configuration Options {H10160} <S20000>
-** EXPERIMENTAL
-**
-** These constants are the available integer configuration options that
-** can be passed as the first argument to the [sqlite3_config()] interface.
-**
-** New configuration options may be added in future releases of SQLite.
-** Existing configuration options might be discontinued. Applications
-** should check the return code from [sqlite3_config()] to make sure that
-** the call worked. The [sqlite3_config()] interface will return a
-** non-zero [error code] if a discontinued or unsupported configuration option
-** is invoked.
-**
-** <dl>
-** <dt>SQLITE_CONFIG_SINGLETHREAD</dt>
-** <dd>There are no arguments to this option. This option disables
-** all mutexing and puts SQLite into a mode where it can only be used
-** by a single thread.</dd>
-**
-** <dt>SQLITE_CONFIG_MULTITHREAD</dt>
-** <dd>There are no arguments to this option. This option disables
-** mutexing on [database connection] and [prepared statement] objects.
-** The application is responsible for serializing access to
-** [database connections] and [prepared statements]. But other mutexes
-** are enabled so that SQLite will be safe to use in a multi-threaded
-** environment as long as no two threads attempt to use the same
-** [database connection] at the same time. See the [threading mode]
-** documentation for additional information.</dd>
-**
-** <dt>SQLITE_CONFIG_SERIALIZED</dt>
-** <dd>There are no arguments to this option. This option enables
-** all mutexes including the recursive
-** mutexes on [database connection] and [prepared statement] objects.
-** In this mode (which is the default when SQLite is compiled with
-** [SQLITE_THREADSAFE=1]) the SQLite library will itself serialize access
-** to [database connections] and [prepared statements] so that the
-** application is free to use the same [database connection] or the
-** same [prepared statement] in different threads at the same time.
-** See the [threading mode] documentation for additional information.</dd>
-**
-** <dt>SQLITE_CONFIG_MALLOC</dt>
-** <dd>This option takes a single argument which is a pointer to an
-** instance of the [sqlite3_mem_methods] structure. The argument specifies
-** alternative low-level memory allocation routines to be used in place of
-** the memory allocation routines built into SQLite.</dd>
-**
-** <dt>SQLITE_CONFIG_GETMALLOC</dt>
-** <dd>This option takes a single argument which is a pointer to an
-** instance of the [sqlite3_mem_methods] structure. The [sqlite3_mem_methods]
-** structure is filled with the currently defined memory allocation routines.
-** This option can be used to overload the default memory allocation
-** routines with a wrapper that simulations memory allocation failure or
-** tracks memory usage, for example.</dd>
-**
-** <dt>SQLITE_CONFIG_MEMSTATUS</dt>
-** <dd>This option takes single argument of type int, interpreted as a
-** boolean, which enables or disables the collection of memory allocation
-** statistics. When disabled, the following SQLite interfaces become
-** non-operational:
-** <ul>
-** <li> [sqlite3_memory_used()]
-** <li> [sqlite3_memory_highwater()]
-** <li> [sqlite3_soft_heap_limit()]
-** <li> [sqlite3_status()]
-** </ul>
-** </dd>
-**
-** <dt>SQLITE_CONFIG_SCRATCH</dt>
-** <dd>This option specifies a static memory buffer that SQLite can use for
-** scratch memory. There are three arguments: A pointer an 8-byte
-** aligned memory buffer from which the scrach allocations will be
-** drawn, the size of each scratch allocation (sz),
-** and the maximum number of scratch allocations (N). The sz
-** argument must be a multiple of 16. The sz parameter should be a few bytes
-** larger than the actual scratch space required due to internal overhead.
-** The first argument should pointer to an 8-byte aligned buffer
-** of at least sz*N bytes of memory.
-** SQLite will use no more than one scratch buffer at once per thread, so
-** N should be set to the expected maximum number of threads. The sz
-** parameter should be 6 times the size of the largest database page size.
-** Scratch buffers are used as part of the btree balance operation. If
-** The btree balancer needs additional memory beyond what is provided by
-** scratch buffers or if no scratch buffer space is specified, then SQLite
-** goes to [sqlite3_malloc()] to obtain the memory it needs.</dd>
-**
-** <dt>SQLITE_CONFIG_PAGECACHE</dt>
-** <dd>This option specifies a static memory buffer that SQLite can use for
-** the database page cache with the default page cache implemenation.
-** This configuration should not be used if an application-define page
-** cache implementation is loaded using the SQLITE_CONFIG_PCACHE 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
-** (a power of two between 512 and 32768) plus a little extra for each
-** page header. The page header size is 20 to 40 bytes depending on
-** the host architecture. It is harmless, apart from the wasted memory,
-** to make sz a little too large. The first
-** argument should point to an allocation of at least sz*N bytes of memory.
-** SQLite will use the memory provided by the first argument to satisfy its
-** memory needs for the first N pages that it adds to cache. If additional
-** page cache memory is needed beyond what is provided by this option, then
-** SQLite goes to [sqlite3_malloc()] for the additional storage space.
-** The implementation might use one or more of the N buffers to hold
-** memory accounting information. The pointer in the first argument must
-** be aligned to an 8-byte boundary or subsequent behavior of SQLite
-** will be undefined.</dd>
-**
-** <dt>SQLITE_CONFIG_HEAP</dt>
-** <dd>This option specifies a static memory buffer that SQLite will use
-** for all of its dynamic memory allocation needs beyond those provided
-** for by [SQLITE_CONFIG_SCRATCH] and [SQLITE_CONFIG_PAGECACHE].
-** There are three arguments: An 8-byte aligned pointer to the memory,
-** the number of bytes in the memory buffer, and the minimum allocation size.
-** If the first pointer (the memory pointer) is NULL, then SQLite reverts
-** to using its default memory allocator (the system malloc() implementation),
-** undoing any prior invocation of [SQLITE_CONFIG_MALLOC]. If the
-** memory pointer is not NULL and either [SQLITE_ENABLE_MEMSYS3] or
-** [SQLITE_ENABLE_MEMSYS5] are defined, then the alternative memory
-** allocator is engaged to handle all of SQLites memory allocation needs.
-** The first pointer (the memory pointer) must be aligned to an 8-byte
-** boundary or subsequent behavior of SQLite will be undefined.</dd>
-**
-** <dt>SQLITE_CONFIG_MUTEX</dt>
-** <dd>This option takes a single argument which is a pointer to an
-** instance of the [sqlite3_mutex_methods] structure. The argument specifies
-** alternative low-level mutex routines to be used in place
-** the mutex routines built into SQLite.</dd>
-**
-** <dt>SQLITE_CONFIG_GETMUTEX</dt>
-** <dd>This option takes a single argument which is a pointer to an
-** instance of the [sqlite3_mutex_methods] structure. The
-** [sqlite3_mutex_methods]
-** structure is filled with the currently defined mutex routines.
-** This option can be used to overload the default mutex allocation
-** routines with a wrapper used to track mutex usage for performance
-** profiling or testing, for example.</dd>
-**
-** <dt>SQLITE_CONFIG_LOOKASIDE</dt>
-** <dd>This option takes two arguments that determine the default
-** memory allocation lookaside optimization. The first argument is the
-** size of each lookaside buffer slot and the second is the number of
-** slots allocated to each database connection. This option sets the
-** <i>default</i> lookaside size. The [SQLITE_DBCONFIG_LOOKASIDE]
-** verb to [sqlite3_db_config()] can be used to change the lookaside
-** configuration on individual connections.</dd>
-**
-** <dt>SQLITE_CONFIG_PCACHE</dt>
-** <dd>This option takes a single argument which is a pointer to
-** an [sqlite3_pcache_methods] 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.</dd>
-**
-** <dt>SQLITE_CONFIG_GETPCACHE</dt>
-** <dd>This option takes a single argument which is a pointer to an
-** [sqlite3_pcache_methods] object. SQLite copies of the current
-** page cache implementation into that object.</dd>
-**
-** </dl>
-*/
-#define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */
-#define SQLITE_CONFIG_MULTITHREAD 2 /* nil */
-#define SQLITE_CONFIG_SERIALIZED 3 /* nil */
-#define SQLITE_CONFIG_MALLOC 4 /* sqlite3_mem_methods* */
-#define SQLITE_CONFIG_GETMALLOC 5 /* sqlite3_mem_methods* */
-#define SQLITE_CONFIG_SCRATCH 6 /* void*, int sz, int N */
-#define SQLITE_CONFIG_PAGECACHE 7 /* void*, int sz, int N */
-#define SQLITE_CONFIG_HEAP 8 /* void*, int nByte, int min */
-#define SQLITE_CONFIG_MEMSTATUS 9 /* boolean */
-#define SQLITE_CONFIG_MUTEX 10 /* sqlite3_mutex_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* */
-
-/*
-** CAPI3REF: Configuration Options {H10170} <S20000>
-** EXPERIMENTAL
-**
-** These constants are the available integer configuration options that
-** can be passed as the second argument to the [sqlite3_db_config()] interface.
-**
-** New configuration options may be added in future releases of SQLite.
-** Existing configuration options might be discontinued. Applications
-** should check the return code from [sqlite3_db_config()] to make sure that
-** the call worked. The [sqlite3_db_config()] interface will return a
-** non-zero [error code] if a discontinued or unsupported configuration option
-** is invoked.
-**
-** <dl>
-** <dt>SQLITE_DBCONFIG_LOOKASIDE</dt>
-** <dd>This option takes three additional arguments that determine the
-** [lookaside memory allocator] configuration for the [database connection].
-** The first argument (the third parameter to [sqlite3_db_config()] is a
-** pointer to an memory buffer to use for lookaside memory.
-** The first argument may be NULL in which case SQLite will allocate the
-** lookaside buffer itself using [sqlite3_malloc()]. The second argument is the
-** size of each lookaside buffer slot and the third argument is the number of
-** slots. The size of the buffer in the first argument must be greater than
-** or equal to the product of the second and third arguments. The buffer
-** must be aligned to an 8-byte boundary. If the second argument is not
-** a multiple of 8, it is internally rounded down to the next smaller
-** multiple of 8. See also: [SQLITE_CONFIG_LOOKASIDE]</dd>
-**
-** </dl>
-*/
-#define SQLITE_DBCONFIG_LOOKASIDE 1001 /* void* int int */
-
-
-/*
-** CAPI3REF: Enable Or Disable Extended Result Codes {H12200} <S10700>
-**
-** The sqlite3_extended_result_codes() routine enables or disables the
-** [extended result codes] feature of SQLite. The extended result
-** codes are disabled by default for historical compatibility considerations.
-**
-** Requirements:
-** [H12201] [H12202]
-*/
-SQLITE_API int sqlite3_extended_result_codes(sqlite3*, int onoff);
-
-/*
-** CAPI3REF: Last Insert Rowid {H12220} <S10700>
-**
-** Each entry in an SQLite table has a unique 64-bit signed
-** integer key called the [ROWID | "rowid"]. The rowid is always available
-** as an undeclared column named ROWID, OID, or _ROWID_ as long as those
-** names are not also used by explicitly declared columns. If
-** the table has a column of type [INTEGER PRIMARY KEY] then that column
-** is another alias for the rowid.
-**
-** This routine returns the [rowid] of the most recent
-** successful [INSERT] into the database from the [database connection]
-** in the first argument. If no successful [INSERT]s
-** have ever occurred on that database connection, zero is returned.
-**
-** If an [INSERT] occurs within a trigger, then the [rowid] of the inserted
-** row is returned by this routine as long as the trigger is running.
-** But once the trigger terminates, the value returned by this routine
-** reverts to the last value inserted before the trigger fired.
-**
-** An [INSERT] that fails due to a constraint violation is not a
-** successful [INSERT] and does not change the value returned by this
-** routine. Thus INSERT OR FAIL, INSERT OR IGNORE, INSERT OR ROLLBACK,
-** and INSERT OR ABORT make no changes to the return value of this
-** routine when their insertion fails. When INSERT OR REPLACE
-** encounters a constraint violation, it does not fail. The
-** INSERT continues to completion after deleting rows that caused
-** the constraint problem so INSERT OR REPLACE will always change
-** the return value of this interface.
-**
-** For the purposes of this routine, an [INSERT] is considered to
-** be successful even if it is subsequently rolled back.
-**
-** Requirements:
-** [H12221] [H12223]
-**
-** If a separate thread performs a new [INSERT] on the same
-** database connection while the [sqlite3_last_insert_rowid()]
-** function is running and thus changes the last insert [rowid],
-** then the value returned by [sqlite3_last_insert_rowid()] is
-** unpredictable and might not equal either the old or the new
-** last insert [rowid].
-*/
-SQLITE_API sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*);
-
-/*
-** CAPI3REF: Count The Number Of Rows Modified {H12240} <S10600>
-**
-** This function returns the number of database rows that were changed
-** or inserted or deleted by the most recently completed SQL statement
-** on the [database connection] specified by the first parameter.
-** Only changes that are directly specified by the [INSERT], [UPDATE],
-** or [DELETE] statement are counted. Auxiliary changes caused by
-** triggers are not counted. Use the [sqlite3_total_changes()] function
-** to find the total number of changes including changes caused by triggers.
-**
-** Changes to a view that are simulated by an [INSTEAD OF trigger]
-** are not counted. Only real table changes are counted.
-**
-** A "row change" is a change to a single row of a single table
-** caused by an INSERT, DELETE, or UPDATE statement. Rows that
-** are changed as side effects of [REPLACE] constraint resolution,
-** rollback, ABORT processing, [DROP TABLE], or by any other
-** mechanisms do not count as direct row changes.
-**
-** A "trigger context" is a scope of execution that begins and
-** ends with the script of a [CREATE TRIGGER | trigger].
-** Most SQL statements are
-** evaluated outside of any trigger. This is the "top level"
-** trigger context. If a trigger fires from the top level, a
-** new trigger context is entered for the duration of that one
-** trigger. Subtriggers create subcontexts for their duration.
-**
-** Calling [sqlite3_exec()] or [sqlite3_step()] recursively does
-** not create a new trigger context.
-**
-** This function returns the number of direct row changes in the
-** most recent INSERT, UPDATE, or DELETE statement within the same
-** trigger context.
-**
-** Thus, when called from the top level, this function returns the
-** number of changes in the most recent INSERT, UPDATE, or DELETE
-** that also occurred at the top level. Within the body of a trigger,
-** the sqlite3_changes() interface can be called to find the number of
-** changes in the most recently completed INSERT, UPDATE, or DELETE
-** statement within the body of the same trigger.
-** However, the number returned does not include changes
-** caused by subtriggers since those have their own context.
-**
-** See also the [sqlite3_total_changes()] interface and the
-** [count_changes pragma].
-**
-** Requirements:
-** [H12241] [H12243]
-**
-** If a separate thread makes changes on the same database connection
-** while [sqlite3_changes()] is running then the value returned
-** is unpredictable and not meaningful.
-*/
-SQLITE_API int sqlite3_changes(sqlite3*);
-
-/*
-** CAPI3REF: Total Number Of Rows Modified {H12260} <S10600>
-**
-** This function returns the number of row changes caused by [INSERT],
-** [UPDATE] or [DELETE] statements since the [database connection] was opened.
-** The count includes all changes from all
-** [CREATE TRIGGER | trigger] contexts. However,
-** the count does not include changes used to implement [REPLACE] constraints,
-** do rollbacks or ABORT processing, or [DROP TABLE] processing. The
-** count does not include rows of views that fire an [INSTEAD OF trigger],
-** though if the INSTEAD OF trigger makes changes of its own, those changes
-** are counted.
-** The changes are counted as soon as the statement that makes them is
-** completed (when the statement handle is passed to [sqlite3_reset()] or
-** [sqlite3_finalize()]).
-**
-** See also the [sqlite3_changes()] interface and the
-** [count_changes pragma].
-**
-** Requirements:
-** [H12261] [H12263]
-**
-** If a separate thread makes changes on the same database connection
-** while [sqlite3_total_changes()] is running then the value
-** returned is unpredictable and not meaningful.
-*/
-SQLITE_API int sqlite3_total_changes(sqlite3*);
-
-/*
-** CAPI3REF: Interrupt A Long-Running Query {H12270} <S30500>
-**
-** This function causes any pending database operation to abort and
-** return at its earliest opportunity. This routine is typically
-** called in response to a user action such as pressing "Cancel"
-** or Ctrl-C where the user wants a long query operation to halt
-** immediately.
-**
-** It is safe to call this routine from a thread different from the
-** thread that is currently running the database operation. But it
-** is not safe to call this routine with a [database connection] that
-** is closed or might close before sqlite3_interrupt() returns.
-**
-** If an SQL operation is very nearly finished at the time when
-** sqlite3_interrupt() is called, then it might not have an opportunity
-** to be interrupted and might continue to completion.
-**
-** An SQL operation that is interrupted will return [SQLITE_INTERRUPT].
-** If the interrupted SQL operation is an INSERT, UPDATE, or DELETE
-** that is inside an explicit transaction, then the entire transaction
-** will be rolled back automatically.
-**
-** The sqlite3_interrupt(D) call is in effect until all currently running
-** SQL statements on [database connection] D complete. Any new SQL statements
-** that are started after the sqlite3_interrupt() call and before the
-** running statements reaches zero are interrupted as if they had been
-** running prior to the sqlite3_interrupt() call. New SQL statements
-** that are started after the running statement count reaches zero are
-** not effected by the sqlite3_interrupt().
-** A call to sqlite3_interrupt(D) that occurs when there are no running
-** SQL statements is a no-op and has no effect on SQL statements
-** that are started after the sqlite3_interrupt() call returns.
-**
-** Requirements:
-** [H12271] [H12272]
-**
-** If the database connection closes while [sqlite3_interrupt()]
-** is running then bad things will likely happen.
-*/
-SQLITE_API void sqlite3_interrupt(sqlite3*);
-
-/*
-** CAPI3REF: Determine If An SQL Statement Is Complete {H10510} <S70200>
-**
-** These routines are useful during command-line input to determine if the
-** currently entered text seems to form a complete SQL statement or
-** if additional input is needed before sending the text into
-** SQLite for parsing. These routines return 1 if the input string
-** appears to be a complete SQL statement. A statement is judged to be
-** complete if it ends with a semicolon token and is not a prefix of a
-** well-formed CREATE TRIGGER statement. Semicolons that are embedded within
-** string literals or quoted identifier names or comments are not
-** independent tokens (they are part of the token in which they are
-** embedded) and thus do not count as a statement terminator. Whitespace
-** and comments that follow the final semicolon are ignored.
-**
-** These routines return 0 if the statement is incomplete. If a
-** memory allocation fails, then SQLITE_NOMEM is returned.
-**
-** These routines do not parse the SQL statements thus
-** will not detect syntactically incorrect SQL.
-**
-** If SQLite has not been initialized using [sqlite3_initialize()] prior
-** to invoking sqlite3_complete16() then sqlite3_initialize() is invoked
-** automatically by sqlite3_complete16(). If that initialization fails,
-** then the return value from sqlite3_complete16() will be non-zero
-** regardless of whether or not the input SQL is complete.
-**
-** Requirements: [H10511] [H10512]
-**
-** The input to [sqlite3_complete()] must be a zero-terminated
-** UTF-8 string.
-**
-** The input to [sqlite3_complete16()] must be a zero-terminated
-** UTF-16 string in native byte order.
-*/
-SQLITE_API int sqlite3_complete(const char *sql);
-SQLITE_API int sqlite3_complete16(const void *sql);
-
-/*
-** CAPI3REF: Register A Callback To Handle SQLITE_BUSY Errors {H12310} <S40400>
-**
-** This routine sets a callback function that might be invoked whenever
-** an attempt is made to open a database table that another thread
-** or process has locked.
-**
-** If the busy callback is NULL, then [SQLITE_BUSY] or [SQLITE_IOERR_BLOCKED]
-** is returned immediately upon encountering the lock. If the busy callback
-** is not NULL, then the callback will be invoked with two arguments.
-**
-** The first argument to the handler is a copy of the void* pointer which
-** is the third argument to sqlite3_busy_handler(). The second argument to
-** the handler callback is the number of times that the busy handler has
-** been invoked for this locking event. If the
-** busy callback returns 0, then no additional attempts are made to
-** access the database and [SQLITE_BUSY] or [SQLITE_IOERR_BLOCKED] is returned.
-** If the callback returns non-zero, then another attempt
-** is made to open the database for reading and the cycle repeats.
-**
-** The presence of a busy handler does not guarantee that it will be invoked
-** when there is lock contention. If SQLite determines that invoking the busy
-** handler could result in a deadlock, it will go ahead and return [SQLITE_BUSY]
-** or [SQLITE_IOERR_BLOCKED] instead of invoking the busy handler.
-** Consider a scenario where one process is holding a read lock that
-** it is trying to promote to a reserved lock and
-** a second process is holding a reserved lock that it is trying
-** to promote to an exclusive lock. The first process cannot proceed
-** because it is blocked by the second and the second process cannot
-** proceed because it is blocked by the first. If both processes
-** invoke the busy handlers, neither will make any progress. Therefore,
-** SQLite returns [SQLITE_BUSY] for the first process, hoping that this
-** will induce the first process to release its read lock and allow
-** the second process to proceed.
-**
-** The default busy callback is NULL.
-**
-** The [SQLITE_BUSY] error is converted to [SQLITE_IOERR_BLOCKED]
-** when SQLite is in the middle of a large transaction where all the
-** changes will not fit into the in-memory cache. SQLite will
-** already hold a RESERVED lock on the database file, but it needs
-** to promote this lock to EXCLUSIVE so that it can spill cache
-** pages into the database file without harm to concurrent
-** readers. If it is unable to promote the lock, then the in-memory
-** cache will be left in an inconsistent state and so the error
-** code is promoted from the relatively benign [SQLITE_BUSY] to
-** the more severe [SQLITE_IOERR_BLOCKED]. This error code promotion
-** forces an automatic rollback of the changes. See the
-** <a href="/cvstrac/wiki?p=CorruptionFollowingBusyError">
-** CorruptionFollowingBusyError</a> wiki page for a discussion of why
-** this is important.
-**
-** There can only be a single busy handler defined for each
-** [database connection]. Setting a new busy handler clears any
-** previously set handler. Note that calling [sqlite3_busy_timeout()]
-** will also set or clear the busy handler.
-**
-** The busy callback should not take any actions which modify the
-** database connection that invoked the busy handler. Any such actions
-** result in undefined behavior.
-**
-** Requirements:
-** [H12311] [H12312] [H12314] [H12316] [H12318]
-**
-** A busy handler must not close the database connection
-** or [prepared statement] that invoked the busy handler.
-*/
-SQLITE_API int sqlite3_busy_handler(sqlite3*, int(*)(void*,int), void*);
-
-/*
-** CAPI3REF: Set A Busy Timeout {H12340} <S40410>
-**
-** This routine sets a [sqlite3_busy_handler | busy handler] that sleeps
-** for a specified amount of time when a table is locked. The handler
-** will sleep multiple times until at least "ms" milliseconds of sleeping
-** have accumulated. {H12343} After "ms" milliseconds of sleeping,
-** the handler returns 0 which causes [sqlite3_step()] to return
-** [SQLITE_BUSY] or [SQLITE_IOERR_BLOCKED].
-**
-** Calling this routine with an argument less than or equal to zero
-** turns off all busy handlers.
-**
-** There can only be a single busy handler for a particular
-** [database connection] any any given moment. If another busy handler
-** was defined (using [sqlite3_busy_handler()]) prior to calling
-** this routine, that other busy handler is cleared.
-**
-** Requirements:
-** [H12341] [H12343] [H12344]
-*/
-SQLITE_API int sqlite3_busy_timeout(sqlite3*, int ms);
-
-/*
-** CAPI3REF: Convenience Routines For Running Queries {H12370} <S10000>
-**
-** Definition: A <b>result table</b> is memory data structure created by the
-** [sqlite3_get_table()] interface. A result table records the
-** complete query results from one or more queries.
-**
-** The table conceptually has a number of rows and columns. But
-** these numbers are not part of the result table itself. These
-** numbers are obtained separately. Let N be the number of rows
-** and M be the number of columns.
-**
-** A result table is an array of pointers to zero-terminated UTF-8 strings.
-** There are (N+1)*M elements in the array. The first M pointers point
-** to zero-terminated strings that contain the names of the columns.
-** The remaining entries all point to query results. NULL values result
-** in NULL pointers. All other values are in their UTF-8 zero-terminated
-** string representation as returned by [sqlite3_column_text()].
-**
-** A result table might consist of one or more memory allocations.
-** It is not safe to pass a result table directly to [sqlite3_free()].
-** A result table should be deallocated using [sqlite3_free_table()].
-**
-** As an example of the result table format, suppose a query result
-** is as follows:
-**
-** <blockquote><pre>
-** Name | Age
-** -----------------------
-** Alice | 43
-** Bob | 28
-** Cindy | 21
-** </pre></blockquote>
-**
-** There are two column (M==2) and three rows (N==3). Thus the
-** result table has 8 entries. Suppose the result table is stored
-** in an array names azResult. Then azResult holds this content:
-**
-** <blockquote><pre>
-** azResult&#91;0] = "Name";
-** azResult&#91;1] = "Age";
-** azResult&#91;2] = "Alice";
-** azResult&#91;3] = "43";
-** azResult&#91;4] = "Bob";
-** azResult&#91;5] = "28";
-** azResult&#91;6] = "Cindy";
-** azResult&#91;7] = "21";
-** </pre></blockquote>
-**
-** The sqlite3_get_table() function evaluates one or more
-** semicolon-separated SQL statements in the zero-terminated UTF-8
-** string of its 2nd parameter. It returns a result table to the
-** pointer given in its 3rd parameter.
-**
-** After the calling function has finished using the result, it should
-** pass the pointer to the result table to sqlite3_free_table() in order to
-** release the memory that was malloced. Because of the way the
-** [sqlite3_malloc()] happens within sqlite3_get_table(), the calling
-** function must not try to call [sqlite3_free()] directly. Only
-** [sqlite3_free_table()] is able to release the memory properly and safely.
-**
-** The sqlite3_get_table() interface is implemented as a wrapper around
-** [sqlite3_exec()]. The sqlite3_get_table() routine does not have access
-** to any internal data structures of SQLite. It uses only the public
-** interface defined here. As a consequence, errors that occur in the
-** wrapper layer outside of the internal [sqlite3_exec()] call are not
-** reflected in subsequent calls to [sqlite3_errcode()] or [sqlite3_errmsg()].
-**
-** Requirements:
-** [H12371] [H12373] [H12374] [H12376] [H12379] [H12382]
-*/
-SQLITE_API int sqlite3_get_table(
- sqlite3 *db, /* An open database */
- const char *zSql, /* SQL to be evaluated */
- char ***pazResult, /* Results of the query */
- int *pnRow, /* Number of result rows written here */
- int *pnColumn, /* Number of result columns written here */
- char **pzErrmsg /* Error msg written here */
-);
-SQLITE_API void sqlite3_free_table(char **result);
-
-/*
-** CAPI3REF: Formatted String Printing Functions {H17400} <S70000><S20000>
-**
-** These routines are work-alikes of the "printf()" family of functions
-** from the standard C library.
-**
-** The sqlite3_mprintf() and sqlite3_vmprintf() routines write their
-** results into memory obtained from [sqlite3_malloc()].
-** The strings returned by these two routines should be
-** released by [sqlite3_free()]. Both routines return a
-** NULL pointer if [sqlite3_malloc()] is unable to allocate enough
-** memory to hold the resulting string.
-**
-** In sqlite3_snprintf() routine is similar to "snprintf()" from
-** the standard C library. The result is written into the
-** buffer supplied as the second parameter whose size is given by
-** the first parameter. Note that the order of the
-** first two parameters is reversed from snprintf(). This is an
-** historical accident that cannot be fixed without breaking
-** backwards compatibility. Note also that sqlite3_snprintf()
-** returns a pointer to its buffer instead of the number of
-** characters actually written into the buffer. We admit that
-** the number of characters written would be a more useful return
-** value but we cannot change the implementation of sqlite3_snprintf()
-** now without breaking compatibility.
-**
-** As long as the buffer size is greater than zero, sqlite3_snprintf()
-** guarantees that the buffer is always zero-terminated. The first
-** parameter "n" is the total size of the buffer, including space for
-** the zero terminator. So the longest string that can be completely
-** written will be n-1 characters.
-**
-** These routines all implement some additional formatting
-** options that are useful for constructing SQL statements.
-** 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
-** 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
-** the string.
-**
-** For example, assume the string variable zText contains text as follows:
-**
-** <blockquote><pre>
-** char *zText = "It's a happy day!";
-** </pre></blockquote>
-**
-** One can use this text in an SQL statement as follows:
-**
-** <blockquote><pre>
-** char *zSQL = sqlite3_mprintf("INSERT INTO table VALUES('%q')", zText);
-** sqlite3_exec(db, zSQL, 0, 0, 0);
-** sqlite3_free(zSQL);
-** </pre></blockquote>
-**
-** Because the %q format string is used, the '\'' character in zText
-** is escaped and the SQL generated is as follows:
-**
-** <blockquote><pre>
-** INSERT INTO table1 VALUES('It''s a happy day!')
-** </pre></blockquote>
-**
-** This is correct. Had we used %s instead of %q, the generated SQL
-** would have looked like this:
-**
-** <blockquote><pre>
-** INSERT INTO table1 VALUES('It's a happy day!');
-** </pre></blockquote>
-**
-** This second example is an SQL syntax error. As a general rule you should
-** always use %q instead of %s when inserting text into a string literal.
-**
-** The %Q option works like %q except it also adds single quotes around
-** the outside of the total string. Additionally, if the parameter in the
-** argument list is a NULL pointer, %Q substitutes the text "NULL" (without
-** single quotes) in place of the %Q option. So, for example, one could say:
-**
-** <blockquote><pre>
-** char *zSQL = sqlite3_mprintf("INSERT INTO table VALUES(%Q)", zText);
-** sqlite3_exec(db, zSQL, 0, 0, 0);
-** sqlite3_free(zSQL);
-** </pre></blockquote>
-**
-** The code above will render a correct SQL statement in the zSQL
-** variable even if the zText variable is a NULL pointer.
-**
-** The "%z" formatting option works exactly like "%s" with the
-** addition that after the string has been read and copied into
-** the result, [sqlite3_free()] is called on the input string. {END}
-**
-** Requirements:
-** [H17403] [H17406] [H17407]
-*/
-SQLITE_API char *sqlite3_mprintf(const char*,...);
-SQLITE_API char *sqlite3_vmprintf(const char*, va_list);
-SQLITE_API char *sqlite3_snprintf(int,char*,const char*, ...);
-
-/*
-** CAPI3REF: Memory Allocation Subsystem {H17300} <S20000>
-**
-** The SQLite core uses these three routines for all of its own
-** internal memory allocation needs. "Core" in the previous sentence
-** does not include operating-system specific VFS implementation. The
-** Windows VFS uses native malloc() and free() for some operations.
-**
-** The sqlite3_malloc() routine returns a pointer to a block
-** of memory at least N bytes in length, where N is the parameter.
-** If sqlite3_malloc() is unable to obtain sufficient free
-** memory, it returns a NULL pointer. If the parameter N to
-** sqlite3_malloc() is zero or negative then sqlite3_malloc() returns
-** a NULL pointer.
-**
-** Calling sqlite3_free() with a pointer previously returned
-** by sqlite3_malloc() or sqlite3_realloc() releases that memory so
-** that it might be reused. The sqlite3_free() routine is
-** a no-op if is called with a NULL pointer. Passing a NULL pointer
-** to sqlite3_free() is harmless. After being freed, memory
-** should neither be read nor written. Even reading previously freed
-** memory might result in a segmentation fault or other severe error.
-** Memory corruption, a segmentation fault, or other severe error
-** might result if sqlite3_free() is called with a non-NULL pointer that
-** was not obtained from sqlite3_malloc() or sqlite3_realloc().
-**
-** The sqlite3_realloc() interface attempts to resize a
-** prior memory allocation to be at least N bytes, where N is the
-** second parameter. The memory allocation to be resized is the first
-** parameter. If the first parameter to sqlite3_realloc()
-** is a NULL pointer then its behavior is identical to calling
-** sqlite3_malloc(N) where N is the second parameter to sqlite3_realloc().
-** If the second parameter to sqlite3_realloc() is zero or
-** negative then the behavior is exactly the same as calling
-** sqlite3_free(P) where P is the first parameter to sqlite3_realloc().
-** sqlite3_realloc() returns a pointer to a memory allocation
-** of at least N bytes in size or NULL if sufficient memory is unavailable.
-** If M is the size of the prior allocation, then min(N,M) bytes
-** of the prior allocation are copied into the beginning of buffer returned
-** by sqlite3_realloc() and the prior allocation is freed.
-** If sqlite3_realloc() returns NULL, then the prior allocation
-** is not freed.
-**
-** The memory returned by sqlite3_malloc() and sqlite3_realloc()
-** is always aligned to at least an 8 byte boundary. {END}
-**
-** The default implementation of the memory allocation subsystem uses
-** the malloc(), realloc() and free() provided by the standard C library.
-** {H17382} However, if SQLite is compiled with the
-** SQLITE_MEMORY_SIZE=<i>NNN</i> C preprocessor macro (where <i>NNN</i>
-** is an integer), then SQLite create a static array of at least
-** <i>NNN</i> bytes in size and uses that array for all of its dynamic
-** memory allocation needs. {END} Additional memory allocator options
-** may be added in future releases.
-**
-** In SQLite version 3.5.0 and 3.5.1, it was possible to define
-** the SQLITE_OMIT_MEMORY_ALLOCATION which would cause the built-in
-** implementation of these routines to be omitted. That capability
-** is no longer provided. Only built-in memory allocators can be used.
-**
-** The Windows OS interface layer calls
-** the system malloc() and free() directly when converting
-** filenames between the UTF-8 encoding used by SQLite
-** and whatever filename encoding is used by the particular Windows
-** installation. Memory allocation errors are detected, but
-** they are reported back as [SQLITE_CANTOPEN] or
-** [SQLITE_IOERR] rather than [SQLITE_NOMEM].
-**
-** Requirements:
-** [H17303] [H17304] [H17305] [H17306] [H17310] [H17312] [H17315] [H17318]
-** [H17321] [H17322] [H17323]
-**
-** The pointer arguments to [sqlite3_free()] and [sqlite3_realloc()]
-** must be either NULL or else pointers obtained from a prior
-** invocation of [sqlite3_malloc()] or [sqlite3_realloc()] that have
-** not yet been released.
-**
-** The application must not read or write any part of
-** a block of memory after it has been released using
-** [sqlite3_free()] or [sqlite3_realloc()].
-*/
-SQLITE_API void *sqlite3_malloc(int);
-SQLITE_API void *sqlite3_realloc(void*, int);
-SQLITE_API void sqlite3_free(void*);
-
-/*
-** CAPI3REF: Memory Allocator Statistics {H17370} <S30210>
-**
-** SQLite provides these two interfaces for reporting on the status
-** of the [sqlite3_malloc()], [sqlite3_free()], and [sqlite3_realloc()]
-** routines, which form the built-in memory allocation subsystem.
-**
-** Requirements:
-** [H17371] [H17373] [H17374] [H17375]
-*/
-SQLITE_API sqlite3_int64 sqlite3_memory_used(void);
-SQLITE_API sqlite3_int64 sqlite3_memory_highwater(int resetFlag);
-
-/*
-** CAPI3REF: Pseudo-Random Number Generator {H17390} <S20000>
-**
-** SQLite contains a high-quality pseudo-random number generator (PRNG) used to
-** select random [ROWID | ROWIDs] when inserting new records into a table that
-** already uses the largest possible [ROWID]. The PRNG is also used for
-** the build-in random() and randomblob() SQL functions. This interface allows
-** applications to access the same PRNG for other purposes.
-**
-** A call to this routine stores N bytes of randomness into buffer P.
-**
-** The first time this routine is invoked (either internally or by
-** the application) the PRNG is seeded using randomness obtained
-** from the xRandomness method of the default [sqlite3_vfs] object.
-** On all subsequent invocations, the pseudo-randomness is generated
-** internally and without recourse to the [sqlite3_vfs] xRandomness
-** method.
-**
-** Requirements:
-** [H17392]
-*/
-SQLITE_API void sqlite3_randomness(int N, void *P);
-
-/*
-** CAPI3REF: Compile-Time Authorization Callbacks {H12500} <S70100>
-**
-** This routine registers a authorizer callback with a particular
-** [database connection], supplied in the first argument.
-** The authorizer callback is invoked as SQL statements are being compiled
-** by [sqlite3_prepare()] or its variants [sqlite3_prepare_v2()],
-** [sqlite3_prepare16()] and [sqlite3_prepare16_v2()]. At various
-** points during the compilation process, as logic is being created
-** to perform various actions, the authorizer callback is invoked to
-** see if those actions are allowed. The authorizer callback should
-** return [SQLITE_OK] to allow the action, [SQLITE_IGNORE] to disallow the
-** specific action but allow the SQL statement to continue to be
-** compiled, or [SQLITE_DENY] to cause the entire SQL statement to be
-** rejected with an error. If the authorizer callback returns
-** any value other than [SQLITE_IGNORE], [SQLITE_OK], or [SQLITE_DENY]
-** then the [sqlite3_prepare_v2()] or equivalent call that triggered
-** the authorizer will fail with an error message.
-**
-** When the callback returns [SQLITE_OK], that means the operation
-** requested is ok. When the callback returns [SQLITE_DENY], the
-** [sqlite3_prepare_v2()] or equivalent call that triggered the
-** authorizer will fail with an error message explaining that
-** access is denied.
-**
-** The first parameter to the authorizer callback is a copy of the third
-** parameter to the sqlite3_set_authorizer() interface. The second parameter
-** to the callback is an integer [SQLITE_COPY | action code] that specifies
-** the particular action to be authorized. The third through sixth parameters
-** to the callback are zero-terminated strings that contain additional
-** details about the action to be authorized.
-**
-** If the action code is [SQLITE_READ]
-** and the callback returns [SQLITE_IGNORE] then the
-** [prepared statement] statement is constructed to substitute
-** a NULL value in place of the table column that would have
-** been read if [SQLITE_OK] had been returned. The [SQLITE_IGNORE]
-** return can be used to deny an untrusted user access to individual
-** columns of a table.
-** If the action code is [SQLITE_DELETE] and the callback returns
-** [SQLITE_IGNORE] then the [DELETE] operation proceeds but the
-** [truncate optimization] is disabled and all rows are deleted individually.
-**
-** An authorizer is used when [sqlite3_prepare | preparing]
-** SQL statements from an untrusted source, to ensure that the SQL statements
-** do not try to access data they are not allowed to see, or that they do not
-** try to execute malicious statements that damage the database. For
-** example, an application may allow a user to enter arbitrary
-** SQL queries for evaluation by a database. But the application does
-** not want the user to be able to make arbitrary changes to the
-** database. An authorizer could then be put in place while the
-** user-entered SQL is being [sqlite3_prepare | prepared] that
-** disallows everything except [SELECT] statements.
-**
-** Applications that need to process SQL from untrusted sources
-** might also consider lowering resource limits using [sqlite3_limit()]
-** and limiting database size using the [max_page_count] [PRAGMA]
-** in addition to using an authorizer.
-**
-** Only a single authorizer can be in place on a database connection
-** at a time. Each call to sqlite3_set_authorizer overrides the
-** previous call. Disable the authorizer by installing a NULL callback.
-** The authorizer is disabled by default.
-**
-** The authorizer callback must not do anything that will modify
-** the database connection that invoked the authorizer callback.
-** Note that [sqlite3_prepare_v2()] and [sqlite3_step()] both modify their
-** database connections for the meaning of "modify" in this paragraph.
-**
-** When [sqlite3_prepare_v2()] is used to prepare a statement, the
-** statement might be re-prepared during [sqlite3_step()] due to a
-** schema change. Hence, the application should ensure that the
-** correct authorizer callback remains in place during the [sqlite3_step()].
-**
-** Note that the authorizer callback is invoked only during
-** [sqlite3_prepare()] or its variants. Authorization is not
-** performed during statement evaluation in [sqlite3_step()], unless
-** as stated in the previous paragraph, sqlite3_step() invokes
-** sqlite3_prepare_v2() to reprepare a statement after a schema change.
-**
-** Requirements:
-** [H12501] [H12502] [H12503] [H12504] [H12505] [H12506] [H12507] [H12510]
-** [H12511] [H12512] [H12520] [H12521] [H12522]
-*/
-SQLITE_API int sqlite3_set_authorizer(
- sqlite3*,
- int (*xAuth)(void*,int,const char*,const char*,const char*,const char*),
- void *pUserData
-);
-
-/*
-** CAPI3REF: Authorizer Return Codes {H12590} <H12500>
-**
-** The [sqlite3_set_authorizer | authorizer callback function] must
-** return either [SQLITE_OK] or one of these two constants in order
-** to signal SQLite whether or not the action is permitted. See the
-** [sqlite3_set_authorizer | authorizer documentation] for additional
-** information.
-*/
-#define SQLITE_DENY 1 /* Abort the SQL statement with an error */
-#define SQLITE_IGNORE 2 /* Don't allow access, but don't generate an error */
-
-/*
-** CAPI3REF: Authorizer Action Codes {H12550} <H12500>
-**
-** The [sqlite3_set_authorizer()] interface registers a callback function
-** that is invoked to authorize certain SQL statement actions. The
-** second parameter to the callback is an integer code that specifies
-** what action is being authorized. These are the integer action codes that
-** the authorizer callback may be passed.
-**
-** These action code values signify what kind of operation is to be
-** authorized. The 3rd and 4th parameters to the authorization
-** callback function will be parameters or NULL depending on which of these
-** codes is used as the second parameter. The 5th parameter to the
-** authorizer callback is the name of the database ("main", "temp",
-** etc.) if applicable. The 6th parameter to the authorizer callback
-** is the name of the inner-most trigger or view that is responsible for
-** the access attempt or NULL if this access attempt is directly from
-** top-level SQL code.
-**
-** Requirements:
-** [H12551] [H12552] [H12553] [H12554]
-*/
-/******************************************* 3rd ************ 4th ***********/
-#define SQLITE_CREATE_INDEX 1 /* Index Name Table Name */
-#define SQLITE_CREATE_TABLE 2 /* Table Name NULL */
-#define SQLITE_CREATE_TEMP_INDEX 3 /* Index Name Table Name */
-#define SQLITE_CREATE_TEMP_TABLE 4 /* Table Name NULL */
-#define SQLITE_CREATE_TEMP_TRIGGER 5 /* Trigger Name Table Name */
-#define SQLITE_CREATE_TEMP_VIEW 6 /* View Name NULL */
-#define SQLITE_CREATE_TRIGGER 7 /* Trigger Name Table Name */
-#define SQLITE_CREATE_VIEW 8 /* View Name NULL */
-#define SQLITE_DELETE 9 /* Table Name NULL */
-#define SQLITE_DROP_INDEX 10 /* Index Name Table Name */
-#define SQLITE_DROP_TABLE 11 /* Table Name NULL */
-#define SQLITE_DROP_TEMP_INDEX 12 /* Index Name Table Name */
-#define SQLITE_DROP_TEMP_TABLE 13 /* Table Name NULL */
-#define SQLITE_DROP_TEMP_TRIGGER 14 /* Trigger Name Table Name */
-#define SQLITE_DROP_TEMP_VIEW 15 /* View Name NULL */
-#define SQLITE_DROP_TRIGGER 16 /* Trigger Name Table Name */
-#define SQLITE_DROP_VIEW 17 /* View Name NULL */
-#define SQLITE_INSERT 18 /* Table Name NULL */
-#define SQLITE_PRAGMA 19 /* Pragma Name 1st arg or NULL */
-#define SQLITE_READ 20 /* Table Name Column Name */
-#define SQLITE_SELECT 21 /* NULL NULL */
-#define SQLITE_TRANSACTION 22 /* Operation NULL */
-#define SQLITE_UPDATE 23 /* Table Name Column Name */
-#define SQLITE_ATTACH 24 /* Filename NULL */
-#define SQLITE_DETACH 25 /* Database Name NULL */
-#define SQLITE_ALTER_TABLE 26 /* Database Name Table Name */
-#define SQLITE_REINDEX 27 /* Index Name NULL */
-#define SQLITE_ANALYZE 28 /* Table Name NULL */
-#define SQLITE_CREATE_VTABLE 29 /* Table Name Module Name */
-#define SQLITE_DROP_VTABLE 30 /* Table Name Module Name */
-#define SQLITE_FUNCTION 31 /* NULL Function Name */
-#define SQLITE_SAVEPOINT 32 /* Operation Savepoint Name */
-#define SQLITE_COPY 0 /* No longer used */
-
-/*
-** CAPI3REF: Tracing And Profiling Functions {H12280} <S60400>
-** EXPERIMENTAL
-**
-** These routines register callback functions that can be used for
-** tracing and profiling the execution of SQL statements.
-**
-** The callback function registered by sqlite3_trace() is invoked at
-** various times when an SQL statement is being run by [sqlite3_step()].
-** The callback returns a UTF-8 rendering of the SQL statement text
-** as the statement first begins executing. Additional callbacks occur
-** as each triggered subprogram is entered. The callbacks for triggers
-** contain a UTF-8 SQL comment that identifies the trigger.
-**
-** The callback function registered by sqlite3_profile() is invoked
-** as each SQL statement finishes. The profile callback contains
-** the original statement text and an estimate of wall-clock time
-** of how long that statement took to run.
-**
-** Requirements:
-** [H12281] [H12282] [H12283] [H12284] [H12285] [H12287] [H12288] [H12289]
-** [H12290]
-*/
-SQLITE_API SQLITE_EXPERIMENTAL void *sqlite3_trace(sqlite3*, void(*xTrace)(void*,const char*), void*);
-SQLITE_API SQLITE_EXPERIMENTAL void *sqlite3_profile(sqlite3*,
- void(*xProfile)(void*,const char*,sqlite3_uint64), void*);
-
-/*
-** CAPI3REF: Query Progress Callbacks {H12910} <S60400>
-**
-** This routine configures a callback function - the
-** progress callback - that is invoked periodically during long
-** running calls to [sqlite3_exec()], [sqlite3_step()] and
-** [sqlite3_get_table()]. An example use for this
-** interface is to keep a GUI updated during a large query.
-**
-** If the progress callback returns non-zero, the operation is
-** interrupted. This feature can be used to implement a
-** "Cancel" button on a GUI progress dialog box.
-**
-** The progress handler must not do anything that will modify
-** the database connection that invoked the progress handler.
-** Note that [sqlite3_prepare_v2()] and [sqlite3_step()] both modify their
-** database connections for the meaning of "modify" in this paragraph.
-**
-** Requirements:
-** [H12911] [H12912] [H12913] [H12914] [H12915] [H12916] [H12917] [H12918]
-**
-*/
-SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
-
-/*
-** CAPI3REF: Opening A New Database Connection {H12700} <S40200>
-**
-** These routines open an SQLite database file whose name is given by the
-** filename argument. The filename argument is interpreted as UTF-8 for
-** sqlite3_open() and sqlite3_open_v2() and as UTF-16 in the native byte
-** order for sqlite3_open16(). A [database connection] handle is usually
-** returned in *ppDb, even if an error occurs. The only exception is that
-** if SQLite is unable to allocate memory to hold the [sqlite3] object,
-** a NULL will be written into *ppDb instead of a pointer to the [sqlite3]
-** object. If the database is opened (and/or created) successfully, then
-** [SQLITE_OK] is returned. Otherwise an [error code] is returned. The
-** [sqlite3_errmsg()] or [sqlite3_errmsg16()] routines can be used to obtain
-** an English language description of the error.
-**
-** The default encoding for the database will be UTF-8 if
-** sqlite3_open() or sqlite3_open_v2() is called and
-** UTF-16 in the native byte order if sqlite3_open16() is used.
-**
-** Whether or not an error occurs when it is opened, resources
-** associated with the [database connection] handle should be released by
-** passing it to [sqlite3_close()] when it is no longer required.
-**
-** The sqlite3_open_v2() interface works like sqlite3_open()
-** except that it accepts two additional parameters for additional control
-** over the new database connection. The flags parameter can take one of
-** the following three values, optionally combined with the
-** [SQLITE_OPEN_NOMUTEX], [SQLITE_OPEN_FULLMUTEX], [SQLITE_OPEN_SHAREDCACHE],
-** and/or [SQLITE_OPEN_PRIVATECACHE] flags:
-**
-** <dl>
-** <dt>[SQLITE_OPEN_READONLY]</dt>
-** <dd>The database is opened in read-only mode. If the database does not
-** already exist, an error is returned.</dd>
-**
-** <dt>[SQLITE_OPEN_READWRITE]</dt>
-** <dd>The database is opened for reading and writing if possible, or reading
-** only if the file is write protected by the operating system. In either
-** case the database must already exist, otherwise an error is returned.</dd>
-**
-** <dt>[SQLITE_OPEN_READWRITE] | [SQLITE_OPEN_CREATE]</dt>
-** <dd>The database is opened for reading and writing, and is creates it if
-** it does not already exist. This is the behavior that is always used for
-** sqlite3_open() and sqlite3_open16().</dd>
-** </dl>
-**
-** If the 3rd parameter to sqlite3_open_v2() is not one of the
-** combinations shown above or one of the combinations shown above combined
-** with the [SQLITE_OPEN_NOMUTEX], [SQLITE_OPEN_FULLMUTEX],
-** [SQLITE_OPEN_SHAREDCACHE] and/or [SQLITE_OPEN_SHAREDCACHE] flags,
-** then the behavior is undefined.
-**
-** If the [SQLITE_OPEN_NOMUTEX] flag is set, then the database connection
-** opens in the multi-thread [threading mode] as long as the single-thread
-** mode has not been set at compile-time or start-time. If the
-** [SQLITE_OPEN_FULLMUTEX] flag is set then the database connection opens
-** in the serialized [threading mode] unless single-thread was
-** previously selected at compile-time or start-time.
-** The [SQLITE_OPEN_SHAREDCACHE] flag causes the database connection to be
-** eligible to use [shared cache mode], regardless of whether or not shared
-** cache is enabled using [sqlite3_enable_shared_cache()]. The
-** [SQLITE_OPEN_PRIVATECACHE] flag causes the database connection to not
-** participate in [shared cache mode] even if it is enabled.
-**
-** If the filename is ":memory:", then a private, temporary in-memory database
-** is created for the connection. This in-memory database will vanish when
-** the database connection is closed. Future versions of SQLite might
-** make use of additional special filenames that begin with the ":" character.
-** It is recommended that when a database filename actually does begin with
-** a ":" character you should prefix the filename with a pathname such as
-** "./" to avoid ambiguity.
-**
-** If the filename is an empty string, then a private, temporary
-** on-disk database will be created. This private database will be
-** automatically deleted as soon as the database connection is closed.
-**
-** The fourth parameter to sqlite3_open_v2() is the name of the
-** [sqlite3_vfs] object that defines the operating system interface that
-** the new database connection should use. If the fourth parameter is
-** a NULL pointer then the default [sqlite3_vfs] object is used.
-**
-** <b>Note to Windows users:</b> The encoding used for the filename argument
-** of sqlite3_open() and sqlite3_open_v2() must be UTF-8, not whatever
-** codepage is currently defined. Filenames containing international
-** characters must be converted to UTF-8 prior to passing them into
-** sqlite3_open() or sqlite3_open_v2().
-**
-** Requirements:
-** [H12701] [H12702] [H12703] [H12704] [H12706] [H12707] [H12709] [H12711]
-** [H12712] [H12713] [H12714] [H12717] [H12719] [H12721] [H12723]
-*/
-SQLITE_API int sqlite3_open(
- const char *filename, /* Database filename (UTF-8) */
- sqlite3 **ppDb /* OUT: SQLite db handle */
-);
-SQLITE_API int sqlite3_open16(
- const void *filename, /* Database filename (UTF-16) */
- sqlite3 **ppDb /* OUT: SQLite db handle */
-);
-SQLITE_API int sqlite3_open_v2(
- const char *filename, /* Database filename (UTF-8) */
- sqlite3 **ppDb, /* OUT: SQLite db handle */
- int flags, /* Flags */
- const char *zVfs /* Name of VFS module to use */
-);
-
-/*
-** CAPI3REF: Error Codes And Messages {H12800} <S60200>
-**
-** The sqlite3_errcode() interface returns the numeric [result code] or
-** [extended result code] for the most recent failed sqlite3_* API call
-** associated with a [database connection]. If a prior API call failed
-** but the most recent API call succeeded, the return value from
-** sqlite3_errcode() is undefined. The sqlite3_extended_errcode()
-** interface is the same except that it always returns the
-** [extended result code] even when extended result codes are
-** disabled.
-**
-** The sqlite3_errmsg() and sqlite3_errmsg16() return English-language
-** text that describes the error, as either UTF-8 or UTF-16 respectively.
-** Memory to hold the error message string is managed internally.
-** The application does not need to worry about freeing the result.
-** However, the error string might be overwritten or deallocated by
-** subsequent calls to other SQLite interface functions.
-**
-** When the serialized [threading mode] is in use, it might be the
-** case that a second error occurs on a separate thread in between
-** the time of the first error and the call to these interfaces.
-** When that happens, the second error will be reported since these
-** interfaces always report the most recent result. To avoid
-** this, each thread can obtain exclusive use of the [database connection] D
-** by invoking [sqlite3_mutex_enter]([sqlite3_db_mutex](D)) before beginning
-** to use D and invoking [sqlite3_mutex_leave]([sqlite3_db_mutex](D)) after
-** all calls to the interfaces listed here are completed.
-**
-** If an interface fails with SQLITE_MISUSE, that means the interface
-** was invoked incorrectly by the application. In that case, the
-** error code and message may or may not be set.
-**
-** Requirements:
-** [H12801] [H12802] [H12803] [H12807] [H12808] [H12809]
-*/
-SQLITE_API int sqlite3_errcode(sqlite3 *db);
-SQLITE_API int sqlite3_extended_errcode(sqlite3 *db);
-SQLITE_API const char *sqlite3_errmsg(sqlite3*);
-SQLITE_API const void *sqlite3_errmsg16(sqlite3*);
-
-/*
-** CAPI3REF: SQL Statement Object {H13000} <H13010>
-** KEYWORDS: {prepared statement} {prepared statements}
-**
-** An instance of this object represents a single SQL statement.
-** This object is variously known as a "prepared statement" or a
-** "compiled SQL statement" or simply as a "statement".
-**
-** The life of a statement object goes something like this:
-**
-** <ol>
-** <li> Create the object using [sqlite3_prepare_v2()] or a related
-** function.
-** <li> Bind values to [host parameters] using the sqlite3_bind_*()
-** interfaces.
-** <li> Run the SQL by calling [sqlite3_step()] one or more times.
-** <li> Reset the statement using [sqlite3_reset()] then go back
-** to step 2. Do this zero or more times.
-** <li> Destroy the object using [sqlite3_finalize()].
-** </ol>
-**
-** Refer to documentation on individual methods above for additional
-** information.
-*/
-typedef struct sqlite3_stmt sqlite3_stmt;
-
-/*
-** CAPI3REF: Run-time Limits {H12760} <S20600>
-**
-** This interface allows the size of various constructs to be limited
-** on a connection by connection basis. The first parameter is the
-** [database connection] whose limit is to be set or queried. The
-** second parameter is one of the [limit categories] that define a
-** class of constructs to be size limited. The third parameter is the
-** new limit for that construct. The function returns the old limit.
-**
-** If the new limit is a negative number, the limit is unchanged.
-** For the limit category of SQLITE_LIMIT_XYZ there is a
-** [limits | hard upper bound]
-** set by a compile-time C preprocessor macro named
-** [limits | SQLITE_MAX_XYZ].
-** (The "_LIMIT_" in the name is changed to "_MAX_".)
-** Attempts to increase a limit above its hard upper bound are
-** silently truncated to the hard upper limit.
-**
-** Run time limits are intended for use in applications that manage
-** both their own internal database and also databases that are controlled
-** by untrusted external sources. An example application might be a
-** web browser that has its own databases for storing history and
-** separate databases controlled by JavaScript applications downloaded
-** off the Internet. The internal databases can be given the
-** large, default limits. Databases managed by external sources can
-** be given much smaller limits designed to prevent a denial of service
-** attack. Developers might also want to use the [sqlite3_set_authorizer()]
-** interface to further control untrusted SQL. The size of the database
-** created by an untrusted script can be contained using the
-** [max_page_count] [PRAGMA].
-**
-** New run-time limit categories may be added in future releases.
-**
-** Requirements:
-** [H12762] [H12766] [H12769]
-*/
-SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal);
-
-/*
-** CAPI3REF: Run-Time Limit Categories {H12790} <H12760>
-** KEYWORDS: {limit category} {limit categories}
-**
-** These constants define various performance limits
-** that can be lowered at run-time using [sqlite3_limit()].
-** The synopsis of the meanings of the various limits is shown below.
-** Additional information is available at [limits | Limits in SQLite].
-**
-** <dl>
-** <dt>SQLITE_LIMIT_LENGTH</dt>
-** <dd>The maximum size of any string or BLOB or table row.<dd>
-**
-** <dt>SQLITE_LIMIT_SQL_LENGTH</dt>
-** <dd>The maximum length of an SQL statement.</dd>
-**
-** <dt>SQLITE_LIMIT_COLUMN</dt>
-** <dd>The maximum number of columns in a table definition or in the
-** result set of a [SELECT] or the maximum number of columns in an index
-** or in an ORDER BY or GROUP BY clause.</dd>
-**
-** <dt>SQLITE_LIMIT_EXPR_DEPTH</dt>
-** <dd>The maximum depth of the parse tree on any expression.</dd>
-**
-** <dt>SQLITE_LIMIT_COMPOUND_SELECT</dt>
-** <dd>The maximum number of terms in a compound SELECT statement.</dd>
-**
-** <dt>SQLITE_LIMIT_VDBE_OP</dt>
-** <dd>The maximum number of instructions in a virtual machine program
-** used to implement an SQL statement.</dd>
-**
-** <dt>SQLITE_LIMIT_FUNCTION_ARG</dt>
-** <dd>The maximum number of arguments on a function.</dd>
-**
-** <dt>SQLITE_LIMIT_ATTACHED</dt>
-** <dd>The maximum number of [ATTACH | attached databases].</dd>
-**
-** <dt>SQLITE_LIMIT_LIKE_PATTERN_LENGTH</dt>
-** <dd>The maximum length of the pattern argument to the [LIKE] or
-** [GLOB] operators.</dd>
-**
-** <dt>SQLITE_LIMIT_VARIABLE_NUMBER</dt>
-** <dd>The maximum number of variables in an SQL statement that can
-** be bound.</dd>
-**
-** <dt>SQLITE_LIMIT_TRIGGER_DEPTH</dt>
-** <dd>The maximum depth of recursion for triggers.</dd>
-** </dl>
-*/
-#define SQLITE_LIMIT_LENGTH 0
-#define SQLITE_LIMIT_SQL_LENGTH 1
-#define SQLITE_LIMIT_COLUMN 2
-#define SQLITE_LIMIT_EXPR_DEPTH 3
-#define SQLITE_LIMIT_COMPOUND_SELECT 4
-#define SQLITE_LIMIT_VDBE_OP 5
-#define SQLITE_LIMIT_FUNCTION_ARG 6
-#define SQLITE_LIMIT_ATTACHED 7
-#define SQLITE_LIMIT_LIKE_PATTERN_LENGTH 8
-#define SQLITE_LIMIT_VARIABLE_NUMBER 9
-#define SQLITE_LIMIT_TRIGGER_DEPTH 10
-
-/*
-** CAPI3REF: Compiling An SQL Statement {H13010} <S10000>
-** KEYWORDS: {SQL statement compiler}
-**
-** To execute an SQL query, it must first be compiled into a byte-code
-** program using one of these routines.
-**
-** The first argument, "db", is a [database connection] obtained from a
-** prior successful call to [sqlite3_open()], [sqlite3_open_v2()] or
-** [sqlite3_open16()]. The database connection must not have been closed.
-**
-** The second argument, "zSql", is the statement to be compiled, encoded
-** as either UTF-8 or UTF-16. The sqlite3_prepare() and sqlite3_prepare_v2()
-** interfaces use UTF-8, and sqlite3_prepare16() and sqlite3_prepare16_v2()
-** use UTF-16.
-**
-** If the nByte argument is less than zero, then zSql is read up to the
-** first zero terminator. If nByte is non-negative, then it is the maximum
-** number of bytes read from zSql. When nByte is non-negative, the
-** zSql string ends at either the first '\000' or '\u0000' character or
-** the nByte-th byte, whichever comes first. If the caller knows
-** that the supplied string is nul-terminated, then there is a small
-** performance advantage to be gained by passing an nByte parameter that
-** is equal to the number of bytes in the input string <i>including</i>
-** the nul-terminator bytes.
-**
-** If pzTail is not NULL then *pzTail is made to point to the first byte
-** past the end of the first SQL statement in zSql. These routines only
-** compile the first statement in zSql, so *pzTail is left pointing to
-** what remains uncompiled.
-**
-** *ppStmt is left pointing to a compiled [prepared statement] that can be
-** executed using [sqlite3_step()]. If there is an error, *ppStmt is set
-** to NULL. If the input text contains no SQL (if the input is an empty
-** string or a comment) then *ppStmt is set to NULL.
-** The calling procedure is responsible for deleting the compiled
-** SQL statement using [sqlite3_finalize()] after it has finished with it.
-** ppStmt may not be NULL.
-**
-** On success, [SQLITE_OK] is returned, otherwise an [error code] is returned.
-**
-** The sqlite3_prepare_v2() and sqlite3_prepare16_v2() interfaces are
-** recommended for all new programs. The two older interfaces are retained
-** for backwards compatibility, but their use is discouraged.
-** In the "v2" interfaces, the prepared statement
-** that is returned (the [sqlite3_stmt] object) contains a copy of the
-** original SQL text. This causes the [sqlite3_step()] interface to
-** behave a differently in two ways:
-**
-** <ol>
-** <li>
-** If the database schema changes, instead of returning [SQLITE_SCHEMA] as it
-** always used to do, [sqlite3_step()] will automatically recompile the SQL
-** statement and try to run it again. If the schema has changed in
-** a way that makes the statement no longer valid, [sqlite3_step()] will still
-** return [SQLITE_SCHEMA]. But unlike the legacy behavior, [SQLITE_SCHEMA] is
-** now a fatal error. Calling [sqlite3_prepare_v2()] again will not make the
-** error go away. Note: use [sqlite3_errmsg()] to find the text
-** of the parsing error that results in an [SQLITE_SCHEMA] return.
-** </li>
-**
-** <li>
-** When an error occurs, [sqlite3_step()] will return one of the detailed
-** [error codes] or [extended error codes]. The legacy behavior was that
-** [sqlite3_step()] would only return a generic [SQLITE_ERROR] result code
-** and you would have to make a second call to [sqlite3_reset()] in order
-** to find the underlying cause of the problem. With the "v2" prepare
-** interfaces, the underlying reason for the error is returned immediately.
-** </li>
-** </ol>
-**
-** Requirements:
-** [H13011] [H13012] [H13013] [H13014] [H13015] [H13016] [H13019] [H13021]
-**
-*/
-SQLITE_API int sqlite3_prepare(
- sqlite3 *db, /* Database handle */
- const char *zSql, /* SQL statement, UTF-8 encoded */
- int nByte, /* Maximum length of zSql in bytes. */
- sqlite3_stmt **ppStmt, /* OUT: Statement handle */
- const char **pzTail /* OUT: Pointer to unused portion of zSql */
-);
-SQLITE_API int sqlite3_prepare_v2(
- sqlite3 *db, /* Database handle */
- const char *zSql, /* SQL statement, UTF-8 encoded */
- int nByte, /* Maximum length of zSql in bytes. */
- sqlite3_stmt **ppStmt, /* OUT: Statement handle */
- const char **pzTail /* OUT: Pointer to unused portion of zSql */
-);
-SQLITE_API int sqlite3_prepare16(
- sqlite3 *db, /* Database handle */
- const void *zSql, /* SQL statement, UTF-16 encoded */
- int nByte, /* Maximum length of zSql in bytes. */
- sqlite3_stmt **ppStmt, /* OUT: Statement handle */
- const void **pzTail /* OUT: Pointer to unused portion of zSql */
-);
-SQLITE_API int sqlite3_prepare16_v2(
- sqlite3 *db, /* Database handle */
- const void *zSql, /* SQL statement, UTF-16 encoded */
- int nByte, /* Maximum length of zSql in bytes. */
- sqlite3_stmt **ppStmt, /* OUT: Statement handle */
- const void **pzTail /* OUT: Pointer to unused portion of zSql */
-);
-
-/*
-** CAPI3REF: Retrieving Statement SQL {H13100} <H13000>
-**
-** This interface can be used to retrieve a saved copy of the original
-** SQL text used to create a [prepared statement] if that statement was
-** compiled using either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()].
-**
-** Requirements:
-** [H13101] [H13102] [H13103]
-*/
-SQLITE_API const char *sqlite3_sql(sqlite3_stmt *pStmt);
-
-/*
-** CAPI3REF: Dynamically Typed Value Object {H15000} <S20200>
-** KEYWORDS: {protected sqlite3_value} {unprotected sqlite3_value}
-**
-** SQLite uses the sqlite3_value object to represent all values
-** that can be stored in a database table. SQLite uses dynamic typing
-** for the values it stores. Values stored in sqlite3_value objects
-** can be integers, floating point values, strings, BLOBs, or NULL.
-**
-** An sqlite3_value object may be either "protected" or "unprotected".
-** Some interfaces require a protected sqlite3_value. Other interfaces
-** will accept either a protected or an unprotected sqlite3_value.
-** Every interface that accepts sqlite3_value arguments specifies
-** whether or not it requires a protected sqlite3_value.
-**
-** The terms "protected" and "unprotected" refer to whether or not
-** a mutex is held. A internal mutex is held for a protected
-** sqlite3_value object but no mutex is held for an unprotected
-** sqlite3_value object. If SQLite is compiled to be single-threaded
-** (with [SQLITE_THREADSAFE=0] and with [sqlite3_threadsafe()] returning 0)
-** or if SQLite is run in one of reduced mutex modes
-** [SQLITE_CONFIG_SINGLETHREAD] or [SQLITE_CONFIG_MULTITHREAD]
-** then there is no distinction between protected and unprotected
-** sqlite3_value objects and they can be used interchangeably. However,
-** for maximum code portability it is recommended that applications
-** still make the distinction between between protected and unprotected
-** sqlite3_value objects even when not strictly required.
-**
-** The sqlite3_value objects that are passed as parameters into the
-** implementation of [application-defined SQL functions] are protected.
-** The sqlite3_value object returned by
-** [sqlite3_column_value()] is unprotected.
-** Unprotected sqlite3_value objects may only be used with
-** [sqlite3_result_value()] and [sqlite3_bind_value()].
-** The [sqlite3_value_blob | sqlite3_value_type()] family of
-** interfaces require protected sqlite3_value objects.
-*/
-typedef struct Mem sqlite3_value;
-
-/*
-** CAPI3REF: SQL Function Context Object {H16001} <S20200>
-**
-** The context in which an SQL function executes is stored in an
-** sqlite3_context object. A pointer to an sqlite3_context object
-** is always first parameter to [application-defined SQL functions].
-** The application-defined SQL function implementation will pass this
-** pointer through into calls to [sqlite3_result_int | sqlite3_result()],
-** [sqlite3_aggregate_context()], [sqlite3_user_data()],
-** [sqlite3_context_db_handle()], [sqlite3_get_auxdata()],
-** and/or [sqlite3_set_auxdata()].
-*/
-typedef struct sqlite3_context sqlite3_context;
-
-/*
-** CAPI3REF: Binding Values To Prepared Statements {H13500} <S70300>
-** KEYWORDS: {host parameter} {host parameters} {host parameter name}
-** KEYWORDS: {SQL parameter} {SQL parameters} {parameter binding}
-**
-** In the SQL strings input to [sqlite3_prepare_v2()] and its variants,
-** literals may be replaced by a [parameter] that matches one of following
-** templates:
-**
-** <ul>
-** <li> ?
-** <li> ?NNN
-** <li> :VVV
-** <li> @VVV
-** <li> $VVV
-** </ul>
-**
-** In the templates above, NNN represents an integer literal,
-** and VVV represents an alphanumeric identifer. The values of these
-** parameters (also called "host parameter names" or "SQL parameters")
-** can be set using the sqlite3_bind_*() routines defined here.
-**
-** The first argument to the sqlite3_bind_*() routines is always
-** a pointer to the [sqlite3_stmt] object returned from
-** [sqlite3_prepare_v2()] or its variants.
-**
-** The second argument is the index of the SQL parameter to be set.
-** The leftmost SQL parameter has an index of 1. When the same named
-** SQL parameter is used more than once, second and subsequent
-** occurrences have the same index as the first occurrence.
-** The index for named parameters can be looked up using the
-** [sqlite3_bind_parameter_index()] API if desired. The index
-** for "?NNN" parameters is the value of NNN.
-** The NNN value must be between 1 and the [sqlite3_limit()]
-** parameter [SQLITE_LIMIT_VARIABLE_NUMBER] (default value: 999).
-**
-** The third argument is the value to bind to the parameter.
-**
-** In those routines that have a fourth argument, its value is the
-** number of bytes in the parameter. To be clear: the value is the
-** number of <u>bytes</u> in the value, not the number of characters.
-** If the fourth parameter is negative, the length of the string is
-** the number of bytes up to the first zero terminator.
-**
-** The fifth argument to sqlite3_bind_blob(), sqlite3_bind_text(), and
-** sqlite3_bind_text16() is a destructor used to dispose of the BLOB or
-** string after SQLite has finished with it. If the fifth argument is
-** the special value [SQLITE_STATIC], then SQLite assumes that the
-** information is in static, unmanaged space and does not need to be freed.
-** If the fifth argument has the value [SQLITE_TRANSIENT], then
-** SQLite makes its own private copy of the data immediately, before
-** the sqlite3_bind_*() routine returns.
-**
-** The sqlite3_bind_zeroblob() routine binds a BLOB of length N that
-** is filled with zeroes. A zeroblob uses a fixed amount of memory
-** (just an integer to hold its size) while it is being processed.
-** Zeroblobs are intended to serve as placeholders for BLOBs whose
-** content is later written using
-** [sqlite3_blob_open | incremental BLOB I/O] routines.
-** A negative value for the zeroblob results in a zero-length BLOB.
-**
-** The sqlite3_bind_*() routines must be called after
-** [sqlite3_prepare_v2()] (and its variants) or [sqlite3_reset()] and
-** before [sqlite3_step()].
-** Bindings are not cleared by the [sqlite3_reset()] routine.
-** Unbound parameters are interpreted as NULL.
-**
-** These routines return [SQLITE_OK] on success or an error code if
-** anything goes wrong. [SQLITE_RANGE] is returned if the parameter
-** index is out of range. [SQLITE_NOMEM] is returned if malloc() fails.
-** [SQLITE_MISUSE] might be returned if these routines are called on a
-** virtual machine that is the wrong state or which has already been finalized.
-** Detection of misuse is unreliable. Applications should not depend
-** on SQLITE_MISUSE returns. SQLITE_MISUSE is intended to indicate a
-** a logic error in the application. Future versions of SQLite might
-** panic rather than return SQLITE_MISUSE.
-**
-** See also: [sqlite3_bind_parameter_count()],
-** [sqlite3_bind_parameter_name()], and [sqlite3_bind_parameter_index()].
-**
-** Requirements:
-** [H13506] [H13509] [H13512] [H13515] [H13518] [H13521] [H13524] [H13527]
-** [H13530] [H13533] [H13536] [H13539] [H13542] [H13545] [H13548] [H13551]
-**
-*/
-SQLITE_API int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*));
-SQLITE_API int sqlite3_bind_double(sqlite3_stmt*, int, double);
-SQLITE_API int sqlite3_bind_int(sqlite3_stmt*, int, int);
-SQLITE_API int sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64);
-SQLITE_API int sqlite3_bind_null(sqlite3_stmt*, int);
-SQLITE_API int sqlite3_bind_text(sqlite3_stmt*, int, const char*, int n, void(*)(void*));
-SQLITE_API int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*));
-SQLITE_API int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*);
-SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n);
-
-/*
-** CAPI3REF: Number Of SQL Parameters {H13600} <S70300>
-**
-** This routine can be used to find the number of [SQL parameters]
-** in a [prepared statement]. SQL parameters are tokens of the
-** form "?", "?NNN", ":AAA", "$AAA", or "@AAA" that serve as
-** placeholders for values that are [sqlite3_bind_blob | bound]
-** to the parameters at a later time.
-**
-** This routine actually returns the index of the largest (rightmost)
-** parameter. For all forms except ?NNN, this will correspond to the
-** number of unique parameters. If parameters of the ?NNN are used,
-** there may be gaps in the list.
-**
-** See also: [sqlite3_bind_blob|sqlite3_bind()],
-** [sqlite3_bind_parameter_name()], and
-** [sqlite3_bind_parameter_index()].
-**
-** Requirements:
-** [H13601]
-*/
-SQLITE_API int sqlite3_bind_parameter_count(sqlite3_stmt*);
-
-/*
-** CAPI3REF: Name Of A Host Parameter {H13620} <S70300>
-**
-** This routine returns a pointer to the name of the n-th
-** [SQL parameter] in a [prepared statement].
-** SQL parameters of the form "?NNN" or ":AAA" or "@AAA" or "$AAA"
-** have a name which is the string "?NNN" or ":AAA" or "@AAA" or "$AAA"
-** respectively.
-** In other words, the initial ":" or "$" or "@" or "?"
-** is included as part of the name.
-** Parameters of the form "?" without a following integer have no name
-** and are also referred to as "anonymous parameters".
-**
-** The first host parameter has an index of 1, not 0.
-**
-** If the value n is out of range or if the n-th parameter is
-** nameless, then NULL is returned. The returned string is
-** always in UTF-8 encoding even if the named parameter was
-** originally specified as UTF-16 in [sqlite3_prepare16()] or
-** [sqlite3_prepare16_v2()].
-**
-** See also: [sqlite3_bind_blob|sqlite3_bind()],
-** [sqlite3_bind_parameter_count()], and
-** [sqlite3_bind_parameter_index()].
-**
-** Requirements:
-** [H13621]
-*/
-SQLITE_API const char *sqlite3_bind_parameter_name(sqlite3_stmt*, int);
-
-/*
-** CAPI3REF: Index Of A Parameter With A Given Name {H13640} <S70300>
-**
-** Return the index of an SQL parameter given its name. The
-** index value returned is suitable for use as the second
-** parameter to [sqlite3_bind_blob|sqlite3_bind()]. A zero
-** is returned if no matching parameter is found. The parameter
-** name must be given in UTF-8 even if the original statement
-** was prepared from UTF-16 text using [sqlite3_prepare16_v2()].
-**
-** See also: [sqlite3_bind_blob|sqlite3_bind()],
-** [sqlite3_bind_parameter_count()], and
-** [sqlite3_bind_parameter_index()].
-**
-** Requirements:
-** [H13641]
-*/
-SQLITE_API int sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName);
-
-/*
-** CAPI3REF: Reset All Bindings On A Prepared Statement {H13660} <S70300>
-**
-** Contrary to the intuition of many, [sqlite3_reset()] does not reset
-** the [sqlite3_bind_blob | bindings] on a [prepared statement].
-** Use this routine to reset all host parameters to NULL.
-**
-** Requirements:
-** [H13661]
-*/
-SQLITE_API int sqlite3_clear_bindings(sqlite3_stmt*);
-
-/*
-** CAPI3REF: Number Of Columns In A Result Set {H13710} <S10700>
-**
-** Return the number of columns in the result set returned by the
-** [prepared statement]. This routine returns 0 if pStmt is an SQL
-** statement that does not return data (for example an [UPDATE]).
-**
-** Requirements:
-** [H13711]
-*/
-SQLITE_API int sqlite3_column_count(sqlite3_stmt *pStmt);
-
-/*
-** CAPI3REF: Column Names In A Result Set {H13720} <S10700>
-**
-** These routines return the name assigned to a particular column
-** in the result set of a [SELECT] statement. The sqlite3_column_name()
-** interface returns a pointer to a zero-terminated UTF-8 string
-** and sqlite3_column_name16() returns a pointer to a zero-terminated
-** UTF-16 string. The first parameter is the [prepared statement]
-** that implements the [SELECT] statement. The second parameter is the
-** column number. The leftmost column is number 0.
-**
-** The returned string pointer is valid until either the [prepared statement]
-** is destroyed by [sqlite3_finalize()] or until the next call to
-** sqlite3_column_name() or sqlite3_column_name16() on the same column.
-**
-** If sqlite3_malloc() fails during the processing of either routine
-** (for example during a conversion from UTF-8 to UTF-16) then a
-** NULL pointer is returned.
-**
-** The name of a result column is the value of the "AS" clause for
-** that column, if there is an AS clause. If there is no AS clause
-** then the name of the column is unspecified and may change from
-** one release of SQLite to the next.
-**
-** Requirements:
-** [H13721] [H13723] [H13724] [H13725] [H13726] [H13727]
-*/
-SQLITE_API const char *sqlite3_column_name(sqlite3_stmt*, int N);
-SQLITE_API const void *sqlite3_column_name16(sqlite3_stmt*, int N);
-
-/*
-** CAPI3REF: Source Of Data In A Query Result {H13740} <S10700>
-**
-** These routines provide a means to determine what column of what
-** table in which database a result of a [SELECT] statement comes from.
-** The name of the database or table or column can be returned as
-** either a UTF-8 or UTF-16 string. The _database_ routines return
-** the database name, the _table_ routines return the table name, and
-** the origin_ routines return the column name.
-** The returned string is valid until the [prepared statement] is destroyed
-** using [sqlite3_finalize()] or until the same information is requested
-** again in a different encoding.
-**
-** The names returned are the original un-aliased names of the
-** database, table, and column.
-**
-** The first argument to the following calls is a [prepared statement].
-** These functions return information about the Nth column returned by
-** the statement, where N is the second function argument.
-**
-** If the Nth column returned by the statement is an expression or
-** subquery and is not a column value, then all of these functions return
-** NULL. These routine might also return NULL if a memory allocation error
-** occurs. Otherwise, they return the name of the attached database, table
-** and column that query result column was extracted from.
-**
-** As with all other SQLite APIs, those postfixed with "16" return
-** UTF-16 encoded strings, the other functions return UTF-8. {END}
-**
-** These APIs are only available if the library was compiled with the
-** [SQLITE_ENABLE_COLUMN_METADATA] C-preprocessor symbol defined.
-**
-** {A13751}
-** If two or more threads call one or more of these routines against the same
-** prepared statement and column at the same time then the results are
-** undefined.
-**
-** Requirements:
-** [H13741] [H13742] [H13743] [H13744] [H13745] [H13746] [H13748]
-**
-** If two or more threads call one or more
-** [sqlite3_column_database_name | column metadata interfaces]
-** for the same [prepared statement] and result column
-** at the same time then the results are undefined.
-*/
-SQLITE_API const char *sqlite3_column_database_name(sqlite3_stmt*,int);
-SQLITE_API const void *sqlite3_column_database_name16(sqlite3_stmt*,int);
-SQLITE_API const char *sqlite3_column_table_name(sqlite3_stmt*,int);
-SQLITE_API const void *sqlite3_column_table_name16(sqlite3_stmt*,int);
-SQLITE_API const char *sqlite3_column_origin_name(sqlite3_stmt*,int);
-SQLITE_API const void *sqlite3_column_origin_name16(sqlite3_stmt*,int);
-
-/*
-** CAPI3REF: Declared Datatype Of A Query Result {H13760} <S10700>
-**
-** The first parameter is a [prepared statement].
-** If this statement is a [SELECT] statement and the Nth column of the
-** returned result set of that [SELECT] is a table column (not an
-** expression or subquery) then the declared type of the table
-** column is returned. If the Nth column of the result set is an
-** expression or subquery, then a NULL pointer is returned.
-** The returned string is always UTF-8 encoded. {END}
-**
-** For example, given the database schema:
-**
-** CREATE TABLE t1(c1 VARIANT);
-**
-** and the following statement to be compiled:
-**
-** SELECT c1 + 1, c1 FROM t1;
-**
-** this routine would return the string "VARIANT" for the second result
-** column (i==1), and a NULL pointer for the first result column (i==0).
-**
-** SQLite uses dynamic run-time typing. So just because a column
-** is declared to contain a particular type does not mean that the
-** data stored in that column is of the declared type. SQLite is
-** strongly typed, but the typing is dynamic not static. Type
-** is associated with individual values, not with the containers
-** used to hold those values.
-**
-** Requirements:
-** [H13761] [H13762] [H13763]
-*/
-SQLITE_API const char *sqlite3_column_decltype(sqlite3_stmt*,int);
-SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt*,int);
-
-/*
-** CAPI3REF: Evaluate An SQL Statement {H13200} <S10000>
-**
-** After a [prepared statement] has been prepared using either
-** [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()] or one of the legacy
-** interfaces [sqlite3_prepare()] or [sqlite3_prepare16()], this function
-** must be called one or more times to evaluate the statement.
-**
-** The details of the behavior of the sqlite3_step() interface depend
-** on whether the statement was prepared using the newer "v2" interface
-** [sqlite3_prepare_v2()] and [sqlite3_prepare16_v2()] or the older legacy
-** interface [sqlite3_prepare()] and [sqlite3_prepare16()]. The use of the
-** new "v2" interface is recommended for new applications but the legacy
-** interface will continue to be supported.
-**
-** In the legacy interface, the return value will be either [SQLITE_BUSY],
-** [SQLITE_DONE], [SQLITE_ROW], [SQLITE_ERROR], or [SQLITE_MISUSE].
-** With the "v2" interface, any of the other [result codes] or
-** [extended result codes] might be returned as well.
-**
-** [SQLITE_BUSY] means that the database engine was unable to acquire the
-** database locks it needs to do its job. If the statement is a [COMMIT]
-** or occurs outside of an explicit transaction, then you can retry the
-** statement. If the statement is not a [COMMIT] and occurs within a
-** explicit transaction then you should rollback the transaction before
-** continuing.
-**
-** [SQLITE_DONE] means that the statement has finished executing
-** successfully. sqlite3_step() should not be called again on this virtual
-** machine without first calling [sqlite3_reset()] to reset the virtual
-** machine back to its initial state.
-**
-** If the SQL statement being executed returns any data, then [SQLITE_ROW]
-** is returned each time a new row of data is ready for processing by the
-** caller. The values may be accessed using the [column access functions].
-** sqlite3_step() is called again to retrieve the next row of data.
-**
-** [SQLITE_ERROR] means that a run-time error (such as a constraint
-** violation) has occurred. sqlite3_step() should not be called again on
-** the VM. More information may be found by calling [sqlite3_errmsg()].
-** With the legacy interface, a more specific error code (for example,
-** [SQLITE_INTERRUPT], [SQLITE_SCHEMA], [SQLITE_CORRUPT], and so forth)
-** can be obtained by calling [sqlite3_reset()] on the
-** [prepared statement]. In the "v2" interface,
-** the more specific error code is returned directly by sqlite3_step().
-**
-** [SQLITE_MISUSE] means that the this routine was called inappropriately.
-** Perhaps it was called on a [prepared statement] that has
-** already been [sqlite3_finalize | finalized] or on one that had
-** previously returned [SQLITE_ERROR] or [SQLITE_DONE]. Or it could
-** be the case that the same database connection is being used by two or
-** more threads at the same moment in time.
-**
-** <b>Goofy Interface Alert:</b> In the legacy interface, the sqlite3_step()
-** API always returns a generic error code, [SQLITE_ERROR], following any
-** error other than [SQLITE_BUSY] and [SQLITE_MISUSE]. You must call
-** [sqlite3_reset()] or [sqlite3_finalize()] in order to find one of the
-** specific [error codes] that better describes the error.
-** We admit that this is a goofy design. The problem has been fixed
-** with the "v2" interface. If you prepare all of your SQL statements
-** using either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()] instead
-** of the legacy [sqlite3_prepare()] and [sqlite3_prepare16()] interfaces,
-** then the more specific [error codes] are returned directly
-** by sqlite3_step(). The use of the "v2" interface is recommended.
-**
-** Requirements:
-** [H13202] [H15304] [H15306] [H15308] [H15310]
-*/
-SQLITE_API int sqlite3_step(sqlite3_stmt*);
-
-/*
-** CAPI3REF: Number of columns in a result set {H13770} <S10700>
-**
-** Returns the number of values in the current row of the result set.
-**
-** Requirements:
-** [H13771] [H13772]
-*/
-SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt);
-
-/*
-** CAPI3REF: Fundamental Datatypes {H10265} <S10110><S10120>
-** KEYWORDS: SQLITE_TEXT
-**
-** {H10266} Every value in SQLite has one of five fundamental datatypes:
-**
-** <ul>
-** <li> 64-bit signed integer
-** <li> 64-bit IEEE floating point number
-** <li> string
-** <li> BLOB
-** <li> NULL
-** </ul> {END}
-**
-** These constants are codes for each of those types.
-**
-** Note that the SQLITE_TEXT constant was also used in SQLite version 2
-** for a completely different meaning. Software that links against both
-** SQLite version 2 and SQLite version 3 should use SQLITE3_TEXT, not
-** SQLITE_TEXT.
-*/
-#define SQLITE_INTEGER 1
-#define SQLITE_FLOAT 2
-#define SQLITE_BLOB 4
-#define SQLITE_NULL 5
-#ifdef SQLITE_TEXT
-# undef SQLITE_TEXT
-#else
-# define SQLITE_TEXT 3
-#endif
-#define SQLITE3_TEXT 3
-
-/*
-** CAPI3REF: Result Values From A Query {H13800} <S10700>
-** KEYWORDS: {column access functions}
-**
-** These routines form the "result set query" interface.
-**
-** These routines return information about a single column of the current
-** result row of a query. In every case the first argument is a pointer
-** to the [prepared statement] that is being evaluated (the [sqlite3_stmt*]
-** that was returned from [sqlite3_prepare_v2()] or one of its variants)
-** and the second argument is the index of the column for which information
-** should be returned. The leftmost column of the result set has the index 0.
-**
-** If the SQL statement does not currently point to a valid row, or if the
-** column index is out of range, the result is undefined.
-** These routines may only be called when the most recent call to
-** [sqlite3_step()] has returned [SQLITE_ROW] and neither
-** [sqlite3_reset()] nor [sqlite3_finalize()] have been called subsequently.
-** If any of these routines are called after [sqlite3_reset()] or
-** [sqlite3_finalize()] or after [sqlite3_step()] has returned
-** something other than [SQLITE_ROW], the results are undefined.
-** If [sqlite3_step()] or [sqlite3_reset()] or [sqlite3_finalize()]
-** are called from a different thread while any of these routines
-** are pending, then the results are undefined.
-**
-** The sqlite3_column_type() routine returns the
-** [SQLITE_INTEGER | datatype code] for the initial data type
-** of the result column. The returned value is one of [SQLITE_INTEGER],
-** [SQLITE_FLOAT], [SQLITE_TEXT], [SQLITE_BLOB], or [SQLITE_NULL]. The value
-** returned by sqlite3_column_type() is only meaningful if no type
-** conversions have occurred as described below. After a type conversion,
-** the value returned by sqlite3_column_type() is undefined. Future
-** versions of SQLite may change the behavior of sqlite3_column_type()
-** following a type conversion.
-**
-** If the result is a BLOB or UTF-8 string then the sqlite3_column_bytes()
-** routine returns the number of bytes in that BLOB or string.
-** If the result is a UTF-16 string, then sqlite3_column_bytes() converts
-** the string to UTF-8 and then returns the number of bytes.
-** If the result is a numeric value then sqlite3_column_bytes() uses
-** [sqlite3_snprintf()] to convert that value to a UTF-8 string and returns
-** the number of bytes in that string.
-** The value returned does not include the zero terminator at the end
-** of the string. For clarity: the value returned is the number of
-** 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
-** value from sqlite3_column_blob() for a zero-length BLOB is an arbitrary
-** pointer, possibly even a NULL pointer.
-**
-** The sqlite3_column_bytes16() routine is similar to sqlite3_column_bytes()
-** but leaves the result in UTF-16 in native byte order instead of UTF-8.
-** The zero terminator is not included in this count.
-**
-** The object returned by [sqlite3_column_value()] is an
-** [unprotected sqlite3_value] object. An unprotected sqlite3_value object
-** may only be used with [sqlite3_bind_value()] and [sqlite3_result_value()].
-** If the [unprotected sqlite3_value] object returned by
-** [sqlite3_column_value()] is used in any other way, including calls
-** to routines like [sqlite3_value_int()], [sqlite3_value_text()],
-** or [sqlite3_value_bytes()], then the behavior is undefined.
-**
-** These routines attempt to convert the value where appropriate. For
-** example, if the internal representation is FLOAT and a text result
-** is requested, [sqlite3_snprintf()] is used internally to perform the
-** conversion automatically. The following table details the conversions
-** that are applied:
-**
-** <blockquote>
-** <table border="1">
-** <tr><th> Internal<br>Type <th> Requested<br>Type <th> Conversion
-**
-** <tr><td> NULL <td> INTEGER <td> Result is 0
-** <tr><td> NULL <td> FLOAT <td> Result is 0.0
-** <tr><td> NULL <td> TEXT <td> Result is NULL pointer
-** <tr><td> NULL <td> BLOB <td> Result is NULL pointer
-** <tr><td> INTEGER <td> FLOAT <td> Convert from integer to float
-** <tr><td> INTEGER <td> TEXT <td> ASCII rendering of the integer
-** <tr><td> INTEGER <td> BLOB <td> Same as INTEGER->TEXT
-** <tr><td> FLOAT <td> INTEGER <td> Convert from float to integer
-** <tr><td> FLOAT <td> TEXT <td> ASCII rendering of the float
-** <tr><td> FLOAT <td> BLOB <td> Same as FLOAT->TEXT
-** <tr><td> TEXT <td> INTEGER <td> Use atoi()
-** <tr><td> TEXT <td> FLOAT <td> Use atof()
-** <tr><td> TEXT <td> BLOB <td> No change
-** <tr><td> BLOB <td> INTEGER <td> Convert to TEXT then use atoi()
-** <tr><td> BLOB <td> FLOAT <td> Convert to TEXT then use atof()
-** <tr><td> BLOB <td> TEXT <td> Add a zero terminator if needed
-** </table>
-** </blockquote>
-**
-** The table above makes reference to standard C library functions atoi()
-** and atof(). SQLite does not really use these functions. It has its
-** own equivalent internal routines. The atoi() and atof() names are
-** used in the table for brevity and because they are familiar to most
-** C programmers.
-**
-** Note that when type conversions occur, pointers returned by prior
-** calls to sqlite3_column_blob(), sqlite3_column_text(), and/or
-** sqlite3_column_text16() may be invalidated.
-** Type conversions and pointer invalidations might occur
-** in the following cases:
-**
-** <ul>
-** <li> The initial content is a BLOB and sqlite3_column_text() or
-** sqlite3_column_text16() is called. A zero-terminator might
-** need to be added to the string.</li>
-** <li> The initial content is UTF-8 text and sqlite3_column_bytes16() or
-** sqlite3_column_text16() is called. The content must be converted
-** to UTF-16.</li>
-** <li> The initial content is UTF-16 text and sqlite3_column_bytes() or
-** sqlite3_column_text() is called. The content must be converted
-** to UTF-8.</li>
-** </ul>
-**
-** Conversions between UTF-16be and UTF-16le are always done in place and do
-** not invalidate a prior pointer, though of course the content of the buffer
-** that the prior pointer points to will have been modified. Other kinds
-** of conversion are done in place when it is possible, but sometimes they
-** are not possible and in those cases prior pointers are invalidated.
-**
-** The safest and easiest to remember policy is to invoke these routines
-** in one of the following ways:
-**
-** <ul>
-** <li>sqlite3_column_text() followed by sqlite3_column_bytes()</li>
-** <li>sqlite3_column_blob() followed by sqlite3_column_bytes()</li>
-** <li>sqlite3_column_text16() followed by sqlite3_column_bytes16()</li>
-** </ul>
-**
-** In other words, you should call sqlite3_column_text(),
-** sqlite3_column_blob(), or sqlite3_column_text16() first to force the result
-** into the desired format, then invoke sqlite3_column_bytes() or
-** sqlite3_column_bytes16() to find the size of the result. Do not mix calls
-** to sqlite3_column_text() or sqlite3_column_blob() with calls to
-** sqlite3_column_bytes16(), and do not mix calls to sqlite3_column_text16()
-** with calls to sqlite3_column_bytes().
-**
-** The pointers returned are valid until a type conversion occurs as
-** described above, or until [sqlite3_step()] or [sqlite3_reset()] or
-** [sqlite3_finalize()] is called. The memory space used to hold strings
-** and BLOBs is freed automatically. Do <b>not</b> pass the pointers returned
-** [sqlite3_column_blob()], [sqlite3_column_text()], etc. into
-** [sqlite3_free()].
-**
-** If a memory allocation error occurs during the evaluation of any
-** of these routines, a default value is returned. The default value
-** is either the integer 0, the floating point number 0.0, or a NULL
-** pointer. Subsequent calls to [sqlite3_errcode()] will return
-** [SQLITE_NOMEM].
-**
-** Requirements:
-** [H13803] [H13806] [H13809] [H13812] [H13815] [H13818] [H13821] [H13824]
-** [H13827] [H13830]
-*/
-SQLITE_API const void *sqlite3_column_blob(sqlite3_stmt*, int iCol);
-SQLITE_API int sqlite3_column_bytes(sqlite3_stmt*, int iCol);
-SQLITE_API int sqlite3_column_bytes16(sqlite3_stmt*, int iCol);
-SQLITE_API double sqlite3_column_double(sqlite3_stmt*, int iCol);
-SQLITE_API int sqlite3_column_int(sqlite3_stmt*, int iCol);
-SQLITE_API sqlite3_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol);
-SQLITE_API const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol);
-SQLITE_API const void *sqlite3_column_text16(sqlite3_stmt*, int iCol);
-SQLITE_API int sqlite3_column_type(sqlite3_stmt*, int iCol);
-SQLITE_API sqlite3_value *sqlite3_column_value(sqlite3_stmt*, int iCol);
-
-/*
-** CAPI3REF: Destroy A Prepared Statement Object {H13300} <S70300><S30100>
-**
-** The sqlite3_finalize() function is called to delete a [prepared statement].
-** If the statement was executed successfully or not executed at all, then
-** SQLITE_OK is returned. If execution of the statement failed then an
-** [error code] or [extended error code] is returned.
-**
-** This routine can be called at any point during the execution of the
-** [prepared statement]. If the virtual machine has not
-** completed execution when this routine is called, that is like
-** encountering an error or an [sqlite3_interrupt | interrupt].
-** Incomplete updates may be rolled back and transactions canceled,
-** depending on the circumstances, and the
-** [error code] returned will be [SQLITE_ABORT].
-**
-** Requirements:
-** [H11302] [H11304]
-*/
-SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt);
-
-/*
-** CAPI3REF: Reset A Prepared Statement Object {H13330} <S70300>
-**
-** The sqlite3_reset() function is called to reset a [prepared statement]
-** object back to its initial state, ready to be re-executed.
-** Any SQL statement variables that had values bound to them using
-** the [sqlite3_bind_blob | sqlite3_bind_*() API] retain their values.
-** Use [sqlite3_clear_bindings()] to reset the bindings.
-**
-** {H11332} The [sqlite3_reset(S)] interface resets the [prepared statement] S
-** back to the beginning of its program.
-**
-** {H11334} If the most recent call to [sqlite3_step(S)] for the
-** [prepared statement] S returned [SQLITE_ROW] or [SQLITE_DONE],
-** or if [sqlite3_step(S)] has never before been called on S,
-** then [sqlite3_reset(S)] returns [SQLITE_OK].
-**
-** {H11336} If the most recent call to [sqlite3_step(S)] for the
-** [prepared statement] S indicated an error, then
-** [sqlite3_reset(S)] returns an appropriate [error code].
-**
-** {H11338} The [sqlite3_reset(S)] interface does not change the values
-** of any [sqlite3_bind_blob|bindings] on the [prepared statement] S.
-*/
-SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt);
-
-/*
-** CAPI3REF: Create Or Redefine SQL Functions {H16100} <S20200>
-** KEYWORDS: {function creation routines}
-** KEYWORDS: {application-defined SQL function}
-** KEYWORDS: {application-defined SQL functions}
-**
-** These two functions (collectively known as "function creation routines")
-** are used to add SQL functions or aggregates or to redefine the behavior
-** of existing SQL functions or aggregates. The only difference between the
-** two is that the second parameter, the name of the (scalar) function or
-** aggregate, is encoded in UTF-8 for sqlite3_create_function() and UTF-16
-** for sqlite3_create_function16().
-**
-** The first parameter is the [database connection] to which the SQL
-** function is to be added. If a single program uses more than one database
-** connection internally, then SQL functions must be added individually to
-** each database connection.
-**
-** The second parameter is the name of the SQL function to be created or
-** redefined. The length of the name is limited to 255 bytes, exclusive of
-** the zero-terminator. Note that the name length limit is in bytes, not
-** characters. Any attempt to create a function with a longer name
-** will result in [SQLITE_ERROR] being returned.
-**
-** The third parameter (nArg)
-** is the number of arguments that the SQL function or
-** aggregate takes. If this parameter is -1, then the SQL function or
-** aggregate may take any number of arguments between 0 and the limit
-** set by [sqlite3_limit]([SQLITE_LIMIT_FUNCTION_ARG]). If the third
-** parameter is less than -1 or greater than 127 then the behavior is
-** undefined.
-**
-** The fourth parameter, eTextRep, specifies what
-** [SQLITE_UTF8 | text encoding] this SQL function prefers for
-** its parameters. Any SQL function implementation should be able to work
-** work with UTF-8, UTF-16le, or UTF-16be. But some implementations may be
-** more efficient with one encoding than another. An application may
-** invoke sqlite3_create_function() or sqlite3_create_function16() multiple
-** times with the same function but with different values of eTextRep.
-** When multiple implementations of the same function are available, SQLite
-** will pick the one that involves the least amount of data conversion.
-** If there is only a single implementation which does not care what text
-** encoding is used, then the fourth argument should be [SQLITE_ANY].
-**
-** The fifth parameter is an arbitrary pointer. The implementation of the
-** function can gain access to this pointer using [sqlite3_user_data()].
-**
-** The seventh, eighth and ninth parameters, xFunc, xStep and xFinal, are
-** pointers to C-language functions that implement the SQL function or
-** aggregate. A scalar SQL function requires an implementation of the xFunc
-** callback only, NULL pointers should be passed as the xStep and xFinal
-** parameters. An aggregate SQL function requires an implementation of xStep
-** and xFinal and NULL should be passed for xFunc. To delete an existing
-** SQL function or aggregate, pass NULL for all three function callbacks.
-**
-** It is permitted to register multiple implementations of the same
-** functions with the same name but with either differing numbers of
-** arguments or differing preferred text encodings. SQLite will use
-** the implementation that most closely matches the way in which the
-** SQL function is used. A function implementation with a non-negative
-** nArg parameter is a better match than a function implementation with
-** a negative nArg. A function where the preferred text encoding
-** matches the database encoding is a better
-** match than a function where the encoding is different.
-** A function where the encoding difference is between UTF16le and UTF16be
-** is a closer match than a function where the encoding difference is
-** between UTF8 and UTF16.
-**
-** Built-in functions may be overloaded by new application-defined functions.
-** The first application-defined function with a given name overrides all
-** built-in functions in the same [database connection] with the same name.
-** Subsequent application-defined functions of the same name only override
-** prior application-defined functions that are an exact match for the
-** number of parameters and preferred encoding.
-**
-** An application-defined function is permitted to call other
-** SQLite interfaces. However, such calls must not
-** close the database connection nor finalize or reset the prepared
-** statement in which the function is running.
-**
-** Requirements:
-** [H16103] [H16106] [H16109] [H16112] [H16118] [H16121] [H16127]
-** [H16130] [H16133] [H16136] [H16139] [H16142]
-*/
-SQLITE_API int sqlite3_create_function(
- sqlite3 *db,
- const char *zFunctionName,
- int nArg,
- int eTextRep,
- void *pApp,
- void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
- void (*xStep)(sqlite3_context*,int,sqlite3_value**),
- void (*xFinal)(sqlite3_context*)
-);
-SQLITE_API int sqlite3_create_function16(
- sqlite3 *db,
- const void *zFunctionName,
- int nArg,
- int eTextRep,
- void *pApp,
- void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
- void (*xStep)(sqlite3_context*,int,sqlite3_value**),
- void (*xFinal)(sqlite3_context*)
-);
-
-/*
-** CAPI3REF: Text Encodings {H10267} <S50200> <H16100>
-**
-** These constant define integer codes that represent the various
-** text encodings supported by SQLite.
-*/
-#define SQLITE_UTF8 1
-#define SQLITE_UTF16LE 2
-#define SQLITE_UTF16BE 3
-#define SQLITE_UTF16 4 /* Use native byte order */
-#define SQLITE_ANY 5 /* sqlite3_create_function only */
-#define SQLITE_UTF16_ALIGNED 8 /* sqlite3_create_collation only */
-
-/*
-** CAPI3REF: Deprecated Functions
-** DEPRECATED
-**
-** These functions are [deprecated]. In order to maintain
-** backwards compatibility with older code, these functions continue
-** to be supported. However, new applications should avoid
-** the use of these functions. To help encourage people to avoid
-** using these functions, we are not going to tell you what they do.
-*/
-#ifndef SQLITE_OMIT_DEPRECATED
-SQLITE_API SQLITE_DEPRECATED int sqlite3_aggregate_count(sqlite3_context*);
-SQLITE_API SQLITE_DEPRECATED int sqlite3_expired(sqlite3_stmt*);
-SQLITE_API SQLITE_DEPRECATED int sqlite3_transfer_bindings(sqlite3_stmt*, sqlite3_stmt*);
-SQLITE_API SQLITE_DEPRECATED int sqlite3_global_recover(void);
-SQLITE_API SQLITE_DEPRECATED void sqlite3_thread_cleanup(void);
-SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int),void*,sqlite3_int64);
-#endif
-
-/*
-** CAPI3REF: Obtaining SQL Function Parameter Values {H15100} <S20200>
-**
-** The C-language implementation of SQL functions and aggregates uses
-** this set of interface routines to access the parameter values on
-** the function or aggregate.
-**
-** The xFunc (for scalar functions) or xStep (for aggregates) parameters
-** to [sqlite3_create_function()] and [sqlite3_create_function16()]
-** define callbacks that implement the SQL functions and aggregates.
-** The 4th parameter to these callbacks is an array of pointers to
-** [protected sqlite3_value] objects. There is one [sqlite3_value] object for
-** each parameter to the SQL function. These routines are used to
-** extract values from the [sqlite3_value] objects.
-**
-** These routines work only with [protected sqlite3_value] objects.
-** Any attempt to use these routines on an [unprotected sqlite3_value]
-** object results in undefined behavior.
-**
-** These routines work just like the corresponding [column access functions]
-** except that these routines take a single [protected sqlite3_value] object
-** pointer instead of a [sqlite3_stmt*] pointer and an integer column number.
-**
-** The sqlite3_value_text16() interface extracts a UTF-16 string
-** in the native byte-order of the host machine. The
-** sqlite3_value_text16be() and sqlite3_value_text16le() interfaces
-** extract UTF-16 strings as big-endian and little-endian respectively.
-**
-** The sqlite3_value_numeric_type() interface attempts to apply
-** numeric affinity to the value. This means that an attempt is
-** made to convert the value to an integer or floating point. If
-** such a conversion is possible without loss of information (in other
-** words, if the value is a string that looks like a number)
-** then the conversion is performed. Otherwise no conversion occurs.
-** The [SQLITE_INTEGER | datatype] after conversion is returned.
-**
-** Please pay particular attention to the fact that the pointer returned
-** from [sqlite3_value_blob()], [sqlite3_value_text()], or
-** [sqlite3_value_text16()] can be invalidated by a subsequent call to
-** [sqlite3_value_bytes()], [sqlite3_value_bytes16()], [sqlite3_value_text()],
-** or [sqlite3_value_text16()].
-**
-** These routines must be called from the same thread as
-** the SQL function that supplied the [sqlite3_value*] parameters.
-**
-** Requirements:
-** [H15103] [H15106] [H15109] [H15112] [H15115] [H15118] [H15121] [H15124]
-** [H15127] [H15130] [H15133] [H15136]
-*/
-SQLITE_API const void *sqlite3_value_blob(sqlite3_value*);
-SQLITE_API int sqlite3_value_bytes(sqlite3_value*);
-SQLITE_API int sqlite3_value_bytes16(sqlite3_value*);
-SQLITE_API double sqlite3_value_double(sqlite3_value*);
-SQLITE_API int sqlite3_value_int(sqlite3_value*);
-SQLITE_API sqlite3_int64 sqlite3_value_int64(sqlite3_value*);
-SQLITE_API const unsigned char *sqlite3_value_text(sqlite3_value*);
-SQLITE_API const void *sqlite3_value_text16(sqlite3_value*);
-SQLITE_API const void *sqlite3_value_text16le(sqlite3_value*);
-SQLITE_API const void *sqlite3_value_text16be(sqlite3_value*);
-SQLITE_API int sqlite3_value_type(sqlite3_value*);
-SQLITE_API int sqlite3_value_numeric_type(sqlite3_value*);
-
-/*
-** CAPI3REF: Obtain Aggregate Function Context {H16210} <S20200>
-**
-** The implementation of aggregate SQL functions use this routine to allocate
-** a structure for storing their state.
-**
-** The first time the sqlite3_aggregate_context() routine is called for a
-** particular aggregate, SQLite allocates nBytes of memory, zeroes out that
-** memory, and returns a pointer to it. On second and subsequent calls to
-** sqlite3_aggregate_context() for the same aggregate function index,
-** the same buffer is returned. The implementation of the aggregate can use
-** the returned buffer to accumulate data.
-**
-** SQLite automatically frees the allocated buffer when the aggregate
-** query concludes.
-**
-** The first parameter should be a copy of the
-** [sqlite3_context | SQL function context] that is the first parameter
-** to the callback routine that implements the aggregate function.
-**
-** This routine must be called from the same thread in which
-** the aggregate SQL function is running.
-**
-** Requirements:
-** [H16211] [H16213] [H16215] [H16217]
-*/
-SQLITE_API void *sqlite3_aggregate_context(sqlite3_context*, int nBytes);
-
-/*
-** CAPI3REF: User Data For Functions {H16240} <S20200>
-**
-** The sqlite3_user_data() interface returns a copy of
-** the pointer that was the pUserData parameter (the 5th parameter)
-** of the [sqlite3_create_function()]
-** and [sqlite3_create_function16()] routines that originally
-** registered the application defined function. {END}
-**
-** This routine must be called from the same thread in which
-** the application-defined function is running.
-**
-** Requirements:
-** [H16243]
-*/
-SQLITE_API void *sqlite3_user_data(sqlite3_context*);
-
-/*
-** CAPI3REF: Database Connection For Functions {H16250} <S60600><S20200>
-**
-** The sqlite3_context_db_handle() interface returns a copy of
-** the pointer to the [database connection] (the 1st parameter)
-** of the [sqlite3_create_function()]
-** and [sqlite3_create_function16()] routines that originally
-** registered the application defined function.
-**
-** Requirements:
-** [H16253]
-*/
-SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*);
-
-/*
-** CAPI3REF: Function Auxiliary Data {H16270} <S20200>
-**
-** The following two functions may be used by scalar SQL functions to
-** associate metadata with argument values. If the same value is passed to
-** multiple invocations of the same SQL function during query execution, under
-** some circumstances the associated metadata may be preserved. This may
-** be used, for example, to add a regular-expression matching scalar
-** function. The compiled version of the regular expression is stored as
-** metadata associated with the SQL value passed as the regular expression
-** pattern. The compiled regular expression can be reused on multiple
-** invocations of the same function so that the original pattern string
-** does not need to be recompiled on each invocation.
-**
-** The sqlite3_get_auxdata() interface returns a pointer to the metadata
-** associated by the sqlite3_set_auxdata() function with the Nth argument
-** value to the application-defined function. If no metadata has been ever
-** been set for the Nth argument of the function, or if the corresponding
-** function parameter has changed since the meta-data was set,
-** then sqlite3_get_auxdata() returns a NULL pointer.
-**
-** The sqlite3_set_auxdata() interface saves the metadata
-** pointed to by its 3rd parameter as the metadata for the N-th
-** argument of the application-defined function. Subsequent
-** calls to sqlite3_get_auxdata() might return this data, if it has
-** not been destroyed.
-** If it is not NULL, SQLite will invoke the destructor
-** function given by the 4th parameter to sqlite3_set_auxdata() on
-** the metadata when the corresponding function parameter changes
-** or when the SQL statement completes, whichever comes first.
-**
-** SQLite is free to call the destructor and drop metadata on any
-** parameter of any function at any time. The only guarantee is that
-** the destructor will be called before the metadata is dropped.
-**
-** In practice, metadata is preserved between function calls for
-** expressions that are constant at compile time. This includes literal
-** values and SQL variables.
-**
-** These routines must be called from the same thread in which
-** the SQL function is running.
-**
-** Requirements:
-** [H16272] [H16274] [H16276] [H16277] [H16278] [H16279]
-*/
-SQLITE_API void *sqlite3_get_auxdata(sqlite3_context*, int N);
-SQLITE_API void sqlite3_set_auxdata(sqlite3_context*, int N, void*, void (*)(void*));
-
-
-/*
-** CAPI3REF: Constants Defining Special Destructor Behavior {H10280} <S30100>
-**
-** These are special values for the destructor that is passed in as the
-** final argument to routines like [sqlite3_result_blob()]. If the destructor
-** argument is SQLITE_STATIC, it means that the content pointer is constant
-** and will never change. It does not need to be destroyed. The
-** SQLITE_TRANSIENT value means that the content will likely change in
-** the near future and that SQLite should make its own private copy of
-** the content before returning.
-**
-** The typedef is necessary to work around problems in certain
-** C++ compilers. See ticket #2191.
-*/
-typedef void (*sqlite3_destructor_type)(void*);
-#define SQLITE_STATIC ((sqlite3_destructor_type)0)
-#define SQLITE_TRANSIENT ((sqlite3_destructor_type)-1)
-
-/*
-** CAPI3REF: Setting The Result Of An SQL Function {H16400} <S20200>
-**
-** These routines are used by the xFunc or xFinal callbacks that
-** implement SQL functions and aggregates. See
-** [sqlite3_create_function()] and [sqlite3_create_function16()]
-** for additional information.
-**
-** These functions work very much like the [parameter binding] family of
-** functions used to bind values to host parameters in prepared statements.
-** Refer to the [SQL parameter] documentation for additional information.
-**
-** The sqlite3_result_blob() interface sets the result from
-** an application-defined function to be the BLOB whose content is pointed
-** to by the second parameter and which is N bytes long where N is the
-** third parameter.
-**
-** The sqlite3_result_zeroblob() interfaces set the result of
-** the application-defined function to be a BLOB containing all zero
-** bytes and N bytes in size, where N is the value of the 2nd parameter.
-**
-** The sqlite3_result_double() interface sets the result from
-** an application-defined function to be a floating point value specified
-** by its 2nd argument.
-**
-** The sqlite3_result_error() and sqlite3_result_error16() functions
-** cause the implemented SQL function to throw an exception.
-** SQLite uses the string pointed to by the
-** 2nd parameter of sqlite3_result_error() or sqlite3_result_error16()
-** as the text of an error message. SQLite interprets the error
-** message string from sqlite3_result_error() as UTF-8. SQLite
-** interprets the string from sqlite3_result_error16() as UTF-16 in native
-** byte order. If the third parameter to sqlite3_result_error()
-** or sqlite3_result_error16() is negative then SQLite takes as the error
-** message all text up through the first zero character.
-** If the third parameter to sqlite3_result_error() or
-** sqlite3_result_error16() is non-negative then SQLite takes that many
-** bytes (not characters) from the 2nd parameter as the error message.
-** The sqlite3_result_error() and sqlite3_result_error16()
-** routines make a private copy of the error message text before
-** they return. Hence, the calling function can deallocate or
-** modify the text after they return without harm.
-** The sqlite3_result_error_code() function changes the error code
-** returned by SQLite as a result of an error in a function. By default,
-** the error code is SQLITE_ERROR. A subsequent call to sqlite3_result_error()
-** or sqlite3_result_error16() resets the error code to SQLITE_ERROR.
-**
-** The sqlite3_result_toobig() interface causes SQLite to throw an error
-** indicating that a string or BLOB is to long to represent.
-**
-** The sqlite3_result_nomem() interface causes SQLite to throw an error
-** indicating that a memory allocation failed.
-**
-** The sqlite3_result_int() interface sets the return value
-** of the application-defined function to be the 32-bit signed integer
-** value given in the 2nd argument.
-** The sqlite3_result_int64() interface sets the return value
-** of the application-defined function to be the 64-bit signed integer
-** value given in the 2nd argument.
-**
-** The sqlite3_result_null() interface sets the return value
-** of the application-defined function to be NULL.
-**
-** The sqlite3_result_text(), sqlite3_result_text16(),
-** sqlite3_result_text16le(), and sqlite3_result_text16be() interfaces
-** set the return value of the application-defined function to be
-** a text string which is represented as UTF-8, UTF-16 native byte order,
-** UTF-16 little endian, or UTF-16 big endian, respectively.
-** SQLite takes the text result from the application from
-** the 2nd parameter of the sqlite3_result_text* interfaces.
-** If the 3rd parameter to the sqlite3_result_text* interfaces
-** is negative, then SQLite takes result text from the 2nd parameter
-** through the first zero character.
-** If the 3rd parameter to the sqlite3_result_text* interfaces
-** is non-negative, then as many bytes (not characters) of the text
-** pointed to by the 2nd parameter are taken as the application-defined
-** function result.
-** If the 4th parameter to the sqlite3_result_text* interfaces
-** or sqlite3_result_blob is a non-NULL pointer, then SQLite calls that
-** function as the destructor on the text or BLOB result when it has
-** finished using that result.
-** If the 4th parameter to the sqlite3_result_text* interfaces or to
-** sqlite3_result_blob is the special constant SQLITE_STATIC, then SQLite
-** assumes that the text or BLOB result is in constant space and does not
-** copy the content of the parameter nor call a destructor on the content
-** when it has finished using that result.
-** If the 4th parameter to the sqlite3_result_text* interfaces
-** or sqlite3_result_blob is the special constant SQLITE_TRANSIENT
-** then SQLite makes a copy of the result into space obtained from
-** from [sqlite3_malloc()] before it returns.
-**
-** The sqlite3_result_value() interface sets the result of
-** the application-defined function to be a copy the
-** [unprotected sqlite3_value] object specified by the 2nd parameter. The
-** sqlite3_result_value() interface makes a copy of the [sqlite3_value]
-** so that the [sqlite3_value] specified in the parameter may change or
-** be deallocated after sqlite3_result_value() returns without harm.
-** A [protected sqlite3_value] object may always be used where an
-** [unprotected sqlite3_value] object is required, so either
-** kind of [sqlite3_value] object can be used with this interface.
-**
-** If these routines are called from within the different thread
-** than the one containing the application-defined function that received
-** the [sqlite3_context] pointer, the results are undefined.
-**
-** Requirements:
-** [H16403] [H16406] [H16409] [H16412] [H16415] [H16418] [H16421] [H16424]
-** [H16427] [H16430] [H16433] [H16436] [H16439] [H16442] [H16445] [H16448]
-** [H16451] [H16454] [H16457] [H16460] [H16463]
-*/
-SQLITE_API void sqlite3_result_blob(sqlite3_context*, const void*, int, void(*)(void*));
-SQLITE_API void sqlite3_result_double(sqlite3_context*, double);
-SQLITE_API void sqlite3_result_error(sqlite3_context*, const char*, int);
-SQLITE_API void sqlite3_result_error16(sqlite3_context*, const void*, int);
-SQLITE_API void sqlite3_result_error_toobig(sqlite3_context*);
-SQLITE_API void sqlite3_result_error_nomem(sqlite3_context*);
-SQLITE_API void sqlite3_result_error_code(sqlite3_context*, int);
-SQLITE_API void sqlite3_result_int(sqlite3_context*, int);
-SQLITE_API void sqlite3_result_int64(sqlite3_context*, sqlite3_int64);
-SQLITE_API void sqlite3_result_null(sqlite3_context*);
-SQLITE_API void sqlite3_result_text(sqlite3_context*, const char*, int, void(*)(void*));
-SQLITE_API void sqlite3_result_text16(sqlite3_context*, const void*, int, void(*)(void*));
-SQLITE_API void sqlite3_result_text16le(sqlite3_context*, const void*, int,void(*)(void*));
-SQLITE_API void sqlite3_result_text16be(sqlite3_context*, const void*, int,void(*)(void*));
-SQLITE_API void sqlite3_result_value(sqlite3_context*, sqlite3_value*);
-SQLITE_API void sqlite3_result_zeroblob(sqlite3_context*, int n);
-
-/*
-** CAPI3REF: Define New Collating Sequences {H16600} <S20300>
-**
-** These functions are used to add new collation sequences to the
-** [database connection] specified as the first argument.
-**
-** The name of the new collation sequence is specified as a UTF-8 string
-** for sqlite3_create_collation() and sqlite3_create_collation_v2()
-** and a UTF-16 string for sqlite3_create_collation16(). In all cases
-** the name is passed as the second function argument.
-**
-** The third argument may be one of the constants [SQLITE_UTF8],
-** [SQLITE_UTF16LE], or [SQLITE_UTF16BE], indicating that the user-supplied
-** routine expects to be passed pointers to strings encoded using UTF-8,
-** UTF-16 little-endian, or UTF-16 big-endian, respectively. The
-** third argument might also be [SQLITE_UTF16] to indicate that the routine
-** expects pointers to be UTF-16 strings in the native byte order, or the
-** argument can be [SQLITE_UTF16_ALIGNED] if the
-** the routine expects pointers to 16-bit word aligned strings
-** of UTF-16 in the native byte order.
-**
-** A pointer to the user supplied routine must be passed as the fifth
-** argument. If it is NULL, this is the same as deleting the collation
-** sequence (so that SQLite cannot call it anymore).
-** Each time the application supplied function is invoked, it is passed
-** as its first parameter a copy of the void* passed as the fourth argument
-** to sqlite3_create_collation() or sqlite3_create_collation16().
-**
-** The remaining arguments to the application-supplied routine are two strings,
-** each represented by a (length, data) pair and encoded in the encoding
-** that was passed as the third argument when the collation sequence was
-** registered. {END} The application defined collation routine should
-** return negative, zero or positive if the first string is less than,
-** equal to, or greater than the second string. i.e. (STRING1 - STRING2).
-**
-** The sqlite3_create_collation_v2() works like sqlite3_create_collation()
-** except that it takes an extra argument which is a destructor for
-** the collation. The destructor is called when the collation is
-** destroyed and is passed a copy of the fourth parameter void* pointer
-** of the sqlite3_create_collation_v2().
-** Collations are destroyed when they are overridden by later calls to the
-** collation creation functions or when the [database connection] is closed
-** using [sqlite3_close()].
-**
-** See also: [sqlite3_collation_needed()] and [sqlite3_collation_needed16()].
-**
-** Requirements:
-** [H16603] [H16604] [H16606] [H16609] [H16612] [H16615] [H16618] [H16621]
-** [H16624] [H16627] [H16630]
-*/
-SQLITE_API int sqlite3_create_collation(
- sqlite3*,
- const char *zName,
- int eTextRep,
- void*,
- int(*xCompare)(void*,int,const void*,int,const void*)
-);
-SQLITE_API int sqlite3_create_collation_v2(
- sqlite3*,
- const char *zName,
- int eTextRep,
- void*,
- int(*xCompare)(void*,int,const void*,int,const void*),
- void(*xDestroy)(void*)
-);
-SQLITE_API int sqlite3_create_collation16(
- sqlite3*,
- const void *zName,
- int eTextRep,
- void*,
- int(*xCompare)(void*,int,const void*,int,const void*)
-);
-
-/*
-** CAPI3REF: Collation Needed Callbacks {H16700} <S20300>
-**
-** To avoid having to register all collation sequences before a database
-** can be used, a single callback function may be registered with the
-** [database connection] to be called whenever an undefined collation
-** sequence is required.
-**
-** If the function is registered using the sqlite3_collation_needed() API,
-** then it is passed the names of undefined collation sequences as strings
-** encoded in UTF-8. {H16703} If sqlite3_collation_needed16() is used,
-** the names are passed as UTF-16 in machine native byte order.
-** A call to either function replaces any existing callback.
-**
-** When the callback is invoked, the first argument passed is a copy
-** of the second argument to sqlite3_collation_needed() or
-** sqlite3_collation_needed16(). The second argument is the database
-** connection. The third argument is one of [SQLITE_UTF8], [SQLITE_UTF16BE],
-** or [SQLITE_UTF16LE], indicating the most desirable form of the collation
-** sequence function required. The fourth parameter is the name of the
-** required collation sequence.
-**
-** The callback function should register the desired collation using
-** [sqlite3_create_collation()], [sqlite3_create_collation16()], or
-** [sqlite3_create_collation_v2()].
-**
-** Requirements:
-** [H16702] [H16704] [H16706]
-*/
-SQLITE_API int sqlite3_collation_needed(
- sqlite3*,
- void*,
- void(*)(void*,sqlite3*,int eTextRep,const char*)
-);
-SQLITE_API int sqlite3_collation_needed16(
- sqlite3*,
- void*,
- void(*)(void*,sqlite3*,int eTextRep,const void*)
-);
-
-/*
-** Specify the key for an encrypted database. This routine should be
-** called right after sqlite3_open().
-**
-** The code to implement this API is not available in the public release
-** of SQLite.
-*/
-SQLITE_API int sqlite3_key(
- sqlite3 *db, /* Database to be rekeyed */
- const void *pKey, int nKey /* The key */
-);
-
-/*
-** Change the key on an open database. If the current database is not
-** encrypted, this routine will encrypt it. If pNew==0 or nNew==0, the
-** database is decrypted.
-**
-** The code to implement this API is not available in the public release
-** of SQLite.
-*/
-SQLITE_API int sqlite3_rekey(
- sqlite3 *db, /* Database to be rekeyed */
- const void *pKey, int nKey /* The new key */
-);
-
-/*
-** CAPI3REF: Suspend Execution For A Short Time {H10530} <S40410>
-**
-** The sqlite3_sleep() function causes the current thread to suspend execution
-** for at least a number of milliseconds specified in its parameter.
-**
-** If the operating system does not support sleep requests with
-** millisecond time resolution, then the time will be rounded up to
-** the nearest second. The number of milliseconds of sleep actually
-** requested from the operating system is returned.
-**
-** SQLite implements this interface by calling the xSleep()
-** method of the default [sqlite3_vfs] object.
-**
-** Requirements: [H10533] [H10536]
-*/
-SQLITE_API int sqlite3_sleep(int);
-
-/*
-** CAPI3REF: Name Of The Folder Holding Temporary Files {H10310} <S20000>
-**
-** If this global variable is made to point to a string which is
-** the name of a folder (a.k.a. directory), then all temporary files
-** created by SQLite will be placed in that directory. If this variable
-** is a NULL pointer, then SQLite performs a search for an appropriate
-** temporary file directory.
-**
-** It is not safe to read or modify this variable in more than one
-** thread at a time. It is not safe to read or modify this variable
-** if a [database connection] is being used at the same time in a separate
-** thread.
-** It is intended that this variable be set once
-** as part of process initialization and before any SQLite interface
-** routines have been called and that this variable remain unchanged
-** thereafter.
-**
-** The [temp_store_directory pragma] may modify this variable and cause
-** it to point to memory obtained from [sqlite3_malloc]. Furthermore,
-** the [temp_store_directory pragma] always assumes that any string
-** that this variable points to is held in memory obtained from
-** [sqlite3_malloc] and the pragma may attempt to free that memory
-** using [sqlite3_free].
-** Hence, if this variable is modified directly, either it should be
-** made NULL or made to point to memory obtained from [sqlite3_malloc]
-** or else the use of the [temp_store_directory pragma] should be avoided.
-*/
-SQLITE_API SQLITE_EXTERN char *sqlite3_temp_directory;
-
-/*
-** CAPI3REF: Test For Auto-Commit Mode {H12930} <S60200>
-** KEYWORDS: {autocommit mode}
-**
-** The sqlite3_get_autocommit() interface returns non-zero or
-** zero if the given database connection is or is not in autocommit mode,
-** respectively. Autocommit mode is on by default.
-** Autocommit mode is disabled by a [BEGIN] statement.
-** Autocommit mode is re-enabled by a [COMMIT] or [ROLLBACK].
-**
-** If certain kinds of errors occur on a statement within a multi-statement
-** transaction (errors including [SQLITE_FULL], [SQLITE_IOERR],
-** [SQLITE_NOMEM], [SQLITE_BUSY], and [SQLITE_INTERRUPT]) then the
-** transaction might be rolled back automatically. The only way to
-** find out whether SQLite automatically rolled back the transaction after
-** an error is to use this function.
-**
-** If another thread changes the autocommit status of the database
-** connection while this routine is running, then the return value
-** is undefined.
-**
-** Requirements: [H12931] [H12932] [H12933] [H12934]
-*/
-SQLITE_API int sqlite3_get_autocommit(sqlite3*);
-
-/*
-** CAPI3REF: Find The Database Handle Of A Prepared Statement {H13120} <S60600>
-**
-** The sqlite3_db_handle interface returns the [database connection] handle
-** to which a [prepared statement] belongs. The [database connection]
-** returned by sqlite3_db_handle is the same [database connection] that was the first argument
-** to the [sqlite3_prepare_v2()] call (or its variants) that was used to
-** create the statement in the first place.
-**
-** Requirements: [H13123]
-*/
-SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt*);
-
-/*
-** CAPI3REF: Find the next prepared statement {H13140} <S60600>
-**
-** This interface returns a pointer to the next [prepared statement] after
-** pStmt associated with the [database connection] pDb. If pStmt is NULL
-** then this interface returns a pointer to the first prepared statement
-** associated with the database connection pDb. If no prepared statement
-** satisfies the conditions of this routine, it returns NULL.
-**
-** The [database connection] pointer D in a call to
-** [sqlite3_next_stmt(D,S)] must refer to an open database
-** connection and in particular must not be a NULL pointer.
-**
-** Requirements: [H13143] [H13146] [H13149] [H13152]
-*/
-SQLITE_API sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt);
-
-/*
-** CAPI3REF: Commit And Rollback Notification Callbacks {H12950} <S60400>
-**
-** The sqlite3_commit_hook() interface registers a callback
-** function to be invoked whenever a transaction is [COMMIT | committed].
-** Any callback set by a previous call to sqlite3_commit_hook()
-** for the same database connection is overridden.
-** The sqlite3_rollback_hook() interface registers a callback
-** function to be invoked whenever a transaction is [ROLLBACK | rolled back].
-** Any callback set by a previous call to sqlite3_commit_hook()
-** for the same database connection is overridden.
-** The pArg argument is passed through to the callback.
-** If the callback on a commit hook function returns non-zero,
-** then the commit is converted into a rollback.
-**
-** If another function was previously registered, its
-** pArg value is returned. Otherwise NULL is returned.
-**
-** 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.
-**
-** Registering a NULL function disables the callback.
-**
-** When the commit hook callback routine returns zero, the [COMMIT]
-** operation is allowed to continue normally. If the commit hook
-** returns non-zero, then the [COMMIT] is converted into a [ROLLBACK].
-** The rollback hook is invoked on a rollback that results from a commit
-** hook returning non-zero, just as it would be with any other rollback.
-**
-** For the purposes of this API, a transaction is said to have been
-** rolled back if an explicit "ROLLBACK" statement is executed, or
-** an error or constraint causes an implicit rollback to occur.
-** The rollback callback is not invoked if a transaction is
-** automatically rolled back because the database connection is closed.
-** The rollback callback is not invoked if a transaction is
-** rolled back because a commit callback returned non-zero.
-** <todo> Check on this </todo>
-**
-** See also the [sqlite3_update_hook()] interface.
-**
-** Requirements:
-** [H12951] [H12952] [H12953] [H12954] [H12955]
-** [H12961] [H12962] [H12963] [H12964]
-*/
-SQLITE_API void *sqlite3_commit_hook(sqlite3*, int(*)(void*), void*);
-SQLITE_API void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*);
-
-/*
-** CAPI3REF: Data Change Notification Callbacks {H12970} <S60400>
-**
-** The sqlite3_update_hook() interface registers a callback function
-** with the [database connection] identified by the first argument
-** to be invoked whenever a row is updated, inserted or deleted.
-** Any callback set by a previous call to this function
-** for the same database connection is overridden.
-**
-** The second argument is a pointer to the function to invoke when a
-** row is updated, inserted or deleted.
-** The first argument to the callback is a copy of the third argument
-** to sqlite3_update_hook().
-** The second callback argument is one of [SQLITE_INSERT], [SQLITE_DELETE],
-** or [SQLITE_UPDATE], depending on the operation that caused the callback
-** to be invoked.
-** The third and fourth arguments to the callback contain pointers to the
-** database and table name containing the affected row.
-** The final callback parameter is the [rowid] of the row.
-** In the case of an update, this is the [rowid] after the update takes place.
-**
-** The update hook is not invoked when internal system tables are
-** modified (i.e. sqlite_master and sqlite_sequence).
-**
-** In the current implementation, the update hook
-** is not invoked when duplication rows are deleted because of an
-** [ON CONFLICT | ON CONFLICT REPLACE] clause. Nor is the update hook
-** invoked when rows are deleted using the [truncate optimization].
-** The exceptions defined in this paragraph might change in a future
-** release of SQLite.
-**
-** The update hook implementation must not do anything that will modify
-** the database connection that invoked the update hook. Any actions
-** to modify the database connection must be deferred until after the
-** completion of the [sqlite3_step()] call that triggered the update hook.
-** Note that [sqlite3_prepare_v2()] and [sqlite3_step()] both modify their
-** database connections for the meaning of "modify" in this paragraph.
-**
-** If another function was previously registered, its pArg value
-** is returned. Otherwise NULL is returned.
-**
-** See also the [sqlite3_commit_hook()] and [sqlite3_rollback_hook()]
-** interfaces.
-**
-** Requirements:
-** [H12971] [H12973] [H12975] [H12977] [H12979] [H12981] [H12983] [H12986]
-*/
-SQLITE_API void *sqlite3_update_hook(
- sqlite3*,
- void(*)(void *,int ,char const *,char const *,sqlite3_int64),
- void*
-);
-
-/*
-** CAPI3REF: Enable Or Disable Shared Pager Cache {H10330} <S30900>
-** KEYWORDS: {shared cache}
-**
-** This routine enables or disables the sharing of the database cache
-** and schema data structures between [database connection | connections]
-** to the same database. Sharing is enabled if the argument is true
-** and disabled if the argument is false.
-**
-** Cache sharing is enabled and disabled for an entire process.
-** This is a change as of SQLite version 3.5.0. In prior versions of SQLite,
-** sharing was enabled or disabled for each thread separately.
-**
-** The cache sharing mode set by this interface effects all subsequent
-** calls to [sqlite3_open()], [sqlite3_open_v2()], and [sqlite3_open16()].
-** Existing database connections continue use the sharing mode
-** that was in effect at the time they were opened.
-**
-** Virtual tables cannot be used with a shared cache. When shared
-** cache is enabled, the [sqlite3_create_module()] API used to register
-** virtual tables will always return an error.
-**
-** This routine returns [SQLITE_OK] if shared cache was enabled or disabled
-** successfully. An [error code] is returned otherwise.
-**
-** Shared cache is disabled by default. But this might change in
-** future releases of SQLite. Applications that care about shared
-** cache setting should set it explicitly.
-**
-** See Also: [SQLite Shared-Cache Mode]
-**
-** Requirements: [H10331] [H10336] [H10337] [H10339]
-*/
-SQLITE_API int sqlite3_enable_shared_cache(int);
-
-/*
-** CAPI3REF: Attempt To Free Heap Memory {H17340} <S30220>
-**
-** The sqlite3_release_memory() interface attempts to free N bytes
-** of heap memory by deallocating non-essential memory allocations
-** held by the database library. {END} Memory used to cache database
-** pages to improve performance is an example of non-essential memory.
-** sqlite3_release_memory() returns the number of bytes actually freed,
-** which might be more or less than the amount requested.
-**
-** Requirements: [H17341] [H17342]
-*/
-SQLITE_API int sqlite3_release_memory(int);
-
-/*
-** CAPI3REF: Impose A Limit On Heap Size {H17350} <S30220>
-**
-** The sqlite3_soft_heap_limit() interface places a "soft" limit
-** on the amount of heap memory that may be allocated by SQLite.
-** If an internal allocation is requested that would exceed the
-** soft heap limit, [sqlite3_release_memory()] is invoked one or
-** more times to free up some space before the allocation is performed.
-**
-** The limit is called "soft", because if [sqlite3_release_memory()]
-** cannot free sufficient memory to prevent the limit from being exceeded,
-** the memory is allocated anyway and the current operation proceeds.
-**
-** A negative or zero value for N means that there is no soft heap limit and
-** [sqlite3_release_memory()] will only be called when memory is exhausted.
-** The default value for the soft heap limit is zero.
-**
-** SQLite makes a best effort to honor the soft heap limit.
-** But if the soft heap limit cannot be honored, execution will
-** continue without error or notification. This is why the limit is
-** called a "soft" limit. It is advisory only.
-**
-** Prior to SQLite version 3.5.0, this routine only constrained the memory
-** allocated by a single thread - the same thread in which this routine
-** runs. Beginning with SQLite version 3.5.0, the soft heap limit is
-** applied to all threads. The value specified for the soft heap limit
-** is an upper bound on the total memory allocation for all threads. In
-** version 3.5.0 there is no mechanism for limiting the heap usage for
-** individual threads.
-**
-** Requirements:
-** [H16351] [H16352] [H16353] [H16354] [H16355] [H16358]
-*/
-SQLITE_API void sqlite3_soft_heap_limit(int);
-
-/*
-** CAPI3REF: Extract Metadata About A Column Of A Table {H12850} <S60300>
-**
-** This routine returns metadata about a specific column of a specific
-** database table accessible using the [database connection] handle
-** passed as the first function argument.
-**
-** The column is identified by the second, third and fourth parameters to
-** this function. The second parameter is either the name of the database
-** (i.e. "main", "temp" or an attached database) containing the specified
-** table or NULL. If it is NULL, then all attached databases are searched
-** for the table using the same algorithm used by the database engine to
-** resolve unqualified table references.
-**
-** The third and fourth parameters to this function are the table and column
-** name of the desired column, respectively. Neither of these parameters
-** may be NULL.
-**
-** Metadata is returned by writing to the memory locations passed as the 5th
-** and subsequent parameters to this function. Any of these arguments may be
-** NULL, in which case the corresponding element of metadata is omitted.
-**
-** <blockquote>
-** <table border="1">
-** <tr><th> Parameter <th> Output<br>Type <th> Description
-**
-** <tr><td> 5th <td> const char* <td> Data type
-** <tr><td> 6th <td> const char* <td> Name of default collation sequence
-** <tr><td> 7th <td> int <td> True if column has a NOT NULL constraint
-** <tr><td> 8th <td> int <td> True if column is part of the PRIMARY KEY
-** <tr><td> 9th <td> int <td> True if column is [AUTOINCREMENT]
-** </table>
-** </blockquote>
-**
-** The memory pointed to by the character pointers returned for the
-** declaration type and collation sequence is valid only until the next
-** call to any SQLite API function.
-**
-** If the specified table is actually a view, an [error code] is returned.
-**
-** If the specified column is "rowid", "oid" or "_rowid_" and an
-** [INTEGER PRIMARY KEY] column has been explicitly declared, then the output
-** parameters are set for the explicitly declared column. If there is no
-** explicitly declared [INTEGER PRIMARY KEY] column, then the output
-** parameters are set as follows:
-**
-** <pre>
-** data type: "INTEGER"
-** collation sequence: "BINARY"
-** not null: 0
-** primary key: 1
-** auto increment: 0
-** </pre>
-**
-** This function may load one or more schemas from database files. If an
-** error occurs during this process, or if the requested table or column
-** cannot be found, an [error code] is returned and an error message left
-** in the [database connection] (to be retrieved using sqlite3_errmsg()).
-**
-** This API is only available if the library was compiled with the
-** [SQLITE_ENABLE_COLUMN_METADATA] C-preprocessor symbol defined.
-*/
-SQLITE_API int sqlite3_table_column_metadata(
- sqlite3 *db, /* Connection handle */
- const char *zDbName, /* Database name or NULL */
- const char *zTableName, /* Table name */
- const char *zColumnName, /* Column name */
- char const **pzDataType, /* OUTPUT: Declared data type */
- char const **pzCollSeq, /* OUTPUT: Collation sequence name */
- int *pNotNull, /* OUTPUT: True if NOT NULL constraint exists */
- int *pPrimaryKey, /* OUTPUT: True if column part of PK */
- int *pAutoinc /* OUTPUT: True if column is auto-increment */
-);
-
-/*
-** CAPI3REF: Load An Extension {H12600} <S20500>
-**
-** This interface loads an SQLite extension library from the named file.
-**
-** {H12601} The sqlite3_load_extension() interface attempts to load an
-** SQLite extension library contained in the file zFile.
-**
-** {H12602} The entry point is zProc.
-**
-** {H12603} zProc may be 0, in which case the name of the entry point
-** defaults to "sqlite3_extension_init".
-**
-** {H12604} The sqlite3_load_extension() interface shall return
-** [SQLITE_OK] on success and [SQLITE_ERROR] if something goes wrong.
-**
-** {H12605} If an error occurs and pzErrMsg is not 0, then the
-** [sqlite3_load_extension()] interface shall attempt to
-** fill *pzErrMsg with error message text stored in memory
-** obtained from [sqlite3_malloc()]. {END} The calling function
-** should free this memory by calling [sqlite3_free()].
-**
-** {H12606} Extension loading must be enabled using
-** [sqlite3_enable_load_extension()] prior to calling this API,
-** otherwise an error will be returned.
-*/
-SQLITE_API int sqlite3_load_extension(
- sqlite3 *db, /* Load the extension into this database connection */
- const char *zFile, /* Name of the shared library containing extension */
- const char *zProc, /* Entry point. Derived from zFile if 0 */
- char **pzErrMsg /* Put error message here if not 0 */
-);
-
-/*
-** CAPI3REF: Enable Or Disable Extension Loading {H12620} <S20500>
-**
-** So as not to open security holes in older applications that are
-** unprepared to deal with extension loading, and as a means of disabling
-** extension loading while evaluating user-entered SQL, the following API
-** is provided to turn the [sqlite3_load_extension()] mechanism on and off.
-**
-** Extension loading is off by default. See ticket #1863.
-**
-** {H12621} Call the sqlite3_enable_load_extension() routine with onoff==1
-** to turn extension loading on and call it with onoff==0 to turn
-** it back off again.
-**
-** {H12622} Extension loading is off by default.
-*/
-SQLITE_API int sqlite3_enable_load_extension(sqlite3 *db, int onoff);
-
-/*
-** CAPI3REF: Automatically Load An Extensions {H12640} <S20500>
-**
-** This API can be invoked at program startup in order to register
-** one or more statically linked extensions that will be available
-** to all new [database connections]. {END}
-**
-** This routine stores a pointer to the extension in an array that is
-** obtained from [sqlite3_malloc()]. If you run a memory leak checker
-** on your program and it reports a leak because of this array, invoke
-** [sqlite3_reset_auto_extension()] prior to shutdown to free the memory.
-**
-** {H12641} This function registers an extension entry point that is
-** automatically invoked whenever a new [database connection]
-** is opened using [sqlite3_open()], [sqlite3_open16()],
-** or [sqlite3_open_v2()].
-**
-** {H12642} Duplicate extensions are detected so calling this routine
-** multiple times with the same extension is harmless.
-**
-** {H12643} This routine stores a pointer to the extension in an array
-** that is obtained from [sqlite3_malloc()].
-**
-** {H12644} Automatic extensions apply across all threads.
-*/
-SQLITE_API int sqlite3_auto_extension(void (*xEntryPoint)(void));
-
-/*
-** CAPI3REF: Reset Automatic Extension Loading {H12660} <S20500>
-**
-** This function disables all previously registered automatic
-** extensions. {END} It undoes the effect of all prior
-** [sqlite3_auto_extension()] calls.
-**
-** {H12661} This function disables all previously registered
-** automatic extensions.
-**
-** {H12662} This function disables automatic extensions in all threads.
-*/
-SQLITE_API void sqlite3_reset_auto_extension(void);
-
-/*
-****** EXPERIMENTAL - subject to change without notice **************
-**
-** The interface to the virtual-table mechanism is currently considered
-** to be experimental. The interface might change in incompatible ways.
-** If this is a problem for you, do not use the interface at this time.
-**
-** When the virtual-table mechanism stabilizes, we will declare the
-** interface fixed, support it indefinitely, and remove this comment.
-*/
-
-/*
-** Structures used by the virtual table interface
-*/
-typedef struct sqlite3_vtab sqlite3_vtab;
-typedef struct sqlite3_index_info sqlite3_index_info;
-typedef struct sqlite3_vtab_cursor sqlite3_vtab_cursor;
-typedef struct sqlite3_module sqlite3_module;
-
-/*
-** CAPI3REF: Virtual Table Object {H18000} <S20400>
-** KEYWORDS: sqlite3_module {virtual table module}
-** EXPERIMENTAL
-**
-** This structure, sometimes called a a "virtual table module",
-** defines the implementation of a [virtual tables].
-** This structure consists mostly of methods for the module.
-**
-** A virtual table module is created by filling in a persistent
-** instance of this structure and passing a pointer to that instance
-** to [sqlite3_create_module()] or [sqlite3_create_module_v2()].
-** The registration remains valid until it is replaced by a different
-** module or until the [database connection] closes. The content
-** of this structure must not change while it is registered with
-** any database connection.
-*/
-struct sqlite3_module {
- int iVersion;
- int (*xCreate)(sqlite3*, void *pAux,
- int argc, const char *const*argv,
- sqlite3_vtab **ppVTab, char**);
- int (*xConnect)(sqlite3*, void *pAux,
- int argc, const char *const*argv,
- sqlite3_vtab **ppVTab, char**);
- int (*xBestIndex)(sqlite3_vtab *pVTab, sqlite3_index_info*);
- int (*xDisconnect)(sqlite3_vtab *pVTab);
- int (*xDestroy)(sqlite3_vtab *pVTab);
- int (*xOpen)(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor);
- int (*xClose)(sqlite3_vtab_cursor*);
- int (*xFilter)(sqlite3_vtab_cursor*, int idxNum, const char *idxStr,
- int argc, sqlite3_value **argv);
- int (*xNext)(sqlite3_vtab_cursor*);
- int (*xEof)(sqlite3_vtab_cursor*);
- int (*xColumn)(sqlite3_vtab_cursor*, sqlite3_context*, int);
- int (*xRowid)(sqlite3_vtab_cursor*, sqlite3_int64 *pRowid);
- int (*xUpdate)(sqlite3_vtab *, int, sqlite3_value **, sqlite3_int64 *);
- int (*xBegin)(sqlite3_vtab *pVTab);
- int (*xSync)(sqlite3_vtab *pVTab);
- int (*xCommit)(sqlite3_vtab *pVTab);
- int (*xRollback)(sqlite3_vtab *pVTab);
- int (*xFindFunction)(sqlite3_vtab *pVtab, int nArg, const char *zName,
- void (**pxFunc)(sqlite3_context*,int,sqlite3_value**),
- void **ppArg);
- int (*xRename)(sqlite3_vtab *pVtab, const char *zNew);
-};
-
-/*
-** CAPI3REF: Virtual Table Indexing Information {H18100} <S20400>
-** KEYWORDS: sqlite3_index_info
-** EXPERIMENTAL
-**
-** The sqlite3_index_info structure and its substructures is used to
-** pass information into and receive the reply from the [xBestIndex]
-** method of a [virtual table module]. The fields under **Inputs** are the
-** inputs to xBestIndex and are read-only. xBestIndex inserts its
-** results into the **Outputs** fields.
-**
-** The aConstraint[] array records WHERE clause constraints of the form:
-**
-** <pre>column OP expr</pre>
-**
-** where OP is =, &lt;, &lt;=, &gt;, or &gt;=. The particular operator is
-** stored in aConstraint[].op. The index of the column is stored in
-** aConstraint[].iColumn. aConstraint[].usable is TRUE if the
-** expr on the right-hand side can be evaluated (and thus the constraint
-** is usable) and false if it cannot.
-**
-** The optimizer automatically inverts terms of the form "expr OP column"
-** and makes other simplifications to the WHERE clause in an attempt to
-** get as many WHERE clause terms into the form shown above as possible.
-** The aConstraint[] array only reports WHERE clause terms in the correct
-** form that refer to the particular virtual table being queried.
-**
-** Information about the ORDER BY clause is stored in aOrderBy[].
-** Each term of aOrderBy records a column of the ORDER BY clause.
-**
-** The [xBestIndex] method must fill aConstraintUsage[] with information
-** about what parameters to pass to xFilter. If argvIndex>0 then
-** the right-hand side of the corresponding aConstraint[] is evaluated
-** and becomes the argvIndex-th entry in argv. If aConstraintUsage[].omit
-** is true, then the constraint is assumed to be fully handled by the
-** virtual table and is not checked again by SQLite.
-**
-** The idxNum and idxPtr values are recorded and passed into the
-** [xFilter] method.
-** [sqlite3_free()] is used to free idxPtr if and only iff
-** needToFreeIdxPtr is true.
-**
-** The orderByConsumed means that output from [xFilter]/[xNext] will occur in
-** the correct order to satisfy the ORDER BY clause so that no separate
-** sorting step is required.
-**
-** The estimatedCost value is an estimate of the cost of doing the
-** particular lookup. A full scan of a table with N entries should have
-** a cost of N. A binary search of a table of N entries should have a
-** cost of approximately log(N).
-*/
-struct sqlite3_index_info {
- /* Inputs */
- int nConstraint; /* Number of entries in aConstraint */
- struct sqlite3_index_constraint {
- int iColumn; /* Column on left-hand side of constraint */
- unsigned char op; /* Constraint operator */
- unsigned char usable; /* True if this constraint is usable */
- int iTermOffset; /* Used internally - xBestIndex should ignore */
- } *aConstraint; /* Table of WHERE clause constraints */
- int nOrderBy; /* Number of terms in the ORDER BY clause */
- struct sqlite3_index_orderby {
- int iColumn; /* Column number */
- unsigned char desc; /* True for DESC. False for ASC. */
- } *aOrderBy; /* The ORDER BY clause */
- /* Outputs */
- struct sqlite3_index_constraint_usage {
- int argvIndex; /* if >0, constraint is part of argv to xFilter */
- unsigned char omit; /* Do not code a test for this constraint */
- } *aConstraintUsage;
- int idxNum; /* Number used to identify the index */
- char *idxStr; /* String, possibly obtained from sqlite3_malloc */
- int needToFreeIdxStr; /* Free idxStr using sqlite3_free() if true */
- int orderByConsumed; /* True if output is already ordered */
- double estimatedCost; /* Estimated cost of using this index */
-};
-#define SQLITE_INDEX_CONSTRAINT_EQ 2
-#define SQLITE_INDEX_CONSTRAINT_GT 4
-#define SQLITE_INDEX_CONSTRAINT_LE 8
-#define SQLITE_INDEX_CONSTRAINT_LT 16
-#define SQLITE_INDEX_CONSTRAINT_GE 32
-#define SQLITE_INDEX_CONSTRAINT_MATCH 64
-
-/*
-** CAPI3REF: Register A Virtual Table Implementation {H18200} <S20400>
-** EXPERIMENTAL
-**
-** This routine is used to register a new [virtual table module] name.
-** Module names must be registered before
-** creating a new [virtual table] using the module, or before using a
-** preexisting [virtual table] for the module.
-**
-** The module name is registered on the [database connection] specified
-** by the first parameter. The name of the module is given by the
-** second parameter. The third parameter is a pointer to
-** the implementation of the [virtual table module]. The fourth
-** parameter is an arbitrary client data pointer that is passed through
-** into the [xCreate] and [xConnect] methods of the virtual table module
-** when a new virtual table is be being created or reinitialized.
-**
-** This interface has exactly the same effect as calling
-** [sqlite3_create_module_v2()] with a NULL client data destructor.
-*/
-SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_create_module(
- sqlite3 *db, /* SQLite connection to register module with */
- const char *zName, /* Name of the module */
- const sqlite3_module *p, /* Methods for the module */
- void *pClientData /* Client data for xCreate/xConnect */
-);
-
-/*
-** CAPI3REF: Register A Virtual Table Implementation {H18210} <S20400>
-** EXPERIMENTAL
-**
-** This routine is identical to the [sqlite3_create_module()] method,
-** except that it has an extra parameter to specify
-** a destructor function for the client data pointer. SQLite will
-** invoke the destructor function (if it is not NULL) when SQLite
-** no longer needs the pClientData pointer.
-*/
-SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_create_module_v2(
- sqlite3 *db, /* SQLite connection to register module with */
- const char *zName, /* Name of the module */
- const sqlite3_module *p, /* Methods for the module */
- void *pClientData, /* Client data for xCreate/xConnect */
- void(*xDestroy)(void*) /* Module destructor function */
-);
-
-/*
-** CAPI3REF: Virtual Table Instance Object {H18010} <S20400>
-** KEYWORDS: sqlite3_vtab
-** EXPERIMENTAL
-**
-** Every [virtual table module] implementation uses a subclass
-** of the following structure to describe a particular instance
-** of the [virtual table]. Each subclass will
-** be tailored to the specific needs of the module implementation.
-** The purpose of this superclass is to define certain fields that are
-** common to all module implementations.
-**
-** Virtual tables methods can set an error message by assigning a
-** string obtained from [sqlite3_mprintf()] to zErrMsg. The method should
-** take care that any prior string is freed by a call to [sqlite3_free()]
-** prior to assigning a new string to zErrMsg. After the error message
-** is delivered up to the client application, the string will be automatically
-** freed by sqlite3_free() and the zErrMsg field will be zeroed.
-*/
-struct sqlite3_vtab {
- const sqlite3_module *pModule; /* The module for this virtual table */
- int nRef; /* NO LONGER USED */
- char *zErrMsg; /* Error message from sqlite3_mprintf() */
- /* Virtual table implementations will typically add additional fields */
-};
-
-/*
-** CAPI3REF: Virtual Table Cursor Object {H18020} <S20400>
-** KEYWORDS: sqlite3_vtab_cursor {virtual table cursor}
-** EXPERIMENTAL
-**
-** Every [virtual table module] implementation uses a subclass of the
-** following structure to describe cursors that point into the
-** [virtual table] and are used
-** to loop through the virtual table. Cursors are created using the
-** [sqlite3_module.xOpen | xOpen] method of the module and are destroyed
-** by the [sqlite3_module.xClose | xClose] method. Cussors are used
-** by the [xFilter], [xNext], [xEof], [xColumn], and [xRowid] methods
-** of the module. Each module implementation will define
-** the content of a cursor structure to suit its own needs.
-**
-** This superclass exists in order to define fields of the cursor that
-** are common to all implementations.
-*/
-struct sqlite3_vtab_cursor {
- sqlite3_vtab *pVtab; /* Virtual table of this cursor */
- /* Virtual table implementations will typically add additional fields */
-};
-
-/*
-** CAPI3REF: Declare The Schema Of A Virtual Table {H18280} <S20400>
-** EXPERIMENTAL
-**
-** The [xCreate] and [xConnect] methods of a
-** [virtual table module] call this interface
-** to declare the format (the names and datatypes of the columns) of
-** the virtual tables they implement.
-*/
-SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_declare_vtab(sqlite3*, const char *zSQL);
-
-/*
-** CAPI3REF: Overload A Function For A Virtual Table {H18300} <S20400>
-** EXPERIMENTAL
-**
-** Virtual tables can provide alternative implementations of functions
-** using the [xFindFunction] method of the [virtual table module].
-** But global versions of those functions
-** must exist in order to be overloaded.
-**
-** This API makes sure a global version of a function with a particular
-** name and number of parameters exists. If no such function exists
-** before this API is called, a new function is created. The implementation
-** of the new function always causes an exception to be thrown. So
-** the new function is not good for anything by itself. Its only
-** purpose is to be a placeholder function that can be overloaded
-** by a [virtual table].
-*/
-SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_overload_function(sqlite3*, const char *zFuncName, int nArg);
-
-/*
-** The interface to the virtual-table mechanism defined above (back up
-** to a comment remarkably similar to this one) is currently considered
-** to be experimental. The interface might change in incompatible ways.
-** If this is a problem for you, do not use the interface at this time.
-**
-** When the virtual-table mechanism stabilizes, we will declare the
-** interface fixed, support it indefinitely, and remove this comment.
-**
-****** EXPERIMENTAL - subject to change without notice **************
-*/
-
-/*
-** CAPI3REF: A Handle To An Open BLOB {H17800} <S30230>
-** KEYWORDS: {BLOB handle} {BLOB handles}
-**
-** An instance of this object represents an open BLOB on which
-** [sqlite3_blob_open | incremental BLOB I/O] can be performed.
-** Objects of this type are created by [sqlite3_blob_open()]
-** and destroyed by [sqlite3_blob_close()].
-** The [sqlite3_blob_read()] and [sqlite3_blob_write()] interfaces
-** can be used to read or write small subsections of the BLOB.
-** The [sqlite3_blob_bytes()] interface returns the size of the BLOB in bytes.
-*/
-typedef struct sqlite3_blob sqlite3_blob;
-
-/*
-** CAPI3REF: Open A BLOB For Incremental I/O {H17810} <S30230>
-**
-** This interfaces opens a [BLOB handle | handle] to the BLOB located
-** in row iRow, column zColumn, table zTable in database zDb;
-** in other words, the same BLOB that would be selected by:
-**
-** <pre>
-** SELECT zColumn FROM zDb.zTable WHERE [rowid] = iRow;
-** </pre> {END}
-**
-** If the flags parameter is non-zero, then the BLOB is opened for read
-** and write access. If it is zero, the BLOB is opened for read access.
-**
-** Note that the database name is not the filename that contains
-** the database but rather the symbolic name of the database that
-** is assigned when the database is connected using [ATTACH].
-** For the main database file, the database name is "main".
-** For TEMP tables, the database name is "temp".
-**
-** On success, [SQLITE_OK] is returned and the new [BLOB handle] is written
-** to *ppBlob. Otherwise an [error code] is returned and *ppBlob is set
-** to be a null pointer.
-** This function sets the [database connection] error code and message
-** accessible via [sqlite3_errcode()] and [sqlite3_errmsg()] and related
-** functions. Note that the *ppBlob variable is always initialized in a
-** way that makes it safe to invoke [sqlite3_blob_close()] on *ppBlob
-** regardless of the success or failure of this routine.
-**
-** If the row that a BLOB handle points to is modified by an
-** [UPDATE], [DELETE], or by [ON CONFLICT] side-effects
-** then the BLOB handle is marked as "expired".
-** This is true if any column of the row is changed, even a column
-** other than the one the BLOB handle is open on.
-** Calls to [sqlite3_blob_read()] and [sqlite3_blob_write()] for
-** a expired BLOB handle fail with an return code of [SQLITE_ABORT].
-** Changes written into a BLOB prior to the BLOB expiring are not
-** rollback by the expiration of the BLOB. Such changes will eventually
-** commit if the transaction continues to completion.
-**
-** Use the [sqlite3_blob_bytes()] interface to determine the size of
-** the opened blob. The size of a blob may not be changed by this
-** interface. Use the [UPDATE] SQL command to change the size of a
-** blob.
-**
-** The [sqlite3_bind_zeroblob()] and [sqlite3_result_zeroblob()] interfaces
-** and the built-in [zeroblob] SQL function can be used, if desired,
-** to create an empty, zero-filled blob in which to read or write using
-** this interface.
-**
-** To avoid a resource leak, every open [BLOB handle] should eventually
-** be released by a call to [sqlite3_blob_close()].
-**
-** Requirements:
-** [H17813] [H17814] [H17816] [H17819] [H17821] [H17824]
-*/
-SQLITE_API int sqlite3_blob_open(
- sqlite3*,
- const char *zDb,
- const char *zTable,
- const char *zColumn,
- sqlite3_int64 iRow,
- int flags,
- sqlite3_blob **ppBlob
-);
-
-/*
-** CAPI3REF: Close A BLOB Handle {H17830} <S30230>
-**
-** Closes an open [BLOB handle].
-**
-** Closing a BLOB shall cause the current transaction to commit
-** if there are no other BLOBs, no pending prepared statements, and the
-** database connection is in [autocommit mode].
-** If any writes were made to the BLOB, they might be held in cache
-** until the close operation if they will fit.
-**
-** Closing the BLOB often forces the changes
-** out to disk and so if any I/O errors occur, they will likely occur
-** at the time when the BLOB is closed. Any errors that occur during
-** closing are reported as a non-zero return value.
-**
-** The BLOB is closed unconditionally. Even if this routine returns
-** an error code, the BLOB is still closed.
-**
-** Calling this routine with a null pointer (which as would be returned
-** by failed call to [sqlite3_blob_open()]) is a harmless no-op.
-**
-** Requirements:
-** [H17833] [H17836] [H17839]
-*/
-SQLITE_API int sqlite3_blob_close(sqlite3_blob *);
-
-/*
-** CAPI3REF: Return The Size Of An Open BLOB {H17840} <S30230>
-**
-** Returns the size in bytes of the BLOB accessible via the
-** successfully opened [BLOB handle] in its only argument. The
-** incremental blob I/O routines can only read or overwriting existing
-** blob content; they cannot change the size of a blob.
-**
-** This routine only works on a [BLOB handle] which has been created
-** by a prior successful call to [sqlite3_blob_open()] and which has not
-** been closed by [sqlite3_blob_close()]. Passing any other pointer in
-** to this routine results in undefined and probably undesirable behavior.
-**
-** Requirements:
-** [H17843]
-*/
-SQLITE_API int sqlite3_blob_bytes(sqlite3_blob *);
-
-/*
-** CAPI3REF: Read Data From A BLOB Incrementally {H17850} <S30230>
-**
-** This function is used to read data from an open [BLOB handle] into a
-** caller-supplied buffer. N bytes of data are copied into buffer Z
-** from the open BLOB, starting at offset iOffset.
-**
-** If offset iOffset is less than N bytes from the end of the BLOB,
-** [SQLITE_ERROR] is returned and no data is read. If N or iOffset is
-** less than zero, [SQLITE_ERROR] is returned and no data is read.
-** The size of the blob (and hence the maximum value of N+iOffset)
-** can be determined using the [sqlite3_blob_bytes()] interface.
-**
-** An attempt to read from an expired [BLOB handle] fails with an
-** error code of [SQLITE_ABORT].
-**
-** On success, SQLITE_OK is returned.
-** Otherwise, an [error code] or an [extended error code] is returned.
-**
-** This routine only works on a [BLOB handle] which has been created
-** by a prior successful call to [sqlite3_blob_open()] and which has not
-** been closed by [sqlite3_blob_close()]. Passing any other pointer in
-** to this routine results in undefined and probably undesirable behavior.
-**
-** See also: [sqlite3_blob_write()].
-**
-** Requirements:
-** [H17853] [H17856] [H17859] [H17862] [H17863] [H17865] [H17868]
-*/
-SQLITE_API int sqlite3_blob_read(sqlite3_blob *, void *Z, int N, int iOffset);
-
-/*
-** CAPI3REF: Write Data Into A BLOB Incrementally {H17870} <S30230>
-**
-** This function is used to write data into an open [BLOB handle] from a
-** caller-supplied buffer. N bytes of data are copied from the buffer Z
-** into the open BLOB, starting at offset iOffset.
-**
-** If the [BLOB handle] passed as the first argument was not opened for
-** writing (the flags parameter to [sqlite3_blob_open()] was zero),
-** this function returns [SQLITE_READONLY].
-**
-** This function may only modify the contents of the BLOB; it is
-** not possible to increase the size of a BLOB using this API.
-** If offset iOffset is less than N bytes from the end of the BLOB,
-** [SQLITE_ERROR] is returned and no data is written. If N is
-** less than zero [SQLITE_ERROR] is returned and no data is written.
-** The size of the BLOB (and hence the maximum value of N+iOffset)
-** can be determined using the [sqlite3_blob_bytes()] interface.
-**
-** An attempt to write to an expired [BLOB handle] fails with an
-** error code of [SQLITE_ABORT]. Writes to the BLOB that occurred
-** before the [BLOB handle] expired are not rolled back by the
-** expiration of the handle, though of course those changes might
-** have been overwritten by the statement that expired the BLOB handle
-** or by other independent statements.
-**
-** On success, SQLITE_OK is returned.
-** Otherwise, an [error code] or an [extended error code] is returned.
-**
-** This routine only works on a [BLOB handle] which has been created
-** by a prior successful call to [sqlite3_blob_open()] and which has not
-** been closed by [sqlite3_blob_close()]. Passing any other pointer in
-** to this routine results in undefined and probably undesirable behavior.
-**
-** See also: [sqlite3_blob_read()].
-**
-** Requirements:
-** [H17873] [H17874] [H17875] [H17876] [H17877] [H17879] [H17882] [H17885]
-** [H17888]
-*/
-SQLITE_API int sqlite3_blob_write(sqlite3_blob *, const void *z, int n, int iOffset);
-
-/*
-** CAPI3REF: Virtual File System Objects {H11200} <S20100>
-**
-** A virtual filesystem (VFS) is an [sqlite3_vfs] object
-** that SQLite uses to interact
-** with the underlying operating system. Most SQLite builds come with a
-** single default VFS that is appropriate for the host computer.
-** New VFSes can be registered and existing VFSes can be unregistered.
-** The following interfaces are provided.
-**
-** The sqlite3_vfs_find() interface returns a pointer to a VFS given its name.
-** Names are case sensitive.
-** Names are zero-terminated UTF-8 strings.
-** If there is no match, a NULL pointer is returned.
-** If zVfsName is NULL then the default VFS is returned.
-**
-** New VFSes are registered with sqlite3_vfs_register().
-** Each new VFS becomes the default VFS if the makeDflt flag is set.
-** The same VFS can be registered multiple times without injury.
-** To make an existing VFS into the default VFS, register it again
-** with the makeDflt flag set. If two different VFSes with the
-** same name are registered, the behavior is undefined. If a
-** VFS is registered with a name that is NULL or an empty string,
-** then the behavior is undefined.
-**
-** Unregister a VFS with the sqlite3_vfs_unregister() interface.
-** If the default VFS is unregistered, another VFS is chosen as
-** the default. The choice for the new VFS is arbitrary.
-**
-** Requirements:
-** [H11203] [H11206] [H11209] [H11212] [H11215] [H11218]
-*/
-SQLITE_API sqlite3_vfs *sqlite3_vfs_find(const char *zVfsName);
-SQLITE_API int sqlite3_vfs_register(sqlite3_vfs*, int makeDflt);
-SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*);
-
-/*
-** CAPI3REF: Mutexes {H17000} <S20000>
-**
-** The SQLite core uses these routines for thread
-** synchronization. Though they are intended for internal
-** use by SQLite, code that links against SQLite is
-** permitted to use any of these routines.
-**
-** The SQLite source code contains multiple implementations
-** of these mutex routines. An appropriate implementation
-** is selected automatically at compile-time. The following
-** implementations are available in the SQLite core:
-**
-** <ul>
-** <li> SQLITE_MUTEX_OS2
-** <li> SQLITE_MUTEX_PTHREAD
-** <li> SQLITE_MUTEX_W32
-** <li> SQLITE_MUTEX_NOOP
-** </ul>
-**
-** 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
-** are appropriate for use on OS/2, Unix, and Windows.
-**
-** If SQLite is compiled with the SQLITE_MUTEX_APPDEF preprocessor
-** macro defined (with "-DSQLITE_MUTEX_APPDEF=1"), then no mutex
-** implementation is included with the library. In this case the
-** application must supply a custom mutex implementation using the
-** [SQLITE_CONFIG_MUTEX] option of the sqlite3_config() function
-** before calling sqlite3_initialize() or any other public sqlite3_
-** function that calls sqlite3_initialize().
-**
-** {H17011} The sqlite3_mutex_alloc() routine allocates a new
-** mutex and returns a pointer to it. {H17012} If it returns NULL
-** that means that a mutex could not be allocated. {H17013} SQLite
-** will unwind its stack and return an error. {H17014} The argument
-** to sqlite3_mutex_alloc() is one of these integer constants:
-**
-** <ul>
-** <li> SQLITE_MUTEX_FAST
-** <li> SQLITE_MUTEX_RECURSIVE
-** <li> SQLITE_MUTEX_STATIC_MASTER
-** <li> SQLITE_MUTEX_STATIC_MEM
-** <li> SQLITE_MUTEX_STATIC_MEM2
-** <li> SQLITE_MUTEX_STATIC_PRNG
-** <li> SQLITE_MUTEX_STATIC_LRU
-** <li> SQLITE_MUTEX_STATIC_LRU2
-** </ul>
-**
-** {H17015} The first two constants cause sqlite3_mutex_alloc() to create
-** a new mutex. The new mutex is recursive when SQLITE_MUTEX_RECURSIVE
-** is used but not necessarily so when SQLITE_MUTEX_FAST is used. {END}
-** The mutex implementation does not need to make a distinction
-** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does
-** not want to. {H17016} But SQLite will only request a recursive mutex in
-** cases where it really needs one. {END} If a faster non-recursive mutex
-** implementation is available on the host platform, the mutex subsystem
-** might return such a mutex in response to SQLITE_MUTEX_FAST.
-**
-** {H17017} The other allowed parameters to sqlite3_mutex_alloc() each return
-** a pointer to a static preexisting mutex. {END} Six static mutexes are
-** used by the current version of SQLite. Future versions of SQLite
-** may add additional static mutexes. Static mutexes are for internal
-** use by SQLite only. Applications that use SQLite mutexes should
-** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or
-** SQLITE_MUTEX_RECURSIVE.
-**
-** {H17018} Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST
-** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc()
-** returns a different mutex on every call. {H17034} But for the static
-** mutex types, the same mutex is returned on every call that has
-** the same type number.
-**
-** {H17019} The sqlite3_mutex_free() routine deallocates a previously
-** allocated dynamic mutex. {H17020} SQLite is careful to deallocate every
-** dynamic mutex that it allocates. {A17021} The dynamic mutexes must not be in
-** use when they are deallocated. {A17022} Attempting to deallocate a static
-** mutex results in undefined behavior. {H17023} SQLite never deallocates
-** a static mutex. {END}
-**
-** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt
-** to enter a mutex. {H17024} If another thread is already within the mutex,
-** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return
-** SQLITE_BUSY. {H17025} The sqlite3_mutex_try() interface returns [SQLITE_OK]
-** upon successful entry. {H17026} Mutexes created using
-** SQLITE_MUTEX_RECURSIVE can be entered multiple times by the same thread.
-** {H17027} In such cases the,
-** mutex must be exited an equal number of times before another thread
-** can enter. {A17028} If the same thread tries to enter any other
-** kind of mutex more than once, the behavior is undefined.
-** {H17029} SQLite will never exhibit
-** such behavior in its own use of mutexes.
-**
-** Some systems (for example, Windows 95) do not support the operation
-** implemented by sqlite3_mutex_try(). On those systems, sqlite3_mutex_try()
-** will always return SQLITE_BUSY. {H17030} The SQLite core only ever uses
-** sqlite3_mutex_try() as an optimization so this is acceptable behavior.
-**
-** {H17031} The sqlite3_mutex_leave() routine exits a mutex that was
-** previously entered by the same thread. {A17032} The behavior
-** is undefined if the mutex is not currently entered by the
-** calling thread or is not currently allocated. {H17033} SQLite will
-** never do either. {END}
-**
-** If the argument to sqlite3_mutex_enter(), sqlite3_mutex_try(), or
-** sqlite3_mutex_leave() is a NULL pointer, then all three routines
-** behave as no-ops.
-**
-** See also: [sqlite3_mutex_held()] and [sqlite3_mutex_notheld()].
-*/
-SQLITE_API sqlite3_mutex *sqlite3_mutex_alloc(int);
-SQLITE_API void sqlite3_mutex_free(sqlite3_mutex*);
-SQLITE_API void sqlite3_mutex_enter(sqlite3_mutex*);
-SQLITE_API int sqlite3_mutex_try(sqlite3_mutex*);
-SQLITE_API void sqlite3_mutex_leave(sqlite3_mutex*);
-
-/*
-** CAPI3REF: Mutex Methods Object {H17120} <S20130>
-** EXPERIMENTAL
-**
-** An instance of this structure defines the low-level routines
-** used to allocate and use mutexes.
-**
-** Usually, the default mutex implementations provided by SQLite are
-** sufficient, however the user has the option of substituting a custom
-** implementation for specialized deployments or systems for which SQLite
-** does not provide a suitable implementation. In this case, the user
-** creates and populates an instance of this structure to pass
-** to sqlite3_config() along with the [SQLITE_CONFIG_MUTEX] option.
-** Additionally, an instance of this structure can be used as an
-** output variable when querying the system for the current mutex
-** implementation, using the [SQLITE_CONFIG_GETMUTEX] option.
-**
-** The xMutexInit method defined by this structure is invoked as
-** part of system initialization by the sqlite3_initialize() function.
-** {H17001} The xMutexInit routine shall be called by SQLite once for each
-** effective call to [sqlite3_initialize()].
-**
-** The xMutexEnd method defined by this structure is invoked as
-** part of system shutdown by the sqlite3_shutdown() function. The
-** implementation of this method is expected to release all outstanding
-** resources obtained by the mutex methods implementation, especially
-** those obtained by the xMutexInit method. {H17003} The xMutexEnd()
-** interface shall be invoked once for each call to [sqlite3_shutdown()].
-**
-** The remaining seven methods defined by this structure (xMutexAlloc,
-** xMutexFree, xMutexEnter, xMutexTry, xMutexLeave, xMutexHeld and
-** xMutexNotheld) implement the following interfaces (respectively):
-**
-** <ul>
-** <li> [sqlite3_mutex_alloc()] </li>
-** <li> [sqlite3_mutex_free()] </li>
-** <li> [sqlite3_mutex_enter()] </li>
-** <li> [sqlite3_mutex_try()] </li>
-** <li> [sqlite3_mutex_leave()] </li>
-** <li> [sqlite3_mutex_held()] </li>
-** <li> [sqlite3_mutex_notheld()] </li>
-** </ul>
-**
-** The only difference is that the public sqlite3_XXX functions enumerated
-** above silently ignore any invocations that pass a NULL pointer instead
-** of a valid mutex handle. The implementations of the methods defined
-** by this structure are not required to handle this case, the results
-** of passing a NULL pointer instead of a valid mutex handle are undefined
-** (i.e. it is acceptable to provide an implementation that segfaults if
-** it is passed a NULL pointer).
-**
-** The xMutexInit() method must be threadsafe. It must be harmless to
-** invoke xMutexInit() mutiple times within the same process and without
-** intervening calls to xMutexEnd(). Second and subsequent calls to
-** xMutexInit() must be no-ops.
-**
-** xMutexInit() must not use SQLite memory allocation ([sqlite3_malloc()]
-** and its associates). Similarly, xMutexAlloc() must not use SQLite memory
-** allocation for a static mutex. However xMutexAlloc() may use SQLite
-** memory allocation for a fast or recursive mutex.
-**
-** SQLite will invoke the xMutexEnd() method when [sqlite3_shutdown()] is
-** called, but only if the prior call to xMutexInit returned SQLITE_OK.
-** If xMutexInit fails in any way, it is expected to clean up after itself
-** prior to returning.
-*/
-typedef struct sqlite3_mutex_methods sqlite3_mutex_methods;
-struct sqlite3_mutex_methods {
- int (*xMutexInit)(void);
- int (*xMutexEnd)(void);
- sqlite3_mutex *(*xMutexAlloc)(int);
- void (*xMutexFree)(sqlite3_mutex *);
- void (*xMutexEnter)(sqlite3_mutex *);
- int (*xMutexTry)(sqlite3_mutex *);
- void (*xMutexLeave)(sqlite3_mutex *);
- int (*xMutexHeld)(sqlite3_mutex *);
- int (*xMutexNotheld)(sqlite3_mutex *);
-};
-
-/*
-** CAPI3REF: Mutex Verification Routines {H17080} <S20130> <S30800>
-**
-** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routines
-** are intended for use inside assert() statements. {H17081} The SQLite core
-** never uses these routines except inside an assert() and applications
-** are advised to follow the lead of the core. {H17082} The core only
-** provides implementations for these routines when it is compiled
-** with the SQLITE_DEBUG flag. {A17087} External mutex implementations
-** are only required to provide these routines if SQLITE_DEBUG is
-** defined and if NDEBUG is not defined.
-**
-** {H17083} These routines should return true if the mutex in their argument
-** is held or not held, respectively, by the calling thread.
-**
-** {X17084} The implementation is not required to provided 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.
-**
-** {H17085} If the argument to sqlite3_mutex_held() is a NULL pointer then
-** the routine should return 1. {END} This seems counter-intuitive since
-** clearly the mutex cannot be held if it does not exist. But the
-** the reason the mutex does not exist is because the build is not
-** using mutexes. And we do not want the assert() containing the
-** call to sqlite3_mutex_held() to fail, so a non-zero return is
-** the appropriate thing to do. {H17086} The sqlite3_mutex_notheld()
-** interface should also return 1 when given a NULL pointer.
-*/
-SQLITE_API int sqlite3_mutex_held(sqlite3_mutex*);
-SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex*);
-
-/*
-** CAPI3REF: Mutex Types {H17001} <H17000>
-**
-** The [sqlite3_mutex_alloc()] interface takes a single argument
-** which is one of these integer constants.
-**
-** The set of static mutexes may change from one SQLite release to the
-** next. Applications that override the built-in mutex logic must be
-** prepared to accommodate additional static mutexes.
-*/
-#define SQLITE_MUTEX_FAST 0
-#define SQLITE_MUTEX_RECURSIVE 1
-#define SQLITE_MUTEX_STATIC_MASTER 2
-#define SQLITE_MUTEX_STATIC_MEM 3 /* sqlite3_malloc() */
-#define SQLITE_MUTEX_STATIC_MEM2 4 /* NOT USED */
-#define SQLITE_MUTEX_STATIC_OPEN 4 /* sqlite3BtreeOpen() */
-#define SQLITE_MUTEX_STATIC_PRNG 5 /* sqlite3_random() */
-#define SQLITE_MUTEX_STATIC_LRU 6 /* lru page list */
-#define SQLITE_MUTEX_STATIC_LRU2 7 /* lru page list */
-
-/*
-** CAPI3REF: Retrieve the mutex for a database connection {H17002} <H17000>
-**
-** This interface returns a pointer the [sqlite3_mutex] object that
-** serializes access to the [database connection] given in the argument
-** when the [threading mode] is Serialized.
-** If the [threading mode] is Single-thread or Multi-thread then this
-** routine returns a NULL pointer.
-*/
-SQLITE_API sqlite3_mutex *sqlite3_db_mutex(sqlite3*);
-
-/*
-** CAPI3REF: Low-Level Control Of Database Files {H11300} <S30800>
-**
-** {H11301} The [sqlite3_file_control()] interface makes a direct call to the
-** xFileControl method for the [sqlite3_io_methods] object associated
-** with a particular database identified by the second argument. {H11302} The
-** name of the database is the name assigned to the database by the
-** <a href="lang_attach.html">ATTACH</a> SQL command that opened the
-** database. {H11303} To control the main database file, use the name "main"
-** or a NULL pointer. {H11304} The third and fourth parameters to this routine
-** are passed directly through to the second and third parameters of
-** the xFileControl method. {H11305} The return value of the xFileControl
-** method becomes the return value of this routine.
-**
-** {H11306} If the second parameter (zDbName) does not match the name of any
-** open database file, then SQLITE_ERROR is returned. {H11307} This error
-** code is not remembered and will not be recalled by [sqlite3_errcode()]
-** or [sqlite3_errmsg()]. {A11308} The underlying xFileControl method might
-** also return SQLITE_ERROR. {A11309} There is no way to distinguish between
-** an incorrect zDbName and an SQLITE_ERROR return from the underlying
-** xFileControl method. {END}
-**
-** See also: [SQLITE_FCNTL_LOCKSTATE]
-*/
-SQLITE_API int sqlite3_file_control(sqlite3*, const char *zDbName, int op, void*);
-
-/*
-** CAPI3REF: Testing Interface {H11400} <S30800>
-**
-** The sqlite3_test_control() interface is used to read out internal
-** state of SQLite and to inject faults into SQLite for testing
-** purposes. The first parameter is an operation code that determines
-** the number, meaning, and operation of all subsequent parameters.
-**
-** This interface is not for use by applications. It exists solely
-** for verifying the correct operation of the SQLite library. Depending
-** on how the SQLite library is compiled, this interface might not exist.
-**
-** The details of the operation codes, their meanings, the parameters
-** they take, and what they do are all subject to change without notice.
-** Unlike most of the SQLite API, this function is not guaranteed to
-** operate consistently from one release to the next.
-*/
-SQLITE_API int sqlite3_test_control(int op, ...);
-
-/*
-** CAPI3REF: Testing Interface Operation Codes {H11410} <H11400>
-**
-** These constants are the valid operation code parameters used
-** as the first argument to [sqlite3_test_control()].
-**
-** These parameters and their meanings are subject to change
-** without notice. These values are for testing purposes only.
-** Applications should not use any of these parameters or the
-** [sqlite3_test_control()] interface.
-*/
-#define SQLITE_TESTCTRL_PRNG_SAVE 5
-#define SQLITE_TESTCTRL_PRNG_RESTORE 6
-#define SQLITE_TESTCTRL_PRNG_RESET 7
-#define SQLITE_TESTCTRL_BITVEC_TEST 8
-#define SQLITE_TESTCTRL_FAULT_INSTALL 9
-#define SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS 10
-#define SQLITE_TESTCTRL_PENDING_BYTE 11
-#define SQLITE_TESTCTRL_ASSERT 12
-#define SQLITE_TESTCTRL_ALWAYS 13
-#define SQLITE_TESTCTRL_RESERVE 14
-
-/*
-** CAPI3REF: SQLite Runtime Status {H17200} <S60200>
-** EXPERIMENTAL
-**
-** This interface is used to retrieve runtime status information
-** about the preformance of SQLite, and optionally to reset various
-** highwater marks. The first argument is an integer code for
-** the specific parameter to measure. Recognized integer codes
-** are of the form [SQLITE_STATUS_MEMORY_USED | SQLITE_STATUS_...].
-** The current value of the parameter is returned into *pCurrent.
-** The highest recorded value is returned in *pHighwater. If the
-** resetFlag is true, then the highest record value is reset after
-** *pHighwater is written. Some parameters do not record the highest
-** value. For those parameters
-** nothing is written into *pHighwater and the resetFlag is ignored.
-** Other parameters record only the highwater mark and not the current
-** value. For these latter parameters nothing is written into *pCurrent.
-**
-** This routine returns SQLITE_OK on success and a non-zero
-** [error code] on failure.
-**
-** This routine is threadsafe but is not atomic. This routine can be
-** called while other threads are running the same or different SQLite
-** interfaces. However the values returned in *pCurrent and
-** *pHighwater reflect the status of SQLite at different points in time
-** and it is possible that another thread might change the parameter
-** in between the times when *pCurrent and *pHighwater are written.
-**
-** See also: [sqlite3_db_status()]
-*/
-SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag);
-
-
-/*
-** CAPI3REF: Status Parameters {H17250} <H17200>
-** EXPERIMENTAL
-**
-** These integer constants designate various run-time status parameters
-** that can be returned by [sqlite3_status()].
-**
-** <dl>
-** <dt>SQLITE_STATUS_MEMORY_USED</dt>
-** <dd>This parameter is the current amount of memory checked out
-** using [sqlite3_malloc()], either directly or indirectly. The
-** figure includes calls made to [sqlite3_malloc()] by the application
-** and internal memory usage by the SQLite library. Scratch memory
-** controlled by [SQLITE_CONFIG_SCRATCH] and auxiliary page-cache
-** memory controlled by [SQLITE_CONFIG_PAGECACHE] is not included in
-** this parameter. The amount returned is the sum of the allocation
-** sizes as reported by the xSize method in [sqlite3_mem_methods].</dd>
-**
-** <dt>SQLITE_STATUS_MALLOC_SIZE</dt>
-** <dd>This parameter records the largest memory allocation request
-** handed to [sqlite3_malloc()] or [sqlite3_realloc()] (or their
-** internal equivalents). Only the value returned in the
-** *pHighwater parameter to [sqlite3_status()] is of interest.
-** The value written into the *pCurrent parameter is undefined.</dd>
-**
-** <dt>SQLITE_STATUS_PAGECACHE_USED</dt>
-** <dd>This parameter returns the number of pages used out of the
-** [pagecache memory allocator] that was configured using
-** [SQLITE_CONFIG_PAGECACHE]. The
-** value returned is in pages, not in bytes.</dd>
-**
-** <dt>SQLITE_STATUS_PAGECACHE_OVERFLOW</dt>
-** <dd>This parameter returns the number of bytes of page cache
-** allocation which could not be statisfied by the [SQLITE_CONFIG_PAGECACHE]
-** buffer and where forced to overflow to [sqlite3_malloc()]. The
-** returned value includes allocations that overflowed because they
-** where too large (they were larger than the "sz" parameter to
-** [SQLITE_CONFIG_PAGECACHE]) and allocations that overflowed because
-** no space was left in the page cache.</dd>
-**
-** <dt>SQLITE_STATUS_PAGECACHE_SIZE</dt>
-** <dd>This parameter records the largest memory allocation request
-** handed to [pagecache memory allocator]. Only the value returned in the
-** *pHighwater parameter to [sqlite3_status()] is of interest.
-** The value written into the *pCurrent parameter is undefined.</dd>
-**
-** <dt>SQLITE_STATUS_SCRATCH_USED</dt>
-** <dd>This parameter returns the number of allocations used out of the
-** [scratch memory allocator] configured using
-** [SQLITE_CONFIG_SCRATCH]. The value returned is in allocations, not
-** in bytes. Since a single thread may only have one scratch allocation
-** outstanding at time, this parameter also reports the number of threads
-** using scratch memory at the same time.</dd>
-**
-** <dt>SQLITE_STATUS_SCRATCH_OVERFLOW</dt>
-** <dd>This parameter returns the number of bytes of scratch memory
-** allocation which could not be statisfied by the [SQLITE_CONFIG_SCRATCH]
-** buffer and where forced to overflow to [sqlite3_malloc()]. The values
-** returned include overflows because the requested allocation was too
-** larger (that is, because the requested allocation was larger than the
-** "sz" parameter to [SQLITE_CONFIG_SCRATCH]) and because no scratch buffer
-** slots were available.
-** </dd>
-**
-** <dt>SQLITE_STATUS_SCRATCH_SIZE</dt>
-** <dd>This parameter records the largest memory allocation request
-** handed to [scratch memory allocator]. Only the value returned in the
-** *pHighwater parameter to [sqlite3_status()] is of interest.
-** The value written into the *pCurrent parameter is undefined.</dd>
-**
-** <dt>SQLITE_STATUS_PARSER_STACK</dt>
-** <dd>This parameter records the deepest parser stack. It is only
-** meaningful if SQLite is compiled with [YYTRACKMAXSTACKDEPTH].</dd>
-** </dl>
-**
-** New status parameters may be added from time to time.
-*/
-#define SQLITE_STATUS_MEMORY_USED 0
-#define SQLITE_STATUS_PAGECACHE_USED 1
-#define SQLITE_STATUS_PAGECACHE_OVERFLOW 2
-#define SQLITE_STATUS_SCRATCH_USED 3
-#define SQLITE_STATUS_SCRATCH_OVERFLOW 4
-#define SQLITE_STATUS_MALLOC_SIZE 5
-#define SQLITE_STATUS_PARSER_STACK 6
-#define SQLITE_STATUS_PAGECACHE_SIZE 7
-#define SQLITE_STATUS_SCRATCH_SIZE 8
-
-/*
-** CAPI3REF: Database Connection Status {H17500} <S60200>
-** EXPERIMENTAL
-**
-** This interface is used to retrieve runtime status information
-** about a single [database connection]. The first argument is the
-** database connection object to be interrogated. The second argument
-** is the parameter to interrogate. Currently, the only allowed value
-** for the second parameter is [SQLITE_DBSTATUS_LOOKASIDE_USED].
-** Additional options will likely appear in future releases of SQLite.
-**
-** The current value of the requested parameter is written into *pCur
-** and the highest instantaneous value is written into *pHiwtr. If
-** the resetFlg is true, then the highest instantaneous value is
-** reset back down to the current value.
-**
-** See also: [sqlite3_status()] and [sqlite3_stmt_status()].
-*/
-SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg);
-
-/*
-** CAPI3REF: Status Parameters for database connections {H17520} <H17500>
-** EXPERIMENTAL
-**
-** These constants are the available integer "verbs" that can be passed as
-** the second argument to the [sqlite3_db_status()] interface.
-**
-** New verbs may be added in future releases of SQLite. Existing verbs
-** might be discontinued. Applications should check the return code from
-** [sqlite3_db_status()] to make sure that the call worked.
-** The [sqlite3_db_status()] interface will return a non-zero error code
-** if a discontinued or unsupported verb is invoked.
-**
-** <dl>
-** <dt>SQLITE_DBSTATUS_LOOKASIDE_USED</dt>
-** <dd>This parameter returns the number of lookaside memory slots currently
-** checked out.</dd>
-** </dl>
-*/
-#define SQLITE_DBSTATUS_LOOKASIDE_USED 0
-
-
-/*
-** CAPI3REF: Prepared Statement Status {H17550} <S60200>
-** EXPERIMENTAL
-**
-** Each prepared statement maintains various
-** [SQLITE_STMTSTATUS_SORT | counters] that measure the number
-** of times it has performed specific operations. These counters can
-** be used to monitor the performance characteristics of the prepared
-** statements. For example, if the number of table steps greatly exceeds
-** the number of table searches or result rows, that would tend to indicate
-** that the prepared statement is using a full table scan rather than
-** an index.
-**
-** This interface is used to retrieve and reset counter values from
-** a [prepared statement]. The first argument is the prepared statement
-** object to be interrogated. The second argument
-** is an integer code for a specific [SQLITE_STMTSTATUS_SORT | counter]
-** to be interrogated.
-** The current value of the requested counter is returned.
-** If the resetFlg is true, then the counter is reset to zero after this
-** interface call returns.
-**
-** See also: [sqlite3_status()] and [sqlite3_db_status()].
-*/
-SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg);
-
-/*
-** CAPI3REF: Status Parameters for prepared statements {H17570} <H17550>
-** EXPERIMENTAL
-**
-** These preprocessor macros define integer codes that name counter
-** values associated with the [sqlite3_stmt_status()] interface.
-** The meanings of the various counters are as follows:
-**
-** <dl>
-** <dt>SQLITE_STMTSTATUS_FULLSCAN_STEP</dt>
-** <dd>This is the number of times that SQLite has stepped forward in
-** a table as part of a full table scan. Large numbers for this counter
-** may indicate opportunities for performance improvement through
-** careful use of indices.</dd>
-**
-** <dt>SQLITE_STMTSTATUS_SORT</dt>
-** <dd>This is the number of sort operations that have occurred.
-** A non-zero value in this counter may indicate an opportunity to
-** improvement performance through careful use of indices.</dd>
-**
-** </dl>
-*/
-#define SQLITE_STMTSTATUS_FULLSCAN_STEP 1
-#define SQLITE_STMTSTATUS_SORT 2
-
-/*
-** CAPI3REF: Custom Page Cache Object
-** EXPERIMENTAL
-**
-** The sqlite3_pcache type is opaque. It is implemented by
-** the pluggable module. The SQLite core has no knowledge of
-** its size or internal structure and never deals with the
-** sqlite3_pcache object except by holding and passing pointers
-** to the object.
-**
-** See [sqlite3_pcache_methods] for additional information.
-*/
-typedef struct sqlite3_pcache sqlite3_pcache;
-
-/*
-** CAPI3REF: Application Defined Page Cache.
-** KEYWORDS: {page cache}
-** EXPERIMENTAL
-**
-** The [sqlite3_config]([SQLITE_CONFIG_PCACHE], ...) interface can
-** register an alternative page cache implementation by passing in an
-** instance of the sqlite3_pcache_methods structure. The majority of the
-** heap memory used by SQLite is used by the page cache to cache data read
-** from, or ready to be written to, the database file. By implementing a
-** custom page cache using this API, an application can control more
-** precisely the amount of memory consumed by SQLite, the way in which
-** that memory is allocated and released, and the policies used to
-** determine exactly which parts of a database file are cached and for
-** how long.
-**
-** The contents of the sqlite3_pcache_methods 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.
-**
-** The xInit() method is called once for each call to [sqlite3_initialize()]
-** (usually only once during the lifetime of the process). It is passed
-** a copy of the sqlite3_pcache_methods.pArg value. It can be used to set
-** up global structures and mutexes required by the custom page cache
-** implementation.
-**
-** The xShutdown() method is called from within [sqlite3_shutdown()],
-** if the application invokes this API. It can be used to clean up
-** any outstanding resources before process shutdown, if required.
-**
-** SQLite holds a [SQLITE_MUTEX_RECURSIVE] mutex when it invokes
-** the xInit method, so the xInit method need not be threadsafe. The
-** xShutdown method is only called from [sqlite3_shutdown()] so it does
-** not need to be threadsafe either. All other methods must be threadsafe
-** in multithreaded applications.
-**
-** SQLite will never invoke xInit() more than once without an intervening
-** call to xShutdown().
-**
-** The xCreate() method is used to construct a new cache instance. 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 about 100 or 200. 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
-** on the SQLite version, the target platform, and how SQLite was compiled.
-** R is constant for a particular build of SQLite. 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
-** 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
-** never invoke xUnpin() except to deliberately delete a page.
-** In other words, a cache created with bPurgeable set to false will
-** never contain any unpinned pages.
-**
-** The xCachesize() method may be called at any time by SQLite to set the
-** suggested maximum cache-size (number of pages stored by) the cache
-** instance passed as the first argument. This is the value configured using
-** the SQLite "[PRAGMA cache_size]" command. As with the bPurgeable parameter,
-** the implementation is not required to do anything with this
-** value; it is advisory only.
-**
-** The xPagecount() method should return the number of pages currently
-** stored in the cache.
-**
-** The xFetch() method is used to fetch a page and return a pointer to it.
-** A 'page', in this context, is a buffer of szPage bytes aligned at an
-** 8-byte boundary. The page to be fetched is determined by the key. The
-** mimimum 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
-** intact. If the requested page is not already in the cache, then the
-** behavior of the cache implementation is determined by the value of the
-** createFlag parameter passed to xFetch, according to the following table:
-**
-** <table border=1 width=85% align=center>
-** <tr><th> createFlag <th> Behaviour when page is not already in cache
-** <tr><td> 0 <td> Do not allocate a new page. Return NULL.
-** <tr><td> 1 <td> Allocate a new page if it easy and convenient to do so.
-** Otherwise return NULL.
-** <tr><td> 2 <td> Make every effort to allocate a new page. Only return
-** NULL if allocating a new page is effectively impossible.
-** </table>
-**
-** SQLite will normally invoke xFetch() with a createFlag of 0 or 1. If
-** a call to xFetch() with createFlag==1 returns NULL, then SQLite will
-** attempt to unpin one or more cache pages by spilling the content of
-** pinned pages to disk and synching the operating system disk cache. After
-** attempting to unpin pages, the xFetch() method will be invoked again with
-** a createFlag of 2.
-**
-** xUnpin() is called by SQLite with a pointer to a currently pinned page
-** as its second argument. If the third parameter, discard, is non-zero,
-** then the page should be evicted from the cache. In this case SQLite
-** assumes that the next time the page is retrieved from the cache using
-** the xFetch() method, it will be zeroed. If the discard parameter is
-** zero, then the page is considered to be unpinned. The cache implementation
-** may choose to evict unpinned pages at any time.
-**
-** The cache is not required to perform any reference counting. A single
-** call to xUnpin() unpins the page regardless of the number of prior calls
-** to xFetch().
-**
-** The xRekey() method is used to change the key value associated with the
-** page passed as the second argument from oldKey to newKey. If the cache
-** previously contains an entry associated with newKey, it should be
-** discarded. Any prior cache entry associated with newKey is guaranteed not
-** to be pinned.
-**
-** When SQLite calls the xTruncate() method, the cache must discard all
-** existing cache entries with page numbers (keys) greater than or equal
-** to the value of the iLimit parameter passed to xTruncate(). If any
-** of these pages are pinned, they are implicitly unpinned, meaning that
-** they can be safely discarded.
-**
-** 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
-** functions.
-*/
-typedef struct sqlite3_pcache_methods sqlite3_pcache_methods;
-struct sqlite3_pcache_methods {
- void *pArg;
- int (*xInit)(void*);
- void (*xShutdown)(void*);
- sqlite3_pcache *(*xCreate)(int szPage, int bPurgeable);
- void (*xCachesize)(sqlite3_pcache*, int nCachesize);
- int (*xPagecount)(sqlite3_pcache*);
- void *(*xFetch)(sqlite3_pcache*, unsigned key, int createFlag);
- void (*xUnpin)(sqlite3_pcache*, void*, int discard);
- void (*xRekey)(sqlite3_pcache*, void*, unsigned oldKey, unsigned newKey);
- void (*xTruncate)(sqlite3_pcache*, unsigned iLimit);
- void (*xDestroy)(sqlite3_pcache*);
-};
-
-/*
-** CAPI3REF: Online Backup Object
-** EXPERIMENTAL
-**
-** The sqlite3_backup object records state information about an ongoing
-** online backup operation. The sqlite3_backup object is created by
-** a call to [sqlite3_backup_init()] and is destroyed by a call to
-** [sqlite3_backup_finish()].
-**
-** See Also: [Using the SQLite Online Backup API]
-*/
-typedef struct sqlite3_backup sqlite3_backup;
-
-/*
-** CAPI3REF: Online Backup API.
-** EXPERIMENTAL
-**
-** This API is used to overwrite the contents of one database with that
-** of another. It is useful either for creating backups of databases or
-** for copying in-memory databases to or from persistent files.
-**
-** See Also: [Using the SQLite Online Backup API]
-**
-** Exclusive access is required to the destination database for the
-** duration of the operation. However the source database is only
-** read-locked while it is actually being read, it is not locked
-** continuously for the entire operation. Thus, the backup may be
-** performed on a live database without preventing other users from
-** writing to the database for an extended period of time.
-**
-** To perform a backup operation:
-** <ol>
-** <li><b>sqlite3_backup_init()</b> is called once to initialize the
-** backup,
-** <li><b>sqlite3_backup_step()</b> is called one or more times to transfer
-** the data between the two databases, and finally
-** <li><b>sqlite3_backup_finish()</b> is called to release all resources
-** associated with the backup operation.
-** </ol>
-** There should be exactly one call to sqlite3_backup_finish() for each
-** successful call to sqlite3_backup_init().
-**
-** <b>sqlite3_backup_init()</b>
-**
-** The first two arguments passed to [sqlite3_backup_init()] are the database
-** handle associated with the destination database and the database name
-** used to attach the destination database to the handle. The database name
-** is "main" for the main database, "temp" for the temporary database, or
-** the name specified as part of the [ATTACH] statement if the destination is
-** an attached database. The third and fourth arguments passed to
-** sqlite3_backup_init() identify the [database connection]
-** and database name used
-** to access the source database. The values passed for the source and
-** destination [database connection] parameters must not be the same.
-**
-** If an error occurs within sqlite3_backup_init(), then NULL is returned
-** and an error code and error message written into the [database connection]
-** passed as the first argument. They may be retrieved using the
-** [sqlite3_errcode()], [sqlite3_errmsg()], and [sqlite3_errmsg16()] functions.
-** Otherwise, if successful, a pointer to an [sqlite3_backup] object is
-** returned. This pointer may be used with the sqlite3_backup_step() and
-** sqlite3_backup_finish() functions to perform the specified backup
-** operation.
-**
-** <b>sqlite3_backup_step()</b>
-**
-** Function [sqlite3_backup_step()] is used to copy up to nPage pages between
-** the source and destination databases, where nPage is the value of the
-** second parameter passed to sqlite3_backup_step(). If nPage is a negative
-** value, all remaining source pages are copied. If the required pages are
-** succesfully copied, but there are still more pages to copy before the
-** backup is complete, it returns [SQLITE_OK]. If no error occured and there
-** are no more pages to copy, then [SQLITE_DONE] is returned. If an error
-** occurs, then an SQLite error code is returned. As well as [SQLITE_OK] and
-** [SQLITE_DONE], a call to sqlite3_backup_step() may return [SQLITE_READONLY],
-** [SQLITE_NOMEM], [SQLITE_BUSY], [SQLITE_LOCKED], or an
-** [SQLITE_IOERR_ACCESS | SQLITE_IOERR_XXX] extended error code.
-**
-** As well as the case where the destination database file was opened for
-** read-only access, sqlite3_backup_step() may return [SQLITE_READONLY] if
-** the destination is an in-memory database with a different page size
-** from the source database.
-**
-** If sqlite3_backup_step() cannot obtain a required file-system lock, then
-** the [sqlite3_busy_handler | busy-handler function]
-** is invoked (if one is specified). If the
-** busy-handler returns non-zero before the lock is available, then
-** [SQLITE_BUSY] is returned to the caller. In this case the call to
-** sqlite3_backup_step() can be retried later. If the source
-** [database connection]
-** is being used to write to the source database when sqlite3_backup_step()
-** is called, then [SQLITE_LOCKED] is returned immediately. Again, in this
-** case the call to sqlite3_backup_step() can be retried later on. If
-** [SQLITE_IOERR_ACCESS | SQLITE_IOERR_XXX], [SQLITE_NOMEM], or
-** [SQLITE_READONLY] is returned, then
-** there is no point in retrying the call to sqlite3_backup_step(). These
-** errors are considered fatal. At this point the application must accept
-** that the backup operation has failed and pass the backup operation handle
-** to the sqlite3_backup_finish() to release associated resources.
-**
-** Following the first call to sqlite3_backup_step(), an exclusive lock is
-** obtained on the destination file. It is not released until either
-** sqlite3_backup_finish() is called or the backup operation is complete
-** and sqlite3_backup_step() returns [SQLITE_DONE]. Additionally, each time
-** a call to sqlite3_backup_step() is made a [shared lock] is obtained on
-** the source database file. This lock is released before the
-** sqlite3_backup_step() call returns. Because the source database is not
-** locked between calls to sqlite3_backup_step(), it may be modified mid-way
-** through the backup procedure. If the source database is modified by an
-** external process or via a database connection other than the one being
-** used by the backup operation, then the backup will be transparently
-** restarted by the next call to sqlite3_backup_step(). If the source
-** database is modified by the using the same database connection as is used
-** by the backup operation, then the backup database is transparently
-** updated at the same time.
-**
-** <b>sqlite3_backup_finish()</b>
-**
-** Once sqlite3_backup_step() has returned [SQLITE_DONE], or when the
-** application wishes to abandon the backup operation, the [sqlite3_backup]
-** object should be passed to sqlite3_backup_finish(). This releases all
-** resources associated with the backup operation. If sqlite3_backup_step()
-** has not yet returned [SQLITE_DONE], then any active write-transaction on the
-** destination database is rolled back. The [sqlite3_backup] object is invalid
-** and may not be used following a call to sqlite3_backup_finish().
-**
-** The value returned by sqlite3_backup_finish is [SQLITE_OK] if no error
-** occurred, regardless or whether or not sqlite3_backup_step() was called
-** a sufficient number of times to complete the backup operation. Or, if
-** an out-of-memory condition or IO error occured during a call to
-** sqlite3_backup_step() then [SQLITE_NOMEM] or an
-** [SQLITE_IOERR_ACCESS | SQLITE_IOERR_XXX] error code
-** is returned. In this case the error code and an error message are
-** written to the destination [database connection].
-**
-** A return of [SQLITE_BUSY] or [SQLITE_LOCKED] from sqlite3_backup_step() is
-** not a permanent error and does not affect the return value of
-** sqlite3_backup_finish().
-**
-** <b>sqlite3_backup_remaining(), sqlite3_backup_pagecount()</b>
-**
-** Each call to sqlite3_backup_step() sets two values stored internally
-** by an [sqlite3_backup] object. The number of pages still to be backed
-** up, which may be queried by sqlite3_backup_remaining(), and the total
-** number of pages in the source database file, which may be queried by
-** sqlite3_backup_pagecount().
-**
-** The values returned by these functions are only updated by
-** sqlite3_backup_step(). If the source database is modified during a backup
-** operation, then the values are not updated to account for any extra
-** pages that need to be updated or the size of the source database file
-** changing.
-**
-** <b>Concurrent Usage of Database Handles</b>
-**
-** The source [database connection] may be used by the application for other
-** purposes while a backup operation is underway or being initialized.
-** If SQLite is compiled and configured to support threadsafe database
-** connections, then the source database connection may be used concurrently
-** from within other threads.
-**
-** However, the application must guarantee that the destination database
-** connection handle is not passed to any other API (by any thread) after
-** sqlite3_backup_init() is called and before the corresponding call to
-** sqlite3_backup_finish(). Unfortunately SQLite does not currently check
-** for this, if the application does use the destination [database connection]
-** for some other purpose during a backup operation, things may appear to
-** work correctly but in fact be subtly malfunctioning. Use of the
-** destination database connection while a backup is in progress might
-** also cause a mutex deadlock.
-**
-** Furthermore, if running in [shared cache mode], the application must
-** guarantee that the shared cache used by the destination database
-** is not accessed while the backup is running. In practice this means
-** that the application must guarantee that the file-system file being
-** backed up to is not accessed by any connection within the process,
-** not just the specific connection that was passed to sqlite3_backup_init().
-**
-** The [sqlite3_backup] object itself is partially threadsafe. Multiple
-** threads may safely make multiple concurrent calls to sqlite3_backup_step().
-** However, the sqlite3_backup_remaining() and sqlite3_backup_pagecount()
-** APIs are not strictly speaking threadsafe. If they are invoked at the
-** same time as another thread is invoking sqlite3_backup_step() it is
-** possible that they return invalid values.
-*/
-SQLITE_API sqlite3_backup *sqlite3_backup_init(
- sqlite3 *pDest, /* Destination database handle */
- const char *zDestName, /* Destination database name */
- sqlite3 *pSource, /* Source database handle */
- const char *zSourceName /* Source database name */
-);
-SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage);
-SQLITE_API int sqlite3_backup_finish(sqlite3_backup *p);
-SQLITE_API int sqlite3_backup_remaining(sqlite3_backup *p);
-SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p);
-
-/*
-** CAPI3REF: Unlock Notification
-** EXPERIMENTAL
-**
-** When running in shared-cache mode, a database operation may fail with
-** an [SQLITE_LOCKED] error if the required locks on the shared-cache or
-** individual tables within the shared-cache cannot be obtained. See
-** [SQLite Shared-Cache Mode] for a description of shared-cache locking.
-** This API may be used to register a callback that SQLite will invoke
-** when the connection currently holding the required lock relinquishes it.
-** This API is only available if the library was compiled with the
-** [SQLITE_ENABLE_UNLOCK_NOTIFY] C-preprocessor symbol defined.
-**
-** See Also: [Using the SQLite Unlock Notification Feature].
-**
-** Shared-cache locks are released when a database connection concludes
-** its current transaction, either by committing it or rolling it back.
-**
-** When a connection (known as the blocked connection) fails to obtain a
-** shared-cache lock and SQLITE_LOCKED is returned to the caller, the
-** identity of the database connection (the blocking connection) that
-** has locked the required resource is stored internally. After an
-** application receives an SQLITE_LOCKED error, it may call the
-** sqlite3_unlock_notify() method with the blocked connection handle as
-** the first argument to register for a callback that will be invoked
-** when the blocking connections current transaction is concluded. The
-** callback is invoked from within the [sqlite3_step] or [sqlite3_close]
-** call that concludes the blocking connections transaction.
-**
-** If sqlite3_unlock_notify() is called in a multi-threaded application,
-** there is a chance that the blocking connection will have already
-** concluded its transaction by the time sqlite3_unlock_notify() is invoked.
-** If this happens, then the specified callback is invoked immediately,
-** from within the call to sqlite3_unlock_notify().
-**
-** If the blocked connection is attempting to obtain a write-lock on a
-** shared-cache table, and more than one other connection currently holds
-** a read-lock on the same table, then SQLite arbitrarily selects one of
-** the other connections to use as the blocking connection.
-**
-** There may be at most one unlock-notify callback registered by a
-** blocked connection. If sqlite3_unlock_notify() is called when the
-** blocked connection already has a registered unlock-notify callback,
-** then the new callback replaces the old. If sqlite3_unlock_notify() is
-** called with a NULL pointer as its second argument, then any existing
-** unlock-notify callback is cancelled. The blocked connections
-** unlock-notify callback may also be canceled by closing the blocked
-** connection using [sqlite3_close()].
-**
-** The unlock-notify callback is not reentrant. If an application invokes
-** any sqlite3_xxx API functions from within an unlock-notify callback, a
-** crash or deadlock may be the result.
-**
-** Unless deadlock is detected (see below), sqlite3_unlock_notify() always
-** returns SQLITE_OK.
-**
-** <b>Callback Invocation Details</b>
-**
-** When an unlock-notify callback is registered, the application provides a
-** single void* pointer that is passed to the callback when it is invoked.
-** However, the signature of the callback function allows SQLite to pass
-** it an array of void* context pointers. The first argument passed to
-** an unlock-notify callback is a pointer to an array of void* pointers,
-** and the second is the number of entries in the array.
-**
-** When a blocking connections transaction is concluded, there may be
-** more than one blocked connection that has registered for an unlock-notify
-** callback. If two or more such blocked connections have specified the
-** same callback function, then instead of invoking the callback function
-** multiple times, it is invoked once with the set of void* context pointers
-** specified by the blocked connections bundled together into an array.
-** This gives the application an opportunity to prioritize any actions
-** related to the set of unblocked database connections.
-**
-** <b>Deadlock Detection</b>
-**
-** Assuming that after registering for an unlock-notify callback a
-** database waits for the callback to be issued before taking any further
-** action (a reasonable assumption), then using this API may cause the
-** application to deadlock. For example, if connection X is waiting for
-** connection Y's transaction to be concluded, and similarly connection
-** Y is waiting on connection X's transaction, then neither connection
-** will proceed and the system may remain deadlocked indefinitely.
-**
-** To avoid this scenario, the sqlite3_unlock_notify() performs deadlock
-** detection. If a given call to sqlite3_unlock_notify() would put the
-** system in a deadlocked state, then SQLITE_LOCKED is returned and no
-** unlock-notify callback is registered. The system is said to be in
-** a deadlocked state if connection A has registered for an unlock-notify
-** callback on the conclusion of connection B's transaction, and connection
-** B has itself registered for an unlock-notify callback when connection
-** A's transaction is concluded. Indirect deadlock is also detected, so
-** the system is also considered to be deadlocked if connection B has
-** registered for an unlock-notify callback on the conclusion of connection
-** C's transaction, where connection C is waiting on connection A. Any
-** number of levels of indirection are allowed.
-**
-** <b>The "DROP TABLE" Exception</b>
-**
-** When a call to [sqlite3_step()] returns SQLITE_LOCKED, it is almost
-** always appropriate to call sqlite3_unlock_notify(). There is however,
-** one exception. When executing a "DROP TABLE" or "DROP INDEX" statement,
-** SQLite checks if there are any currently executing SELECT statements
-** that belong to the same connection. If there are, SQLITE_LOCKED is
-** returned. In this case there is no "blocking connection", so invoking
-** sqlite3_unlock_notify() results in the unlock-notify callback being
-** invoked immediately. If the application then re-attempts the "DROP TABLE"
-** or "DROP INDEX" query, an infinite loop might be the result.
-**
-** One way around this problem is to check the extended error code returned
-** by an sqlite3_step() call. If there is a blocking connection, then the
-** extended error code is set to SQLITE_LOCKED_SHAREDCACHE. Otherwise, in
-** the special "DROP TABLE/INDEX" case, the extended error code is just
-** SQLITE_LOCKED.
-*/
-SQLITE_API int sqlite3_unlock_notify(
- sqlite3 *pBlocked, /* Waiting connection */
- void (*xNotify)(void **apArg, int nArg), /* Callback function to invoke */
- void *pNotifyArg /* Argument to pass to xNotify */
-);
-
-
-/*
-** CAPI3REF: String Comparison
-** EXPERIMENTAL
-**
-** The [sqlite3_strnicmp()] API allows applications and extensions to
-** compare the contents of two buffers containing UTF-8 strings in a
-** case-indendent fashion, using the same definition of case independence
-** that SQLite uses internally when comparing identifiers.
-*/
-SQLITE_API int sqlite3_strnicmp(const char *, const char *, int);
-
-/*
-** Undo the hack that converts floating point types to integer for
-** builds on processors without floating point support.
-*/
-#ifdef SQLITE_OMIT_FLOATING_POINT
-# undef double
-#endif
-
-#ifdef __cplusplus
-} /* End of the 'extern "C"' block */
-#endif
-#endif
-